]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gas/config/tc-arm.c
* bfd/elf32-arm.h (arm_print_private_bfd_data): Add EABI v3.
[thirdparty/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 Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
8 Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
9
10 This file is part of GAS, the GNU Assembler.
11
12 GAS is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
15 any later version.
16
17 GAS is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with GAS; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
25 02111-1307, USA. */
26
27 #include <string.h>
28 #define NO_RELOC 0
29 #include "as.h"
30 #include "safe-ctype.h"
31
32 /* Need TARGET_CPU. */
33 #include "config.h"
34 #include "subsegs.h"
35 #include "obstack.h"
36 #include "symbols.h"
37 #include "listing.h"
38
39 #ifdef OBJ_ELF
40 #include "elf/arm.h"
41 #include "dwarf2dbg.h"
42 #endif
43
44 /* XXX Set this to 1 after the next binutils release */
45 #define WARN_DEPRECATED 0
46
47 /* The following bitmasks control CPU extensions: */
48 #define ARM_EXT_V1 0x00000001 /* All processors (core set). */
49 #define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
50 #define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
51 #define ARM_EXT_V3 0x00000008 /* MSR MRS. */
52 #define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
53 #define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
54 #define ARM_EXT_V4T 0x00000040 /* Thumb v1. */
55 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
56 #define ARM_EXT_V5T 0x00000100 /* Thumb v2. */
57 #define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
58 #define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
59 #define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */
60 #define ARM_EXT_V6 0x00001000 /* ARM V6. */
61
62 /* Co-processor space extensions. */
63 #define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */
64 #define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. */
65 #define ARM_CEXT_IWMMXT 0x00200000 /* Intel Wireless MMX technology coprocessor. */
66
67 /* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
68 defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
69 ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
70 three more to cover cores prior to ARM6. Finally, there are cores which
71 implement further extensions in the co-processor space. */
72 #define ARM_ARCH_V1 ARM_EXT_V1
73 #define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)
74 #define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)
75 #define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)
76 #define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)
77 #define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)
78 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)
79 #define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)
80 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)
81 #define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)
82 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
83 #define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
84 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
85 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)
86 #define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)
87 #define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE | ARM_EXT_V5J)
88 #define ARM_ARCH_V6 (ARM_ARCH_V5TEJ | ARM_EXT_V6)
89
90 /* Processors with specific extensions in the co-processor space. */
91 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)
92 #define ARM_ARCH_IWMMXT (ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT)
93
94 /* Some useful combinations: */
95 #define ARM_ANY 0x0000ffff /* Any basic core. */
96 #define ARM_ALL 0x00ffffff /* Any core + co-processor */
97 #define CPROC_ANY 0x00ff0000 /* Any co-processor */
98 #define FPU_ANY 0xff000000 /* Note this is ~ARM_ALL. */
99
100
101 #define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */
102 #define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */
103 #define FPU_VFP_EXT_NONE 0x20000000 /* Use VFP word-ordering. */
104 #define FPU_VFP_EXT_V1xD 0x10000000 /* Base VFP instruction set. */
105 #define FPU_VFP_EXT_V1 0x08000000 /* Double-precision insns. */
106 #define FPU_VFP_EXT_V2 0x04000000 /* ARM10E VFPr1. */
107 #define FPU_MAVERICK 0x02000000 /* Cirrus Maverick. */
108 #define FPU_NONE 0
109
110 #define FPU_ARCH_FPE FPU_FPA_EXT_V1
111 #define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
112
113 #define FPU_ARCH_VFP FPU_VFP_EXT_NONE
114 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
115 #define FPU_ARCH_VFP_V1 (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
116 #define FPU_ARCH_VFP_V2 (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
117
118 #define FPU_ARCH_MAVERICK FPU_MAVERICK
119
120 enum arm_float_abi
121 {
122 ARM_FLOAT_ABI_HARD,
123 ARM_FLOAT_ABI_SOFTFP,
124 ARM_FLOAT_ABI_SOFT
125 };
126
127 /* Types of processor to assemble for. */
128 #define ARM_1 ARM_ARCH_V1
129 #define ARM_2 ARM_ARCH_V2
130 #define ARM_3 ARM_ARCH_V2S
131 #define ARM_250 ARM_ARCH_V2S
132 #define ARM_6 ARM_ARCH_V3
133 #define ARM_7 ARM_ARCH_V3
134 #define ARM_8 ARM_ARCH_V4
135 #define ARM_9 ARM_ARCH_V4T
136 #define ARM_STRONG ARM_ARCH_V4
137 #define ARM_CPU_MASK 0x0000000f /* XXX? */
138
139 #ifndef CPU_DEFAULT
140 #if defined __XSCALE__
141 #define CPU_DEFAULT (ARM_ARCH_XSCALE)
142 #else
143 #if defined __thumb__
144 #define CPU_DEFAULT (ARM_ARCH_V5T)
145 #else
146 #define CPU_DEFAULT ARM_ANY
147 #endif
148 #endif
149 #endif
150
151 #ifdef TE_LINUX
152 #define FPU_DEFAULT FPU_ARCH_FPA
153 #endif
154
155 #ifdef TE_NetBSD
156 #ifdef OBJ_ELF
157 #define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, but VFP order. */
158 #else
159 /* Legacy a.out format. */
160 #define FPU_DEFAULT FPU_ARCH_FPA /* Soft-float, but FPA order. */
161 #endif
162 #endif
163
164 /* For backwards compatibility we default to the FPA. */
165 #ifndef FPU_DEFAULT
166 #define FPU_DEFAULT FPU_ARCH_FPA
167 #endif
168
169 #define streq(a, b) (strcmp (a, b) == 0)
170 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
171
172 static unsigned long cpu_variant;
173 static int target_oabi = 0;
174
175 /* Flags stored in private area of BFD structure. */
176 static int uses_apcs_26 = FALSE;
177 static int atpcs = FALSE;
178 static int support_interwork = FALSE;
179 static int uses_apcs_float = FALSE;
180 static int pic_code = FALSE;
181
182 /* Variables that we set while parsing command-line options. Once all
183 options have been read we re-process these values to set the real
184 assembly flags. */
185 static int legacy_cpu = -1;
186 static int legacy_fpu = -1;
187
188 static int mcpu_cpu_opt = -1;
189 static int mcpu_fpu_opt = -1;
190 static int march_cpu_opt = -1;
191 static int march_fpu_opt = -1;
192 static int mfpu_opt = -1;
193 static int mfloat_abi_opt = -1;
194 static int meabi_flags = EF_ARM_EABI_UNKNOWN;
195
196 /* This array holds the chars that always start a comment. If the
197 pre-processor is disabled, these aren't very useful. */
198 const char comment_chars[] = "@";
199
200 /* This array holds the chars that only start a comment at the beginning of
201 a line. If the line seems to have the form '# 123 filename'
202 .line and .file directives will appear in the pre-processed output. */
203 /* Note that input_file.c hand checks for '#' at the beginning of the
204 first line of the input file. This is because the compiler outputs
205 #NO_APP at the beginning of its output. */
206 /* Also note that comments like this one will always work. */
207 const char line_comment_chars[] = "#";
208
209 const char line_separator_chars[] = ";";
210
211 /* Chars that can be used to separate mant
212 from exp in floating point numbers. */
213 const char EXP_CHARS[] = "eE";
214
215 /* Chars that mean this number is a floating point constant. */
216 /* As in 0f12.456 */
217 /* or 0d1.2345e12 */
218
219 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
220
221 /* Prefix characters that indicate the start of an immediate
222 value. */
223 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
224
225 #ifdef OBJ_ELF
226 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
227 symbolS * GOT_symbol;
228 #endif
229
230 /* Size of relocation record. */
231 const int md_reloc_size = 8;
232
233 /* 0: assemble for ARM,
234 1: assemble for Thumb,
235 2: assemble for Thumb even though target CPU does not support thumb
236 instructions. */
237 static int thumb_mode = 0;
238
239 typedef struct arm_fix
240 {
241 int thumb_mode;
242 } arm_fix_data;
243
244 struct arm_it
245 {
246 const char * error;
247 unsigned long instruction;
248 int size;
249 struct
250 {
251 bfd_reloc_code_real_type type;
252 expressionS exp;
253 int pc_rel;
254 } reloc;
255 };
256
257 struct arm_it inst;
258
259 enum asm_shift_index
260 {
261 SHIFT_LSL = 0,
262 SHIFT_LSR,
263 SHIFT_ASR,
264 SHIFT_ROR,
265 SHIFT_RRX
266 };
267
268 struct asm_shift_properties
269 {
270 enum asm_shift_index index;
271 unsigned long bit_field;
272 unsigned int allows_0 : 1;
273 unsigned int allows_32 : 1;
274 };
275
276 static const struct asm_shift_properties shift_properties [] =
277 {
278 { SHIFT_LSL, 0, 1, 0},
279 { SHIFT_LSR, 0x20, 0, 1},
280 { SHIFT_ASR, 0x40, 0, 1},
281 { SHIFT_ROR, 0x60, 0, 0},
282 { SHIFT_RRX, 0x60, 0, 0}
283 };
284
285 struct asm_shift_name
286 {
287 const char * name;
288 const struct asm_shift_properties * properties;
289 };
290
291 static const struct asm_shift_name shift_names [] =
292 {
293 { "asl", shift_properties + SHIFT_LSL },
294 { "lsl", shift_properties + SHIFT_LSL },
295 { "lsr", shift_properties + SHIFT_LSR },
296 { "asr", shift_properties + SHIFT_ASR },
297 { "ror", shift_properties + SHIFT_ROR },
298 { "rrx", shift_properties + SHIFT_RRX },
299 { "ASL", shift_properties + SHIFT_LSL },
300 { "LSL", shift_properties + SHIFT_LSL },
301 { "LSR", shift_properties + SHIFT_LSR },
302 { "ASR", shift_properties + SHIFT_ASR },
303 { "ROR", shift_properties + SHIFT_ROR },
304 { "RRX", shift_properties + SHIFT_RRX }
305 };
306
307 /* Any kind of shift is accepted. */
308 #define NO_SHIFT_RESTRICT 1
309 /* The shift operand must be an immediate value, not a register. */
310 #define SHIFT_IMMEDIATE 0
311 /* The shift must be LSL or ASR and the operand must be an immediate. */
312 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
313 /* The shift must be ASR and the operand must be an immediate. */
314 #define SHIFT_ASR_IMMEDIATE 3
315 /* The shift must be LSL and the operand must be an immediate. */
316 #define SHIFT_LSL_IMMEDIATE 4
317
318 #define NUM_FLOAT_VALS 8
319
320 const char * fp_const[] =
321 {
322 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
323 };
324
325 /* Number of littlenums required to hold an extended precision number. */
326 #define MAX_LITTLENUMS 6
327
328 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
329
330 #define FAIL (-1)
331 #define SUCCESS (0)
332
333 /* Whether a Co-processor load/store operation accepts write-back forms. */
334 #define CP_WB_OK 1
335 #define CP_NO_WB 0
336
337 #define SUFF_S 1
338 #define SUFF_D 2
339 #define SUFF_E 3
340 #define SUFF_P 4
341
342 #define CP_T_X 0x00008000
343 #define CP_T_Y 0x00400000
344 #define CP_T_Pre 0x01000000
345 #define CP_T_UD 0x00800000
346 #define CP_T_WB 0x00200000
347
348 #define CONDS_BIT 0x00100000
349 #define LOAD_BIT 0x00100000
350
351 #define DOUBLE_LOAD_FLAG 0x00000001
352
353 struct asm_cond
354 {
355 const char * template;
356 unsigned long value;
357 };
358
359 #define COND_ALWAYS 0xe0000000
360 #define COND_MASK 0xf0000000
361
362 static const struct asm_cond conds[] =
363 {
364 {"eq", 0x00000000},
365 {"ne", 0x10000000},
366 {"cs", 0x20000000}, {"hs", 0x20000000},
367 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
368 {"mi", 0x40000000},
369 {"pl", 0x50000000},
370 {"vs", 0x60000000},
371 {"vc", 0x70000000},
372 {"hi", 0x80000000},
373 {"ls", 0x90000000},
374 {"ge", 0xa0000000},
375 {"lt", 0xb0000000},
376 {"gt", 0xc0000000},
377 {"le", 0xd0000000},
378 {"al", 0xe0000000},
379 {"nv", 0xf0000000}
380 };
381
382 struct asm_psr
383 {
384 const char *template;
385 bfd_boolean cpsr;
386 unsigned long field;
387 };
388
389 /* The bit that distinguishes CPSR and SPSR. */
390 #define SPSR_BIT (1 << 22)
391
392 /* How many bits to shift the PSR_xxx bits up by. */
393 #define PSR_SHIFT 16
394
395 #define PSR_c (1 << 0)
396 #define PSR_x (1 << 1)
397 #define PSR_s (1 << 2)
398 #define PSR_f (1 << 3)
399
400 static const struct asm_psr psrs[] =
401 {
402 {"CPSR", TRUE, PSR_c | PSR_f},
403 {"CPSR_all", TRUE, PSR_c | PSR_f},
404 {"SPSR", FALSE, PSR_c | PSR_f},
405 {"SPSR_all", FALSE, PSR_c | PSR_f},
406 {"CPSR_flg", TRUE, PSR_f},
407 {"CPSR_f", TRUE, PSR_f},
408 {"SPSR_flg", FALSE, PSR_f},
409 {"SPSR_f", FALSE, PSR_f},
410 {"CPSR_c", TRUE, PSR_c},
411 {"CPSR_ctl", TRUE, PSR_c},
412 {"SPSR_c", FALSE, PSR_c},
413 {"SPSR_ctl", FALSE, PSR_c},
414 {"CPSR_x", TRUE, PSR_x},
415 {"CPSR_s", TRUE, PSR_s},
416 {"SPSR_x", FALSE, PSR_x},
417 {"SPSR_s", FALSE, PSR_s},
418 /* Combinations of flags. */
419 {"CPSR_fs", TRUE, PSR_f | PSR_s},
420 {"CPSR_fx", TRUE, PSR_f | PSR_x},
421 {"CPSR_fc", TRUE, PSR_f | PSR_c},
422 {"CPSR_sf", TRUE, PSR_s | PSR_f},
423 {"CPSR_sx", TRUE, PSR_s | PSR_x},
424 {"CPSR_sc", TRUE, PSR_s | PSR_c},
425 {"CPSR_xf", TRUE, PSR_x | PSR_f},
426 {"CPSR_xs", TRUE, PSR_x | PSR_s},
427 {"CPSR_xc", TRUE, PSR_x | PSR_c},
428 {"CPSR_cf", TRUE, PSR_c | PSR_f},
429 {"CPSR_cs", TRUE, PSR_c | PSR_s},
430 {"CPSR_cx", TRUE, PSR_c | PSR_x},
431 {"CPSR_fsx", TRUE, PSR_f | PSR_s | PSR_x},
432 {"CPSR_fsc", TRUE, PSR_f | PSR_s | PSR_c},
433 {"CPSR_fxs", TRUE, PSR_f | PSR_x | PSR_s},
434 {"CPSR_fxc", TRUE, PSR_f | PSR_x | PSR_c},
435 {"CPSR_fcs", TRUE, PSR_f | PSR_c | PSR_s},
436 {"CPSR_fcx", TRUE, PSR_f | PSR_c | PSR_x},
437 {"CPSR_sfx", TRUE, PSR_s | PSR_f | PSR_x},
438 {"CPSR_sfc", TRUE, PSR_s | PSR_f | PSR_c},
439 {"CPSR_sxf", TRUE, PSR_s | PSR_x | PSR_f},
440 {"CPSR_sxc", TRUE, PSR_s | PSR_x | PSR_c},
441 {"CPSR_scf", TRUE, PSR_s | PSR_c | PSR_f},
442 {"CPSR_scx", TRUE, PSR_s | PSR_c | PSR_x},
443 {"CPSR_xfs", TRUE, PSR_x | PSR_f | PSR_s},
444 {"CPSR_xfc", TRUE, PSR_x | PSR_f | PSR_c},
445 {"CPSR_xsf", TRUE, PSR_x | PSR_s | PSR_f},
446 {"CPSR_xsc", TRUE, PSR_x | PSR_s | PSR_c},
447 {"CPSR_xcf", TRUE, PSR_x | PSR_c | PSR_f},
448 {"CPSR_xcs", TRUE, PSR_x | PSR_c | PSR_s},
449 {"CPSR_cfs", TRUE, PSR_c | PSR_f | PSR_s},
450 {"CPSR_cfx", TRUE, PSR_c | PSR_f | PSR_x},
451 {"CPSR_csf", TRUE, PSR_c | PSR_s | PSR_f},
452 {"CPSR_csx", TRUE, PSR_c | PSR_s | PSR_x},
453 {"CPSR_cxf", TRUE, PSR_c | PSR_x | PSR_f},
454 {"CPSR_cxs", TRUE, PSR_c | PSR_x | PSR_s},
455 {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
456 {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
457 {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
458 {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
459 {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
460 {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
461 {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
462 {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
463 {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
464 {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
465 {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
466 {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
467 {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
468 {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
469 {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
470 {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
471 {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
472 {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
473 {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
474 {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
475 {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
476 {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
477 {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
478 {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
479 {"SPSR_fs", FALSE, PSR_f | PSR_s},
480 {"SPSR_fx", FALSE, PSR_f | PSR_x},
481 {"SPSR_fc", FALSE, PSR_f | PSR_c},
482 {"SPSR_sf", FALSE, PSR_s | PSR_f},
483 {"SPSR_sx", FALSE, PSR_s | PSR_x},
484 {"SPSR_sc", FALSE, PSR_s | PSR_c},
485 {"SPSR_xf", FALSE, PSR_x | PSR_f},
486 {"SPSR_xs", FALSE, PSR_x | PSR_s},
487 {"SPSR_xc", FALSE, PSR_x | PSR_c},
488 {"SPSR_cf", FALSE, PSR_c | PSR_f},
489 {"SPSR_cs", FALSE, PSR_c | PSR_s},
490 {"SPSR_cx", FALSE, PSR_c | PSR_x},
491 {"SPSR_fsx", FALSE, PSR_f | PSR_s | PSR_x},
492 {"SPSR_fsc", FALSE, PSR_f | PSR_s | PSR_c},
493 {"SPSR_fxs", FALSE, PSR_f | PSR_x | PSR_s},
494 {"SPSR_fxc", FALSE, PSR_f | PSR_x | PSR_c},
495 {"SPSR_fcs", FALSE, PSR_f | PSR_c | PSR_s},
496 {"SPSR_fcx", FALSE, PSR_f | PSR_c | PSR_x},
497 {"SPSR_sfx", FALSE, PSR_s | PSR_f | PSR_x},
498 {"SPSR_sfc", FALSE, PSR_s | PSR_f | PSR_c},
499 {"SPSR_sxf", FALSE, PSR_s | PSR_x | PSR_f},
500 {"SPSR_sxc", FALSE, PSR_s | PSR_x | PSR_c},
501 {"SPSR_scf", FALSE, PSR_s | PSR_c | PSR_f},
502 {"SPSR_scx", FALSE, PSR_s | PSR_c | PSR_x},
503 {"SPSR_xfs", FALSE, PSR_x | PSR_f | PSR_s},
504 {"SPSR_xfc", FALSE, PSR_x | PSR_f | PSR_c},
505 {"SPSR_xsf", FALSE, PSR_x | PSR_s | PSR_f},
506 {"SPSR_xsc", FALSE, PSR_x | PSR_s | PSR_c},
507 {"SPSR_xcf", FALSE, PSR_x | PSR_c | PSR_f},
508 {"SPSR_xcs", FALSE, PSR_x | PSR_c | PSR_s},
509 {"SPSR_cfs", FALSE, PSR_c | PSR_f | PSR_s},
510 {"SPSR_cfx", FALSE, PSR_c | PSR_f | PSR_x},
511 {"SPSR_csf", FALSE, PSR_c | PSR_s | PSR_f},
512 {"SPSR_csx", FALSE, PSR_c | PSR_s | PSR_x},
513 {"SPSR_cxf", FALSE, PSR_c | PSR_x | PSR_f},
514 {"SPSR_cxs", FALSE, PSR_c | PSR_x | PSR_s},
515 {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
516 {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
517 {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
518 {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
519 {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
520 {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
521 {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
522 {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
523 {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
524 {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
525 {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
526 {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
527 {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
528 {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
529 {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
530 {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
531 {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
532 {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
533 {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
534 {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
535 {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
536 {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
537 {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
538 {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
539 };
540
541 enum wreg_type
542 {
543 IWMMXT_REG_WR = 0,
544 IWMMXT_REG_WC = 1,
545 IWMMXT_REG_WR_OR_WC = 2,
546 IWMMXT_REG_WCG
547 };
548
549 enum iwmmxt_insn_type
550 {
551 check_rd,
552 check_wr,
553 check_wrwr,
554 check_wrwrwr,
555 check_wrwrwcg,
556 check_tbcst,
557 check_tmovmsk,
558 check_tmia,
559 check_tmcrr,
560 check_tmrrc,
561 check_tmcr,
562 check_tmrc,
563 check_tinsr,
564 check_textrc,
565 check_waligni,
566 check_textrm,
567 check_wshufh
568 };
569
570 enum vfp_dp_reg_pos
571 {
572 VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
573 };
574
575 enum vfp_sp_reg_pos
576 {
577 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
578 };
579
580 enum vfp_ldstm_type
581 {
582 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
583 };
584
585 /* VFP system registers. */
586 struct vfp_reg
587 {
588 const char *name;
589 unsigned long regno;
590 };
591
592 static const struct vfp_reg vfp_regs[] =
593 {
594 {"fpsid", 0x00000000},
595 {"FPSID", 0x00000000},
596 {"fpscr", 0x00010000},
597 {"FPSCR", 0x00010000},
598 {"fpexc", 0x00080000},
599 {"FPEXC", 0x00080000}
600 };
601
602 /* Structure for a hash table entry for a register. */
603 struct reg_entry
604 {
605 const char * name;
606 int number;
607 bfd_boolean builtin;
608 };
609
610 /* Some well known registers that we refer to directly elsewhere. */
611 #define REG_SP 13
612 #define REG_LR 14
613 #define REG_PC 15
614
615 #define wr_register(reg) ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
616 #define wc_register(reg) ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
617 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
618
619 /* These are the standard names. Users can add aliases with .req.
620 and delete them with .unreq. */
621
622 /* Integer Register Numbers. */
623 static const struct reg_entry rn_table[] =
624 {
625 {"r0", 0, TRUE}, {"r1", 1, TRUE}, {"r2", 2, TRUE}, {"r3", 3, TRUE},
626 {"r4", 4, TRUE}, {"r5", 5, TRUE}, {"r6", 6, TRUE}, {"r7", 7, TRUE},
627 {"r8", 8, TRUE}, {"r9", 9, TRUE}, {"r10", 10, TRUE}, {"r11", 11, TRUE},
628 {"r12", 12, TRUE}, {"r13", REG_SP, TRUE}, {"r14", REG_LR, TRUE}, {"r15", REG_PC, TRUE},
629 /* ATPCS Synonyms. */
630 {"a1", 0, TRUE}, {"a2", 1, TRUE}, {"a3", 2, TRUE}, {"a4", 3, TRUE},
631 {"v1", 4, TRUE}, {"v2", 5, TRUE}, {"v3", 6, TRUE}, {"v4", 7, TRUE},
632 {"v5", 8, TRUE}, {"v6", 9, TRUE}, {"v7", 10, TRUE}, {"v8", 11, TRUE},
633 /* Well-known aliases. */
634 {"wr", 7, TRUE}, {"sb", 9, TRUE}, {"sl", 10, TRUE}, {"fp", 11, TRUE},
635 {"ip", 12, TRUE}, {"sp", REG_SP, TRUE}, {"lr", REG_LR, TRUE}, {"pc", REG_PC, TRUE},
636 {NULL, 0, TRUE}
637 };
638
639 #define WR_PREFIX 0x200
640 #define WC_PREFIX 0x400
641
642 static const struct reg_entry iwmmxt_table[] =
643 {
644 /* Intel Wireless MMX technology register names. */
645 { "wr0", 0x0 | WR_PREFIX, TRUE}, {"wr1", 0x1 | WR_PREFIX, TRUE},
646 { "wr2", 0x2 | WR_PREFIX, TRUE}, {"wr3", 0x3 | WR_PREFIX, TRUE},
647 { "wr4", 0x4 | WR_PREFIX, TRUE}, {"wr5", 0x5 | WR_PREFIX, TRUE},
648 { "wr6", 0x6 | WR_PREFIX, TRUE}, {"wr7", 0x7 | WR_PREFIX, TRUE},
649 { "wr8", 0x8 | WR_PREFIX, TRUE}, {"wr9", 0x9 | WR_PREFIX, TRUE},
650 { "wr10", 0xa | WR_PREFIX, TRUE}, {"wr11", 0xb | WR_PREFIX, TRUE},
651 { "wr12", 0xc | WR_PREFIX, TRUE}, {"wr13", 0xd | WR_PREFIX, TRUE},
652 { "wr14", 0xe | WR_PREFIX, TRUE}, {"wr15", 0xf | WR_PREFIX, TRUE},
653 { "wcid", 0x0 | WC_PREFIX, TRUE}, {"wcon", 0x1 | WC_PREFIX, TRUE},
654 {"wcssf", 0x2 | WC_PREFIX, TRUE}, {"wcasf", 0x3 | WC_PREFIX, TRUE},
655 {"wcgr0", 0x8 | WC_PREFIX, TRUE}, {"wcgr1", 0x9 | WC_PREFIX, TRUE},
656 {"wcgr2", 0xa | WC_PREFIX, TRUE}, {"wcgr3", 0xb | WC_PREFIX, TRUE},
657
658 { "wR0", 0x0 | WR_PREFIX, TRUE}, {"wR1", 0x1 | WR_PREFIX, TRUE},
659 { "wR2", 0x2 | WR_PREFIX, TRUE}, {"wR3", 0x3 | WR_PREFIX, TRUE},
660 { "wR4", 0x4 | WR_PREFIX, TRUE}, {"wR5", 0x5 | WR_PREFIX, TRUE},
661 { "wR6", 0x6 | WR_PREFIX, TRUE}, {"wR7", 0x7 | WR_PREFIX, TRUE},
662 { "wR8", 0x8 | WR_PREFIX, TRUE}, {"wR9", 0x9 | WR_PREFIX, TRUE},
663 { "wR10", 0xa | WR_PREFIX, TRUE}, {"wR11", 0xb | WR_PREFIX, TRUE},
664 { "wR12", 0xc | WR_PREFIX, TRUE}, {"wR13", 0xd | WR_PREFIX, TRUE},
665 { "wR14", 0xe | WR_PREFIX, TRUE}, {"wR15", 0xf | WR_PREFIX, TRUE},
666 { "wCID", 0x0 | WC_PREFIX, TRUE}, {"wCon", 0x1 | WC_PREFIX, TRUE},
667 {"wCSSF", 0x2 | WC_PREFIX, TRUE}, {"wCASF", 0x3 | WC_PREFIX, TRUE},
668 {"wCGR0", 0x8 | WC_PREFIX, TRUE}, {"wCGR1", 0x9 | WC_PREFIX, TRUE},
669 {"wCGR2", 0xa | WC_PREFIX, TRUE}, {"wCGR3", 0xb | WC_PREFIX, TRUE},
670 {NULL, 0, TRUE}
671 };
672
673 /* Co-processor Numbers. */
674 static const struct reg_entry cp_table[] =
675 {
676 {"p0", 0, TRUE}, {"p1", 1, TRUE}, {"p2", 2, TRUE}, {"p3", 3, TRUE},
677 {"p4", 4, TRUE}, {"p5", 5, TRUE}, {"p6", 6, TRUE}, {"p7", 7, TRUE},
678 {"p8", 8, TRUE}, {"p9", 9, TRUE}, {"p10", 10, TRUE}, {"p11", 11, TRUE},
679 {"p12", 12, TRUE}, {"p13", 13, TRUE}, {"p14", 14, TRUE}, {"p15", 15, TRUE},
680 {NULL, 0, TRUE}
681 };
682
683 /* Co-processor Register Numbers. */
684 static const struct reg_entry cn_table[] =
685 {
686 {"c0", 0, TRUE}, {"c1", 1, TRUE}, {"c2", 2, TRUE}, {"c3", 3, TRUE},
687 {"c4", 4, TRUE}, {"c5", 5, TRUE}, {"c6", 6, TRUE}, {"c7", 7, TRUE},
688 {"c8", 8, TRUE}, {"c9", 9, TRUE}, {"c10", 10, TRUE}, {"c11", 11, TRUE},
689 {"c12", 12, TRUE}, {"c13", 13, TRUE}, {"c14", 14, TRUE}, {"c15", 15, TRUE},
690 /* Not really valid, but kept for back-wards compatibility. */
691 {"cr0", 0, TRUE}, {"cr1", 1, TRUE}, {"cr2", 2, TRUE}, {"cr3", 3, TRUE},
692 {"cr4", 4, TRUE}, {"cr5", 5, TRUE}, {"cr6", 6, TRUE}, {"cr7", 7, TRUE},
693 {"cr8", 8, TRUE}, {"cr9", 9, TRUE}, {"cr10", 10, TRUE}, {"cr11", 11, TRUE},
694 {"cr12", 12, TRUE}, {"cr13", 13, TRUE}, {"cr14", 14, TRUE}, {"cr15", 15, TRUE},
695 {NULL, 0, TRUE}
696 };
697
698 /* FPA Registers. */
699 static const struct reg_entry fn_table[] =
700 {
701 {"f0", 0, TRUE}, {"f1", 1, TRUE}, {"f2", 2, TRUE}, {"f3", 3, TRUE},
702 {"f4", 4, TRUE}, {"f5", 5, TRUE}, {"f6", 6, TRUE}, {"f7", 7, TRUE},
703 {NULL, 0, TRUE}
704 };
705
706 /* VFP SP Registers. */
707 static const struct reg_entry sn_table[] =
708 {
709 {"s0", 0, TRUE}, {"s1", 1, TRUE}, {"s2", 2, TRUE}, {"s3", 3, TRUE},
710 {"s4", 4, TRUE}, {"s5", 5, TRUE}, {"s6", 6, TRUE}, {"s7", 7, TRUE},
711 {"s8", 8, TRUE}, {"s9", 9, TRUE}, {"s10", 10, TRUE}, {"s11", 11, TRUE},
712 {"s12", 12, TRUE}, {"s13", 13, TRUE}, {"s14", 14, TRUE}, {"s15", 15, TRUE},
713 {"s16", 16, TRUE}, {"s17", 17, TRUE}, {"s18", 18, TRUE}, {"s19", 19, TRUE},
714 {"s20", 20, TRUE}, {"s21", 21, TRUE}, {"s22", 22, TRUE}, {"s23", 23, TRUE},
715 {"s24", 24, TRUE}, {"s25", 25, TRUE}, {"s26", 26, TRUE}, {"s27", 27, TRUE},
716 {"s28", 28, TRUE}, {"s29", 29, TRUE}, {"s30", 30, TRUE}, {"s31", 31, TRUE},
717 {NULL, 0, TRUE}
718 };
719
720 /* VFP DP Registers. */
721 static const struct reg_entry dn_table[] =
722 {
723 {"d0", 0, TRUE}, {"d1", 1, TRUE}, {"d2", 2, TRUE}, {"d3", 3, TRUE},
724 {"d4", 4, TRUE}, {"d5", 5, TRUE}, {"d6", 6, TRUE}, {"d7", 7, TRUE},
725 {"d8", 8, TRUE}, {"d9", 9, TRUE}, {"d10", 10, TRUE}, {"d11", 11, TRUE},
726 {"d12", 12, TRUE}, {"d13", 13, TRUE}, {"d14", 14, TRUE}, {"d15", 15, TRUE},
727 {NULL, 0, TRUE}
728 };
729
730 /* Maverick DSP coprocessor registers. */
731 static const struct reg_entry mav_mvf_table[] =
732 {
733 {"mvf0", 0, TRUE}, {"mvf1", 1, TRUE}, {"mvf2", 2, TRUE}, {"mvf3", 3, TRUE},
734 {"mvf4", 4, TRUE}, {"mvf5", 5, TRUE}, {"mvf6", 6, TRUE}, {"mvf7", 7, TRUE},
735 {"mvf8", 8, TRUE}, {"mvf9", 9, TRUE}, {"mvf10", 10, TRUE}, {"mvf11", 11, TRUE},
736 {"mvf12", 12, TRUE}, {"mvf13", 13, TRUE}, {"mvf14", 14, TRUE}, {"mvf15", 15, TRUE},
737 {NULL, 0, TRUE}
738 };
739
740 static const struct reg_entry mav_mvd_table[] =
741 {
742 {"mvd0", 0, TRUE}, {"mvd1", 1, TRUE}, {"mvd2", 2, TRUE}, {"mvd3", 3, TRUE},
743 {"mvd4", 4, TRUE}, {"mvd5", 5, TRUE}, {"mvd6", 6, TRUE}, {"mvd7", 7, TRUE},
744 {"mvd8", 8, TRUE}, {"mvd9", 9, TRUE}, {"mvd10", 10, TRUE}, {"mvd11", 11, TRUE},
745 {"mvd12", 12, TRUE}, {"mvd13", 13, TRUE}, {"mvd14", 14, TRUE}, {"mvd15", 15, TRUE},
746 {NULL, 0, TRUE}
747 };
748
749 static const struct reg_entry mav_mvfx_table[] =
750 {
751 {"mvfx0", 0, TRUE}, {"mvfx1", 1, TRUE}, {"mvfx2", 2, TRUE}, {"mvfx3", 3, TRUE},
752 {"mvfx4", 4, TRUE}, {"mvfx5", 5, TRUE}, {"mvfx6", 6, TRUE}, {"mvfx7", 7, TRUE},
753 {"mvfx8", 8, TRUE}, {"mvfx9", 9, TRUE}, {"mvfx10", 10, TRUE}, {"mvfx11", 11, TRUE},
754 {"mvfx12", 12, TRUE}, {"mvfx13", 13, TRUE}, {"mvfx14", 14, TRUE}, {"mvfx15", 15, TRUE},
755 {NULL, 0, TRUE}
756 };
757
758 static const struct reg_entry mav_mvdx_table[] =
759 {
760 {"mvdx0", 0, TRUE}, {"mvdx1", 1, TRUE}, {"mvdx2", 2, TRUE}, {"mvdx3", 3, TRUE},
761 {"mvdx4", 4, TRUE}, {"mvdx5", 5, TRUE}, {"mvdx6", 6, TRUE}, {"mvdx7", 7, TRUE},
762 {"mvdx8", 8, TRUE}, {"mvdx9", 9, TRUE}, {"mvdx10", 10, TRUE}, {"mvdx11", 11, TRUE},
763 {"mvdx12", 12, TRUE}, {"mvdx13", 13, TRUE}, {"mvdx14", 14, TRUE}, {"mvdx15", 15, TRUE},
764 {NULL, 0, TRUE}
765 };
766
767 static const struct reg_entry mav_mvax_table[] =
768 {
769 {"mvax0", 0, TRUE}, {"mvax1", 1, TRUE}, {"mvax2", 2, TRUE}, {"mvax3", 3, TRUE},
770 {NULL, 0, TRUE}
771 };
772
773 static const struct reg_entry mav_dspsc_table[] =
774 {
775 {"dspsc", 0, TRUE},
776 {NULL, 0, TRUE}
777 };
778
779 struct reg_map
780 {
781 const struct reg_entry *names;
782 int max_regno;
783 struct hash_control *htab;
784 const char *expected;
785 };
786
787 struct reg_map all_reg_maps[] =
788 {
789 {rn_table, 15, NULL, N_("ARM register expected")},
790 {cp_table, 15, NULL, N_("bad or missing co-processor number")},
791 {cn_table, 15, NULL, N_("co-processor register expected")},
792 {fn_table, 7, NULL, N_("FPA register expected")},
793 {sn_table, 31, NULL, N_("VFP single precision register expected")},
794 {dn_table, 15, NULL, N_("VFP double precision register expected")},
795 {mav_mvf_table, 15, NULL, N_("Maverick MVF register expected")},
796 {mav_mvd_table, 15, NULL, N_("Maverick MVD register expected")},
797 {mav_mvfx_table, 15, NULL, N_("Maverick MVFX register expected")},
798 {mav_mvdx_table, 15, NULL, N_("Maverick MVDX register expected")},
799 {mav_mvax_table, 3, NULL, N_("Maverick MVAX register expected")},
800 {mav_dspsc_table, 0, NULL, N_("Maverick DSPSC register expected")},
801 {iwmmxt_table, 23, NULL, N_("Intel Wireless MMX technology register expected")},
802 };
803
804 /* Enumeration matching entries in table above. */
805 enum arm_reg_type
806 {
807 REG_TYPE_RN = 0,
808 #define REG_TYPE_FIRST REG_TYPE_RN
809 REG_TYPE_CP = 1,
810 REG_TYPE_CN = 2,
811 REG_TYPE_FN = 3,
812 REG_TYPE_SN = 4,
813 REG_TYPE_DN = 5,
814 REG_TYPE_MVF = 6,
815 REG_TYPE_MVD = 7,
816 REG_TYPE_MVFX = 8,
817 REG_TYPE_MVDX = 9,
818 REG_TYPE_MVAX = 10,
819 REG_TYPE_DSPSC = 11,
820 REG_TYPE_IWMMXT = 12,
821
822 REG_TYPE_MAX = 13
823 };
824
825 /* Functions called by parser. */
826 /* ARM instructions. */
827 static void do_arit PARAMS ((char *));
828 static void do_cmp PARAMS ((char *));
829 static void do_mov PARAMS ((char *));
830 static void do_ldst PARAMS ((char *));
831 static void do_ldstt PARAMS ((char *));
832 static void do_ldmstm PARAMS ((char *));
833 static void do_branch PARAMS ((char *));
834 static void do_swi PARAMS ((char *));
835
836 /* Pseudo Op codes. */
837 static void do_adr PARAMS ((char *));
838 static void do_adrl PARAMS ((char *));
839 static void do_empty PARAMS ((char *));
840
841 /* ARM v2. */
842 static void do_mul PARAMS ((char *));
843 static void do_mla PARAMS ((char *));
844
845 /* ARM v2S. */
846 static void do_swap PARAMS ((char *));
847
848 /* ARM v3. */
849 static void do_msr PARAMS ((char *));
850 static void do_mrs PARAMS ((char *));
851
852 /* ARM v3M. */
853 static void do_mull PARAMS ((char *));
854
855 /* ARM v4. */
856 static void do_ldstv4 PARAMS ((char *));
857
858 /* ARM v4T. */
859 static void do_bx PARAMS ((char *));
860
861 /* ARM v5T. */
862 static void do_blx PARAMS ((char *));
863 static void do_bkpt PARAMS ((char *));
864 static void do_clz PARAMS ((char *));
865 static void do_lstc2 PARAMS ((char *));
866 static void do_cdp2 PARAMS ((char *));
867 static void do_co_reg2 PARAMS ((char *));
868
869 /* ARM v5TExP. */
870 static void do_smla PARAMS ((char *));
871 static void do_smlal PARAMS ((char *));
872 static void do_smul PARAMS ((char *));
873 static void do_qadd PARAMS ((char *));
874
875 /* ARM v5TE. */
876 static void do_pld PARAMS ((char *));
877 static void do_ldrd PARAMS ((char *));
878 static void do_co_reg2c PARAMS ((char *));
879
880 /* ARM v5TEJ. */
881 static void do_bxj PARAMS ((char *));
882
883 /* ARM V6. */
884 static void do_cps PARAMS ((char *));
885 static void do_cpsi PARAMS ((char *));
886 static void do_ldrex PARAMS ((char *));
887 static void do_pkhbt PARAMS ((char *));
888 static void do_pkhtb PARAMS ((char *));
889 static void do_qadd16 PARAMS ((char *));
890 static void do_rev PARAMS ((char *));
891 static void do_rfe PARAMS ((char *));
892 static void do_sxtah PARAMS ((char *));
893 static void do_sxth PARAMS ((char *));
894 static void do_setend PARAMS ((char *));
895 static void do_smlad PARAMS ((char *));
896 static void do_smlald PARAMS ((char *));
897 static void do_smmul PARAMS ((char *));
898 static void do_ssat PARAMS ((char *));
899 static void do_usat PARAMS ((char *));
900 static void do_srs PARAMS ((char *));
901 static void do_ssat16 PARAMS ((char *));
902 static void do_usat16 PARAMS ((char *));
903 static void do_strex PARAMS ((char *));
904 static void do_umaal PARAMS ((char *));
905
906 static void do_cps_mode PARAMS ((char **));
907 static void do_cps_flags PARAMS ((char **, int));
908 static int do_endian_specifier PARAMS ((char *));
909 static void do_pkh_core PARAMS ((char *, int));
910 static void do_sat PARAMS ((char **, int));
911 static void do_sat16 PARAMS ((char **, int));
912
913 /* Coprocessor Instructions. */
914 static void do_cdp PARAMS ((char *));
915 static void do_lstc PARAMS ((char *));
916 static void do_co_reg PARAMS ((char *));
917
918 /* FPA instructions. */
919 static void do_fpa_ctrl PARAMS ((char *));
920 static void do_fpa_ldst PARAMS ((char *));
921 static void do_fpa_ldmstm PARAMS ((char *));
922 static void do_fpa_dyadic PARAMS ((char *));
923 static void do_fpa_monadic PARAMS ((char *));
924 static void do_fpa_cmp PARAMS ((char *));
925 static void do_fpa_from_reg PARAMS ((char *));
926 static void do_fpa_to_reg PARAMS ((char *));
927
928 /* VFP instructions. */
929 static void do_vfp_sp_monadic PARAMS ((char *));
930 static void do_vfp_dp_monadic PARAMS ((char *));
931 static void do_vfp_sp_dyadic PARAMS ((char *));
932 static void do_vfp_dp_dyadic PARAMS ((char *));
933 static void do_vfp_reg_from_sp PARAMS ((char *));
934 static void do_vfp_sp_from_reg PARAMS ((char *));
935 static void do_vfp_reg2_from_sp2 PARAMS ((char *));
936 static void do_vfp_sp2_from_reg2 PARAMS ((char *));
937 static void do_vfp_reg_from_dp PARAMS ((char *));
938 static void do_vfp_reg2_from_dp PARAMS ((char *));
939 static void do_vfp_dp_from_reg PARAMS ((char *));
940 static void do_vfp_dp_from_reg2 PARAMS ((char *));
941 static void do_vfp_reg_from_ctrl PARAMS ((char *));
942 static void do_vfp_ctrl_from_reg PARAMS ((char *));
943 static void do_vfp_sp_ldst PARAMS ((char *));
944 static void do_vfp_dp_ldst PARAMS ((char *));
945 static void do_vfp_sp_ldstmia PARAMS ((char *));
946 static void do_vfp_sp_ldstmdb PARAMS ((char *));
947 static void do_vfp_dp_ldstmia PARAMS ((char *));
948 static void do_vfp_dp_ldstmdb PARAMS ((char *));
949 static void do_vfp_xp_ldstmia PARAMS ((char *));
950 static void do_vfp_xp_ldstmdb PARAMS ((char *));
951 static void do_vfp_sp_compare_z PARAMS ((char *));
952 static void do_vfp_dp_compare_z PARAMS ((char *));
953 static void do_vfp_dp_sp_cvt PARAMS ((char *));
954 static void do_vfp_sp_dp_cvt PARAMS ((char *));
955
956 /* XScale. */
957 static void do_xsc_mia PARAMS ((char *));
958 static void do_xsc_mar PARAMS ((char *));
959 static void do_xsc_mra PARAMS ((char *));
960
961 /* Maverick. */
962 static void do_mav_binops PARAMS ((char *, int, enum arm_reg_type,
963 enum arm_reg_type));
964 static void do_mav_binops_1a PARAMS ((char *));
965 static void do_mav_binops_1b PARAMS ((char *));
966 static void do_mav_binops_1c PARAMS ((char *));
967 static void do_mav_binops_1d PARAMS ((char *));
968 static void do_mav_binops_1e PARAMS ((char *));
969 static void do_mav_binops_1f PARAMS ((char *));
970 static void do_mav_binops_1g PARAMS ((char *));
971 static void do_mav_binops_1h PARAMS ((char *));
972 static void do_mav_binops_1i PARAMS ((char *));
973 static void do_mav_binops_1j PARAMS ((char *));
974 static void do_mav_binops_1k PARAMS ((char *));
975 static void do_mav_binops_1l PARAMS ((char *));
976 static void do_mav_binops_1m PARAMS ((char *));
977 static void do_mav_binops_1n PARAMS ((char *));
978 static void do_mav_binops_1o PARAMS ((char *));
979 static void do_mav_binops_2a PARAMS ((char *));
980 static void do_mav_binops_2b PARAMS ((char *));
981 static void do_mav_binops_2c PARAMS ((char *));
982 static void do_mav_binops_3a PARAMS ((char *));
983 static void do_mav_binops_3b PARAMS ((char *));
984 static void do_mav_binops_3c PARAMS ((char *));
985 static void do_mav_binops_3d PARAMS ((char *));
986 static void do_mav_triple PARAMS ((char *, int, enum arm_reg_type,
987 enum arm_reg_type,
988 enum arm_reg_type));
989 static void do_mav_triple_4a PARAMS ((char *));
990 static void do_mav_triple_4b PARAMS ((char *));
991 static void do_mav_triple_5a PARAMS ((char *));
992 static void do_mav_triple_5b PARAMS ((char *));
993 static void do_mav_triple_5c PARAMS ((char *));
994 static void do_mav_triple_5d PARAMS ((char *));
995 static void do_mav_triple_5e PARAMS ((char *));
996 static void do_mav_triple_5f PARAMS ((char *));
997 static void do_mav_triple_5g PARAMS ((char *));
998 static void do_mav_triple_5h PARAMS ((char *));
999 static void do_mav_quad PARAMS ((char *, int, enum arm_reg_type,
1000 enum arm_reg_type,
1001 enum arm_reg_type,
1002 enum arm_reg_type));
1003 static void do_mav_quad_6a PARAMS ((char *));
1004 static void do_mav_quad_6b PARAMS ((char *));
1005 static void do_mav_dspsc_1 PARAMS ((char *));
1006 static void do_mav_dspsc_2 PARAMS ((char *));
1007 static void do_mav_shift PARAMS ((char *, enum arm_reg_type,
1008 enum arm_reg_type));
1009 static void do_mav_shift_1 PARAMS ((char *));
1010 static void do_mav_shift_2 PARAMS ((char *));
1011 static void do_mav_ldst PARAMS ((char *, enum arm_reg_type));
1012 static void do_mav_ldst_1 PARAMS ((char *));
1013 static void do_mav_ldst_2 PARAMS ((char *));
1014 static void do_mav_ldst_3 PARAMS ((char *));
1015 static void do_mav_ldst_4 PARAMS ((char *));
1016
1017 static int mav_reg_required_here PARAMS ((char **, int,
1018 enum arm_reg_type));
1019 static int mav_parse_offset PARAMS ((char **, int *));
1020
1021 static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *,
1022 int, int));
1023 static int arm_reg_parse PARAMS ((char **, struct hash_control *));
1024 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
1025 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
1026 static void symbol_locate PARAMS ((symbolS *, const char *, segT, valueT,
1027 fragS *));
1028 static int add_to_lit_pool PARAMS ((void));
1029 static unsigned validate_immediate PARAMS ((unsigned));
1030 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
1031 unsigned int *));
1032 static int validate_offset_imm PARAMS ((unsigned int, int));
1033 static void opcode_select PARAMS ((int));
1034 static void end_of_line PARAMS ((char *));
1035 static int reg_required_here PARAMS ((char **, int));
1036 static int psr_required_here PARAMS ((char **));
1037 static int co_proc_number PARAMS ((char **));
1038 static int cp_opc_expr PARAMS ((char **, int, int));
1039 static int cp_reg_required_here PARAMS ((char **, int));
1040 static int fp_reg_required_here PARAMS ((char **, int));
1041 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
1042 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
1043 static void vfp_sp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
1044 static void vfp_dp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
1045 static long vfp_sp_reg_list PARAMS ((char **, enum vfp_sp_reg_pos));
1046 static long vfp_dp_reg_list PARAMS ((char **));
1047 static int vfp_psr_required_here PARAMS ((char **str));
1048 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
1049 static int cp_address_offset PARAMS ((char **));
1050 static int cp_address_required_here PARAMS ((char **, int));
1051 static int my_get_float_expression PARAMS ((char **));
1052 static int skip_past_comma PARAMS ((char **));
1053 static int walk_no_bignums PARAMS ((symbolS *));
1054 static int negate_data_op PARAMS ((unsigned long *, unsigned long));
1055 static int data_op2 PARAMS ((char **));
1056 static int fp_op2 PARAMS ((char **));
1057 static long reg_list PARAMS ((char **));
1058 static void thumb_load_store PARAMS ((char *, int, int));
1059 static int decode_shift PARAMS ((char **, int));
1060 static int ldst_extend PARAMS ((char **));
1061 static int ldst_extend_v4 PARAMS ((char **));
1062 static void thumb_add_sub PARAMS ((char *, int));
1063 static void insert_reg PARAMS ((const struct reg_entry *,
1064 struct hash_control *));
1065 static void thumb_shift PARAMS ((char *, int));
1066 static void thumb_mov_compare PARAMS ((char *, int));
1067 static void build_arm_ops_hsh PARAMS ((void));
1068 static void set_constant_flonums PARAMS ((void));
1069 static valueT md_chars_to_number PARAMS ((char *, int));
1070 static void build_reg_hsh PARAMS ((struct reg_map *));
1071 static void insert_reg_alias PARAMS ((char *, int, struct hash_control *));
1072 static int create_register_alias PARAMS ((char *, char *));
1073 static void output_inst PARAMS ((const char *));
1074 static int accum0_required_here PARAMS ((char **));
1075 static int ld_mode_required_here PARAMS ((char **));
1076 static void do_branch25 PARAMS ((char *));
1077 static symbolS * find_real_start PARAMS ((symbolS *));
1078 #ifdef OBJ_ELF
1079 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
1080 #endif
1081
1082 static int wreg_required_here PARAMS ((char **, int, enum wreg_type));
1083 static void do_iwmmxt_byte_addr PARAMS ((char *));
1084 static void do_iwmmxt_tandc PARAMS ((char *));
1085 static void do_iwmmxt_tbcst PARAMS ((char *));
1086 static void do_iwmmxt_textrc PARAMS ((char *));
1087 static void do_iwmmxt_textrm PARAMS ((char *));
1088 static void do_iwmmxt_tinsr PARAMS ((char *));
1089 static void do_iwmmxt_tmcr PARAMS ((char *));
1090 static void do_iwmmxt_tmcrr PARAMS ((char *));
1091 static void do_iwmmxt_tmia PARAMS ((char *));
1092 static void do_iwmmxt_tmovmsk PARAMS ((char *));
1093 static void do_iwmmxt_tmrc PARAMS ((char *));
1094 static void do_iwmmxt_tmrrc PARAMS ((char *));
1095 static void do_iwmmxt_torc PARAMS ((char *));
1096 static void do_iwmmxt_waligni PARAMS ((char *));
1097 static void do_iwmmxt_wmov PARAMS ((char *));
1098 static void do_iwmmxt_word_addr PARAMS ((char *));
1099 static void do_iwmmxt_wrwr PARAMS ((char *));
1100 static void do_iwmmxt_wrwrwcg PARAMS ((char *));
1101 static void do_iwmmxt_wrwrwr PARAMS ((char *));
1102 static void do_iwmmxt_wshufh PARAMS ((char *));
1103 static void do_iwmmxt_wzero PARAMS ((char *));
1104 static int cp_byte_address_offset PARAMS ((char **));
1105 static int cp_byte_address_required_here PARAMS ((char **));
1106
1107 /* ARM instructions take 4bytes in the object file, Thumb instructions
1108 take 2: */
1109 #define INSN_SIZE 4
1110
1111 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
1112 #define MAV_MODE1 0x100c
1113
1114 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
1115 #define MAV_MODE2 0x0c10
1116
1117 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
1118 #define MAV_MODE3 0x100c
1119
1120 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
1121 #define MAV_MODE4 0x0c0010
1122
1123 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
1124 #define MAV_MODE5 0x00100c
1125
1126 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
1127 #define MAV_MODE6 0x00100c05
1128
1129 struct asm_opcode
1130 {
1131 /* Basic string to match. */
1132 const char * template;
1133
1134 /* Basic instruction code. */
1135 unsigned long value;
1136
1137 /* Offset into the template where the condition code (if any) will be.
1138 If zero, then the instruction is never conditional. */
1139 unsigned cond_offset;
1140
1141 /* Which architecture variant provides this instruction. */
1142 unsigned long variant;
1143
1144 /* Function to call to parse args. */
1145 void (* parms) PARAMS ((char *));
1146 };
1147
1148 static const struct asm_opcode insns[] =
1149 {
1150 /* Core ARM Instructions. */
1151 {"and", 0xe0000000, 3, ARM_EXT_V1, do_arit},
1152 {"ands", 0xe0100000, 3, ARM_EXT_V1, do_arit},
1153 {"eor", 0xe0200000, 3, ARM_EXT_V1, do_arit},
1154 {"eors", 0xe0300000, 3, ARM_EXT_V1, do_arit},
1155 {"sub", 0xe0400000, 3, ARM_EXT_V1, do_arit},
1156 {"subs", 0xe0500000, 3, ARM_EXT_V1, do_arit},
1157 {"rsb", 0xe0600000, 3, ARM_EXT_V1, do_arit},
1158 {"rsbs", 0xe0700000, 3, ARM_EXT_V1, do_arit},
1159 {"add", 0xe0800000, 3, ARM_EXT_V1, do_arit},
1160 {"adds", 0xe0900000, 3, ARM_EXT_V1, do_arit},
1161 {"adc", 0xe0a00000, 3, ARM_EXT_V1, do_arit},
1162 {"adcs", 0xe0b00000, 3, ARM_EXT_V1, do_arit},
1163 {"sbc", 0xe0c00000, 3, ARM_EXT_V1, do_arit},
1164 {"sbcs", 0xe0d00000, 3, ARM_EXT_V1, do_arit},
1165 {"rsc", 0xe0e00000, 3, ARM_EXT_V1, do_arit},
1166 {"rscs", 0xe0f00000, 3, ARM_EXT_V1, do_arit},
1167 {"orr", 0xe1800000, 3, ARM_EXT_V1, do_arit},
1168 {"orrs", 0xe1900000, 3, ARM_EXT_V1, do_arit},
1169 {"bic", 0xe1c00000, 3, ARM_EXT_V1, do_arit},
1170 {"bics", 0xe1d00000, 3, ARM_EXT_V1, do_arit},
1171
1172 {"tst", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
1173 {"tsts", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
1174 {"tstp", 0xe110f000, 3, ARM_EXT_V1, do_cmp},
1175 {"teq", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
1176 {"teqs", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
1177 {"teqp", 0xe130f000, 3, ARM_EXT_V1, do_cmp},
1178 {"cmp", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
1179 {"cmps", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
1180 {"cmpp", 0xe150f000, 3, ARM_EXT_V1, do_cmp},
1181 {"cmn", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
1182 {"cmns", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
1183 {"cmnp", 0xe170f000, 3, ARM_EXT_V1, do_cmp},
1184
1185 {"mov", 0xe1a00000, 3, ARM_EXT_V1, do_mov},
1186 {"movs", 0xe1b00000, 3, ARM_EXT_V1, do_mov},
1187 {"mvn", 0xe1e00000, 3, ARM_EXT_V1, do_mov},
1188 {"mvns", 0xe1f00000, 3, ARM_EXT_V1, do_mov},
1189
1190 {"ldr", 0xe4100000, 3, ARM_EXT_V1, do_ldst},
1191 {"ldrb", 0xe4500000, 3, ARM_EXT_V1, do_ldst},
1192 {"ldrt", 0xe4300000, 3, ARM_EXT_V1, do_ldstt},
1193 {"ldrbt", 0xe4700000, 3, ARM_EXT_V1, do_ldstt},
1194 {"str", 0xe4000000, 3, ARM_EXT_V1, do_ldst},
1195 {"strb", 0xe4400000, 3, ARM_EXT_V1, do_ldst},
1196 {"strt", 0xe4200000, 3, ARM_EXT_V1, do_ldstt},
1197 {"strbt", 0xe4600000, 3, ARM_EXT_V1, do_ldstt},
1198
1199 {"stmia", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
1200 {"stmib", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
1201 {"stmda", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
1202 {"stmdb", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
1203 {"stmfd", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
1204 {"stmfa", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
1205 {"stmea", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
1206 {"stmed", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
1207
1208 {"ldmia", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
1209 {"ldmib", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
1210 {"ldmda", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
1211 {"ldmdb", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
1212 {"ldmfd", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
1213 {"ldmfa", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
1214 {"ldmea", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
1215 {"ldmed", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
1216
1217 {"swi", 0xef000000, 3, ARM_EXT_V1, do_swi},
1218 #ifdef TE_WINCE
1219 /* XXX This is the wrong place to do this. Think multi-arch. */
1220 {"bl", 0xeb000000, 2, ARM_EXT_V1, do_branch},
1221 {"b", 0xea000000, 1, ARM_EXT_V1, do_branch},
1222 #else
1223 {"bl", 0xebfffffe, 2, ARM_EXT_V1, do_branch},
1224 {"b", 0xeafffffe, 1, ARM_EXT_V1, do_branch},
1225 #endif
1226
1227 /* Pseudo ops. */
1228 {"adr", 0xe28f0000, 3, ARM_EXT_V1, do_adr},
1229 {"adrl", 0xe28f0000, 3, ARM_EXT_V1, do_adrl},
1230 {"nop", 0xe1a00000, 3, ARM_EXT_V1, do_empty},
1231
1232 /* ARM 2 multiplies. */
1233 {"mul", 0xe0000090, 3, ARM_EXT_V2, do_mul},
1234 {"muls", 0xe0100090, 3, ARM_EXT_V2, do_mul},
1235 {"mla", 0xe0200090, 3, ARM_EXT_V2, do_mla},
1236 {"mlas", 0xe0300090, 3, ARM_EXT_V2, do_mla},
1237
1238 /* Generic coprocessor instructions. */
1239 {"cdp", 0xee000000, 3, ARM_EXT_V2, do_cdp},
1240 {"ldc", 0xec100000, 3, ARM_EXT_V2, do_lstc},
1241 {"ldcl", 0xec500000, 3, ARM_EXT_V2, do_lstc},
1242 {"stc", 0xec000000, 3, ARM_EXT_V2, do_lstc},
1243 {"stcl", 0xec400000, 3, ARM_EXT_V2, do_lstc},
1244 {"mcr", 0xee000010, 3, ARM_EXT_V2, do_co_reg},
1245 {"mrc", 0xee100010, 3, ARM_EXT_V2, do_co_reg},
1246
1247 /* ARM 3 - swp instructions. */
1248 {"swp", 0xe1000090, 3, ARM_EXT_V2S, do_swap},
1249 {"swpb", 0xe1400090, 3, ARM_EXT_V2S, do_swap},
1250
1251 /* ARM 6 Status register instructions. */
1252 {"mrs", 0xe10f0000, 3, ARM_EXT_V3, do_mrs},
1253 {"msr", 0xe120f000, 3, ARM_EXT_V3, do_msr},
1254 /* ScottB: our code uses 0xe128f000 for msr.
1255 NickC: but this is wrong because the bits 16 through 19 are
1256 handled by the PSR_xxx defines above. */
1257
1258 /* ARM 7M long multiplies. */
1259 {"smull", 0xe0c00090, 5, ARM_EXT_V3M, do_mull},
1260 {"smulls", 0xe0d00090, 5, ARM_EXT_V3M, do_mull},
1261 {"umull", 0xe0800090, 5, ARM_EXT_V3M, do_mull},
1262 {"umulls", 0xe0900090, 5, ARM_EXT_V3M, do_mull},
1263 {"smlal", 0xe0e00090, 5, ARM_EXT_V3M, do_mull},
1264 {"smlals", 0xe0f00090, 5, ARM_EXT_V3M, do_mull},
1265 {"umlal", 0xe0a00090, 5, ARM_EXT_V3M, do_mull},
1266 {"umlals", 0xe0b00090, 5, ARM_EXT_V3M, do_mull},
1267
1268 /* ARM Architecture 4. */
1269 {"ldrh", 0xe01000b0, 3, ARM_EXT_V4, do_ldstv4},
1270 {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4, do_ldstv4},
1271 {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4, do_ldstv4},
1272 {"strh", 0xe00000b0, 3, ARM_EXT_V4, do_ldstv4},
1273
1274 /* ARM Architecture 4T. */
1275 /* Note: bx (and blx) are required on V5, even if the processor does
1276 not support Thumb. */
1277 {"bx", 0xe12fff10, 2, ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1278
1279 /* ARM Architecture 5T. */
1280 /* Note: blx has 2 variants, so the .value is set dynamically.
1281 Only one of the variants has conditional execution. */
1282 {"blx", 0xe0000000, 3, ARM_EXT_V5, do_blx},
1283 {"clz", 0xe16f0f10, 3, ARM_EXT_V5, do_clz},
1284 {"bkpt", 0xe1200070, 0, ARM_EXT_V5, do_bkpt},
1285 {"ldc2", 0xfc100000, 0, ARM_EXT_V5, do_lstc2},
1286 {"ldc2l", 0xfc500000, 0, ARM_EXT_V5, do_lstc2},
1287 {"stc2", 0xfc000000, 0, ARM_EXT_V5, do_lstc2},
1288 {"stc2l", 0xfc400000, 0, ARM_EXT_V5, do_lstc2},
1289 {"cdp2", 0xfe000000, 0, ARM_EXT_V5, do_cdp2},
1290 {"mcr2", 0xfe000010, 0, ARM_EXT_V5, do_co_reg2},
1291 {"mrc2", 0xfe100010, 0, ARM_EXT_V5, do_co_reg2},
1292
1293 /* ARM Architecture 5TExP. */
1294 {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP, do_smla},
1295 {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP, do_smla},
1296 {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP, do_smla},
1297 {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP, do_smla},
1298
1299 {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP, do_smla},
1300 {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP, do_smla},
1301
1302 {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP, do_smlal},
1303 {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP, do_smlal},
1304 {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP, do_smlal},
1305 {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP, do_smlal},
1306
1307 {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP, do_smul},
1308 {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP, do_smul},
1309 {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP, do_smul},
1310 {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP, do_smul},
1311
1312 {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP, do_smul},
1313 {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP, do_smul},
1314
1315 {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP, do_qadd},
1316 {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP, do_qadd},
1317 {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP, do_qadd},
1318 {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP, do_qadd},
1319
1320 /* ARM Architecture 5TE. */
1321 {"pld", 0xf450f000, 0, ARM_EXT_V5E, do_pld},
1322 {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E, do_ldrd},
1323 {"strd", 0xe00000f0, 3, ARM_EXT_V5E, do_ldrd},
1324
1325 {"mcrr", 0xec400000, 4, ARM_EXT_V5E, do_co_reg2c},
1326 {"mrrc", 0xec500000, 4, ARM_EXT_V5E, do_co_reg2c},
1327
1328 /* ARM Architecture 5TEJ. */
1329 {"bxj", 0xe12fff20, 3, ARM_EXT_V5J, do_bxj},
1330
1331 /* ARM V6. */
1332 { "cps", 0xf1020000, 0, ARM_EXT_V6, do_cps},
1333 { "cpsie", 0xf1080000, 0, ARM_EXT_V6, do_cpsi},
1334 { "cpsid", 0xf10C0000, 0, ARM_EXT_V6, do_cpsi},
1335 { "ldrex", 0xe1900f9f, 5, ARM_EXT_V6, do_ldrex},
1336 { "mcrr2", 0xfc400000, 0, ARM_EXT_V6, do_co_reg2c},
1337 { "mrrc2", 0xfc500000, 0, ARM_EXT_V6, do_co_reg2c},
1338 { "pkhbt", 0xe6800010, 5, ARM_EXT_V6, do_pkhbt},
1339 { "pkhtb", 0xe6800050, 5, ARM_EXT_V6, do_pkhtb},
1340 { "qadd16", 0xe6200f10, 6, ARM_EXT_V6, do_qadd16},
1341 { "qadd8", 0xe6200f90, 5, ARM_EXT_V6, do_qadd16},
1342 { "qaddsubx", 0xe6200f30, 8, ARM_EXT_V6, do_qadd16},
1343 { "qsub16", 0xe6200f70, 6, ARM_EXT_V6, do_qadd16},
1344 { "qsub8", 0xe6200ff0, 5, ARM_EXT_V6, do_qadd16},
1345 { "qsubaddx", 0xe6200f50, 8, ARM_EXT_V6, do_qadd16},
1346 { "sadd16", 0xe6100f10, 6, ARM_EXT_V6, do_qadd16},
1347 { "sadd8", 0xe6100f90, 5, ARM_EXT_V6, do_qadd16},
1348 { "saddsubx", 0xe6100f30, 8, ARM_EXT_V6, do_qadd16},
1349 { "shadd16", 0xe6300f10, 7, ARM_EXT_V6, do_qadd16},
1350 { "shadd8", 0xe6300f90, 6, ARM_EXT_V6, do_qadd16},
1351 { "shaddsubx", 0xe6300f30, 9, ARM_EXT_V6, do_qadd16},
1352 { "shsub16", 0xe6300f70, 7, ARM_EXT_V6, do_qadd16},
1353 { "shsub8", 0xe6300ff0, 6, ARM_EXT_V6, do_qadd16},
1354 { "shsubaddx", 0xe6300f50, 9, ARM_EXT_V6, do_qadd16},
1355 { "ssub16", 0xe6100f70, 6, ARM_EXT_V6, do_qadd16},
1356 { "ssub8", 0xe6100ff0, 5, ARM_EXT_V6, do_qadd16},
1357 { "ssubaddx", 0xe6100f50, 8, ARM_EXT_V6, do_qadd16},
1358 { "uadd16", 0xe6500f10, 6, ARM_EXT_V6, do_qadd16},
1359 { "uadd8", 0xe6500f90, 5, ARM_EXT_V6, do_qadd16},
1360 { "uaddsubx", 0xe6500f30, 8, ARM_EXT_V6, do_qadd16},
1361 { "uhadd16", 0xe6700f10, 7, ARM_EXT_V6, do_qadd16},
1362 { "uhadd8", 0xe6700f90, 6, ARM_EXT_V6, do_qadd16},
1363 { "uhaddsubx", 0xe6700f30, 9, ARM_EXT_V6, do_qadd16},
1364 { "uhsub16", 0xe6700f70, 7, ARM_EXT_V6, do_qadd16},
1365 { "uhsub8", 0xe6700ff0, 6, ARM_EXT_V6, do_qadd16},
1366 { "uhsubaddx", 0xe6700f50, 9, ARM_EXT_V6, do_qadd16},
1367 { "uqadd16", 0xe6600f10, 7, ARM_EXT_V6, do_qadd16},
1368 { "uqadd8", 0xe6600f90, 6, ARM_EXT_V6, do_qadd16},
1369 { "uqaddsubx", 0xe6600f30, 9, ARM_EXT_V6, do_qadd16},
1370 { "uqsub16", 0xe6600f70, 7, ARM_EXT_V6, do_qadd16},
1371 { "uqsub8", 0xe6600ff0, 6, ARM_EXT_V6, do_qadd16},
1372 { "uqsubaddx", 0xe6600f50, 9, ARM_EXT_V6, do_qadd16},
1373 { "usub16", 0xe6500f70, 6, ARM_EXT_V6, do_qadd16},
1374 { "usub8", 0xe6500ff0, 5, ARM_EXT_V6, do_qadd16},
1375 { "usubaddx", 0xe6500f50, 8, ARM_EXT_V6, do_qadd16},
1376 { "rev", 0xe6bf0f30, 3, ARM_EXT_V6, do_rev},
1377 { "rev16", 0xe6bf0fb0, 5, ARM_EXT_V6, do_rev},
1378 { "revsh", 0xe6ff0fb0, 5, ARM_EXT_V6, do_rev},
1379 { "rfeia", 0xf8900a00, 0, ARM_EXT_V6, do_rfe},
1380 { "rfeib", 0xf9900a00, 0, ARM_EXT_V6, do_rfe},
1381 { "rfeda", 0xf8100a00, 0, ARM_EXT_V6, do_rfe},
1382 { "rfedb", 0xf9100a00, 0, ARM_EXT_V6, do_rfe},
1383 { "rfefd", 0xf8900a00, 0, ARM_EXT_V6, do_rfe},
1384 { "rfefa", 0xf9900a00, 0, ARM_EXT_V6, do_rfe},
1385 { "rfeea", 0xf8100a00, 0, ARM_EXT_V6, do_rfe},
1386 { "rfeed", 0xf9100a00, 0, ARM_EXT_V6, do_rfe},
1387 { "sxtah", 0xe6b00070, 5, ARM_EXT_V6, do_sxtah},
1388 { "sxtab16", 0xe6800070, 7, ARM_EXT_V6, do_sxtah},
1389 { "sxtab", 0xe6a00070, 5, ARM_EXT_V6, do_sxtah},
1390 { "sxth", 0xe6bf0070, 4, ARM_EXT_V6, do_sxth},
1391 { "sxtb16", 0xe68f0070, 6, ARM_EXT_V6, do_sxth},
1392 { "sxtb", 0xe6af0070, 4, ARM_EXT_V6, do_sxth},
1393 { "uxtah", 0xe6f00070, 5, ARM_EXT_V6, do_sxtah},
1394 { "uxtab16", 0xe6c00070, 7, ARM_EXT_V6, do_sxtah},
1395 { "uxtab", 0xe6e00070, 5, ARM_EXT_V6, do_sxtah},
1396 { "uxth", 0xe6ff0070, 4, ARM_EXT_V6, do_sxth},
1397 { "uxtb16", 0xe6cf0070, 6, ARM_EXT_V6, do_sxth},
1398 { "uxtb", 0xe6ef0070, 4, ARM_EXT_V6, do_sxth},
1399 { "sel", 0xe68000b0, 3, ARM_EXT_V6, do_qadd16},
1400 { "setend", 0xf1010000, 0, ARM_EXT_V6, do_setend},
1401 { "smlad", 0xe7000010, 5, ARM_EXT_V6, do_smlad},
1402 { "smladx", 0xe7000030, 6, ARM_EXT_V6, do_smlad},
1403 { "smlald", 0xe7400010, 6, ARM_EXT_V6, do_smlald},
1404 { "smlaldx", 0xe7400030, 7, ARM_EXT_V6, do_smlald},
1405 { "smlsd", 0xe7000050, 5, ARM_EXT_V6, do_smlad},
1406 { "smlsdx", 0xe7000070, 6, ARM_EXT_V6, do_smlad},
1407 { "smlsld", 0xe7400050, 6, ARM_EXT_V6, do_smlald},
1408 { "smlsldx", 0xe7400070, 7, ARM_EXT_V6, do_smlald},
1409 { "smmla", 0xe7500010, 5, ARM_EXT_V6, do_smlad},
1410 { "smmlar", 0xe7500030, 6, ARM_EXT_V6, do_smlad},
1411 { "smmls", 0xe75000d0, 5, ARM_EXT_V6, do_smlad},
1412 { "smmlsr", 0xe75000f0, 6, ARM_EXT_V6, do_smlad},
1413 { "smmul", 0xe750f010, 5, ARM_EXT_V6, do_smmul},
1414 { "smmulr", 0xe750f030, 6, ARM_EXT_V6, do_smmul},
1415 { "smuad", 0xe700f010, 5, ARM_EXT_V6, do_smmul},
1416 { "smuadx", 0xe700f030, 6, ARM_EXT_V6, do_smmul},
1417 { "smusd", 0xe700f050, 5, ARM_EXT_V6, do_smmul},
1418 { "smusdx", 0xe700f070, 6, ARM_EXT_V6, do_smmul},
1419 { "srsia", 0xf8cd0500, 0, ARM_EXT_V6, do_srs},
1420 { "srsib", 0xf9cd0500, 0, ARM_EXT_V6, do_srs},
1421 { "srsda", 0xf84d0500, 0, ARM_EXT_V6, do_srs},
1422 { "srsdb", 0xf94d0500, 0, ARM_EXT_V6, do_srs},
1423 { "ssat", 0xe6a00010, 4, ARM_EXT_V6, do_ssat},
1424 { "ssat16", 0xe6a00f30, 6, ARM_EXT_V6, do_ssat16},
1425 { "strex", 0xe1800f90, 5, ARM_EXT_V6, do_strex},
1426 { "umaal", 0xe0400090, 5, ARM_EXT_V6, do_umaal},
1427 { "usad8", 0xe780f010, 5, ARM_EXT_V6, do_smmul},
1428 { "usada8", 0xe7800010, 6, ARM_EXT_V6, do_smlad},
1429 { "usat", 0xe6e00010, 4, ARM_EXT_V6, do_usat},
1430 { "usat16", 0xe6e00f30, 6, ARM_EXT_V6, do_usat16},
1431
1432 /* Core FPA instruction set (V1). */
1433 {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1434 {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1435 {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1436 {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1437
1438 {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1439 {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1440 {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1441 {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1442
1443 {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1444 {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1445 {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1446 {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1447
1448 {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1449 {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1450 {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1451 {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1452 {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1453 {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1454 {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1455 {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1456 {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1457 {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1458 {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1459 {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1460
1461 {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1462 {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1463 {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1464 {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1465 {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1466 {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1467 {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1468 {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1469 {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1470 {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1471 {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1472 {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1473
1474 {"abss", 0xee208100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1475 {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1476 {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1477 {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1478 {"absd", 0xee208180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1479 {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1480 {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1481 {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1482 {"abse", 0xee288100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1483 {"absep", 0xee288120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1484 {"absem", 0xee288140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1485 {"absez", 0xee288160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1486
1487 {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1488 {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1489 {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1490 {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1491 {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1492 {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1493 {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1494 {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1495 {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1496 {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1497 {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1498 {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1499
1500 {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1501 {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1502 {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1503 {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1504 {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1505 {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1506 {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1507 {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1508 {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1509 {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1510 {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1511 {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1512
1513 {"logs", 0xee508100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1514 {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1515 {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1516 {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1517 {"logd", 0xee508180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1518 {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1519 {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1520 {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1521 {"loge", 0xee588100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1522 {"logep", 0xee588120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1523 {"logem", 0xee588140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1524 {"logez", 0xee588160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1525
1526 {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1527 {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1528 {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1529 {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1530 {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1531 {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1532 {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1533 {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1534 {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1535 {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1536 {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1537 {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1538
1539 {"exps", 0xee708100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1540 {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1541 {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1542 {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1543 {"expd", 0xee708180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1544 {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1545 {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1546 {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1547 {"expe", 0xee788100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1548 {"expep", 0xee788120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1549 {"expem", 0xee788140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1550 {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1551
1552 {"sins", 0xee808100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1553 {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1554 {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1555 {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1556 {"sind", 0xee808180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1557 {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1558 {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1559 {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1560 {"sine", 0xee888100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1561 {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1562 {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1563 {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1564
1565 {"coss", 0xee908100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1566 {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1567 {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1568 {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1569 {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1570 {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1571 {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1572 {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1573 {"cose", 0xee988100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1574 {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1575 {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1576 {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1577
1578 {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1579 {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1580 {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1581 {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1582 {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1583 {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1584 {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1585 {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1586 {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1587 {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1588 {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1589 {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1590
1591 {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1592 {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1593 {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1594 {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1595 {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1596 {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1597 {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1598 {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1599 {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1600 {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1601 {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1602 {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1603
1604 {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1605 {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1606 {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1607 {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1608 {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1609 {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1610 {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1611 {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1612 {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1613 {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1614 {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1615 {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1616
1617 {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1618 {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1619 {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1620 {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1621 {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1622 {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1623 {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1624 {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1625 {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1626 {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1627 {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1628 {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1629
1630 {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1631 {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1632 {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1633 {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1634 {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1635 {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1636 {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1637 {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1638 {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1639 {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1640 {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1641 {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1642
1643 {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1644 {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1645 {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1646 {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1647 {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1648 {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1649 {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1650 {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1651 {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1652 {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1653 {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1654 {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1655
1656 {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1657 {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1658 {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1659 {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1660 {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1661 {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1662 {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1663 {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1664 {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1665 {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1666 {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1667 {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1668
1669 {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1670 {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1671 {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1672 {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1673 {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1674 {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1675 {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1676 {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1677 {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1678 {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1679 {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1680 {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1681
1682 {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1683 {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1684 {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1685 {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1686 {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1687 {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1688 {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1689 {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1690 {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1691 {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1692 {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1693 {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1694
1695 {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1696 {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1697 {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1698 {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1699 {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1700 {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1701 {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1702 {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1703 {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1704 {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1705 {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1706 {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1707
1708 {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1709 {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1710 {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1711 {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1712 {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1713 {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1714 {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1715 {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1716 {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1717 {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1718 {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1719 {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1720
1721 {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1722 {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1723 {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1724 {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1725 {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1726 {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1727 {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1728 {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1729 {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1730 {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1731 {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1732 {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1733
1734 {"pows", 0xee600100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1735 {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1736 {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1737 {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1738 {"powd", 0xee600180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1739 {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1740 {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1741 {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1742 {"powe", 0xee680100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1743 {"powep", 0xee680120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1744 {"powem", 0xee680140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1745 {"powez", 0xee680160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1746
1747 {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1748 {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1749 {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1750 {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1751 {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1752 {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1753 {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1754 {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1755 {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1756 {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1757 {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1758 {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1759
1760 {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1761 {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1762 {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1763 {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1764 {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1765 {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1766 {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1767 {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1768 {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1769 {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1770 {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1771 {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1772
1773 {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1774 {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1775 {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1776 {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1777 {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1778 {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1779 {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1780 {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1781 {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1782 {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1783 {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1784 {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1785
1786 {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1787 {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1788 {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1789 {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1790 {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1791 {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1792 {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1793 {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1794 {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1795 {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1796 {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1797 {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1798
1799 {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1800 {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1801 {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1802 {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1803 {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1804 {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1805 {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1806 {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1807 {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1808 {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1809 {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1810 {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1811
1812 {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1813 {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1814 {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1815 {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1816 {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1817 {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1818 {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1819 {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1820 {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1821 {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1822 {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1823 {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1824
1825 {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1826 {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1827 {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1828 {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1829 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1830 not be an optional suffix, but part of the instruction. To be
1831 compatible, we accept either. */
1832 {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
1833 {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
1834
1835 {"flts", 0xee000110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1836 {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1837 {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1838 {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1839 {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1840 {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1841 {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1842 {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1843 {"flte", 0xee080110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1844 {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1845 {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1846 {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1847
1848 /* The implementation of the FIX instruction is broken on some
1849 assemblers, in that it accepts a precision specifier as well as a
1850 rounding specifier, despite the fact that this is meaningless.
1851 To be more compatible, we accept it as well, though of course it
1852 does not set any bits. */
1853 {"fix", 0xee100110, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1854 {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1855 {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1856 {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1857 {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1858 {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1859 {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1860 {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1861 {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1862 {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1863 {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1864 {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1865 {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1866
1867 /* Instructions that were new with the real FPA, call them V2. */
1868 {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1869 {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1870 {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1871 {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1872 {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1873 {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1874
1875 /* VFP V1xD (single precision). */
1876 /* Moves and type conversions. */
1877 {"fcpys", 0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1878 {"fmrs", 0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1879 {"fmsr", 0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1880 {"fmstat", 0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1881 {"fsitos", 0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1882 {"fuitos", 0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1883 {"ftosis", 0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1884 {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1885 {"ftouis", 0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1886 {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1887 {"fmrx", 0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1888 {"fmxr", 0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1889
1890 /* Memory operations. */
1891 {"flds", 0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1892 {"fsts", 0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1893 {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1894 {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1895 {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1896 {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1897 {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1898 {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1899 {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1900 {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1901 {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1902 {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1903 {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1904 {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1905 {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1906 {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1907 {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1908 {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1909
1910 /* Monadic operations. */
1911 {"fabss", 0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1912 {"fnegs", 0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1913 {"fsqrts", 0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1914
1915 /* Dyadic operations. */
1916 {"fadds", 0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1917 {"fsubs", 0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1918 {"fmuls", 0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1919 {"fdivs", 0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1920 {"fmacs", 0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1921 {"fmscs", 0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1922 {"fnmuls", 0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1923 {"fnmacs", 0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1924 {"fnmscs", 0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1925
1926 /* Comparisons. */
1927 {"fcmps", 0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1928 {"fcmpzs", 0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1929 {"fcmpes", 0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1930 {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1931
1932 /* VFP V1 (Double precision). */
1933 /* Moves and type conversions. */
1934 {"fcpyd", 0xeeb00b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1935 {"fcvtds", 0xeeb70ac0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1936 {"fcvtsd", 0xeeb70bc0, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1937 {"fmdhr", 0xee200b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
1938 {"fmdlr", 0xee000b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
1939 {"fmrdh", 0xee300b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
1940 {"fmrdl", 0xee100b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
1941 {"fsitod", 0xeeb80bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1942 {"fuitod", 0xeeb80b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1943 {"ftosid", 0xeebd0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1944 {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1945 {"ftouid", 0xeebc0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1946 {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1947
1948 /* Memory operations. */
1949 {"fldd", 0xed100b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
1950 {"fstd", 0xed000b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
1951 {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1952 {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1953 {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1954 {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1955 {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1956 {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1957 {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1958 {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1959
1960 /* Monadic operations. */
1961 {"fabsd", 0xeeb00bc0, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1962 {"fnegd", 0xeeb10b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1963 {"fsqrtd", 0xeeb10bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1964
1965 /* Dyadic operations. */
1966 {"faddd", 0xee300b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1967 {"fsubd", 0xee300b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1968 {"fmuld", 0xee200b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1969 {"fdivd", 0xee800b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1970 {"fmacd", 0xee000b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1971 {"fmscd", 0xee100b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1972 {"fnmuld", 0xee200b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1973 {"fnmacd", 0xee000b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1974 {"fnmscd", 0xee100b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1975
1976 /* Comparisons. */
1977 {"fcmpd", 0xeeb40b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1978 {"fcmpzd", 0xeeb50b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
1979 {"fcmped", 0xeeb40bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1980 {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
1981
1982 /* VFP V2. */
1983 {"fmsrr", 0xec400a10, 5, FPU_VFP_EXT_V2, do_vfp_sp2_from_reg2},
1984 {"fmrrs", 0xec500a10, 5, FPU_VFP_EXT_V2, do_vfp_reg2_from_sp2},
1985 {"fmdrr", 0xec400b10, 5, FPU_VFP_EXT_V2, do_vfp_dp_from_reg2},
1986 {"fmrrd", 0xec500b10, 5, FPU_VFP_EXT_V2, do_vfp_reg2_from_dp},
1987
1988 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
1989 {"mia", 0xee200010, 3, ARM_CEXT_XSCALE, do_xsc_mia},
1990 {"miaph", 0xee280010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1991 {"miabb", 0xee2c0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1992 {"miabt", 0xee2d0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1993 {"miatb", 0xee2e0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1994 {"miatt", 0xee2f0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1995 {"mar", 0xec400000, 3, ARM_CEXT_XSCALE, do_xsc_mar},
1996 {"mra", 0xec500000, 3, ARM_CEXT_XSCALE, do_xsc_mra},
1997
1998 /* Intel Wireless MMX technology instructions. */
1999 {"tandcb", 0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2000 {"tandch", 0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2001 {"tandcw", 0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
2002 {"tbcstb", 0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2003 {"tbcsth", 0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2004 {"tbcstw", 0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
2005 {"textrcb", 0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2006 {"textrch", 0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2007 {"textrcw", 0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
2008 {"textrmub", 0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2009 {"textrmuh", 0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2010 {"textrmuw", 0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2011 {"textrmsb", 0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2012 {"textrmsh", 0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2013 {"textrmsw", 0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
2014 {"tinsrb", 0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2015 {"tinsrh", 0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2016 {"tinsrw", 0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
2017 {"tmcr", 0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
2018 {"tmcrr", 0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
2019 {"tmia", 0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2020 {"tmiaph", 0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2021 {"tmiabb", 0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2022 {"tmiabt", 0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2023 {"tmiatb", 0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2024 {"tmiatt", 0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
2025 {"tmovmskb", 0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2026 {"tmovmskh", 0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2027 {"tmovmskw", 0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
2028 {"tmrc", 0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
2029 {"tmrrc", 0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
2030 {"torcb", 0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2031 {"torch", 0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2032 {"torcw", 0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
2033 {"waccb", 0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2034 {"wacch", 0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2035 {"waccw", 0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2036 {"waddbss", 0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2037 {"waddb", 0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2038 {"waddbus", 0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2039 {"waddhss", 0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2040 {"waddh", 0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2041 {"waddhus", 0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2042 {"waddwss", 0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2043 {"waddw", 0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2044 {"waddwus", 0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2045 {"waligni", 0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
2046 {"walignr0", 0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2047 {"walignr1", 0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2048 {"walignr2", 0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2049 {"walignr3", 0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2050 {"wand", 0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2051 {"wandn", 0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2052 {"wavg2b", 0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2053 {"wavg2br", 0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2054 {"wavg2h", 0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2055 {"wavg2hr", 0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2056 {"wcmpeqb", 0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2057 {"wcmpeqh", 0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2058 {"wcmpeqw", 0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2059 {"wcmpgtub", 0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2060 {"wcmpgtuh", 0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2061 {"wcmpgtuw", 0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2062 {"wcmpgtsb", 0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2063 {"wcmpgtsh", 0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2064 {"wcmpgtsw", 0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2065 {"wldrb", 0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2066 {"wldrh", 0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2067 {"wldrw", 0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2068 {"wldrd", 0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2069 {"wmacs", 0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2070 {"wmacsz", 0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2071 {"wmacu", 0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2072 {"wmacuz", 0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2073 {"wmadds", 0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2074 {"wmaddu", 0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2075 {"wmaxsb", 0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2076 {"wmaxsh", 0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2077 {"wmaxsw", 0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2078 {"wmaxub", 0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2079 {"wmaxuh", 0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2080 {"wmaxuw", 0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2081 {"wminsb", 0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2082 {"wminsh", 0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2083 {"wminsw", 0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2084 {"wminub", 0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2085 {"wminuh", 0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2086 {"wminuw", 0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2087 {"wmov", 0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
2088 {"wmulsm", 0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2089 {"wmulsl", 0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2090 {"wmulum", 0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2091 {"wmulul", 0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2092 {"wor", 0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2093 {"wpackhss", 0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2094 {"wpackhus", 0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2095 {"wpackwss", 0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2096 {"wpackwus", 0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2097 {"wpackdss", 0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2098 {"wpackdus", 0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2099 {"wrorh", 0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2100 {"wrorhg", 0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2101 {"wrorw", 0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2102 {"wrorwg", 0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2103 {"wrord", 0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2104 {"wrordg", 0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2105 {"wsadb", 0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2106 {"wsadbz", 0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2107 {"wsadh", 0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2108 {"wsadhz", 0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2109 {"wshufh", 0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
2110 {"wsllh", 0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2111 {"wsllhg", 0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2112 {"wsllw", 0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2113 {"wsllwg", 0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2114 {"wslld", 0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2115 {"wslldg", 0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2116 {"wsrah", 0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2117 {"wsrahg", 0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2118 {"wsraw", 0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2119 {"wsrawg", 0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2120 {"wsrad", 0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2121 {"wsradg", 0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2122 {"wsrlh", 0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2123 {"wsrlhg", 0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2124 {"wsrlw", 0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2125 {"wsrlwg", 0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2126 {"wsrld", 0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2127 {"wsrldg", 0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
2128 {"wstrb", 0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2129 {"wstrh", 0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
2130 {"wstrw", 0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2131 {"wstrd", 0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
2132 {"wsubbss", 0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2133 {"wsubb", 0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2134 {"wsubbus", 0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2135 {"wsubhss", 0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2136 {"wsubh", 0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2137 {"wsubhus", 0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2138 {"wsubwss", 0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2139 {"wsubw", 0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2140 {"wsubwus", 0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2141 {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2142 {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2143 {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2144 {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2145 {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2146 {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2147 {"wunpckihb", 0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2148 {"wunpckihh", 0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2149 {"wunpckihw", 0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2150 {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2151 {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2152 {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2153 {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2154 {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2155 {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
2156 {"wunpckilb", 0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2157 {"wunpckilh", 0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2158 {"wunpckilw", 0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2159 {"wxor", 0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
2160 {"wzero", 0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
2161
2162 /* Cirrus Maverick instructions. */
2163 {"cfldrs", 0xec100400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
2164 {"cfldrd", 0xec500400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
2165 {"cfldr32", 0xec100500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_3},
2166 {"cfldr64", 0xec500500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_4},
2167 {"cfstrs", 0xec000400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
2168 {"cfstrd", 0xec400400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
2169 {"cfstr32", 0xec000500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_3},
2170 {"cfstr64", 0xec400500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_4},
2171 {"cfmvsr", 0xee000450, 6, ARM_CEXT_MAVERICK, do_mav_binops_2a},
2172 {"cfmvrs", 0xee100450, 6, ARM_CEXT_MAVERICK, do_mav_binops_1a},
2173 {"cfmvdlr", 0xee000410, 7, ARM_CEXT_MAVERICK, do_mav_binops_2b},
2174 {"cfmvrdl", 0xee100410, 7, ARM_CEXT_MAVERICK, do_mav_binops_1b},
2175 {"cfmvdhr", 0xee000430, 7, ARM_CEXT_MAVERICK, do_mav_binops_2b},
2176 {"cfmvrdh", 0xee100430, 7, ARM_CEXT_MAVERICK, do_mav_binops_1b},
2177 {"cfmv64lr", 0xee000510, 8, ARM_CEXT_MAVERICK, do_mav_binops_2c},
2178 {"cfmvr64l", 0xee100510, 8, ARM_CEXT_MAVERICK, do_mav_binops_1c},
2179 {"cfmv64hr", 0xee000530, 8, ARM_CEXT_MAVERICK, do_mav_binops_2c},
2180 {"cfmvr64h", 0xee100530, 8, ARM_CEXT_MAVERICK, do_mav_binops_1c},
2181 {"cfmval32", 0xee200440, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2182 {"cfmv32al", 0xee100440, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2183 {"cfmvam32", 0xee200460, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2184 {"cfmv32am", 0xee100460, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2185 {"cfmvah32", 0xee200480, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2186 {"cfmv32ah", 0xee100480, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2187 {"cfmva32", 0xee2004a0, 7, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2188 {"cfmv32a", 0xee1004a0, 7, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2189 {"cfmva64", 0xee2004c0, 7, ARM_CEXT_MAVERICK, do_mav_binops_3c},
2190 {"cfmv64a", 0xee1004c0, 7, ARM_CEXT_MAVERICK, do_mav_binops_3d},
2191 {"cfmvsc32", 0xee2004e0, 8, ARM_CEXT_MAVERICK, do_mav_dspsc_1},
2192 {"cfmv32sc", 0xee1004e0, 8, ARM_CEXT_MAVERICK, do_mav_dspsc_2},
2193 {"cfcpys", 0xee000400, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
2194 {"cfcpyd", 0xee000420, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
2195 {"cfcvtsd", 0xee000460, 7, ARM_CEXT_MAVERICK, do_mav_binops_1f},
2196 {"cfcvtds", 0xee000440, 7, ARM_CEXT_MAVERICK, do_mav_binops_1g},
2197 {"cfcvt32s", 0xee000480, 8, ARM_CEXT_MAVERICK, do_mav_binops_1h},
2198 {"cfcvt32d", 0xee0004a0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1i},
2199 {"cfcvt64s", 0xee0004c0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1j},
2200 {"cfcvt64d", 0xee0004e0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1k},
2201 {"cfcvts32", 0xee100580, 8, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2202 {"cfcvtd32", 0xee1005a0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2203 {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2204 {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2205 {"cfrshl32", 0xee000550, 8, ARM_CEXT_MAVERICK, do_mav_triple_4a},
2206 {"cfrshl64", 0xee000570, 8, ARM_CEXT_MAVERICK, do_mav_triple_4b},
2207 {"cfsh32", 0xee000500, 6, ARM_CEXT_MAVERICK, do_mav_shift_1},
2208 {"cfsh64", 0xee200500, 6, ARM_CEXT_MAVERICK, do_mav_shift_2},
2209 {"cfcmps", 0xee100490, 6, ARM_CEXT_MAVERICK, do_mav_triple_5a},
2210 {"cfcmpd", 0xee1004b0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5b},
2211 {"cfcmp32", 0xee100590, 7, ARM_CEXT_MAVERICK, do_mav_triple_5c},
2212 {"cfcmp64", 0xee1005b0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5d},
2213 {"cfabss", 0xee300400, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
2214 {"cfabsd", 0xee300420, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
2215 {"cfnegs", 0xee300440, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
2216 {"cfnegd", 0xee300460, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
2217 {"cfadds", 0xee300480, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
2218 {"cfaddd", 0xee3004a0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
2219 {"cfsubs", 0xee3004c0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
2220 {"cfsubd", 0xee3004e0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
2221 {"cfmuls", 0xee100400, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
2222 {"cfmuld", 0xee100420, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
2223 {"cfabs32", 0xee300500, 7, ARM_CEXT_MAVERICK, do_mav_binops_1n},
2224 {"cfabs64", 0xee300520, 7, ARM_CEXT_MAVERICK, do_mav_binops_1o},
2225 {"cfneg32", 0xee300540, 7, ARM_CEXT_MAVERICK, do_mav_binops_1n},
2226 {"cfneg64", 0xee300560, 7, ARM_CEXT_MAVERICK, do_mav_binops_1o},
2227 {"cfadd32", 0xee300580, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2228 {"cfadd64", 0xee3005a0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
2229 {"cfsub32", 0xee3005c0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2230 {"cfsub64", 0xee3005e0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
2231 {"cfmul32", 0xee100500, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2232 {"cfmul64", 0xee100520, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
2233 {"cfmac32", 0xee100540, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2234 {"cfmsc32", 0xee100560, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2235 {"cfmadd32", 0xee000600, 8, ARM_CEXT_MAVERICK, do_mav_quad_6a},
2236 {"cfmsub32", 0xee100600, 8, ARM_CEXT_MAVERICK, do_mav_quad_6a},
2237 {"cfmadda32", 0xee200600, 9, ARM_CEXT_MAVERICK, do_mav_quad_6b},
2238 {"cfmsuba32", 0xee300600, 9, ARM_CEXT_MAVERICK, do_mav_quad_6b},
2239 };
2240
2241 /* Defines for various bits that we will want to toggle. */
2242 #define INST_IMMEDIATE 0x02000000
2243 #define OFFSET_REG 0x02000000
2244 #define HWOFFSET_IMM 0x00400000
2245 #define SHIFT_BY_REG 0x00000010
2246 #define PRE_INDEX 0x01000000
2247 #define INDEX_UP 0x00800000
2248 #define WRITE_BACK 0x00200000
2249 #define LDM_TYPE_2_OR_3 0x00400000
2250
2251 #define LITERAL_MASK 0xf000f000
2252 #define OPCODE_MASK 0xfe1fffff
2253 #define V4_STR_BIT 0x00000020
2254
2255 #define DATA_OP_SHIFT 21
2256
2257 /* Codes to distinguish the arithmetic instructions. */
2258 #define OPCODE_AND 0
2259 #define OPCODE_EOR 1
2260 #define OPCODE_SUB 2
2261 #define OPCODE_RSB 3
2262 #define OPCODE_ADD 4
2263 #define OPCODE_ADC 5
2264 #define OPCODE_SBC 6
2265 #define OPCODE_RSC 7
2266 #define OPCODE_TST 8
2267 #define OPCODE_TEQ 9
2268 #define OPCODE_CMP 10
2269 #define OPCODE_CMN 11
2270 #define OPCODE_ORR 12
2271 #define OPCODE_MOV 13
2272 #define OPCODE_BIC 14
2273 #define OPCODE_MVN 15
2274
2275 /* Thumb v1 (ARMv4T). */
2276 static void do_t_nop PARAMS ((char *));
2277 static void do_t_arit PARAMS ((char *));
2278 static void do_t_add PARAMS ((char *));
2279 static void do_t_asr PARAMS ((char *));
2280 static void do_t_branch9 PARAMS ((char *));
2281 static void do_t_branch12 PARAMS ((char *));
2282 static void do_t_branch23 PARAMS ((char *));
2283 static void do_t_bx PARAMS ((char *));
2284 static void do_t_compare PARAMS ((char *));
2285 static void do_t_ldmstm PARAMS ((char *));
2286 static void do_t_ldr PARAMS ((char *));
2287 static void do_t_ldrb PARAMS ((char *));
2288 static void do_t_ldrh PARAMS ((char *));
2289 static void do_t_lds PARAMS ((char *));
2290 static void do_t_lsl PARAMS ((char *));
2291 static void do_t_lsr PARAMS ((char *));
2292 static void do_t_mov PARAMS ((char *));
2293 static void do_t_push_pop PARAMS ((char *));
2294 static void do_t_str PARAMS ((char *));
2295 static void do_t_strb PARAMS ((char *));
2296 static void do_t_strh PARAMS ((char *));
2297 static void do_t_sub PARAMS ((char *));
2298 static void do_t_swi PARAMS ((char *));
2299 static void do_t_adr PARAMS ((char *));
2300
2301 /* Thumb v2 (ARMv5T). */
2302 static void do_t_blx PARAMS ((char *));
2303 static void do_t_bkpt PARAMS ((char *));
2304
2305 /* ARM V6. */
2306 static void do_t_cps PARAMS ((char *));
2307 static void do_t_cpy PARAMS ((char *));
2308 static void do_t_setend PARAMS ((char *));;
2309
2310 #define T_OPCODE_MUL 0x4340
2311 #define T_OPCODE_TST 0x4200
2312 #define T_OPCODE_CMN 0x42c0
2313 #define T_OPCODE_NEG 0x4240
2314 #define T_OPCODE_MVN 0x43c0
2315
2316 #define T_OPCODE_ADD_R3 0x1800
2317 #define T_OPCODE_SUB_R3 0x1a00
2318 #define T_OPCODE_ADD_HI 0x4400
2319 #define T_OPCODE_ADD_ST 0xb000
2320 #define T_OPCODE_SUB_ST 0xb080
2321 #define T_OPCODE_ADD_SP 0xa800
2322 #define T_OPCODE_ADD_PC 0xa000
2323 #define T_OPCODE_ADD_I8 0x3000
2324 #define T_OPCODE_SUB_I8 0x3800
2325 #define T_OPCODE_ADD_I3 0x1c00
2326 #define T_OPCODE_SUB_I3 0x1e00
2327
2328 #define T_OPCODE_ASR_R 0x4100
2329 #define T_OPCODE_LSL_R 0x4080
2330 #define T_OPCODE_LSR_R 0x40c0
2331 #define T_OPCODE_ASR_I 0x1000
2332 #define T_OPCODE_LSL_I 0x0000
2333 #define T_OPCODE_LSR_I 0x0800
2334
2335 #define T_OPCODE_MOV_I8 0x2000
2336 #define T_OPCODE_CMP_I8 0x2800
2337 #define T_OPCODE_CMP_LR 0x4280
2338 #define T_OPCODE_MOV_HR 0x4600
2339 #define T_OPCODE_CMP_HR 0x4500
2340
2341 #define T_OPCODE_LDR_PC 0x4800
2342 #define T_OPCODE_LDR_SP 0x9800
2343 #define T_OPCODE_STR_SP 0x9000
2344 #define T_OPCODE_LDR_IW 0x6800
2345 #define T_OPCODE_STR_IW 0x6000
2346 #define T_OPCODE_LDR_IH 0x8800
2347 #define T_OPCODE_STR_IH 0x8000
2348 #define T_OPCODE_LDR_IB 0x7800
2349 #define T_OPCODE_STR_IB 0x7000
2350 #define T_OPCODE_LDR_RW 0x5800
2351 #define T_OPCODE_STR_RW 0x5000
2352 #define T_OPCODE_LDR_RH 0x5a00
2353 #define T_OPCODE_STR_RH 0x5200
2354 #define T_OPCODE_LDR_RB 0x5c00
2355 #define T_OPCODE_STR_RB 0x5400
2356
2357 #define T_OPCODE_PUSH 0xb400
2358 #define T_OPCODE_POP 0xbc00
2359
2360 #define T_OPCODE_BRANCH 0xe7fe
2361
2362 static int thumb_reg PARAMS ((char ** str, int hi_lo));
2363
2364 #define THUMB_SIZE 2 /* Size of thumb instruction. */
2365 #define THUMB_REG_LO 0x1
2366 #define THUMB_REG_HI 0x2
2367 #define THUMB_REG_ANY 0x3
2368
2369 #define THUMB_H1 0x0080
2370 #define THUMB_H2 0x0040
2371
2372 #define THUMB_ASR 0
2373 #define THUMB_LSL 1
2374 #define THUMB_LSR 2
2375
2376 #define THUMB_MOVE 0
2377 #define THUMB_COMPARE 1
2378 #define THUMB_CPY 2
2379
2380 #define THUMB_LOAD 0
2381 #define THUMB_STORE 1
2382
2383 #define THUMB_PP_PC_LR 0x0100
2384
2385 /* These three are used for immediate shifts, do not alter. */
2386 #define THUMB_WORD 2
2387 #define THUMB_HALFWORD 1
2388 #define THUMB_BYTE 0
2389
2390 struct thumb_opcode
2391 {
2392 /* Basic string to match. */
2393 const char * template;
2394
2395 /* Basic instruction code. */
2396 unsigned long value;
2397
2398 int size;
2399
2400 /* Which CPU variants this exists for. */
2401 unsigned long variant;
2402
2403 /* Function to call to parse args. */
2404 void (* parms) PARAMS ((char *));
2405 };
2406
2407 static const struct thumb_opcode tinsns[] =
2408 {
2409 /* Thumb v1 (ARMv4T). */
2410 {"adc", 0x4140, 2, ARM_EXT_V4T, do_t_arit},
2411 {"add", 0x0000, 2, ARM_EXT_V4T, do_t_add},
2412 {"and", 0x4000, 2, ARM_EXT_V4T, do_t_arit},
2413 {"asr", 0x0000, 2, ARM_EXT_V4T, do_t_asr},
2414 {"b", T_OPCODE_BRANCH, 2, ARM_EXT_V4T, do_t_branch12},
2415 {"beq", 0xd0fe, 2, ARM_EXT_V4T, do_t_branch9},
2416 {"bne", 0xd1fe, 2, ARM_EXT_V4T, do_t_branch9},
2417 {"bcs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
2418 {"bhs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
2419 {"bcc", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
2420 {"bul", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
2421 {"blo", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
2422 {"bmi", 0xd4fe, 2, ARM_EXT_V4T, do_t_branch9},
2423 {"bpl", 0xd5fe, 2, ARM_EXT_V4T, do_t_branch9},
2424 {"bvs", 0xd6fe, 2, ARM_EXT_V4T, do_t_branch9},
2425 {"bvc", 0xd7fe, 2, ARM_EXT_V4T, do_t_branch9},
2426 {"bhi", 0xd8fe, 2, ARM_EXT_V4T, do_t_branch9},
2427 {"bls", 0xd9fe, 2, ARM_EXT_V4T, do_t_branch9},
2428 {"bge", 0xdafe, 2, ARM_EXT_V4T, do_t_branch9},
2429 {"blt", 0xdbfe, 2, ARM_EXT_V4T, do_t_branch9},
2430 {"bgt", 0xdcfe, 2, ARM_EXT_V4T, do_t_branch9},
2431 {"ble", 0xddfe, 2, ARM_EXT_V4T, do_t_branch9},
2432 {"bal", 0xdefe, 2, ARM_EXT_V4T, do_t_branch9},
2433 {"bic", 0x4380, 2, ARM_EXT_V4T, do_t_arit},
2434 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T, do_t_branch23},
2435 {"bx", 0x4700, 2, ARM_EXT_V4T, do_t_bx},
2436 {"cmn", T_OPCODE_CMN, 2, ARM_EXT_V4T, do_t_arit},
2437 {"cmp", 0x0000, 2, ARM_EXT_V4T, do_t_compare},
2438 {"eor", 0x4040, 2, ARM_EXT_V4T, do_t_arit},
2439 {"ldmia", 0xc800, 2, ARM_EXT_V4T, do_t_ldmstm},
2440 {"ldr", 0x0000, 2, ARM_EXT_V4T, do_t_ldr},
2441 {"ldrb", 0x0000, 2, ARM_EXT_V4T, do_t_ldrb},
2442 {"ldrh", 0x0000, 2, ARM_EXT_V4T, do_t_ldrh},
2443 {"ldrsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
2444 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
2445 {"ldsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
2446 {"ldsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
2447 {"lsl", 0x0000, 2, ARM_EXT_V4T, do_t_lsl},
2448 {"lsr", 0x0000, 2, ARM_EXT_V4T, do_t_lsr},
2449 {"mov", 0x0000, 2, ARM_EXT_V4T, do_t_mov},
2450 {"mul", T_OPCODE_MUL, 2, ARM_EXT_V4T, do_t_arit},
2451 {"mvn", T_OPCODE_MVN, 2, ARM_EXT_V4T, do_t_arit},
2452 {"neg", T_OPCODE_NEG, 2, ARM_EXT_V4T, do_t_arit},
2453 {"orr", 0x4300, 2, ARM_EXT_V4T, do_t_arit},
2454 {"pop", 0xbc00, 2, ARM_EXT_V4T, do_t_push_pop},
2455 {"push", 0xb400, 2, ARM_EXT_V4T, do_t_push_pop},
2456 {"ror", 0x41c0, 2, ARM_EXT_V4T, do_t_arit},
2457 {"sbc", 0x4180, 2, ARM_EXT_V4T, do_t_arit},
2458 {"stmia", 0xc000, 2, ARM_EXT_V4T, do_t_ldmstm},
2459 {"str", 0x0000, 2, ARM_EXT_V4T, do_t_str},
2460 {"strb", 0x0000, 2, ARM_EXT_V4T, do_t_strb},
2461 {"strh", 0x0000, 2, ARM_EXT_V4T, do_t_strh},
2462 {"swi", 0xdf00, 2, ARM_EXT_V4T, do_t_swi},
2463 {"sub", 0x0000, 2, ARM_EXT_V4T, do_t_sub},
2464 {"tst", T_OPCODE_TST, 2, ARM_EXT_V4T, do_t_arit},
2465 /* Pseudo ops: */
2466 {"adr", 0x0000, 2, ARM_EXT_V4T, do_t_adr},
2467 {"nop", 0x46C0, 2, ARM_EXT_V4T, do_t_nop}, /* mov r8,r8 */
2468 /* Thumb v2 (ARMv5T). */
2469 {"blx", 0, 0, ARM_EXT_V5T, do_t_blx},
2470 {"bkpt", 0xbe00, 2, ARM_EXT_V5T, do_t_bkpt},
2471
2472 /* ARM V6. */
2473 {"cpsie", 0xb660, 2, ARM_EXT_V6, do_t_cps},
2474 {"cpsid", 0xb670, 2, ARM_EXT_V6, do_t_cps},
2475 {"cpy", 0x4600, 2, ARM_EXT_V6, do_t_cpy},
2476 {"rev", 0xba00, 2, ARM_EXT_V6, do_t_arit},
2477 {"rev16", 0xba40, 2, ARM_EXT_V6, do_t_arit},
2478 {"revsh", 0xbac0, 2, ARM_EXT_V6, do_t_arit},
2479 {"setend", 0xb650, 2, ARM_EXT_V6, do_t_setend},
2480 {"sxth", 0xb200, 2, ARM_EXT_V6, do_t_arit},
2481 {"sxtb", 0xb240, 2, ARM_EXT_V6, do_t_arit},
2482 {"uxth", 0xb280, 2, ARM_EXT_V6, do_t_arit},
2483 {"uxtb", 0xb2c0, 2, ARM_EXT_V6, do_t_arit},
2484 };
2485
2486 #define BAD_ARGS _("bad arguments to instruction")
2487 #define BAD_PC _("r15 not allowed here")
2488 #define BAD_COND _("instruction is not conditional")
2489 #define ERR_NO_ACCUM _("acc0 expected")
2490
2491 static struct hash_control * arm_ops_hsh = NULL;
2492 static struct hash_control * arm_tops_hsh = NULL;
2493 static struct hash_control * arm_cond_hsh = NULL;
2494 static struct hash_control * arm_shift_hsh = NULL;
2495 static struct hash_control * arm_psr_hsh = NULL;
2496
2497 /* This table describes all the machine specific pseudo-ops the assembler
2498 has to support. The fields are:
2499 pseudo-op name without dot
2500 function to call to execute this pseudo-op
2501 Integer arg to pass to the function. */
2502
2503 static void s_req PARAMS ((int));
2504 static void s_unreq PARAMS ((int));
2505 static void s_align PARAMS ((int));
2506 static void s_bss PARAMS ((int));
2507 static void s_even PARAMS ((int));
2508 static void s_ltorg PARAMS ((int));
2509 static void s_arm PARAMS ((int));
2510 static void s_thumb PARAMS ((int));
2511 static void s_code PARAMS ((int));
2512 static void s_force_thumb PARAMS ((int));
2513 static void s_thumb_func PARAMS ((int));
2514 static void s_thumb_set PARAMS ((int));
2515 #ifdef OBJ_ELF
2516 static void s_arm_elf_cons PARAMS ((int));
2517 #endif
2518
2519 static int my_get_expression PARAMS ((expressionS *, char **));
2520
2521 const pseudo_typeS md_pseudo_table[] =
2522 {
2523 /* Never called because '.req' does not start a line. */
2524 { "req", s_req, 0 },
2525 { "unreq", s_unreq, 0 },
2526 { "bss", s_bss, 0 },
2527 { "align", s_align, 0 },
2528 { "arm", s_arm, 0 },
2529 { "thumb", s_thumb, 0 },
2530 { "code", s_code, 0 },
2531 { "force_thumb", s_force_thumb, 0 },
2532 { "thumb_func", s_thumb_func, 0 },
2533 { "thumb_set", s_thumb_set, 0 },
2534 { "even", s_even, 0 },
2535 { "ltorg", s_ltorg, 0 },
2536 { "pool", s_ltorg, 0 },
2537 #ifdef OBJ_ELF
2538 { "word", s_arm_elf_cons, 4 },
2539 { "long", s_arm_elf_cons, 4 },
2540 #else
2541 { "word", cons, 4},
2542 #endif
2543 { "extend", float_cons, 'x' },
2544 { "ldouble", float_cons, 'x' },
2545 { "packed", float_cons, 'p' },
2546 { 0, 0, 0 }
2547 };
2548
2549 /* Other internal functions. */
2550 static int arm_parse_extension PARAMS ((char *, int *));
2551 static int arm_parse_cpu PARAMS ((char *));
2552 static int arm_parse_arch PARAMS ((char *));
2553 static int arm_parse_fpu PARAMS ((char *));
2554 static int arm_parse_float_abi PARAMS ((char *));
2555 static int arm_parse_eabi PARAMS ((char *));
2556 #if 0 /* Suppressed - for now. */
2557 #if defined OBJ_COFF || defined OBJ_ELF
2558 static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
2559 #endif
2560 #endif
2561
2562 /* Stuff needed to resolve the label ambiguity
2563 As:
2564 ...
2565 label: <insn>
2566 may differ from:
2567 ...
2568 label:
2569 <insn>
2570 */
2571
2572 symbolS * last_label_seen;
2573 static int label_is_thumb_function_name = FALSE;
2574
2575 /* Literal Pool stuff. */
2576
2577 #define MAX_LITERAL_POOL_SIZE 1024
2578
2579 /* Literal pool structure. Held on a per-section
2580 and per-sub-section basis. */
2581 typedef struct literal_pool
2582 {
2583 expressionS literals [MAX_LITERAL_POOL_SIZE];
2584 unsigned int next_free_entry;
2585 unsigned int id;
2586 symbolS * symbol;
2587 segT section;
2588 subsegT sub_section;
2589 struct literal_pool * next;
2590 } literal_pool;
2591
2592 /* Pointer to a linked list of literal pools. */
2593 literal_pool * list_of_pools = NULL;
2594
2595 static literal_pool * find_literal_pool PARAMS ((void));
2596 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2597
2598 static literal_pool *
2599 find_literal_pool ()
2600 {
2601 literal_pool * pool;
2602
2603 for (pool = list_of_pools; pool != NULL; pool = pool->next)
2604 {
2605 if (pool->section == now_seg
2606 && pool->sub_section == now_subseg)
2607 break;
2608 }
2609
2610 return pool;
2611 }
2612
2613 static literal_pool *
2614 find_or_make_literal_pool ()
2615 {
2616 /* Next literal pool ID number. */
2617 static unsigned int latest_pool_num = 1;
2618 literal_pool * pool;
2619
2620 pool = find_literal_pool ();
2621
2622 if (pool == NULL)
2623 {
2624 /* Create a new pool. */
2625 pool = (literal_pool *) xmalloc (sizeof (* pool));
2626 if (! pool)
2627 return NULL;
2628
2629 pool->next_free_entry = 0;
2630 pool->section = now_seg;
2631 pool->sub_section = now_subseg;
2632 pool->next = list_of_pools;
2633 pool->symbol = NULL;
2634
2635 /* Add it to the list. */
2636 list_of_pools = pool;
2637 }
2638
2639 /* New pools, and emptied pools, will have a NULL symbol. */
2640 if (pool->symbol == NULL)
2641 {
2642 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2643 (valueT) 0, &zero_address_frag);
2644 pool->id = latest_pool_num ++;
2645 }
2646
2647 /* Done. */
2648 return pool;
2649 }
2650
2651 /* Add the literal in the global 'inst'
2652 structure to the relevent literal pool. */
2653 static int
2654 add_to_lit_pool ()
2655 {
2656 literal_pool * pool;
2657 unsigned int entry;
2658
2659 pool = find_or_make_literal_pool ();
2660
2661 /* Check if this literal value is already in the pool. */
2662 for (entry = 0; entry < pool->next_free_entry; entry ++)
2663 {
2664 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2665 && (inst.reloc.exp.X_op == O_constant)
2666 && (pool->literals[entry].X_add_number
2667 == inst.reloc.exp.X_add_number)
2668 && (pool->literals[entry].X_unsigned
2669 == inst.reloc.exp.X_unsigned))
2670 break;
2671
2672 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2673 && (inst.reloc.exp.X_op == O_symbol)
2674 && (pool->literals[entry].X_add_number
2675 == inst.reloc.exp.X_add_number)
2676 && (pool->literals[entry].X_add_symbol
2677 == inst.reloc.exp.X_add_symbol)
2678 && (pool->literals[entry].X_op_symbol
2679 == inst.reloc.exp.X_op_symbol))
2680 break;
2681 }
2682
2683 /* Do we need to create a new entry? */
2684 if (entry == pool->next_free_entry)
2685 {
2686 if (entry >= MAX_LITERAL_POOL_SIZE)
2687 {
2688 inst.error = _("literal pool overflow");
2689 return FAIL;
2690 }
2691
2692 pool->literals[entry] = inst.reloc.exp;
2693 pool->next_free_entry += 1;
2694 }
2695
2696 inst.reloc.exp.X_op = O_symbol;
2697 inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2698 inst.reloc.exp.X_add_symbol = pool->symbol;
2699
2700 return SUCCESS;
2701 }
2702
2703 /* Can't use symbol_new here, so have to create a symbol and then at
2704 a later date assign it a value. Thats what these functions do. */
2705
2706 static void
2707 symbol_locate (symbolP, name, segment, valu, frag)
2708 symbolS * symbolP;
2709 const char * name; /* It is copied, the caller can modify. */
2710 segT segment; /* Segment identifier (SEG_<something>). */
2711 valueT valu; /* Symbol value. */
2712 fragS * frag; /* Associated fragment. */
2713 {
2714 unsigned int name_length;
2715 char * preserved_copy_of_name;
2716
2717 name_length = strlen (name) + 1; /* +1 for \0. */
2718 obstack_grow (&notes, name, name_length);
2719 preserved_copy_of_name = obstack_finish (&notes);
2720 #ifdef STRIP_UNDERSCORE
2721 if (preserved_copy_of_name[0] == '_')
2722 preserved_copy_of_name++;
2723 #endif
2724
2725 #ifdef tc_canonicalize_symbol_name
2726 preserved_copy_of_name =
2727 tc_canonicalize_symbol_name (preserved_copy_of_name);
2728 #endif
2729
2730 S_SET_NAME (symbolP, preserved_copy_of_name);
2731
2732 S_SET_SEGMENT (symbolP, segment);
2733 S_SET_VALUE (symbolP, valu);
2734 symbol_clear_list_pointers (symbolP);
2735
2736 symbol_set_frag (symbolP, frag);
2737
2738 /* Link to end of symbol chain. */
2739 {
2740 extern int symbol_table_frozen;
2741 if (symbol_table_frozen)
2742 abort ();
2743 }
2744
2745 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2746
2747 obj_symbol_new_hook (symbolP);
2748
2749 #ifdef tc_symbol_new_hook
2750 tc_symbol_new_hook (symbolP);
2751 #endif
2752
2753 #ifdef DEBUG_SYMS
2754 verify_symbol_chain (symbol_rootP, symbol_lastP);
2755 #endif /* DEBUG_SYMS */
2756 }
2757
2758 /* Check that an immediate is valid.
2759 If so, convert it to the right format. */
2760
2761 static unsigned int
2762 validate_immediate (val)
2763 unsigned int val;
2764 {
2765 unsigned int a;
2766 unsigned int i;
2767
2768 #define rotate_left(v, n) (v << n | v >> (32 - n))
2769
2770 for (i = 0; i < 32; i += 2)
2771 if ((a = rotate_left (val, i)) <= 0xff)
2772 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
2773
2774 return FAIL;
2775 }
2776
2777 /* Check to see if an immediate can be computed as two separate immediate
2778 values, added together. We already know that this value cannot be
2779 computed by just one ARM instruction. */
2780
2781 static unsigned int
2782 validate_immediate_twopart (val, highpart)
2783 unsigned int val;
2784 unsigned int * highpart;
2785 {
2786 unsigned int a;
2787 unsigned int i;
2788
2789 for (i = 0; i < 32; i += 2)
2790 if (((a = rotate_left (val, i)) & 0xff) != 0)
2791 {
2792 if (a & 0xff00)
2793 {
2794 if (a & ~ 0xffff)
2795 continue;
2796 * highpart = (a >> 8) | ((i + 24) << 7);
2797 }
2798 else if (a & 0xff0000)
2799 {
2800 if (a & 0xff000000)
2801 continue;
2802 * highpart = (a >> 16) | ((i + 16) << 7);
2803 }
2804 else
2805 {
2806 assert (a & 0xff000000);
2807 * highpart = (a >> 24) | ((i + 8) << 7);
2808 }
2809
2810 return (a & 0xff) | (i << 7);
2811 }
2812
2813 return FAIL;
2814 }
2815
2816 static int
2817 validate_offset_imm (val, hwse)
2818 unsigned int val;
2819 int hwse;
2820 {
2821 if ((hwse && val > 255) || val > 4095)
2822 return FAIL;
2823 return val;
2824 }
2825
2826 \f
2827 #ifdef OBJ_ELF
2828 enum mstate
2829 {
2830 MAP_DATA,
2831 MAP_ARM,
2832 MAP_THUMB
2833 };
2834
2835 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
2836 (This text is taken from version B-02 of the spec):
2837
2838 4.4.7 Mapping and tagging symbols
2839
2840 A section of an ARM ELF file can contain a mixture of ARM code,
2841 Thumb code, and data. There are inline transitions between code
2842 and data at literal pool boundaries. There can also be inline
2843 transitions between ARM code and Thumb code, for example in
2844 ARM-Thumb inter-working veneers. Linkers, machine-level
2845 debuggers, profiling tools, and disassembly tools need to map
2846 images accurately. For example, setting an ARM breakpoint on a
2847 Thumb location, or in a literal pool, can crash the program
2848 being debugged, ruining the debugging session.
2849
2850 ARM ELF entities are mapped (see section 4.4.7.1 below) and
2851 tagged (see section 4.4.7.2 below) using local symbols (with
2852 binding STB_LOCAL). To assist consumers, mapping and tagging
2853 symbols should be collated first in the symbol table, before
2854 other symbols with binding STB_LOCAL.
2855
2856 To allow properly collated mapping and tagging symbols to be
2857 skipped by consumers that have no interest in them, the first
2858 such symbol should have the name $m and its st_value field equal
2859 to the total number of mapping and tagging symbols (including
2860 the $m) in the symbol table.
2861
2862 4.4.7.1 Mapping symbols
2863
2864 $a Labels the first byte of a sequence of ARM instructions.
2865 Its type is STT_FUNC.
2866
2867 $d Labels the first byte of a sequence of data items.
2868 Its type is STT_OBJECT.
2869
2870 $t Labels the first byte of a sequence of Thumb instructions.
2871 Its type is STT_FUNC.
2872
2873 This list of mapping symbols may be extended in the future.
2874
2875 Section-relative mapping symbols
2876
2877 Mapping symbols defined in a section define a sequence of
2878 half-open address intervals that cover the address range of the
2879 section. Each interval starts at the address defined by a
2880 mapping symbol, and continues up to, but not including, the
2881 address defined by the next (in address order) mapping symbol or
2882 the end of the section. A corollary is that there must be a
2883 mapping symbol defined at the beginning of each section.
2884 Consumers can ignore the size of a section-relative mapping
2885 symbol. Producers can set it to 0.
2886
2887 Absolute mapping symbols
2888
2889 Because of the need to crystallize a Thumb address with the
2890 Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
2891 STT_FUNC defined in section SHN_ABS) need to be mapped with $a
2892 or $t.
2893
2894 The extent of a mapping symbol defined in SHN_ABS is [st_value,
2895 st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
2896 where [x, y) denotes the half-open address range from x,
2897 inclusive, to y, exclusive.
2898
2899 In the absence of a mapping symbol, a consumer can interpret a
2900 function symbol with an odd value as the Thumb code address
2901 obtained by clearing the least significant bit of the
2902 value. This interpretation is deprecated, and it may not work in
2903 the future.
2904
2905 Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
2906 the EABI (which is still under development), so they are not
2907 implemented here. */
2908
2909 static void
2910 mapping_state (enum mstate state)
2911 {
2912 static enum mstate mapstate = MAP_DATA;
2913 symbolS * symbolP;
2914 const char * symname;
2915 int type;
2916
2917 if (mapstate == state)
2918 /* The mapping symbol has already been emitted.
2919 There is nothing else to do. */
2920 return;
2921
2922 mapstate = state;
2923
2924 switch (state)
2925 {
2926 case MAP_DATA:
2927 symname = "$d";
2928 type = BSF_OBJECT;
2929 break;
2930 case MAP_ARM:
2931 symname = "$a";
2932 type = BSF_FUNCTION;
2933 break;
2934 case MAP_THUMB:
2935 symname = "$t";
2936 type = BSF_FUNCTION;
2937 break;
2938 default:
2939 abort ();
2940 }
2941
2942 symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
2943 symbol_table_insert (symbolP);
2944 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2945
2946 switch (state)
2947 {
2948 case MAP_ARM:
2949 THUMB_SET_FUNC (symbolP, 0);
2950 ARM_SET_THUMB (symbolP, 0);
2951 ARM_SET_INTERWORK (symbolP, support_interwork);
2952 break;
2953
2954 case MAP_THUMB:
2955 THUMB_SET_FUNC (symbolP, 1);
2956 ARM_SET_THUMB (symbolP, 1);
2957 ARM_SET_INTERWORK (symbolP, support_interwork);
2958 break;
2959
2960 case MAP_DATA:
2961 default:
2962 return;
2963 }
2964 }
2965
2966 /* When we change sections we need to issue a new mapping symbol. */
2967
2968 void
2969 arm_elf_change_section (void)
2970 {
2971 flagword flags;
2972
2973 if (!SEG_NORMAL (now_seg))
2974 return;
2975
2976 flags = bfd_get_section_flags (stdoutput, now_seg);
2977
2978 /* We can ignore sections that only contain debug info. */
2979 if ((flags & SEC_ALLOC) == 0)
2980 return;
2981
2982 if (flags & SEC_CODE)
2983 {
2984 if (thumb_mode)
2985 mapping_state (MAP_THUMB);
2986 else
2987 mapping_state (MAP_ARM);
2988 }
2989 else
2990 /* This section does not contain code. Therefore it must contain data. */
2991 mapping_state (MAP_DATA);
2992 }
2993 #else
2994 #define mapping_state(a)
2995 #endif /* OBJ_ELF */
2996 \f
2997
2998 static void
2999 s_req (a)
3000 int a ATTRIBUTE_UNUSED;
3001 {
3002 as_bad (_("invalid syntax for .req directive"));
3003 }
3004
3005 /* The .unreq directive deletes an alias which was previously defined
3006 by .req. For example:
3007
3008 my_alias .req r11
3009 .unreq my_alias */
3010
3011 static void
3012 s_unreq (int a ATTRIBUTE_UNUSED)
3013 {
3014 char *name;
3015 char saved_char;
3016
3017 skip_whitespace (input_line_pointer);
3018 name = input_line_pointer;
3019
3020 while (*input_line_pointer != 0
3021 && *input_line_pointer != ' '
3022 && *input_line_pointer != '\n')
3023 ++input_line_pointer;
3024
3025 saved_char = *input_line_pointer;
3026 *input_line_pointer = 0;
3027
3028 if (*name)
3029 {
3030 enum arm_reg_type req_type = arm_reg_parse_any (name);
3031
3032 if (req_type != REG_TYPE_MAX)
3033 {
3034 char *temp_name = name;
3035 int req_no = arm_reg_parse (&temp_name, all_reg_maps[req_type].htab);
3036
3037 if (req_no != FAIL)
3038 {
3039 struct reg_entry *req_entry;
3040
3041 /* Check to see if this alias is a builtin one. */
3042 req_entry = hash_delete (all_reg_maps[req_type].htab, name);
3043
3044 if (!req_entry)
3045 as_bad (_("unreq: missing hash entry for \"%s\""), name);
3046 else if (req_entry->builtin)
3047 /* FIXME: We are deleting a built in register alias which
3048 points to a const data structure, so we only need to
3049 free up the memory used by the key in the hash table.
3050 Unfortunately we have not recorded this value, so this
3051 is a memory leak. */
3052 /* FIXME: Should we issue a warning message ? */
3053 ;
3054 else
3055 {
3056 /* Deleting a user defined alias. We need to free the
3057 key and the value, but fortunately the key is the same
3058 as the value->name field. */
3059 free ((char *) req_entry->name);
3060 free (req_entry);
3061 }
3062 }
3063 else
3064 as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3065 }
3066 else
3067 as_bad (_(".unreq: unrecognized symbol \"%s\""), name);
3068 }
3069 else
3070 as_bad (_("invalid syntax for .unreq directive"));
3071
3072 *input_line_pointer = saved_char;
3073 demand_empty_rest_of_line ();
3074 }
3075
3076 static void
3077 s_bss (ignore)
3078 int ignore ATTRIBUTE_UNUSED;
3079 {
3080 /* We don't support putting frags in the BSS segment, we fake it by
3081 marking in_bss, then looking at s_skip for clues. */
3082 subseg_set (bss_section, 0);
3083 demand_empty_rest_of_line ();
3084 mapping_state (MAP_DATA);
3085 }
3086
3087 static void
3088 s_even (ignore)
3089 int ignore ATTRIBUTE_UNUSED;
3090 {
3091 /* Never make frag if expect extra pass. */
3092 if (!need_pass_2)
3093 frag_align (1, 0, 0);
3094
3095 record_alignment (now_seg, 1);
3096
3097 demand_empty_rest_of_line ();
3098 }
3099
3100 static void
3101 s_ltorg (ignored)
3102 int ignored ATTRIBUTE_UNUSED;
3103 {
3104 unsigned int entry;
3105 literal_pool * pool;
3106 char sym_name[20];
3107
3108 pool = find_literal_pool ();
3109 if (pool == NULL
3110 || pool->symbol == NULL
3111 || pool->next_free_entry == 0)
3112 return;
3113
3114 /* Align pool as you have word accesses.
3115 Only make a frag if we have to. */
3116 if (!need_pass_2)
3117 frag_align (2, 0, 0);
3118
3119 record_alignment (now_seg, 2);
3120
3121 sprintf (sym_name, "$$lit_\002%x", pool->id);
3122
3123 symbol_locate (pool->symbol, sym_name, now_seg,
3124 (valueT) frag_now_fix (), frag_now);
3125 symbol_table_insert (pool->symbol);
3126
3127 ARM_SET_THUMB (pool->symbol, thumb_mode);
3128
3129 #if defined OBJ_COFF || defined OBJ_ELF
3130 ARM_SET_INTERWORK (pool->symbol, support_interwork);
3131 #endif
3132
3133 for (entry = 0; entry < pool->next_free_entry; entry ++)
3134 /* First output the expression in the instruction to the pool. */
3135 emit_expr (&(pool->literals[entry]), 4); /* .word */
3136
3137 /* Mark the pool as empty. */
3138 pool->next_free_entry = 0;
3139 pool->symbol = NULL;
3140 }
3141
3142 /* Same as s_align_ptwo but align 0 => align 2. */
3143
3144 static void
3145 s_align (unused)
3146 int unused ATTRIBUTE_UNUSED;
3147 {
3148 register int temp;
3149 register long temp_fill;
3150 long max_alignment = 15;
3151
3152 temp = get_absolute_expression ();
3153 if (temp > max_alignment)
3154 as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
3155 else if (temp < 0)
3156 {
3157 as_bad (_("alignment negative. 0 assumed."));
3158 temp = 0;
3159 }
3160
3161 if (*input_line_pointer == ',')
3162 {
3163 input_line_pointer++;
3164 temp_fill = get_absolute_expression ();
3165 }
3166 else
3167 temp_fill = 0;
3168
3169 if (!temp)
3170 temp = 2;
3171
3172 /* Only make a frag if we HAVE to. */
3173 if (temp && !need_pass_2)
3174 frag_align (temp, (int) temp_fill, 0);
3175 demand_empty_rest_of_line ();
3176
3177 record_alignment (now_seg, temp);
3178 }
3179
3180 static void
3181 s_force_thumb (ignore)
3182 int ignore ATTRIBUTE_UNUSED;
3183 {
3184 /* If we are not already in thumb mode go into it, EVEN if
3185 the target processor does not support thumb instructions.
3186 This is used by gcc/config/arm/lib1funcs.asm for example
3187 to compile interworking support functions even if the
3188 target processor should not support interworking. */
3189 if (! thumb_mode)
3190 {
3191 thumb_mode = 2;
3192
3193 record_alignment (now_seg, 1);
3194 }
3195
3196 demand_empty_rest_of_line ();
3197 }
3198
3199 static void
3200 s_thumb_func (ignore)
3201 int ignore ATTRIBUTE_UNUSED;
3202 {
3203 if (! thumb_mode)
3204 opcode_select (16);
3205
3206 /* The following label is the name/address of the start of a Thumb function.
3207 We need to know this for the interworking support. */
3208 label_is_thumb_function_name = TRUE;
3209
3210 demand_empty_rest_of_line ();
3211 }
3212
3213 /* Perform a .set directive, but also mark the alias as
3214 being a thumb function. */
3215
3216 static void
3217 s_thumb_set (equiv)
3218 int equiv;
3219 {
3220 /* XXX the following is a duplicate of the code for s_set() in read.c
3221 We cannot just call that code as we need to get at the symbol that
3222 is created. */
3223 register char * name;
3224 register char delim;
3225 register char * end_name;
3226 register symbolS * symbolP;
3227
3228 /* Especial apologies for the random logic:
3229 This just grew, and could be parsed much more simply!
3230 Dean - in haste. */
3231 name = input_line_pointer;
3232 delim = get_symbol_end ();
3233 end_name = input_line_pointer;
3234 *end_name = delim;
3235
3236 SKIP_WHITESPACE ();
3237
3238 if (*input_line_pointer != ',')
3239 {
3240 *end_name = 0;
3241 as_bad (_("expected comma after name \"%s\""), name);
3242 *end_name = delim;
3243 ignore_rest_of_line ();
3244 return;
3245 }
3246
3247 input_line_pointer++;
3248 *end_name = 0;
3249
3250 if (name[0] == '.' && name[1] == '\0')
3251 {
3252 /* XXX - this should not happen to .thumb_set. */
3253 abort ();
3254 }
3255
3256 if ((symbolP = symbol_find (name)) == NULL
3257 && (symbolP = md_undefined_symbol (name)) == NULL)
3258 {
3259 #ifndef NO_LISTING
3260 /* When doing symbol listings, play games with dummy fragments living
3261 outside the normal fragment chain to record the file and line info
3262 for this symbol. */
3263 if (listing & LISTING_SYMBOLS)
3264 {
3265 extern struct list_info_struct * listing_tail;
3266 fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
3267
3268 memset (dummy_frag, 0, sizeof (fragS));
3269 dummy_frag->fr_type = rs_fill;
3270 dummy_frag->line = listing_tail;
3271 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3272 dummy_frag->fr_symbol = symbolP;
3273 }
3274 else
3275 #endif
3276 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3277
3278 #ifdef OBJ_COFF
3279 /* "set" symbols are local unless otherwise specified. */
3280 SF_SET_LOCAL (symbolP);
3281 #endif /* OBJ_COFF */
3282 } /* Make a new symbol. */
3283
3284 symbol_table_insert (symbolP);
3285
3286 * end_name = delim;
3287
3288 if (equiv
3289 && S_IS_DEFINED (symbolP)
3290 && S_GET_SEGMENT (symbolP) != reg_section)
3291 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3292
3293 pseudo_set (symbolP);
3294
3295 demand_empty_rest_of_line ();
3296
3297 /* XXX Now we come to the Thumb specific bit of code. */
3298
3299 THUMB_SET_FUNC (symbolP, 1);
3300 ARM_SET_THUMB (symbolP, 1);
3301 #if defined OBJ_ELF || defined OBJ_COFF
3302 ARM_SET_INTERWORK (symbolP, support_interwork);
3303 #endif
3304 }
3305
3306 static void
3307 opcode_select (width)
3308 int width;
3309 {
3310 switch (width)
3311 {
3312 case 16:
3313 if (! thumb_mode)
3314 {
3315 if (! (cpu_variant & ARM_EXT_V4T))
3316 as_bad (_("selected processor does not support THUMB opcodes"));
3317
3318 thumb_mode = 1;
3319 /* No need to force the alignment, since we will have been
3320 coming from ARM mode, which is word-aligned. */
3321 record_alignment (now_seg, 1);
3322 }
3323 mapping_state (MAP_THUMB);
3324 break;
3325
3326 case 32:
3327 if (thumb_mode)
3328 {
3329 if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
3330 as_bad (_("selected processor does not support ARM opcodes"));
3331
3332 thumb_mode = 0;
3333
3334 if (!need_pass_2)
3335 frag_align (2, 0, 0);
3336
3337 record_alignment (now_seg, 1);
3338 }
3339 mapping_state (MAP_ARM);
3340 break;
3341
3342 default:
3343 as_bad (_("invalid instruction size selected (%d)"), width);
3344 }
3345 }
3346
3347 static void
3348 s_arm (ignore)
3349 int ignore ATTRIBUTE_UNUSED;
3350 {
3351 opcode_select (32);
3352 demand_empty_rest_of_line ();
3353 }
3354
3355 static void
3356 s_thumb (ignore)
3357 int ignore ATTRIBUTE_UNUSED;
3358 {
3359 opcode_select (16);
3360 demand_empty_rest_of_line ();
3361 }
3362
3363 static void
3364 s_code (unused)
3365 int unused ATTRIBUTE_UNUSED;
3366 {
3367 register int temp;
3368
3369 temp = get_absolute_expression ();
3370 switch (temp)
3371 {
3372 case 16:
3373 case 32:
3374 opcode_select (temp);
3375 break;
3376
3377 default:
3378 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
3379 }
3380 }
3381
3382 static void
3383 end_of_line (str)
3384 char *str;
3385 {
3386 skip_whitespace (str);
3387
3388 if (*str != '\0' && !inst.error)
3389 inst.error = _("garbage following instruction");
3390 }
3391
3392 static int
3393 skip_past_comma (str)
3394 char ** str;
3395 {
3396 char * p = * str, c;
3397 int comma = 0;
3398
3399 while ((c = *p) == ' ' || c == ',')
3400 {
3401 p++;
3402 if (c == ',' && comma++)
3403 return FAIL;
3404 }
3405
3406 if (c == '\0')
3407 return FAIL;
3408
3409 *str = p;
3410 return comma ? SUCCESS : FAIL;
3411 }
3412
3413 /* A standard register must be given at this point.
3414 SHIFT is the place to put it in inst.instruction.
3415 Restores input start point on error.
3416 Returns the reg#, or FAIL. */
3417
3418 static int
3419 reg_required_here (str, shift)
3420 char ** str;
3421 int shift;
3422 {
3423 static char buff [128]; /* XXX */
3424 int reg;
3425 char * start = * str;
3426
3427 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
3428 {
3429 if (shift >= 0)
3430 inst.instruction |= reg << shift;
3431 return reg;
3432 }
3433
3434 /* Restore the start point, we may have got a reg of the wrong class. */
3435 *str = start;
3436
3437 /* In the few cases where we might be able to accept something else
3438 this error can be overridden. */
3439 sprintf (buff, _("register expected, not '%.100s'"), start);
3440 inst.error = buff;
3441
3442 return FAIL;
3443 }
3444
3445 /* A Intel Wireless MMX technology register
3446 must be given at this point.
3447 Shift is the place to put it in inst.instruction.
3448 Restores input start point on err.
3449 Returns the reg#, or FAIL. */
3450
3451 static int
3452 wreg_required_here (str, shift, reg_type)
3453 char ** str;
3454 int shift;
3455 enum wreg_type reg_type;
3456 {
3457 static char buff [128];
3458 int reg;
3459 char * start = *str;
3460
3461 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
3462 {
3463 if (wr_register (reg)
3464 && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
3465 {
3466 if (shift >= 0)
3467 inst.instruction |= (reg ^ WR_PREFIX) << shift;
3468 return reg;
3469 }
3470 else if (wc_register (reg)
3471 && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
3472 {
3473 if (shift >= 0)
3474 inst.instruction |= (reg ^ WC_PREFIX) << shift;
3475 return reg;
3476 }
3477 else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
3478 {
3479 if (shift >= 0)
3480 inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
3481 return reg;
3482 }
3483 }
3484
3485 /* Restore the start point, we may have got a reg of the wrong class. */
3486 *str = start;
3487
3488 /* In the few cases where we might be able to accept
3489 something else this error can be overridden. */
3490 sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
3491 inst.error = buff;
3492
3493 return FAIL;
3494 }
3495
3496 static const struct asm_psr *
3497 arm_psr_parse (ccp)
3498 register char ** ccp;
3499 {
3500 char * start = * ccp;
3501 char c;
3502 char * p;
3503 const struct asm_psr * psr;
3504
3505 p = start;
3506
3507 /* Skip to the end of the next word in the input stream. */
3508 do
3509 {
3510 c = *p++;
3511 }
3512 while (ISALPHA (c) || c == '_');
3513
3514 /* Terminate the word. */
3515 *--p = 0;
3516
3517 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
3518 feature for ease of use and backwards compatibility. */
3519 if (!strncmp (start, "cpsr", 4))
3520 strncpy (start, "CPSR", 4);
3521 else if (!strncmp (start, "spsr", 4))
3522 strncpy (start, "SPSR", 4);
3523
3524 /* Now locate the word in the psr hash table. */
3525 psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
3526
3527 /* Restore the input stream. */
3528 *p = c;
3529
3530 /* If we found a valid match, advance the
3531 stream pointer past the end of the word. */
3532 *ccp = p;
3533
3534 return psr;
3535 }
3536
3537 /* Parse the input looking for a PSR flag. */
3538
3539 static int
3540 psr_required_here (str)
3541 char ** str;
3542 {
3543 char * start = * str;
3544 const struct asm_psr * psr;
3545
3546 psr = arm_psr_parse (str);
3547
3548 if (psr)
3549 {
3550 /* If this is the SPSR that is being modified, set the R bit. */
3551 if (! psr->cpsr)
3552 inst.instruction |= SPSR_BIT;
3553
3554 /* Set the psr flags in the MSR instruction. */
3555 inst.instruction |= psr->field << PSR_SHIFT;
3556
3557 return SUCCESS;
3558 }
3559
3560 /* In the few cases where we might be able to accept
3561 something else this error can be overridden. */
3562 inst.error = _("flag for {c}psr instruction expected");
3563
3564 /* Restore the start point. */
3565 *str = start;
3566 return FAIL;
3567 }
3568
3569 static int
3570 co_proc_number (str)
3571 char **str;
3572 {
3573 int processor, pchar;
3574 char *start;
3575
3576 skip_whitespace (*str);
3577 start = *str;
3578
3579 /* The data sheet seems to imply that just a number on its own is valid
3580 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
3581 accept either. */
3582 if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
3583 == FAIL)
3584 {
3585 *str = start;
3586
3587 pchar = *(*str)++;
3588 if (pchar >= '0' && pchar <= '9')
3589 {
3590 processor = pchar - '0';
3591 if (**str >= '0' && **str <= '9')
3592 {
3593 processor = processor * 10 + *(*str)++ - '0';
3594 if (processor > 15)
3595 {
3596 inst.error = _("illegal co-processor number");
3597 return FAIL;
3598 }
3599 }
3600 }
3601 else
3602 {
3603 inst.error = _("bad or missing co-processor number");
3604 return FAIL;
3605 }
3606 }
3607
3608 inst.instruction |= processor << 8;
3609 return SUCCESS;
3610 }
3611
3612 static int
3613 cp_opc_expr (str, where, length)
3614 char ** str;
3615 int where;
3616 int length;
3617 {
3618 expressionS expr;
3619
3620 skip_whitespace (* str);
3621
3622 memset (&expr, '\0', sizeof (expr));
3623
3624 if (my_get_expression (&expr, str))
3625 return FAIL;
3626 if (expr.X_op != O_constant)
3627 {
3628 inst.error = _("bad or missing expression");
3629 return FAIL;
3630 }
3631
3632 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
3633 {
3634 inst.error = _("immediate co-processor expression too large");
3635 return FAIL;
3636 }
3637
3638 inst.instruction |= expr.X_add_number << where;
3639 return SUCCESS;
3640 }
3641
3642 static int
3643 cp_reg_required_here (str, where)
3644 char ** str;
3645 int where;
3646 {
3647 int reg;
3648 char * start = *str;
3649
3650 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
3651 {
3652 inst.instruction |= reg << where;
3653 return reg;
3654 }
3655
3656 /* In the few cases where we might be able to accept something else
3657 this error can be overridden. */
3658 inst.error = _("co-processor register expected");
3659
3660 /* Restore the start point. */
3661 *str = start;
3662 return FAIL;
3663 }
3664
3665 static int
3666 fp_reg_required_here (str, where)
3667 char ** str;
3668 int where;
3669 {
3670 int reg;
3671 char * start = * str;
3672
3673 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
3674 {
3675 inst.instruction |= reg << where;
3676 return reg;
3677 }
3678
3679 /* In the few cases where we might be able to accept something else
3680 this error can be overridden. */
3681 inst.error = _("floating point register expected");
3682
3683 /* Restore the start point. */
3684 *str = start;
3685 return FAIL;
3686 }
3687
3688 static int
3689 cp_address_offset (str)
3690 char ** str;
3691 {
3692 int offset;
3693
3694 skip_whitespace (* str);
3695
3696 if (! is_immediate_prefix (**str))
3697 {
3698 inst.error = _("immediate expression expected");
3699 return FAIL;
3700 }
3701
3702 (*str)++;
3703
3704 if (my_get_expression (& inst.reloc.exp, str))
3705 return FAIL;
3706
3707 if (inst.reloc.exp.X_op == O_constant)
3708 {
3709 offset = inst.reloc.exp.X_add_number;
3710
3711 if (offset & 3)
3712 {
3713 inst.error = _("co-processor address must be word aligned");
3714 return FAIL;
3715 }
3716
3717 if (offset > 1023 || offset < -1023)
3718 {
3719 inst.error = _("offset too large");
3720 return FAIL;
3721 }
3722
3723 if (offset >= 0)
3724 inst.instruction |= INDEX_UP;
3725 else
3726 offset = -offset;
3727
3728 inst.instruction |= offset >> 2;
3729 }
3730 else
3731 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3732
3733 return SUCCESS;
3734 }
3735
3736 static int
3737 cp_address_required_here (str, wb_ok)
3738 char ** str;
3739 int wb_ok;
3740 {
3741 char * p = * str;
3742 int pre_inc = 0;
3743 int write_back = 0;
3744
3745 if (*p == '[')
3746 {
3747 int reg;
3748
3749 p++;
3750 skip_whitespace (p);
3751
3752 if ((reg = reg_required_here (& p, 16)) == FAIL)
3753 return FAIL;
3754
3755 skip_whitespace (p);
3756
3757 if (*p == ']')
3758 {
3759 p++;
3760
3761 skip_whitespace (p);
3762
3763 if (*p == '\0')
3764 {
3765 /* As an extension to the official ARM syntax we allow:
3766
3767 [Rn]
3768
3769 as a short hand for:
3770
3771 [Rn,#0] */
3772 inst.instruction |= PRE_INDEX | INDEX_UP;
3773 *str = p;
3774 return SUCCESS;
3775 }
3776
3777 if (skip_past_comma (& p) == FAIL)
3778 {
3779 inst.error = _("comma expected after closing square bracket");
3780 return FAIL;
3781 }
3782
3783 skip_whitespace (p);
3784
3785 if (*p == '#')
3786 {
3787 if (wb_ok)
3788 {
3789 /* [Rn], #expr */
3790 write_back = WRITE_BACK;
3791
3792 if (reg == REG_PC)
3793 {
3794 inst.error = _("pc may not be used in post-increment");
3795 return FAIL;
3796 }
3797
3798 if (cp_address_offset (& p) == FAIL)
3799 return FAIL;
3800 }
3801 else
3802 pre_inc = PRE_INDEX | INDEX_UP;
3803 }
3804 else if (*p == '{')
3805 {
3806 int option;
3807
3808 /* [Rn], {<expr>} */
3809 p++;
3810
3811 skip_whitespace (p);
3812
3813 if (my_get_expression (& inst.reloc.exp, & p))
3814 return FAIL;
3815
3816 if (inst.reloc.exp.X_op == O_constant)
3817 {
3818 option = inst.reloc.exp.X_add_number;
3819
3820 if (option > 255 || option < 0)
3821 {
3822 inst.error = _("'option' field too large");
3823 return FAIL;
3824 }
3825
3826 skip_whitespace (p);
3827
3828 if (*p != '}')
3829 {
3830 inst.error = _("'}' expected at end of 'option' field");
3831 return FAIL;
3832 }
3833 else
3834 {
3835 p++;
3836 inst.instruction |= option;
3837 inst.instruction |= INDEX_UP;
3838 }
3839 }
3840 else
3841 {
3842 inst.error = _("non-constant expressions for 'option' field not supported");
3843 return FAIL;
3844 }
3845 }
3846 else
3847 {
3848 inst.error = _("# or { expected after comma");
3849 return FAIL;
3850 }
3851 }
3852 else
3853 {
3854 /* '['Rn, #expr']'[!] */
3855
3856 if (skip_past_comma (& p) == FAIL)
3857 {
3858 inst.error = _("pre-indexed expression expected");
3859 return FAIL;
3860 }
3861
3862 pre_inc = PRE_INDEX;
3863
3864 if (cp_address_offset (& p) == FAIL)
3865 return FAIL;
3866
3867 skip_whitespace (p);
3868
3869 if (*p++ != ']')
3870 {
3871 inst.error = _("missing ]");
3872 return FAIL;
3873 }
3874
3875 skip_whitespace (p);
3876
3877 if (wb_ok && *p == '!')
3878 {
3879 if (reg == REG_PC)
3880 {
3881 inst.error = _("pc may not be used with write-back");
3882 return FAIL;
3883 }
3884
3885 p++;
3886 write_back = WRITE_BACK;
3887 }
3888 }
3889 }
3890 else
3891 {
3892 if (my_get_expression (&inst.reloc.exp, &p))
3893 return FAIL;
3894
3895 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3896 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3897 inst.reloc.pc_rel = 1;
3898 inst.instruction |= (REG_PC << 16);
3899 pre_inc = PRE_INDEX;
3900 }
3901
3902 inst.instruction |= write_back | pre_inc;
3903 *str = p;
3904 return SUCCESS;
3905 }
3906
3907 static int
3908 cp_byte_address_offset (str)
3909 char ** str;
3910 {
3911 int offset;
3912
3913 skip_whitespace (* str);
3914
3915 if (! is_immediate_prefix (**str))
3916 {
3917 inst.error = _("immediate expression expected");
3918 return FAIL;
3919 }
3920
3921 (*str)++;
3922
3923 if (my_get_expression (& inst.reloc.exp, str))
3924 return FAIL;
3925
3926 if (inst.reloc.exp.X_op == O_constant)
3927 {
3928 offset = inst.reloc.exp.X_add_number;
3929
3930 if (offset > 255 || offset < -255)
3931 {
3932 inst.error = _("offset too large");
3933 return FAIL;
3934 }
3935
3936 if (offset >= 0)
3937 inst.instruction |= INDEX_UP;
3938 else
3939 offset = -offset;
3940
3941 inst.instruction |= offset;
3942 }
3943 else
3944 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3945
3946 return SUCCESS;
3947 }
3948
3949 static int
3950 cp_byte_address_required_here (str)
3951 char ** str;
3952 {
3953 char * p = * str;
3954 int pre_inc = 0;
3955 int write_back = 0;
3956
3957 if (*p == '[')
3958 {
3959 int reg;
3960
3961 p++;
3962 skip_whitespace (p);
3963
3964 if ((reg = reg_required_here (& p, 16)) == FAIL)
3965 return FAIL;
3966
3967 skip_whitespace (p);
3968
3969 if (*p == ']')
3970 {
3971 p++;
3972
3973 if (skip_past_comma (& p) == SUCCESS)
3974 {
3975 /* [Rn], #expr */
3976 write_back = WRITE_BACK;
3977
3978 if (reg == REG_PC)
3979 {
3980 inst.error = _("pc may not be used in post-increment");
3981 return FAIL;
3982 }
3983
3984 if (cp_byte_address_offset (& p) == FAIL)
3985 return FAIL;
3986 }
3987 else
3988 pre_inc = PRE_INDEX | INDEX_UP;
3989 }
3990 else
3991 {
3992 /* '['Rn, #expr']'[!] */
3993
3994 if (skip_past_comma (& p) == FAIL)
3995 {
3996 inst.error = _("pre-indexed expression expected");
3997 return FAIL;
3998 }
3999
4000 pre_inc = PRE_INDEX;
4001
4002 if (cp_byte_address_offset (& p) == FAIL)
4003 return FAIL;
4004
4005 skip_whitespace (p);
4006
4007 if (*p++ != ']')
4008 {
4009 inst.error = _("missing ]");
4010 return FAIL;
4011 }
4012
4013 skip_whitespace (p);
4014
4015 if (*p == '!')
4016 {
4017 if (reg == REG_PC)
4018 {
4019 inst.error = _("pc may not be used with write-back");
4020 return FAIL;
4021 }
4022
4023 p++;
4024 write_back = WRITE_BACK;
4025 }
4026 }
4027 }
4028 else
4029 {
4030 if (my_get_expression (&inst.reloc.exp, &p))
4031 return FAIL;
4032
4033 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
4034 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
4035 inst.reloc.pc_rel = 1;
4036 inst.instruction |= (REG_PC << 16);
4037 pre_inc = PRE_INDEX;
4038 }
4039
4040 inst.instruction |= write_back | pre_inc;
4041 *str = p;
4042 return SUCCESS;
4043 }
4044
4045 static void
4046 do_empty (str)
4047 char * str;
4048 {
4049 /* Do nothing really. */
4050 end_of_line (str);
4051 }
4052
4053 static void
4054 do_mrs (str)
4055 char *str;
4056 {
4057 int skip = 0;
4058
4059 /* Only one syntax. */
4060 skip_whitespace (str);
4061
4062 if (reg_required_here (&str, 12) == FAIL)
4063 {
4064 inst.error = BAD_ARGS;
4065 return;
4066 }
4067
4068 if (skip_past_comma (&str) == FAIL)
4069 {
4070 inst.error = _("comma expected after register name");
4071 return;
4072 }
4073
4074 skip_whitespace (str);
4075
4076 if ( strcmp (str, "CPSR") == 0
4077 || strcmp (str, "SPSR") == 0
4078 /* Lower case versions for backwards compatibility. */
4079 || strcmp (str, "cpsr") == 0
4080 || strcmp (str, "spsr") == 0)
4081 skip = 4;
4082
4083 /* This is for backwards compatibility with older toolchains. */
4084 else if ( strcmp (str, "cpsr_all") == 0
4085 || strcmp (str, "spsr_all") == 0)
4086 skip = 8;
4087 else
4088 {
4089 inst.error = _("CPSR or SPSR expected");
4090 return;
4091 }
4092
4093 if (* str == 's' || * str == 'S')
4094 inst.instruction |= SPSR_BIT;
4095 str += skip;
4096
4097 end_of_line (str);
4098 }
4099
4100 /* Two possible forms:
4101 "{C|S}PSR_<field>, Rm",
4102 "{C|S}PSR_f, #expression". */
4103
4104 static void
4105 do_msr (str)
4106 char * str;
4107 {
4108 skip_whitespace (str);
4109
4110 if (psr_required_here (& str) == FAIL)
4111 return;
4112
4113 if (skip_past_comma (& str) == FAIL)
4114 {
4115 inst.error = _("comma missing after psr flags");
4116 return;
4117 }
4118
4119 skip_whitespace (str);
4120
4121 if (reg_required_here (& str, 0) != FAIL)
4122 {
4123 inst.error = NULL;
4124 end_of_line (str);
4125 return;
4126 }
4127
4128 if (! is_immediate_prefix (* str))
4129 {
4130 inst.error =
4131 _("only a register or immediate value can follow a psr flag");
4132 return;
4133 }
4134
4135 str ++;
4136 inst.error = NULL;
4137
4138 if (my_get_expression (& inst.reloc.exp, & str))
4139 {
4140 inst.error =
4141 _("only a register or immediate value can follow a psr flag");
4142 return;
4143 }
4144
4145 #if 0 /* The first edition of the ARM architecture manual stated that
4146 writing anything other than the flags with an immediate operation
4147 had UNPREDICTABLE effects. This constraint was removed in the
4148 second edition of the specification. */
4149 if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
4150 && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
4151 {
4152 inst.error = _("immediate value cannot be used to set this field");
4153 return;
4154 }
4155 #endif
4156
4157 inst.instruction |= INST_IMMEDIATE;
4158
4159 if (inst.reloc.exp.X_add_symbol)
4160 {
4161 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4162 inst.reloc.pc_rel = 0;
4163 }
4164 else
4165 {
4166 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
4167
4168 if (value == (unsigned) FAIL)
4169 {
4170 inst.error = _("invalid constant");
4171 return;
4172 }
4173
4174 inst.instruction |= value;
4175 }
4176
4177 inst.error = NULL;
4178 end_of_line (str);
4179 }
4180
4181 /* Long Multiply Parser
4182 UMULL RdLo, RdHi, Rm, Rs
4183 SMULL RdLo, RdHi, Rm, Rs
4184 UMLAL RdLo, RdHi, Rm, Rs
4185 SMLAL RdLo, RdHi, Rm, Rs. */
4186
4187 static void
4188 do_mull (str)
4189 char * str;
4190 {
4191 int rdlo, rdhi, rm, rs;
4192
4193 /* Only one format "rdlo, rdhi, rm, rs". */
4194 skip_whitespace (str);
4195
4196 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
4197 {
4198 inst.error = BAD_ARGS;
4199 return;
4200 }
4201
4202 if (skip_past_comma (&str) == FAIL
4203 || (rdhi = reg_required_here (&str, 16)) == FAIL)
4204 {
4205 inst.error = BAD_ARGS;
4206 return;
4207 }
4208
4209 if (skip_past_comma (&str) == FAIL
4210 || (rm = reg_required_here (&str, 0)) == FAIL)
4211 {
4212 inst.error = BAD_ARGS;
4213 return;
4214 }
4215
4216 /* rdhi, rdlo and rm must all be different. */
4217 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
4218 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
4219
4220 if (skip_past_comma (&str) == FAIL
4221 || (rs = reg_required_here (&str, 8)) == FAIL)
4222 {
4223 inst.error = BAD_ARGS;
4224 return;
4225 }
4226
4227 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
4228 {
4229 inst.error = BAD_PC;
4230 return;
4231 }
4232
4233 end_of_line (str);
4234 }
4235
4236 static void
4237 do_mul (str)
4238 char * str;
4239 {
4240 int rd, rm;
4241
4242 /* Only one format "rd, rm, rs". */
4243 skip_whitespace (str);
4244
4245 if ((rd = reg_required_here (&str, 16)) == FAIL)
4246 {
4247 inst.error = BAD_ARGS;
4248 return;
4249 }
4250
4251 if (rd == REG_PC)
4252 {
4253 inst.error = BAD_PC;
4254 return;
4255 }
4256
4257 if (skip_past_comma (&str) == FAIL
4258 || (rm = reg_required_here (&str, 0)) == FAIL)
4259 {
4260 inst.error = BAD_ARGS;
4261 return;
4262 }
4263
4264 if (rm == REG_PC)
4265 {
4266 inst.error = BAD_PC;
4267 return;
4268 }
4269
4270 if (rm == rd)
4271 as_tsktsk (_("rd and rm should be different in mul"));
4272
4273 if (skip_past_comma (&str) == FAIL
4274 || (rm = reg_required_here (&str, 8)) == FAIL)
4275 {
4276 inst.error = BAD_ARGS;
4277 return;
4278 }
4279
4280 if (rm == REG_PC)
4281 {
4282 inst.error = BAD_PC;
4283 return;
4284 }
4285
4286 end_of_line (str);
4287 }
4288
4289 static void
4290 do_mla (str)
4291 char * str;
4292 {
4293 int rd, rm;
4294
4295 /* Only one format "rd, rm, rs, rn". */
4296 skip_whitespace (str);
4297
4298 if ((rd = reg_required_here (&str, 16)) == FAIL)
4299 {
4300 inst.error = BAD_ARGS;
4301 return;
4302 }
4303
4304 if (rd == REG_PC)
4305 {
4306 inst.error = BAD_PC;
4307 return;
4308 }
4309
4310 if (skip_past_comma (&str) == FAIL
4311 || (rm = reg_required_here (&str, 0)) == FAIL)
4312 {
4313 inst.error = BAD_ARGS;
4314 return;
4315 }
4316
4317 if (rm == REG_PC)
4318 {
4319 inst.error = BAD_PC;
4320 return;
4321 }
4322
4323 if (rm == rd)
4324 as_tsktsk (_("rd and rm should be different in mla"));
4325
4326 if (skip_past_comma (&str) == FAIL
4327 || (rd = reg_required_here (&str, 8)) == FAIL
4328 || skip_past_comma (&str) == FAIL
4329 || (rm = reg_required_here (&str, 12)) == FAIL)
4330 {
4331 inst.error = BAD_ARGS;
4332 return;
4333 }
4334
4335 if (rd == REG_PC || rm == REG_PC)
4336 {
4337 inst.error = BAD_PC;
4338 return;
4339 }
4340
4341 end_of_line (str);
4342 }
4343
4344 /* Expects *str -> the characters "acc0", possibly with leading blanks.
4345 Advances *str to the next non-alphanumeric.
4346 Returns 0, or else FAIL (in which case sets inst.error).
4347
4348 (In a future XScale, there may be accumulators other than zero.
4349 At that time this routine and its callers can be upgraded to suit.) */
4350
4351 static int
4352 accum0_required_here (str)
4353 char ** str;
4354 {
4355 static char buff [128]; /* Note the address is taken. Hence, static. */
4356 char * p = * str;
4357 char c;
4358 int result = 0; /* The accum number. */
4359
4360 skip_whitespace (p);
4361
4362 *str = p; /* Advance caller's string pointer too. */
4363 c = *p++;
4364 while (ISALNUM (c))
4365 c = *p++;
4366
4367 *--p = 0; /* Aap nul into input buffer at non-alnum. */
4368
4369 if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
4370 {
4371 sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
4372 inst.error = buff;
4373 result = FAIL;
4374 }
4375
4376 *p = c; /* Unzap. */
4377 *str = p; /* Caller's string pointer to after match. */
4378 return result;
4379 }
4380
4381 /* Expects **str -> after a comma. May be leading blanks.
4382 Advances *str, recognizing a load mode, and setting inst.instruction.
4383 Returns rn, or else FAIL (in which case may set inst.error
4384 and not advance str)
4385
4386 Note: doesn't know Rd, so no err checks that require such knowledge. */
4387
4388 static int
4389 ld_mode_required_here (string)
4390 char ** string;
4391 {
4392 char * str = * string;
4393 int rn;
4394 int pre_inc = 0;
4395
4396 skip_whitespace (str);
4397
4398 if (* str == '[')
4399 {
4400 str++;
4401
4402 skip_whitespace (str);
4403
4404 if ((rn = reg_required_here (& str, 16)) == FAIL)
4405 return FAIL;
4406
4407 skip_whitespace (str);
4408
4409 if (* str == ']')
4410 {
4411 str ++;
4412
4413 if (skip_past_comma (& str) == SUCCESS)
4414 {
4415 /* [Rn],... (post inc) */
4416 if (ldst_extend_v4 (&str) == FAIL)
4417 return FAIL;
4418 }
4419 else /* [Rn] */
4420 {
4421 skip_whitespace (str);
4422
4423 if (* str == '!')
4424 {
4425 str ++;
4426 inst.instruction |= WRITE_BACK;
4427 }
4428
4429 inst.instruction |= INDEX_UP | HWOFFSET_IMM;
4430 pre_inc = 1;
4431 }
4432 }
4433 else /* [Rn,...] */
4434 {
4435 if (skip_past_comma (& str) == FAIL)
4436 {
4437 inst.error = _("pre-indexed expression expected");
4438 return FAIL;
4439 }
4440
4441 pre_inc = 1;
4442
4443 if (ldst_extend_v4 (&str) == FAIL)
4444 return FAIL;
4445
4446 skip_whitespace (str);
4447
4448 if (* str ++ != ']')
4449 {
4450 inst.error = _("missing ]");
4451 return FAIL;
4452 }
4453
4454 skip_whitespace (str);
4455
4456 if (* str == '!')
4457 {
4458 str ++;
4459 inst.instruction |= WRITE_BACK;
4460 }
4461 }
4462 }
4463 else if (* str == '=') /* ldr's "r,=label" syntax */
4464 /* We should never reach here, because <text> = <expression> is
4465 caught gas/read.c read_a_source_file() as a .set operation. */
4466 return FAIL;
4467 else /* PC +- 8 bit immediate offset. */
4468 {
4469 if (my_get_expression (& inst.reloc.exp, & str))
4470 return FAIL;
4471
4472 inst.instruction |= HWOFFSET_IMM; /* The I bit. */
4473 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
4474 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
4475 inst.reloc.pc_rel = 1;
4476 inst.instruction |= (REG_PC << 16);
4477
4478 rn = REG_PC;
4479 pre_inc = 1;
4480 }
4481
4482 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
4483 * string = str;
4484
4485 return rn;
4486 }
4487
4488 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
4489 SMLAxy{cond} Rd,Rm,Rs,Rn
4490 SMLAWy{cond} Rd,Rm,Rs,Rn
4491 Error if any register is R15. */
4492
4493 static void
4494 do_smla (str)
4495 char * str;
4496 {
4497 int rd, rm, rs, rn;
4498
4499 skip_whitespace (str);
4500
4501 if ((rd = reg_required_here (& str, 16)) == FAIL
4502 || skip_past_comma (& str) == FAIL
4503 || (rm = reg_required_here (& str, 0)) == FAIL
4504 || skip_past_comma (& str) == FAIL
4505 || (rs = reg_required_here (& str, 8)) == FAIL
4506 || skip_past_comma (& str) == FAIL
4507 || (rn = reg_required_here (& str, 12)) == FAIL)
4508 inst.error = BAD_ARGS;
4509
4510 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
4511 inst.error = BAD_PC;
4512
4513 else
4514 end_of_line (str);
4515 }
4516
4517 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4518 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4519 Error if any register is R15.
4520 Warning if Rdlo == Rdhi. */
4521
4522 static void
4523 do_smlal (str)
4524 char * str;
4525 {
4526 int rdlo, rdhi, rm, rs;
4527
4528 skip_whitespace (str);
4529
4530 if ((rdlo = reg_required_here (& str, 12)) == FAIL
4531 || skip_past_comma (& str) == FAIL
4532 || (rdhi = reg_required_here (& str, 16)) == FAIL
4533 || skip_past_comma (& str) == FAIL
4534 || (rm = reg_required_here (& str, 0)) == FAIL
4535 || skip_past_comma (& str) == FAIL
4536 || (rs = reg_required_here (& str, 8)) == FAIL)
4537 {
4538 inst.error = BAD_ARGS;
4539 return;
4540 }
4541
4542 if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4543 {
4544 inst.error = BAD_PC;
4545 return;
4546 }
4547
4548 if (rdlo == rdhi)
4549 as_tsktsk (_("rdhi and rdlo must be different"));
4550
4551 end_of_line (str);
4552 }
4553
4554 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4555 SMULxy{cond} Rd,Rm,Rs
4556 Error if any register is R15. */
4557
4558 static void
4559 do_smul (str)
4560 char * str;
4561 {
4562 int rd, rm, rs;
4563
4564 skip_whitespace (str);
4565
4566 if ((rd = reg_required_here (& str, 16)) == FAIL
4567 || skip_past_comma (& str) == FAIL
4568 || (rm = reg_required_here (& str, 0)) == FAIL
4569 || skip_past_comma (& str) == FAIL
4570 || (rs = reg_required_here (& str, 8)) == FAIL)
4571 inst.error = BAD_ARGS;
4572
4573 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
4574 inst.error = BAD_PC;
4575
4576 else
4577 end_of_line (str);
4578 }
4579
4580 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4581 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4582 Error if any register is R15. */
4583
4584 static void
4585 do_qadd (str)
4586 char * str;
4587 {
4588 int rd, rm, rn;
4589
4590 skip_whitespace (str);
4591
4592 if ((rd = reg_required_here (& str, 12)) == FAIL
4593 || skip_past_comma (& str) == FAIL
4594 || (rm = reg_required_here (& str, 0)) == FAIL
4595 || skip_past_comma (& str) == FAIL
4596 || (rn = reg_required_here (& str, 16)) == FAIL)
4597 inst.error = BAD_ARGS;
4598
4599 else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4600 inst.error = BAD_PC;
4601
4602 else
4603 end_of_line (str);
4604 }
4605
4606 /* ARM V5E (el Segundo)
4607 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4608 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4609
4610 These are equivalent to the XScale instructions MAR and MRA,
4611 respectively, when coproc == 0, opcode == 0, and CRm == 0.
4612
4613 Result unpredicatable if Rd or Rn is R15. */
4614
4615 static void
4616 do_co_reg2c (str)
4617 char * str;
4618 {
4619 int rd, rn;
4620
4621 skip_whitespace (str);
4622
4623 if (co_proc_number (& str) == FAIL)
4624 {
4625 if (!inst.error)
4626 inst.error = BAD_ARGS;
4627 return;
4628 }
4629
4630 if (skip_past_comma (& str) == FAIL
4631 || cp_opc_expr (& str, 4, 4) == FAIL)
4632 {
4633 if (!inst.error)
4634 inst.error = BAD_ARGS;
4635 return;
4636 }
4637
4638 if (skip_past_comma (& str) == FAIL
4639 || (rd = reg_required_here (& str, 12)) == FAIL)
4640 {
4641 if (!inst.error)
4642 inst.error = BAD_ARGS;
4643 return;
4644 }
4645
4646 if (skip_past_comma (& str) == FAIL
4647 || (rn = reg_required_here (& str, 16)) == FAIL)
4648 {
4649 if (!inst.error)
4650 inst.error = BAD_ARGS;
4651 return;
4652 }
4653
4654 /* Unpredictable result if rd or rn is R15. */
4655 if (rd == REG_PC || rn == REG_PC)
4656 as_tsktsk
4657 (_("Warning: instruction unpredictable when using r15"));
4658
4659 if (skip_past_comma (& str) == FAIL
4660 || cp_reg_required_here (& str, 0) == FAIL)
4661 {
4662 if (!inst.error)
4663 inst.error = BAD_ARGS;
4664 return;
4665 }
4666
4667 end_of_line (str);
4668 }
4669
4670 /* ARM V5 count-leading-zeroes instruction (argument parse)
4671 CLZ{<cond>} <Rd>, <Rm>
4672 Condition defaults to COND_ALWAYS.
4673 Error if Rd or Rm are R15. */
4674
4675 static void
4676 do_clz (str)
4677 char * str;
4678 {
4679 int rd, rm;
4680
4681 skip_whitespace (str);
4682
4683 if (((rd = reg_required_here (& str, 12)) == FAIL)
4684 || (skip_past_comma (& str) == FAIL)
4685 || ((rm = reg_required_here (& str, 0)) == FAIL))
4686 inst.error = BAD_ARGS;
4687
4688 else if (rd == REG_PC || rm == REG_PC )
4689 inst.error = BAD_PC;
4690
4691 else
4692 end_of_line (str);
4693 }
4694
4695 /* ARM V5 (argument parse)
4696 LDC2{L} <coproc>, <CRd>, <addressing mode>
4697 STC2{L} <coproc>, <CRd>, <addressing mode>
4698 Instruction is not conditional, and has 0xf in the condition field.
4699 Otherwise, it's the same as LDC/STC. */
4700
4701 static void
4702 do_lstc2 (str)
4703 char * str;
4704 {
4705 skip_whitespace (str);
4706
4707 if (co_proc_number (& str) == FAIL)
4708 {
4709 if (!inst.error)
4710 inst.error = BAD_ARGS;
4711 }
4712 else if (skip_past_comma (& str) == FAIL
4713 || cp_reg_required_here (& str, 12) == FAIL)
4714 {
4715 if (!inst.error)
4716 inst.error = BAD_ARGS;
4717 }
4718 else if (skip_past_comma (& str) == FAIL
4719 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
4720 {
4721 if (! inst.error)
4722 inst.error = BAD_ARGS;
4723 }
4724 else
4725 end_of_line (str);
4726 }
4727
4728 /* ARM V5 (argument parse)
4729 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4730 Instruction is not conditional, and has 0xf in the condition field.
4731 Otherwise, it's the same as CDP. */
4732
4733 static void
4734 do_cdp2 (str)
4735 char * str;
4736 {
4737 skip_whitespace (str);
4738
4739 if (co_proc_number (& str) == FAIL)
4740 {
4741 if (!inst.error)
4742 inst.error = BAD_ARGS;
4743 return;
4744 }
4745
4746 if (skip_past_comma (& str) == FAIL
4747 || cp_opc_expr (& str, 20,4) == FAIL)
4748 {
4749 if (!inst.error)
4750 inst.error = BAD_ARGS;
4751 return;
4752 }
4753
4754 if (skip_past_comma (& str) == FAIL
4755 || cp_reg_required_here (& str, 12) == FAIL)
4756 {
4757 if (!inst.error)
4758 inst.error = BAD_ARGS;
4759 return;
4760 }
4761
4762 if (skip_past_comma (& str) == FAIL
4763 || cp_reg_required_here (& str, 16) == FAIL)
4764 {
4765 if (!inst.error)
4766 inst.error = BAD_ARGS;
4767 return;
4768 }
4769
4770 if (skip_past_comma (& str) == FAIL
4771 || cp_reg_required_here (& str, 0) == FAIL)
4772 {
4773 if (!inst.error)
4774 inst.error = BAD_ARGS;
4775 return;
4776 }
4777
4778 if (skip_past_comma (& str) == SUCCESS)
4779 {
4780 if (cp_opc_expr (& str, 5, 3) == FAIL)
4781 {
4782 if (!inst.error)
4783 inst.error = BAD_ARGS;
4784 return;
4785 }
4786 }
4787
4788 end_of_line (str);
4789 }
4790
4791 /* ARM V5 (argument parse)
4792 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4793 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4794 Instruction is not conditional, and has 0xf in the condition field.
4795 Otherwise, it's the same as MCR/MRC. */
4796
4797 static void
4798 do_co_reg2 (str)
4799 char * str;
4800 {
4801 skip_whitespace (str);
4802
4803 if (co_proc_number (& str) == FAIL)
4804 {
4805 if (!inst.error)
4806 inst.error = BAD_ARGS;
4807 return;
4808 }
4809
4810 if (skip_past_comma (& str) == FAIL
4811 || cp_opc_expr (& str, 21, 3) == FAIL)
4812 {
4813 if (!inst.error)
4814 inst.error = BAD_ARGS;
4815 return;
4816 }
4817
4818 if (skip_past_comma (& str) == FAIL
4819 || reg_required_here (& str, 12) == FAIL)
4820 {
4821 if (!inst.error)
4822 inst.error = BAD_ARGS;
4823 return;
4824 }
4825
4826 if (skip_past_comma (& str) == FAIL
4827 || cp_reg_required_here (& str, 16) == FAIL)
4828 {
4829 if (!inst.error)
4830 inst.error = BAD_ARGS;
4831 return;
4832 }
4833
4834 if (skip_past_comma (& str) == FAIL
4835 || cp_reg_required_here (& str, 0) == FAIL)
4836 {
4837 if (!inst.error)
4838 inst.error = BAD_ARGS;
4839 return;
4840 }
4841
4842 if (skip_past_comma (& str) == SUCCESS)
4843 {
4844 if (cp_opc_expr (& str, 5, 3) == FAIL)
4845 {
4846 if (!inst.error)
4847 inst.error = BAD_ARGS;
4848 return;
4849 }
4850 }
4851
4852 end_of_line (str);
4853 }
4854
4855 /* ARM v5TEJ. Jump to Jazelle code. */
4856 static void
4857 do_bxj (str)
4858 char * str;
4859 {
4860 int reg;
4861
4862 skip_whitespace (str);
4863
4864 if ((reg = reg_required_here (&str, 0)) == FAIL)
4865 {
4866 inst.error = BAD_ARGS;
4867 return;
4868 }
4869
4870 /* Note - it is not illegal to do a "bxj pc". Useless, but not illegal. */
4871 if (reg == REG_PC)
4872 as_tsktsk (_("use of r15 in bxj is not really useful"));
4873
4874 end_of_line (str);
4875 }
4876
4877 /* ARM V6 umaal (argument parse). */
4878
4879 static void
4880 do_umaal (str)
4881 char *str;
4882 {
4883
4884 int rdlo, rdhi, rm, rs;
4885
4886 skip_whitespace (str);
4887 if ((rdlo = reg_required_here (& str, 12)) == FAIL
4888 || skip_past_comma (& str) == FAIL
4889 || (rdhi = reg_required_here (& str, 16)) == FAIL
4890 || skip_past_comma (& str) == FAIL
4891 || (rm = reg_required_here (& str, 0)) == FAIL
4892 || skip_past_comma (& str) == FAIL
4893 || (rs = reg_required_here (& str, 8)) == FAIL)
4894 {
4895 inst.error = BAD_ARGS;
4896 return;
4897 }
4898
4899 if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4900 {
4901 inst.error = BAD_PC;
4902 return;
4903 }
4904
4905 end_of_line (str);
4906 }
4907
4908 /* ARM V6 strex (argument parse). */
4909
4910 static void
4911 do_strex (str)
4912 char *str;
4913 {
4914 int rd, rm, rn;
4915
4916 /* Parse Rd, Rm,. */
4917 skip_whitespace (str);
4918 if ((rd = reg_required_here (& str, 12)) == FAIL
4919 || skip_past_comma (& str) == FAIL
4920 || (rm = reg_required_here (& str, 0)) == FAIL
4921 || skip_past_comma (& str) == FAIL)
4922 {
4923 inst.error = BAD_ARGS;
4924 return;
4925 }
4926 if (rd == REG_PC || rm == REG_PC)
4927 {
4928 inst.error = BAD_PC;
4929 return;
4930 }
4931 if (rd == rm)
4932 {
4933 inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4934 return;
4935 }
4936
4937 /* Skip past '['. */
4938 if ((strlen (str) >= 1)
4939 && strncmp (str, "[", 1) == 0)
4940 str+=1;
4941 skip_whitespace (str);
4942
4943 /* Parse Rn. */
4944 if ((rn = reg_required_here (& str, 16)) == FAIL)
4945 {
4946 inst.error = BAD_ARGS;
4947 return;
4948 }
4949 else if (rn == REG_PC)
4950 {
4951 inst.error = BAD_PC;
4952 return;
4953 }
4954 if (rd == rn)
4955 {
4956 inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
4957 return;
4958 }
4959 skip_whitespace (str);
4960
4961 /* Skip past ']'. */
4962 if ((strlen (str) >= 1)
4963 && strncmp (str, "]", 1) == 0)
4964 str+=1;
4965
4966 end_of_line (str);
4967 }
4968
4969 /* ARM V6 ssat (argument parse). */
4970
4971 static void
4972 do_ssat (str)
4973 char* str;
4974 {
4975 do_sat (&str, /*bias=*/-1);
4976 end_of_line (str);
4977 }
4978
4979 /* ARM V6 usat (argument parse). */
4980
4981 static void
4982 do_usat (str)
4983 char* str;
4984 {
4985 do_sat (&str, /*bias=*/0);
4986 end_of_line (str);
4987 }
4988
4989 static void
4990 do_sat (str, bias)
4991 char **str;
4992 int bias;
4993 {
4994 int rd, rm;
4995 expressionS expr;
4996
4997 skip_whitespace (*str);
4998
4999 /* Parse <Rd>, field. */
5000 if ((rd = reg_required_here (str, 12)) == FAIL
5001 || skip_past_comma (str) == FAIL)
5002 {
5003 inst.error = BAD_ARGS;
5004 return;
5005 }
5006 if (rd == REG_PC)
5007 {
5008 inst.error = BAD_PC;
5009 return;
5010 }
5011
5012 /* Parse #<immed>, field. */
5013 if (is_immediate_prefix (**str))
5014 (*str)++;
5015 else
5016 {
5017 inst.error = _("immediate expression expected");
5018 return;
5019 }
5020 if (my_get_expression (&expr, str))
5021 {
5022 inst.error = _("bad expression");
5023 return;
5024 }
5025 if (expr.X_op != O_constant)
5026 {
5027 inst.error = _("constant expression expected");
5028 return;
5029 }
5030 if (expr.X_add_number + bias < 0
5031 || expr.X_add_number + bias > 31)
5032 {
5033 inst.error = _("immediate value out of range");
5034 return;
5035 }
5036 inst.instruction |= (expr.X_add_number + bias) << 16;
5037 if (skip_past_comma (str) == FAIL)
5038 {
5039 inst.error = BAD_ARGS;
5040 return;
5041 }
5042
5043 /* Parse <Rm> field. */
5044 if ((rm = reg_required_here (str, 0)) == FAIL)
5045 {
5046 inst.error = BAD_ARGS;
5047 return;
5048 }
5049 if (rm == REG_PC)
5050 {
5051 inst.error = BAD_PC;
5052 return;
5053 }
5054
5055 if (skip_past_comma (str) == SUCCESS)
5056 decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
5057 }
5058
5059 /* ARM V6 ssat16 (argument parse). */
5060
5061 static void
5062 do_ssat16 (str)
5063 char *str;
5064 {
5065 do_sat16 (&str, /*bias=*/-1);
5066 end_of_line (str);
5067 }
5068
5069 static void
5070 do_usat16 (str)
5071 char *str;
5072 {
5073 do_sat16 (&str, /*bias=*/0);
5074 end_of_line (str);
5075 }
5076
5077 static void
5078 do_sat16 (str, bias)
5079 char **str;
5080 int bias;
5081 {
5082 int rd, rm;
5083 expressionS expr;
5084
5085 skip_whitespace (*str);
5086
5087 /* Parse the <Rd> field. */
5088 if ((rd = reg_required_here (str, 12)) == FAIL
5089 || skip_past_comma (str) == FAIL)
5090 {
5091 inst.error = BAD_ARGS;
5092 return;
5093 }
5094 if (rd == REG_PC)
5095 {
5096 inst.error = BAD_PC;
5097 return;
5098 }
5099
5100 /* Parse #<immed>, field. */
5101 if (is_immediate_prefix (**str))
5102 (*str)++;
5103 else
5104 {
5105 inst.error = _("immediate expression expected");
5106 return;
5107 }
5108 if (my_get_expression (&expr, str))
5109 {
5110 inst.error = _("bad expression");
5111 return;
5112 }
5113 if (expr.X_op != O_constant)
5114 {
5115 inst.error = _("constant expression expected");
5116 return;
5117 }
5118 if (expr.X_add_number + bias < 0
5119 || expr.X_add_number + bias > 15)
5120 {
5121 inst.error = _("immediate value out of range");
5122 return;
5123 }
5124 inst.instruction |= (expr.X_add_number + bias) << 16;
5125 if (skip_past_comma (str) == FAIL)
5126 {
5127 inst.error = BAD_ARGS;
5128 return;
5129 }
5130
5131 /* Parse <Rm> field. */
5132 if ((rm = reg_required_here (str, 0)) == FAIL)
5133 {
5134 inst.error = BAD_ARGS;
5135 return;
5136 }
5137 if (rm == REG_PC)
5138 {
5139 inst.error = BAD_PC;
5140 return;
5141 }
5142 }
5143
5144 /* ARM V6 srs (argument parse). */
5145
5146 static void
5147 do_srs (str)
5148 char* str;
5149 {
5150 char *exclam;
5151 skip_whitespace (str);
5152 exclam = strchr (str, '!');
5153 if (exclam)
5154 *exclam = '\0';
5155 do_cps_mode (&str);
5156 if (exclam)
5157 *exclam = '!';
5158 if (*str == '!')
5159 {
5160 inst.instruction |= WRITE_BACK;
5161 str++;
5162 }
5163 end_of_line (str);
5164 }
5165
5166 /* ARM V6 SMMUL (argument parse). */
5167
5168 static void
5169 do_smmul (str)
5170 char* str;
5171 {
5172 int rd, rm, rs;
5173
5174 skip_whitespace (str);
5175 if ((rd = reg_required_here (&str, 16)) == FAIL
5176 || skip_past_comma (&str) == FAIL
5177 || (rm = reg_required_here (&str, 0)) == FAIL
5178 || skip_past_comma (&str) == FAIL
5179 || (rs = reg_required_here (&str, 8)) == FAIL)
5180 {
5181 inst.error = BAD_ARGS;
5182 return;
5183 }
5184
5185 if (rd == REG_PC
5186 || rm == REG_PC
5187 || rs == REG_PC)
5188 {
5189 inst.error = BAD_PC;
5190 return;
5191 }
5192
5193 end_of_line (str);
5194
5195 }
5196
5197 /* ARM V6 SMLALD (argument parse). */
5198
5199 static void
5200 do_smlald (str)
5201 char* str;
5202 {
5203 int rdlo, rdhi, rm, rs;
5204 skip_whitespace (str);
5205 if ((rdlo = reg_required_here (&str, 12)) == FAIL
5206 || skip_past_comma (&str) == FAIL
5207 || (rdhi = reg_required_here (&str, 16)) == FAIL
5208 || skip_past_comma (&str) == FAIL
5209 || (rm = reg_required_here (&str, 0)) == FAIL
5210 || skip_past_comma (&str) == FAIL
5211 || (rs = reg_required_here (&str, 8)) == FAIL)
5212 {
5213 inst.error = BAD_ARGS;
5214 return;
5215 }
5216
5217 if (rdlo == REG_PC
5218 || rdhi == REG_PC
5219 || rm == REG_PC
5220 || rs == REG_PC)
5221 {
5222 inst.error = BAD_PC;
5223 return;
5224 }
5225
5226 end_of_line (str);
5227 }
5228
5229 /* ARM V6 SMLAD (argument parse). Signed multiply accumulate dual.
5230 smlad{x}{<cond>} Rd, Rm, Rs, Rn */
5231
5232 static void
5233 do_smlad (str)
5234 char *str;
5235 {
5236 int rd, rm, rs, rn;
5237
5238 skip_whitespace (str);
5239 if ((rd = reg_required_here (&str, 16)) == FAIL
5240 || skip_past_comma (&str) == FAIL
5241 || (rm = reg_required_here (&str, 0)) == FAIL
5242 || skip_past_comma (&str) == FAIL
5243 || (rs = reg_required_here (&str, 8)) == FAIL
5244 || skip_past_comma (&str) == FAIL
5245 || (rn = reg_required_here (&str, 12)) == FAIL)
5246 {
5247 inst.error = BAD_ARGS;
5248 return;
5249 }
5250
5251 if (rd == REG_PC
5252 || rn == REG_PC
5253 || rs == REG_PC
5254 || rm == REG_PC)
5255 {
5256 inst.error = BAD_PC;
5257 return;
5258 }
5259
5260 end_of_line (str);
5261 }
5262
5263 /* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
5264 preserving the other bits.
5265
5266 setend <endian_specifier>, where <endian_specifier> is either
5267 BE or LE. */
5268
5269 static void
5270 do_setend (str)
5271 char *str;
5272 {
5273 if (do_endian_specifier (str))
5274 inst.instruction |= 0x200;
5275 }
5276
5277 /* Returns true if the endian-specifier indicates big-endianness. */
5278
5279 static int
5280 do_endian_specifier (str)
5281 char *str;
5282 {
5283 int big_endian = 0;
5284
5285 skip_whitespace (str);
5286 if (strlen (str) < 2)
5287 inst.error = _("missing endian specifier");
5288 else if (strncasecmp (str, "BE", 2) == 0)
5289 {
5290 str += 2;
5291 big_endian = 1;
5292 }
5293 else if (strncasecmp (str, "LE", 2) == 0)
5294 str += 2;
5295 else
5296 inst.error = _("valid endian specifiers are be or le");
5297
5298 end_of_line (str);
5299
5300 return big_endian;
5301 }
5302
5303 /* ARM V6 SXTH.
5304
5305 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
5306 Condition defaults to COND_ALWAYS.
5307 Error if any register uses R15. */
5308
5309 static void
5310 do_sxth (str)
5311 char *str;
5312 {
5313 int rd, rm;
5314 expressionS expr;
5315 int rotation_clear_mask = 0xfffff3ff;
5316 int rotation_eight_mask = 0x00000400;
5317 int rotation_sixteen_mask = 0x00000800;
5318 int rotation_twenty_four_mask = 0x00000c00;
5319
5320 skip_whitespace (str);
5321 if ((rd = reg_required_here (&str, 12)) == FAIL
5322 || skip_past_comma (&str) == FAIL
5323 || (rm = reg_required_here (&str, 0)) == FAIL)
5324 {
5325 inst.error = BAD_ARGS;
5326 return;
5327 }
5328
5329 else if (rd == REG_PC || rm == REG_PC)
5330 {
5331 inst.error = BAD_PC;
5332 return;
5333 }
5334
5335 /* Zero out the rotation field. */
5336 inst.instruction &= rotation_clear_mask;
5337
5338 /* Check for lack of optional rotation field. */
5339 if (skip_past_comma (&str) == FAIL)
5340 {
5341 end_of_line (str);
5342 return;
5343 }
5344
5345 /* Move past 'ROR'. */
5346 skip_whitespace (str);
5347 if (strncasecmp (str, "ROR", 3) == 0)
5348 str+=3;
5349 else
5350 {
5351 inst.error = _("missing rotation field after comma");
5352 return;
5353 }
5354
5355 /* Get the immediate constant. */
5356 skip_whitespace (str);
5357 if (is_immediate_prefix (* str))
5358 str++;
5359 else
5360 {
5361 inst.error = _("immediate expression expected");
5362 return;
5363 }
5364
5365 if (my_get_expression (&expr, &str))
5366 {
5367 inst.error = _("bad expression");
5368 return;
5369 }
5370
5371 if (expr.X_op != O_constant)
5372 {
5373 inst.error = _("constant expression expected");
5374 return;
5375 }
5376
5377 switch (expr.X_add_number)
5378 {
5379 case 0:
5380 /* Rotation field has already been zeroed. */
5381 break;
5382 case 8:
5383 inst.instruction |= rotation_eight_mask;
5384 break;
5385
5386 case 16:
5387 inst.instruction |= rotation_sixteen_mask;
5388 break;
5389
5390 case 24:
5391 inst.instruction |= rotation_twenty_four_mask;
5392 break;
5393
5394 default:
5395 inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5396 break;
5397 }
5398
5399 end_of_line (str);
5400
5401 }
5402
5403 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
5404 extends it to 32-bits, and adds the result to a value in another
5405 register. You can specify a rotation by 0, 8, 16, or 24 bits
5406 before extracting the 16-bit value.
5407 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
5408 Condition defaults to COND_ALWAYS.
5409 Error if any register uses R15. */
5410
5411 static void
5412 do_sxtah (str)
5413 char *str;
5414 {
5415 int rd, rn, rm;
5416 expressionS expr;
5417 int rotation_clear_mask = 0xfffff3ff;
5418 int rotation_eight_mask = 0x00000400;
5419 int rotation_sixteen_mask = 0x00000800;
5420 int rotation_twenty_four_mask = 0x00000c00;
5421
5422 skip_whitespace (str);
5423 if ((rd = reg_required_here (&str, 12)) == FAIL
5424 || skip_past_comma (&str) == FAIL
5425 || (rn = reg_required_here (&str, 16)) == FAIL
5426 || skip_past_comma (&str) == FAIL
5427 || (rm = reg_required_here (&str, 0)) == FAIL)
5428 {
5429 inst.error = BAD_ARGS;
5430 return;
5431 }
5432
5433 else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5434 {
5435 inst.error = BAD_PC;
5436 return;
5437 }
5438
5439 /* Zero out the rotation field. */
5440 inst.instruction &= rotation_clear_mask;
5441
5442 /* Check for lack of optional rotation field. */
5443 if (skip_past_comma (&str) == FAIL)
5444 {
5445 end_of_line (str);
5446 return;
5447 }
5448
5449 /* Move past 'ROR'. */
5450 skip_whitespace (str);
5451 if (strncasecmp (str, "ROR", 3) == 0)
5452 str+=3;
5453 else
5454 {
5455 inst.error = _("missing rotation field after comma");
5456 return;
5457 }
5458
5459 /* Get the immediate constant. */
5460 skip_whitespace (str);
5461 if (is_immediate_prefix (* str))
5462 str++;
5463 else
5464 {
5465 inst.error = _("immediate expression expected");
5466 return;
5467 }
5468
5469 if (my_get_expression (&expr, &str))
5470 {
5471 inst.error = _("bad expression");
5472 return;
5473 }
5474
5475 if (expr.X_op != O_constant)
5476 {
5477 inst.error = _("constant expression expected");
5478 return;
5479 }
5480
5481 switch (expr.X_add_number)
5482 {
5483 case 0:
5484 /* Rotation field has already been zeroed. */
5485 break;
5486
5487 case 8:
5488 inst.instruction |= rotation_eight_mask;
5489 break;
5490
5491 case 16:
5492 inst.instruction |= rotation_sixteen_mask;
5493 break;
5494
5495 case 24:
5496 inst.instruction |= rotation_twenty_four_mask;
5497 break;
5498
5499 default:
5500 inst.error = _("rotation can be 8, 16, 24 or 0 when field is ommited");
5501 break;
5502 }
5503
5504 end_of_line (str);
5505
5506 }
5507
5508
5509 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
5510 word at the specified address and the following word
5511 respectively.
5512 Unconditionally executed.
5513 Error if Rn is R15.
5514 */
5515
5516 static void
5517 do_rfe (str)
5518 char *str;
5519 {
5520 int rn;
5521
5522 skip_whitespace (str);
5523
5524 if ((rn = reg_required_here (&str, 16)) == FAIL)
5525 return;
5526
5527 if (rn == REG_PC)
5528 {
5529 inst.error = BAD_PC;
5530 return;
5531 }
5532
5533 skip_whitespace (str);
5534
5535 if (*str == '!')
5536 {
5537 inst.instruction |= WRITE_BACK;
5538 str++;
5539 }
5540 end_of_line (str);
5541 }
5542
5543 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
5544 register (argument parse).
5545 REV{<cond>} Rd, Rm.
5546 Condition defaults to COND_ALWAYS.
5547 Error if Rd or Rm are R15. */
5548
5549 static void
5550 do_rev (str)
5551 char* str;
5552 {
5553 int rd, rm;
5554
5555 skip_whitespace (str);
5556
5557 if ((rd = reg_required_here (&str, 12)) == FAIL
5558 || skip_past_comma (&str) == FAIL
5559 || (rm = reg_required_here (&str, 0)) == FAIL)
5560 inst.error = BAD_ARGS;
5561
5562 else if (rd == REG_PC || rm == REG_PC)
5563 inst.error = BAD_PC;
5564
5565 else
5566 end_of_line (str);
5567 }
5568
5569 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
5570 QADD16{<cond>} <Rd>, <Rn>, <Rm>
5571 Condition defaults to COND_ALWAYS.
5572 Error if Rd, Rn or Rm are R15. */
5573
5574 static void
5575 do_qadd16 (str)
5576 char* str;
5577 {
5578 int rd, rm, rn;
5579
5580 skip_whitespace (str);
5581
5582 if ((rd = reg_required_here (&str, 12)) == FAIL
5583 || skip_past_comma (&str) == FAIL
5584 || (rn = reg_required_here (&str, 16)) == FAIL
5585 || skip_past_comma (&str) == FAIL
5586 || (rm = reg_required_here (&str, 0)) == FAIL)
5587 inst.error = BAD_ARGS;
5588
5589 else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
5590 inst.error = BAD_PC;
5591
5592 else
5593 end_of_line (str);
5594 }
5595
5596 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
5597 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
5598 Condition defaults to COND_ALWAYS.
5599 Error if Rd, Rn or Rm are R15. */
5600
5601 static void
5602 do_pkhbt (str)
5603 char* str;
5604 {
5605 do_pkh_core (str, SHIFT_LSL_IMMEDIATE);
5606 }
5607
5608 /* ARM V6 PKHTB (Argument Parse). */
5609
5610 static void
5611 do_pkhtb (str)
5612 char* str;
5613 {
5614 do_pkh_core (str, SHIFT_ASR_IMMEDIATE);
5615 }
5616
5617 static void
5618 do_pkh_core (str, shift)
5619 char* str;
5620 int shift;
5621 {
5622 int rd, rn, rm;
5623
5624 skip_whitespace (str);
5625 if (((rd = reg_required_here (&str, 12)) == FAIL)
5626 || (skip_past_comma (&str) == FAIL)
5627 || ((rn = reg_required_here (&str, 16)) == FAIL)
5628 || (skip_past_comma (&str) == FAIL)
5629 || ((rm = reg_required_here (&str, 0)) == FAIL))
5630 {
5631 inst.error = BAD_ARGS;
5632 return;
5633 }
5634
5635 else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
5636 {
5637 inst.error = BAD_PC;
5638 return;
5639 }
5640
5641 /* Check for optional shift immediate constant. */
5642 if (skip_past_comma (&str) == FAIL)
5643 {
5644 if (shift == SHIFT_ASR_IMMEDIATE)
5645 {
5646 /* If the shift specifier is ommited, turn the instruction
5647 into pkhbt rd, rm, rn. First, switch the instruction
5648 code, and clear the rn and rm fields. */
5649 inst.instruction &= 0xfff0f010;
5650 /* Now, re-encode the registers. */
5651 inst.instruction |= (rm << 16) | rn;
5652 }
5653 return;
5654 }
5655
5656 decode_shift (&str, shift);
5657 }
5658
5659 /* ARM V6 Load Register Exclusive instruction (argument parse).
5660 LDREX{<cond>} <Rd, [<Rn>]
5661 Condition defaults to COND_ALWAYS.
5662 Error if Rd or Rn are R15.
5663 See ARMARMv6 A4.1.27: LDREX. */
5664
5665
5666 static void
5667 do_ldrex (str)
5668 char * str;
5669 {
5670 int rd, rn;
5671
5672 skip_whitespace (str);
5673
5674 /* Parse Rd. */
5675 if (((rd = reg_required_here (&str, 12)) == FAIL)
5676 || (skip_past_comma (&str) == FAIL))
5677 {
5678 inst.error = BAD_ARGS;
5679 return;
5680 }
5681 else if (rd == REG_PC)
5682 {
5683 inst.error = BAD_PC;
5684 return;
5685 }
5686 skip_whitespace (str);
5687
5688 /* Skip past '['. */
5689 if ((strlen (str) >= 1)
5690 &&strncmp (str, "[", 1) == 0)
5691 str+=1;
5692 skip_whitespace (str);
5693
5694 /* Parse Rn. */
5695 if ((rn = reg_required_here (&str, 16)) == FAIL)
5696 {
5697 inst.error = BAD_ARGS;
5698 return;
5699 }
5700 else if (rn == REG_PC)
5701 {
5702 inst.error = BAD_PC;
5703 return;
5704 }
5705 skip_whitespace (str);
5706
5707 /* Skip past ']'. */
5708 if ((strlen (str) >= 1)
5709 && strncmp (str, "]", 1) == 0)
5710 str+=1;
5711
5712 end_of_line (str);
5713 }
5714
5715 /* ARM V6 change processor state instruction (argument parse)
5716 CPS, CPSIE, CSPID . */
5717
5718 static void
5719 do_cps (str)
5720 char * str;
5721 {
5722 do_cps_mode (&str);
5723 end_of_line (str);
5724 }
5725
5726 static void
5727 do_cpsi (str)
5728 char * str;
5729 {
5730 do_cps_flags (&str, /*thumb_p=*/0);
5731
5732 if (skip_past_comma (&str) == SUCCESS)
5733 {
5734 skip_whitespace (str);
5735 do_cps_mode (&str);
5736 }
5737 end_of_line (str);
5738 }
5739
5740 static void
5741 do_cps_mode (str)
5742 char **str;
5743 {
5744 expressionS expr;
5745
5746 skip_whitespace (*str);
5747
5748 if (! is_immediate_prefix (**str))
5749 {
5750 inst.error = _("immediate expression expected");
5751 return;
5752 }
5753
5754 (*str)++; /* Strip off the immediate signifier. */
5755 if (my_get_expression (&expr, str))
5756 {
5757 inst.error = _("bad expression");
5758 return;
5759 }
5760
5761 if (expr.X_op != O_constant)
5762 {
5763 inst.error = _("constant expression expected");
5764 return;
5765 }
5766
5767 /* The mode is a 5 bit field. Valid values are 0-31. */
5768 if (((unsigned) expr.X_add_number) > 31
5769 || (inst.reloc.exp.X_add_number) < 0)
5770 {
5771 inst.error = _("invalid constant");
5772 return;
5773 }
5774
5775 inst.instruction |= expr.X_add_number;
5776 }
5777
5778 static void
5779 do_cps_flags (str, thumb_p)
5780 char **str;
5781 int thumb_p;
5782 {
5783 struct cps_flag {
5784 char character;
5785 unsigned long arm_value;
5786 unsigned long thumb_value;
5787 };
5788 static struct cps_flag flag_table[] = {
5789 {'a', 0x100, 0x4 },
5790 {'i', 0x080, 0x2 },
5791 {'f', 0x040, 0x1 }
5792 };
5793
5794 int saw_a_flag = 0;
5795
5796 skip_whitespace (*str);
5797
5798 /* Get the a, f and i flags. */
5799 while (**str && **str != ',')
5800 {
5801 struct cps_flag *p;
5802 struct cps_flag *q = flag_table + sizeof (flag_table)/sizeof (*p);
5803 for (p = flag_table; p < q; ++p)
5804 if (strncasecmp (*str, &p->character, 1) == 0)
5805 {
5806 inst.instruction |= (thumb_p ? p->thumb_value : p->arm_value);
5807 saw_a_flag = 1;
5808 break;
5809 }
5810 if (p == q)
5811 {
5812 inst.error = _("unrecognized flag");
5813 return;
5814 }
5815 (*str)++;
5816 }
5817 if (!saw_a_flag)
5818 inst.error = _("no 'a', 'i', or 'f' flags for 'cps'");
5819 }
5820
5821 /* THUMB V5 breakpoint instruction (argument parse)
5822 BKPT <immed_8>. */
5823
5824 static void
5825 do_t_bkpt (str)
5826 char * str;
5827 {
5828 expressionS expr;
5829 unsigned long number;
5830
5831 skip_whitespace (str);
5832
5833 /* Allow optional leading '#'. */
5834 if (is_immediate_prefix (*str))
5835 str ++;
5836
5837 memset (& expr, '\0', sizeof (expr));
5838 if (my_get_expression (& expr, & str)
5839 || (expr.X_op != O_constant
5840 /* As a convenience we allow 'bkpt' without an operand. */
5841 && expr.X_op != O_absent))
5842 {
5843 inst.error = _("bad expression");
5844 return;
5845 }
5846
5847 number = expr.X_add_number;
5848
5849 /* Check it fits an 8 bit unsigned. */
5850 if (number != (number & 0xff))
5851 {
5852 inst.error = _("immediate value out of range");
5853 return;
5854 }
5855
5856 inst.instruction |= number;
5857
5858 end_of_line (str);
5859 }
5860
5861 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
5862 Expects inst.instruction is set for BLX(1).
5863 Note: this is cloned from do_branch, and the reloc changed to be a
5864 new one that can cope with setting one extra bit (the H bit). */
5865
5866 static void
5867 do_branch25 (str)
5868 char * str;
5869 {
5870 if (my_get_expression (& inst.reloc.exp, & str))
5871 return;
5872
5873 #ifdef OBJ_ELF
5874 {
5875 char * save_in;
5876
5877 /* ScottB: February 5, 1998 */
5878 /* Check to see of PLT32 reloc required for the instruction. */
5879
5880 /* arm_parse_reloc() works on input_line_pointer.
5881 We actually want to parse the operands to the branch instruction
5882 passed in 'str'. Save the input pointer and restore it later. */
5883 save_in = input_line_pointer;
5884 input_line_pointer = str;
5885
5886 if (inst.reloc.exp.X_op == O_symbol
5887 && *str == '('
5888 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
5889 {
5890 inst.reloc.type = BFD_RELOC_ARM_PLT32;
5891 inst.reloc.pc_rel = 0;
5892 /* Modify str to point to after parsed operands, otherwise
5893 end_of_line() will complain about the (PLT) left in str. */
5894 str = input_line_pointer;
5895 }
5896 else
5897 {
5898 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
5899 inst.reloc.pc_rel = 1;
5900 }
5901
5902 input_line_pointer = save_in;
5903 }
5904 #else
5905 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
5906 inst.reloc.pc_rel = 1;
5907 #endif /* OBJ_ELF */
5908
5909 end_of_line (str);
5910 }
5911
5912 /* ARM V5 branch-link-exchange instruction (argument parse)
5913 BLX <target_addr> ie BLX(1)
5914 BLX{<condition>} <Rm> ie BLX(2)
5915 Unfortunately, there are two different opcodes for this mnemonic.
5916 So, the insns[].value is not used, and the code here zaps values
5917 into inst.instruction.
5918 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
5919
5920 static void
5921 do_blx (str)
5922 char * str;
5923 {
5924 char * mystr = str;
5925 int rm;
5926
5927 skip_whitespace (mystr);
5928 rm = reg_required_here (& mystr, 0);
5929
5930 /* The above may set inst.error. Ignore his opinion. */
5931 inst.error = 0;
5932
5933 if (rm != FAIL)
5934 {
5935 /* Arg is a register.
5936 Use the condition code our caller put in inst.instruction.
5937 Pass ourselves off as a BX with a funny opcode. */
5938 inst.instruction |= 0x012fff30;
5939 do_bx (str);
5940 }
5941 else
5942 {
5943 /* This must be is BLX <target address>, no condition allowed. */
5944 if (inst.instruction != COND_ALWAYS)
5945 {
5946 inst.error = BAD_COND;
5947 return;
5948 }
5949
5950 inst.instruction = 0xfafffffe;
5951
5952 /* Process like a B/BL, but with a different reloc.
5953 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
5954 do_branch25 (str);
5955 }
5956 }
5957
5958 /* ARM V5 Thumb BLX (argument parse)
5959 BLX <target_addr> which is BLX(1)
5960 BLX <Rm> which is BLX(2)
5961 Unfortunately, there are two different opcodes for this mnemonic.
5962 So, the tinsns[].value is not used, and the code here zaps values
5963 into inst.instruction. */
5964
5965 static void
5966 do_t_blx (str)
5967 char * str;
5968 {
5969 char * mystr = str;
5970 int rm;
5971
5972 skip_whitespace (mystr);
5973 inst.instruction = 0x4780;
5974
5975 /* Note that this call is to the ARM register recognizer. BLX(2)
5976 uses the ARM register space, not the Thumb one, so a call to
5977 thumb_reg() would be wrong. */
5978 rm = reg_required_here (& mystr, 3);
5979 inst.error = 0;
5980
5981 if (rm != FAIL)
5982 {
5983 /* It's BLX(2). The .instruction was zapped with rm & is final. */
5984 inst.size = 2;
5985 }
5986 else
5987 {
5988 /* No ARM register. This must be BLX(1). Change the .instruction. */
5989 inst.instruction = 0xf7ffeffe;
5990 inst.size = 4;
5991
5992 if (my_get_expression (& inst.reloc.exp, & mystr))
5993 return;
5994
5995 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
5996 inst.reloc.pc_rel = 1;
5997 }
5998
5999 end_of_line (mystr);
6000 }
6001
6002 /* ARM V5 breakpoint instruction (argument parse)
6003 BKPT <16 bit unsigned immediate>
6004 Instruction is not conditional.
6005 The bit pattern given in insns[] has the COND_ALWAYS condition,
6006 and it is an error if the caller tried to override that. */
6007
6008 static void
6009 do_bkpt (str)
6010 char * str;
6011 {
6012 expressionS expr;
6013 unsigned long number;
6014
6015 skip_whitespace (str);
6016
6017 /* Allow optional leading '#'. */
6018 if (is_immediate_prefix (* str))
6019 str++;
6020
6021 memset (& expr, '\0', sizeof (expr));
6022
6023 if (my_get_expression (& expr, & str)
6024 || (expr.X_op != O_constant
6025 /* As a convenience we allow 'bkpt' without an operand. */
6026 && expr.X_op != O_absent))
6027 {
6028 inst.error = _("bad expression");
6029 return;
6030 }
6031
6032 number = expr.X_add_number;
6033
6034 /* Check it fits a 16 bit unsigned. */
6035 if (number != (number & 0xffff))
6036 {
6037 inst.error = _("immediate value out of range");
6038 return;
6039 }
6040
6041 /* Top 12 of 16 bits to bits 19:8. */
6042 inst.instruction |= (number & 0xfff0) << 4;
6043
6044 /* Bottom 4 of 16 bits to bits 3:0. */
6045 inst.instruction |= number & 0xf;
6046
6047 end_of_line (str);
6048 }
6049
6050 /* THUMB CPS instruction (argument parse). */
6051
6052 static void
6053 do_t_cps (str)
6054 char *str;
6055 {
6056 do_cps_flags (&str, /*thumb_p=*/1);
6057 end_of_line (str);
6058 }
6059
6060 /* THUMB CPY instruction (argument parse). */
6061
6062 static void
6063 do_t_cpy (str)
6064 char *str;
6065 {
6066 thumb_mov_compare (str, THUMB_CPY);
6067 }
6068
6069 /* THUMB SETEND instruction (argument parse). */
6070
6071 static void
6072 do_t_setend (str)
6073 char *str;
6074 {
6075 if (do_endian_specifier (str))
6076 inst.instruction |= 0x8;
6077 }
6078
6079 static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
6080
6081 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate. */
6082
6083 static unsigned long
6084 check_iwmmxt_insn (str, insn_type, immediate_size)
6085 char * str;
6086 enum iwmmxt_insn_type insn_type;
6087 int immediate_size;
6088 {
6089 int reg = 0;
6090 const char * inst_error;
6091 expressionS expr;
6092 unsigned long number;
6093
6094 inst_error = inst.error;
6095 if (!inst.error)
6096 inst.error = BAD_ARGS;
6097 skip_whitespace (str);
6098
6099 switch (insn_type)
6100 {
6101 case check_rd:
6102 if ((reg = reg_required_here (&str, 12)) == FAIL)
6103 return FAIL;
6104 break;
6105
6106 case check_wr:
6107 if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
6108 return FAIL;
6109 break;
6110
6111 case check_wrwr:
6112 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6113 || skip_past_comma (&str) == FAIL
6114 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6115 return FAIL;
6116 break;
6117
6118 case check_wrwrwr:
6119 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6120 || skip_past_comma (&str) == FAIL
6121 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6122 || skip_past_comma (&str) == FAIL
6123 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6124 return FAIL;
6125 break;
6126
6127 case check_wrwrwcg:
6128 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6129 || skip_past_comma (&str) == FAIL
6130 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6131 || skip_past_comma (&str) == FAIL
6132 || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
6133 return FAIL;
6134 break;
6135
6136 case check_tbcst:
6137 if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6138 || skip_past_comma (&str) == FAIL
6139 || reg_required_here (&str, 12) == FAIL))
6140 return FAIL;
6141 break;
6142
6143 case check_tmovmsk:
6144 if ((reg_required_here (&str, 12) == FAIL
6145 || skip_past_comma (&str) == FAIL
6146 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
6147 return FAIL;
6148 break;
6149
6150 case check_tmia:
6151 if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
6152 || skip_past_comma (&str) == FAIL
6153 || reg_required_here (&str, 0) == FAIL
6154 || skip_past_comma (&str) == FAIL
6155 || reg_required_here (&str, 12) == FAIL))
6156 return FAIL;
6157 break;
6158
6159 case check_tmcrr:
6160 if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6161 || skip_past_comma (&str) == FAIL
6162 || reg_required_here (&str, 12) == FAIL
6163 || skip_past_comma (&str) == FAIL
6164 || reg_required_here (&str, 16) == FAIL))
6165 return FAIL;
6166 break;
6167
6168 case check_tmrrc:
6169 if ((reg_required_here (&str, 12) == FAIL
6170 || skip_past_comma (&str) == FAIL
6171 || reg_required_here (&str, 16) == FAIL
6172 || skip_past_comma (&str) == FAIL
6173 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
6174 return FAIL;
6175 break;
6176
6177 case check_tmcr:
6178 if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
6179 || skip_past_comma (&str) == FAIL
6180 || reg_required_here (&str, 12) == FAIL))
6181 return FAIL;
6182 break;
6183
6184 case check_tmrc:
6185 if ((reg_required_here (&str, 12) == FAIL
6186 || skip_past_comma (&str) == FAIL
6187 || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
6188 return FAIL;
6189 break;
6190
6191 case check_tinsr:
6192 if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6193 || skip_past_comma (&str) == FAIL
6194 || reg_required_here (&str, 12) == FAIL
6195 || skip_past_comma (&str) == FAIL))
6196 return FAIL;
6197 break;
6198
6199 case check_textrc:
6200 if ((reg_required_here (&str, 12) == FAIL
6201 || skip_past_comma (&str) == FAIL))
6202 return FAIL;
6203 break;
6204
6205 case check_waligni:
6206 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6207 || skip_past_comma (&str) == FAIL
6208 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6209 || skip_past_comma (&str) == FAIL
6210 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
6211 || skip_past_comma (&str) == FAIL))
6212 return FAIL;
6213 break;
6214
6215 case check_textrm:
6216 if ((reg_required_here (&str, 12) == FAIL
6217 || skip_past_comma (&str) == FAIL
6218 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6219 || skip_past_comma (&str) == FAIL))
6220 return FAIL;
6221 break;
6222
6223 case check_wshufh:
6224 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
6225 || skip_past_comma (&str) == FAIL
6226 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
6227 || skip_past_comma (&str) == FAIL))
6228 return FAIL;
6229 break;
6230 }
6231
6232 if (immediate_size == 0)
6233 {
6234 end_of_line (str);
6235 inst.error = inst_error;
6236 return reg;
6237 }
6238 else
6239 {
6240 skip_whitespace (str);
6241
6242 /* Allow optional leading '#'. */
6243 if (is_immediate_prefix (* str))
6244 str++;
6245
6246 memset (& expr, '\0', sizeof (expr));
6247
6248 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
6249 {
6250 inst.error = _("bad or missing expression");
6251 return FAIL;
6252 }
6253
6254 number = expr.X_add_number;
6255
6256 if (number != (number & immediate_size))
6257 {
6258 inst.error = _("immediate value out of range");
6259 return FAIL;
6260 }
6261 end_of_line (str);
6262 inst.error = inst_error;
6263 return number;
6264 }
6265 }
6266
6267 static void
6268 do_iwmmxt_byte_addr (str)
6269 char * str;
6270 {
6271 int op = (inst.instruction & 0x300) >> 8;
6272 int reg;
6273
6274 inst.instruction &= ~0x300;
6275 inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
6276
6277 skip_whitespace (str);
6278
6279 if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6280 || skip_past_comma (& str) == FAIL
6281 || cp_byte_address_required_here (&str) == FAIL)
6282 {
6283 if (! inst.error)
6284 inst.error = BAD_ARGS;
6285 }
6286 else
6287 end_of_line (str);
6288
6289 if (wc_register (reg))
6290 {
6291 as_bad (_("non-word size not supported with control register"));
6292 inst.instruction |= 0xf0000100;
6293 inst.instruction &= ~0x00400000;
6294 }
6295 }
6296
6297 static void
6298 do_iwmmxt_tandc (str)
6299 char * str;
6300 {
6301 int reg;
6302
6303 reg = check_iwmmxt_insn (str, check_rd, 0);
6304
6305 if (reg != REG_PC && !inst.error)
6306 inst.error = _("only r15 allowed here");
6307 }
6308
6309 static void
6310 do_iwmmxt_tbcst (str)
6311 char * str;
6312 {
6313 check_iwmmxt_insn (str, check_tbcst, 0);
6314 }
6315
6316 static void
6317 do_iwmmxt_textrc (str)
6318 char * str;
6319 {
6320 unsigned long number;
6321
6322 if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
6323 return;
6324
6325 inst.instruction |= number & 0x7;
6326 }
6327
6328 static void
6329 do_iwmmxt_textrm (str)
6330 char * str;
6331 {
6332 unsigned long number;
6333
6334 if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
6335 return;
6336
6337 inst.instruction |= number & 0x7;
6338 }
6339
6340 static void
6341 do_iwmmxt_tinsr (str)
6342 char * str;
6343 {
6344 unsigned long number;
6345
6346 if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
6347 return;
6348
6349 inst.instruction |= number & 0x7;
6350 }
6351
6352 static void
6353 do_iwmmxt_tmcr (str)
6354 char * str;
6355 {
6356 check_iwmmxt_insn (str, check_tmcr, 0);
6357 }
6358
6359 static void
6360 do_iwmmxt_tmcrr (str)
6361 char * str;
6362 {
6363 check_iwmmxt_insn (str, check_tmcrr, 0);
6364 }
6365
6366 static void
6367 do_iwmmxt_tmia (str)
6368 char * str;
6369 {
6370 check_iwmmxt_insn (str, check_tmia, 0);
6371 }
6372
6373 static void
6374 do_iwmmxt_tmovmsk (str)
6375 char * str;
6376 {
6377 check_iwmmxt_insn (str, check_tmovmsk, 0);
6378 }
6379
6380 static void
6381 do_iwmmxt_tmrc (str)
6382 char * str;
6383 {
6384 check_iwmmxt_insn (str, check_tmrc, 0);
6385 }
6386
6387 static void
6388 do_iwmmxt_tmrrc (str)
6389 char * str;
6390 {
6391 check_iwmmxt_insn (str, check_tmrrc, 0);
6392 }
6393
6394 static void
6395 do_iwmmxt_torc (str)
6396 char * str;
6397 {
6398 check_iwmmxt_insn (str, check_rd, 0);
6399 }
6400
6401 static void
6402 do_iwmmxt_waligni (str)
6403 char * str;
6404 {
6405 unsigned long number;
6406
6407 if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
6408 return;
6409
6410 inst.instruction |= ((number & 0x7) << 20);
6411 }
6412
6413 static void
6414 do_iwmmxt_wmov (str)
6415 char * str;
6416 {
6417 if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
6418 return;
6419
6420 inst.instruction |= ((inst.instruction >> 16) & 0xf);
6421 }
6422
6423 static void
6424 do_iwmmxt_word_addr (str)
6425 char * str;
6426 {
6427 int op = (inst.instruction & 0x300) >> 8;
6428 int reg;
6429
6430 inst.instruction &= ~0x300;
6431 inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
6432
6433 skip_whitespace (str);
6434
6435 if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
6436 || skip_past_comma (& str) == FAIL
6437 || cp_address_required_here (& str, CP_WB_OK) == FAIL)
6438 {
6439 if (! inst.error)
6440 inst.error = BAD_ARGS;
6441 }
6442 else
6443 end_of_line (str);
6444
6445 if (wc_register (reg))
6446 {
6447 if ((inst.instruction & COND_MASK) != COND_ALWAYS)
6448 as_bad (_("conditional execution not supported with control register"));
6449 if (op != 2)
6450 as_bad (_("non-word size not supported with control register"));
6451 inst.instruction |= 0xf0000100;
6452 inst.instruction &= ~0x00400000;
6453 }
6454 }
6455
6456 static void
6457 do_iwmmxt_wrwr (str)
6458 char * str;
6459 {
6460 check_iwmmxt_insn (str, check_wrwr, 0);
6461 }
6462
6463 static void
6464 do_iwmmxt_wrwrwcg (str)
6465 char * str;
6466 {
6467 check_iwmmxt_insn (str, check_wrwrwcg, 0);
6468 }
6469
6470 static void
6471 do_iwmmxt_wrwrwr (str)
6472 char * str;
6473 {
6474 check_iwmmxt_insn (str, check_wrwrwr, 0);
6475 }
6476
6477 static void
6478 do_iwmmxt_wshufh (str)
6479 char * str;
6480 {
6481 unsigned long number;
6482
6483 if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
6484 return;
6485
6486 inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
6487 }
6488
6489 static void
6490 do_iwmmxt_wzero (str)
6491 char * str;
6492 {
6493 if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
6494 return;
6495
6496 inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
6497 }
6498
6499 /* Xscale multiply-accumulate (argument parse)
6500 MIAcc acc0,Rm,Rs
6501 MIAPHcc acc0,Rm,Rs
6502 MIAxycc acc0,Rm,Rs. */
6503
6504 static void
6505 do_xsc_mia (str)
6506 char * str;
6507 {
6508 int rs;
6509 int rm;
6510
6511 if (accum0_required_here (& str) == FAIL)
6512 inst.error = ERR_NO_ACCUM;
6513
6514 else if (skip_past_comma (& str) == FAIL
6515 || (rm = reg_required_here (& str, 0)) == FAIL)
6516 inst.error = BAD_ARGS;
6517
6518 else if (skip_past_comma (& str) == FAIL
6519 || (rs = reg_required_here (& str, 12)) == FAIL)
6520 inst.error = BAD_ARGS;
6521
6522 /* inst.instruction has now been zapped with both rm and rs. */
6523 else if (rm == REG_PC || rs == REG_PC)
6524 inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */
6525
6526 else
6527 end_of_line (str);
6528 }
6529
6530 /* Xscale move-accumulator-register (argument parse)
6531
6532 MARcc acc0,RdLo,RdHi. */
6533
6534 static void
6535 do_xsc_mar (str)
6536 char * str;
6537 {
6538 int rdlo, rdhi;
6539
6540 if (accum0_required_here (& str) == FAIL)
6541 inst.error = ERR_NO_ACCUM;
6542
6543 else if (skip_past_comma (& str) == FAIL
6544 || (rdlo = reg_required_here (& str, 12)) == FAIL)
6545 inst.error = BAD_ARGS;
6546
6547 else if (skip_past_comma (& str) == FAIL
6548 || (rdhi = reg_required_here (& str, 16)) == FAIL)
6549 inst.error = BAD_ARGS;
6550
6551 /* inst.instruction has now been zapped with both rdlo and rdhi. */
6552 else if (rdlo == REG_PC || rdhi == REG_PC)
6553 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
6554
6555 else
6556 end_of_line (str);
6557 }
6558
6559 /* Xscale move-register-accumulator (argument parse)
6560
6561 MRAcc RdLo,RdHi,acc0. */
6562
6563 static void
6564 do_xsc_mra (str)
6565 char * str;
6566 {
6567 int rdlo;
6568 int rdhi;
6569
6570 skip_whitespace (str);
6571
6572 if ((rdlo = reg_required_here (& str, 12)) == FAIL)
6573 inst.error = BAD_ARGS;
6574
6575 else if (skip_past_comma (& str) == FAIL
6576 || (rdhi = reg_required_here (& str, 16)) == FAIL)
6577 inst.error = BAD_ARGS;
6578
6579 else if (skip_past_comma (& str) == FAIL
6580 || accum0_required_here (& str) == FAIL)
6581 inst.error = ERR_NO_ACCUM;
6582
6583 /* inst.instruction has now been zapped with both rdlo and rdhi. */
6584 else if (rdlo == rdhi)
6585 inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */
6586
6587 else if (rdlo == REG_PC || rdhi == REG_PC)
6588 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
6589 else
6590 end_of_line (str);
6591 }
6592
6593 /* ARMv5TE: Preload-Cache
6594
6595 PLD <addr_mode>
6596
6597 Syntactically, like LDR with B=1, W=0, L=1. */
6598
6599 static void
6600 do_pld (str)
6601 char * str;
6602 {
6603 int rd;
6604
6605 skip_whitespace (str);
6606
6607 if (* str != '[')
6608 {
6609 inst.error = _("'[' expected after PLD mnemonic");
6610 return;
6611 }
6612
6613 ++str;
6614 skip_whitespace (str);
6615
6616 if ((rd = reg_required_here (& str, 16)) == FAIL)
6617 return;
6618
6619 skip_whitespace (str);
6620
6621 if (*str == ']')
6622 {
6623 /* [Rn], ... ? */
6624 ++str;
6625 skip_whitespace (str);
6626
6627 /* Post-indexed addressing is not allowed with PLD. */
6628 if (skip_past_comma (&str) == SUCCESS)
6629 {
6630 inst.error
6631 = _("post-indexed expression used in preload instruction");
6632 return;
6633 }
6634 else if (*str == '!') /* [Rn]! */
6635 {
6636 inst.error = _("writeback used in preload instruction");
6637 ++str;
6638 }
6639 else /* [Rn] */
6640 inst.instruction |= INDEX_UP | PRE_INDEX;
6641 }
6642 else /* [Rn, ...] */
6643 {
6644 if (skip_past_comma (& str) == FAIL)
6645 {
6646 inst.error = _("pre-indexed expression expected");
6647 return;
6648 }
6649
6650 if (ldst_extend (&str) == FAIL)
6651 return;
6652
6653 skip_whitespace (str);
6654
6655 if (* str != ']')
6656 {
6657 inst.error = _("missing ]");
6658 return;
6659 }
6660
6661 ++ str;
6662 skip_whitespace (str);
6663
6664 if (* str == '!') /* [Rn]! */
6665 {
6666 inst.error = _("writeback used in preload instruction");
6667 ++ str;
6668 }
6669
6670 inst.instruction |= PRE_INDEX;
6671 }
6672
6673 end_of_line (str);
6674 }
6675
6676 /* ARMv5TE load-consecutive (argument parse)
6677 Mode is like LDRH.
6678
6679 LDRccD R, mode
6680 STRccD R, mode. */
6681
6682 static void
6683 do_ldrd (str)
6684 char * str;
6685 {
6686 int rd;
6687 int rn;
6688
6689 skip_whitespace (str);
6690
6691 if ((rd = reg_required_here (& str, 12)) == FAIL)
6692 {
6693 inst.error = BAD_ARGS;
6694 return;
6695 }
6696
6697 if (skip_past_comma (& str) == FAIL
6698 || (rn = ld_mode_required_here (& str)) == FAIL)
6699 {
6700 if (!inst.error)
6701 inst.error = BAD_ARGS;
6702 return;
6703 }
6704
6705 /* inst.instruction has now been zapped with Rd and the addressing mode. */
6706 if (rd & 1) /* Unpredictable result if Rd is odd. */
6707 {
6708 inst.error = _("destination register must be even");
6709 return;
6710 }
6711
6712 if (rd == REG_LR)
6713 {
6714 inst.error = _("r14 not allowed here");
6715 return;
6716 }
6717
6718 if (((rd == rn) || (rd + 1 == rn))
6719 && ((inst.instruction & WRITE_BACK)
6720 || (!(inst.instruction & PRE_INDEX))))
6721 as_warn (_("pre/post-indexing used when modified address register is destination"));
6722
6723 /* For an index-register load, the index register must not overlap the
6724 destination (even if not write-back). */
6725 if ((inst.instruction & V4_STR_BIT) == 0
6726 && (inst.instruction & HWOFFSET_IMM) == 0)
6727 {
6728 int rm = inst.instruction & 0x0000000f;
6729
6730 if (rm == rd || (rm == rd + 1))
6731 as_warn (_("ldrd destination registers must not overlap index register"));
6732 }
6733
6734 end_of_line (str);
6735 }
6736
6737 /* Returns the index into fp_values of a floating point number,
6738 or -1 if not in the table. */
6739
6740 static int
6741 my_get_float_expression (str)
6742 char ** str;
6743 {
6744 LITTLENUM_TYPE words[MAX_LITTLENUMS];
6745 char * save_in;
6746 expressionS exp;
6747 int i;
6748 int j;
6749
6750 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
6751
6752 /* Look for a raw floating point number. */
6753 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
6754 && is_end_of_line[(unsigned char) *save_in])
6755 {
6756 for (i = 0; i < NUM_FLOAT_VALS; i++)
6757 {
6758 for (j = 0; j < MAX_LITTLENUMS; j++)
6759 {
6760 if (words[j] != fp_values[i][j])
6761 break;
6762 }
6763
6764 if (j == MAX_LITTLENUMS)
6765 {
6766 *str = save_in;
6767 return i;
6768 }
6769 }
6770 }
6771
6772 /* Try and parse a more complex expression, this will probably fail
6773 unless the code uses a floating point prefix (eg "0f"). */
6774 save_in = input_line_pointer;
6775 input_line_pointer = *str;
6776 if (expression (&exp) == absolute_section
6777 && exp.X_op == O_big
6778 && exp.X_add_number < 0)
6779 {
6780 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
6781 Ditto for 15. */
6782 if (gen_to_words (words, 5, (long) 15) == 0)
6783 {
6784 for (i = 0; i < NUM_FLOAT_VALS; i++)
6785 {
6786 for (j = 0; j < MAX_LITTLENUMS; j++)
6787 {
6788 if (words[j] != fp_values[i][j])
6789 break;
6790 }
6791
6792 if (j == MAX_LITTLENUMS)
6793 {
6794 *str = input_line_pointer;
6795 input_line_pointer = save_in;
6796 return i;
6797 }
6798 }
6799 }
6800 }
6801
6802 *str = input_line_pointer;
6803 input_line_pointer = save_in;
6804 return -1;
6805 }
6806
6807 /* Return TRUE if anything in the expression is a bignum. */
6808
6809 static int
6810 walk_no_bignums (sp)
6811 symbolS * sp;
6812 {
6813 if (symbol_get_value_expression (sp)->X_op == O_big)
6814 return 1;
6815
6816 if (symbol_get_value_expression (sp)->X_add_symbol)
6817 {
6818 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
6819 || (symbol_get_value_expression (sp)->X_op_symbol
6820 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
6821 }
6822
6823 return 0;
6824 }
6825
6826 static int in_my_get_expression = 0;
6827
6828 static int
6829 my_get_expression (ep, str)
6830 expressionS * ep;
6831 char ** str;
6832 {
6833 char * save_in;
6834 segT seg;
6835
6836 save_in = input_line_pointer;
6837 input_line_pointer = *str;
6838 in_my_get_expression = 1;
6839 seg = expression (ep);
6840 in_my_get_expression = 0;
6841
6842 if (ep->X_op == O_illegal)
6843 {
6844 /* We found a bad expression in md_operand(). */
6845 *str = input_line_pointer;
6846 input_line_pointer = save_in;
6847 return 1;
6848 }
6849
6850 #ifdef OBJ_AOUT
6851 if (seg != absolute_section
6852 && seg != text_section
6853 && seg != data_section
6854 && seg != bss_section
6855 && seg != undefined_section)
6856 {
6857 inst.error = _("bad_segment");
6858 *str = input_line_pointer;
6859 input_line_pointer = save_in;
6860 return 1;
6861 }
6862 #endif
6863
6864 /* Get rid of any bignums now, so that we don't generate an error for which
6865 we can't establish a line number later on. Big numbers are never valid
6866 in instructions, which is where this routine is always called. */
6867 if (ep->X_op == O_big
6868 || (ep->X_add_symbol
6869 && (walk_no_bignums (ep->X_add_symbol)
6870 || (ep->X_op_symbol
6871 && walk_no_bignums (ep->X_op_symbol)))))
6872 {
6873 inst.error = _("invalid constant");
6874 *str = input_line_pointer;
6875 input_line_pointer = save_in;
6876 return 1;
6877 }
6878
6879 *str = input_line_pointer;
6880 input_line_pointer = save_in;
6881 return 0;
6882 }
6883
6884 /* We handle all bad expressions here, so that we can report the faulty
6885 instruction in the error message. */
6886 void
6887 md_operand (expr)
6888 expressionS *expr;
6889 {
6890 if (in_my_get_expression)
6891 {
6892 expr->X_op = O_illegal;
6893 if (inst.error == NULL)
6894 inst.error = _("bad expression");
6895 }
6896 }
6897
6898 /* KIND indicates what kind of shifts are accepted. */
6899
6900 static int
6901 decode_shift (str, kind)
6902 char ** str;
6903 int kind;
6904 {
6905 const struct asm_shift_name * shift;
6906 char * p;
6907 char c;
6908
6909 skip_whitespace (* str);
6910
6911 for (p = * str; ISALPHA (* p); p ++)
6912 ;
6913
6914 if (p == * str)
6915 {
6916 inst.error = _("shift expression expected");
6917 return FAIL;
6918 }
6919
6920 c = * p;
6921 * p = '\0';
6922 shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
6923 * p = c;
6924
6925 if (shift == NULL)
6926 {
6927 inst.error = _("shift expression expected");
6928 return FAIL;
6929 }
6930
6931 assert (shift->properties->index == shift_properties[shift->properties->index].index);
6932
6933 if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
6934 && shift->properties->index != SHIFT_LSL
6935 && shift->properties->index != SHIFT_ASR)
6936 {
6937 inst.error = _("'LSL' or 'ASR' required");
6938 return FAIL;
6939 }
6940 else if (kind == SHIFT_LSL_IMMEDIATE
6941 && shift->properties->index != SHIFT_LSL)
6942 {
6943 inst.error = _("'LSL' required");
6944 return FAIL;
6945 }
6946 else if (kind == SHIFT_ASR_IMMEDIATE
6947 && shift->properties->index != SHIFT_ASR)
6948 {
6949 inst.error = _("'ASR' required");
6950 return FAIL;
6951 }
6952
6953 if (shift->properties->index == SHIFT_RRX)
6954 {
6955 * str = p;
6956 inst.instruction |= shift->properties->bit_field;
6957 return SUCCESS;
6958 }
6959
6960 skip_whitespace (p);
6961
6962 if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
6963 {
6964 inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
6965 * str = p;
6966 return SUCCESS;
6967 }
6968 else if (! is_immediate_prefix (* p))
6969 {
6970 inst.error = (NO_SHIFT_RESTRICT
6971 ? _("shift requires register or #expression")
6972 : _("shift requires #expression"));
6973 * str = p;
6974 return FAIL;
6975 }
6976
6977 inst.error = NULL;
6978 p ++;
6979
6980 if (my_get_expression (& inst.reloc.exp, & p))
6981 return FAIL;
6982
6983 /* Validate some simple #expressions. */
6984 if (inst.reloc.exp.X_op == O_constant)
6985 {
6986 unsigned num = inst.reloc.exp.X_add_number;
6987
6988 /* Reject operations greater than 32. */
6989 if (num > 32
6990 /* Reject a shift of 0 unless the mode allows it. */
6991 || (num == 0 && shift->properties->allows_0 == 0)
6992 /* Reject a shift of 32 unless the mode allows it. */
6993 || (num == 32 && shift->properties->allows_32 == 0)
6994 )
6995 {
6996 /* As a special case we allow a shift of zero for
6997 modes that do not support it to be recoded as an
6998 logical shift left of zero (ie nothing). We warn
6999 about this though. */
7000 if (num == 0)
7001 {
7002 as_warn (_("shift of 0 ignored."));
7003 shift = & shift_names[0];
7004 assert (shift->properties->index == SHIFT_LSL);
7005 }
7006 else
7007 {
7008 inst.error = _("invalid immediate shift");
7009 return FAIL;
7010 }
7011 }
7012
7013 /* Shifts of 32 are encoded as 0, for those shifts that
7014 support it. */
7015 if (num == 32)
7016 num = 0;
7017
7018 inst.instruction |= (num << 7) | shift->properties->bit_field;
7019 }
7020 else
7021 {
7022 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
7023 inst.reloc.pc_rel = 0;
7024 inst.instruction |= shift->properties->bit_field;
7025 }
7026
7027 * str = p;
7028 return SUCCESS;
7029 }
7030
7031 /* Do those data_ops which can take a negative immediate constant
7032 by altering the instruction. A bit of a hack really.
7033 MOV <-> MVN
7034 AND <-> BIC
7035 ADC <-> SBC
7036 by inverting the second operand, and
7037 ADD <-> SUB
7038 CMP <-> CMN
7039 by negating the second operand. */
7040
7041 static int
7042 negate_data_op (instruction, value)
7043 unsigned long * instruction;
7044 unsigned long value;
7045 {
7046 int op, new_inst;
7047 unsigned long negated, inverted;
7048
7049 negated = validate_immediate (-value);
7050 inverted = validate_immediate (~value);
7051
7052 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
7053 switch (op)
7054 {
7055 /* First negates. */
7056 case OPCODE_SUB: /* ADD <-> SUB */
7057 new_inst = OPCODE_ADD;
7058 value = negated;
7059 break;
7060
7061 case OPCODE_ADD:
7062 new_inst = OPCODE_SUB;
7063 value = negated;
7064 break;
7065
7066 case OPCODE_CMP: /* CMP <-> CMN */
7067 new_inst = OPCODE_CMN;
7068 value = negated;
7069 break;
7070
7071 case OPCODE_CMN:
7072 new_inst = OPCODE_CMP;
7073 value = negated;
7074 break;
7075
7076 /* Now Inverted ops. */
7077 case OPCODE_MOV: /* MOV <-> MVN */
7078 new_inst = OPCODE_MVN;
7079 value = inverted;
7080 break;
7081
7082 case OPCODE_MVN:
7083 new_inst = OPCODE_MOV;
7084 value = inverted;
7085 break;
7086
7087 case OPCODE_AND: /* AND <-> BIC */
7088 new_inst = OPCODE_BIC;
7089 value = inverted;
7090 break;
7091
7092 case OPCODE_BIC:
7093 new_inst = OPCODE_AND;
7094 value = inverted;
7095 break;
7096
7097 case OPCODE_ADC: /* ADC <-> SBC */
7098 new_inst = OPCODE_SBC;
7099 value = inverted;
7100 break;
7101
7102 case OPCODE_SBC:
7103 new_inst = OPCODE_ADC;
7104 value = inverted;
7105 break;
7106
7107 /* We cannot do anything. */
7108 default:
7109 return FAIL;
7110 }
7111
7112 if (value == (unsigned) FAIL)
7113 return FAIL;
7114
7115 *instruction &= OPCODE_MASK;
7116 *instruction |= new_inst << DATA_OP_SHIFT;
7117 return value;
7118 }
7119
7120 static int
7121 data_op2 (str)
7122 char ** str;
7123 {
7124 int value;
7125 expressionS expr;
7126
7127 skip_whitespace (* str);
7128
7129 if (reg_required_here (str, 0) != FAIL)
7130 {
7131 if (skip_past_comma (str) == SUCCESS)
7132 /* Shift operation on register. */
7133 return decode_shift (str, NO_SHIFT_RESTRICT);
7134
7135 return SUCCESS;
7136 }
7137 else
7138 {
7139 /* Immediate expression. */
7140 if (is_immediate_prefix (**str))
7141 {
7142 (*str)++;
7143 inst.error = NULL;
7144
7145 if (my_get_expression (&inst.reloc.exp, str))
7146 return FAIL;
7147
7148 if (inst.reloc.exp.X_add_symbol)
7149 {
7150 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7151 inst.reloc.pc_rel = 0;
7152 }
7153 else
7154 {
7155 if (skip_past_comma (str) == SUCCESS)
7156 {
7157 /* #x, y -- ie explicit rotation by Y. */
7158 if (my_get_expression (&expr, str))
7159 return FAIL;
7160
7161 if (expr.X_op != O_constant)
7162 {
7163 inst.error = _("constant expression expected");
7164 return FAIL;
7165 }
7166
7167 /* Rotate must be a multiple of 2. */
7168 if (((unsigned) expr.X_add_number) > 30
7169 || (expr.X_add_number & 1) != 0
7170 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
7171 {
7172 inst.error = _("invalid constant");
7173 return FAIL;
7174 }
7175 inst.instruction |= INST_IMMEDIATE;
7176 inst.instruction |= inst.reloc.exp.X_add_number;
7177 inst.instruction |= expr.X_add_number << 7;
7178 return SUCCESS;
7179 }
7180
7181 /* Implicit rotation, select a suitable one. */
7182 value = validate_immediate (inst.reloc.exp.X_add_number);
7183
7184 if (value == FAIL)
7185 {
7186 /* Can't be done. Perhaps the code reads something like
7187 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
7188 if ((value = negate_data_op (&inst.instruction,
7189 inst.reloc.exp.X_add_number))
7190 == FAIL)
7191 {
7192 inst.error = _("invalid constant");
7193 return FAIL;
7194 }
7195 }
7196
7197 inst.instruction |= value;
7198 }
7199
7200 inst.instruction |= INST_IMMEDIATE;
7201 return SUCCESS;
7202 }
7203
7204 (*str)++;
7205 inst.error = _("register or shift expression expected");
7206 return FAIL;
7207 }
7208 }
7209
7210 static int
7211 fp_op2 (str)
7212 char ** str;
7213 {
7214 skip_whitespace (* str);
7215
7216 if (fp_reg_required_here (str, 0) != FAIL)
7217 return SUCCESS;
7218 else
7219 {
7220 /* Immediate expression. */
7221 if (*((*str)++) == '#')
7222 {
7223 int i;
7224
7225 inst.error = NULL;
7226
7227 skip_whitespace (* str);
7228
7229 /* First try and match exact strings, this is to guarantee
7230 that some formats will work even for cross assembly. */
7231
7232 for (i = 0; fp_const[i]; i++)
7233 {
7234 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
7235 {
7236 char *start = *str;
7237
7238 *str += strlen (fp_const[i]);
7239 if (is_end_of_line[(unsigned char) **str])
7240 {
7241 inst.instruction |= i + 8;
7242 return SUCCESS;
7243 }
7244 *str = start;
7245 }
7246 }
7247
7248 /* Just because we didn't get a match doesn't mean that the
7249 constant isn't valid, just that it is in a format that we
7250 don't automatically recognize. Try parsing it with
7251 the standard expression routines. */
7252 if ((i = my_get_float_expression (str)) >= 0)
7253 {
7254 inst.instruction |= i + 8;
7255 return SUCCESS;
7256 }
7257
7258 inst.error = _("invalid floating point immediate expression");
7259 return FAIL;
7260 }
7261 inst.error =
7262 _("floating point register or immediate expression expected");
7263 return FAIL;
7264 }
7265 }
7266
7267 static void
7268 do_arit (str)
7269 char * str;
7270 {
7271 skip_whitespace (str);
7272
7273 if (reg_required_here (&str, 12) == FAIL
7274 || skip_past_comma (&str) == FAIL
7275 || reg_required_here (&str, 16) == FAIL
7276 || skip_past_comma (&str) == FAIL
7277 || data_op2 (&str) == FAIL)
7278 {
7279 if (!inst.error)
7280 inst.error = BAD_ARGS;
7281 return;
7282 }
7283
7284 end_of_line (str);
7285 }
7286
7287 static void
7288 do_adr (str)
7289 char * str;
7290 {
7291 /* This is a pseudo-op of the form "adr rd, label" to be converted
7292 into a relative address of the form "add rd, pc, #label-.-8". */
7293 skip_whitespace (str);
7294
7295 if (reg_required_here (&str, 12) == FAIL
7296 || skip_past_comma (&str) == FAIL
7297 || my_get_expression (&inst.reloc.exp, &str))
7298 {
7299 if (!inst.error)
7300 inst.error = BAD_ARGS;
7301 return;
7302 }
7303
7304 /* Frag hacking will turn this into a sub instruction if the offset turns
7305 out to be negative. */
7306 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
7307 #ifndef TE_WINCE
7308 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
7309 #endif
7310 inst.reloc.pc_rel = 1;
7311
7312 end_of_line (str);
7313 }
7314
7315 static void
7316 do_adrl (str)
7317 char * str;
7318 {
7319 /* This is a pseudo-op of the form "adrl rd, label" to be converted
7320 into a relative address of the form:
7321 add rd, pc, #low(label-.-8)"
7322 add rd, rd, #high(label-.-8)" */
7323
7324 skip_whitespace (str);
7325
7326 if (reg_required_here (&str, 12) == FAIL
7327 || skip_past_comma (&str) == FAIL
7328 || my_get_expression (&inst.reloc.exp, &str))
7329 {
7330 if (!inst.error)
7331 inst.error = BAD_ARGS;
7332
7333 return;
7334 }
7335
7336 end_of_line (str);
7337 /* Frag hacking will turn this into a sub instruction if the offset turns
7338 out to be negative. */
7339 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
7340 #ifndef TE_WINCE
7341 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
7342 #endif
7343 inst.reloc.pc_rel = 1;
7344 inst.size = INSN_SIZE * 2;
7345 }
7346
7347 static void
7348 do_cmp (str)
7349 char * str;
7350 {
7351 skip_whitespace (str);
7352
7353 if (reg_required_here (&str, 16) == FAIL)
7354 {
7355 if (!inst.error)
7356 inst.error = BAD_ARGS;
7357 return;
7358 }
7359
7360 if (skip_past_comma (&str) == FAIL
7361 || data_op2 (&str) == FAIL)
7362 {
7363 if (!inst.error)
7364 inst.error = BAD_ARGS;
7365 return;
7366 }
7367
7368 end_of_line (str);
7369 }
7370
7371 static void
7372 do_mov (str)
7373 char * str;
7374 {
7375 skip_whitespace (str);
7376
7377 if (reg_required_here (&str, 12) == FAIL)
7378 {
7379 if (!inst.error)
7380 inst.error = BAD_ARGS;
7381 return;
7382 }
7383
7384 if (skip_past_comma (&str) == FAIL
7385 || data_op2 (&str) == FAIL)
7386 {
7387 if (!inst.error)
7388 inst.error = BAD_ARGS;
7389 return;
7390 }
7391
7392 end_of_line (str);
7393 }
7394
7395 static int
7396 ldst_extend (str)
7397 char ** str;
7398 {
7399 int add = INDEX_UP;
7400
7401 switch (**str)
7402 {
7403 case '#':
7404 case '$':
7405 (*str)++;
7406 if (my_get_expression (& inst.reloc.exp, str))
7407 return FAIL;
7408
7409 if (inst.reloc.exp.X_op == O_constant)
7410 {
7411 int value = inst.reloc.exp.X_add_number;
7412
7413 if (value < -4095 || value > 4095)
7414 {
7415 inst.error = _("address offset too large");
7416 return FAIL;
7417 }
7418
7419 if (value < 0)
7420 {
7421 value = -value;
7422 add = 0;
7423 }
7424
7425 inst.instruction |= add | value;
7426 }
7427 else
7428 {
7429 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7430 inst.reloc.pc_rel = 0;
7431 }
7432 return SUCCESS;
7433
7434 case '-':
7435 add = 0;
7436 /* Fall through. */
7437
7438 case '+':
7439 (*str)++;
7440 /* Fall through. */
7441
7442 default:
7443 if (reg_required_here (str, 0) == FAIL)
7444 return FAIL;
7445
7446 inst.instruction |= add | OFFSET_REG;
7447 if (skip_past_comma (str) == SUCCESS)
7448 return decode_shift (str, SHIFT_IMMEDIATE);
7449
7450 return SUCCESS;
7451 }
7452 }
7453
7454 static void
7455 do_ldst (str)
7456 char * str;
7457 {
7458 int pre_inc = 0;
7459 int conflict_reg;
7460 int value;
7461
7462 skip_whitespace (str);
7463
7464 if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
7465 {
7466 if (!inst.error)
7467 inst.error = BAD_ARGS;
7468 return;
7469 }
7470
7471 if (skip_past_comma (&str) == FAIL)
7472 {
7473 inst.error = _("address expected");
7474 return;
7475 }
7476
7477 if (*str == '[')
7478 {
7479 int reg;
7480
7481 str++;
7482
7483 skip_whitespace (str);
7484
7485 if ((reg = reg_required_here (&str, 16)) == FAIL)
7486 return;
7487
7488 /* Conflicts can occur on stores as well as loads. */
7489 conflict_reg = (conflict_reg == reg);
7490
7491 skip_whitespace (str);
7492
7493 if (*str == ']')
7494 {
7495 str ++;
7496
7497 if (skip_past_comma (&str) == SUCCESS)
7498 {
7499 /* [Rn],... (post inc) */
7500 if (ldst_extend (&str) == FAIL)
7501 return;
7502 if (conflict_reg)
7503 as_warn (_("%s register same as write-back base"),
7504 ((inst.instruction & LOAD_BIT)
7505 ? _("destination") : _("source")));
7506 }
7507 else
7508 {
7509 /* [Rn] */
7510 skip_whitespace (str);
7511
7512 if (*str == '!')
7513 {
7514 if (conflict_reg)
7515 as_warn (_("%s register same as write-back base"),
7516 ((inst.instruction & LOAD_BIT)
7517 ? _("destination") : _("source")));
7518 str++;
7519 inst.instruction |= WRITE_BACK;
7520 }
7521
7522 inst.instruction |= INDEX_UP;
7523 pre_inc = 1;
7524 }
7525 }
7526 else
7527 {
7528 /* [Rn,...] */
7529 if (skip_past_comma (&str) == FAIL)
7530 {
7531 inst.error = _("pre-indexed expression expected");
7532 return;
7533 }
7534
7535 pre_inc = 1;
7536 if (ldst_extend (&str) == FAIL)
7537 return;
7538
7539 skip_whitespace (str);
7540
7541 if (*str++ != ']')
7542 {
7543 inst.error = _("missing ]");
7544 return;
7545 }
7546
7547 skip_whitespace (str);
7548
7549 if (*str == '!')
7550 {
7551 if (conflict_reg)
7552 as_warn (_("%s register same as write-back base"),
7553 ((inst.instruction & LOAD_BIT)
7554 ? _("destination") : _("source")));
7555 str++;
7556 inst.instruction |= WRITE_BACK;
7557 }
7558 }
7559 }
7560 else if (*str == '=')
7561 {
7562 if ((inst.instruction & LOAD_BIT) == 0)
7563 {
7564 inst.error = _("invalid pseudo operation");
7565 return;
7566 }
7567
7568 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
7569 str++;
7570
7571 skip_whitespace (str);
7572
7573 if (my_get_expression (&inst.reloc.exp, &str))
7574 return;
7575
7576 if (inst.reloc.exp.X_op != O_constant
7577 && inst.reloc.exp.X_op != O_symbol)
7578 {
7579 inst.error = _("constant expression expected");
7580 return;
7581 }
7582
7583 if (inst.reloc.exp.X_op == O_constant)
7584 {
7585 value = validate_immediate (inst.reloc.exp.X_add_number);
7586
7587 if (value != FAIL)
7588 {
7589 /* This can be done with a mov instruction. */
7590 inst.instruction &= LITERAL_MASK;
7591 inst.instruction |= (INST_IMMEDIATE
7592 | (OPCODE_MOV << DATA_OP_SHIFT));
7593 inst.instruction |= value & 0xfff;
7594 end_of_line (str);
7595 return;
7596 }
7597
7598 value = validate_immediate (~inst.reloc.exp.X_add_number);
7599
7600 if (value != FAIL)
7601 {
7602 /* This can be done with a mvn instruction. */
7603 inst.instruction &= LITERAL_MASK;
7604 inst.instruction |= (INST_IMMEDIATE
7605 | (OPCODE_MVN << DATA_OP_SHIFT));
7606 inst.instruction |= value & 0xfff;
7607 end_of_line (str);
7608 return;
7609 }
7610 }
7611
7612 /* Insert into literal pool. */
7613 if (add_to_lit_pool () == FAIL)
7614 {
7615 if (!inst.error)
7616 inst.error = _("literal pool insertion failed");
7617 return;
7618 }
7619
7620 /* Change the instruction exp to point to the pool. */
7621 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
7622 inst.reloc.pc_rel = 1;
7623 inst.instruction |= (REG_PC << 16);
7624 pre_inc = 1;
7625 }
7626 else
7627 {
7628 if (my_get_expression (&inst.reloc.exp, &str))
7629 return;
7630
7631 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
7632 #ifndef TE_WINCE
7633 /* PC rel adjust. */
7634 inst.reloc.exp.X_add_number -= 8;
7635 #endif
7636 inst.reloc.pc_rel = 1;
7637 inst.instruction |= (REG_PC << 16);
7638 pre_inc = 1;
7639 }
7640
7641 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7642 end_of_line (str);
7643 }
7644
7645 static void
7646 do_ldstt (str)
7647 char * str;
7648 {
7649 int conflict_reg;
7650
7651 skip_whitespace (str);
7652
7653 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7654 {
7655 if (!inst.error)
7656 inst.error = BAD_ARGS;
7657 return;
7658 }
7659
7660 if (skip_past_comma (& str) == FAIL)
7661 {
7662 inst.error = _("address expected");
7663 return;
7664 }
7665
7666 if (*str == '[')
7667 {
7668 int reg;
7669
7670 str++;
7671
7672 skip_whitespace (str);
7673
7674 if ((reg = reg_required_here (&str, 16)) == FAIL)
7675 return;
7676
7677 /* ldrt/strt always use post-indexed addressing, so if the base is
7678 the same as Rd, we warn. */
7679 if (conflict_reg == reg)
7680 as_warn (_("%s register same as write-back base"),
7681 ((inst.instruction & LOAD_BIT)
7682 ? _("destination") : _("source")));
7683
7684 skip_whitespace (str);
7685
7686 if (*str == ']')
7687 {
7688 str ++;
7689
7690 if (skip_past_comma (&str) == SUCCESS)
7691 {
7692 /* [Rn],... (post inc) */
7693 if (ldst_extend (&str) == FAIL)
7694 return;
7695 }
7696 else
7697 {
7698 /* [Rn] */
7699 skip_whitespace (str);
7700
7701 /* Skip a write-back '!'. */
7702 if (*str == '!')
7703 str++;
7704
7705 inst.instruction |= INDEX_UP;
7706 }
7707 }
7708 else
7709 {
7710 inst.error = _("post-indexed expression expected");
7711 return;
7712 }
7713 }
7714 else
7715 {
7716 inst.error = _("post-indexed expression expected");
7717 return;
7718 }
7719
7720 end_of_line (str);
7721 }
7722
7723 static int
7724 ldst_extend_v4 (str)
7725 char ** str;
7726 {
7727 int add = INDEX_UP;
7728
7729 switch (**str)
7730 {
7731 case '#':
7732 case '$':
7733 (*str)++;
7734 if (my_get_expression (& inst.reloc.exp, str))
7735 return FAIL;
7736
7737 if (inst.reloc.exp.X_op == O_constant)
7738 {
7739 int value = inst.reloc.exp.X_add_number;
7740
7741 if (value < -255 || value > 255)
7742 {
7743 inst.error = _("address offset too large");
7744 return FAIL;
7745 }
7746
7747 if (value < 0)
7748 {
7749 value = -value;
7750 add = 0;
7751 }
7752
7753 /* Halfword and signextension instructions have the
7754 immediate value split across bits 11..8 and bits 3..0. */
7755 inst.instruction |= (add | HWOFFSET_IMM
7756 | ((value >> 4) << 8) | (value & 0xF));
7757 }
7758 else
7759 {
7760 inst.instruction |= HWOFFSET_IMM;
7761 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7762 inst.reloc.pc_rel = 0;
7763 }
7764 return SUCCESS;
7765
7766 case '-':
7767 add = 0;
7768 /* Fall through. */
7769
7770 case '+':
7771 (*str)++;
7772 /* Fall through. */
7773
7774 default:
7775 if (reg_required_here (str, 0) == FAIL)
7776 return FAIL;
7777
7778 inst.instruction |= add;
7779 return SUCCESS;
7780 }
7781 }
7782
7783 /* Halfword and signed-byte load/store operations. */
7784 static void
7785 do_ldstv4 (str)
7786 char * str;
7787 {
7788 int pre_inc = 0;
7789 int conflict_reg;
7790 int value;
7791
7792 skip_whitespace (str);
7793
7794 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
7795 {
7796 if (!inst.error)
7797 inst.error = BAD_ARGS;
7798 return;
7799 }
7800
7801 if (skip_past_comma (& str) == FAIL)
7802 {
7803 inst.error = _("address expected");
7804 return;
7805 }
7806
7807 if (*str == '[')
7808 {
7809 int reg;
7810
7811 str++;
7812
7813 skip_whitespace (str);
7814
7815 if ((reg = reg_required_here (&str, 16)) == FAIL)
7816 return;
7817
7818 /* Conflicts can occur on stores as well as loads. */
7819 conflict_reg = (conflict_reg == reg);
7820
7821 skip_whitespace (str);
7822
7823 if (*str == ']')
7824 {
7825 str ++;
7826
7827 if (skip_past_comma (&str) == SUCCESS)
7828 {
7829 /* [Rn],... (post inc) */
7830 if (ldst_extend_v4 (&str) == FAIL)
7831 return;
7832 if (conflict_reg)
7833 as_warn (_("%s register same as write-back base"),
7834 ((inst.instruction & LOAD_BIT)
7835 ? _("destination") : _("source")));
7836 }
7837 else
7838 {
7839 /* [Rn] */
7840 inst.instruction |= HWOFFSET_IMM;
7841
7842 skip_whitespace (str);
7843
7844 if (*str == '!')
7845 {
7846 if (conflict_reg)
7847 as_warn (_("%s register same as write-back base"),
7848 ((inst.instruction & LOAD_BIT)
7849 ? _("destination") : _("source")));
7850 str++;
7851 inst.instruction |= WRITE_BACK;
7852 }
7853
7854 inst.instruction |= INDEX_UP;
7855 pre_inc = 1;
7856 }
7857 }
7858 else
7859 {
7860 /* [Rn,...] */
7861 if (skip_past_comma (&str) == FAIL)
7862 {
7863 inst.error = _("pre-indexed expression expected");
7864 return;
7865 }
7866
7867 pre_inc = 1;
7868 if (ldst_extend_v4 (&str) == FAIL)
7869 return;
7870
7871 skip_whitespace (str);
7872
7873 if (*str++ != ']')
7874 {
7875 inst.error = _("missing ]");
7876 return;
7877 }
7878
7879 skip_whitespace (str);
7880
7881 if (*str == '!')
7882 {
7883 if (conflict_reg)
7884 as_warn (_("%s register same as write-back base"),
7885 ((inst.instruction & LOAD_BIT)
7886 ? _("destination") : _("source")));
7887 str++;
7888 inst.instruction |= WRITE_BACK;
7889 }
7890 }
7891 }
7892 else if (*str == '=')
7893 {
7894 if ((inst.instruction & LOAD_BIT) == 0)
7895 {
7896 inst.error = _("invalid pseudo operation");
7897 return;
7898 }
7899
7900 /* XXX Does this work correctly for half-word/byte ops? */
7901 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
7902 str++;
7903
7904 skip_whitespace (str);
7905
7906 if (my_get_expression (&inst.reloc.exp, &str))
7907 return;
7908
7909 if (inst.reloc.exp.X_op != O_constant
7910 && inst.reloc.exp.X_op != O_symbol)
7911 {
7912 inst.error = _("constant expression expected");
7913 return;
7914 }
7915
7916 if (inst.reloc.exp.X_op == O_constant)
7917 {
7918 value = validate_immediate (inst.reloc.exp.X_add_number);
7919
7920 if (value != FAIL)
7921 {
7922 /* This can be done with a mov instruction. */
7923 inst.instruction &= LITERAL_MASK;
7924 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
7925 inst.instruction |= value & 0xfff;
7926 end_of_line (str);
7927 return;
7928 }
7929
7930 value = validate_immediate (~ inst.reloc.exp.X_add_number);
7931
7932 if (value != FAIL)
7933 {
7934 /* This can be done with a mvn instruction. */
7935 inst.instruction &= LITERAL_MASK;
7936 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
7937 inst.instruction |= value & 0xfff;
7938 end_of_line (str);
7939 return;
7940 }
7941 }
7942
7943 /* Insert into literal pool. */
7944 if (add_to_lit_pool () == FAIL)
7945 {
7946 if (!inst.error)
7947 inst.error = _("literal pool insertion failed");
7948 return;
7949 }
7950
7951 /* Change the instruction exp to point to the pool. */
7952 inst.instruction |= HWOFFSET_IMM;
7953 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
7954 inst.reloc.pc_rel = 1;
7955 inst.instruction |= (REG_PC << 16);
7956 pre_inc = 1;
7957 }
7958 else
7959 {
7960 if (my_get_expression (&inst.reloc.exp, &str))
7961 return;
7962
7963 inst.instruction |= HWOFFSET_IMM;
7964 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
7965 #ifndef TE_WINCE
7966 /* PC rel adjust. */
7967 inst.reloc.exp.X_add_number -= 8;
7968 #endif
7969 inst.reloc.pc_rel = 1;
7970 inst.instruction |= (REG_PC << 16);
7971 pre_inc = 1;
7972 }
7973
7974 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
7975 end_of_line (str);
7976 }
7977
7978 static long
7979 reg_list (strp)
7980 char ** strp;
7981 {
7982 char * str = * strp;
7983 long range = 0;
7984 int another_range;
7985
7986 /* We come back here if we get ranges concatenated by '+' or '|'. */
7987 do
7988 {
7989 another_range = 0;
7990
7991 if (*str == '{')
7992 {
7993 int in_range = 0;
7994 int cur_reg = -1;
7995
7996 str++;
7997 do
7998 {
7999 int reg;
8000
8001 skip_whitespace (str);
8002
8003 if ((reg = reg_required_here (& str, -1)) == FAIL)
8004 return FAIL;
8005
8006 if (in_range)
8007 {
8008 int i;
8009
8010 if (reg <= cur_reg)
8011 {
8012 inst.error = _("bad range in register list");
8013 return FAIL;
8014 }
8015
8016 for (i = cur_reg + 1; i < reg; i++)
8017 {
8018 if (range & (1 << i))
8019 as_tsktsk
8020 (_("Warning: duplicated register (r%d) in register list"),
8021 i);
8022 else
8023 range |= 1 << i;
8024 }
8025 in_range = 0;
8026 }
8027
8028 if (range & (1 << reg))
8029 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
8030 reg);
8031 else if (reg <= cur_reg)
8032 as_tsktsk (_("Warning: register range not in ascending order"));
8033
8034 range |= 1 << reg;
8035 cur_reg = reg;
8036 }
8037 while (skip_past_comma (&str) != FAIL
8038 || (in_range = 1, *str++ == '-'));
8039 str--;
8040 skip_whitespace (str);
8041
8042 if (*str++ != '}')
8043 {
8044 inst.error = _("missing `}'");
8045 return FAIL;
8046 }
8047 }
8048 else
8049 {
8050 expressionS expr;
8051
8052 if (my_get_expression (&expr, &str))
8053 return FAIL;
8054
8055 if (expr.X_op == O_constant)
8056 {
8057 if (expr.X_add_number
8058 != (expr.X_add_number & 0x0000ffff))
8059 {
8060 inst.error = _("invalid register mask");
8061 return FAIL;
8062 }
8063
8064 if ((range & expr.X_add_number) != 0)
8065 {
8066 int regno = range & expr.X_add_number;
8067
8068 regno &= -regno;
8069 regno = (1 << regno) - 1;
8070 as_tsktsk
8071 (_("Warning: duplicated register (r%d) in register list"),
8072 regno);
8073 }
8074
8075 range |= expr.X_add_number;
8076 }
8077 else
8078 {
8079 if (inst.reloc.type != 0)
8080 {
8081 inst.error = _("expression too complex");
8082 return FAIL;
8083 }
8084
8085 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
8086 inst.reloc.type = BFD_RELOC_ARM_MULTI;
8087 inst.reloc.pc_rel = 0;
8088 }
8089 }
8090
8091 skip_whitespace (str);
8092
8093 if (*str == '|' || *str == '+')
8094 {
8095 str++;
8096 another_range = 1;
8097 }
8098 }
8099 while (another_range);
8100
8101 *strp = str;
8102 return range;
8103 }
8104
8105 static void
8106 do_ldmstm (str)
8107 char * str;
8108 {
8109 int base_reg;
8110 long range;
8111
8112 skip_whitespace (str);
8113
8114 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
8115 return;
8116
8117 if (base_reg == REG_PC)
8118 {
8119 inst.error = _("r15 not allowed as base register");
8120 return;
8121 }
8122
8123 skip_whitespace (str);
8124
8125 if (*str == '!')
8126 {
8127 inst.instruction |= WRITE_BACK;
8128 str++;
8129 }
8130
8131 if (skip_past_comma (&str) == FAIL
8132 || (range = reg_list (&str)) == FAIL)
8133 {
8134 if (! inst.error)
8135 inst.error = BAD_ARGS;
8136 return;
8137 }
8138
8139 if (*str == '^')
8140 {
8141 str++;
8142 inst.instruction |= LDM_TYPE_2_OR_3;
8143 }
8144
8145 if (inst.instruction & WRITE_BACK)
8146 {
8147 /* Check for unpredictable uses of writeback. */
8148 if (inst.instruction & LOAD_BIT)
8149 {
8150 /* Not allowed in LDM type 2. */
8151 if ((inst.instruction & LDM_TYPE_2_OR_3)
8152 && ((range & (1 << REG_PC)) == 0))
8153 as_warn (_("writeback of base register is UNPREDICTABLE"));
8154 /* Only allowed if base reg not in list for other types. */
8155 else if (range & (1 << base_reg))
8156 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
8157 }
8158 else /* STM. */
8159 {
8160 /* Not allowed for type 2. */
8161 if (inst.instruction & LDM_TYPE_2_OR_3)
8162 as_warn (_("writeback of base register is UNPREDICTABLE"));
8163 /* Only allowed if base reg not in list, or first in list. */
8164 else if ((range & (1 << base_reg))
8165 && (range & ((1 << base_reg) - 1)))
8166 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
8167 }
8168 }
8169
8170 inst.instruction |= range;
8171 end_of_line (str);
8172 }
8173
8174 static void
8175 do_swi (str)
8176 char * str;
8177 {
8178 skip_whitespace (str);
8179
8180 /* Allow optional leading '#'. */
8181 if (is_immediate_prefix (*str))
8182 str++;
8183
8184 if (my_get_expression (& inst.reloc.exp, & str))
8185 return;
8186
8187 inst.reloc.type = BFD_RELOC_ARM_SWI;
8188 inst.reloc.pc_rel = 0;
8189 end_of_line (str);
8190 }
8191
8192 static void
8193 do_swap (str)
8194 char * str;
8195 {
8196 int reg;
8197
8198 skip_whitespace (str);
8199
8200 if ((reg = reg_required_here (&str, 12)) == FAIL)
8201 return;
8202
8203 if (reg == REG_PC)
8204 {
8205 inst.error = _("r15 not allowed in swap");
8206 return;
8207 }
8208
8209 if (skip_past_comma (&str) == FAIL
8210 || (reg = reg_required_here (&str, 0)) == FAIL)
8211 {
8212 if (!inst.error)
8213 inst.error = BAD_ARGS;
8214 return;
8215 }
8216
8217 if (reg == REG_PC)
8218 {
8219 inst.error = _("r15 not allowed in swap");
8220 return;
8221 }
8222
8223 if (skip_past_comma (&str) == FAIL
8224 || *str++ != '[')
8225 {
8226 inst.error = BAD_ARGS;
8227 return;
8228 }
8229
8230 skip_whitespace (str);
8231
8232 if ((reg = reg_required_here (&str, 16)) == FAIL)
8233 return;
8234
8235 if (reg == REG_PC)
8236 {
8237 inst.error = BAD_PC;
8238 return;
8239 }
8240
8241 skip_whitespace (str);
8242
8243 if (*str++ != ']')
8244 {
8245 inst.error = _("missing ]");
8246 return;
8247 }
8248
8249 end_of_line (str);
8250 }
8251
8252 static void
8253 do_branch (str)
8254 char * str;
8255 {
8256 if (my_get_expression (&inst.reloc.exp, &str))
8257 return;
8258
8259 #ifdef OBJ_ELF
8260 {
8261 char * save_in;
8262
8263 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
8264 required for the instruction. */
8265
8266 /* arm_parse_reloc () works on input_line_pointer.
8267 We actually want to parse the operands to the branch instruction
8268 passed in 'str'. Save the input pointer and restore it later. */
8269 save_in = input_line_pointer;
8270 input_line_pointer = str;
8271 if (inst.reloc.exp.X_op == O_symbol
8272 && *str == '('
8273 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
8274 {
8275 inst.reloc.type = BFD_RELOC_ARM_PLT32;
8276 inst.reloc.pc_rel = 0;
8277 /* Modify str to point to after parsed operands, otherwise
8278 end_of_line() will complain about the (PLT) left in str. */
8279 str = input_line_pointer;
8280 }
8281 else
8282 {
8283 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
8284 inst.reloc.pc_rel = 1;
8285 }
8286 input_line_pointer = save_in;
8287 }
8288 #else
8289 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
8290 inst.reloc.pc_rel = 1;
8291 #endif /* OBJ_ELF */
8292
8293 end_of_line (str);
8294 }
8295
8296 static void
8297 do_bx (str)
8298 char * str;
8299 {
8300 int reg;
8301
8302 skip_whitespace (str);
8303
8304 if ((reg = reg_required_here (&str, 0)) == FAIL)
8305 {
8306 inst.error = BAD_ARGS;
8307 return;
8308 }
8309
8310 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
8311 if (reg == REG_PC)
8312 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
8313
8314 end_of_line (str);
8315 }
8316
8317 static void
8318 do_cdp (str)
8319 char * str;
8320 {
8321 /* Co-processor data operation.
8322 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
8323 skip_whitespace (str);
8324
8325 if (co_proc_number (&str) == FAIL)
8326 {
8327 if (!inst.error)
8328 inst.error = BAD_ARGS;
8329 return;
8330 }
8331
8332 if (skip_past_comma (&str) == FAIL
8333 || cp_opc_expr (&str, 20,4) == FAIL)
8334 {
8335 if (!inst.error)
8336 inst.error = BAD_ARGS;
8337 return;
8338 }
8339
8340 if (skip_past_comma (&str) == FAIL
8341 || cp_reg_required_here (&str, 12) == FAIL)
8342 {
8343 if (!inst.error)
8344 inst.error = BAD_ARGS;
8345 return;
8346 }
8347
8348 if (skip_past_comma (&str) == FAIL
8349 || cp_reg_required_here (&str, 16) == FAIL)
8350 {
8351 if (!inst.error)
8352 inst.error = BAD_ARGS;
8353 return;
8354 }
8355
8356 if (skip_past_comma (&str) == FAIL
8357 || cp_reg_required_here (&str, 0) == FAIL)
8358 {
8359 if (!inst.error)
8360 inst.error = BAD_ARGS;
8361 return;
8362 }
8363
8364 if (skip_past_comma (&str) == SUCCESS)
8365 {
8366 if (cp_opc_expr (&str, 5, 3) == FAIL)
8367 {
8368 if (!inst.error)
8369 inst.error = BAD_ARGS;
8370 return;
8371 }
8372 }
8373
8374 end_of_line (str);
8375 }
8376
8377 static void
8378 do_lstc (str)
8379 char * str;
8380 {
8381 /* Co-processor register load/store.
8382 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
8383
8384 skip_whitespace (str);
8385
8386 if (co_proc_number (&str) == FAIL)
8387 {
8388 if (!inst.error)
8389 inst.error = BAD_ARGS;
8390 return;
8391 }
8392
8393 if (skip_past_comma (&str) == FAIL
8394 || cp_reg_required_here (&str, 12) == FAIL)
8395 {
8396 if (!inst.error)
8397 inst.error = BAD_ARGS;
8398 return;
8399 }
8400
8401 if (skip_past_comma (&str) == FAIL
8402 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8403 {
8404 if (! inst.error)
8405 inst.error = BAD_ARGS;
8406 return;
8407 }
8408
8409 end_of_line (str);
8410 }
8411
8412 static void
8413 do_co_reg (str)
8414 char * str;
8415 {
8416 /* Co-processor register transfer.
8417 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
8418
8419 skip_whitespace (str);
8420
8421 if (co_proc_number (&str) == FAIL)
8422 {
8423 if (!inst.error)
8424 inst.error = BAD_ARGS;
8425 return;
8426 }
8427
8428 if (skip_past_comma (&str) == FAIL
8429 || cp_opc_expr (&str, 21, 3) == FAIL)
8430 {
8431 if (!inst.error)
8432 inst.error = BAD_ARGS;
8433 return;
8434 }
8435
8436 if (skip_past_comma (&str) == FAIL
8437 || reg_required_here (&str, 12) == FAIL)
8438 {
8439 if (!inst.error)
8440 inst.error = BAD_ARGS;
8441 return;
8442 }
8443
8444 if (skip_past_comma (&str) == FAIL
8445 || cp_reg_required_here (&str, 16) == FAIL)
8446 {
8447 if (!inst.error)
8448 inst.error = BAD_ARGS;
8449 return;
8450 }
8451
8452 if (skip_past_comma (&str) == FAIL
8453 || cp_reg_required_here (&str, 0) == FAIL)
8454 {
8455 if (!inst.error)
8456 inst.error = BAD_ARGS;
8457 return;
8458 }
8459
8460 if (skip_past_comma (&str) == SUCCESS)
8461 {
8462 if (cp_opc_expr (&str, 5, 3) == FAIL)
8463 {
8464 if (!inst.error)
8465 inst.error = BAD_ARGS;
8466 return;
8467 }
8468 }
8469
8470 end_of_line (str);
8471 }
8472
8473 static void
8474 do_fpa_ctrl (str)
8475 char * str;
8476 {
8477 /* FP control registers.
8478 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
8479
8480 skip_whitespace (str);
8481
8482 if (reg_required_here (&str, 12) == FAIL)
8483 {
8484 if (!inst.error)
8485 inst.error = BAD_ARGS;
8486 return;
8487 }
8488
8489 end_of_line (str);
8490 }
8491
8492 static void
8493 do_fpa_ldst (str)
8494 char * str;
8495 {
8496 skip_whitespace (str);
8497
8498 if (fp_reg_required_here (&str, 12) == FAIL)
8499 {
8500 if (!inst.error)
8501 inst.error = BAD_ARGS;
8502 return;
8503 }
8504
8505 if (skip_past_comma (&str) == FAIL
8506 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8507 {
8508 if (!inst.error)
8509 inst.error = BAD_ARGS;
8510 return;
8511 }
8512
8513 end_of_line (str);
8514 }
8515
8516 static void
8517 do_fpa_ldmstm (str)
8518 char * str;
8519 {
8520 int num_regs;
8521
8522 skip_whitespace (str);
8523
8524 if (fp_reg_required_here (&str, 12) == FAIL)
8525 {
8526 if (! inst.error)
8527 inst.error = BAD_ARGS;
8528 return;
8529 }
8530
8531 /* Get Number of registers to transfer. */
8532 if (skip_past_comma (&str) == FAIL
8533 || my_get_expression (&inst.reloc.exp, &str))
8534 {
8535 if (! inst.error)
8536 inst.error = _("constant expression expected");
8537 return;
8538 }
8539
8540 if (inst.reloc.exp.X_op != O_constant)
8541 {
8542 inst.error = _("constant value required for number of registers");
8543 return;
8544 }
8545
8546 num_regs = inst.reloc.exp.X_add_number;
8547
8548 if (num_regs < 1 || num_regs > 4)
8549 {
8550 inst.error = _("number of registers must be in the range [1:4]");
8551 return;
8552 }
8553
8554 switch (num_regs)
8555 {
8556 case 1:
8557 inst.instruction |= CP_T_X;
8558 break;
8559 case 2:
8560 inst.instruction |= CP_T_Y;
8561 break;
8562 case 3:
8563 inst.instruction |= CP_T_Y | CP_T_X;
8564 break;
8565 case 4:
8566 break;
8567 default:
8568 abort ();
8569 }
8570
8571 if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format. */
8572 {
8573 int reg;
8574 int write_back;
8575 int offset;
8576
8577 /* The instruction specified "ea" or "fd", so we can only accept
8578 [Rn]{!}. The instruction does not really support stacking or
8579 unstacking, so we have to emulate these by setting appropriate
8580 bits and offsets. */
8581 if (skip_past_comma (&str) == FAIL
8582 || *str != '[')
8583 {
8584 if (! inst.error)
8585 inst.error = BAD_ARGS;
8586 return;
8587 }
8588
8589 str++;
8590 skip_whitespace (str);
8591
8592 if ((reg = reg_required_here (&str, 16)) == FAIL)
8593 return;
8594
8595 skip_whitespace (str);
8596
8597 if (*str != ']')
8598 {
8599 inst.error = BAD_ARGS;
8600 return;
8601 }
8602
8603 str++;
8604 if (*str == '!')
8605 {
8606 write_back = 1;
8607 str++;
8608 if (reg == REG_PC)
8609 {
8610 inst.error =
8611 _("r15 not allowed as base register with write-back");
8612 return;
8613 }
8614 }
8615 else
8616 write_back = 0;
8617
8618 if (inst.instruction & CP_T_Pre)
8619 {
8620 /* Pre-decrement. */
8621 offset = 3 * num_regs;
8622 if (write_back)
8623 inst.instruction |= CP_T_WB;
8624 }
8625 else
8626 {
8627 /* Post-increment. */
8628 if (write_back)
8629 {
8630 inst.instruction |= CP_T_WB;
8631 offset = 3 * num_regs;
8632 }
8633 else
8634 {
8635 /* No write-back, so convert this into a standard pre-increment
8636 instruction -- aesthetically more pleasing. */
8637 inst.instruction |= CP_T_Pre | CP_T_UD;
8638 offset = 0;
8639 }
8640 }
8641
8642 inst.instruction |= offset;
8643 }
8644 else if (skip_past_comma (&str) == FAIL
8645 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
8646 {
8647 if (! inst.error)
8648 inst.error = BAD_ARGS;
8649 return;
8650 }
8651
8652 end_of_line (str);
8653 }
8654
8655 static void
8656 do_fpa_dyadic (str)
8657 char * str;
8658 {
8659 skip_whitespace (str);
8660
8661 if (fp_reg_required_here (&str, 12) == FAIL)
8662 {
8663 if (! inst.error)
8664 inst.error = BAD_ARGS;
8665 return;
8666 }
8667
8668 if (skip_past_comma (&str) == FAIL
8669 || fp_reg_required_here (&str, 16) == FAIL)
8670 {
8671 if (! inst.error)
8672 inst.error = BAD_ARGS;
8673 return;
8674 }
8675
8676 if (skip_past_comma (&str) == FAIL
8677 || fp_op2 (&str) == FAIL)
8678 {
8679 if (! inst.error)
8680 inst.error = BAD_ARGS;
8681 return;
8682 }
8683
8684 end_of_line (str);
8685 }
8686
8687 static void
8688 do_fpa_monadic (str)
8689 char * str;
8690 {
8691 skip_whitespace (str);
8692
8693 if (fp_reg_required_here (&str, 12) == FAIL)
8694 {
8695 if (! inst.error)
8696 inst.error = BAD_ARGS;
8697 return;
8698 }
8699
8700 if (skip_past_comma (&str) == FAIL
8701 || fp_op2 (&str) == FAIL)
8702 {
8703 if (! inst.error)
8704 inst.error = BAD_ARGS;
8705 return;
8706 }
8707
8708 end_of_line (str);
8709 }
8710
8711 static void
8712 do_fpa_cmp (str)
8713 char * str;
8714 {
8715 skip_whitespace (str);
8716
8717 if (fp_reg_required_here (&str, 16) == FAIL)
8718 {
8719 if (! inst.error)
8720 inst.error = BAD_ARGS;
8721 return;
8722 }
8723
8724 if (skip_past_comma (&str) == FAIL
8725 || fp_op2 (&str) == FAIL)
8726 {
8727 if (! inst.error)
8728 inst.error = BAD_ARGS;
8729 return;
8730 }
8731
8732 end_of_line (str);
8733 }
8734
8735 static void
8736 do_fpa_from_reg (str)
8737 char * str;
8738 {
8739 skip_whitespace (str);
8740
8741 if (fp_reg_required_here (&str, 16) == FAIL)
8742 {
8743 if (! inst.error)
8744 inst.error = BAD_ARGS;
8745 return;
8746 }
8747
8748 if (skip_past_comma (&str) == FAIL
8749 || reg_required_here (&str, 12) == FAIL)
8750 {
8751 if (! inst.error)
8752 inst.error = BAD_ARGS;
8753 return;
8754 }
8755
8756 end_of_line (str);
8757 }
8758
8759 static void
8760 do_fpa_to_reg (str)
8761 char * str;
8762 {
8763 skip_whitespace (str);
8764
8765 if (reg_required_here (&str, 12) == FAIL)
8766 return;
8767
8768 if (skip_past_comma (&str) == FAIL
8769 || fp_reg_required_here (&str, 0) == FAIL)
8770 {
8771 if (! inst.error)
8772 inst.error = BAD_ARGS;
8773 return;
8774 }
8775
8776 end_of_line (str);
8777 }
8778
8779 static int
8780 vfp_sp_reg_required_here (str, pos)
8781 char **str;
8782 enum vfp_sp_reg_pos pos;
8783 {
8784 int reg;
8785 char *start = *str;
8786
8787 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
8788 {
8789 switch (pos)
8790 {
8791 case VFP_REG_Sd:
8792 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
8793 break;
8794
8795 case VFP_REG_Sn:
8796 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
8797 break;
8798
8799 case VFP_REG_Sm:
8800 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
8801 break;
8802
8803 default:
8804 abort ();
8805 }
8806 return reg;
8807 }
8808
8809 /* In the few cases where we might be able to accept something else
8810 this error can be overridden. */
8811 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
8812
8813 /* Restore the start point. */
8814 *str = start;
8815 return FAIL;
8816 }
8817
8818 static int
8819 vfp_dp_reg_required_here (str, pos)
8820 char **str;
8821 enum vfp_dp_reg_pos pos;
8822 {
8823 int reg;
8824 char *start = *str;
8825
8826 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
8827 {
8828 switch (pos)
8829 {
8830 case VFP_REG_Dd:
8831 inst.instruction |= reg << 12;
8832 break;
8833
8834 case VFP_REG_Dn:
8835 inst.instruction |= reg << 16;
8836 break;
8837
8838 case VFP_REG_Dm:
8839 inst.instruction |= reg << 0;
8840 break;
8841
8842 default:
8843 abort ();
8844 }
8845 return reg;
8846 }
8847
8848 /* In the few cases where we might be able to accept something else
8849 this error can be overridden. */
8850 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
8851
8852 /* Restore the start point. */
8853 *str = start;
8854 return FAIL;
8855 }
8856
8857 static void
8858 do_vfp_sp_monadic (str)
8859 char *str;
8860 {
8861 skip_whitespace (str);
8862
8863 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8864 return;
8865
8866 if (skip_past_comma (&str) == FAIL
8867 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8868 {
8869 if (! inst.error)
8870 inst.error = BAD_ARGS;
8871 return;
8872 }
8873
8874 end_of_line (str);
8875 }
8876
8877 static void
8878 do_vfp_dp_monadic (str)
8879 char *str;
8880 {
8881 skip_whitespace (str);
8882
8883 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8884 return;
8885
8886 if (skip_past_comma (&str) == FAIL
8887 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8888 {
8889 if (! inst.error)
8890 inst.error = BAD_ARGS;
8891 return;
8892 }
8893
8894 end_of_line (str);
8895 }
8896
8897 static void
8898 do_vfp_sp_dyadic (str)
8899 char *str;
8900 {
8901 skip_whitespace (str);
8902
8903 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8904 return;
8905
8906 if (skip_past_comma (&str) == FAIL
8907 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
8908 || skip_past_comma (&str) == FAIL
8909 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8910 {
8911 if (! inst.error)
8912 inst.error = BAD_ARGS;
8913 return;
8914 }
8915
8916 end_of_line (str);
8917 }
8918
8919 static void
8920 do_vfp_dp_dyadic (str)
8921 char *str;
8922 {
8923 skip_whitespace (str);
8924
8925 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8926 return;
8927
8928 if (skip_past_comma (&str) == FAIL
8929 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
8930 || skip_past_comma (&str) == FAIL
8931 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8932 {
8933 if (! inst.error)
8934 inst.error = BAD_ARGS;
8935 return;
8936 }
8937
8938 end_of_line (str);
8939 }
8940
8941 static void
8942 do_vfp_reg_from_sp (str)
8943 char *str;
8944 {
8945 skip_whitespace (str);
8946
8947 if (reg_required_here (&str, 12) == FAIL)
8948 return;
8949
8950 if (skip_past_comma (&str) == FAIL
8951 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8952 {
8953 if (! inst.error)
8954 inst.error = BAD_ARGS;
8955 return;
8956 }
8957
8958 end_of_line (str);
8959 }
8960
8961 static void
8962 do_vfp_reg2_from_sp2 (str)
8963 char *str;
8964 {
8965 skip_whitespace (str);
8966
8967 if (reg_required_here (&str, 12) == FAIL
8968 || skip_past_comma (&str) == FAIL
8969 || reg_required_here (&str, 16) == FAIL
8970 || skip_past_comma (&str) == FAIL)
8971 {
8972 if (! inst.error)
8973 inst.error = BAD_ARGS;
8974 return;
8975 }
8976
8977 /* We require exactly two consecutive SP registers. */
8978 if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
8979 {
8980 if (! inst.error)
8981 inst.error = _("only two consecutive VFP SP registers allowed here");
8982 }
8983
8984 end_of_line (str);
8985 }
8986
8987 static void
8988 do_vfp_sp_from_reg (str)
8989 char *str;
8990 {
8991 skip_whitespace (str);
8992
8993 if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
8994 return;
8995
8996 if (skip_past_comma (&str) == FAIL
8997 || reg_required_here (&str, 12) == FAIL)
8998 {
8999 if (! inst.error)
9000 inst.error = BAD_ARGS;
9001 return;
9002 }
9003
9004 end_of_line (str);
9005 }
9006
9007 static void
9008 do_vfp_sp2_from_reg2 (str)
9009 char *str;
9010 {
9011 skip_whitespace (str);
9012
9013 /* We require exactly two consecutive SP registers. */
9014 if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
9015 {
9016 if (! inst.error)
9017 inst.error = _("only two consecutive VFP SP registers allowed here");
9018 }
9019
9020 if (skip_past_comma (&str) == FAIL
9021 || reg_required_here (&str, 12) == FAIL
9022 || skip_past_comma (&str) == FAIL
9023 || reg_required_here (&str, 16) == FAIL)
9024 {
9025 if (! inst.error)
9026 inst.error = BAD_ARGS;
9027 return;
9028 }
9029
9030 end_of_line (str);
9031 }
9032
9033 static void
9034 do_vfp_reg_from_dp (str)
9035 char *str;
9036 {
9037 skip_whitespace (str);
9038
9039 if (reg_required_here (&str, 12) == FAIL)
9040 return;
9041
9042 if (skip_past_comma (&str) == FAIL
9043 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9044 {
9045 if (! inst.error)
9046 inst.error = BAD_ARGS;
9047 return;
9048 }
9049
9050 end_of_line (str);
9051 }
9052
9053 static void
9054 do_vfp_reg2_from_dp (str)
9055 char *str;
9056 {
9057 skip_whitespace (str);
9058
9059 if (reg_required_here (&str, 12) == FAIL)
9060 return;
9061
9062 if (skip_past_comma (&str) == FAIL
9063 || reg_required_here (&str, 16) == FAIL
9064 || skip_past_comma (&str) == FAIL
9065 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9066 {
9067 if (! inst.error)
9068 inst.error = BAD_ARGS;
9069 return;
9070 }
9071
9072 end_of_line (str);
9073 }
9074
9075 static void
9076 do_vfp_dp_from_reg (str)
9077 char *str;
9078 {
9079 skip_whitespace (str);
9080
9081 if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
9082 return;
9083
9084 if (skip_past_comma (&str) == FAIL
9085 || reg_required_here (&str, 12) == FAIL)
9086 {
9087 if (! inst.error)
9088 inst.error = BAD_ARGS;
9089 return;
9090 }
9091
9092 end_of_line (str);
9093 }
9094
9095 static void
9096 do_vfp_dp_from_reg2 (str)
9097 char *str;
9098 {
9099 skip_whitespace (str);
9100
9101 if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9102 return;
9103
9104 if (skip_past_comma (&str) == FAIL
9105 || reg_required_here (&str, 12) == FAIL
9106 || skip_past_comma (&str) == FAIL
9107 || reg_required_here (&str, 16) == FAIL)
9108 {
9109 if (! inst.error)
9110 inst.error = BAD_ARGS;
9111 return;
9112 }
9113
9114 end_of_line (str);
9115 }
9116
9117 static const struct vfp_reg *
9118 vfp_psr_parse (str)
9119 char **str;
9120 {
9121 char *start = *str;
9122 char c;
9123 char *p;
9124 const struct vfp_reg *vreg;
9125
9126 p = start;
9127
9128 /* Find the end of the current token. */
9129 do
9130 {
9131 c = *p++;
9132 }
9133 while (ISALPHA (c));
9134
9135 /* Mark it. */
9136 *--p = 0;
9137
9138 for (vreg = vfp_regs + 0;
9139 vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
9140 vreg++)
9141 {
9142 if (strcmp (start, vreg->name) == 0)
9143 {
9144 *p = c;
9145 *str = p;
9146 return vreg;
9147 }
9148 }
9149
9150 *p = c;
9151 return NULL;
9152 }
9153
9154 static int
9155 vfp_psr_required_here (str)
9156 char **str;
9157 {
9158 char *start = *str;
9159 const struct vfp_reg *vreg;
9160
9161 vreg = vfp_psr_parse (str);
9162
9163 if (vreg)
9164 {
9165 inst.instruction |= vreg->regno;
9166 return SUCCESS;
9167 }
9168
9169 inst.error = _("VFP system register expected");
9170
9171 *str = start;
9172 return FAIL;
9173 }
9174
9175 static void
9176 do_vfp_reg_from_ctrl (str)
9177 char *str;
9178 {
9179 skip_whitespace (str);
9180
9181 if (reg_required_here (&str, 12) == FAIL)
9182 return;
9183
9184 if (skip_past_comma (&str) == FAIL
9185 || vfp_psr_required_here (&str) == FAIL)
9186 {
9187 if (! inst.error)
9188 inst.error = BAD_ARGS;
9189 return;
9190 }
9191
9192 end_of_line (str);
9193 }
9194
9195 static void
9196 do_vfp_ctrl_from_reg (str)
9197 char *str;
9198 {
9199 skip_whitespace (str);
9200
9201 if (vfp_psr_required_here (&str) == FAIL)
9202 return;
9203
9204 if (skip_past_comma (&str) == FAIL
9205 || reg_required_here (&str, 12) == FAIL)
9206 {
9207 if (! inst.error)
9208 inst.error = BAD_ARGS;
9209 return;
9210 }
9211
9212 end_of_line (str);
9213 }
9214
9215 static void
9216 do_vfp_sp_ldst (str)
9217 char *str;
9218 {
9219 skip_whitespace (str);
9220
9221 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9222 {
9223 if (!inst.error)
9224 inst.error = BAD_ARGS;
9225 return;
9226 }
9227
9228 if (skip_past_comma (&str) == FAIL
9229 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9230 {
9231 if (!inst.error)
9232 inst.error = BAD_ARGS;
9233 return;
9234 }
9235
9236 end_of_line (str);
9237 }
9238
9239 static void
9240 do_vfp_dp_ldst (str)
9241 char *str;
9242 {
9243 skip_whitespace (str);
9244
9245 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9246 {
9247 if (!inst.error)
9248 inst.error = BAD_ARGS;
9249 return;
9250 }
9251
9252 if (skip_past_comma (&str) == FAIL
9253 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
9254 {
9255 if (!inst.error)
9256 inst.error = BAD_ARGS;
9257 return;
9258 }
9259
9260 end_of_line (str);
9261 }
9262
9263 /* Parse and encode a VFP SP register list, storing the initial
9264 register in position POS and returning the range as the result. If
9265 the string is invalid return FAIL (an invalid range). */
9266 static long
9267 vfp_sp_reg_list (str, pos)
9268 char **str;
9269 enum vfp_sp_reg_pos pos;
9270 {
9271 long range = 0;
9272 int base_reg = 0;
9273 int new_base;
9274 long base_bits = 0;
9275 int count = 0;
9276 long tempinst;
9277 unsigned long mask = 0;
9278 int warned = 0;
9279
9280 if (**str != '{')
9281 return FAIL;
9282
9283 (*str)++;
9284 skip_whitespace (*str);
9285
9286 tempinst = inst.instruction;
9287
9288 do
9289 {
9290 inst.instruction = 0;
9291
9292 if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
9293 return FAIL;
9294
9295 if (count == 0 || base_reg > new_base)
9296 {
9297 base_reg = new_base;
9298 base_bits = inst.instruction;
9299 }
9300
9301 if (mask & (1 << new_base))
9302 {
9303 inst.error = _("invalid register list");
9304 return FAIL;
9305 }
9306
9307 if ((mask >> new_base) != 0 && ! warned)
9308 {
9309 as_tsktsk (_("register list not in ascending order"));
9310 warned = 1;
9311 }
9312
9313 mask |= 1 << new_base;
9314 count++;
9315
9316 skip_whitespace (*str);
9317
9318 if (**str == '-') /* We have the start of a range expression */
9319 {
9320 int high_range;
9321
9322 (*str)++;
9323
9324 if ((high_range
9325 = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
9326 == FAIL)
9327 {
9328 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
9329 return FAIL;
9330 }
9331
9332 if (high_range <= new_base)
9333 {
9334 inst.error = _("register range not in ascending order");
9335 return FAIL;
9336 }
9337
9338 for (new_base++; new_base <= high_range; new_base++)
9339 {
9340 if (mask & (1 << new_base))
9341 {
9342 inst.error = _("invalid register list");
9343 return FAIL;
9344 }
9345
9346 mask |= 1 << new_base;
9347 count++;
9348 }
9349 }
9350 }
9351 while (skip_past_comma (str) != FAIL);
9352
9353 if (**str != '}')
9354 {
9355 inst.error = _("invalid register list");
9356 return FAIL;
9357 }
9358
9359 (*str)++;
9360
9361 range = count;
9362
9363 /* Sanity check -- should have raised a parse error above. */
9364 if (count == 0 || count > 32)
9365 abort ();
9366
9367 /* Final test -- the registers must be consecutive. */
9368 while (count--)
9369 {
9370 if ((mask & (1 << base_reg++)) == 0)
9371 {
9372 inst.error = _("non-contiguous register range");
9373 return FAIL;
9374 }
9375 }
9376
9377 inst.instruction = tempinst | base_bits;
9378 return range;
9379 }
9380
9381 static long
9382 vfp_dp_reg_list (str)
9383 char **str;
9384 {
9385 long range = 0;
9386 int base_reg = 0;
9387 int new_base;
9388 int count = 0;
9389 long tempinst;
9390 unsigned long mask = 0;
9391 int warned = 0;
9392
9393 if (**str != '{')
9394 return FAIL;
9395
9396 (*str)++;
9397 skip_whitespace (*str);
9398
9399 tempinst = inst.instruction;
9400
9401 do
9402 {
9403 inst.instruction = 0;
9404
9405 if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
9406 return FAIL;
9407
9408 if (count == 0 || base_reg > new_base)
9409 {
9410 base_reg = new_base;
9411 range = inst.instruction;
9412 }
9413
9414 if (mask & (1 << new_base))
9415 {
9416 inst.error = _("invalid register list");
9417 return FAIL;
9418 }
9419
9420 if ((mask >> new_base) != 0 && ! warned)
9421 {
9422 as_tsktsk (_("register list not in ascending order"));
9423 warned = 1;
9424 }
9425
9426 mask |= 1 << new_base;
9427 count++;
9428
9429 skip_whitespace (*str);
9430
9431 if (**str == '-') /* We have the start of a range expression */
9432 {
9433 int high_range;
9434
9435 (*str)++;
9436
9437 if ((high_range
9438 = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
9439 == FAIL)
9440 {
9441 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
9442 return FAIL;
9443 }
9444
9445 if (high_range <= new_base)
9446 {
9447 inst.error = _("register range not in ascending order");
9448 return FAIL;
9449 }
9450
9451 for (new_base++; new_base <= high_range; new_base++)
9452 {
9453 if (mask & (1 << new_base))
9454 {
9455 inst.error = _("invalid register list");
9456 return FAIL;
9457 }
9458
9459 mask |= 1 << new_base;
9460 count++;
9461 }
9462 }
9463 }
9464 while (skip_past_comma (str) != FAIL);
9465
9466 if (**str != '}')
9467 {
9468 inst.error = _("invalid register list");
9469 return FAIL;
9470 }
9471
9472 (*str)++;
9473
9474 range |= 2 * count;
9475
9476 /* Sanity check -- should have raised a parse error above. */
9477 if (count == 0 || count > 16)
9478 abort ();
9479
9480 /* Final test -- the registers must be consecutive. */
9481 while (count--)
9482 {
9483 if ((mask & (1 << base_reg++)) == 0)
9484 {
9485 inst.error = _("non-contiguous register range");
9486 return FAIL;
9487 }
9488 }
9489
9490 inst.instruction = tempinst;
9491 return range;
9492 }
9493
9494 static void
9495 vfp_sp_ldstm (str, ldstm_type)
9496 char *str;
9497 enum vfp_ldstm_type ldstm_type;
9498 {
9499 long range;
9500
9501 skip_whitespace (str);
9502
9503 if (reg_required_here (&str, 16) == FAIL)
9504 return;
9505
9506 skip_whitespace (str);
9507
9508 if (*str == '!')
9509 {
9510 inst.instruction |= WRITE_BACK;
9511 str++;
9512 }
9513 else if (ldstm_type != VFP_LDSTMIA)
9514 {
9515 inst.error = _("this addressing mode requires base-register writeback");
9516 return;
9517 }
9518
9519 if (skip_past_comma (&str) == FAIL
9520 || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
9521 {
9522 if (!inst.error)
9523 inst.error = BAD_ARGS;
9524 return;
9525 }
9526
9527 inst.instruction |= range;
9528 end_of_line (str);
9529 }
9530
9531 static void
9532 vfp_dp_ldstm (str, ldstm_type)
9533 char *str;
9534 enum vfp_ldstm_type ldstm_type;
9535 {
9536 long range;
9537
9538 skip_whitespace (str);
9539
9540 if (reg_required_here (&str, 16) == FAIL)
9541 return;
9542
9543 skip_whitespace (str);
9544
9545 if (*str == '!')
9546 {
9547 inst.instruction |= WRITE_BACK;
9548 str++;
9549 }
9550 else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
9551 {
9552 inst.error = _("this addressing mode requires base-register writeback");
9553 return;
9554 }
9555
9556 if (skip_past_comma (&str) == FAIL
9557 || (range = vfp_dp_reg_list (&str)) == FAIL)
9558 {
9559 if (!inst.error)
9560 inst.error = BAD_ARGS;
9561 return;
9562 }
9563
9564 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
9565 range += 1;
9566
9567 inst.instruction |= range;
9568 end_of_line (str);
9569 }
9570
9571 static void
9572 do_vfp_sp_ldstmia (str)
9573 char *str;
9574 {
9575 vfp_sp_ldstm (str, VFP_LDSTMIA);
9576 }
9577
9578 static void
9579 do_vfp_sp_ldstmdb (str)
9580 char *str;
9581 {
9582 vfp_sp_ldstm (str, VFP_LDSTMDB);
9583 }
9584
9585 static void
9586 do_vfp_dp_ldstmia (str)
9587 char *str;
9588 {
9589 vfp_dp_ldstm (str, VFP_LDSTMIA);
9590 }
9591
9592 static void
9593 do_vfp_dp_ldstmdb (str)
9594 char *str;
9595 {
9596 vfp_dp_ldstm (str, VFP_LDSTMDB);
9597 }
9598
9599 static void
9600 do_vfp_xp_ldstmia (str)
9601 char *str;
9602 {
9603 vfp_dp_ldstm (str, VFP_LDSTMIAX);
9604 }
9605
9606 static void
9607 do_vfp_xp_ldstmdb (str)
9608 char *str;
9609 {
9610 vfp_dp_ldstm (str, VFP_LDSTMDBX);
9611 }
9612
9613 static void
9614 do_vfp_sp_compare_z (str)
9615 char *str;
9616 {
9617 skip_whitespace (str);
9618
9619 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9620 {
9621 if (!inst.error)
9622 inst.error = BAD_ARGS;
9623 return;
9624 }
9625
9626 end_of_line (str);
9627 }
9628
9629 static void
9630 do_vfp_dp_compare_z (str)
9631 char *str;
9632 {
9633 skip_whitespace (str);
9634
9635 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9636 {
9637 if (!inst.error)
9638 inst.error = BAD_ARGS;
9639 return;
9640 }
9641
9642 end_of_line (str);
9643 }
9644
9645 static void
9646 do_vfp_dp_sp_cvt (str)
9647 char *str;
9648 {
9649 skip_whitespace (str);
9650
9651 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
9652 return;
9653
9654 if (skip_past_comma (&str) == FAIL
9655 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
9656 {
9657 if (! inst.error)
9658 inst.error = BAD_ARGS;
9659 return;
9660 }
9661
9662 end_of_line (str);
9663 }
9664
9665 static void
9666 do_vfp_sp_dp_cvt (str)
9667 char *str;
9668 {
9669 skip_whitespace (str);
9670
9671 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
9672 return;
9673
9674 if (skip_past_comma (&str) == FAIL
9675 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
9676 {
9677 if (! inst.error)
9678 inst.error = BAD_ARGS;
9679 return;
9680 }
9681
9682 end_of_line (str);
9683 }
9684
9685 /* Thumb specific routines. */
9686
9687 /* Parse and validate that a register is of the right form, this saves
9688 repeated checking of this information in many similar cases.
9689 Unlike the 32-bit case we do not insert the register into the opcode
9690 here, since the position is often unknown until the full instruction
9691 has been parsed. */
9692
9693 static int
9694 thumb_reg (strp, hi_lo)
9695 char ** strp;
9696 int hi_lo;
9697 {
9698 int reg;
9699
9700 if ((reg = reg_required_here (strp, -1)) == FAIL)
9701 return FAIL;
9702
9703 switch (hi_lo)
9704 {
9705 case THUMB_REG_LO:
9706 if (reg > 7)
9707 {
9708 inst.error = _("lo register required");
9709 return FAIL;
9710 }
9711 break;
9712
9713 case THUMB_REG_HI:
9714 if (reg < 8)
9715 {
9716 inst.error = _("hi register required");
9717 return FAIL;
9718 }
9719 break;
9720
9721 default:
9722 break;
9723 }
9724
9725 return reg;
9726 }
9727
9728 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
9729 was SUB. */
9730
9731 static void
9732 thumb_add_sub (str, subtract)
9733 char * str;
9734 int subtract;
9735 {
9736 int Rd, Rs, Rn = FAIL;
9737
9738 skip_whitespace (str);
9739
9740 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
9741 || skip_past_comma (&str) == FAIL)
9742 {
9743 if (! inst.error)
9744 inst.error = BAD_ARGS;
9745 return;
9746 }
9747
9748 if (is_immediate_prefix (*str))
9749 {
9750 Rs = Rd;
9751 str++;
9752 if (my_get_expression (&inst.reloc.exp, &str))
9753 return;
9754 }
9755 else
9756 {
9757 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9758 return;
9759
9760 if (skip_past_comma (&str) == FAIL)
9761 {
9762 /* Two operand format, shuffle the registers
9763 and pretend there are 3. */
9764 Rn = Rs;
9765 Rs = Rd;
9766 }
9767 else if (is_immediate_prefix (*str))
9768 {
9769 str++;
9770 if (my_get_expression (&inst.reloc.exp, &str))
9771 return;
9772 }
9773 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9774 return;
9775 }
9776
9777 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9778 for the latter case, EXPR contains the immediate that was found. */
9779 if (Rn != FAIL)
9780 {
9781 /* All register format. */
9782 if (Rd > 7 || Rs > 7 || Rn > 7)
9783 {
9784 if (Rs != Rd)
9785 {
9786 inst.error = _("dest and source1 must be the same register");
9787 return;
9788 }
9789
9790 /* Can't do this for SUB. */
9791 if (subtract)
9792 {
9793 inst.error = _("subtract valid only on lo regs");
9794 return;
9795 }
9796
9797 inst.instruction = (T_OPCODE_ADD_HI
9798 | (Rd > 7 ? THUMB_H1 : 0)
9799 | (Rn > 7 ? THUMB_H2 : 0));
9800 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
9801 }
9802 else
9803 {
9804 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
9805 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
9806 }
9807 }
9808 else
9809 {
9810 /* Immediate expression, now things start to get nasty. */
9811
9812 /* First deal with HI regs, only very restricted cases allowed:
9813 Adjusting SP, and using PC or SP to get an address. */
9814 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
9815 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
9816 {
9817 inst.error = _("invalid Hi register with immediate");
9818 return;
9819 }
9820
9821 if (inst.reloc.exp.X_op != O_constant)
9822 {
9823 /* Value isn't known yet, all we can do is store all the fragments
9824 we know about in the instruction and let the reloc hacking
9825 work it all out. */
9826 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
9827 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9828 }
9829 else
9830 {
9831 int offset = inst.reloc.exp.X_add_number;
9832
9833 if (subtract)
9834 offset = - offset;
9835
9836 if (offset < 0)
9837 {
9838 offset = - offset;
9839 subtract = 1;
9840
9841 /* Quick check, in case offset is MIN_INT. */
9842 if (offset < 0)
9843 {
9844 inst.error = _("immediate value out of range");
9845 return;
9846 }
9847 }
9848 /* Note - you cannot convert a subtract of 0 into an
9849 add of 0 because the carry flag is set differently. */
9850 else if (offset > 0)
9851 subtract = 0;
9852
9853 if (Rd == REG_SP)
9854 {
9855 if (offset & ~0x1fc)
9856 {
9857 inst.error = _("invalid immediate value for stack adjust");
9858 return;
9859 }
9860 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
9861 inst.instruction |= offset >> 2;
9862 }
9863 else if (Rs == REG_PC || Rs == REG_SP)
9864 {
9865 if (subtract
9866 || (offset & ~0x3fc))
9867 {
9868 inst.error = _("invalid immediate for address calculation");
9869 return;
9870 }
9871 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
9872 : T_OPCODE_ADD_SP);
9873 inst.instruction |= (Rd << 8) | (offset >> 2);
9874 }
9875 else if (Rs == Rd)
9876 {
9877 if (offset & ~0xff)
9878 {
9879 inst.error = _("immediate value out of range");
9880 return;
9881 }
9882 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
9883 inst.instruction |= (Rd << 8) | offset;
9884 }
9885 else
9886 {
9887 if (offset & ~0x7)
9888 {
9889 inst.error = _("immediate value out of range");
9890 return;
9891 }
9892 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
9893 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
9894 }
9895 }
9896 }
9897
9898 end_of_line (str);
9899 }
9900
9901 static void
9902 thumb_shift (str, shift)
9903 char * str;
9904 int shift;
9905 {
9906 int Rd, Rs, Rn = FAIL;
9907
9908 skip_whitespace (str);
9909
9910 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9911 || skip_past_comma (&str) == FAIL)
9912 {
9913 if (! inst.error)
9914 inst.error = BAD_ARGS;
9915 return;
9916 }
9917
9918 if (is_immediate_prefix (*str))
9919 {
9920 /* Two operand immediate format, set Rs to Rd. */
9921 Rs = Rd;
9922 str ++;
9923 if (my_get_expression (&inst.reloc.exp, &str))
9924 return;
9925 }
9926 else
9927 {
9928 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9929 return;
9930
9931 if (skip_past_comma (&str) == FAIL)
9932 {
9933 /* Two operand format, shuffle the registers
9934 and pretend there are 3. */
9935 Rn = Rs;
9936 Rs = Rd;
9937 }
9938 else if (is_immediate_prefix (*str))
9939 {
9940 str++;
9941 if (my_get_expression (&inst.reloc.exp, &str))
9942 return;
9943 }
9944 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9945 return;
9946 }
9947
9948 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9949 for the latter case, EXPR contains the immediate that was found. */
9950
9951 if (Rn != FAIL)
9952 {
9953 if (Rs != Rd)
9954 {
9955 inst.error = _("source1 and dest must be same register");
9956 return;
9957 }
9958
9959 switch (shift)
9960 {
9961 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
9962 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
9963 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
9964 }
9965
9966 inst.instruction |= Rd | (Rn << 3);
9967 }
9968 else
9969 {
9970 switch (shift)
9971 {
9972 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
9973 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
9974 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
9975 }
9976
9977 if (inst.reloc.exp.X_op != O_constant)
9978 {
9979 /* Value isn't known yet, create a dummy reloc and let reloc
9980 hacking fix it up. */
9981 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
9982 }
9983 else
9984 {
9985 unsigned shift_value = inst.reloc.exp.X_add_number;
9986
9987 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
9988 {
9989 inst.error = _("invalid immediate for shift");
9990 return;
9991 }
9992
9993 /* Shifts of zero are handled by converting to LSL. */
9994 if (shift_value == 0)
9995 inst.instruction = T_OPCODE_LSL_I;
9996
9997 /* Shifts of 32 are encoded as a shift of zero. */
9998 if (shift_value == 32)
9999 shift_value = 0;
10000
10001 inst.instruction |= shift_value << 6;
10002 }
10003
10004 inst.instruction |= Rd | (Rs << 3);
10005 }
10006
10007 end_of_line (str);
10008 }
10009
10010 static void
10011 thumb_mov_compare (str, move)
10012 char * str;
10013 int move;
10014 {
10015 int Rd, Rs = FAIL;
10016
10017 skip_whitespace (str);
10018
10019 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
10020 || skip_past_comma (&str) == FAIL)
10021 {
10022 if (! inst.error)
10023 inst.error = BAD_ARGS;
10024 return;
10025 }
10026
10027 if (move != THUMB_CPY && is_immediate_prefix (*str))
10028 {
10029 str++;
10030 if (my_get_expression (&inst.reloc.exp, &str))
10031 return;
10032 }
10033 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10034 return;
10035
10036 if (Rs != FAIL)
10037 {
10038 if (move != THUMB_CPY && Rs < 8 && Rd < 8)
10039 {
10040 if (move == THUMB_MOVE)
10041 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
10042 since a MOV instruction produces unpredictable results. */
10043 inst.instruction = T_OPCODE_ADD_I3;
10044 else
10045 inst.instruction = T_OPCODE_CMP_LR;
10046 inst.instruction |= Rd | (Rs << 3);
10047 }
10048 else
10049 {
10050 if (move == THUMB_MOVE)
10051 inst.instruction = T_OPCODE_MOV_HR;
10052 else if (move != THUMB_CPY)
10053 inst.instruction = T_OPCODE_CMP_HR;
10054
10055 if (Rd > 7)
10056 inst.instruction |= THUMB_H1;
10057
10058 if (Rs > 7)
10059 inst.instruction |= THUMB_H2;
10060
10061 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
10062 }
10063 }
10064 else
10065 {
10066 if (Rd > 7)
10067 {
10068 inst.error = _("only lo regs allowed with immediate");
10069 return;
10070 }
10071
10072 if (move == THUMB_MOVE)
10073 inst.instruction = T_OPCODE_MOV_I8;
10074 else
10075 inst.instruction = T_OPCODE_CMP_I8;
10076
10077 inst.instruction |= Rd << 8;
10078
10079 if (inst.reloc.exp.X_op != O_constant)
10080 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
10081 else
10082 {
10083 unsigned value = inst.reloc.exp.X_add_number;
10084
10085 if (value > 255)
10086 {
10087 inst.error = _("invalid immediate");
10088 return;
10089 }
10090
10091 inst.instruction |= value;
10092 }
10093 }
10094
10095 end_of_line (str);
10096 }
10097
10098 static void
10099 thumb_load_store (str, load_store, size)
10100 char * str;
10101 int load_store;
10102 int size;
10103 {
10104 int Rd, Rb, Ro = FAIL;
10105
10106 skip_whitespace (str);
10107
10108 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10109 || skip_past_comma (&str) == FAIL)
10110 {
10111 if (! inst.error)
10112 inst.error = BAD_ARGS;
10113 return;
10114 }
10115
10116 if (*str == '[')
10117 {
10118 str++;
10119 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
10120 return;
10121
10122 if (skip_past_comma (&str) != FAIL)
10123 {
10124 if (is_immediate_prefix (*str))
10125 {
10126 str++;
10127 if (my_get_expression (&inst.reloc.exp, &str))
10128 return;
10129 }
10130 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10131 return;
10132 }
10133 else
10134 {
10135 inst.reloc.exp.X_op = O_constant;
10136 inst.reloc.exp.X_add_number = 0;
10137 }
10138
10139 if (*str != ']')
10140 {
10141 inst.error = _("expected ']'");
10142 return;
10143 }
10144 str++;
10145 }
10146 else if (*str == '=')
10147 {
10148 if (load_store != THUMB_LOAD)
10149 {
10150 inst.error = _("invalid pseudo operation");
10151 return;
10152 }
10153
10154 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
10155 str++;
10156
10157 skip_whitespace (str);
10158
10159 if (my_get_expression (& inst.reloc.exp, & str))
10160 return;
10161
10162 end_of_line (str);
10163
10164 if ( inst.reloc.exp.X_op != O_constant
10165 && inst.reloc.exp.X_op != O_symbol)
10166 {
10167 inst.error = "Constant expression expected";
10168 return;
10169 }
10170
10171 if (inst.reloc.exp.X_op == O_constant
10172 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
10173 {
10174 /* This can be done with a mov instruction. */
10175
10176 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
10177 inst.instruction |= inst.reloc.exp.X_add_number;
10178 return;
10179 }
10180
10181 /* Insert into literal pool. */
10182 if (add_to_lit_pool () == FAIL)
10183 {
10184 if (!inst.error)
10185 inst.error = "literal pool insertion failed";
10186 return;
10187 }
10188
10189 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10190 inst.reloc.pc_rel = 1;
10191 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
10192 /* Adjust ARM pipeline offset to Thumb. */
10193 inst.reloc.exp.X_add_number += 4;
10194
10195 return;
10196 }
10197 else
10198 {
10199 if (my_get_expression (&inst.reloc.exp, &str))
10200 return;
10201
10202 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
10203 inst.reloc.pc_rel = 1;
10204 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
10205 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10206 end_of_line (str);
10207 return;
10208 }
10209
10210 if (Rb == REG_PC || Rb == REG_SP)
10211 {
10212 if (size != THUMB_WORD)
10213 {
10214 inst.error = _("byte or halfword not valid for base register");
10215 return;
10216 }
10217 else if (Rb == REG_PC && load_store != THUMB_LOAD)
10218 {
10219 inst.error = _("r15 based store not allowed");
10220 return;
10221 }
10222 else if (Ro != FAIL)
10223 {
10224 inst.error = _("invalid base register for register offset");
10225 return;
10226 }
10227
10228 if (Rb == REG_PC)
10229 inst.instruction = T_OPCODE_LDR_PC;
10230 else if (load_store == THUMB_LOAD)
10231 inst.instruction = T_OPCODE_LDR_SP;
10232 else
10233 inst.instruction = T_OPCODE_STR_SP;
10234
10235 inst.instruction |= Rd << 8;
10236 if (inst.reloc.exp.X_op == O_constant)
10237 {
10238 unsigned offset = inst.reloc.exp.X_add_number;
10239
10240 if (offset & ~0x3fc)
10241 {
10242 inst.error = _("invalid offset");
10243 return;
10244 }
10245
10246 inst.instruction |= offset >> 2;
10247 }
10248 else
10249 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10250 }
10251 else if (Rb > 7)
10252 {
10253 inst.error = _("invalid base register in load/store");
10254 return;
10255 }
10256 else if (Ro == FAIL)
10257 {
10258 /* Immediate offset. */
10259 if (size == THUMB_WORD)
10260 inst.instruction = (load_store == THUMB_LOAD
10261 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
10262 else if (size == THUMB_HALFWORD)
10263 inst.instruction = (load_store == THUMB_LOAD
10264 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
10265 else
10266 inst.instruction = (load_store == THUMB_LOAD
10267 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
10268
10269 inst.instruction |= Rd | (Rb << 3);
10270
10271 if (inst.reloc.exp.X_op == O_constant)
10272 {
10273 unsigned offset = inst.reloc.exp.X_add_number;
10274
10275 if (offset & ~(0x1f << size))
10276 {
10277 inst.error = _("invalid offset");
10278 return;
10279 }
10280 inst.instruction |= (offset >> size) << 6;
10281 }
10282 else
10283 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
10284 }
10285 else
10286 {
10287 /* Register offset. */
10288 if (size == THUMB_WORD)
10289 inst.instruction = (load_store == THUMB_LOAD
10290 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
10291 else if (size == THUMB_HALFWORD)
10292 inst.instruction = (load_store == THUMB_LOAD
10293 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
10294 else
10295 inst.instruction = (load_store == THUMB_LOAD
10296 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
10297
10298 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
10299 }
10300
10301 end_of_line (str);
10302 }
10303
10304 /* A register must be given at this point.
10305
10306 Shift is the place to put it in inst.instruction.
10307
10308 Restores input start point on err.
10309 Returns the reg#, or FAIL. */
10310
10311 static int
10312 mav_reg_required_here (str, shift, regtype)
10313 char ** str;
10314 int shift;
10315 enum arm_reg_type regtype;
10316 {
10317 int reg;
10318 char *start = *str;
10319
10320 if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
10321 {
10322 if (shift >= 0)
10323 inst.instruction |= reg << shift;
10324
10325 return reg;
10326 }
10327
10328 /* Restore the start point. */
10329 *str = start;
10330
10331 /* In the few cases where we might be able to accept something else
10332 this error can be overridden. */
10333 inst.error = _(all_reg_maps[regtype].expected);
10334
10335 return FAIL;
10336 }
10337
10338 /* Cirrus Maverick Instructions. */
10339
10340 /* Wrapper functions. */
10341
10342 static void
10343 do_mav_binops_1a (str)
10344 char * str;
10345 {
10346 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
10347 }
10348
10349 static void
10350 do_mav_binops_1b (str)
10351 char * str;
10352 {
10353 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
10354 }
10355
10356 static void
10357 do_mav_binops_1c (str)
10358 char * str;
10359 {
10360 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
10361 }
10362
10363 static void
10364 do_mav_binops_1d (str)
10365 char * str;
10366 {
10367 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
10368 }
10369
10370 static void
10371 do_mav_binops_1e (str)
10372 char * str;
10373 {
10374 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
10375 }
10376
10377 static void
10378 do_mav_binops_1f (str)
10379 char * str;
10380 {
10381 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
10382 }
10383
10384 static void
10385 do_mav_binops_1g (str)
10386 char * str;
10387 {
10388 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
10389 }
10390
10391 static void
10392 do_mav_binops_1h (str)
10393 char * str;
10394 {
10395 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
10396 }
10397
10398 static void
10399 do_mav_binops_1i (str)
10400 char * str;
10401 {
10402 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
10403 }
10404
10405 static void
10406 do_mav_binops_1j (str)
10407 char * str;
10408 {
10409 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
10410 }
10411
10412 static void
10413 do_mav_binops_1k (str)
10414 char * str;
10415 {
10416 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
10417 }
10418
10419 static void
10420 do_mav_binops_1l (str)
10421 char * str;
10422 {
10423 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
10424 }
10425
10426 static void
10427 do_mav_binops_1m (str)
10428 char * str;
10429 {
10430 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
10431 }
10432
10433 static void
10434 do_mav_binops_1n (str)
10435 char * str;
10436 {
10437 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
10438 }
10439
10440 static void
10441 do_mav_binops_1o (str)
10442 char * str;
10443 {
10444 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
10445 }
10446
10447 static void
10448 do_mav_binops_2a (str)
10449 char * str;
10450 {
10451 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
10452 }
10453
10454 static void
10455 do_mav_binops_2b (str)
10456 char * str;
10457 {
10458 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
10459 }
10460
10461 static void
10462 do_mav_binops_2c (str)
10463 char * str;
10464 {
10465 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
10466 }
10467
10468 static void
10469 do_mav_binops_3a (str)
10470 char * str;
10471 {
10472 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
10473 }
10474
10475 static void
10476 do_mav_binops_3b (str)
10477 char * str;
10478 {
10479 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
10480 }
10481
10482 static void
10483 do_mav_binops_3c (str)
10484 char * str;
10485 {
10486 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
10487 }
10488
10489 static void
10490 do_mav_binops_3d (str)
10491 char * str;
10492 {
10493 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
10494 }
10495
10496 static void
10497 do_mav_triple_4a (str)
10498 char * str;
10499 {
10500 do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
10501 }
10502
10503 static void
10504 do_mav_triple_4b (str)
10505 char * str;
10506 {
10507 do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
10508 }
10509
10510 static void
10511 do_mav_triple_5a (str)
10512 char * str;
10513 {
10514 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
10515 }
10516
10517 static void
10518 do_mav_triple_5b (str)
10519 char * str;
10520 {
10521 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
10522 }
10523
10524 static void
10525 do_mav_triple_5c (str)
10526 char * str;
10527 {
10528 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
10529 }
10530
10531 static void
10532 do_mav_triple_5d (str)
10533 char * str;
10534 {
10535 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
10536 }
10537
10538 static void
10539 do_mav_triple_5e (str)
10540 char * str;
10541 {
10542 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
10543 }
10544
10545 static void
10546 do_mav_triple_5f (str)
10547 char * str;
10548 {
10549 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
10550 }
10551
10552 static void
10553 do_mav_triple_5g (str)
10554 char * str;
10555 {
10556 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
10557 }
10558
10559 static void
10560 do_mav_triple_5h (str)
10561 char * str;
10562 {
10563 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
10564 }
10565
10566 static void
10567 do_mav_quad_6a (str)
10568 char * str;
10569 {
10570 do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
10571 REG_TYPE_MVFX);
10572 }
10573
10574 static void
10575 do_mav_quad_6b (str)
10576 char * str;
10577 {
10578 do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
10579 REG_TYPE_MVFX);
10580 }
10581
10582 /* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
10583 static void
10584 do_mav_dspsc_1 (str)
10585 char * str;
10586 {
10587 skip_whitespace (str);
10588
10589 /* cfmvsc32. */
10590 if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
10591 || skip_past_comma (&str) == FAIL
10592 || mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL)
10593 {
10594 if (!inst.error)
10595 inst.error = BAD_ARGS;
10596
10597 return;
10598 }
10599
10600 end_of_line (str);
10601 }
10602
10603 /* cfmv32sc<cond> MVDX[15:0],DSPSC. */
10604 static void
10605 do_mav_dspsc_2 (str)
10606 char * str;
10607 {
10608 skip_whitespace (str);
10609
10610 /* cfmv32sc. */
10611 if (mav_reg_required_here (&str, 12, REG_TYPE_MVDX) == FAIL
10612 || skip_past_comma (&str) == FAIL
10613 || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
10614 {
10615 if (!inst.error)
10616 inst.error = BAD_ARGS;
10617
10618 return;
10619 }
10620
10621 end_of_line (str);
10622 }
10623
10624 static void
10625 do_mav_shift_1 (str)
10626 char * str;
10627 {
10628 do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
10629 }
10630
10631 static void
10632 do_mav_shift_2 (str)
10633 char * str;
10634 {
10635 do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
10636 }
10637
10638 static void
10639 do_mav_ldst_1 (str)
10640 char * str;
10641 {
10642 do_mav_ldst (str, REG_TYPE_MVF);
10643 }
10644
10645 static void
10646 do_mav_ldst_2 (str)
10647 char * str;
10648 {
10649 do_mav_ldst (str, REG_TYPE_MVD);
10650 }
10651
10652 static void
10653 do_mav_ldst_3 (str)
10654 char * str;
10655 {
10656 do_mav_ldst (str, REG_TYPE_MVFX);
10657 }
10658
10659 static void
10660 do_mav_ldst_4 (str)
10661 char * str;
10662 {
10663 do_mav_ldst (str, REG_TYPE_MVDX);
10664 }
10665
10666 /* Isnsn like "foo X,Y". */
10667
10668 static void
10669 do_mav_binops (str, mode, reg0, reg1)
10670 char * str;
10671 int mode;
10672 enum arm_reg_type reg0;
10673 enum arm_reg_type reg1;
10674 {
10675 int shift0, shift1;
10676
10677 shift0 = mode & 0xff;
10678 shift1 = (mode >> 8) & 0xff;
10679
10680 skip_whitespace (str);
10681
10682 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10683 || skip_past_comma (&str) == FAIL
10684 || mav_reg_required_here (&str, shift1, reg1) == FAIL)
10685 {
10686 if (!inst.error)
10687 inst.error = BAD_ARGS;
10688 }
10689 else
10690 end_of_line (str);
10691 }
10692
10693 /* Isnsn like "foo X,Y,Z". */
10694
10695 static void
10696 do_mav_triple (str, mode, reg0, reg1, reg2)
10697 char * str;
10698 int mode;
10699 enum arm_reg_type reg0;
10700 enum arm_reg_type reg1;
10701 enum arm_reg_type reg2;
10702 {
10703 int shift0, shift1, shift2;
10704
10705 shift0 = mode & 0xff;
10706 shift1 = (mode >> 8) & 0xff;
10707 shift2 = (mode >> 16) & 0xff;
10708
10709 skip_whitespace (str);
10710
10711 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10712 || skip_past_comma (&str) == FAIL
10713 || mav_reg_required_here (&str, shift1, reg1) == FAIL
10714 || skip_past_comma (&str) == FAIL
10715 || mav_reg_required_here (&str, shift2, reg2) == FAIL)
10716 {
10717 if (!inst.error)
10718 inst.error = BAD_ARGS;
10719 }
10720 else
10721 end_of_line (str);
10722 }
10723
10724 /* Isnsn like "foo W,X,Y,Z".
10725 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
10726
10727 static void
10728 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
10729 char * str;
10730 int mode;
10731 enum arm_reg_type reg0;
10732 enum arm_reg_type reg1;
10733 enum arm_reg_type reg2;
10734 enum arm_reg_type reg3;
10735 {
10736 int shift0, shift1, shift2, shift3;
10737
10738 shift0= mode & 0xff;
10739 shift1 = (mode >> 8) & 0xff;
10740 shift2 = (mode >> 16) & 0xff;
10741 shift3 = (mode >> 24) & 0xff;
10742
10743 skip_whitespace (str);
10744
10745 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
10746 || skip_past_comma (&str) == FAIL
10747 || mav_reg_required_here (&str, shift1, reg1) == FAIL
10748 || skip_past_comma (&str) == FAIL
10749 || mav_reg_required_here (&str, shift2, reg2) == FAIL
10750 || skip_past_comma (&str) == FAIL
10751 || mav_reg_required_here (&str, shift3, reg3) == FAIL)
10752 {
10753 if (!inst.error)
10754 inst.error = BAD_ARGS;
10755 }
10756 else
10757 end_of_line (str);
10758 }
10759
10760 /* Maverick shift immediate instructions.
10761 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10762 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
10763
10764 static void
10765 do_mav_shift (str, reg0, reg1)
10766 char * str;
10767 enum arm_reg_type reg0;
10768 enum arm_reg_type reg1;
10769 {
10770 int error;
10771 int imm, neg = 0;
10772
10773 skip_whitespace (str);
10774
10775 error = 0;
10776
10777 if (mav_reg_required_here (&str, 12, reg0) == FAIL
10778 || skip_past_comma (&str) == FAIL
10779 || mav_reg_required_here (&str, 16, reg1) == FAIL
10780 || skip_past_comma (&str) == FAIL)
10781 {
10782 if (!inst.error)
10783 inst.error = BAD_ARGS;
10784 return;
10785 }
10786
10787 /* Calculate the immediate operand.
10788 The operand is a 7bit signed number. */
10789 skip_whitespace (str);
10790
10791 if (*str == '#')
10792 ++str;
10793
10794 if (!ISDIGIT (*str) && *str != '-')
10795 {
10796 inst.error = _("expecting immediate, 7bit operand");
10797 return;
10798 }
10799
10800 if (*str == '-')
10801 {
10802 neg = 1;
10803 ++str;
10804 }
10805
10806 for (imm = 0; *str && ISDIGIT (*str); ++str)
10807 imm = imm * 10 + *str - '0';
10808
10809 if (imm > 64)
10810 {
10811 inst.error = _("immediate out of range");
10812 return;
10813 }
10814
10815 /* Make negative imm's into 7bit signed numbers. */
10816 if (neg)
10817 {
10818 imm = -imm;
10819 imm &= 0x0000007f;
10820 }
10821
10822 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10823 Bits 5-7 of the insn should have bits 4-6 of the immediate.
10824 Bit 4 should be 0. */
10825 imm = (imm & 0xf) | ((imm & 0x70) << 1);
10826
10827 inst.instruction |= imm;
10828 end_of_line (str);
10829 }
10830
10831 static int
10832 mav_parse_offset (str, negative)
10833 char ** str;
10834 int *negative;
10835 {
10836 char * p = *str;
10837 int offset;
10838
10839 *negative = 0;
10840
10841 skip_whitespace (p);
10842
10843 if (*p == '#')
10844 ++p;
10845
10846 if (*p == '-')
10847 {
10848 *negative = 1;
10849 ++p;
10850 }
10851
10852 if (!ISDIGIT (*p))
10853 {
10854 inst.error = _("offset expected");
10855 return 0;
10856 }
10857
10858 for (offset = 0; *p && ISDIGIT (*p); ++p)
10859 offset = offset * 10 + *p - '0';
10860
10861 if (offset > 0xff)
10862 {
10863 inst.error = _("offset out of range");
10864 return 0;
10865 }
10866
10867 *str = p;
10868
10869 return *negative ? -offset : offset;
10870 }
10871
10872 /* Maverick load/store instructions.
10873 <insn><cond> CRd,[Rn,<offset>]{!}.
10874 <insn><cond> CRd,[Rn],<offset>. */
10875
10876 static void
10877 do_mav_ldst (str, reg0)
10878 char * str;
10879 enum arm_reg_type reg0;
10880 {
10881 int offset, negative;
10882
10883 skip_whitespace (str);
10884
10885 if (mav_reg_required_here (&str, 12, reg0) == FAIL
10886 || skip_past_comma (&str) == FAIL
10887 || *str++ != '['
10888 || reg_required_here (&str, 16) == FAIL)
10889 goto fail_ldst;
10890
10891 if (skip_past_comma (&str) == SUCCESS)
10892 {
10893 /* You are here: "<offset>]{!}". */
10894 inst.instruction |= PRE_INDEX;
10895
10896 offset = mav_parse_offset (&str, &negative);
10897
10898 if (inst.error)
10899 return;
10900
10901 if (*str++ != ']')
10902 {
10903 inst.error = _("missing ]");
10904 return;
10905 }
10906
10907 if (*str == '!')
10908 {
10909 inst.instruction |= WRITE_BACK;
10910 ++str;
10911 }
10912 }
10913 else
10914 {
10915 /* You are here: "], <offset>". */
10916 if (*str++ != ']')
10917 {
10918 inst.error = _("missing ]");
10919 return;
10920 }
10921
10922 if (skip_past_comma (&str) == FAIL
10923 || (offset = mav_parse_offset (&str, &negative), inst.error))
10924 goto fail_ldst;
10925
10926 inst.instruction |= CP_T_WB; /* Post indexed, set bit W. */
10927 }
10928
10929 if (negative)
10930 offset = -offset;
10931 else
10932 inst.instruction |= CP_T_UD; /* Positive, so set bit U. */
10933
10934 inst.instruction |= offset >> 2;
10935 end_of_line (str);
10936 return;
10937
10938 fail_ldst:
10939 if (!inst.error)
10940 inst.error = BAD_ARGS;
10941 }
10942
10943 static void
10944 do_t_nop (str)
10945 char * str;
10946 {
10947 /* Do nothing. */
10948 end_of_line (str);
10949 }
10950
10951 /* Handle the Format 4 instructions that do not have equivalents in other
10952 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
10953 BIC and MVN. */
10954
10955 static void
10956 do_t_arit (str)
10957 char * str;
10958 {
10959 int Rd, Rs, Rn;
10960
10961 skip_whitespace (str);
10962
10963 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
10964 || skip_past_comma (&str) == FAIL
10965 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10966 {
10967 inst.error = BAD_ARGS;
10968 return;
10969 }
10970
10971 if (skip_past_comma (&str) != FAIL)
10972 {
10973 /* Three operand format not allowed for TST, CMN, NEG and MVN.
10974 (It isn't allowed for CMP either, but that isn't handled by this
10975 function.) */
10976 if (inst.instruction == T_OPCODE_TST
10977 || inst.instruction == T_OPCODE_CMN
10978 || inst.instruction == T_OPCODE_NEG
10979 || inst.instruction == T_OPCODE_MVN)
10980 {
10981 inst.error = BAD_ARGS;
10982 return;
10983 }
10984
10985 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
10986 return;
10987
10988 if (Rs != Rd)
10989 {
10990 inst.error = _("dest and source1 must be the same register");
10991 return;
10992 }
10993 Rs = Rn;
10994 }
10995
10996 if (inst.instruction == T_OPCODE_MUL
10997 && Rs == Rd)
10998 as_tsktsk (_("Rs and Rd must be different in MUL"));
10999
11000 inst.instruction |= Rd | (Rs << 3);
11001 end_of_line (str);
11002 }
11003
11004 static void
11005 do_t_add (str)
11006 char * str;
11007 {
11008 thumb_add_sub (str, 0);
11009 }
11010
11011 static void
11012 do_t_asr (str)
11013 char * str;
11014 {
11015 thumb_shift (str, THUMB_ASR);
11016 }
11017
11018 static void
11019 do_t_branch9 (str)
11020 char * str;
11021 {
11022 if (my_get_expression (&inst.reloc.exp, &str))
11023 return;
11024 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
11025 inst.reloc.pc_rel = 1;
11026 end_of_line (str);
11027 }
11028
11029 static void
11030 do_t_branch12 (str)
11031 char * str;
11032 {
11033 if (my_get_expression (&inst.reloc.exp, &str))
11034 return;
11035 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
11036 inst.reloc.pc_rel = 1;
11037 end_of_line (str);
11038 }
11039
11040 /* Find the real, Thumb encoded start of a Thumb function. */
11041
11042 static symbolS *
11043 find_real_start (symbolP)
11044 symbolS * symbolP;
11045 {
11046 char * real_start;
11047 const char * name = S_GET_NAME (symbolP);
11048 symbolS * new_target;
11049
11050 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
11051 #define STUB_NAME ".real_start_of"
11052
11053 if (name == NULL)
11054 abort ();
11055
11056 /* Names that start with '.' are local labels, not function entry points.
11057 The compiler may generate BL instructions to these labels because it
11058 needs to perform a branch to a far away location. */
11059 if (name[0] == '.')
11060 return symbolP;
11061
11062 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
11063 sprintf (real_start, "%s%s", STUB_NAME, name);
11064
11065 new_target = symbol_find (real_start);
11066
11067 if (new_target == NULL)
11068 {
11069 as_warn ("Failed to find real start of function: %s\n", name);
11070 new_target = symbolP;
11071 }
11072
11073 free (real_start);
11074
11075 return new_target;
11076 }
11077
11078 static void
11079 do_t_branch23 (str)
11080 char * str;
11081 {
11082 if (my_get_expression (& inst.reloc.exp, & str))
11083 return;
11084
11085 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
11086 inst.reloc.pc_rel = 1;
11087 end_of_line (str);
11088
11089 /* If the destination of the branch is a defined symbol which does not have
11090 the THUMB_FUNC attribute, then we must be calling a function which has
11091 the (interfacearm) attribute. We look for the Thumb entry point to that
11092 function and change the branch to refer to that function instead. */
11093 if ( inst.reloc.exp.X_op == O_symbol
11094 && inst.reloc.exp.X_add_symbol != NULL
11095 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
11096 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
11097 inst.reloc.exp.X_add_symbol =
11098 find_real_start (inst.reloc.exp.X_add_symbol);
11099 }
11100
11101 static void
11102 do_t_bx (str)
11103 char * str;
11104 {
11105 int reg;
11106
11107 skip_whitespace (str);
11108
11109 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
11110 return;
11111
11112 /* This sets THUMB_H2 from the top bit of reg. */
11113 inst.instruction |= reg << 3;
11114
11115 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
11116 should cause the alignment to be checked once it is known. This is
11117 because BX PC only works if the instruction is word aligned. */
11118
11119 end_of_line (str);
11120 }
11121
11122 static void
11123 do_t_compare (str)
11124 char * str;
11125 {
11126 thumb_mov_compare (str, THUMB_COMPARE);
11127 }
11128
11129 static void
11130 do_t_ldmstm (str)
11131 char * str;
11132 {
11133 int Rb;
11134 long range;
11135
11136 skip_whitespace (str);
11137
11138 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
11139 return;
11140
11141 if (*str != '!')
11142 as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
11143 else
11144 str++;
11145
11146 if (skip_past_comma (&str) == FAIL
11147 || (range = reg_list (&str)) == FAIL)
11148 {
11149 if (! inst.error)
11150 inst.error = BAD_ARGS;
11151 return;
11152 }
11153
11154 if (inst.reloc.type != BFD_RELOC_NONE)
11155 {
11156 /* This really doesn't seem worth it. */
11157 inst.reloc.type = BFD_RELOC_NONE;
11158 inst.error = _("expression too complex");
11159 return;
11160 }
11161
11162 if (range & ~0xff)
11163 {
11164 inst.error = _("only lo-regs valid in load/store multiple");
11165 return;
11166 }
11167
11168 inst.instruction |= (Rb << 8) | range;
11169 end_of_line (str);
11170 }
11171
11172 static void
11173 do_t_ldr (str)
11174 char * str;
11175 {
11176 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
11177 }
11178
11179 static void
11180 do_t_ldrb (str)
11181 char * str;
11182 {
11183 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
11184 }
11185
11186 static void
11187 do_t_ldrh (str)
11188 char * str;
11189 {
11190 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
11191 }
11192
11193 static void
11194 do_t_lds (str)
11195 char * str;
11196 {
11197 int Rd, Rb, Ro;
11198
11199 skip_whitespace (str);
11200
11201 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11202 || skip_past_comma (&str) == FAIL
11203 || *str++ != '['
11204 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11205 || skip_past_comma (&str) == FAIL
11206 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
11207 || *str++ != ']')
11208 {
11209 if (! inst.error)
11210 inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
11211 return;
11212 }
11213
11214 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
11215 end_of_line (str);
11216 }
11217
11218 static void
11219 do_t_lsl (str)
11220 char * str;
11221 {
11222 thumb_shift (str, THUMB_LSL);
11223 }
11224
11225 static void
11226 do_t_lsr (str)
11227 char * str;
11228 {
11229 thumb_shift (str, THUMB_LSR);
11230 }
11231
11232 static void
11233 do_t_mov (str)
11234 char * str;
11235 {
11236 thumb_mov_compare (str, THUMB_MOVE);
11237 }
11238
11239 static void
11240 do_t_push_pop (str)
11241 char * str;
11242 {
11243 long range;
11244
11245 skip_whitespace (str);
11246
11247 if ((range = reg_list (&str)) == FAIL)
11248 {
11249 if (! inst.error)
11250 inst.error = BAD_ARGS;
11251 return;
11252 }
11253
11254 if (inst.reloc.type != BFD_RELOC_NONE)
11255 {
11256 /* This really doesn't seem worth it. */
11257 inst.reloc.type = BFD_RELOC_NONE;
11258 inst.error = _("expression too complex");
11259 return;
11260 }
11261
11262 if (range & ~0xff)
11263 {
11264 if ((inst.instruction == T_OPCODE_PUSH
11265 && (range & ~0xff) == 1 << REG_LR)
11266 || (inst.instruction == T_OPCODE_POP
11267 && (range & ~0xff) == 1 << REG_PC))
11268 {
11269 inst.instruction |= THUMB_PP_PC_LR;
11270 range &= 0xff;
11271 }
11272 else
11273 {
11274 inst.error = _("invalid register list to push/pop instruction");
11275 return;
11276 }
11277 }
11278
11279 inst.instruction |= range;
11280 end_of_line (str);
11281 }
11282
11283 static void
11284 do_t_str (str)
11285 char * str;
11286 {
11287 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
11288 }
11289
11290 static void
11291 do_t_strb (str)
11292 char * str;
11293 {
11294 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
11295 }
11296
11297 static void
11298 do_t_strh (str)
11299 char * str;
11300 {
11301 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
11302 }
11303
11304 static void
11305 do_t_sub (str)
11306 char * str;
11307 {
11308 thumb_add_sub (str, 1);
11309 }
11310
11311 static void
11312 do_t_swi (str)
11313 char * str;
11314 {
11315 skip_whitespace (str);
11316
11317 if (my_get_expression (&inst.reloc.exp, &str))
11318 return;
11319
11320 inst.reloc.type = BFD_RELOC_ARM_SWI;
11321 end_of_line (str);
11322 }
11323
11324 static void
11325 do_t_adr (str)
11326 char * str;
11327 {
11328 int reg;
11329
11330 /* This is a pseudo-op of the form "adr rd, label" to be converted
11331 into a relative address of the form "add rd, pc, #label-.-4". */
11332 skip_whitespace (str);
11333
11334 /* Store Rd in temporary location inside instruction. */
11335 if ((reg = reg_required_here (&str, 4)) == FAIL
11336 || (reg > 7) /* For Thumb reg must be r0..r7. */
11337 || skip_past_comma (&str) == FAIL
11338 || my_get_expression (&inst.reloc.exp, &str))
11339 {
11340 if (!inst.error)
11341 inst.error = BAD_ARGS;
11342 return;
11343 }
11344
11345 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
11346 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
11347 inst.reloc.pc_rel = 1;
11348 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
11349
11350 end_of_line (str);
11351 }
11352
11353 static void
11354 insert_reg (r, htab)
11355 const struct reg_entry *r;
11356 struct hash_control *htab;
11357 {
11358 int len = strlen (r->name) + 2;
11359 char * buf = (char *) xmalloc (len);
11360 char * buf2 = (char *) xmalloc (len);
11361 int i = 0;
11362
11363 #ifdef REGISTER_PREFIX
11364 buf[i++] = REGISTER_PREFIX;
11365 #endif
11366
11367 strcpy (buf + i, r->name);
11368
11369 for (i = 0; buf[i]; i++)
11370 buf2[i] = TOUPPER (buf[i]);
11371
11372 buf2[i] = '\0';
11373
11374 hash_insert (htab, buf, (PTR) r);
11375 hash_insert (htab, buf2, (PTR) r);
11376 }
11377
11378 static void
11379 build_reg_hsh (map)
11380 struct reg_map *map;
11381 {
11382 const struct reg_entry *r;
11383
11384 if ((map->htab = hash_new ()) == NULL)
11385 as_fatal (_("virtual memory exhausted"));
11386
11387 for (r = map->names; r->name != NULL; r++)
11388 insert_reg (r, map->htab);
11389 }
11390
11391 static void
11392 insert_reg_alias (str, regnum, htab)
11393 char *str;
11394 int regnum;
11395 struct hash_control *htab;
11396 {
11397 const char *error;
11398 struct reg_entry *new = xmalloc (sizeof (struct reg_entry));
11399 const char *name = xmalloc (strlen (str) + 1);
11400
11401 strcpy ((char *) name, str);
11402
11403 new->name = name;
11404 new->number = regnum;
11405 new->builtin = FALSE;
11406
11407 error = hash_insert (htab, name, (PTR) new);
11408 if (error)
11409 {
11410 as_bad (_("failed to create an alias for %s, reason: %s"),
11411 str, error);
11412 free ((char *) name);
11413 free (new);
11414 }
11415 }
11416
11417 /* Look for the .req directive. This is of the form:
11418
11419 new_register_name .req existing_register_name
11420
11421 If we find one, or if it looks sufficiently like one that we want to
11422 handle any error here, return non-zero. Otherwise return zero. */
11423 static int
11424 create_register_alias (newname, p)
11425 char *newname;
11426 char *p;
11427 {
11428 char *q;
11429 char c;
11430
11431 q = p;
11432 skip_whitespace (q);
11433
11434 c = *p;
11435 *p = '\0';
11436
11437 if (*q && !strncmp (q, ".req ", 5))
11438 {
11439 char *copy_of_str;
11440 char *r;
11441
11442 #ifdef IGNORE_OPCODE_CASE
11443 newname = original_case_string;
11444 #endif
11445 copy_of_str = newname;
11446
11447 q += 4;
11448 skip_whitespace (q);
11449
11450 for (r = q; *r != '\0'; r++)
11451 if (*r == ' ')
11452 break;
11453
11454 if (r != q)
11455 {
11456 enum arm_reg_type new_type, old_type;
11457 int old_regno;
11458 char d = *r;
11459
11460 *r = '\0';
11461 old_type = arm_reg_parse_any (q);
11462 *r = d;
11463
11464 new_type = arm_reg_parse_any (newname);
11465
11466 if (new_type == REG_TYPE_MAX)
11467 {
11468 if (old_type != REG_TYPE_MAX)
11469 {
11470 old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
11471 insert_reg_alias (newname, old_regno,
11472 all_reg_maps[old_type].htab);
11473 }
11474 else
11475 as_warn (_("register '%s' does not exist\n"), q);
11476 }
11477 else if (old_type == REG_TYPE_MAX)
11478 {
11479 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
11480 copy_of_str, q);
11481 }
11482 else
11483 {
11484 /* Do not warn about redefinitions to the same alias. */
11485 if (new_type != old_type
11486 || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
11487 != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
11488 as_warn (_("ignoring redefinition of register alias '%s'"),
11489 copy_of_str);
11490
11491 }
11492 }
11493 else
11494 as_warn (_("ignoring incomplete .req pseuso op"));
11495
11496 *p = c;
11497 return 1;
11498 }
11499
11500 *p = c;
11501 return 0;
11502 }
11503
11504 static void
11505 set_constant_flonums ()
11506 {
11507 int i;
11508
11509 for (i = 0; i < NUM_FLOAT_VALS; i++)
11510 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
11511 abort ();
11512 }
11513
11514 /* Iterate over the base tables to create the instruction patterns. */
11515 static void
11516 build_arm_ops_hsh ()
11517 {
11518 unsigned int i;
11519 unsigned int j;
11520 static struct obstack insn_obstack;
11521
11522 obstack_begin (&insn_obstack, 4000);
11523
11524 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
11525 {
11526 const struct asm_opcode *insn = insns + i;
11527
11528 if (insn->cond_offset != 0)
11529 {
11530 /* Insn supports conditional execution. Build the varaints
11531 and insert them in the hash table. */
11532 for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
11533 {
11534 unsigned len = strlen (insn->template);
11535 struct asm_opcode *new;
11536 char *template;
11537
11538 new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
11539 /* All condition codes are two characters. */
11540 template = obstack_alloc (&insn_obstack, len + 3);
11541
11542 strncpy (template, insn->template, insn->cond_offset);
11543 strcpy (template + insn->cond_offset, conds[j].template);
11544 if (len > insn->cond_offset)
11545 strcpy (template + insn->cond_offset + 2,
11546 insn->template + insn->cond_offset);
11547 new->template = template;
11548 new->cond_offset = 0;
11549 new->variant = insn->variant;
11550 new->parms = insn->parms;
11551 new->value = (insn->value & ~COND_MASK) | conds[j].value;
11552
11553 hash_insert (arm_ops_hsh, new->template, (PTR) new);
11554 }
11555 }
11556 /* Finally, insert the unconditional insn in the table directly;
11557 no need to build a copy. */
11558 hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
11559 }
11560 }
11561
11562 #if 0 /* Suppressed - for now. */
11563 #if defined OBJ_ELF || defined OBJ_COFF
11564
11565 #ifdef OBJ_ELF
11566 #define arm_Note Elf_External_Note
11567 #else
11568 typedef struct
11569 {
11570 unsigned char namesz[4]; /* Size of entry's owner string. */
11571 unsigned char descsz[4]; /* Size of the note descriptor. */
11572 unsigned char type[4]; /* Interpretation of the descriptor. */
11573 char name[1]; /* Start of the name+desc data. */
11574 } arm_Note;
11575 #endif
11576
11577 /* The description is kept to a fix sized in order to make updating
11578 it and merging it easier. */
11579 #define ARM_NOTE_DESCRIPTION_LENGTH 8
11580
11581 static void
11582 arm_add_note (name, description, type)
11583 const char * name;
11584 const char * description;
11585 unsigned int type;
11586 {
11587 arm_Note note ATTRIBUTE_UNUSED;
11588 char * p;
11589 unsigned int name_len;
11590
11591 name_len = (strlen (name) + 1 + 3) & ~3;
11592
11593 p = frag_more (sizeof (note.namesz));
11594 md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
11595
11596 p = frag_more (sizeof (note.descsz));
11597 md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
11598
11599 p = frag_more (sizeof (note.type));
11600 md_number_to_chars (p, (valueT) type, sizeof (note.type));
11601
11602 p = frag_more (name_len);
11603 strcpy (p, name);
11604
11605 p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
11606 strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
11607 frag_align (2, 0, 0);
11608 }
11609 #endif
11610 #endif
11611
11612 void
11613 md_begin ()
11614 {
11615 unsigned mach;
11616 unsigned int i;
11617
11618 if ( (arm_ops_hsh = hash_new ()) == NULL
11619 || (arm_tops_hsh = hash_new ()) == NULL
11620 || (arm_cond_hsh = hash_new ()) == NULL
11621 || (arm_shift_hsh = hash_new ()) == NULL
11622 || (arm_psr_hsh = hash_new ()) == NULL)
11623 as_fatal (_("virtual memory exhausted"));
11624
11625 build_arm_ops_hsh ();
11626 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
11627 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
11628 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
11629 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
11630 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
11631 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
11632 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
11633 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
11634
11635 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
11636 build_reg_hsh (all_reg_maps + i);
11637
11638 set_constant_flonums ();
11639
11640 /* Set the cpu variant based on the command-line options. We prefer
11641 -mcpu= over -march= if both are set (as for GCC); and we prefer
11642 -mfpu= over any other way of setting the floating point unit.
11643 Use of legacy options with new options are faulted. */
11644 if (legacy_cpu != -1)
11645 {
11646 if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
11647 as_bad (_("use of old and new-style options to set CPU type"));
11648
11649 mcpu_cpu_opt = legacy_cpu;
11650 }
11651 else if (mcpu_cpu_opt == -1)
11652 mcpu_cpu_opt = march_cpu_opt;
11653
11654 if (legacy_fpu != -1)
11655 {
11656 if (mfpu_opt != -1)
11657 as_bad (_("use of old and new-style options to set FPU type"));
11658
11659 mfpu_opt = legacy_fpu;
11660 }
11661 else if (mfpu_opt == -1)
11662 {
11663 #if !(defined (TE_LINUX) || defined (TE_NetBSD))
11664 /* Some environments specify a default FPU. If they don't, infer it
11665 from the processor. */
11666 if (mcpu_fpu_opt != -1)
11667 mfpu_opt = mcpu_fpu_opt;
11668 else
11669 mfpu_opt = march_fpu_opt;
11670 #else
11671 mfpu_opt = FPU_DEFAULT;
11672 #endif
11673 }
11674
11675 if (mfpu_opt == -1)
11676 {
11677 if (mcpu_cpu_opt == -1)
11678 mfpu_opt = FPU_DEFAULT;
11679 else if (mcpu_cpu_opt & ARM_EXT_V5)
11680 mfpu_opt = FPU_ARCH_VFP_V2;
11681 else
11682 mfpu_opt = FPU_ARCH_FPA;
11683 }
11684
11685 if (mcpu_cpu_opt == -1)
11686 mcpu_cpu_opt = CPU_DEFAULT;
11687
11688 cpu_variant = mcpu_cpu_opt | mfpu_opt;
11689
11690 #if defined OBJ_COFF || defined OBJ_ELF
11691 {
11692 unsigned int flags = meabi_flags;
11693
11694 switch (meabi_flags)
11695 {
11696 case EF_ARM_EABI_UNKNOWN:
11697 /* Set the flags in the private structure. */
11698 if (uses_apcs_26) flags |= F_APCS26;
11699 if (support_interwork) flags |= F_INTERWORK;
11700 if (uses_apcs_float) flags |= F_APCS_FLOAT;
11701 if (pic_code) flags |= F_PIC;
11702 if ((cpu_variant & FPU_ANY) == FPU_NONE
11703 || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only. */
11704 {
11705 flags |= F_SOFT_FLOAT;
11706 }
11707 switch (mfloat_abi_opt)
11708 {
11709 case ARM_FLOAT_ABI_SOFT:
11710 case ARM_FLOAT_ABI_SOFTFP:
11711 flags |= F_SOFT_FLOAT;
11712 break;
11713
11714 case ARM_FLOAT_ABI_HARD:
11715 if (flags & F_SOFT_FLOAT)
11716 as_bad (_("hard-float conflicts with specified fpu"));
11717 break;
11718 }
11719 /* Using VFP conventions (even if soft-float). */
11720 if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
11721
11722 #if defined OBJ_ELF
11723 if (cpu_variant & FPU_ARCH_MAVERICK)
11724 flags |= EF_ARM_MAVERICK_FLOAT;
11725 #endif
11726 break;
11727
11728 case EF_ARM_EABI_VER3:
11729 /* No additional flags to set. */
11730 break;
11731
11732 default:
11733 abort ();
11734 }
11735
11736 bfd_set_private_flags (stdoutput, flags);
11737
11738 /* We have run out flags in the COFF header to encode the
11739 status of ATPCS support, so instead we create a dummy,
11740 empty, debug section called .arm.atpcs. */
11741 if (atpcs)
11742 {
11743 asection * sec;
11744
11745 sec = bfd_make_section (stdoutput, ".arm.atpcs");
11746
11747 if (sec != NULL)
11748 {
11749 bfd_set_section_flags
11750 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
11751 bfd_set_section_size (stdoutput, sec, 0);
11752 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
11753 }
11754 }
11755 }
11756 #endif
11757
11758 /* Record the CPU type as well. */
11759 switch (cpu_variant & ARM_CPU_MASK)
11760 {
11761 case ARM_2:
11762 mach = bfd_mach_arm_2;
11763 break;
11764
11765 case ARM_3: /* Also ARM_250. */
11766 mach = bfd_mach_arm_2a;
11767 break;
11768
11769 case ARM_6: /* Also ARM_7. */
11770 mach = bfd_mach_arm_3;
11771 break;
11772
11773 default:
11774 mach = bfd_mach_arm_unknown;
11775 break;
11776 }
11777
11778 /* Catch special cases. */
11779 if (cpu_variant & ARM_CEXT_IWMMXT)
11780 mach = bfd_mach_arm_iWMMXt;
11781 else if (cpu_variant & ARM_CEXT_XSCALE)
11782 mach = bfd_mach_arm_XScale;
11783 else if (cpu_variant & ARM_CEXT_MAVERICK)
11784 mach = bfd_mach_arm_ep9312;
11785 else if (cpu_variant & ARM_EXT_V5E)
11786 mach = bfd_mach_arm_5TE;
11787 else if (cpu_variant & ARM_EXT_V5)
11788 {
11789 if (cpu_variant & ARM_EXT_V4T)
11790 mach = bfd_mach_arm_5T;
11791 else
11792 mach = bfd_mach_arm_5;
11793 }
11794 else if (cpu_variant & ARM_EXT_V4)
11795 {
11796 if (cpu_variant & ARM_EXT_V4T)
11797 mach = bfd_mach_arm_4T;
11798 else
11799 mach = bfd_mach_arm_4;
11800 }
11801 else if (cpu_variant & ARM_EXT_V3M)
11802 mach = bfd_mach_arm_3M;
11803
11804 #if 0 /* Suppressed - for now. */
11805 #if defined (OBJ_ELF) || defined (OBJ_COFF)
11806
11807 /* Create a .note section to fully identify this arm binary. */
11808
11809 #define NOTE_ARCH_STRING "arch: "
11810
11811 #if defined OBJ_COFF && ! defined NT_VERSION
11812 #define NT_VERSION 1
11813 #define NT_ARCH 2
11814 #endif
11815
11816 {
11817 segT current_seg = now_seg;
11818 subsegT current_subseg = now_subseg;
11819 asection * arm_arch;
11820 const char * arch_string;
11821
11822 arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
11823
11824 #ifdef OBJ_COFF
11825 bfd_set_section_flags (stdoutput, arm_arch,
11826 SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
11827 | SEC_HAS_CONTENTS);
11828 #else
11829 bfd_set_section_flags (stdoutput, arm_arch,
11830 SEC_READONLY | SEC_HAS_CONTENTS);
11831 #endif
11832 arm_arch->output_section = arm_arch;
11833 subseg_set (arm_arch, 0);
11834
11835 switch (mach)
11836 {
11837 default:
11838 case bfd_mach_arm_unknown: arch_string = "unknown"; break;
11839 case bfd_mach_arm_2: arch_string = "armv2"; break;
11840 case bfd_mach_arm_2a: arch_string = "armv2a"; break;
11841 case bfd_mach_arm_3: arch_string = "armv3"; break;
11842 case bfd_mach_arm_3M: arch_string = "armv3M"; break;
11843 case bfd_mach_arm_4: arch_string = "armv4"; break;
11844 case bfd_mach_arm_4T: arch_string = "armv4t"; break;
11845 case bfd_mach_arm_5: arch_string = "armv5"; break;
11846 case bfd_mach_arm_5T: arch_string = "armv5t"; break;
11847 case bfd_mach_arm_5TE: arch_string = "armv5te"; break;
11848 case bfd_mach_arm_XScale: arch_string = "XScale"; break;
11849 case bfd_mach_arm_ep9312: arch_string = "ep9312"; break;
11850 case bfd_mach_arm_iWMMXt: arch_string = "iWMMXt"; break;
11851 }
11852
11853 arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
11854
11855 subseg_set (current_seg, current_subseg);
11856 }
11857 #endif
11858 #endif /* Suppressed code. */
11859
11860 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
11861 }
11862
11863 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11864 for use in the a.out file, and stores them in the array pointed to by buf.
11865 This knows about the endian-ness of the target machine and does
11866 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
11867 2 (short) and 4 (long) Floating numbers are put out as a series of
11868 LITTLENUMS (shorts, here at least). */
11869
11870 void
11871 md_number_to_chars (buf, val, n)
11872 char * buf;
11873 valueT val;
11874 int n;
11875 {
11876 if (target_big_endian)
11877 number_to_chars_bigendian (buf, val, n);
11878 else
11879 number_to_chars_littleendian (buf, val, n);
11880 }
11881
11882 static valueT
11883 md_chars_to_number (buf, n)
11884 char * buf;
11885 int n;
11886 {
11887 valueT result = 0;
11888 unsigned char * where = (unsigned char *) buf;
11889
11890 if (target_big_endian)
11891 {
11892 while (n--)
11893 {
11894 result <<= 8;
11895 result |= (*where++ & 255);
11896 }
11897 }
11898 else
11899 {
11900 while (n--)
11901 {
11902 result <<= 8;
11903 result |= (where[n] & 255);
11904 }
11905 }
11906
11907 return result;
11908 }
11909
11910 /* Turn a string in input_line_pointer into a floating point constant
11911 of type TYPE, and store the appropriate bytes in *LITP. The number
11912 of LITTLENUMS emitted is stored in *SIZEP. An error message is
11913 returned, or NULL on OK.
11914
11915 Note that fp constants aren't represent in the normal way on the ARM.
11916 In big endian mode, things are as expected. However, in little endian
11917 mode fp constants are big-endian word-wise, and little-endian byte-wise
11918 within the words. For example, (double) 1.1 in big endian mode is
11919 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11920 the byte sequence 99 99 f1 3f 9a 99 99 99.
11921
11922 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
11923
11924 char *
11925 md_atof (type, litP, sizeP)
11926 char type;
11927 char * litP;
11928 int * sizeP;
11929 {
11930 int prec;
11931 LITTLENUM_TYPE words[MAX_LITTLENUMS];
11932 char *t;
11933 int i;
11934
11935 switch (type)
11936 {
11937 case 'f':
11938 case 'F':
11939 case 's':
11940 case 'S':
11941 prec = 2;
11942 break;
11943
11944 case 'd':
11945 case 'D':
11946 case 'r':
11947 case 'R':
11948 prec = 4;
11949 break;
11950
11951 case 'x':
11952 case 'X':
11953 prec = 6;
11954 break;
11955
11956 case 'p':
11957 case 'P':
11958 prec = 6;
11959 break;
11960
11961 default:
11962 *sizeP = 0;
11963 return _("bad call to MD_ATOF()");
11964 }
11965
11966 t = atof_ieee (input_line_pointer, type, words);
11967 if (t)
11968 input_line_pointer = t;
11969 *sizeP = prec * 2;
11970
11971 if (target_big_endian)
11972 {
11973 for (i = 0; i < prec; i++)
11974 {
11975 md_number_to_chars (litP, (valueT) words[i], 2);
11976 litP += 2;
11977 }
11978 }
11979 else
11980 {
11981 if (cpu_variant & FPU_ARCH_VFP)
11982 for (i = prec - 1; i >= 0; i--)
11983 {
11984 md_number_to_chars (litP, (valueT) words[i], 2);
11985 litP += 2;
11986 }
11987 else
11988 /* For a 4 byte float the order of elements in `words' is 1 0.
11989 For an 8 byte float the order is 1 0 3 2. */
11990 for (i = 0; i < prec; i += 2)
11991 {
11992 md_number_to_chars (litP, (valueT) words[i + 1], 2);
11993 md_number_to_chars (litP + 2, (valueT) words[i], 2);
11994 litP += 4;
11995 }
11996 }
11997
11998 return 0;
11999 }
12000
12001 /* The knowledge of the PC's pipeline offset is built into the insns
12002 themselves. */
12003
12004 long
12005 md_pcrel_from (fixP)
12006 fixS * fixP;
12007 {
12008 if (fixP->fx_addsy
12009 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
12010 && fixP->fx_subsy == NULL)
12011 return 0;
12012
12013 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
12014 {
12015 /* PC relative addressing on the Thumb is slightly odd
12016 as the bottom two bits of the PC are forced to zero
12017 for the calculation. */
12018 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
12019 }
12020
12021 #ifdef TE_WINCE
12022 /* The pattern was adjusted to accommodate CE's off-by-one fixups,
12023 so we un-adjust here to compensate for the accommodation. */
12024 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
12025 #else
12026 return fixP->fx_where + fixP->fx_frag->fr_address;
12027 #endif
12028 }
12029
12030 /* Round up a section size to the appropriate boundary. */
12031
12032 valueT
12033 md_section_align (segment, size)
12034 segT segment ATTRIBUTE_UNUSED;
12035 valueT size;
12036 {
12037 #ifdef OBJ_ELF
12038 return size;
12039 #else
12040 /* Round all sects to multiple of 4. */
12041 return (size + 3) & ~3;
12042 #endif
12043 }
12044
12045 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
12046 Otherwise we have no need to default values of symbols. */
12047
12048 symbolS *
12049 md_undefined_symbol (name)
12050 char * name ATTRIBUTE_UNUSED;
12051 {
12052 #ifdef OBJ_ELF
12053 if (name[0] == '_' && name[1] == 'G'
12054 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
12055 {
12056 if (!GOT_symbol)
12057 {
12058 if (symbol_find (name))
12059 as_bad ("GOT already in the symbol table");
12060
12061 GOT_symbol = symbol_new (name, undefined_section,
12062 (valueT) 0, & zero_address_frag);
12063 }
12064
12065 return GOT_symbol;
12066 }
12067 #endif
12068
12069 return 0;
12070 }
12071
12072 /* arm_reg_parse () := if it looks like a register, return its token and
12073 advance the pointer. */
12074
12075 static int
12076 arm_reg_parse (ccp, htab)
12077 register char ** ccp;
12078 struct hash_control *htab;
12079 {
12080 char * start = * ccp;
12081 char c;
12082 char * p;
12083 struct reg_entry * reg;
12084
12085 #ifdef REGISTER_PREFIX
12086 if (*start != REGISTER_PREFIX)
12087 return FAIL;
12088 p = start + 1;
12089 #else
12090 p = start;
12091 #ifdef OPTIONAL_REGISTER_PREFIX
12092 if (*p == OPTIONAL_REGISTER_PREFIX)
12093 p++, start++;
12094 #endif
12095 #endif
12096 if (!ISALPHA (*p) || !is_name_beginner (*p))
12097 return FAIL;
12098
12099 c = *p++;
12100 while (ISALPHA (c) || ISDIGIT (c) || c == '_')
12101 c = *p++;
12102
12103 *--p = 0;
12104 reg = (struct reg_entry *) hash_find (htab, start);
12105 *p = c;
12106
12107 if (reg)
12108 {
12109 *ccp = p;
12110 return reg->number;
12111 }
12112
12113 return FAIL;
12114 }
12115
12116 /* Search for the following register name in each of the possible reg name
12117 tables. Return the classification if found, or REG_TYPE_MAX if not
12118 present. */
12119 static enum arm_reg_type
12120 arm_reg_parse_any (cp)
12121 char *cp;
12122 {
12123 int i;
12124
12125 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
12126 if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
12127 return (enum arm_reg_type) i;
12128
12129 return REG_TYPE_MAX;
12130 }
12131
12132 void
12133 md_apply_fix3 (fixP, valP, seg)
12134 fixS * fixP;
12135 valueT * valP;
12136 segT seg;
12137 {
12138 offsetT value = * valP;
12139 offsetT newval;
12140 unsigned int newimm;
12141 unsigned long temp;
12142 int sign;
12143 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
12144 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
12145
12146 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
12147
12148 /* Note whether this will delete the relocation. */
12149 #if 0
12150 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
12151 doesn't work fully.) */
12152 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
12153 && !fixP->fx_pcrel)
12154 #else
12155 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
12156 #endif
12157 fixP->fx_done = 1;
12158
12159 /* If this symbol is in a different section then we need to leave it for
12160 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
12161 so we have to undo it's effects here. */
12162 if (fixP->fx_pcrel)
12163 {
12164 if (fixP->fx_addsy != NULL
12165 && S_IS_DEFINED (fixP->fx_addsy)
12166 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
12167 {
12168 if (target_oabi
12169 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
12170 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
12171 ))
12172 value = 0;
12173 else
12174 value += md_pcrel_from (fixP);
12175 }
12176 }
12177
12178 /* Remember value for emit_reloc. */
12179 fixP->fx_addnumber = value;
12180
12181 switch (fixP->fx_r_type)
12182 {
12183 case BFD_RELOC_ARM_IMMEDIATE:
12184 newimm = validate_immediate (value);
12185 temp = md_chars_to_number (buf, INSN_SIZE);
12186
12187 /* If the instruction will fail, see if we can fix things up by
12188 changing the opcode. */
12189 if (newimm == (unsigned int) FAIL
12190 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
12191 {
12192 as_bad_where (fixP->fx_file, fixP->fx_line,
12193 _("invalid constant (%lx) after fixup"),
12194 (unsigned long) value);
12195 break;
12196 }
12197
12198 newimm |= (temp & 0xfffff000);
12199 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12200 fixP->fx_done = 1;
12201 break;
12202
12203 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12204 {
12205 unsigned int highpart = 0;
12206 unsigned int newinsn = 0xe1a00000; /* nop. */
12207
12208 newimm = validate_immediate (value);
12209 temp = md_chars_to_number (buf, INSN_SIZE);
12210
12211 /* If the instruction will fail, see if we can fix things up by
12212 changing the opcode. */
12213 if (newimm == (unsigned int) FAIL
12214 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
12215 {
12216 /* No ? OK - try using two ADD instructions to generate
12217 the value. */
12218 newimm = validate_immediate_twopart (value, & highpart);
12219
12220 /* Yes - then make sure that the second instruction is
12221 also an add. */
12222 if (newimm != (unsigned int) FAIL)
12223 newinsn = temp;
12224 /* Still No ? Try using a negated value. */
12225 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
12226 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
12227 /* Otherwise - give up. */
12228 else
12229 {
12230 as_bad_where (fixP->fx_file, fixP->fx_line,
12231 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
12232 (long) value);
12233 break;
12234 }
12235
12236 /* Replace the first operand in the 2nd instruction (which
12237 is the PC) with the destination register. We have
12238 already added in the PC in the first instruction and we
12239 do not want to do it again. */
12240 newinsn &= ~ 0xf0000;
12241 newinsn |= ((newinsn & 0x0f000) << 4);
12242 }
12243
12244 newimm |= (temp & 0xfffff000);
12245 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
12246
12247 highpart |= (newinsn & 0xfffff000);
12248 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
12249 }
12250 break;
12251
12252 case BFD_RELOC_ARM_OFFSET_IMM:
12253 sign = value >= 0;
12254
12255 if (value < 0)
12256 value = - value;
12257
12258 if (validate_offset_imm (value, 0) == FAIL)
12259 {
12260 as_bad_where (fixP->fx_file, fixP->fx_line,
12261 _("bad immediate value for offset (%ld)"),
12262 (long) value);
12263 break;
12264 }
12265
12266 newval = md_chars_to_number (buf, INSN_SIZE);
12267 newval &= 0xff7ff000;
12268 newval |= value | (sign ? INDEX_UP : 0);
12269 md_number_to_chars (buf, newval, INSN_SIZE);
12270 break;
12271
12272 case BFD_RELOC_ARM_OFFSET_IMM8:
12273 case BFD_RELOC_ARM_HWLITERAL:
12274 sign = value >= 0;
12275
12276 if (value < 0)
12277 value = - value;
12278
12279 if (validate_offset_imm (value, 1) == FAIL)
12280 {
12281 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
12282 as_bad_where (fixP->fx_file, fixP->fx_line,
12283 _("invalid literal constant: pool needs to be closer"));
12284 else
12285 as_bad (_("bad immediate value for half-word offset (%ld)"),
12286 (long) value);
12287 break;
12288 }
12289
12290 newval = md_chars_to_number (buf, INSN_SIZE);
12291 newval &= 0xff7ff0f0;
12292 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
12293 md_number_to_chars (buf, newval, INSN_SIZE);
12294 break;
12295
12296 case BFD_RELOC_ARM_LITERAL:
12297 sign = value >= 0;
12298
12299 if (value < 0)
12300 value = - value;
12301
12302 if (validate_offset_imm (value, 0) == FAIL)
12303 {
12304 as_bad_where (fixP->fx_file, fixP->fx_line,
12305 _("invalid literal constant: pool needs to be closer"));
12306 break;
12307 }
12308
12309 newval = md_chars_to_number (buf, INSN_SIZE);
12310 newval &= 0xff7ff000;
12311 newval |= value | (sign ? INDEX_UP : 0);
12312 md_number_to_chars (buf, newval, INSN_SIZE);
12313 break;
12314
12315 case BFD_RELOC_ARM_SHIFT_IMM:
12316 newval = md_chars_to_number (buf, INSN_SIZE);
12317 if (((unsigned long) value) > 32
12318 || (value == 32
12319 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
12320 {
12321 as_bad_where (fixP->fx_file, fixP->fx_line,
12322 _("shift expression is too large"));
12323 break;
12324 }
12325
12326 if (value == 0)
12327 /* Shifts of zero must be done as lsl. */
12328 newval &= ~0x60;
12329 else if (value == 32)
12330 value = 0;
12331 newval &= 0xfffff07f;
12332 newval |= (value & 0x1f) << 7;
12333 md_number_to_chars (buf, newval, INSN_SIZE);
12334 break;
12335
12336 case BFD_RELOC_ARM_SWI:
12337 if (arm_data->thumb_mode)
12338 {
12339 if (((unsigned long) value) > 0xff)
12340 as_bad_where (fixP->fx_file, fixP->fx_line,
12341 _("invalid swi expression"));
12342 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
12343 newval |= value;
12344 md_number_to_chars (buf, newval, THUMB_SIZE);
12345 }
12346 else
12347 {
12348 if (((unsigned long) value) > 0x00ffffff)
12349 as_bad_where (fixP->fx_file, fixP->fx_line,
12350 _("invalid swi expression"));
12351 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
12352 newval |= value;
12353 md_number_to_chars (buf, newval, INSN_SIZE);
12354 }
12355 break;
12356
12357 case BFD_RELOC_ARM_MULTI:
12358 if (((unsigned long) value) > 0xffff)
12359 as_bad_where (fixP->fx_file, fixP->fx_line,
12360 _("invalid expression in load/store multiple"));
12361 newval = value | md_chars_to_number (buf, INSN_SIZE);
12362 md_number_to_chars (buf, newval, INSN_SIZE);
12363 break;
12364
12365 case BFD_RELOC_ARM_PCREL_BRANCH:
12366 newval = md_chars_to_number (buf, INSN_SIZE);
12367
12368 /* Sign-extend a 24-bit number. */
12369 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
12370
12371 #ifdef OBJ_ELF
12372 if (! target_oabi)
12373 value = fixP->fx_offset;
12374 #endif
12375
12376 /* We are going to store value (shifted right by two) in the
12377 instruction, in a 24 bit, signed field. Thus we need to check
12378 that none of the top 8 bits of the shifted value (top 7 bits of
12379 the unshifted, unsigned value) are set, or that they are all set. */
12380 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
12381 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
12382 {
12383 #ifdef OBJ_ELF
12384 /* Normally we would be stuck at this point, since we cannot store
12385 the absolute address that is the destination of the branch in the
12386 24 bits of the branch instruction. If however, we happen to know
12387 that the destination of the branch is in the same section as the
12388 branch instruction itself, then we can compute the relocation for
12389 ourselves and not have to bother the linker with it.
12390
12391 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
12392 because I have not worked out how to do this for OBJ_COFF or
12393 target_oabi. */
12394 if (! target_oabi
12395 && fixP->fx_addsy != NULL
12396 && S_IS_DEFINED (fixP->fx_addsy)
12397 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
12398 {
12399 /* Get pc relative value to go into the branch. */
12400 value = * valP;
12401
12402 /* Permit a backward branch provided that enough bits
12403 are set. Allow a forwards branch, provided that
12404 enough bits are clear. */
12405 if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
12406 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
12407 fixP->fx_done = 1;
12408 }
12409
12410 if (! fixP->fx_done)
12411 #endif
12412 as_bad_where (fixP->fx_file, fixP->fx_line,
12413 _("GAS can't handle same-section branch dest >= 0x04000000"));
12414 }
12415
12416 value >>= 2;
12417 value += SEXT24 (newval);
12418
12419 if ( (value & ~ ((offsetT) 0xffffff)) != 0
12420 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
12421 as_bad_where (fixP->fx_file, fixP->fx_line,
12422 _("out of range branch"));
12423
12424 newval = (value & 0x00ffffff) | (newval & 0xff000000);
12425 md_number_to_chars (buf, newval, INSN_SIZE);
12426 break;
12427
12428 case BFD_RELOC_ARM_PCREL_BLX:
12429 {
12430 offsetT hbit;
12431 newval = md_chars_to_number (buf, INSN_SIZE);
12432
12433 #ifdef OBJ_ELF
12434 if (! target_oabi)
12435 value = fixP->fx_offset;
12436 #endif
12437 hbit = (value >> 1) & 1;
12438 value = (value >> 2) & 0x00ffffff;
12439 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
12440 newval = value | (newval & 0xfe000000) | (hbit << 24);
12441 md_number_to_chars (buf, newval, INSN_SIZE);
12442 }
12443 break;
12444
12445 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
12446 newval = md_chars_to_number (buf, THUMB_SIZE);
12447 {
12448 addressT diff = (newval & 0xff) << 1;
12449 if (diff & 0x100)
12450 diff |= ~0xff;
12451
12452 value += diff;
12453 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
12454 as_bad_where (fixP->fx_file, fixP->fx_line,
12455 _("branch out of range"));
12456 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
12457 }
12458 md_number_to_chars (buf, newval, THUMB_SIZE);
12459 break;
12460
12461 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
12462 newval = md_chars_to_number (buf, THUMB_SIZE);
12463 {
12464 addressT diff = (newval & 0x7ff) << 1;
12465 if (diff & 0x800)
12466 diff |= ~0x7ff;
12467
12468 value += diff;
12469 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
12470 as_bad_where (fixP->fx_file, fixP->fx_line,
12471 _("branch out of range"));
12472 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
12473 }
12474 md_number_to_chars (buf, newval, THUMB_SIZE);
12475 break;
12476
12477 case BFD_RELOC_THUMB_PCREL_BLX:
12478 case BFD_RELOC_THUMB_PCREL_BRANCH23:
12479 {
12480 offsetT newval2;
12481 addressT diff;
12482
12483 newval = md_chars_to_number (buf, THUMB_SIZE);
12484 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
12485 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
12486 if (diff & 0x400000)
12487 diff |= ~0x3fffff;
12488 #ifdef OBJ_ELF
12489 value = fixP->fx_offset;
12490 #endif
12491 value += diff;
12492
12493 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
12494 as_bad_where (fixP->fx_file, fixP->fx_line,
12495 _("branch with link out of range"));
12496
12497 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
12498 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
12499 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
12500 /* For a BLX instruction, make sure that the relocation is rounded up
12501 to a word boundary. This follows the semantics of the instruction
12502 which specifies that bit 1 of the target address will come from bit
12503 1 of the base address. */
12504 newval2 = (newval2 + 1) & ~ 1;
12505 md_number_to_chars (buf, newval, THUMB_SIZE);
12506 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
12507 }
12508 break;
12509
12510 case BFD_RELOC_8:
12511 if (fixP->fx_done || fixP->fx_pcrel)
12512 md_number_to_chars (buf, value, 1);
12513 #ifdef OBJ_ELF
12514 else if (!target_oabi)
12515 {
12516 value = fixP->fx_offset;
12517 md_number_to_chars (buf, value, 1);
12518 }
12519 #endif
12520 break;
12521
12522 case BFD_RELOC_16:
12523 if (fixP->fx_done || fixP->fx_pcrel)
12524 md_number_to_chars (buf, value, 2);
12525 #ifdef OBJ_ELF
12526 else if (!target_oabi)
12527 {
12528 value = fixP->fx_offset;
12529 md_number_to_chars (buf, value, 2);
12530 }
12531 #endif
12532 break;
12533
12534 #ifdef OBJ_ELF
12535 case BFD_RELOC_ARM_GOT32:
12536 case BFD_RELOC_ARM_GOTOFF:
12537 md_number_to_chars (buf, 0, 4);
12538 break;
12539 #endif
12540
12541 case BFD_RELOC_RVA:
12542 case BFD_RELOC_32:
12543 if (fixP->fx_done || fixP->fx_pcrel)
12544 md_number_to_chars (buf, value, 4);
12545 #ifdef OBJ_ELF
12546 else if (!target_oabi)
12547 {
12548 value = fixP->fx_offset;
12549 md_number_to_chars (buf, value, 4);
12550 }
12551 #endif
12552 break;
12553
12554 #ifdef OBJ_ELF
12555 case BFD_RELOC_ARM_PLT32:
12556 /* It appears the instruction is fully prepared at this point. */
12557 break;
12558 #endif
12559
12560 case BFD_RELOC_ARM_CP_OFF_IMM:
12561 sign = value >= 0;
12562 if (value < -1023 || value > 1023 || (value & 3))
12563 as_bad_where (fixP->fx_file, fixP->fx_line,
12564 _("illegal value for co-processor offset"));
12565 if (value < 0)
12566 value = -value;
12567 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12568 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
12569 md_number_to_chars (buf, newval, INSN_SIZE);
12570 break;
12571
12572 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
12573 sign = value >= 0;
12574 if (value < -255 || value > 255)
12575 as_bad_where (fixP->fx_file, fixP->fx_line,
12576 _("Illegal value for co-processor offset"));
12577 if (value < 0)
12578 value = -value;
12579 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
12580 newval |= value | (sign ? INDEX_UP : 0);
12581 md_number_to_chars (buf, newval , INSN_SIZE);
12582 break;
12583
12584 case BFD_RELOC_ARM_THUMB_OFFSET:
12585 newval = md_chars_to_number (buf, THUMB_SIZE);
12586 /* Exactly what ranges, and where the offset is inserted depends
12587 on the type of instruction, we can establish this from the
12588 top 4 bits. */
12589 switch (newval >> 12)
12590 {
12591 case 4: /* PC load. */
12592 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12593 forced to zero for these loads, so we will need to round
12594 up the offset if the instruction address is not word
12595 aligned (since the final address produced must be, and
12596 we can only describe word-aligned immediate offsets). */
12597
12598 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
12599 as_bad_where (fixP->fx_file, fixP->fx_line,
12600 _("invalid offset, target not word aligned (0x%08X)"),
12601 (unsigned int) (fixP->fx_frag->fr_address
12602 + fixP->fx_where + value));
12603
12604 if ((value + 2) & ~0x3fe)
12605 as_bad_where (fixP->fx_file, fixP->fx_line,
12606 _("invalid offset, value too big (0x%08lX)"),
12607 (long) value);
12608
12609 /* Round up, since pc will be rounded down. */
12610 newval |= (value + 2) >> 2;
12611 break;
12612
12613 case 9: /* SP load/store. */
12614 if (value & ~0x3fc)
12615 as_bad_where (fixP->fx_file, fixP->fx_line,
12616 _("invalid offset, value too big (0x%08lX)"),
12617 (long) value);
12618 newval |= value >> 2;
12619 break;
12620
12621 case 6: /* Word load/store. */
12622 if (value & ~0x7c)
12623 as_bad_where (fixP->fx_file, fixP->fx_line,
12624 _("invalid offset, value too big (0x%08lX)"),
12625 (long) value);
12626 newval |= value << 4; /* 6 - 2. */
12627 break;
12628
12629 case 7: /* Byte load/store. */
12630 if (value & ~0x1f)
12631 as_bad_where (fixP->fx_file, fixP->fx_line,
12632 _("invalid offset, value too big (0x%08lX)"),
12633 (long) value);
12634 newval |= value << 6;
12635 break;
12636
12637 case 8: /* Halfword load/store. */
12638 if (value & ~0x3e)
12639 as_bad_where (fixP->fx_file, fixP->fx_line,
12640 _("invalid offset, value too big (0x%08lX)"),
12641 (long) value);
12642 newval |= value << 5; /* 6 - 1. */
12643 break;
12644
12645 default:
12646 as_bad_where (fixP->fx_file, fixP->fx_line,
12647 "Unable to process relocation for thumb opcode: %lx",
12648 (unsigned long) newval);
12649 break;
12650 }
12651 md_number_to_chars (buf, newval, THUMB_SIZE);
12652 break;
12653
12654 case BFD_RELOC_ARM_THUMB_ADD:
12655 /* This is a complicated relocation, since we use it for all of
12656 the following immediate relocations:
12657
12658 3bit ADD/SUB
12659 8bit ADD/SUB
12660 9bit ADD/SUB SP word-aligned
12661 10bit ADD PC/SP word-aligned
12662
12663 The type of instruction being processed is encoded in the
12664 instruction field:
12665
12666 0x8000 SUB
12667 0x00F0 Rd
12668 0x000F Rs
12669 */
12670 newval = md_chars_to_number (buf, THUMB_SIZE);
12671 {
12672 int rd = (newval >> 4) & 0xf;
12673 int rs = newval & 0xf;
12674 int subtract = newval & 0x8000;
12675
12676 if (rd == REG_SP)
12677 {
12678 if (value & ~0x1fc)
12679 as_bad_where (fixP->fx_file, fixP->fx_line,
12680 _("invalid immediate for stack address calculation"));
12681 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
12682 newval |= value >> 2;
12683 }
12684 else if (rs == REG_PC || rs == REG_SP)
12685 {
12686 if (subtract ||
12687 value & ~0x3fc)
12688 as_bad_where (fixP->fx_file, fixP->fx_line,
12689 _("invalid immediate for address calculation (value = 0x%08lX)"),
12690 (unsigned long) value);
12691 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
12692 newval |= rd << 8;
12693 newval |= value >> 2;
12694 }
12695 else if (rs == rd)
12696 {
12697 if (value & ~0xff)
12698 as_bad_where (fixP->fx_file, fixP->fx_line,
12699 _("invalid 8bit immediate"));
12700 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
12701 newval |= (rd << 8) | value;
12702 }
12703 else
12704 {
12705 if (value & ~0x7)
12706 as_bad_where (fixP->fx_file, fixP->fx_line,
12707 _("invalid 3bit immediate"));
12708 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
12709 newval |= rd | (rs << 3) | (value << 6);
12710 }
12711 }
12712 md_number_to_chars (buf, newval, THUMB_SIZE);
12713 break;
12714
12715 case BFD_RELOC_ARM_THUMB_IMM:
12716 newval = md_chars_to_number (buf, THUMB_SIZE);
12717 switch (newval >> 11)
12718 {
12719 case 0x04: /* 8bit immediate MOV. */
12720 case 0x05: /* 8bit immediate CMP. */
12721 if (value < 0 || value > 255)
12722 as_bad_where (fixP->fx_file, fixP->fx_line,
12723 _("invalid immediate: %ld is too large"),
12724 (long) value);
12725 newval |= value;
12726 break;
12727
12728 default:
12729 abort ();
12730 }
12731 md_number_to_chars (buf, newval, THUMB_SIZE);
12732 break;
12733
12734 case BFD_RELOC_ARM_THUMB_SHIFT:
12735 /* 5bit shift value (0..31). */
12736 if (value < 0 || value > 31)
12737 as_bad_where (fixP->fx_file, fixP->fx_line,
12738 _("illegal Thumb shift value: %ld"), (long) value);
12739 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
12740 newval |= value << 6;
12741 md_number_to_chars (buf, newval, THUMB_SIZE);
12742 break;
12743
12744 case BFD_RELOC_VTABLE_INHERIT:
12745 case BFD_RELOC_VTABLE_ENTRY:
12746 fixP->fx_done = 0;
12747 return;
12748
12749 case BFD_RELOC_NONE:
12750 default:
12751 as_bad_where (fixP->fx_file, fixP->fx_line,
12752 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
12753 }
12754 }
12755
12756 /* Translate internal representation of relocation info to BFD target
12757 format. */
12758
12759 arelent *
12760 tc_gen_reloc (section, fixp)
12761 asection * section ATTRIBUTE_UNUSED;
12762 fixS * fixp;
12763 {
12764 arelent * reloc;
12765 bfd_reloc_code_real_type code;
12766
12767 reloc = (arelent *) xmalloc (sizeof (arelent));
12768
12769 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
12770 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
12771 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
12772
12773 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
12774 #ifndef OBJ_ELF
12775 if (fixp->fx_pcrel == 0)
12776 reloc->addend = fixp->fx_offset;
12777 else
12778 reloc->addend = fixp->fx_offset = reloc->address;
12779 #else /* OBJ_ELF */
12780 reloc->addend = fixp->fx_offset;
12781 #endif
12782
12783 switch (fixp->fx_r_type)
12784 {
12785 case BFD_RELOC_8:
12786 if (fixp->fx_pcrel)
12787 {
12788 code = BFD_RELOC_8_PCREL;
12789 break;
12790 }
12791
12792 case BFD_RELOC_16:
12793 if (fixp->fx_pcrel)
12794 {
12795 code = BFD_RELOC_16_PCREL;
12796 break;
12797 }
12798
12799 case BFD_RELOC_32:
12800 if (fixp->fx_pcrel)
12801 {
12802 code = BFD_RELOC_32_PCREL;
12803 break;
12804 }
12805
12806 case BFD_RELOC_ARM_PCREL_BRANCH:
12807 case BFD_RELOC_ARM_PCREL_BLX:
12808 case BFD_RELOC_RVA:
12809 case BFD_RELOC_THUMB_PCREL_BRANCH9:
12810 case BFD_RELOC_THUMB_PCREL_BRANCH12:
12811 case BFD_RELOC_THUMB_PCREL_BRANCH23:
12812 case BFD_RELOC_THUMB_PCREL_BLX:
12813 case BFD_RELOC_VTABLE_ENTRY:
12814 case BFD_RELOC_VTABLE_INHERIT:
12815 code = fixp->fx_r_type;
12816 break;
12817
12818 case BFD_RELOC_ARM_LITERAL:
12819 case BFD_RELOC_ARM_HWLITERAL:
12820 /* If this is called then the a literal has
12821 been referenced across a section boundary. */
12822 as_bad_where (fixp->fx_file, fixp->fx_line,
12823 _("literal referenced across section boundary"));
12824 return NULL;
12825
12826 #ifdef OBJ_ELF
12827 case BFD_RELOC_ARM_GOT32:
12828 case BFD_RELOC_ARM_GOTOFF:
12829 case BFD_RELOC_ARM_PLT32:
12830 code = fixp->fx_r_type;
12831 break;
12832 #endif
12833
12834 case BFD_RELOC_ARM_IMMEDIATE:
12835 as_bad_where (fixp->fx_file, fixp->fx_line,
12836 _("internal relocation (type: IMMEDIATE) not fixed up"));
12837 return NULL;
12838
12839 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
12840 as_bad_where (fixp->fx_file, fixp->fx_line,
12841 _("ADRL used for a symbol not defined in the same file"));
12842 return NULL;
12843
12844 case BFD_RELOC_ARM_OFFSET_IMM:
12845 if (fixp->fx_addsy != NULL
12846 && !S_IS_DEFINED (fixp->fx_addsy)
12847 && S_IS_LOCAL (fixp->fx_addsy))
12848 {
12849 as_bad_where (fixp->fx_file, fixp->fx_line,
12850 _("undefined local label `%s'"),
12851 S_GET_NAME (fixp->fx_addsy));
12852 return NULL;
12853 }
12854
12855 as_bad_where (fixp->fx_file, fixp->fx_line,
12856 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12857 return NULL;
12858
12859 default:
12860 {
12861 char * type;
12862
12863 switch (fixp->fx_r_type)
12864 {
12865 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
12866 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
12867 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
12868 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
12869 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
12870 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
12871 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
12872 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
12873 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12874 default: type = _("<unknown>"); break;
12875 }
12876 as_bad_where (fixp->fx_file, fixp->fx_line,
12877 _("cannot represent %s relocation in this object file format"),
12878 type);
12879 return NULL;
12880 }
12881 }
12882
12883 #ifdef OBJ_ELF
12884 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12885 && GOT_symbol
12886 && fixp->fx_addsy == GOT_symbol)
12887 {
12888 code = BFD_RELOC_ARM_GOTPC;
12889 reloc->addend = fixp->fx_offset = reloc->address;
12890 }
12891 #endif
12892
12893 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
12894
12895 if (reloc->howto == NULL)
12896 {
12897 as_bad_where (fixp->fx_file, fixp->fx_line,
12898 _("cannot represent %s relocation in this object file format"),
12899 bfd_get_reloc_code_name (code));
12900 return NULL;
12901 }
12902
12903 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12904 vtable entry to be used in the relocation's section offset. */
12905 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12906 reloc->address = fixp->fx_offset;
12907
12908 return reloc;
12909 }
12910
12911 int
12912 md_estimate_size_before_relax (fragP, segtype)
12913 fragS * fragP ATTRIBUTE_UNUSED;
12914 segT segtype ATTRIBUTE_UNUSED;
12915 {
12916 as_fatal (_("md_estimate_size_before_relax\n"));
12917 return 1;
12918 }
12919
12920 static void
12921 output_inst (str)
12922 const char *str;
12923 {
12924 char * to = NULL;
12925
12926 if (inst.error)
12927 {
12928 as_bad ("%s -- `%s'", inst.error, str);
12929 return;
12930 }
12931
12932 to = frag_more (inst.size);
12933
12934 if (thumb_mode && (inst.size > THUMB_SIZE))
12935 {
12936 assert (inst.size == (2 * THUMB_SIZE));
12937 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
12938 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
12939 }
12940 else if (inst.size > INSN_SIZE)
12941 {
12942 assert (inst.size == (2 * INSN_SIZE));
12943 md_number_to_chars (to, inst.instruction, INSN_SIZE);
12944 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
12945 }
12946 else
12947 md_number_to_chars (to, inst.instruction, inst.size);
12948
12949 if (inst.reloc.type != BFD_RELOC_NONE)
12950 fix_new_arm (frag_now, to - frag_now->fr_literal,
12951 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
12952 inst.reloc.type);
12953
12954 #ifdef OBJ_ELF
12955 dwarf2_emit_insn (inst.size);
12956 #endif
12957 }
12958
12959 void
12960 md_assemble (str)
12961 char * str;
12962 {
12963 char c;
12964 char *p;
12965 char *start;
12966
12967 /* Align the instruction.
12968 This may not be the right thing to do but ... */
12969 #if 0
12970 arm_align (2, 0);
12971 #endif
12972
12973 /* Align the previous label if needed. */
12974 if (last_label_seen != NULL)
12975 {
12976 symbol_set_frag (last_label_seen, frag_now);
12977 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
12978 S_SET_SEGMENT (last_label_seen, now_seg);
12979 }
12980
12981 memset (&inst, '\0', sizeof (inst));
12982 inst.reloc.type = BFD_RELOC_NONE;
12983
12984 skip_whitespace (str);
12985
12986 /* Scan up to the end of the op-code, which must end in white space or
12987 end of string. */
12988 for (start = p = str; *p != '\0'; p++)
12989 if (*p == ' ')
12990 break;
12991
12992 if (p == str)
12993 {
12994 as_bad (_("no operator -- statement `%s'\n"), str);
12995 return;
12996 }
12997
12998 if (thumb_mode)
12999 {
13000 const struct thumb_opcode * opcode;
13001
13002 c = *p;
13003 *p = '\0';
13004 opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
13005 *p = c;
13006
13007 if (opcode)
13008 {
13009 /* Check that this instruction is supported for this CPU. */
13010 if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
13011 {
13012 as_bad (_("selected processor does not support `%s'"), str);
13013 return;
13014 }
13015
13016 mapping_state (MAP_THUMB);
13017 inst.instruction = opcode->value;
13018 inst.size = opcode->size;
13019 (*opcode->parms) (p);
13020 output_inst (str);
13021 return;
13022 }
13023 }
13024 else
13025 {
13026 const struct asm_opcode * opcode;
13027
13028 c = *p;
13029 *p = '\0';
13030 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
13031 *p = c;
13032
13033 if (opcode)
13034 {
13035 /* Check that this instruction is supported for this CPU. */
13036 if ((opcode->variant & cpu_variant) == 0)
13037 {
13038 as_bad (_("selected processor does not support `%s'"), str);
13039 return;
13040 }
13041
13042 mapping_state (MAP_ARM);
13043 inst.instruction = opcode->value;
13044 inst.size = INSN_SIZE;
13045 (*opcode->parms) (p);
13046 output_inst (str);
13047 return;
13048 }
13049 }
13050
13051 /* It wasn't an instruction, but it might be a register alias of the form
13052 alias .req reg. */
13053 if (create_register_alias (str, p))
13054 return;
13055
13056 as_bad (_("bad instruction `%s'"), start);
13057 }
13058
13059 /* md_parse_option
13060 Invocation line includes a switch not recognized by the base assembler.
13061 See if it's a processor-specific option.
13062
13063 This routine is somewhat complicated by the need for backwards
13064 compatibility (since older releases of gcc can't be changed).
13065 The new options try to make the interface as compatible as
13066 possible with GCC.
13067
13068 New options (supported) are:
13069
13070 -mcpu=<cpu name> Assemble for selected processor
13071 -march=<architecture name> Assemble for selected architecture
13072 -mfpu=<fpu architecture> Assemble for selected FPU.
13073 -EB/-mbig-endian Big-endian
13074 -EL/-mlittle-endian Little-endian
13075 -k Generate PIC code
13076 -mthumb Start in Thumb mode
13077 -mthumb-interwork Code supports ARM/Thumb interworking
13078
13079 For now we will also provide support for:
13080
13081 -mapcs-32 32-bit Program counter
13082 -mapcs-26 26-bit Program counter
13083 -macps-float Floats passed in FP registers
13084 -mapcs-reentrant Reentrant code
13085 -matpcs
13086 (sometime these will probably be replaced with -mapcs=<list of options>
13087 and -matpcs=<list of options>)
13088
13089 The remaining options are only supported for back-wards compatibility.
13090 Cpu variants, the arm part is optional:
13091 -m[arm]1 Currently not supported.
13092 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
13093 -m[arm]3 Arm 3 processor
13094 -m[arm]6[xx], Arm 6 processors
13095 -m[arm]7[xx][t][[d]m] Arm 7 processors
13096 -m[arm]8[10] Arm 8 processors
13097 -m[arm]9[20][tdmi] Arm 9 processors
13098 -mstrongarm[110[0]] StrongARM processors
13099 -mxscale XScale processors
13100 -m[arm]v[2345[t[e]]] Arm architectures
13101 -mall All (except the ARM1)
13102 FP variants:
13103 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
13104 -mfpe-old (No float load/store multiples)
13105 -mvfpxd VFP Single precision
13106 -mvfp All VFP
13107 -mno-fpu Disable all floating point instructions
13108
13109 The following CPU names are recognized:
13110 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
13111 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
13112 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
13113 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
13114 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
13115 arm10t arm10e, arm1020t, arm1020e, arm10200e,
13116 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
13117
13118 */
13119
13120 const char * md_shortopts = "m:k";
13121
13122 #ifdef ARM_BI_ENDIAN
13123 #define OPTION_EB (OPTION_MD_BASE + 0)
13124 #define OPTION_EL (OPTION_MD_BASE + 1)
13125 #else
13126 #if TARGET_BYTES_BIG_ENDIAN
13127 #define OPTION_EB (OPTION_MD_BASE + 0)
13128 #else
13129 #define OPTION_EL (OPTION_MD_BASE + 1)
13130 #endif
13131 #endif
13132
13133 struct option md_longopts[] =
13134 {
13135 #ifdef OPTION_EB
13136 {"EB", no_argument, NULL, OPTION_EB},
13137 #endif
13138 #ifdef OPTION_EL
13139 {"EL", no_argument, NULL, OPTION_EL},
13140 #endif
13141 {NULL, no_argument, NULL, 0}
13142 };
13143
13144 size_t md_longopts_size = sizeof (md_longopts);
13145
13146 struct arm_option_table
13147 {
13148 char *option; /* Option name to match. */
13149 char *help; /* Help information. */
13150 int *var; /* Variable to change. */
13151 int value; /* What to change it to. */
13152 char *deprecated; /* If non-null, print this message. */
13153 };
13154
13155 struct arm_option_table arm_opts[] =
13156 {
13157 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
13158 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
13159 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
13160 &support_interwork, 1, NULL},
13161 {"moabi", N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
13162 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
13163 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
13164 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
13165 1, NULL},
13166 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
13167 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
13168 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
13169 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
13170 NULL},
13171
13172 /* These are recognized by the assembler, but have no affect on code. */
13173 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
13174 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
13175
13176 /* DON'T add any new processors to this list -- we want the whole list
13177 to go away... Add them to the processors table instead. */
13178 {"marm1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
13179 {"m1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
13180 {"marm2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
13181 {"m2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
13182 {"marm250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13183 {"m250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
13184 {"marm3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13185 {"m3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
13186 {"marm6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
13187 {"m6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
13188 {"marm600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
13189 {"m600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
13190 {"marm610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
13191 {"m610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
13192 {"marm620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
13193 {"m620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
13194 {"marm7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
13195 {"m7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
13196 {"marm70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
13197 {"m70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
13198 {"marm700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
13199 {"m700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
13200 {"marm700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
13201 {"m700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
13202 {"marm710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
13203 {"m710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
13204 {"marm710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
13205 {"m710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
13206 {"marm720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
13207 {"m720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
13208 {"marm7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
13209 {"m7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
13210 {"marm7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
13211 {"m7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
13212 {"marm7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13213 {"m7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
13214 {"marm7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13215 {"m7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
13216 {"marm7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13217 {"m7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
13218 {"marm7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
13219 {"m7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
13220 {"marm7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
13221 {"m7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
13222 {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
13223 {"m7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
13224 {"marm7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13225 {"m7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13226 {"marm7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13227 {"m7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
13228 {"marm710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13229 {"m710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
13230 {"marm720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13231 {"m720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
13232 {"marm740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13233 {"m740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
13234 {"marm8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
13235 {"m8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
13236 {"marm810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
13237 {"m810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
13238 {"marm9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13239 {"m9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
13240 {"marm9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13241 {"m9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
13242 {"marm920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13243 {"m920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
13244 {"marm940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13245 {"m940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
13246 {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
13247 {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
13248 N_("use -mcpu=strongarm110")},
13249 {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
13250 N_("use -mcpu=strongarm1100")},
13251 {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
13252 N_("use -mcpu=strongarm1110")},
13253 {"mxscale", NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
13254 {"miwmmxt", NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
13255 {"mall", NULL, &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
13256
13257 /* Architecture variants -- don't add any more to this list either. */
13258 {"mv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
13259 {"marmv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
13260 {"mv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13261 {"marmv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
13262 {"mv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
13263 {"marmv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
13264 {"mv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13265 {"marmv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
13266 {"mv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
13267 {"marmv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
13268 {"mv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13269 {"marmv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
13270 {"mv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
13271 {"marmv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
13272 {"mv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13273 {"marmv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
13274 {"mv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13275 {"marmv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
13276
13277 /* Floating point variants -- don't add any more to this list either. */
13278 {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
13279 {"mfpa10", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
13280 {"mfpa11", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
13281 {"mno-fpu", NULL, &legacy_fpu, 0,
13282 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
13283
13284 {NULL, NULL, NULL, 0, NULL}
13285 };
13286
13287 struct arm_cpu_option_table
13288 {
13289 char *name;
13290 int value;
13291 /* For some CPUs we assume an FPU unless the user explicitly sets
13292 -mfpu=... */
13293 int default_fpu;
13294 };
13295
13296 /* This list should, at a minimum, contain all the cpu names
13297 recognized by GCC. */
13298 static struct arm_cpu_option_table arm_cpus[] =
13299 {
13300 {"all", ARM_ANY, FPU_ARCH_FPA},
13301 {"arm1", ARM_ARCH_V1, FPU_ARCH_FPA},
13302 {"arm2", ARM_ARCH_V2, FPU_ARCH_FPA},
13303 {"arm250", ARM_ARCH_V2S, FPU_ARCH_FPA},
13304 {"arm3", ARM_ARCH_V2S, FPU_ARCH_FPA},
13305 {"arm6", ARM_ARCH_V3, FPU_ARCH_FPA},
13306 {"arm60", ARM_ARCH_V3, FPU_ARCH_FPA},
13307 {"arm600", ARM_ARCH_V3, FPU_ARCH_FPA},
13308 {"arm610", ARM_ARCH_V3, FPU_ARCH_FPA},
13309 {"arm620", ARM_ARCH_V3, FPU_ARCH_FPA},
13310 {"arm7", ARM_ARCH_V3, FPU_ARCH_FPA},
13311 {"arm7m", ARM_ARCH_V3M, FPU_ARCH_FPA},
13312 {"arm7d", ARM_ARCH_V3, FPU_ARCH_FPA},
13313 {"arm7dm", ARM_ARCH_V3M, FPU_ARCH_FPA},
13314 {"arm7di", ARM_ARCH_V3, FPU_ARCH_FPA},
13315 {"arm7dmi", ARM_ARCH_V3M, FPU_ARCH_FPA},
13316 {"arm70", ARM_ARCH_V3, FPU_ARCH_FPA},
13317 {"arm700", ARM_ARCH_V3, FPU_ARCH_FPA},
13318 {"arm700i", ARM_ARCH_V3, FPU_ARCH_FPA},
13319 {"arm710", ARM_ARCH_V3, FPU_ARCH_FPA},
13320 {"arm710t", ARM_ARCH_V4T, FPU_ARCH_FPA},
13321 {"arm720", ARM_ARCH_V3, FPU_ARCH_FPA},
13322 {"arm720t", ARM_ARCH_V4T, FPU_ARCH_FPA},
13323 {"arm740t", ARM_ARCH_V4T, FPU_ARCH_FPA},
13324 {"arm710c", ARM_ARCH_V3, FPU_ARCH_FPA},
13325 {"arm7100", ARM_ARCH_V3, FPU_ARCH_FPA},
13326 {"arm7500", ARM_ARCH_V3, FPU_ARCH_FPA},
13327 {"arm7500fe", ARM_ARCH_V3, FPU_ARCH_FPA},
13328 {"arm7t", ARM_ARCH_V4T, FPU_ARCH_FPA},
13329 {"arm7tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
13330 {"arm8", ARM_ARCH_V4, FPU_ARCH_FPA},
13331 {"arm810", ARM_ARCH_V4, FPU_ARCH_FPA},
13332 {"strongarm", ARM_ARCH_V4, FPU_ARCH_FPA},
13333 {"strongarm1", ARM_ARCH_V4, FPU_ARCH_FPA},
13334 {"strongarm110", ARM_ARCH_V4, FPU_ARCH_FPA},
13335 {"strongarm1100", ARM_ARCH_V4, FPU_ARCH_FPA},
13336 {"strongarm1110", ARM_ARCH_V4, FPU_ARCH_FPA},
13337 {"arm9", ARM_ARCH_V4T, FPU_ARCH_FPA},
13338 {"arm920", ARM_ARCH_V4T, FPU_ARCH_FPA},
13339 {"arm920t", ARM_ARCH_V4T, FPU_ARCH_FPA},
13340 {"arm922t", ARM_ARCH_V4T, FPU_ARCH_FPA},
13341 {"arm940t", ARM_ARCH_V4T, FPU_ARCH_FPA},
13342 {"arm9tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
13343 /* For V5 or later processors we default to using VFP; but the user
13344 should really set the FPU type explicitly. */
13345 {"arm9e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13346 {"arm9e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
13347 {"arm926ej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2},
13348 {"arm926ejs", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2},
13349 {"arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13350 {"arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
13351 {"arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
13352 {"arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
13353 {"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
13354 {"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
13355 {"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
13356 {"arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
13357 {"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
13358 {"arm1026ejs", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
13359 {"arm1136js", ARM_ARCH_V6, FPU_NONE},
13360 {"arm1136jfs", ARM_ARCH_V6, FPU_ARCH_VFP_V2},
13361 /* ??? XSCALE is really an architecture. */
13362 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13363 /* ??? iwmmxt is not a processor. */
13364 {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
13365 {"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
13366 /* Maverick */
13367 {"ep9312", ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK},
13368 {NULL, 0, 0}
13369 };
13370
13371 struct arm_arch_option_table
13372 {
13373 char *name;
13374 int value;
13375 int default_fpu;
13376 };
13377
13378 /* This list should, at a minimum, contain all the architecture names
13379 recognized by GCC. */
13380 static struct arm_arch_option_table arm_archs[] =
13381 {
13382 {"all", ARM_ANY, FPU_ARCH_FPA},
13383 {"armv1", ARM_ARCH_V1, FPU_ARCH_FPA},
13384 {"armv2", ARM_ARCH_V2, FPU_ARCH_FPA},
13385 {"armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA},
13386 {"armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA},
13387 {"armv3", ARM_ARCH_V3, FPU_ARCH_FPA},
13388 {"armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA},
13389 {"armv4", ARM_ARCH_V4, FPU_ARCH_FPA},
13390 {"armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA},
13391 {"armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA},
13392 {"armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA},
13393 {"armv5", ARM_ARCH_V5, FPU_ARCH_VFP},
13394 {"armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP},
13395 {"armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP},
13396 {"armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP},
13397 {"armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP},
13398 {"armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP},
13399 {"armv6", ARM_ARCH_V6, FPU_ARCH_VFP},
13400 {"armv6j", ARM_ARCH_V6, FPU_ARCH_VFP},
13401 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
13402 {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
13403 {NULL, 0, 0}
13404 };
13405
13406 /* ISA extensions in the co-processor space. */
13407 struct arm_arch_extension_table
13408 {
13409 char *name;
13410 int value;
13411 };
13412
13413 static struct arm_arch_extension_table arm_extensions[] =
13414 {
13415 {"maverick", ARM_CEXT_MAVERICK},
13416 {"xscale", ARM_CEXT_XSCALE},
13417 {"iwmmxt", ARM_CEXT_IWMMXT},
13418 {NULL, 0}
13419 };
13420
13421 struct arm_fpu_option_table
13422 {
13423 char *name;
13424 int value;
13425 };
13426
13427 /* This list should, at a minimum, contain all the fpu names
13428 recognized by GCC. */
13429 static struct arm_fpu_option_table arm_fpus[] =
13430 {
13431 {"softfpa", FPU_NONE},
13432 {"fpe", FPU_ARCH_FPE},
13433 {"fpe2", FPU_ARCH_FPE},
13434 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
13435 {"fpa", FPU_ARCH_FPA},
13436 {"fpa10", FPU_ARCH_FPA},
13437 {"fpa11", FPU_ARCH_FPA},
13438 {"arm7500fe", FPU_ARCH_FPA},
13439 {"softvfp", FPU_ARCH_VFP},
13440 {"softvfp+vfp", FPU_ARCH_VFP_V2},
13441 {"vfp", FPU_ARCH_VFP_V2},
13442 {"vfp9", FPU_ARCH_VFP_V2},
13443 {"vfp10", FPU_ARCH_VFP_V2},
13444 {"vfp10-r0", FPU_ARCH_VFP_V1},
13445 {"vfpxd", FPU_ARCH_VFP_V1xD},
13446 {"arm1020t", FPU_ARCH_VFP_V1},
13447 {"arm1020e", FPU_ARCH_VFP_V2},
13448 {"arm1136jfs", FPU_ARCH_VFP_V2},
13449 {"maverick", FPU_ARCH_MAVERICK},
13450 {NULL, 0}
13451 };
13452
13453 struct arm_float_abi_option_table
13454 {
13455 char *name;
13456 int value;
13457 };
13458
13459 static struct arm_float_abi_option_table arm_float_abis[] =
13460 {
13461 {"hard", ARM_FLOAT_ABI_HARD},
13462 {"softfp", ARM_FLOAT_ABI_SOFTFP},
13463 {"soft", ARM_FLOAT_ABI_SOFT},
13464 {NULL, 0}
13465 };
13466
13467 struct arm_eabi_option_table
13468 {
13469 char *name;
13470 unsigned int value;
13471 };
13472
13473 /* We only know hot to output GNU and ver 3 (AAELF) formats. */
13474 static struct arm_eabi_option_table arm_eabis[] =
13475 {
13476 {"gnu", EF_ARM_EABI_UNKNOWN},
13477 {"3", EF_ARM_EABI_VER3},
13478 {NULL, 0}
13479 };
13480
13481 struct arm_long_option_table
13482 {
13483 char *option; /* Substring to match. */
13484 char *help; /* Help information. */
13485 int (*func) PARAMS ((char *subopt)); /* Function to decode sub-option. */
13486 char *deprecated; /* If non-null, print this message. */
13487 };
13488
13489 static int
13490 arm_parse_extension (str, opt_p)
13491 char *str;
13492 int *opt_p;
13493 {
13494 while (str != NULL && *str != 0)
13495 {
13496 struct arm_arch_extension_table *opt;
13497 char *ext;
13498 int optlen;
13499
13500 if (*str != '+')
13501 {
13502 as_bad (_("invalid architectural extension"));
13503 return 0;
13504 }
13505
13506 str++;
13507 ext = strchr (str, '+');
13508
13509 if (ext != NULL)
13510 optlen = ext - str;
13511 else
13512 optlen = strlen (str);
13513
13514 if (optlen == 0)
13515 {
13516 as_bad (_("missing architectural extension"));
13517 return 0;
13518 }
13519
13520 for (opt = arm_extensions; opt->name != NULL; opt++)
13521 if (strncmp (opt->name, str, optlen) == 0)
13522 {
13523 *opt_p |= opt->value;
13524 break;
13525 }
13526
13527 if (opt->name == NULL)
13528 {
13529 as_bad (_("unknown architectural extnsion `%s'"), str);
13530 return 0;
13531 }
13532
13533 str = ext;
13534 };
13535
13536 return 1;
13537 }
13538
13539 static int
13540 arm_parse_cpu (str)
13541 char *str;
13542 {
13543 struct arm_cpu_option_table *opt;
13544 char *ext = strchr (str, '+');
13545 int optlen;
13546
13547 if (ext != NULL)
13548 optlen = ext - str;
13549 else
13550 optlen = strlen (str);
13551
13552 if (optlen == 0)
13553 {
13554 as_bad (_("missing cpu name `%s'"), str);
13555 return 0;
13556 }
13557
13558 for (opt = arm_cpus; opt->name != NULL; opt++)
13559 if (strncmp (opt->name, str, optlen) == 0)
13560 {
13561 mcpu_cpu_opt = opt->value;
13562 mcpu_fpu_opt = opt->default_fpu;
13563
13564 if (ext != NULL)
13565 return arm_parse_extension (ext, &mcpu_cpu_opt);
13566
13567 return 1;
13568 }
13569
13570 as_bad (_("unknown cpu `%s'"), str);
13571 return 0;
13572 }
13573
13574 static int
13575 arm_parse_arch (str)
13576 char *str;
13577 {
13578 struct arm_arch_option_table *opt;
13579 char *ext = strchr (str, '+');
13580 int optlen;
13581
13582 if (ext != NULL)
13583 optlen = ext - str;
13584 else
13585 optlen = strlen (str);
13586
13587 if (optlen == 0)
13588 {
13589 as_bad (_("missing architecture name `%s'"), str);
13590 return 0;
13591 }
13592
13593
13594 for (opt = arm_archs; opt->name != NULL; opt++)
13595 if (strcmp (opt->name, str) == 0)
13596 {
13597 march_cpu_opt = opt->value;
13598 march_fpu_opt = opt->default_fpu;
13599
13600 if (ext != NULL)
13601 return arm_parse_extension (ext, &march_cpu_opt);
13602
13603 return 1;
13604 }
13605
13606 as_bad (_("unknown architecture `%s'\n"), str);
13607 return 0;
13608 }
13609
13610 static int
13611 arm_parse_fpu (str)
13612 char *str;
13613 {
13614 struct arm_fpu_option_table *opt;
13615
13616 for (opt = arm_fpus; opt->name != NULL; opt++)
13617 if (strcmp (opt->name, str) == 0)
13618 {
13619 mfpu_opt = opt->value;
13620 return 1;
13621 }
13622
13623 as_bad (_("unknown floating point format `%s'\n"), str);
13624 return 0;
13625 }
13626
13627 static int
13628 arm_parse_float_abi (str)
13629 char * str;
13630 {
13631 struct arm_float_abi_option_table *opt;
13632
13633 for (opt = arm_float_abis; opt->name != NULL; opt++)
13634 if (strcmp (opt->name, str) == 0)
13635 {
13636 mfloat_abi_opt = opt->value;
13637 return 1;
13638 }
13639
13640 as_bad (_("unknown floating point abi `%s'\n"), str);
13641 return 0;
13642 }
13643
13644 static int
13645 arm_parse_eabi (str)
13646 char * str;
13647 {
13648 struct arm_eabi_option_table *opt;
13649
13650 for (opt = arm_eabis; opt->name != NULL; opt++)
13651 if (strcmp (opt->name, str) == 0)
13652 {
13653 meabi_flags = opt->value;
13654 return 1;
13655 }
13656 as_bad (_("unknown EABI `%s'\n"), str);
13657 return 0;
13658 }
13659
13660 struct arm_long_option_table arm_long_opts[] =
13661 {
13662 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
13663 arm_parse_cpu, NULL},
13664 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
13665 arm_parse_arch, NULL},
13666 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
13667 arm_parse_fpu, NULL},
13668 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
13669 arm_parse_float_abi, NULL},
13670 {"meabi=", N_("<ver>\t assemble for eabi version <ver>"),
13671 arm_parse_eabi, NULL},
13672 {NULL, NULL, 0, NULL}
13673 };
13674
13675 int
13676 md_parse_option (c, arg)
13677 int c;
13678 char * arg;
13679 {
13680 struct arm_option_table *opt;
13681 struct arm_long_option_table *lopt;
13682
13683 switch (c)
13684 {
13685 #ifdef OPTION_EB
13686 case OPTION_EB:
13687 target_big_endian = 1;
13688 break;
13689 #endif
13690
13691 #ifdef OPTION_EL
13692 case OPTION_EL:
13693 target_big_endian = 0;
13694 break;
13695 #endif
13696
13697 case 'a':
13698 /* Listing option. Just ignore these, we don't support additional
13699 ones. */
13700 return 0;
13701
13702 default:
13703 for (opt = arm_opts; opt->option != NULL; opt++)
13704 {
13705 if (c == opt->option[0]
13706 && ((arg == NULL && opt->option[1] == 0)
13707 || strcmp (arg, opt->option + 1) == 0))
13708 {
13709 #if WARN_DEPRECATED
13710 /* If the option is deprecated, tell the user. */
13711 if (opt->deprecated != NULL)
13712 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13713 arg ? arg : "", _(opt->deprecated));
13714 #endif
13715
13716 if (opt->var != NULL)
13717 *opt->var = opt->value;
13718
13719 return 1;
13720 }
13721 }
13722
13723 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13724 {
13725 /* These options are expected to have an argument. */
13726 if (c == lopt->option[0]
13727 && arg != NULL
13728 && strncmp (arg, lopt->option + 1,
13729 strlen (lopt->option + 1)) == 0)
13730 {
13731 #if WARN_DEPRECATED
13732 /* If the option is deprecated, tell the user. */
13733 if (lopt->deprecated != NULL)
13734 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13735 _(lopt->deprecated));
13736 #endif
13737
13738 /* Call the sup-option parser. */
13739 return (*lopt->func)(arg + strlen (lopt->option) - 1);
13740 }
13741 }
13742
13743 as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
13744 return 0;
13745 }
13746
13747 return 1;
13748 }
13749
13750 void
13751 md_show_usage (fp)
13752 FILE * fp;
13753 {
13754 struct arm_option_table *opt;
13755 struct arm_long_option_table *lopt;
13756
13757 fprintf (fp, _(" ARM-specific assembler options:\n"));
13758
13759 for (opt = arm_opts; opt->option != NULL; opt++)
13760 if (opt->help != NULL)
13761 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
13762
13763 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13764 if (lopt->help != NULL)
13765 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
13766
13767 #ifdef OPTION_EB
13768 fprintf (fp, _("\
13769 -EB assemble code for a big-endian cpu\n"));
13770 #endif
13771
13772 #ifdef OPTION_EL
13773 fprintf (fp, _("\
13774 -EL assemble code for a little-endian cpu\n"));
13775 #endif
13776 }
13777
13778 /* We need to be able to fix up arbitrary expressions in some statements.
13779 This is so that we can handle symbols that are an arbitrary distance from
13780 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
13781 which returns part of an address in a form which will be valid for
13782 a data instruction. We do this by pushing the expression into a symbol
13783 in the expr_section, and creating a fix for that. */
13784
13785 static void
13786 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
13787 fragS * frag;
13788 int where;
13789 short int size;
13790 expressionS * exp;
13791 int pc_rel;
13792 int reloc;
13793 {
13794 fixS * new_fix;
13795 arm_fix_data * arm_data;
13796
13797 switch (exp->X_op)
13798 {
13799 case O_constant:
13800 case O_symbol:
13801 case O_add:
13802 case O_subtract:
13803 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
13804 break;
13805
13806 default:
13807 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
13808 pc_rel, reloc);
13809 break;
13810 }
13811
13812 /* Mark whether the fix is to a THUMB instruction, or an ARM
13813 instruction. */
13814 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
13815 new_fix->tc_fix_data = (PTR) arm_data;
13816 arm_data->thumb_mode = thumb_mode;
13817 }
13818
13819 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
13820
13821 void
13822 cons_fix_new_arm (frag, where, size, exp)
13823 fragS * frag;
13824 int where;
13825 int size;
13826 expressionS * exp;
13827 {
13828 bfd_reloc_code_real_type type;
13829 int pcrel = 0;
13830
13831 /* Pick a reloc.
13832 FIXME: @@ Should look at CPU word size. */
13833 switch (size)
13834 {
13835 case 1:
13836 type = BFD_RELOC_8;
13837 break;
13838 case 2:
13839 type = BFD_RELOC_16;
13840 break;
13841 case 4:
13842 default:
13843 type = BFD_RELOC_32;
13844 break;
13845 case 8:
13846 type = BFD_RELOC_64;
13847 break;
13848 }
13849
13850 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
13851 }
13852
13853 /* A good place to do this, although this was probably not intended
13854 for this kind of use. We need to dump the literal pool before
13855 references are made to a null symbol pointer. */
13856
13857 void
13858 arm_cleanup ()
13859 {
13860 literal_pool * pool;
13861
13862 for (pool = list_of_pools; pool; pool = pool->next)
13863 {
13864 /* Put it at the end of the relevent section. */
13865 subseg_set (pool->section, pool->sub_section);
13866 s_ltorg (0);
13867 }
13868 }
13869
13870 void
13871 arm_start_line_hook ()
13872 {
13873 last_label_seen = NULL;
13874 }
13875
13876 void
13877 arm_frob_label (sym)
13878 symbolS * sym;
13879 {
13880 last_label_seen = sym;
13881
13882 ARM_SET_THUMB (sym, thumb_mode);
13883
13884 #if defined OBJ_COFF || defined OBJ_ELF
13885 ARM_SET_INTERWORK (sym, support_interwork);
13886 #endif
13887
13888 /* Note - do not allow local symbols (.Lxxx) to be labeled
13889 as Thumb functions. This is because these labels, whilst
13890 they exist inside Thumb code, are not the entry points for
13891 possible ARM->Thumb calls. Also, these labels can be used
13892 as part of a computed goto or switch statement. eg gcc
13893 can generate code that looks like this:
13894
13895 ldr r2, [pc, .Laaa]
13896 lsl r3, r3, #2
13897 ldr r2, [r3, r2]
13898 mov pc, r2
13899
13900 .Lbbb: .word .Lxxx
13901 .Lccc: .word .Lyyy
13902 ..etc...
13903 .Laaa: .word Lbbb
13904
13905 The first instruction loads the address of the jump table.
13906 The second instruction converts a table index into a byte offset.
13907 The third instruction gets the jump address out of the table.
13908 The fourth instruction performs the jump.
13909
13910 If the address stored at .Laaa is that of a symbol which has the
13911 Thumb_Func bit set, then the linker will arrange for this address
13912 to have the bottom bit set, which in turn would mean that the
13913 address computation performed by the third instruction would end
13914 up with the bottom bit set. Since the ARM is capable of unaligned
13915 word loads, the instruction would then load the incorrect address
13916 out of the jump table, and chaos would ensue. */
13917 if (label_is_thumb_function_name
13918 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
13919 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
13920 {
13921 /* When the address of a Thumb function is taken the bottom
13922 bit of that address should be set. This will allow
13923 interworking between Arm and Thumb functions to work
13924 correctly. */
13925
13926 THUMB_SET_FUNC (sym, 1);
13927
13928 label_is_thumb_function_name = FALSE;
13929 }
13930 }
13931
13932 /* Adjust the symbol table. This marks Thumb symbols as distinct from
13933 ARM ones. */
13934
13935 void
13936 arm_adjust_symtab ()
13937 {
13938 #ifdef OBJ_COFF
13939 symbolS * sym;
13940
13941 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13942 {
13943 if (ARM_IS_THUMB (sym))
13944 {
13945 if (THUMB_IS_FUNC (sym))
13946 {
13947 /* Mark the symbol as a Thumb function. */
13948 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
13949 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
13950 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
13951
13952 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
13953 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
13954 else
13955 as_bad (_("%s: unexpected function type: %d"),
13956 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
13957 }
13958 else switch (S_GET_STORAGE_CLASS (sym))
13959 {
13960 case C_EXT:
13961 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
13962 break;
13963 case C_STAT:
13964 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
13965 break;
13966 case C_LABEL:
13967 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
13968 break;
13969 default:
13970 /* Do nothing. */
13971 break;
13972 }
13973 }
13974
13975 if (ARM_IS_INTERWORK (sym))
13976 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
13977 }
13978 #endif
13979 #ifdef OBJ_ELF
13980 symbolS * sym;
13981 char bind;
13982
13983 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
13984 {
13985 if (ARM_IS_THUMB (sym))
13986 {
13987 elf_symbol_type * elf_sym;
13988
13989 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
13990 bind = ELF_ST_BIND (elf_sym);
13991
13992 /* If it's a .thumb_func, declare it as so,
13993 otherwise tag label as .code 16. */
13994 if (THUMB_IS_FUNC (sym))
13995 elf_sym->internal_elf_sym.st_info =
13996 ELF_ST_INFO (bind, STT_ARM_TFUNC);
13997 else
13998 elf_sym->internal_elf_sym.st_info =
13999 ELF_ST_INFO (bind, STT_ARM_16BIT);
14000 }
14001 }
14002 #endif
14003 }
14004
14005 int
14006 arm_data_in_code ()
14007 {
14008 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
14009 {
14010 *input_line_pointer = '/';
14011 input_line_pointer += 5;
14012 *input_line_pointer = 0;
14013 return 1;
14014 }
14015
14016 return 0;
14017 }
14018
14019 char *
14020 arm_canonicalize_symbol_name (name)
14021 char * name;
14022 {
14023 int len;
14024
14025 if (thumb_mode && (len = strlen (name)) > 5
14026 && streq (name + len - 5, "/data"))
14027 *(name + len - 5) = 0;
14028
14029 return name;
14030 }
14031
14032 #if defined OBJ_COFF || defined OBJ_ELF
14033 void
14034 arm_validate_fix (fixP)
14035 fixS * fixP;
14036 {
14037 /* If the destination of the branch is a defined symbol which does not have
14038 the THUMB_FUNC attribute, then we must be calling a function which has
14039 the (interfacearm) attribute. We look for the Thumb entry point to that
14040 function and change the branch to refer to that function instead. */
14041 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
14042 && fixP->fx_addsy != NULL
14043 && S_IS_DEFINED (fixP->fx_addsy)
14044 && ! THUMB_IS_FUNC (fixP->fx_addsy))
14045 {
14046 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
14047 }
14048 }
14049 #endif
14050
14051 int
14052 arm_force_relocation (fixp)
14053 struct fix * fixp;
14054 {
14055 #if defined (OBJ_COFF) && defined (TE_PE)
14056 if (fixp->fx_r_type == BFD_RELOC_RVA)
14057 return 1;
14058 #endif
14059 #ifdef OBJ_ELF
14060 if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
14061 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
14062 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
14063 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
14064 return 1;
14065 #endif
14066
14067 /* Resolve these relocations even if the symbol is extern or weak. */
14068 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
14069 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
14070 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14071 return 0;
14072
14073 return generic_force_reloc (fixp);
14074 }
14075
14076 #ifdef OBJ_COFF
14077 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
14078 local labels from being added to the output symbol table when they
14079 are used with the ADRL pseudo op. The ADRL relocation should always
14080 be resolved before the binbary is emitted, so it is safe to say that
14081 it is adjustable. */
14082
14083 bfd_boolean
14084 arm_fix_adjustable (fixP)
14085 fixS * fixP;
14086 {
14087 if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
14088 return 1;
14089 return 0;
14090 }
14091 #endif
14092
14093 #ifdef OBJ_ELF
14094 /* Relocations against Thumb function names must be left unadjusted,
14095 so that the linker can use this information to correctly set the
14096 bottom bit of their addresses. The MIPS version of this function
14097 also prevents relocations that are mips-16 specific, but I do not
14098 know why it does this.
14099
14100 FIXME:
14101 There is one other problem that ought to be addressed here, but
14102 which currently is not: Taking the address of a label (rather
14103 than a function) and then later jumping to that address. Such
14104 addresses also ought to have their bottom bit set (assuming that
14105 they reside in Thumb code), but at the moment they will not. */
14106
14107 bfd_boolean
14108 arm_fix_adjustable (fixP)
14109 fixS * fixP;
14110 {
14111 if (fixP->fx_addsy == NULL)
14112 return 1;
14113
14114 if (THUMB_IS_FUNC (fixP->fx_addsy)
14115 && fixP->fx_subsy == NULL)
14116 return 0;
14117
14118 /* We need the symbol name for the VTABLE entries. */
14119 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
14120 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
14121 return 0;
14122
14123 /* Don't allow symbols to be discarded on GOT related relocs. */
14124 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
14125 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
14126 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
14127 return 0;
14128
14129 return 1;
14130 }
14131
14132 const char *
14133 elf32_arm_target_format ()
14134 {
14135 if (target_big_endian)
14136 {
14137 if (target_oabi)
14138 return "elf32-bigarm-oabi";
14139 else
14140 return "elf32-bigarm";
14141 }
14142 else
14143 {
14144 if (target_oabi)
14145 return "elf32-littlearm-oabi";
14146 else
14147 return "elf32-littlearm";
14148 }
14149 }
14150
14151 void
14152 armelf_frob_symbol (symp, puntp)
14153 symbolS * symp;
14154 int * puntp;
14155 {
14156 elf_frob_symbol (symp, puntp);
14157 }
14158
14159 static bfd_reloc_code_real_type
14160 arm_parse_reloc ()
14161 {
14162 char id [16];
14163 char * ip;
14164 unsigned int i;
14165 static struct
14166 {
14167 char * str;
14168 int len;
14169 bfd_reloc_code_real_type reloc;
14170 }
14171 reloc_map[] =
14172 {
14173 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
14174 MAP ("(got)", BFD_RELOC_ARM_GOT32),
14175 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
14176 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
14177 branch instructions generated by GCC for PLT relocs. */
14178 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
14179 { NULL, 0, BFD_RELOC_UNUSED }
14180 #undef MAP
14181 };
14182
14183 for (i = 0, ip = input_line_pointer;
14184 i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
14185 i++, ip++)
14186 id[i] = TOLOWER (*ip);
14187
14188 for (i = 0; reloc_map[i].str; i++)
14189 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
14190 break;
14191
14192 input_line_pointer += reloc_map[i].len;
14193
14194 return reloc_map[i].reloc;
14195 }
14196
14197 static void
14198 s_arm_elf_cons (nbytes)
14199 int nbytes;
14200 {
14201 expressionS exp;
14202
14203 #ifdef md_flush_pending_output
14204 md_flush_pending_output ();
14205 #endif
14206
14207 if (is_it_end_of_statement ())
14208 {
14209 demand_empty_rest_of_line ();
14210 return;
14211 }
14212
14213 #ifdef md_cons_align
14214 md_cons_align (nbytes);
14215 #endif
14216
14217 mapping_state (MAP_DATA);
14218 do
14219 {
14220 bfd_reloc_code_real_type reloc;
14221
14222 expression (& exp);
14223
14224 if (exp.X_op == O_symbol
14225 && * input_line_pointer == '('
14226 && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
14227 {
14228 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
14229 int size = bfd_get_reloc_size (howto);
14230
14231 if (size > nbytes)
14232 as_bad ("%s relocations do not fit in %d bytes",
14233 howto->name, nbytes);
14234 else
14235 {
14236 register char *p = frag_more ((int) nbytes);
14237 int offset = nbytes - size;
14238
14239 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
14240 &exp, 0, reloc);
14241 }
14242 }
14243 else
14244 emit_expr (&exp, (unsigned int) nbytes);
14245 }
14246 while (*input_line_pointer++ == ',');
14247
14248 /* Put terminator back into stream. */
14249 input_line_pointer --;
14250 demand_empty_rest_of_line ();
14251 }
14252
14253 #endif /* OBJ_ELF */
14254
14255 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
14256 of an rs_align_code fragment. */
14257
14258 void
14259 arm_handle_align (fragP)
14260 fragS *fragP;
14261 {
14262 static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14263 static char const thumb_noop[2] = { 0xc0, 0x46 };
14264 static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14265 static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
14266
14267 int bytes, fix, noop_size;
14268 char * p;
14269 const char * noop;
14270
14271 if (fragP->fr_type != rs_align_code)
14272 return;
14273
14274 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
14275 p = fragP->fr_literal + fragP->fr_fix;
14276 fix = 0;
14277
14278 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
14279 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
14280
14281 if (fragP->tc_frag_data)
14282 {
14283 if (target_big_endian)
14284 noop = thumb_bigend_noop;
14285 else
14286 noop = thumb_noop;
14287 noop_size = sizeof (thumb_noop);
14288 }
14289 else
14290 {
14291 if (target_big_endian)
14292 noop = arm_bigend_noop;
14293 else
14294 noop = arm_noop;
14295 noop_size = sizeof (arm_noop);
14296 }
14297
14298 if (bytes & (noop_size - 1))
14299 {
14300 fix = bytes & (noop_size - 1);
14301 memset (p, 0, fix);
14302 p += fix;
14303 bytes -= fix;
14304 }
14305
14306 while (bytes >= noop_size)
14307 {
14308 memcpy (p, noop, noop_size);
14309 p += noop_size;
14310 bytes -= noop_size;
14311 fix += noop_size;
14312 }
14313
14314 fragP->fr_fix += fix;
14315 fragP->fr_var = noop_size;
14316 }
14317
14318 /* Called from md_do_align. Used to create an alignment
14319 frag in a code section. */
14320
14321 void
14322 arm_frag_align_code (n, max)
14323 int n;
14324 int max;
14325 {
14326 char * p;
14327
14328 /* We assume that there will never be a requirement
14329 to support alignments greater than 32 bytes. */
14330 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
14331 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14332
14333 p = frag_var (rs_align_code,
14334 MAX_MEM_FOR_RS_ALIGN_CODE,
14335 1,
14336 (relax_substateT) max,
14337 (symbolS *) NULL,
14338 (offsetT) n,
14339 (char *) NULL);
14340 *p = 0;
14341
14342 }
14343
14344 /* Perform target specific initialisation of a frag. */
14345
14346 void
14347 arm_init_frag (fragP)
14348 fragS *fragP;
14349 {
14350 /* Record whether this frag is in an ARM or a THUMB area. */
14351 fragP->tc_frag_data = thumb_mode;
14352 }