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)
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 #include "safe-ctype.h"
30 /* Need TARGET_CPU. */
39 #include "dwarf2dbg.h"
42 /* XXX Set this to 1 after the next binutils release */
43 #define WARN_DEPRECATED 0
45 /* The following bitmasks control CPU extensions: */
46 #define ARM_EXT_V1 0x00000001 /* All processors (core set). */
47 #define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
48 #define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
49 #define ARM_EXT_V3 0x00000008 /* MSR MRS. */
50 #define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
51 #define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
52 #define ARM_EXT_V4T 0x00000040 /* Thumb v1. */
53 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
54 #define ARM_EXT_V5T 0x00000100 /* Thumb v2. */
55 #define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
56 #define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
57 #define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */
59 /* Co-processor space extensions. */
60 #define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */
61 #define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. */
62 #define ARM_CEXT_IWMMXT 0x00200000 /* Intel Wireless MMX technology coprocessor. */
64 /* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
65 defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
66 ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
67 three more to cover cores prior to ARM6. Finally, there are cores which
68 implement further extensions in the co-processor space. */
69 #define ARM_ARCH_V1 ARM_EXT_V1
70 #define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)
71 #define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)
72 #define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)
73 #define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)
74 #define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)
75 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)
76 #define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)
77 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)
78 #define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)
79 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
80 #define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
81 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
82 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)
83 #define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)
84 #define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE | ARM_EXT_V5J)
86 /* Processors with specific extensions in the co-processor space. */
87 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)
88 #define ARM_ARCH_IWMMXT (ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT)
90 /* Some useful combinations: */
91 #define ARM_ANY 0x0000ffff /* Any basic core. */
92 #define ARM_ALL 0x00ffffff /* Any core + co-processor */
93 #define CPROC_ANY 0x00ff0000 /* Any co-processor */
94 #define FPU_ANY 0xff000000 /* Note this is ~ARM_ALL. */
97 #define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */
98 #define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */
99 #define FPU_VFP_EXT_NONE 0x20000000 /* Use VFP word-ordering. */
100 #define FPU_VFP_EXT_V1xD 0x10000000 /* Base VFP instruction set. */
101 #define FPU_VFP_EXT_V1 0x08000000 /* Double-precision insns. */
102 #define FPU_VFP_EXT_V2 0x04000000 /* ARM10E VFPr1. */
105 #define FPU_ARCH_FPE FPU_FPA_EXT_V1
106 #define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
108 #define FPU_ARCH_VFP FPU_VFP_EXT_NONE
109 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
110 #define FPU_ARCH_VFP_V1 (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
111 #define FPU_ARCH_VFP_V2 (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
113 /* Types of processor to assemble for. */
114 #define ARM_1 ARM_ARCH_V1
115 #define ARM_2 ARM_ARCH_V2
116 #define ARM_3 ARM_ARCH_V2S
117 #define ARM_250 ARM_ARCH_V2S
118 #define ARM_6 ARM_ARCH_V3
119 #define ARM_7 ARM_ARCH_V3
120 #define ARM_8 ARM_ARCH_V4
121 #define ARM_9 ARM_ARCH_V4T
122 #define ARM_STRONG ARM_ARCH_V4
123 #define ARM_CPU_MASK 0x0000000f /* XXX? */
126 #if defined __XSCALE__
127 #define CPU_DEFAULT (ARM_ARCH_XSCALE)
129 #if defined __thumb__
130 #define CPU_DEFAULT (ARM_ARCH_V5T)
132 #define CPU_DEFAULT ARM_ANY
137 /* For backwards compatibility we default to the FPA. */
139 #define FPU_DEFAULT FPU_ARCH_FPA
142 #define streq(a, b) (strcmp (a, b) == 0)
143 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
145 static unsigned long cpu_variant;
146 static int target_oabi = 0;
148 /* Flags stored in private area of BFD structure. */
149 static int uses_apcs_26 = FALSE;
150 static int atpcs = FALSE;
151 static int support_interwork = FALSE;
152 static int uses_apcs_float = FALSE;
153 static int pic_code = FALSE;
155 /* Variables that we set while parsing command-line options. Once all
156 options have been read we re-process these values to set the real
158 static int legacy_cpu = -1;
159 static int legacy_fpu = -1;
161 static int mcpu_cpu_opt = -1;
162 static int mcpu_fpu_opt = -1;
163 static int march_cpu_opt = -1;
164 static int march_fpu_opt = -1;
165 static int mfpu_opt = -1;
167 /* This array holds the chars that always start a comment. If the
168 pre-processor is disabled, these aren't very useful. */
169 const char comment_chars[] = "@";
171 /* This array holds the chars that only start a comment at the beginning of
172 a line. If the line seems to have the form '# 123 filename'
173 .line and .file directives will appear in the pre-processed output. */
174 /* Note that input_file.c hand checks for '#' at the beginning of the
175 first line of the input file. This is because the compiler outputs
176 #NO_APP at the beginning of its output. */
177 /* Also note that comments like this one will always work. */
178 const char line_comment_chars[] = "#";
180 const char line_separator_chars[] = ";";
182 /* Chars that can be used to separate mant
183 from exp in floating point numbers. */
184 const char EXP_CHARS[] = "eE";
186 /* Chars that mean this number is a floating point constant. */
190 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
192 /* Prefix characters that indicate the start of an immediate
194 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
197 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
198 symbolS * GOT_symbol;
201 /* Size of relocation record. */
202 const int md_reloc_size = 8;
204 /* 0: assemble for ARM,
205 1: assemble for Thumb,
206 2: assemble for Thumb even though target CPU does not support thumb
208 static int thumb_mode = 0;
210 typedef struct arm_fix
218 unsigned long instruction;
222 bfd_reloc_code_real_type type;
239 struct asm_shift_properties
241 enum asm_shift_index index;
242 unsigned long bit_field;
243 unsigned int allows_0 : 1;
244 unsigned int allows_32 : 1;
247 static const struct asm_shift_properties shift_properties [] =
249 { SHIFT_LSL, 0, 1, 0},
250 { SHIFT_LSR, 0x20, 0, 1},
251 { SHIFT_ASR, 0x40, 0, 1},
252 { SHIFT_ROR, 0x60, 0, 0},
253 { SHIFT_RRX, 0x60, 0, 0}
256 struct asm_shift_name
259 const struct asm_shift_properties * properties;
262 static const struct asm_shift_name shift_names [] =
264 { "asl", shift_properties + SHIFT_LSL },
265 { "lsl", shift_properties + SHIFT_LSL },
266 { "lsr", shift_properties + SHIFT_LSR },
267 { "asr", shift_properties + SHIFT_ASR },
268 { "ror", shift_properties + SHIFT_ROR },
269 { "rrx", shift_properties + SHIFT_RRX },
270 { "ASL", shift_properties + SHIFT_LSL },
271 { "LSL", shift_properties + SHIFT_LSL },
272 { "LSR", shift_properties + SHIFT_LSR },
273 { "ASR", shift_properties + SHIFT_ASR },
274 { "ROR", shift_properties + SHIFT_ROR },
275 { "RRX", shift_properties + SHIFT_RRX }
278 #define NO_SHIFT_RESTRICT 1
279 #define SHIFT_RESTRICT 0
281 #define NUM_FLOAT_VALS 8
283 const char * fp_const[] =
285 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
288 /* Number of littlenums required to hold an extended precision number. */
289 #define MAX_LITTLENUMS 6
291 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
296 /* Whether a Co-processor load/store operation accepts write-back forms. */
305 #define CP_T_X 0x00008000
306 #define CP_T_Y 0x00400000
307 #define CP_T_Pre 0x01000000
308 #define CP_T_UD 0x00800000
309 #define CP_T_WB 0x00200000
311 #define CONDS_BIT 0x00100000
312 #define LOAD_BIT 0x00100000
314 #define DOUBLE_LOAD_FLAG 0x00000001
318 const char * template;
322 #define COND_ALWAYS 0xe0000000
323 #define COND_MASK 0xf0000000
325 static const struct asm_cond conds[] =
329 {"cs", 0x20000000}, {"hs", 0x20000000},
330 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
347 const char *template;
352 /* The bit that distnguishes CPSR and SPSR. */
353 #define SPSR_BIT (1 << 22)
355 /* How many bits to shift the PSR_xxx bits up by. */
358 #define PSR_c (1 << 0)
359 #define PSR_x (1 << 1)
360 #define PSR_s (1 << 2)
361 #define PSR_f (1 << 3)
363 static const struct asm_psr psrs[] =
365 {"CPSR", TRUE, PSR_c | PSR_f},
366 {"CPSR_all", TRUE, PSR_c | PSR_f},
367 {"SPSR", FALSE, PSR_c | PSR_f},
368 {"SPSR_all", FALSE, PSR_c | PSR_f},
369 {"CPSR_flg", TRUE, PSR_f},
370 {"CPSR_f", TRUE, PSR_f},
371 {"SPSR_flg", FALSE, PSR_f},
372 {"SPSR_f", FALSE, PSR_f},
373 {"CPSR_c", TRUE, PSR_c},
374 {"CPSR_ctl", TRUE, PSR_c},
375 {"SPSR_c", FALSE, PSR_c},
376 {"SPSR_ctl", FALSE, PSR_c},
377 {"CPSR_x", TRUE, PSR_x},
378 {"CPSR_s", TRUE, PSR_s},
379 {"SPSR_x", FALSE, PSR_x},
380 {"SPSR_s", FALSE, PSR_s},
381 /* Combinations of flags. */
382 {"CPSR_fs", TRUE, PSR_f | PSR_s},
383 {"CPSR_fx", TRUE, PSR_f | PSR_x},
384 {"CPSR_fc", TRUE, PSR_f | PSR_c},
385 {"CPSR_sf", TRUE, PSR_s | PSR_f},
386 {"CPSR_sx", TRUE, PSR_s | PSR_x},
387 {"CPSR_sc", TRUE, PSR_s | PSR_c},
388 {"CPSR_xf", TRUE, PSR_x | PSR_f},
389 {"CPSR_xs", TRUE, PSR_x | PSR_s},
390 {"CPSR_xc", TRUE, PSR_x | PSR_c},
391 {"CPSR_cf", TRUE, PSR_c | PSR_f},
392 {"CPSR_cs", TRUE, PSR_c | PSR_s},
393 {"CPSR_cx", TRUE, PSR_c | PSR_x},
394 {"CPSR_fsx", TRUE, PSR_f | PSR_s | PSR_x},
395 {"CPSR_fsc", TRUE, PSR_f | PSR_s | PSR_c},
396 {"CPSR_fxs", TRUE, PSR_f | PSR_x | PSR_s},
397 {"CPSR_fxc", TRUE, PSR_f | PSR_x | PSR_c},
398 {"CPSR_fcs", TRUE, PSR_f | PSR_c | PSR_s},
399 {"CPSR_fcx", TRUE, PSR_f | PSR_c | PSR_x},
400 {"CPSR_sfx", TRUE, PSR_s | PSR_f | PSR_x},
401 {"CPSR_sfc", TRUE, PSR_s | PSR_f | PSR_c},
402 {"CPSR_sxf", TRUE, PSR_s | PSR_x | PSR_f},
403 {"CPSR_sxc", TRUE, PSR_s | PSR_x | PSR_c},
404 {"CPSR_scf", TRUE, PSR_s | PSR_c | PSR_f},
405 {"CPSR_scx", TRUE, PSR_s | PSR_c | PSR_x},
406 {"CPSR_xfs", TRUE, PSR_x | PSR_f | PSR_s},
407 {"CPSR_xfc", TRUE, PSR_x | PSR_f | PSR_c},
408 {"CPSR_xsf", TRUE, PSR_x | PSR_s | PSR_f},
409 {"CPSR_xsc", TRUE, PSR_x | PSR_s | PSR_c},
410 {"CPSR_xcf", TRUE, PSR_x | PSR_c | PSR_f},
411 {"CPSR_xcs", TRUE, PSR_x | PSR_c | PSR_s},
412 {"CPSR_cfs", TRUE, PSR_c | PSR_f | PSR_s},
413 {"CPSR_cfx", TRUE, PSR_c | PSR_f | PSR_x},
414 {"CPSR_csf", TRUE, PSR_c | PSR_s | PSR_f},
415 {"CPSR_csx", TRUE, PSR_c | PSR_s | PSR_x},
416 {"CPSR_cxf", TRUE, PSR_c | PSR_x | PSR_f},
417 {"CPSR_cxs", TRUE, PSR_c | PSR_x | PSR_s},
418 {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
419 {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
420 {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
421 {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
422 {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
423 {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
424 {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
425 {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
426 {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
427 {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
428 {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
429 {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
430 {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
431 {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
432 {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
433 {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
434 {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
435 {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
436 {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
437 {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
438 {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
439 {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
440 {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
441 {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
442 {"SPSR_fs", FALSE, PSR_f | PSR_s},
443 {"SPSR_fx", FALSE, PSR_f | PSR_x},
444 {"SPSR_fc", FALSE, PSR_f | PSR_c},
445 {"SPSR_sf", FALSE, PSR_s | PSR_f},
446 {"SPSR_sx", FALSE, PSR_s | PSR_x},
447 {"SPSR_sc", FALSE, PSR_s | PSR_c},
448 {"SPSR_xf", FALSE, PSR_x | PSR_f},
449 {"SPSR_xs", FALSE, PSR_x | PSR_s},
450 {"SPSR_xc", FALSE, PSR_x | PSR_c},
451 {"SPSR_cf", FALSE, PSR_c | PSR_f},
452 {"SPSR_cs", FALSE, PSR_c | PSR_s},
453 {"SPSR_cx", FALSE, PSR_c | PSR_x},
454 {"SPSR_fsx", FALSE, PSR_f | PSR_s | PSR_x},
455 {"SPSR_fsc", FALSE, PSR_f | PSR_s | PSR_c},
456 {"SPSR_fxs", FALSE, PSR_f | PSR_x | PSR_s},
457 {"SPSR_fxc", FALSE, PSR_f | PSR_x | PSR_c},
458 {"SPSR_fcs", FALSE, PSR_f | PSR_c | PSR_s},
459 {"SPSR_fcx", FALSE, PSR_f | PSR_c | PSR_x},
460 {"SPSR_sfx", FALSE, PSR_s | PSR_f | PSR_x},
461 {"SPSR_sfc", FALSE, PSR_s | PSR_f | PSR_c},
462 {"SPSR_sxf", FALSE, PSR_s | PSR_x | PSR_f},
463 {"SPSR_sxc", FALSE, PSR_s | PSR_x | PSR_c},
464 {"SPSR_scf", FALSE, PSR_s | PSR_c | PSR_f},
465 {"SPSR_scx", FALSE, PSR_s | PSR_c | PSR_x},
466 {"SPSR_xfs", FALSE, PSR_x | PSR_f | PSR_s},
467 {"SPSR_xfc", FALSE, PSR_x | PSR_f | PSR_c},
468 {"SPSR_xsf", FALSE, PSR_x | PSR_s | PSR_f},
469 {"SPSR_xsc", FALSE, PSR_x | PSR_s | PSR_c},
470 {"SPSR_xcf", FALSE, PSR_x | PSR_c | PSR_f},
471 {"SPSR_xcs", FALSE, PSR_x | PSR_c | PSR_s},
472 {"SPSR_cfs", FALSE, PSR_c | PSR_f | PSR_s},
473 {"SPSR_cfx", FALSE, PSR_c | PSR_f | PSR_x},
474 {"SPSR_csf", FALSE, PSR_c | PSR_s | PSR_f},
475 {"SPSR_csx", FALSE, PSR_c | PSR_s | PSR_x},
476 {"SPSR_cxf", FALSE, PSR_c | PSR_x | PSR_f},
477 {"SPSR_cxs", FALSE, PSR_c | PSR_x | PSR_s},
478 {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
479 {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
480 {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
481 {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
482 {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
483 {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
484 {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
485 {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
486 {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
487 {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
488 {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
489 {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
490 {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
491 {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
492 {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
493 {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
494 {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
495 {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
496 {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
497 {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
498 {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
499 {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
500 {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
501 {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
508 IWMMXT_REG_WR_OR_WC = 2,
512 enum iwmmxt_insn_type
535 VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
540 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
545 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
548 /* VFP system registers. */
555 static const struct vfp_reg vfp_regs[] =
557 {"fpsid", 0x00000000},
558 {"FPSID", 0x00000000},
559 {"fpscr", 0x00010000},
560 {"FPSCR", 0x00010000},
561 {"fpexc", 0x00080000},
562 {"FPEXC", 0x00080000}
565 /* Structure for a hash table entry for a register. */
572 /* Some well known registers that we refer to directly elsewhere. */
577 #define wr_register(reg) ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
578 #define wc_register(reg) ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
579 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
581 /* These are the standard names. Users can add aliases with .req. */
582 /* Integer Register Numbers. */
583 static const struct reg_entry rn_table[] =
585 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
586 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
587 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
588 {"r12", 12}, {"r13", REG_SP}, {"r14", REG_LR}, {"r15", REG_PC},
589 /* ATPCS Synonyms. */
590 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
591 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7},
592 {"v5", 8}, {"v6", 9}, {"v7", 10}, {"v8", 11},
593 /* Well-known aliases. */
595 {"sb", 9}, {"sl", 10}, {"fp", 11},
596 {"ip", 12}, {"sp", REG_SP}, {"lr", REG_LR}, {"pc", REG_PC},
600 #define WR_PREFIX 0x200
601 #define WC_PREFIX 0x400
603 static const struct reg_entry iwmmxt_table[] =
605 /* Intel Wireless MMX technology register names. */
606 { "wr0", 0x0 | WR_PREFIX}, {"wr1", 0x1 | WR_PREFIX},
607 { "wr2", 0x2 | WR_PREFIX}, {"wr3", 0x3 | WR_PREFIX},
608 { "wr4", 0x4 | WR_PREFIX}, {"wr5", 0x5 | WR_PREFIX},
609 { "wr6", 0x6 | WR_PREFIX}, {"wr7", 0x7 | WR_PREFIX},
610 { "wr8", 0x8 | WR_PREFIX}, {"wr9", 0x9 | WR_PREFIX},
611 { "wr10", 0xa | WR_PREFIX}, {"wr11", 0xb | WR_PREFIX},
612 { "wr12", 0xc | WR_PREFIX}, {"wr13", 0xd | WR_PREFIX},
613 { "wr14", 0xe | WR_PREFIX}, {"wr15", 0xf | WR_PREFIX},
614 { "wcid", 0x0 | WC_PREFIX}, {"wcon", 0x1 | WC_PREFIX},
615 {"wcssf", 0x2 | WC_PREFIX}, {"wcasf", 0x3 | WC_PREFIX},
616 {"wcgr0", 0x8 | WC_PREFIX}, {"wcgr1", 0x9 | WC_PREFIX},
617 {"wcgr2", 0xa | WC_PREFIX}, {"wcgr3", 0xb | WC_PREFIX},
619 { "wR0", 0x0 | WR_PREFIX}, {"wR1", 0x1 | WR_PREFIX},
620 { "wR2", 0x2 | WR_PREFIX}, {"wR3", 0x3 | WR_PREFIX},
621 { "wR4", 0x4 | WR_PREFIX}, {"wR5", 0x5 | WR_PREFIX},
622 { "wR6", 0x6 | WR_PREFIX}, {"wR7", 0x7 | WR_PREFIX},
623 { "wR8", 0x8 | WR_PREFIX}, {"wR9", 0x9 | WR_PREFIX},
624 { "wR10", 0xa | WR_PREFIX}, {"wR11", 0xb | WR_PREFIX},
625 { "wR12", 0xc | WR_PREFIX}, {"wR13", 0xd | WR_PREFIX},
626 { "wR14", 0xe | WR_PREFIX}, {"wR15", 0xf | WR_PREFIX},
627 { "wCID", 0x0 | WC_PREFIX}, {"wCon", 0x1 | WC_PREFIX},
628 {"wCSSF", 0x2 | WC_PREFIX}, {"wCASF", 0x3 | WC_PREFIX},
629 {"wCGR0", 0x8 | WC_PREFIX}, {"wCGR1", 0x9 | WC_PREFIX},
630 {"wCGR2", 0xa | WC_PREFIX}, {"wCGR3", 0xb | WC_PREFIX},
634 /* Co-processor Numbers. */
635 static const struct reg_entry cp_table[] =
637 {"p0", 0}, {"p1", 1}, {"p2", 2}, {"p3", 3},
638 {"p4", 4}, {"p5", 5}, {"p6", 6}, {"p7", 7},
639 {"p8", 8}, {"p9", 9}, {"p10", 10}, {"p11", 11},
640 {"p12", 12}, {"p13", 13}, {"p14", 14}, {"p15", 15},
644 /* Co-processor Register Numbers. */
645 static const struct reg_entry cn_table[] =
647 {"c0", 0}, {"c1", 1}, {"c2", 2}, {"c3", 3},
648 {"c4", 4}, {"c5", 5}, {"c6", 6}, {"c7", 7},
649 {"c8", 8}, {"c9", 9}, {"c10", 10}, {"c11", 11},
650 {"c12", 12}, {"c13", 13}, {"c14", 14}, {"c15", 15},
651 /* Not really valid, but kept for back-wards compatibility. */
652 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
653 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
654 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
655 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
660 static const struct reg_entry fn_table[] =
662 {"f0", 0}, {"f1", 1}, {"f2", 2}, {"f3", 3},
663 {"f4", 4}, {"f5", 5}, {"f6", 6}, {"f7", 7},
667 /* VFP SP Registers. */
668 static const struct reg_entry sn_table[] =
670 {"s0", 0}, {"s1", 1}, {"s2", 2}, {"s3", 3},
671 {"s4", 4}, {"s5", 5}, {"s6", 6}, {"s7", 7},
672 {"s8", 8}, {"s9", 9}, {"s10", 10}, {"s11", 11},
673 {"s12", 12}, {"s13", 13}, {"s14", 14}, {"s15", 15},
674 {"s16", 16}, {"s17", 17}, {"s18", 18}, {"s19", 19},
675 {"s20", 20}, {"s21", 21}, {"s22", 22}, {"s23", 23},
676 {"s24", 24}, {"s25", 25}, {"s26", 26}, {"s27", 27},
677 {"s28", 28}, {"s29", 29}, {"s30", 30}, {"s31", 31},
681 /* VFP DP Registers. */
682 static const struct reg_entry dn_table[] =
684 {"d0", 0}, {"d1", 1}, {"d2", 2}, {"d3", 3},
685 {"d4", 4}, {"d5", 5}, {"d6", 6}, {"d7", 7},
686 {"d8", 8}, {"d9", 9}, {"d10", 10}, {"d11", 11},
687 {"d12", 12}, {"d13", 13}, {"d14", 14}, {"d15", 15},
691 /* Maverick DSP coprocessor registers. */
692 static const struct reg_entry mav_mvf_table[] =
694 {"mvf0", 0}, {"mvf1", 1}, {"mvf2", 2}, {"mvf3", 3},
695 {"mvf4", 4}, {"mvf5", 5}, {"mvf6", 6}, {"mvf7", 7},
696 {"mvf8", 8}, {"mvf9", 9}, {"mvf10", 10}, {"mvf11", 11},
697 {"mvf12", 12}, {"mvf13", 13}, {"mvf14", 14}, {"mvf15", 15},
701 static const struct reg_entry mav_mvd_table[] =
703 {"mvd0", 0}, {"mvd1", 1}, {"mvd2", 2}, {"mvd3", 3},
704 {"mvd4", 4}, {"mvd5", 5}, {"mvd6", 6}, {"mvd7", 7},
705 {"mvd8", 8}, {"mvd9", 9}, {"mvd10", 10}, {"mvd11", 11},
706 {"mvd12", 12}, {"mvd13", 13}, {"mvd14", 14}, {"mvd15", 15},
710 static const struct reg_entry mav_mvfx_table[] =
712 {"mvfx0", 0}, {"mvfx1", 1}, {"mvfx2", 2}, {"mvfx3", 3},
713 {"mvfx4", 4}, {"mvfx5", 5}, {"mvfx6", 6}, {"mvfx7", 7},
714 {"mvfx8", 8}, {"mvfx9", 9}, {"mvfx10", 10}, {"mvfx11", 11},
715 {"mvfx12", 12}, {"mvfx13", 13}, {"mvfx14", 14}, {"mvfx15", 15},
719 static const struct reg_entry mav_mvdx_table[] =
721 {"mvdx0", 0}, {"mvdx1", 1}, {"mvdx2", 2}, {"mvdx3", 3},
722 {"mvdx4", 4}, {"mvdx5", 5}, {"mvdx6", 6}, {"mvdx7", 7},
723 {"mvdx8", 8}, {"mvdx9", 9}, {"mvdx10", 10}, {"mvdx11", 11},
724 {"mvdx12", 12}, {"mvdx13", 13}, {"mvdx14", 14}, {"mvdx15", 15},
728 static const struct reg_entry mav_mvax_table[] =
730 {"mvax0", 0}, {"mvax1", 1}, {"mvax2", 2}, {"mvax3", 3},
734 static const struct reg_entry mav_dspsc_table[] =
742 const struct reg_entry *names;
744 struct hash_control *htab;
745 const char *expected;
748 struct reg_map all_reg_maps[] =
750 {rn_table, 15, NULL, N_("ARM register expected")},
751 {cp_table, 15, NULL, N_("bad or missing co-processor number")},
752 {cn_table, 15, NULL, N_("co-processor register expected")},
753 {fn_table, 7, NULL, N_("FPA register expected")},
754 {sn_table, 31, NULL, N_("VFP single precision register expected")},
755 {dn_table, 15, NULL, N_("VFP double precision register expected")},
756 {mav_mvf_table, 15, NULL, N_("Maverick MVF register expected")},
757 {mav_mvd_table, 15, NULL, N_("Maverick MVD register expected")},
758 {mav_mvfx_table, 15, NULL, N_("Maverick MVFX register expected")},
759 {mav_mvdx_table, 15, NULL, N_("Maverick MVFX register expected")},
760 {mav_mvax_table, 3, NULL, N_("Maverick MVAX register expected")},
761 {mav_dspsc_table, 0, NULL, N_("Maverick DSPSC register expected")},
762 {iwmmxt_table, 23, NULL, N_("Intel Wireless MMX technology register expected")},
765 /* Enumeration matching entries in table above. */
769 #define REG_TYPE_FIRST REG_TYPE_RN
781 REG_TYPE_IWMMXT = 12,
786 /* Functions called by parser. */
787 /* ARM instructions. */
788 static void do_arit PARAMS ((char *));
789 static void do_cmp PARAMS ((char *));
790 static void do_mov PARAMS ((char *));
791 static void do_ldst PARAMS ((char *));
792 static void do_ldstt PARAMS ((char *));
793 static void do_ldmstm PARAMS ((char *));
794 static void do_branch PARAMS ((char *));
795 static void do_swi PARAMS ((char *));
797 /* Pseudo Op codes. */
798 static void do_adr PARAMS ((char *));
799 static void do_adrl PARAMS ((char *));
800 static void do_empty PARAMS ((char *));
803 static void do_mul PARAMS ((char *));
804 static void do_mla PARAMS ((char *));
807 static void do_swap PARAMS ((char *));
810 static void do_msr PARAMS ((char *));
811 static void do_mrs PARAMS ((char *));
814 static void do_mull PARAMS ((char *));
817 static void do_ldstv4 PARAMS ((char *));
820 static void do_bx PARAMS ((char *));
823 static void do_blx PARAMS ((char *));
824 static void do_bkpt PARAMS ((char *));
825 static void do_clz PARAMS ((char *));
826 static void do_lstc2 PARAMS ((char *));
827 static void do_cdp2 PARAMS ((char *));
828 static void do_co_reg2 PARAMS ((char *));
831 static void do_smla PARAMS ((char *));
832 static void do_smlal PARAMS ((char *));
833 static void do_smul PARAMS ((char *));
834 static void do_qadd PARAMS ((char *));
837 static void do_pld PARAMS ((char *));
838 static void do_ldrd PARAMS ((char *));
839 static void do_co_reg2c PARAMS ((char *));
842 static void do_bxj PARAMS ((char *));
844 /* Coprocessor Instructions. */
845 static void do_cdp PARAMS ((char *));
846 static void do_lstc PARAMS ((char *));
847 static void do_co_reg PARAMS ((char *));
849 /* FPA instructions. */
850 static void do_fpa_ctrl PARAMS ((char *));
851 static void do_fpa_ldst PARAMS ((char *));
852 static void do_fpa_ldmstm PARAMS ((char *));
853 static void do_fpa_dyadic PARAMS ((char *));
854 static void do_fpa_monadic PARAMS ((char *));
855 static void do_fpa_cmp PARAMS ((char *));
856 static void do_fpa_from_reg PARAMS ((char *));
857 static void do_fpa_to_reg PARAMS ((char *));
859 /* VFP instructions. */
860 static void do_vfp_sp_monadic PARAMS ((char *));
861 static void do_vfp_dp_monadic PARAMS ((char *));
862 static void do_vfp_sp_dyadic PARAMS ((char *));
863 static void do_vfp_dp_dyadic PARAMS ((char *));
864 static void do_vfp_reg_from_sp PARAMS ((char *));
865 static void do_vfp_sp_from_reg PARAMS ((char *));
866 static void do_vfp_sp_reg2 PARAMS ((char *));
867 static void do_vfp_reg_from_dp PARAMS ((char *));
868 static void do_vfp_reg2_from_dp PARAMS ((char *));
869 static void do_vfp_dp_from_reg PARAMS ((char *));
870 static void do_vfp_dp_from_reg2 PARAMS ((char *));
871 static void do_vfp_reg_from_ctrl PARAMS ((char *));
872 static void do_vfp_ctrl_from_reg PARAMS ((char *));
873 static void do_vfp_sp_ldst PARAMS ((char *));
874 static void do_vfp_dp_ldst PARAMS ((char *));
875 static void do_vfp_sp_ldstmia PARAMS ((char *));
876 static void do_vfp_sp_ldstmdb PARAMS ((char *));
877 static void do_vfp_dp_ldstmia PARAMS ((char *));
878 static void do_vfp_dp_ldstmdb PARAMS ((char *));
879 static void do_vfp_xp_ldstmia PARAMS ((char *));
880 static void do_vfp_xp_ldstmdb PARAMS ((char *));
881 static void do_vfp_sp_compare_z PARAMS ((char *));
882 static void do_vfp_dp_compare_z PARAMS ((char *));
883 static void do_vfp_dp_sp_cvt PARAMS ((char *));
884 static void do_vfp_sp_dp_cvt PARAMS ((char *));
887 static void do_xsc_mia PARAMS ((char *));
888 static void do_xsc_mar PARAMS ((char *));
889 static void do_xsc_mra PARAMS ((char *));
892 static void do_mav_binops PARAMS ((char *, int, enum arm_reg_type,
894 static void do_mav_binops_1a PARAMS ((char *));
895 static void do_mav_binops_1b PARAMS ((char *));
896 static void do_mav_binops_1c PARAMS ((char *));
897 static void do_mav_binops_1d PARAMS ((char *));
898 static void do_mav_binops_1e PARAMS ((char *));
899 static void do_mav_binops_1f PARAMS ((char *));
900 static void do_mav_binops_1g PARAMS ((char *));
901 static void do_mav_binops_1h PARAMS ((char *));
902 static void do_mav_binops_1i PARAMS ((char *));
903 static void do_mav_binops_1j PARAMS ((char *));
904 static void do_mav_binops_1k PARAMS ((char *));
905 static void do_mav_binops_1l PARAMS ((char *));
906 static void do_mav_binops_1m PARAMS ((char *));
907 static void do_mav_binops_1n PARAMS ((char *));
908 static void do_mav_binops_1o PARAMS ((char *));
909 static void do_mav_binops_2a PARAMS ((char *));
910 static void do_mav_binops_2b PARAMS ((char *));
911 static void do_mav_binops_2c PARAMS ((char *));
912 static void do_mav_binops_3a PARAMS ((char *));
913 static void do_mav_binops_3b PARAMS ((char *));
914 static void do_mav_binops_3c PARAMS ((char *));
915 static void do_mav_binops_3d PARAMS ((char *));
916 static void do_mav_triple PARAMS ((char *, int, enum arm_reg_type,
919 static void do_mav_triple_4a PARAMS ((char *));
920 static void do_mav_triple_4b PARAMS ((char *));
921 static void do_mav_triple_5a PARAMS ((char *));
922 static void do_mav_triple_5b PARAMS ((char *));
923 static void do_mav_triple_5c PARAMS ((char *));
924 static void do_mav_triple_5d PARAMS ((char *));
925 static void do_mav_triple_5e PARAMS ((char *));
926 static void do_mav_triple_5f PARAMS ((char *));
927 static void do_mav_triple_5g PARAMS ((char *));
928 static void do_mav_triple_5h PARAMS ((char *));
929 static void do_mav_quad PARAMS ((char *, int, enum arm_reg_type,
933 static void do_mav_quad_6a PARAMS ((char *));
934 static void do_mav_quad_6b PARAMS ((char *));
935 static void do_mav_dspsc_1 PARAMS ((char *));
936 static void do_mav_dspsc_2 PARAMS ((char *));
937 static void do_mav_shift PARAMS ((char *, enum arm_reg_type,
939 static void do_mav_shift_1 PARAMS ((char *));
940 static void do_mav_shift_2 PARAMS ((char *));
941 static void do_mav_ldst PARAMS ((char *, enum arm_reg_type));
942 static void do_mav_ldst_1 PARAMS ((char *));
943 static void do_mav_ldst_2 PARAMS ((char *));
944 static void do_mav_ldst_3 PARAMS ((char *));
945 static void do_mav_ldst_4 PARAMS ((char *));
947 static int mav_reg_required_here PARAMS ((char **, int,
949 static int mav_parse_offset PARAMS ((char **, int *));
951 static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *,
953 static int arm_reg_parse PARAMS ((char **, struct hash_control *));
954 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
955 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
956 static void symbol_locate PARAMS ((symbolS *, const char *, segT, valueT,
958 static int add_to_lit_pool PARAMS ((void));
959 static unsigned validate_immediate PARAMS ((unsigned));
960 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
962 static int validate_offset_imm PARAMS ((unsigned int, int));
963 static void opcode_select PARAMS ((int));
964 static void end_of_line PARAMS ((char *));
965 static int reg_required_here PARAMS ((char **, int));
966 static int psr_required_here PARAMS ((char **));
967 static int co_proc_number PARAMS ((char **));
968 static int cp_opc_expr PARAMS ((char **, int, int));
969 static int cp_reg_required_here PARAMS ((char **, int));
970 static int fp_reg_required_here PARAMS ((char **, int));
971 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
972 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
973 static void vfp_sp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
974 static void vfp_dp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
975 static long vfp_sp_reg_list PARAMS ((char **, enum vfp_sp_reg_pos));
976 static long vfp_dp_reg_list PARAMS ((char **));
977 static int vfp_psr_required_here PARAMS ((char **str));
978 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
979 static int cp_address_offset PARAMS ((char **));
980 static int cp_address_required_here PARAMS ((char **, int));
981 static int my_get_float_expression PARAMS ((char **));
982 static int skip_past_comma PARAMS ((char **));
983 static int walk_no_bignums PARAMS ((symbolS *));
984 static int negate_data_op PARAMS ((unsigned long *, unsigned long));
985 static int data_op2 PARAMS ((char **));
986 static int fp_op2 PARAMS ((char **));
987 static long reg_list PARAMS ((char **));
988 static void thumb_load_store PARAMS ((char *, int, int));
989 static int decode_shift PARAMS ((char **, int));
990 static int ldst_extend PARAMS ((char **));
991 static int ldst_extend_v4 PARAMS ((char **));
992 static void thumb_add_sub PARAMS ((char *, int));
993 static void insert_reg PARAMS ((const struct reg_entry *,
994 struct hash_control *));
995 static void thumb_shift PARAMS ((char *, int));
996 static void thumb_mov_compare PARAMS ((char *, int));
997 static void build_arm_ops_hsh PARAMS ((void));
998 static void set_constant_flonums PARAMS ((void));
999 static valueT md_chars_to_number PARAMS ((char *, int));
1000 static void build_reg_hsh PARAMS ((struct reg_map *));
1001 static void insert_reg_alias PARAMS ((char *, int, struct hash_control *));
1002 static int create_register_alias PARAMS ((char *, char *));
1003 static void output_inst PARAMS ((const char *));
1004 static int accum0_required_here PARAMS ((char **));
1005 static int ld_mode_required_here PARAMS ((char **));
1006 static void do_branch25 PARAMS ((char *));
1007 static symbolS * find_real_start PARAMS ((symbolS *));
1009 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
1012 static int wreg_required_here PARAMS ((char **, int, enum wreg_type));
1013 static void do_iwmmxt_byte_addr PARAMS ((char *));
1014 static void do_iwmmxt_tandc PARAMS ((char *));
1015 static void do_iwmmxt_tbcst PARAMS ((char *));
1016 static void do_iwmmxt_textrc PARAMS ((char *));
1017 static void do_iwmmxt_textrm PARAMS ((char *));
1018 static void do_iwmmxt_tinsr PARAMS ((char *));
1019 static void do_iwmmxt_tmcr PARAMS ((char *));
1020 static void do_iwmmxt_tmcrr PARAMS ((char *));
1021 static void do_iwmmxt_tmia PARAMS ((char *));
1022 static void do_iwmmxt_tmovmsk PARAMS ((char *));
1023 static void do_iwmmxt_tmrc PARAMS ((char *));
1024 static void do_iwmmxt_tmrrc PARAMS ((char *));
1025 static void do_iwmmxt_torc PARAMS ((char *));
1026 static void do_iwmmxt_waligni PARAMS ((char *));
1027 static void do_iwmmxt_wmov PARAMS ((char *));
1028 static void do_iwmmxt_word_addr PARAMS ((char *));
1029 static void do_iwmmxt_wrwr PARAMS ((char *));
1030 static void do_iwmmxt_wrwrwcg PARAMS ((char *));
1031 static void do_iwmmxt_wrwrwr PARAMS ((char *));
1032 static void do_iwmmxt_wshufh PARAMS ((char *));
1033 static void do_iwmmxt_wzero PARAMS ((char *));
1034 static int cp_byte_address_offset PARAMS ((char **));
1035 static int cp_byte_address_required_here PARAMS ((char **));
1037 /* ARM instructions take 4bytes in the object file, Thumb instructions
1041 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
1042 #define MAV_MODE1 0x100c
1044 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
1045 #define MAV_MODE2 0x0c10
1047 /* "INSN<cond> X,Y" where X:0, Y:bit16. */
1048 #define MAV_MODE3 0x1000
1050 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
1051 #define MAV_MODE4 0x0c0010
1053 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
1054 #define MAV_MODE5 0x00100c
1056 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
1057 #define MAV_MODE6 0x00100c05
1061 /* Basic string to match. */
1062 const char * template;
1064 /* Basic instruction code. */
1065 unsigned long value;
1067 /* Offset into the template where the condition code (if any) will be.
1068 If zero, then the instruction is never conditional. */
1069 unsigned cond_offset;
1071 /* Which architecture variant provides this instruction. */
1072 unsigned long variant;
1074 /* Function to call to parse args. */
1075 void (* parms) PARAMS ((char *));
1078 static const struct asm_opcode insns[] =
1080 /* Core ARM Instructions. */
1081 {"and", 0xe0000000, 3, ARM_EXT_V1, do_arit},
1082 {"ands", 0xe0100000, 3, ARM_EXT_V1, do_arit},
1083 {"eor", 0xe0200000, 3, ARM_EXT_V1, do_arit},
1084 {"eors", 0xe0300000, 3, ARM_EXT_V1, do_arit},
1085 {"sub", 0xe0400000, 3, ARM_EXT_V1, do_arit},
1086 {"subs", 0xe0500000, 3, ARM_EXT_V1, do_arit},
1087 {"rsb", 0xe0600000, 3, ARM_EXT_V1, do_arit},
1088 {"rsbs", 0xe0700000, 3, ARM_EXT_V1, do_arit},
1089 {"add", 0xe0800000, 3, ARM_EXT_V1, do_arit},
1090 {"adds", 0xe0900000, 3, ARM_EXT_V1, do_arit},
1091 {"adc", 0xe0a00000, 3, ARM_EXT_V1, do_arit},
1092 {"adcs", 0xe0b00000, 3, ARM_EXT_V1, do_arit},
1093 {"sbc", 0xe0c00000, 3, ARM_EXT_V1, do_arit},
1094 {"sbcs", 0xe0d00000, 3, ARM_EXT_V1, do_arit},
1095 {"rsc", 0xe0e00000, 3, ARM_EXT_V1, do_arit},
1096 {"rscs", 0xe0f00000, 3, ARM_EXT_V1, do_arit},
1097 {"orr", 0xe1800000, 3, ARM_EXT_V1, do_arit},
1098 {"orrs", 0xe1900000, 3, ARM_EXT_V1, do_arit},
1099 {"bic", 0xe1c00000, 3, ARM_EXT_V1, do_arit},
1100 {"bics", 0xe1d00000, 3, ARM_EXT_V1, do_arit},
1102 {"tst", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
1103 {"tsts", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
1104 {"tstp", 0xe110f000, 3, ARM_EXT_V1, do_cmp},
1105 {"teq", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
1106 {"teqs", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
1107 {"teqp", 0xe130f000, 3, ARM_EXT_V1, do_cmp},
1108 {"cmp", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
1109 {"cmps", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
1110 {"cmpp", 0xe150f000, 3, ARM_EXT_V1, do_cmp},
1111 {"cmn", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
1112 {"cmns", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
1113 {"cmnp", 0xe170f000, 3, ARM_EXT_V1, do_cmp},
1115 {"mov", 0xe1a00000, 3, ARM_EXT_V1, do_mov},
1116 {"movs", 0xe1b00000, 3, ARM_EXT_V1, do_mov},
1117 {"mvn", 0xe1e00000, 3, ARM_EXT_V1, do_mov},
1118 {"mvns", 0xe1f00000, 3, ARM_EXT_V1, do_mov},
1120 {"ldr", 0xe4100000, 3, ARM_EXT_V1, do_ldst},
1121 {"ldrb", 0xe4500000, 3, ARM_EXT_V1, do_ldst},
1122 {"ldrt", 0xe4300000, 3, ARM_EXT_V1, do_ldstt},
1123 {"ldrbt", 0xe4700000, 3, ARM_EXT_V1, do_ldstt},
1124 {"str", 0xe4000000, 3, ARM_EXT_V1, do_ldst},
1125 {"strb", 0xe4400000, 3, ARM_EXT_V1, do_ldst},
1126 {"strt", 0xe4200000, 3, ARM_EXT_V1, do_ldstt},
1127 {"strbt", 0xe4600000, 3, ARM_EXT_V1, do_ldstt},
1129 {"stmia", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
1130 {"stmib", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
1131 {"stmda", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
1132 {"stmdb", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
1133 {"stmfd", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
1134 {"stmfa", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
1135 {"stmea", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
1136 {"stmed", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
1138 {"ldmia", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
1139 {"ldmib", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
1140 {"ldmda", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
1141 {"ldmdb", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
1142 {"ldmfd", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
1143 {"ldmfa", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
1144 {"ldmea", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
1145 {"ldmed", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
1147 {"swi", 0xef000000, 3, ARM_EXT_V1, do_swi},
1149 /* XXX This is the wrong place to do this. Think multi-arch. */
1150 {"bl", 0xeb000000, 2, ARM_EXT_V1, do_branch},
1151 {"b", 0xea000000, 1, ARM_EXT_V1, do_branch},
1153 {"bl", 0xebfffffe, 2, ARM_EXT_V1, do_branch},
1154 {"b", 0xeafffffe, 1, ARM_EXT_V1, do_branch},
1158 {"adr", 0xe28f0000, 3, ARM_EXT_V1, do_adr},
1159 {"adrl", 0xe28f0000, 3, ARM_EXT_V1, do_adrl},
1160 {"nop", 0xe1a00000, 3, ARM_EXT_V1, do_empty},
1162 /* ARM 2 multiplies. */
1163 {"mul", 0xe0000090, 3, ARM_EXT_V2, do_mul},
1164 {"muls", 0xe0100090, 3, ARM_EXT_V2, do_mul},
1165 {"mla", 0xe0200090, 3, ARM_EXT_V2, do_mla},
1166 {"mlas", 0xe0300090, 3, ARM_EXT_V2, do_mla},
1168 /* Generic copressor instructions. */
1169 {"cdp", 0xee000000, 3, ARM_EXT_V2, do_cdp},
1170 {"ldc", 0xec100000, 3, ARM_EXT_V2, do_lstc},
1171 {"ldcl", 0xec500000, 3, ARM_EXT_V2, do_lstc},
1172 {"stc", 0xec000000, 3, ARM_EXT_V2, do_lstc},
1173 {"stcl", 0xec400000, 3, ARM_EXT_V2, do_lstc},
1174 {"mcr", 0xee000010, 3, ARM_EXT_V2, do_co_reg},
1175 {"mrc", 0xee100010, 3, ARM_EXT_V2, do_co_reg},
1177 /* ARM 3 - swp instructions. */
1178 {"swp", 0xe1000090, 3, ARM_EXT_V2S, do_swap},
1179 {"swpb", 0xe1400090, 3, ARM_EXT_V2S, do_swap},
1181 /* ARM 6 Status register instructions. */
1182 {"mrs", 0xe10f0000, 3, ARM_EXT_V3, do_mrs},
1183 {"msr", 0xe120f000, 3, ARM_EXT_V3, do_msr},
1184 /* ScottB: our code uses 0xe128f000 for msr.
1185 NickC: but this is wrong because the bits 16 through 19 are
1186 handled by the PSR_xxx defines above. */
1188 /* ARM 7M long multiplies. */
1189 {"smull", 0xe0c00090, 5, ARM_EXT_V3M, do_mull},
1190 {"smulls", 0xe0d00090, 5, ARM_EXT_V3M, do_mull},
1191 {"umull", 0xe0800090, 5, ARM_EXT_V3M, do_mull},
1192 {"umulls", 0xe0900090, 5, ARM_EXT_V3M, do_mull},
1193 {"smlal", 0xe0e00090, 5, ARM_EXT_V3M, do_mull},
1194 {"smlals", 0xe0f00090, 5, ARM_EXT_V3M, do_mull},
1195 {"umlal", 0xe0a00090, 5, ARM_EXT_V3M, do_mull},
1196 {"umlals", 0xe0b00090, 5, ARM_EXT_V3M, do_mull},
1198 /* ARM Architecture 4. */
1199 {"ldrh", 0xe01000b0, 3, ARM_EXT_V4, do_ldstv4},
1200 {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4, do_ldstv4},
1201 {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4, do_ldstv4},
1202 {"strh", 0xe00000b0, 3, ARM_EXT_V4, do_ldstv4},
1204 /* ARM Architecture 4T. */
1205 /* Note: bx (and blx) are required on V5, even if the processor does
1206 not support Thumb. */
1207 {"bx", 0xe12fff10, 2, ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1209 /* ARM Architecture 5T. */
1210 /* Note: blx has 2 variants, so the .value is set dynamically.
1211 Only one of the variants has conditional execution. */
1212 {"blx", 0xe0000000, 3, ARM_EXT_V5, do_blx},
1213 {"clz", 0xe16f0f10, 3, ARM_EXT_V5, do_clz},
1214 {"bkpt", 0xe1200070, 0, ARM_EXT_V5, do_bkpt},
1215 {"ldc2", 0xfc100000, 0, ARM_EXT_V5, do_lstc2},
1216 {"ldc2l", 0xfc500000, 0, ARM_EXT_V5, do_lstc2},
1217 {"stc2", 0xfc000000, 0, ARM_EXT_V5, do_lstc2},
1218 {"stc2l", 0xfc400000, 0, ARM_EXT_V5, do_lstc2},
1219 {"cdp2", 0xfe000000, 0, ARM_EXT_V5, do_cdp2},
1220 {"mcr2", 0xfe000010, 0, ARM_EXT_V5, do_co_reg2},
1221 {"mrc2", 0xfe100010, 0, ARM_EXT_V5, do_co_reg2},
1223 /* ARM Architecture 5TExP. */
1224 {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP, do_smla},
1225 {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP, do_smla},
1226 {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP, do_smla},
1227 {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP, do_smla},
1229 {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP, do_smla},
1230 {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP, do_smla},
1232 {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP, do_smlal},
1233 {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP, do_smlal},
1234 {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP, do_smlal},
1235 {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP, do_smlal},
1237 {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP, do_smul},
1238 {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP, do_smul},
1239 {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP, do_smul},
1240 {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP, do_smul},
1242 {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP, do_smul},
1243 {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP, do_smul},
1245 {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP, do_qadd},
1246 {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP, do_qadd},
1247 {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP, do_qadd},
1248 {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP, do_qadd},
1250 /* ARM Architecture 5TE. */
1251 {"pld", 0xf450f000, 0, ARM_EXT_V5E, do_pld},
1252 {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E, do_ldrd},
1253 {"strd", 0xe00000f0, 3, ARM_EXT_V5E, do_ldrd},
1255 {"mcrr", 0xec400000, 4, ARM_EXT_V5E, do_co_reg2c},
1256 {"mrrc", 0xec500000, 4, ARM_EXT_V5E, do_co_reg2c},
1258 /* ARM Architecture 5TEJ. */
1259 {"bxj", 0xe12fff20, 3, ARM_EXT_V5J, do_bxj},
1261 /* Core FPA instruction set (V1). */
1262 {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1263 {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1264 {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1265 {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1267 {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1268 {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1269 {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1270 {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1272 {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1273 {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1274 {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1275 {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1277 {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1278 {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1279 {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1280 {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1281 {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1282 {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1283 {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1284 {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1285 {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1286 {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1287 {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1288 {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1290 {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1291 {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1292 {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1293 {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1294 {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1295 {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1296 {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1297 {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1298 {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1299 {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1300 {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1301 {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1303 {"abss", 0xee208100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1304 {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1305 {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1306 {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1307 {"absd", 0xee208180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1308 {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1309 {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1310 {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1311 {"abse", 0xee288100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1312 {"absep", 0xee288120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1313 {"absem", 0xee288140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1314 {"absez", 0xee288160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1316 {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1317 {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1318 {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1319 {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1320 {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1321 {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1322 {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1323 {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1324 {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1325 {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1326 {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1327 {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1329 {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1330 {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1331 {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1332 {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1333 {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1334 {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1335 {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1336 {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1337 {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1338 {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1339 {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1340 {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1342 {"logs", 0xee508100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1343 {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1344 {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1345 {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1346 {"logd", 0xee508180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1347 {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1348 {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1349 {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1350 {"loge", 0xee588100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1351 {"logep", 0xee588120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1352 {"logem", 0xee588140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1353 {"logez", 0xee588160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1355 {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1356 {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1357 {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1358 {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1359 {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1360 {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1361 {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1362 {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1363 {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1364 {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1365 {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1366 {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1368 {"exps", 0xee708100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1369 {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1370 {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1371 {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1372 {"expd", 0xee708180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1373 {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1374 {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1375 {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1376 {"expe", 0xee788100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1377 {"expep", 0xee788120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1378 {"expem", 0xee788140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1379 {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1381 {"sins", 0xee808100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1382 {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1383 {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1384 {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1385 {"sind", 0xee808180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1386 {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1387 {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1388 {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1389 {"sine", 0xee888100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1390 {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1391 {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1392 {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1394 {"coss", 0xee908100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1395 {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1396 {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1397 {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1398 {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1399 {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1400 {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1401 {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1402 {"cose", 0xee988100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1403 {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1404 {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1405 {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1407 {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1408 {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1409 {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1410 {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1411 {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1412 {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1413 {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1414 {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1415 {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1416 {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1417 {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1418 {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1420 {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1421 {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1422 {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1423 {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1424 {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1425 {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1426 {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1427 {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1428 {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1429 {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1430 {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1431 {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1433 {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1434 {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1435 {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1436 {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1437 {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1438 {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1439 {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1440 {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1441 {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1442 {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1443 {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1444 {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1446 {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1447 {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1448 {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1449 {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1450 {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1451 {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1452 {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1453 {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1454 {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1455 {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1456 {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1457 {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1459 {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1460 {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1461 {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1462 {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1463 {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1464 {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1465 {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1466 {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1467 {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1468 {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1469 {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1470 {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1472 {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1473 {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1474 {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1475 {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1476 {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1477 {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1478 {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1479 {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1480 {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1481 {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1482 {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1483 {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1485 {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1486 {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1487 {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1488 {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1489 {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1490 {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1491 {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1492 {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1493 {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1494 {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1495 {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1496 {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1498 {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1499 {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1500 {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1501 {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1502 {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1503 {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1504 {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1505 {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1506 {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1507 {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1508 {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1509 {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1511 {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1512 {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1513 {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1514 {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1515 {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1516 {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1517 {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1518 {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1519 {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1520 {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1521 {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1522 {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1524 {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1525 {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1526 {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1527 {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1528 {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1529 {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1530 {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1531 {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1532 {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1533 {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1534 {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1535 {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1537 {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1538 {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1539 {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1540 {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1541 {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1542 {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1543 {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1544 {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1545 {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1546 {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1547 {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1548 {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1550 {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1551 {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1552 {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1553 {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1554 {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1555 {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1556 {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1557 {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1558 {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1559 {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1560 {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1561 {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1563 {"pows", 0xee600100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1564 {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1565 {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1566 {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1567 {"powd", 0xee600180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1568 {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1569 {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1570 {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1571 {"powe", 0xee680100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1572 {"powep", 0xee680120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1573 {"powem", 0xee680140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1574 {"powez", 0xee680160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1576 {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1577 {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1578 {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1579 {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1580 {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1581 {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1582 {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1583 {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1584 {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1585 {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1586 {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1587 {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1589 {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1590 {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1591 {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1592 {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1593 {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1594 {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1595 {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1596 {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1597 {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1598 {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1599 {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1600 {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1602 {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1603 {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1604 {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1605 {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1606 {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1607 {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1608 {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1609 {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1610 {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1611 {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1612 {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1613 {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1615 {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1616 {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1617 {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1618 {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1619 {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1620 {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1621 {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1622 {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1623 {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1624 {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1625 {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1626 {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1628 {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1629 {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1630 {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1631 {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1632 {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1633 {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1634 {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1635 {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1636 {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1637 {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1638 {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1639 {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1641 {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1642 {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1643 {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1644 {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1645 {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1646 {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1647 {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1648 {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1649 {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1650 {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1651 {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1652 {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1654 {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1655 {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1656 {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1657 {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1658 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1659 not be an optional suffix, but part of the instruction. To be
1660 compatible, we accept either. */
1661 {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
1662 {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
1664 {"flts", 0xee000110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1665 {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1666 {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1667 {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1668 {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1669 {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1670 {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1671 {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1672 {"flte", 0xee080110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1673 {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1674 {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1675 {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1677 /* The implementation of the FIX instruction is broken on some
1678 assemblers, in that it accepts a precision specifier as well as a
1679 rounding specifier, despite the fact that this is meaningless.
1680 To be more compatible, we accept it as well, though of course it
1681 does not set any bits. */
1682 {"fix", 0xee100110, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1683 {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1684 {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1685 {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1686 {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1687 {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1688 {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1689 {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1690 {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1691 {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1692 {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1693 {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1694 {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1696 /* Instructions that were new with the real FPA, call them V2. */
1697 {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1698 {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1699 {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1700 {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1701 {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1702 {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1704 /* VFP V1xD (single precision). */
1705 /* Moves and type conversions. */
1706 {"fcpys", 0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1707 {"fmrs", 0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1708 {"fmsr", 0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1709 {"fmstat", 0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1710 {"fsitos", 0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1711 {"fuitos", 0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1712 {"ftosis", 0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1713 {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1714 {"ftouis", 0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1715 {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1716 {"fmrx", 0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1717 {"fmxr", 0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1719 /* Memory operations. */
1720 {"flds", 0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1721 {"fsts", 0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1722 {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1723 {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1724 {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1725 {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1726 {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1727 {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1728 {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1729 {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1730 {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1731 {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1732 {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1733 {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1734 {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1735 {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1736 {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1737 {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1739 /* Monadic operations. */
1740 {"fabss", 0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1741 {"fnegs", 0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1742 {"fsqrts", 0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1744 /* Dyadic operations. */
1745 {"fadds", 0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1746 {"fsubs", 0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1747 {"fmuls", 0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1748 {"fdivs", 0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1749 {"fmacs", 0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1750 {"fmscs", 0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1751 {"fnmuls", 0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1752 {"fnmacs", 0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1753 {"fnmscs", 0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1756 {"fcmps", 0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1757 {"fcmpzs", 0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1758 {"fcmpes", 0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1759 {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1761 /* VFP V1 (Double precision). */
1762 /* Moves and type conversions. */
1763 {"fcpyd", 0xeeb00b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1764 {"fcvtds", 0xeeb70ac0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1765 {"fcvtsd", 0xeeb70bc0, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1766 {"fmdhr", 0xee200b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
1767 {"fmdlr", 0xee000b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
1768 {"fmrdh", 0xee300b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
1769 {"fmrdl", 0xee100b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
1770 {"fsitod", 0xeeb80bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1771 {"fuitod", 0xeeb80b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1772 {"ftosid", 0xeebd0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1773 {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1774 {"ftouid", 0xeebc0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1775 {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1777 /* Memory operations. */
1778 {"fldd", 0xed100b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
1779 {"fstd", 0xed000b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
1780 {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1781 {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1782 {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1783 {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1784 {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1785 {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1786 {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1787 {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1789 /* Monadic operations. */
1790 {"fabsd", 0xeeb00bc0, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1791 {"fnegd", 0xeeb10b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1792 {"fsqrtd", 0xeeb10bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1794 /* Dyadic operations. */
1795 {"faddd", 0xee300b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1796 {"fsubd", 0xee300b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1797 {"fmuld", 0xee200b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1798 {"fdivd", 0xee800b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1799 {"fmacd", 0xee000b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1800 {"fmscd", 0xee100b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1801 {"fnmuld", 0xee200b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1802 {"fnmacd", 0xee000b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1803 {"fnmscd", 0xee100b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1806 {"fcmpd", 0xeeb40b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1807 {"fcmpzd", 0xeeb50b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
1808 {"fcmped", 0xeeb40bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1809 {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
1812 {"fmsrr", 0xec400a10, 5, FPU_VFP_EXT_V2, do_vfp_sp_reg2},
1813 {"fmrrs", 0xec500a10, 5, FPU_VFP_EXT_V2, do_vfp_sp_reg2},
1814 {"fmdrr", 0xec400b10, 5, FPU_VFP_EXT_V2, do_vfp_dp_from_reg2},
1815 {"fmrrd", 0xec500b10, 5, FPU_VFP_EXT_V2, do_vfp_reg2_from_dp},
1817 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
1818 {"mia", 0xee200010, 3, ARM_CEXT_XSCALE, do_xsc_mia},
1819 {"miaph", 0xee280010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1820 {"miabb", 0xee2c0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1821 {"miabt", 0xee2d0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1822 {"miatb", 0xee2e0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1823 {"miatt", 0xee2f0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1824 {"mar", 0xec400000, 3, ARM_CEXT_XSCALE, do_xsc_mar},
1825 {"mra", 0xec500000, 3, ARM_CEXT_XSCALE, do_xsc_mra},
1827 /* Intel Wireless MMX technology instructions. */
1828 {"tandcb", 0xee130130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1829 {"tandch", 0xee530130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1830 {"tandcw", 0xee930130, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tandc},
1831 {"tbcstb", 0xee400010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
1832 {"tbcsth", 0xee400050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
1833 {"tbcstw", 0xee400090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tbcst},
1834 {"textrcb", 0xee130170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
1835 {"textrch", 0xee530170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
1836 {"textrcw", 0xee930170, 7, ARM_CEXT_IWMMXT, do_iwmmxt_textrc},
1837 {"textrmub", 0xee100070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1838 {"textrmuh", 0xee500070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1839 {"textrmuw", 0xee900070, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1840 {"textrmsb", 0xee100078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1841 {"textrmsh", 0xee500078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1842 {"textrmsw", 0xee900078, 8, ARM_CEXT_IWMMXT, do_iwmmxt_textrm},
1843 {"tinsrb", 0xee600010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
1844 {"tinsrh", 0xee600050, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
1845 {"tinsrw", 0xee600090, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tinsr},
1846 {"tmcr", 0xee000110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmcr},
1847 {"tmcrr", 0xec400000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmcrr},
1848 {"tmia", 0xee200010, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1849 {"tmiaph", 0xee280010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1850 {"tmiabb", 0xee2c0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1851 {"tmiabt", 0xee2d0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1852 {"tmiatb", 0xee2e0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1853 {"tmiatt", 0xee2f0010, 6, ARM_CEXT_IWMMXT, do_iwmmxt_tmia},
1854 {"tmovmskb", 0xee100030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
1855 {"tmovmskh", 0xee500030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
1856 {"tmovmskw", 0xee900030, 8, ARM_CEXT_IWMMXT, do_iwmmxt_tmovmsk},
1857 {"tmrc", 0xee100110, 4, ARM_CEXT_IWMMXT, do_iwmmxt_tmrc},
1858 {"tmrrc", 0xec500000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_tmrrc},
1859 {"torcb", 0xee130150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
1860 {"torch", 0xee530150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
1861 {"torcw", 0xee930150, 5, ARM_CEXT_IWMMXT, do_iwmmxt_torc},
1862 {"waccb", 0xee0001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1863 {"wacch", 0xee4001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1864 {"waccw", 0xee8001c0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1865 {"waddbss", 0xee300180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1866 {"waddb", 0xee000180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1867 {"waddbus", 0xee100180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1868 {"waddhss", 0xee700180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1869 {"waddh", 0xee400180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1870 {"waddhus", 0xee500180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1871 {"waddwss", 0xeeb00180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1872 {"waddw", 0xee800180, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1873 {"waddwus", 0xee900180, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1874 {"waligni", 0xee000020, 7, ARM_CEXT_IWMMXT, do_iwmmxt_waligni},
1875 {"walignr0", 0xee800020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1876 {"walignr1", 0xee900020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1877 {"walignr2", 0xeea00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1878 {"walignr3", 0xeeb00020, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1879 {"wand", 0xee200000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1880 {"wandn", 0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1881 {"wavg2b", 0xee800000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1882 {"wavg2br", 0xee900000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1883 {"wavg2h", 0xeec00000, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1884 {"wavg2hr", 0xeed00000, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1885 {"wcmpeqb", 0xee000060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1886 {"wcmpeqh", 0xee400060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1887 {"wcmpeqw", 0xee800060, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1888 {"wcmpgtub", 0xee100060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1889 {"wcmpgtuh", 0xee500060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1890 {"wcmpgtuw", 0xee900060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1891 {"wcmpgtsb", 0xee300060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1892 {"wcmpgtsh", 0xee700060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1893 {"wcmpgtsw", 0xeeb00060, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1894 {"wldrb", 0xec100000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
1895 {"wldrh", 0xec100100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
1896 {"wldrw", 0xec100200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
1897 {"wldrd", 0xec100300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
1898 {"wmacs", 0xee600100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1899 {"wmacsz", 0xee700100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1900 {"wmacu", 0xee400100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1901 {"wmacuz", 0xee500100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1902 {"wmadds", 0xeea00100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1903 {"wmaddu", 0xee800100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1904 {"wmaxsb", 0xee200160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1905 {"wmaxsh", 0xee600160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1906 {"wmaxsw", 0xeea00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1907 {"wmaxub", 0xee000160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1908 {"wmaxuh", 0xee400160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1909 {"wmaxuw", 0xee800160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1910 {"wminsb", 0xee300160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1911 {"wminsh", 0xee700160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1912 {"wminsw", 0xeeb00160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1913 {"wminub", 0xee100160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1914 {"wminuh", 0xee500160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1915 {"wminuw", 0xee900160, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1916 {"wmov", 0xee000000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wmov},
1917 {"wmulsm", 0xee300100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1918 {"wmulsl", 0xee200100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1919 {"wmulum", 0xee100100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1920 {"wmulul", 0xee000100, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1921 {"wor", 0xee000000, 3, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1922 {"wpackhss", 0xee700080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1923 {"wpackhus", 0xee500080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1924 {"wpackwss", 0xeeb00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1925 {"wpackwus", 0xee900080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1926 {"wpackdss", 0xeef00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1927 {"wpackdus", 0xeed00080, 8, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1928 {"wrorh", 0xee700040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1929 {"wrorhg", 0xee700148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1930 {"wrorw", 0xeeb00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1931 {"wrorwg", 0xeeb00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1932 {"wrord", 0xeef00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1933 {"wrordg", 0xeef00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1934 {"wsadb", 0xee000120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1935 {"wsadbz", 0xee100120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1936 {"wsadh", 0xee400120, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1937 {"wsadhz", 0xee500120, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1938 {"wshufh", 0xee0001e0, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wshufh},
1939 {"wsllh", 0xee500040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1940 {"wsllhg", 0xee500148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1941 {"wsllw", 0xee900040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1942 {"wsllwg", 0xee900148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1943 {"wslld", 0xeed00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1944 {"wslldg", 0xeed00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1945 {"wsrah", 0xee400040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1946 {"wsrahg", 0xee400148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1947 {"wsraw", 0xee800040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1948 {"wsrawg", 0xee800148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1949 {"wsrad", 0xeec00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1950 {"wsradg", 0xeec00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1951 {"wsrlh", 0xee600040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1952 {"wsrlhg", 0xee600148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1953 {"wsrlw", 0xeea00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1954 {"wsrlwg", 0xeea00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1955 {"wsrld", 0xeee00040, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1956 {"wsrldg", 0xeee00148, 6, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwcg},
1957 {"wstrb", 0xec000000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
1958 {"wstrh", 0xec000100, 5, ARM_CEXT_IWMMXT, do_iwmmxt_byte_addr},
1959 {"wstrw", 0xec000200, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
1960 {"wstrd", 0xec000300, 5, ARM_CEXT_IWMMXT, do_iwmmxt_word_addr},
1961 {"wsubbss", 0xee3001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1962 {"wsubb", 0xee0001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1963 {"wsubbus", 0xee1001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1964 {"wsubhss", 0xee7001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1965 {"wsubh", 0xee4001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1966 {"wsubhus", 0xee5001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1967 {"wsubwss", 0xeeb001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1968 {"wsubw", 0xee8001a0, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1969 {"wsubwus", 0xee9001a0, 7, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1970 {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1971 {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1972 {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1973 {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1974 {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1975 {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1976 {"wunpckihb", 0xee1000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1977 {"wunpckihh", 0xee5000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1978 {"wunpckihw", 0xee9000c0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1979 {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1980 {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1981 {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1982 {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1983 {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1984 {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT, do_iwmmxt_wrwr},
1985 {"wunpckilb", 0xee1000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1986 {"wunpckilh", 0xee5000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1987 {"wunpckilw", 0xee9000e0, 9, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1988 {"wxor", 0xee100000, 4, ARM_CEXT_IWMMXT, do_iwmmxt_wrwrwr},
1989 {"wzero", 0xee300000, 5, ARM_CEXT_IWMMXT, do_iwmmxt_wzero},
1991 /* Cirrus Maverick instructions. */
1992 {"cfldrs", 0xec100400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
1993 {"cfldrd", 0xec500400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
1994 {"cfldr32", 0xec100500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_3},
1995 {"cfldr64", 0xec500500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_4},
1996 {"cfstrs", 0xec000400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
1997 {"cfstrd", 0xec400400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
1998 {"cfstr32", 0xec000500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_3},
1999 {"cfstr64", 0xec400500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_4},
2000 {"cfmvsr", 0xee000450, 6, ARM_CEXT_MAVERICK, do_mav_binops_2a},
2001 {"cfmvrs", 0xee100450, 6, ARM_CEXT_MAVERICK, do_mav_binops_1a},
2002 {"cfmvdlr", 0xee000410, 7, ARM_CEXT_MAVERICK, do_mav_binops_2b},
2003 {"cfmvrdl", 0xee100410, 7, ARM_CEXT_MAVERICK, do_mav_binops_1b},
2004 {"cfmvdhr", 0xee000430, 7, ARM_CEXT_MAVERICK, do_mav_binops_2b},
2005 {"cfmvrdh", 0xee100430, 7, ARM_CEXT_MAVERICK, do_mav_binops_1b},
2006 {"cfmv64lr", 0xee000510, 8, ARM_CEXT_MAVERICK, do_mav_binops_2c},
2007 {"cfmvr64l", 0xee100510, 8, ARM_CEXT_MAVERICK, do_mav_binops_1c},
2008 {"cfmv64hr", 0xee000530, 8, ARM_CEXT_MAVERICK, do_mav_binops_2c},
2009 {"cfmvr64h", 0xee100530, 8, ARM_CEXT_MAVERICK, do_mav_binops_1c},
2010 {"cfmval32", 0xee100610, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2011 {"cfmv32al", 0xee000610, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2012 {"cfmvam32", 0xee100630, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2013 {"cfmv32am", 0xee000630, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2014 {"cfmvah32", 0xee100650, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2015 {"cfmv32ah", 0xee000650, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2016 {"cfmva32", 0xee100670, 7, ARM_CEXT_MAVERICK, do_mav_binops_3a},
2017 {"cfmv32a", 0xee000670, 7, ARM_CEXT_MAVERICK, do_mav_binops_3b},
2018 {"cfmva64", 0xee100690, 7, ARM_CEXT_MAVERICK, do_mav_binops_3c},
2019 {"cfmv64a", 0xee000690, 7, ARM_CEXT_MAVERICK, do_mav_binops_3d},
2020 {"cfmvsc32", 0xee1006b0, 8, ARM_CEXT_MAVERICK, do_mav_dspsc_1},
2021 {"cfmv32sc", 0xee0006b0, 8, ARM_CEXT_MAVERICK, do_mav_dspsc_2},
2022 {"cfcpys", 0xee000400, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
2023 {"cfcpyd", 0xee000420, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
2024 {"cfcvtsd", 0xee000460, 7, ARM_CEXT_MAVERICK, do_mav_binops_1f},
2025 {"cfcvtds", 0xee000440, 7, ARM_CEXT_MAVERICK, do_mav_binops_1g},
2026 {"cfcvt32s", 0xee000480, 8, ARM_CEXT_MAVERICK, do_mav_binops_1h},
2027 {"cfcvt32d", 0xee0004a0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1i},
2028 {"cfcvt64s", 0xee0004c0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1j},
2029 {"cfcvt64d", 0xee0004e0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1k},
2030 {"cfcvts32", 0xee100580, 8, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2031 {"cfcvtd32", 0xee1005a0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2032 {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
2033 {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
2034 {"cfrshl32", 0xee000550, 8, ARM_CEXT_MAVERICK, do_mav_triple_4a},
2035 {"cfrshl64", 0xee000570, 8, ARM_CEXT_MAVERICK, do_mav_triple_4b},
2036 {"cfsh32", 0xee000500, 6, ARM_CEXT_MAVERICK, do_mav_shift_1},
2037 {"cfsh64", 0xee200500, 6, ARM_CEXT_MAVERICK, do_mav_shift_2},
2038 {"cfcmps", 0xee100490, 6, ARM_CEXT_MAVERICK, do_mav_triple_5a},
2039 {"cfcmpd", 0xee1004b0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5b},
2040 {"cfcmp32", 0xee100590, 7, ARM_CEXT_MAVERICK, do_mav_triple_5c},
2041 {"cfcmp64", 0xee1005b0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5d},
2042 {"cfabss", 0xee300400, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
2043 {"cfabsd", 0xee300420, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
2044 {"cfnegs", 0xee300440, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
2045 {"cfnegd", 0xee300460, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
2046 {"cfadds", 0xee300480, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
2047 {"cfaddd", 0xee3004a0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
2048 {"cfsubs", 0xee3004c0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
2049 {"cfsubd", 0xee3004e0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
2050 {"cfmuls", 0xee100400, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
2051 {"cfmuld", 0xee100420, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
2052 {"cfabs32", 0xee300500, 7, ARM_CEXT_MAVERICK, do_mav_binops_1n},
2053 {"cfabs64", 0xee300520, 7, ARM_CEXT_MAVERICK, do_mav_binops_1o},
2054 {"cfneg32", 0xee300540, 7, ARM_CEXT_MAVERICK, do_mav_binops_1n},
2055 {"cfneg64", 0xee300560, 7, ARM_CEXT_MAVERICK, do_mav_binops_1o},
2056 {"cfadd32", 0xee300580, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2057 {"cfadd64", 0xee3005a0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
2058 {"cfsub32", 0xee3005c0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2059 {"cfsub64", 0xee3005e0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
2060 {"cfmul32", 0xee100500, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2061 {"cfmul64", 0xee100520, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
2062 {"cfmac32", 0xee100540, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2063 {"cfmsc32", 0xee100560, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
2064 {"cfmadd32", 0xee000600, 8, ARM_CEXT_MAVERICK, do_mav_quad_6a},
2065 {"cfmsub32", 0xee100600, 8, ARM_CEXT_MAVERICK, do_mav_quad_6a},
2066 {"cfmadda32", 0xee200600, 9, ARM_CEXT_MAVERICK, do_mav_quad_6b},
2067 {"cfmsuba32", 0xee300600, 9, ARM_CEXT_MAVERICK, do_mav_quad_6b},
2070 /* Defines for various bits that we will want to toggle. */
2071 #define INST_IMMEDIATE 0x02000000
2072 #define OFFSET_REG 0x02000000
2073 #define HWOFFSET_IMM 0x00400000
2074 #define SHIFT_BY_REG 0x00000010
2075 #define PRE_INDEX 0x01000000
2076 #define INDEX_UP 0x00800000
2077 #define WRITE_BACK 0x00200000
2078 #define LDM_TYPE_2_OR_3 0x00400000
2080 #define LITERAL_MASK 0xf000f000
2081 #define OPCODE_MASK 0xfe1fffff
2082 #define V4_STR_BIT 0x00000020
2084 #define DATA_OP_SHIFT 21
2086 /* Codes to distinguish the arithmetic instructions. */
2087 #define OPCODE_AND 0
2088 #define OPCODE_EOR 1
2089 #define OPCODE_SUB 2
2090 #define OPCODE_RSB 3
2091 #define OPCODE_ADD 4
2092 #define OPCODE_ADC 5
2093 #define OPCODE_SBC 6
2094 #define OPCODE_RSC 7
2095 #define OPCODE_TST 8
2096 #define OPCODE_TEQ 9
2097 #define OPCODE_CMP 10
2098 #define OPCODE_CMN 11
2099 #define OPCODE_ORR 12
2100 #define OPCODE_MOV 13
2101 #define OPCODE_BIC 14
2102 #define OPCODE_MVN 15
2104 /* Thumb v1 (ARMv4T). */
2105 static void do_t_nop PARAMS ((char *));
2106 static void do_t_arit PARAMS ((char *));
2107 static void do_t_add PARAMS ((char *));
2108 static void do_t_asr PARAMS ((char *));
2109 static void do_t_branch9 PARAMS ((char *));
2110 static void do_t_branch12 PARAMS ((char *));
2111 static void do_t_branch23 PARAMS ((char *));
2112 static void do_t_bx PARAMS ((char *));
2113 static void do_t_compare PARAMS ((char *));
2114 static void do_t_ldmstm PARAMS ((char *));
2115 static void do_t_ldr PARAMS ((char *));
2116 static void do_t_ldrb PARAMS ((char *));
2117 static void do_t_ldrh PARAMS ((char *));
2118 static void do_t_lds PARAMS ((char *));
2119 static void do_t_lsl PARAMS ((char *));
2120 static void do_t_lsr PARAMS ((char *));
2121 static void do_t_mov PARAMS ((char *));
2122 static void do_t_push_pop PARAMS ((char *));
2123 static void do_t_str PARAMS ((char *));
2124 static void do_t_strb PARAMS ((char *));
2125 static void do_t_strh PARAMS ((char *));
2126 static void do_t_sub PARAMS ((char *));
2127 static void do_t_swi PARAMS ((char *));
2128 static void do_t_adr PARAMS ((char *));
2130 /* Thumb v2 (ARMv5T). */
2131 static void do_t_blx PARAMS ((char *));
2132 static void do_t_bkpt PARAMS ((char *));
2134 #define T_OPCODE_MUL 0x4340
2135 #define T_OPCODE_TST 0x4200
2136 #define T_OPCODE_CMN 0x42c0
2137 #define T_OPCODE_NEG 0x4240
2138 #define T_OPCODE_MVN 0x43c0
2140 #define T_OPCODE_ADD_R3 0x1800
2141 #define T_OPCODE_SUB_R3 0x1a00
2142 #define T_OPCODE_ADD_HI 0x4400
2143 #define T_OPCODE_ADD_ST 0xb000
2144 #define T_OPCODE_SUB_ST 0xb080
2145 #define T_OPCODE_ADD_SP 0xa800
2146 #define T_OPCODE_ADD_PC 0xa000
2147 #define T_OPCODE_ADD_I8 0x3000
2148 #define T_OPCODE_SUB_I8 0x3800
2149 #define T_OPCODE_ADD_I3 0x1c00
2150 #define T_OPCODE_SUB_I3 0x1e00
2152 #define T_OPCODE_ASR_R 0x4100
2153 #define T_OPCODE_LSL_R 0x4080
2154 #define T_OPCODE_LSR_R 0x40c0
2155 #define T_OPCODE_ASR_I 0x1000
2156 #define T_OPCODE_LSL_I 0x0000
2157 #define T_OPCODE_LSR_I 0x0800
2159 #define T_OPCODE_MOV_I8 0x2000
2160 #define T_OPCODE_CMP_I8 0x2800
2161 #define T_OPCODE_CMP_LR 0x4280
2162 #define T_OPCODE_MOV_HR 0x4600
2163 #define T_OPCODE_CMP_HR 0x4500
2165 #define T_OPCODE_LDR_PC 0x4800
2166 #define T_OPCODE_LDR_SP 0x9800
2167 #define T_OPCODE_STR_SP 0x9000
2168 #define T_OPCODE_LDR_IW 0x6800
2169 #define T_OPCODE_STR_IW 0x6000
2170 #define T_OPCODE_LDR_IH 0x8800
2171 #define T_OPCODE_STR_IH 0x8000
2172 #define T_OPCODE_LDR_IB 0x7800
2173 #define T_OPCODE_STR_IB 0x7000
2174 #define T_OPCODE_LDR_RW 0x5800
2175 #define T_OPCODE_STR_RW 0x5000
2176 #define T_OPCODE_LDR_RH 0x5a00
2177 #define T_OPCODE_STR_RH 0x5200
2178 #define T_OPCODE_LDR_RB 0x5c00
2179 #define T_OPCODE_STR_RB 0x5400
2181 #define T_OPCODE_PUSH 0xb400
2182 #define T_OPCODE_POP 0xbc00
2184 #define T_OPCODE_BRANCH 0xe7fe
2186 static int thumb_reg PARAMS ((char ** str, int hi_lo));
2188 #define THUMB_SIZE 2 /* Size of thumb instruction. */
2189 #define THUMB_REG_LO 0x1
2190 #define THUMB_REG_HI 0x2
2191 #define THUMB_REG_ANY 0x3
2193 #define THUMB_H1 0x0080
2194 #define THUMB_H2 0x0040
2200 #define THUMB_MOVE 0
2201 #define THUMB_COMPARE 1
2203 #define THUMB_LOAD 0
2204 #define THUMB_STORE 1
2206 #define THUMB_PP_PC_LR 0x0100
2208 /* These three are used for immediate shifts, do not alter. */
2209 #define THUMB_WORD 2
2210 #define THUMB_HALFWORD 1
2211 #define THUMB_BYTE 0
2215 /* Basic string to match. */
2216 const char * template;
2218 /* Basic instruction code. */
2219 unsigned long value;
2223 /* Which CPU variants this exists for. */
2224 unsigned long variant;
2226 /* Function to call to parse args. */
2227 void (* parms) PARAMS ((char *));
2230 static const struct thumb_opcode tinsns[] =
2232 /* Thumb v1 (ARMv4T). */
2233 {"adc", 0x4140, 2, ARM_EXT_V4T, do_t_arit},
2234 {"add", 0x0000, 2, ARM_EXT_V4T, do_t_add},
2235 {"and", 0x4000, 2, ARM_EXT_V4T, do_t_arit},
2236 {"asr", 0x0000, 2, ARM_EXT_V4T, do_t_asr},
2237 {"b", T_OPCODE_BRANCH, 2, ARM_EXT_V4T, do_t_branch12},
2238 {"beq", 0xd0fe, 2, ARM_EXT_V4T, do_t_branch9},
2239 {"bne", 0xd1fe, 2, ARM_EXT_V4T, do_t_branch9},
2240 {"bcs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
2241 {"bhs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
2242 {"bcc", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
2243 {"bul", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
2244 {"blo", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
2245 {"bmi", 0xd4fe, 2, ARM_EXT_V4T, do_t_branch9},
2246 {"bpl", 0xd5fe, 2, ARM_EXT_V4T, do_t_branch9},
2247 {"bvs", 0xd6fe, 2, ARM_EXT_V4T, do_t_branch9},
2248 {"bvc", 0xd7fe, 2, ARM_EXT_V4T, do_t_branch9},
2249 {"bhi", 0xd8fe, 2, ARM_EXT_V4T, do_t_branch9},
2250 {"bls", 0xd9fe, 2, ARM_EXT_V4T, do_t_branch9},
2251 {"bge", 0xdafe, 2, ARM_EXT_V4T, do_t_branch9},
2252 {"blt", 0xdbfe, 2, ARM_EXT_V4T, do_t_branch9},
2253 {"bgt", 0xdcfe, 2, ARM_EXT_V4T, do_t_branch9},
2254 {"ble", 0xddfe, 2, ARM_EXT_V4T, do_t_branch9},
2255 {"bal", 0xdefe, 2, ARM_EXT_V4T, do_t_branch9},
2256 {"bic", 0x4380, 2, ARM_EXT_V4T, do_t_arit},
2257 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T, do_t_branch23},
2258 {"bx", 0x4700, 2, ARM_EXT_V4T, do_t_bx},
2259 {"cmn", T_OPCODE_CMN, 2, ARM_EXT_V4T, do_t_arit},
2260 {"cmp", 0x0000, 2, ARM_EXT_V4T, do_t_compare},
2261 {"eor", 0x4040, 2, ARM_EXT_V4T, do_t_arit},
2262 {"ldmia", 0xc800, 2, ARM_EXT_V4T, do_t_ldmstm},
2263 {"ldr", 0x0000, 2, ARM_EXT_V4T, do_t_ldr},
2264 {"ldrb", 0x0000, 2, ARM_EXT_V4T, do_t_ldrb},
2265 {"ldrh", 0x0000, 2, ARM_EXT_V4T, do_t_ldrh},
2266 {"ldrsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
2267 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
2268 {"ldsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
2269 {"ldsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
2270 {"lsl", 0x0000, 2, ARM_EXT_V4T, do_t_lsl},
2271 {"lsr", 0x0000, 2, ARM_EXT_V4T, do_t_lsr},
2272 {"mov", 0x0000, 2, ARM_EXT_V4T, do_t_mov},
2273 {"mul", T_OPCODE_MUL, 2, ARM_EXT_V4T, do_t_arit},
2274 {"mvn", T_OPCODE_MVN, 2, ARM_EXT_V4T, do_t_arit},
2275 {"neg", T_OPCODE_NEG, 2, ARM_EXT_V4T, do_t_arit},
2276 {"orr", 0x4300, 2, ARM_EXT_V4T, do_t_arit},
2277 {"pop", 0xbc00, 2, ARM_EXT_V4T, do_t_push_pop},
2278 {"push", 0xb400, 2, ARM_EXT_V4T, do_t_push_pop},
2279 {"ror", 0x41c0, 2, ARM_EXT_V4T, do_t_arit},
2280 {"sbc", 0x4180, 2, ARM_EXT_V4T, do_t_arit},
2281 {"stmia", 0xc000, 2, ARM_EXT_V4T, do_t_ldmstm},
2282 {"str", 0x0000, 2, ARM_EXT_V4T, do_t_str},
2283 {"strb", 0x0000, 2, ARM_EXT_V4T, do_t_strb},
2284 {"strh", 0x0000, 2, ARM_EXT_V4T, do_t_strh},
2285 {"swi", 0xdf00, 2, ARM_EXT_V4T, do_t_swi},
2286 {"sub", 0x0000, 2, ARM_EXT_V4T, do_t_sub},
2287 {"tst", T_OPCODE_TST, 2, ARM_EXT_V4T, do_t_arit},
2289 {"adr", 0x0000, 2, ARM_EXT_V4T, do_t_adr},
2290 {"nop", 0x46C0, 2, ARM_EXT_V4T, do_t_nop}, /* mov r8,r8 */
2291 /* Thumb v2 (ARMv5T). */
2292 {"blx", 0, 0, ARM_EXT_V5T, do_t_blx},
2293 {"bkpt", 0xbe00, 2, ARM_EXT_V5T, do_t_bkpt},
2296 #define BAD_ARGS _("bad arguments to instruction")
2297 #define BAD_PC _("r15 not allowed here")
2298 #define BAD_COND _("instruction is not conditional")
2299 #define ERR_NO_ACCUM _("acc0 expected")
2301 static struct hash_control * arm_ops_hsh = NULL;
2302 static struct hash_control * arm_tops_hsh = NULL;
2303 static struct hash_control * arm_cond_hsh = NULL;
2304 static struct hash_control * arm_shift_hsh = NULL;
2305 static struct hash_control * arm_psr_hsh = NULL;
2307 /* This table describes all the machine specific pseudo-ops the assembler
2308 has to support. The fields are:
2309 pseudo-op name without dot
2310 function to call to execute this pseudo-op
2311 Integer arg to pass to the function. */
2313 static void s_req PARAMS ((int));
2314 static void s_align PARAMS ((int));
2315 static void s_bss PARAMS ((int));
2316 static void s_even PARAMS ((int));
2317 static void s_ltorg PARAMS ((int));
2318 static void s_arm PARAMS ((int));
2319 static void s_thumb PARAMS ((int));
2320 static void s_code PARAMS ((int));
2321 static void s_force_thumb PARAMS ((int));
2322 static void s_thumb_func PARAMS ((int));
2323 static void s_thumb_set PARAMS ((int));
2325 static void s_arm_elf_cons PARAMS ((int));
2328 static int my_get_expression PARAMS ((expressionS *, char **));
2330 const pseudo_typeS md_pseudo_table[] =
2332 /* Never called becasue '.req' does not start line. */
2333 { "req", s_req, 0 },
2334 { "bss", s_bss, 0 },
2335 { "align", s_align, 0 },
2336 { "arm", s_arm, 0 },
2337 { "thumb", s_thumb, 0 },
2338 { "code", s_code, 0 },
2339 { "force_thumb", s_force_thumb, 0 },
2340 { "thumb_func", s_thumb_func, 0 },
2341 { "thumb_set", s_thumb_set, 0 },
2342 { "even", s_even, 0 },
2343 { "ltorg", s_ltorg, 0 },
2344 { "pool", s_ltorg, 0 },
2346 { "word", s_arm_elf_cons, 4 },
2347 { "long", s_arm_elf_cons, 4 },
2348 { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
2349 { "loc", dwarf2_directive_loc, 0 },
2353 { "extend", float_cons, 'x' },
2354 { "ldouble", float_cons, 'x' },
2355 { "packed", float_cons, 'p' },
2359 /* Other internal functions. */
2360 static int arm_parse_extension PARAMS ((char *, int *));
2361 static int arm_parse_cpu PARAMS ((char *));
2362 static int arm_parse_arch PARAMS ((char *));
2363 static int arm_parse_fpu PARAMS ((char *));
2364 #if defined OBJ_COFF || defined OBJ_ELF
2365 static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
2368 /* Stuff needed to resolve the label ambiguity
2378 symbolS * last_label_seen;
2379 static int label_is_thumb_function_name = FALSE;
2381 /* Literal Pool stuff. */
2383 #define MAX_LITERAL_POOL_SIZE 1024
2385 /* Literal pool structure. Held on a per-section
2386 and per-sub-section basis. */
2387 typedef struct literal_pool
2389 expressionS literals [MAX_LITERAL_POOL_SIZE];
2390 unsigned int next_free_entry;
2394 subsegT sub_section;
2395 struct literal_pool * next;
2398 /* Pointer to a linked list of literal pools. */
2399 literal_pool * list_of_pools = NULL;
2401 static literal_pool * find_literal_pool PARAMS ((void));
2402 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2404 static literal_pool *
2405 find_literal_pool ()
2407 literal_pool * pool;
2409 for (pool = list_of_pools; pool != NULL; pool = pool->next)
2411 if (pool->section == now_seg
2412 && pool->sub_section == now_subseg)
2419 static literal_pool *
2420 find_or_make_literal_pool ()
2422 /* Next literal pool ID number. */
2423 static unsigned int latest_pool_num = 1;
2424 literal_pool * pool;
2426 pool = find_literal_pool ();
2430 /* Create a new pool. */
2431 pool = (literal_pool *) xmalloc (sizeof (* pool));
2435 pool->next_free_entry = 0;
2436 pool->section = now_seg;
2437 pool->sub_section = now_subseg;
2438 pool->next = list_of_pools;
2439 pool->symbol = NULL;
2441 /* Add it to the list. */
2442 list_of_pools = pool;
2445 /* New pools, and emptied pools, will have a NULL symbol. */
2446 if (pool->symbol == NULL)
2448 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2449 (valueT) 0, &zero_address_frag);
2450 pool->id = latest_pool_num ++;
2457 /* Add the literal in the global 'inst'
2458 structure to the relevent literal pool. */
2462 literal_pool * pool;
2465 pool = find_or_make_literal_pool ();
2467 /* Check if this literal value is already in the pool. */
2468 for (entry = 0; entry < pool->next_free_entry; entry ++)
2470 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2471 && (inst.reloc.exp.X_op == O_constant)
2472 && (pool->literals[entry].X_add_number
2473 == inst.reloc.exp.X_add_number)
2474 && (pool->literals[entry].X_unsigned
2475 == inst.reloc.exp.X_unsigned))
2478 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2479 && (inst.reloc.exp.X_op == O_symbol)
2480 && (pool->literals[entry].X_add_number
2481 == inst.reloc.exp.X_add_number)
2482 && (pool->literals[entry].X_add_symbol
2483 == inst.reloc.exp.X_add_symbol)
2484 && (pool->literals[entry].X_op_symbol
2485 == inst.reloc.exp.X_op_symbol))
2489 /* Do we need to create a new entry? */
2490 if (entry == pool->next_free_entry)
2492 if (entry >= MAX_LITERAL_POOL_SIZE)
2494 inst.error = _("literal pool overflow");
2498 pool->literals[entry] = inst.reloc.exp;
2499 pool->next_free_entry += 1;
2502 inst.reloc.exp.X_op = O_symbol;
2503 inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2504 inst.reloc.exp.X_add_symbol = pool->symbol;
2509 /* Can't use symbol_new here, so have to create a symbol and then at
2510 a later date assign it a value. Thats what these functions do. */
2513 symbol_locate (symbolP, name, segment, valu, frag)
2515 const char * name; /* It is copied, the caller can modify. */
2516 segT segment; /* Segment identifier (SEG_<something>). */
2517 valueT valu; /* Symbol value. */
2518 fragS * frag; /* Associated fragment. */
2520 unsigned int name_length;
2521 char * preserved_copy_of_name;
2523 name_length = strlen (name) + 1; /* +1 for \0. */
2524 obstack_grow (¬es, name, name_length);
2525 preserved_copy_of_name = obstack_finish (¬es);
2526 #ifdef STRIP_UNDERSCORE
2527 if (preserved_copy_of_name[0] == '_')
2528 preserved_copy_of_name++;
2531 #ifdef tc_canonicalize_symbol_name
2532 preserved_copy_of_name =
2533 tc_canonicalize_symbol_name (preserved_copy_of_name);
2536 S_SET_NAME (symbolP, preserved_copy_of_name);
2538 S_SET_SEGMENT (symbolP, segment);
2539 S_SET_VALUE (symbolP, valu);
2540 symbol_clear_list_pointers (symbolP);
2542 symbol_set_frag (symbolP, frag);
2544 /* Link to end of symbol chain. */
2546 extern int symbol_table_frozen;
2547 if (symbol_table_frozen)
2551 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2553 obj_symbol_new_hook (symbolP);
2555 #ifdef tc_symbol_new_hook
2556 tc_symbol_new_hook (symbolP);
2560 verify_symbol_chain (symbol_rootP, symbol_lastP);
2561 #endif /* DEBUG_SYMS */
2564 /* Check that an immediate is valid.
2565 If so, convert it to the right format. */
2568 validate_immediate (val)
2574 #define rotate_left(v, n) (v << n | v >> (32 - n))
2576 for (i = 0; i < 32; i += 2)
2577 if ((a = rotate_left (val, i)) <= 0xff)
2578 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
2583 /* Check to see if an immediate can be computed as two seperate immediate
2584 values, added together. We already know that this value cannot be
2585 computed by just one ARM instruction. */
2588 validate_immediate_twopart (val, highpart)
2590 unsigned int * highpart;
2595 for (i = 0; i < 32; i += 2)
2596 if (((a = rotate_left (val, i)) & 0xff) != 0)
2602 * highpart = (a >> 8) | ((i + 24) << 7);
2604 else if (a & 0xff0000)
2608 * highpart = (a >> 16) | ((i + 16) << 7);
2612 assert (a & 0xff000000);
2613 * highpart = (a >> 24) | ((i + 8) << 7);
2616 return (a & 0xff) | (i << 7);
2623 validate_offset_imm (val, hwse)
2627 if ((hwse && val > 255) || val > 4095)
2634 int a ATTRIBUTE_UNUSED;
2636 as_bad (_("invalid syntax for .req directive"));
2641 int ignore ATTRIBUTE_UNUSED;
2643 /* We don't support putting frags in the BSS segment, we fake it by
2644 marking in_bss, then looking at s_skip for clues. */
2645 subseg_set (bss_section, 0);
2646 demand_empty_rest_of_line ();
2651 int ignore ATTRIBUTE_UNUSED;
2653 /* Never make frag if expect extra pass. */
2655 frag_align (1, 0, 0);
2657 record_alignment (now_seg, 1);
2659 demand_empty_rest_of_line ();
2664 int ignored ATTRIBUTE_UNUSED;
2667 literal_pool * pool;
2670 pool = find_literal_pool ();
2672 || pool->symbol == NULL
2673 || pool->next_free_entry == 0)
2676 /* Align pool as you have word accesses.
2677 Only make a frag if we have to. */
2679 frag_align (2, 0, 0);
2681 record_alignment (now_seg, 2);
2683 sprintf (sym_name, "$$lit_\002%x", pool->id);
2685 symbol_locate (pool->symbol, sym_name, now_seg,
2686 (valueT) frag_now_fix (), frag_now);
2687 symbol_table_insert (pool->symbol);
2689 ARM_SET_THUMB (pool->symbol, thumb_mode);
2691 #if defined OBJ_COFF || defined OBJ_ELF
2692 ARM_SET_INTERWORK (pool->symbol, support_interwork);
2695 for (entry = 0; entry < pool->next_free_entry; entry ++)
2696 /* First output the expression in the instruction to the pool. */
2697 emit_expr (&(pool->literals[entry]), 4); /* .word */
2699 /* Mark the pool as empty. */
2700 pool->next_free_entry = 0;
2701 pool->symbol = NULL;
2704 /* Same as s_align_ptwo but align 0 => align 2. */
2708 int unused ATTRIBUTE_UNUSED;
2711 register long temp_fill;
2712 long max_alignment = 15;
2714 temp = get_absolute_expression ();
2715 if (temp > max_alignment)
2716 as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
2719 as_bad (_("alignment negative. 0 assumed."));
2723 if (*input_line_pointer == ',')
2725 input_line_pointer++;
2726 temp_fill = get_absolute_expression ();
2734 /* Only make a frag if we HAVE to. */
2735 if (temp && !need_pass_2)
2736 frag_align (temp, (int) temp_fill, 0);
2737 demand_empty_rest_of_line ();
2739 record_alignment (now_seg, temp);
2743 s_force_thumb (ignore)
2744 int ignore ATTRIBUTE_UNUSED;
2746 /* If we are not already in thumb mode go into it, EVEN if
2747 the target processor does not support thumb instructions.
2748 This is used by gcc/config/arm/lib1funcs.asm for example
2749 to compile interworking support functions even if the
2750 target processor should not support interworking. */
2755 record_alignment (now_seg, 1);
2758 demand_empty_rest_of_line ();
2762 s_thumb_func (ignore)
2763 int ignore ATTRIBUTE_UNUSED;
2768 /* The following label is the name/address of the start of a Thumb function.
2769 We need to know this for the interworking support. */
2770 label_is_thumb_function_name = TRUE;
2772 demand_empty_rest_of_line ();
2775 /* Perform a .set directive, but also mark the alias as
2776 being a thumb function. */
2782 /* XXX the following is a duplicate of the code for s_set() in read.c
2783 We cannot just call that code as we need to get at the symbol that
2785 register char * name;
2786 register char delim;
2787 register char * end_name;
2788 register symbolS * symbolP;
2790 /* Especial apologies for the random logic:
2791 This just grew, and could be parsed much more simply!
2793 name = input_line_pointer;
2794 delim = get_symbol_end ();
2795 end_name = input_line_pointer;
2800 if (*input_line_pointer != ',')
2803 as_bad (_("expected comma after name \"%s\""), name);
2805 ignore_rest_of_line ();
2809 input_line_pointer++;
2812 if (name[0] == '.' && name[1] == '\0')
2814 /* XXX - this should not happen to .thumb_set. */
2818 if ((symbolP = symbol_find (name)) == NULL
2819 && (symbolP = md_undefined_symbol (name)) == NULL)
2822 /* When doing symbol listings, play games with dummy fragments living
2823 outside the normal fragment chain to record the file and line info
2825 if (listing & LISTING_SYMBOLS)
2827 extern struct list_info_struct * listing_tail;
2828 fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
2830 memset (dummy_frag, 0, sizeof (fragS));
2831 dummy_frag->fr_type = rs_fill;
2832 dummy_frag->line = listing_tail;
2833 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
2834 dummy_frag->fr_symbol = symbolP;
2838 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
2841 /* "set" symbols are local unless otherwise specified. */
2842 SF_SET_LOCAL (symbolP);
2843 #endif /* OBJ_COFF */
2844 } /* Make a new symbol. */
2846 symbol_table_insert (symbolP);
2851 && S_IS_DEFINED (symbolP)
2852 && S_GET_SEGMENT (symbolP) != reg_section)
2853 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
2855 pseudo_set (symbolP);
2857 demand_empty_rest_of_line ();
2859 /* XXX Now we come to the Thumb specific bit of code. */
2861 THUMB_SET_FUNC (symbolP, 1);
2862 ARM_SET_THUMB (symbolP, 1);
2863 #if defined OBJ_ELF || defined OBJ_COFF
2864 ARM_SET_INTERWORK (symbolP, support_interwork);
2869 opcode_select (width)
2877 if (! (cpu_variant & ARM_EXT_V4T))
2878 as_bad (_("selected processor does not support THUMB opcodes"));
2881 /* No need to force the alignment, since we will have been
2882 coming from ARM mode, which is word-aligned. */
2883 record_alignment (now_seg, 1);
2890 if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
2891 as_bad (_("selected processor does not support ARM opcodes"));
2896 frag_align (2, 0, 0);
2898 record_alignment (now_seg, 1);
2903 as_bad (_("invalid instruction size selected (%d)"), width);
2909 int ignore ATTRIBUTE_UNUSED;
2912 demand_empty_rest_of_line ();
2917 int ignore ATTRIBUTE_UNUSED;
2920 demand_empty_rest_of_line ();
2925 int unused ATTRIBUTE_UNUSED;
2929 temp = get_absolute_expression ();
2934 opcode_select (temp);
2938 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
2946 skip_whitespace (str);
2948 if (*str != '\0' && !inst.error)
2949 inst.error = _("garbage following instruction");
2953 skip_past_comma (str)
2956 char * p = * str, c;
2959 while ((c = *p) == ' ' || c == ',')
2962 if (c == ',' && comma++)
2970 return comma ? SUCCESS : FAIL;
2973 /* A standard register must be given at this point.
2974 SHIFT is the place to put it in inst.instruction.
2975 Restores input start point on error.
2976 Returns the reg#, or FAIL. */
2979 reg_required_here (str, shift)
2983 static char buff [128]; /* XXX */
2985 char * start = * str;
2987 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
2990 inst.instruction |= reg << shift;
2994 /* Restore the start point, we may have got a reg of the wrong class. */
2997 /* In the few cases where we might be able to accept something else
2998 this error can be overridden. */
2999 sprintf (buff, _("register expected, not '%.100s'"), start);
3005 /* A Intel Wireless MMX technology register
3006 must be given at this point.
3007 Shift is the place to put it in inst.instruction.
3008 Restores input start point on err.
3009 Returns the reg#, or FAIL. */
3012 wreg_required_here (str, shift, reg_type)
3015 enum wreg_type reg_type;
3017 static char buff [128];
3019 char * start = *str;
3021 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
3023 if (wr_register (reg)
3024 && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
3027 inst.instruction |= (reg ^ WR_PREFIX) << shift;
3030 else if (wc_register (reg)
3031 && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
3034 inst.instruction |= (reg ^ WC_PREFIX) << shift;
3037 else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
3040 inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
3045 /* Restore the start point, we may have got a reg of the wrong class. */
3048 /* In the few cases where we might be able to accept
3049 something else this error can be overridden. */
3050 sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
3056 static const struct asm_psr *
3058 register char ** ccp;
3060 char * start = * ccp;
3063 const struct asm_psr * psr;
3067 /* Skip to the end of the next word in the input stream. */
3072 while (ISALPHA (c) || c == '_');
3074 /* Terminate the word. */
3077 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
3078 feature for ease of use and backwards compatibility. */
3079 if (!strncmp (start, "cpsr", 4))
3080 strncpy (start, "CPSR", 4);
3081 else if (!strncmp (start, "spsr", 4))
3082 strncpy (start, "SPSR", 4);
3084 /* Now locate the word in the psr hash table. */
3085 psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
3087 /* Restore the input stream. */
3090 /* If we found a valid match, advance the
3091 stream pointer past the end of the word. */
3097 /* Parse the input looking for a PSR flag. */
3100 psr_required_here (str)
3103 char * start = * str;
3104 const struct asm_psr * psr;
3106 psr = arm_psr_parse (str);
3110 /* If this is the SPSR that is being modified, set the R bit. */
3112 inst.instruction |= SPSR_BIT;
3114 /* Set the psr flags in the MSR instruction. */
3115 inst.instruction |= psr->field << PSR_SHIFT;
3120 /* In the few cases where we might be able to accept
3121 something else this error can be overridden. */
3122 inst.error = _("flag for {c}psr instruction expected");
3124 /* Restore the start point. */
3130 co_proc_number (str)
3133 int processor, pchar;
3136 skip_whitespace (*str);
3139 /* The data sheet seems to imply that just a number on its own is valid
3140 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
3142 if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
3148 if (pchar >= '0' && pchar <= '9')
3150 processor = pchar - '0';
3151 if (**str >= '0' && **str <= '9')
3153 processor = processor * 10 + *(*str)++ - '0';
3156 inst.error = _("illegal co-processor number");
3163 inst.error = _("bad or missing co-processor number");
3168 inst.instruction |= processor << 8;
3173 cp_opc_expr (str, where, length)
3180 skip_whitespace (* str);
3182 memset (&expr, '\0', sizeof (expr));
3184 if (my_get_expression (&expr, str))
3186 if (expr.X_op != O_constant)
3188 inst.error = _("bad or missing expression");
3192 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
3194 inst.error = _("immediate co-processor expression too large");
3198 inst.instruction |= expr.X_add_number << where;
3203 cp_reg_required_here (str, where)
3208 char * start = *str;
3210 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
3212 inst.instruction |= reg << where;
3216 /* In the few cases where we might be able to accept something else
3217 this error can be overridden. */
3218 inst.error = _("co-processor register expected");
3220 /* Restore the start point. */
3226 fp_reg_required_here (str, where)
3231 char * start = * str;
3233 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
3235 inst.instruction |= reg << where;
3239 /* In the few cases where we might be able to accept something else
3240 this error can be overridden. */
3241 inst.error = _("floating point register expected");
3243 /* Restore the start point. */
3249 cp_address_offset (str)
3254 skip_whitespace (* str);
3256 if (! is_immediate_prefix (**str))
3258 inst.error = _("immediate expression expected");
3264 if (my_get_expression (& inst.reloc.exp, str))
3267 if (inst.reloc.exp.X_op == O_constant)
3269 offset = inst.reloc.exp.X_add_number;
3273 inst.error = _("co-processor address must be word aligned");
3277 if (offset > 1023 || offset < -1023)
3279 inst.error = _("offset too large");
3284 inst.instruction |= INDEX_UP;
3288 inst.instruction |= offset >> 2;
3291 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3297 cp_address_required_here (str, wb_ok)
3310 skip_whitespace (p);
3312 if ((reg = reg_required_here (& p, 16)) == FAIL)
3315 skip_whitespace (p);
3321 if (wb_ok && skip_past_comma (& p) == SUCCESS)
3324 write_back = WRITE_BACK;
3328 inst.error = _("pc may not be used in post-increment");
3332 if (cp_address_offset (& p) == FAIL)
3336 pre_inc = PRE_INDEX | INDEX_UP;
3340 /* '['Rn, #expr']'[!] */
3342 if (skip_past_comma (& p) == FAIL)
3344 inst.error = _("pre-indexed expression expected");
3348 pre_inc = PRE_INDEX;
3350 if (cp_address_offset (& p) == FAIL)
3353 skip_whitespace (p);
3357 inst.error = _("missing ]");
3361 skip_whitespace (p);
3363 if (wb_ok && *p == '!')
3367 inst.error = _("pc may not be used with write-back");
3372 write_back = WRITE_BACK;
3378 if (my_get_expression (&inst.reloc.exp, &p))
3381 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3382 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3383 inst.reloc.pc_rel = 1;
3384 inst.instruction |= (REG_PC << 16);
3385 pre_inc = PRE_INDEX;
3388 inst.instruction |= write_back | pre_inc;
3394 cp_byte_address_offset (str)
3399 skip_whitespace (* str);
3401 if (! is_immediate_prefix (**str))
3403 inst.error = _("immediate expression expected");
3409 if (my_get_expression (& inst.reloc.exp, str))
3412 if (inst.reloc.exp.X_op == O_constant)
3414 offset = inst.reloc.exp.X_add_number;
3416 if (offset > 255 || offset < -255)
3418 inst.error = _("offset too large");
3423 inst.instruction |= INDEX_UP;
3427 inst.instruction |= offset;
3430 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3436 cp_byte_address_required_here (str)
3448 skip_whitespace (p);
3450 if ((reg = reg_required_here (& p, 16)) == FAIL)
3453 skip_whitespace (p);
3459 if (skip_past_comma (& p) == SUCCESS)
3462 write_back = WRITE_BACK;
3466 inst.error = _("pc may not be used in post-increment");
3470 if (cp_byte_address_offset (& p) == FAIL)
3474 pre_inc = PRE_INDEX | INDEX_UP;
3478 /* '['Rn, #expr']'[!] */
3480 if (skip_past_comma (& p) == FAIL)
3482 inst.error = _("pre-indexed expression expected");
3486 pre_inc = PRE_INDEX;
3488 if (cp_byte_address_offset (& p) == FAIL)
3491 skip_whitespace (p);
3495 inst.error = _("missing ]");
3499 skip_whitespace (p);
3505 inst.error = _("pc may not be used with write-back");
3510 write_back = WRITE_BACK;
3516 if (my_get_expression (&inst.reloc.exp, &p))
3519 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3520 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3521 inst.reloc.pc_rel = 1;
3522 inst.instruction |= (REG_PC << 16);
3523 pre_inc = PRE_INDEX;
3526 inst.instruction |= write_back | pre_inc;
3535 /* Do nothing really. */
3546 /* Only one syntax. */
3547 skip_whitespace (str);
3549 if (reg_required_here (&str, 12) == FAIL)
3551 inst.error = BAD_ARGS;
3555 if (skip_past_comma (&str) == FAIL)
3557 inst.error = _("comma expected after register name");
3561 skip_whitespace (str);
3563 if ( strcmp (str, "CPSR") == 0
3564 || strcmp (str, "SPSR") == 0
3565 /* Lower case versions for backwards compatability. */
3566 || strcmp (str, "cpsr") == 0
3567 || strcmp (str, "spsr") == 0)
3570 /* This is for backwards compatability with older toolchains. */
3571 else if ( strcmp (str, "cpsr_all") == 0
3572 || strcmp (str, "spsr_all") == 0)
3576 inst.error = _("CPSR or SPSR expected");
3580 if (* str == 's' || * str == 'S')
3581 inst.instruction |= SPSR_BIT;
3587 /* Two possible forms:
3588 "{C|S}PSR_<field>, Rm",
3589 "{C|S}PSR_f, #expression". */
3595 skip_whitespace (str);
3597 if (psr_required_here (& str) == FAIL)
3600 if (skip_past_comma (& str) == FAIL)
3602 inst.error = _("comma missing after psr flags");
3606 skip_whitespace (str);
3608 if (reg_required_here (& str, 0) != FAIL)
3615 if (! is_immediate_prefix (* str))
3618 _("only a register or immediate value can follow a psr flag");
3625 if (my_get_expression (& inst.reloc.exp, & str))
3628 _("only a register or immediate value can follow a psr flag");
3632 #if 0 /* The first edition of the ARM architecture manual stated that
3633 writing anything other than the flags with an immediate operation
3634 had UNPREDICTABLE effects. This constraint was removed in the
3635 second edition of the specification. */
3636 if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
3637 && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
3639 inst.error = _("immediate value cannot be used to set this field");
3644 inst.instruction |= INST_IMMEDIATE;
3646 if (inst.reloc.exp.X_add_symbol)
3648 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
3649 inst.reloc.pc_rel = 0;
3653 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
3655 if (value == (unsigned) FAIL)
3657 inst.error = _("invalid constant");
3661 inst.instruction |= value;
3668 /* Long Multiply Parser
3669 UMULL RdLo, RdHi, Rm, Rs
3670 SMULL RdLo, RdHi, Rm, Rs
3671 UMLAL RdLo, RdHi, Rm, Rs
3672 SMLAL RdLo, RdHi, Rm, Rs. */
3678 int rdlo, rdhi, rm, rs;
3680 /* Only one format "rdlo, rdhi, rm, rs". */
3681 skip_whitespace (str);
3683 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
3685 inst.error = BAD_ARGS;
3689 if (skip_past_comma (&str) == FAIL
3690 || (rdhi = reg_required_here (&str, 16)) == FAIL)
3692 inst.error = BAD_ARGS;
3696 if (skip_past_comma (&str) == FAIL
3697 || (rm = reg_required_here (&str, 0)) == FAIL)
3699 inst.error = BAD_ARGS;
3703 /* rdhi, rdlo and rm must all be different. */
3704 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
3705 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
3707 if (skip_past_comma (&str) == FAIL
3708 || (rs = reg_required_here (&str, 8)) == FAIL)
3710 inst.error = BAD_ARGS;
3714 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
3716 inst.error = BAD_PC;
3730 /* Only one format "rd, rm, rs". */
3731 skip_whitespace (str);
3733 if ((rd = reg_required_here (&str, 16)) == FAIL)
3735 inst.error = BAD_ARGS;
3741 inst.error = BAD_PC;
3745 if (skip_past_comma (&str) == FAIL
3746 || (rm = reg_required_here (&str, 0)) == FAIL)
3748 inst.error = BAD_ARGS;
3754 inst.error = BAD_PC;
3759 as_tsktsk (_("rd and rm should be different in mul"));
3761 if (skip_past_comma (&str) == FAIL
3762 || (rm = reg_required_here (&str, 8)) == FAIL)
3764 inst.error = BAD_ARGS;
3770 inst.error = BAD_PC;
3784 /* Only one format "rd, rm, rs, rn". */
3785 skip_whitespace (str);
3787 if ((rd = reg_required_here (&str, 16)) == FAIL)
3789 inst.error = BAD_ARGS;
3795 inst.error = BAD_PC;
3799 if (skip_past_comma (&str) == FAIL
3800 || (rm = reg_required_here (&str, 0)) == FAIL)
3802 inst.error = BAD_ARGS;
3808 inst.error = BAD_PC;
3813 as_tsktsk (_("rd and rm should be different in mla"));
3815 if (skip_past_comma (&str) == FAIL
3816 || (rd = reg_required_here (&str, 8)) == FAIL
3817 || skip_past_comma (&str) == FAIL
3818 || (rm = reg_required_here (&str, 12)) == FAIL)
3820 inst.error = BAD_ARGS;
3824 if (rd == REG_PC || rm == REG_PC)
3826 inst.error = BAD_PC;
3834 /* Expects *str -> the characters "acc0", possibly with leading blanks.
3835 Advances *str to the next non-alphanumeric.
3836 Returns 0, or else FAIL (in which case sets inst.error).
3838 (In a future XScale, there may be accumulators other than zero.
3839 At that time this routine and its callers can be upgraded to suit.) */
3842 accum0_required_here (str)
3845 static char buff [128]; /* Note the address is taken. Hence, static. */
3848 int result = 0; /* The accum number. */
3850 skip_whitespace (p);
3852 *str = p; /* Advance caller's string pointer too. */
3857 *--p = 0; /* Aap nul into input buffer at non-alnum. */
3859 if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
3861 sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
3866 *p = c; /* Unzap. */
3867 *str = p; /* Caller's string pointer to after match. */
3871 /* Expects **str -> after a comma. May be leading blanks.
3872 Advances *str, recognizing a load mode, and setting inst.instruction.
3873 Returns rn, or else FAIL (in which case may set inst.error
3874 and not advance str)
3876 Note: doesn't know Rd, so no err checks that require such knowledge. */
3879 ld_mode_required_here (string)
3882 char * str = * string;
3886 skip_whitespace (str);
3892 skip_whitespace (str);
3894 if ((rn = reg_required_here (& str, 16)) == FAIL)
3897 skip_whitespace (str);
3903 if (skip_past_comma (& str) == SUCCESS)
3905 /* [Rn],... (post inc) */
3906 if (ldst_extend_v4 (&str) == FAIL)
3911 skip_whitespace (str);
3916 inst.instruction |= WRITE_BACK;
3919 inst.instruction |= INDEX_UP | HWOFFSET_IMM;
3925 if (skip_past_comma (& str) == FAIL)
3927 inst.error = _("pre-indexed expression expected");
3933 if (ldst_extend_v4 (&str) == FAIL)
3936 skip_whitespace (str);
3938 if (* str ++ != ']')
3940 inst.error = _("missing ]");
3944 skip_whitespace (str);
3949 inst.instruction |= WRITE_BACK;
3953 else if (* str == '=') /* ldr's "r,=label" syntax */
3954 /* We should never reach here, because <text> = <expression> is
3955 caught gas/read.c read_a_source_file() as a .set operation. */
3957 else /* PC +- 8 bit immediate offset. */
3959 if (my_get_expression (& inst.reloc.exp, & str))
3962 inst.instruction |= HWOFFSET_IMM; /* The I bit. */
3963 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
3964 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3965 inst.reloc.pc_rel = 1;
3966 inst.instruction |= (REG_PC << 16);
3972 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
3978 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3979 SMLAxy{cond} Rd,Rm,Rs,Rn
3980 SMLAWy{cond} Rd,Rm,Rs,Rn
3981 Error if any register is R15. */
3989 skip_whitespace (str);
3991 if ((rd = reg_required_here (& str, 16)) == FAIL
3992 || skip_past_comma (& str) == FAIL
3993 || (rm = reg_required_here (& str, 0)) == FAIL
3994 || skip_past_comma (& str) == FAIL
3995 || (rs = reg_required_here (& str, 8)) == FAIL
3996 || skip_past_comma (& str) == FAIL
3997 || (rn = reg_required_here (& str, 12)) == FAIL)
3998 inst.error = BAD_ARGS;
4000 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
4001 inst.error = BAD_PC;
4007 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4008 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4009 Error if any register is R15.
4010 Warning if Rdlo == Rdhi. */
4016 int rdlo, rdhi, rm, rs;
4018 skip_whitespace (str);
4020 if ((rdlo = reg_required_here (& str, 12)) == FAIL
4021 || skip_past_comma (& str) == FAIL
4022 || (rdhi = reg_required_here (& str, 16)) == FAIL
4023 || skip_past_comma (& str) == FAIL
4024 || (rm = reg_required_here (& str, 0)) == FAIL
4025 || skip_past_comma (& str) == FAIL
4026 || (rs = reg_required_here (& str, 8)) == FAIL)
4028 inst.error = BAD_ARGS;
4032 if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4034 inst.error = BAD_PC;
4039 as_tsktsk (_("rdhi and rdlo must be different"));
4044 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4045 SMULxy{cond} Rd,Rm,Rs
4046 Error if any register is R15. */
4054 skip_whitespace (str);
4056 if ((rd = reg_required_here (& str, 16)) == FAIL
4057 || skip_past_comma (& str) == FAIL
4058 || (rm = reg_required_here (& str, 0)) == FAIL
4059 || skip_past_comma (& str) == FAIL
4060 || (rs = reg_required_here (& str, 8)) == FAIL)
4061 inst.error = BAD_ARGS;
4063 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
4064 inst.error = BAD_PC;
4070 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4071 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4072 Error if any register is R15. */
4080 skip_whitespace (str);
4082 if ((rd = reg_required_here (& str, 12)) == FAIL
4083 || skip_past_comma (& str) == FAIL
4084 || (rm = reg_required_here (& str, 0)) == FAIL
4085 || skip_past_comma (& str) == FAIL
4086 || (rn = reg_required_here (& str, 16)) == FAIL)
4087 inst.error = BAD_ARGS;
4089 else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4090 inst.error = BAD_PC;
4096 /* ARM V5E (el Segundo)
4097 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4098 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4100 These are equivalent to the XScale instructions MAR and MRA,
4101 respectively, when coproc == 0, opcode == 0, and CRm == 0.
4103 Result unpredicatable if Rd or Rn is R15. */
4111 skip_whitespace (str);
4113 if (co_proc_number (& str) == FAIL)
4116 inst.error = BAD_ARGS;
4120 if (skip_past_comma (& str) == FAIL
4121 || cp_opc_expr (& str, 4, 4) == FAIL)
4124 inst.error = BAD_ARGS;
4128 if (skip_past_comma (& str) == FAIL
4129 || (rd = reg_required_here (& str, 12)) == FAIL)
4132 inst.error = BAD_ARGS;
4136 if (skip_past_comma (& str) == FAIL
4137 || (rn = reg_required_here (& str, 16)) == FAIL)
4140 inst.error = BAD_ARGS;
4144 /* Unpredictable result if rd or rn is R15. */
4145 if (rd == REG_PC || rn == REG_PC)
4147 (_("Warning: instruction unpredictable when using r15"));
4149 if (skip_past_comma (& str) == FAIL
4150 || cp_reg_required_here (& str, 0) == FAIL)
4153 inst.error = BAD_ARGS;
4160 /* ARM V5 count-leading-zeroes instruction (argument parse)
4161 CLZ{<cond>} <Rd>, <Rm>
4162 Condition defaults to COND_ALWAYS.
4163 Error if Rd or Rm are R15. */
4171 skip_whitespace (str);
4173 if (((rd = reg_required_here (& str, 12)) == FAIL)
4174 || (skip_past_comma (& str) == FAIL)
4175 || ((rm = reg_required_here (& str, 0)) == FAIL))
4176 inst.error = BAD_ARGS;
4178 else if (rd == REG_PC || rm == REG_PC )
4179 inst.error = BAD_PC;
4185 /* ARM V5 (argument parse)
4186 LDC2{L} <coproc>, <CRd>, <addressing mode>
4187 STC2{L} <coproc>, <CRd>, <addressing mode>
4188 Instruction is not conditional, and has 0xf in the codition field.
4189 Otherwise, it's the same as LDC/STC. */
4195 skip_whitespace (str);
4197 if (co_proc_number (& str) == FAIL)
4200 inst.error = BAD_ARGS;
4202 else if (skip_past_comma (& str) == FAIL
4203 || cp_reg_required_here (& str, 12) == FAIL)
4206 inst.error = BAD_ARGS;
4208 else if (skip_past_comma (& str) == FAIL
4209 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
4212 inst.error = BAD_ARGS;
4218 /* ARM V5 (argument parse)
4219 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4220 Instruction is not conditional, and has 0xf in the condition field.
4221 Otherwise, it's the same as CDP. */
4227 skip_whitespace (str);
4229 if (co_proc_number (& str) == FAIL)
4232 inst.error = BAD_ARGS;
4236 if (skip_past_comma (& str) == FAIL
4237 || cp_opc_expr (& str, 20,4) == FAIL)
4240 inst.error = BAD_ARGS;
4244 if (skip_past_comma (& str) == FAIL
4245 || cp_reg_required_here (& str, 12) == FAIL)
4248 inst.error = BAD_ARGS;
4252 if (skip_past_comma (& str) == FAIL
4253 || cp_reg_required_here (& str, 16) == FAIL)
4256 inst.error = BAD_ARGS;
4260 if (skip_past_comma (& str) == FAIL
4261 || cp_reg_required_here (& str, 0) == FAIL)
4264 inst.error = BAD_ARGS;
4268 if (skip_past_comma (& str) == SUCCESS)
4270 if (cp_opc_expr (& str, 5, 3) == FAIL)
4273 inst.error = BAD_ARGS;
4281 /* ARM V5 (argument parse)
4282 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4283 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4284 Instruction is not conditional, and has 0xf in the condition field.
4285 Otherwise, it's the same as MCR/MRC. */
4291 skip_whitespace (str);
4293 if (co_proc_number (& str) == FAIL)
4296 inst.error = BAD_ARGS;
4300 if (skip_past_comma (& str) == FAIL
4301 || cp_opc_expr (& str, 21, 3) == FAIL)
4304 inst.error = BAD_ARGS;
4308 if (skip_past_comma (& str) == FAIL
4309 || reg_required_here (& str, 12) == FAIL)
4312 inst.error = BAD_ARGS;
4316 if (skip_past_comma (& str) == FAIL
4317 || cp_reg_required_here (& str, 16) == FAIL)
4320 inst.error = BAD_ARGS;
4324 if (skip_past_comma (& str) == FAIL
4325 || cp_reg_required_here (& str, 0) == FAIL)
4328 inst.error = BAD_ARGS;
4332 if (skip_past_comma (& str) == SUCCESS)
4334 if (cp_opc_expr (& str, 5, 3) == FAIL)
4337 inst.error = BAD_ARGS;
4345 /* ARM v5TEJ. Jump to Jazelle code. */
4352 skip_whitespace (str);
4354 if ((reg = reg_required_here (&str, 0)) == FAIL)
4356 inst.error = BAD_ARGS;
4360 /* Note - it is not illegal to do a "bxj pc". Useless, but not illegal. */
4362 as_tsktsk (_("use of r15 in bxj is not really useful"));
4367 /* THUMB V5 breakpoint instruction (argument parse)
4375 unsigned long number;
4377 skip_whitespace (str);
4379 /* Allow optional leading '#'. */
4380 if (is_immediate_prefix (*str))
4383 memset (& expr, '\0', sizeof (expr));
4384 if (my_get_expression (& expr, & str)
4385 || (expr.X_op != O_constant
4386 /* As a convenience we allow 'bkpt' without an operand. */
4387 && expr.X_op != O_absent))
4389 inst.error = _("bad expression");
4393 number = expr.X_add_number;
4395 /* Check it fits an 8 bit unsigned. */
4396 if (number != (number & 0xff))
4398 inst.error = _("immediate value out of range");
4402 inst.instruction |= number;
4407 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
4408 Expects inst.instruction is set for BLX(1).
4409 Note: this is cloned from do_branch, and the reloc changed to be a
4410 new one that can cope with setting one extra bit (the H bit). */
4416 if (my_get_expression (& inst.reloc.exp, & str))
4423 /* ScottB: February 5, 1998 */
4424 /* Check to see of PLT32 reloc required for the instruction. */
4426 /* arm_parse_reloc() works on input_line_pointer.
4427 We actually want to parse the operands to the branch instruction
4428 passed in 'str'. Save the input pointer and restore it later. */
4429 save_in = input_line_pointer;
4430 input_line_pointer = str;
4432 if (inst.reloc.exp.X_op == O_symbol
4434 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4436 inst.reloc.type = BFD_RELOC_ARM_PLT32;
4437 inst.reloc.pc_rel = 0;
4438 /* Modify str to point to after parsed operands, otherwise
4439 end_of_line() will complain about the (PLT) left in str. */
4440 str = input_line_pointer;
4444 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
4445 inst.reloc.pc_rel = 1;
4448 input_line_pointer = save_in;
4451 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
4452 inst.reloc.pc_rel = 1;
4453 #endif /* OBJ_ELF */
4458 /* ARM V5 branch-link-exchange instruction (argument parse)
4459 BLX <target_addr> ie BLX(1)
4460 BLX{<condition>} <Rm> ie BLX(2)
4461 Unfortunately, there are two different opcodes for this mnemonic.
4462 So, the insns[].value is not used, and the code here zaps values
4463 into inst.instruction.
4464 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
4473 skip_whitespace (mystr);
4474 rm = reg_required_here (& mystr, 0);
4476 /* The above may set inst.error. Ignore his opinion. */
4481 /* Arg is a register.
4482 Use the condition code our caller put in inst.instruction.
4483 Pass ourselves off as a BX with a funny opcode. */
4484 inst.instruction |= 0x012fff30;
4489 /* This must be is BLX <target address>, no condition allowed. */
4490 if (inst.instruction != COND_ALWAYS)
4492 inst.error = BAD_COND;
4496 inst.instruction = 0xfafffffe;
4498 /* Process like a B/BL, but with a different reloc.
4499 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
4504 /* ARM V5 Thumb BLX (argument parse)
4505 BLX <target_addr> which is BLX(1)
4506 BLX <Rm> which is BLX(2)
4507 Unfortunately, there are two different opcodes for this mnemonic.
4508 So, the tinsns[].value is not used, and the code here zaps values
4509 into inst.instruction. */
4518 skip_whitespace (mystr);
4519 inst.instruction = 0x4780;
4521 /* Note that this call is to the ARM register recognizer. BLX(2)
4522 uses the ARM register space, not the Thumb one, so a call to
4523 thumb_reg() would be wrong. */
4524 rm = reg_required_here (& mystr, 3);
4529 /* It's BLX(2). The .instruction was zapped with rm & is final. */
4534 /* No ARM register. This must be BLX(1). Change the .instruction. */
4535 inst.instruction = 0xf7ffeffe;
4538 if (my_get_expression (& inst.reloc.exp, & mystr))
4541 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
4542 inst.reloc.pc_rel = 1;
4545 end_of_line (mystr);
4548 /* ARM V5 breakpoint instruction (argument parse)
4549 BKPT <16 bit unsigned immediate>
4550 Instruction is not conditional.
4551 The bit pattern given in insns[] has the COND_ALWAYS condition,
4552 and it is an error if the caller tried to override that. */
4559 unsigned long number;
4561 skip_whitespace (str);
4563 /* Allow optional leading '#'. */
4564 if (is_immediate_prefix (* str))
4567 memset (& expr, '\0', sizeof (expr));
4569 if (my_get_expression (& expr, & str)
4570 || (expr.X_op != O_constant
4571 /* As a convenience we allow 'bkpt' without an operand. */
4572 && expr.X_op != O_absent))
4574 inst.error = _("bad expression");
4578 number = expr.X_add_number;
4580 /* Check it fits a 16 bit unsigned. */
4581 if (number != (number & 0xffff))
4583 inst.error = _("immediate value out of range");
4587 /* Top 12 of 16 bits to bits 19:8. */
4588 inst.instruction |= (number & 0xfff0) << 4;
4590 /* Bottom 4 of 16 bits to bits 3:0. */
4591 inst.instruction |= number & 0xf;
4596 static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
4598 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate. */
4600 static unsigned long
4601 check_iwmmxt_insn (str, insn_type, immediate_size)
4603 enum iwmmxt_insn_type insn_type;
4607 const char * inst_error;
4609 unsigned long number;
4611 inst_error = inst.error;
4613 inst.error = BAD_ARGS;
4614 skip_whitespace (str);
4619 if ((reg = reg_required_here (&str, 12)) == FAIL)
4624 if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
4629 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4630 || skip_past_comma (&str) == FAIL
4631 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
4636 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4637 || skip_past_comma (&str) == FAIL
4638 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4639 || skip_past_comma (&str) == FAIL
4640 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
4645 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4646 || skip_past_comma (&str) == FAIL
4647 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4648 || skip_past_comma (&str) == FAIL
4649 || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
4654 if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4655 || skip_past_comma (&str) == FAIL
4656 || reg_required_here (&str, 12) == FAIL))
4661 if ((reg_required_here (&str, 12) == FAIL
4662 || skip_past_comma (&str) == FAIL
4663 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
4668 if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
4669 || skip_past_comma (&str) == FAIL
4670 || reg_required_here (&str, 0) == FAIL
4671 || skip_past_comma (&str) == FAIL
4672 || reg_required_here (&str, 12) == FAIL))
4677 if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
4678 || skip_past_comma (&str) == FAIL
4679 || reg_required_here (&str, 12) == FAIL
4680 || skip_past_comma (&str) == FAIL
4681 || reg_required_here (&str, 16) == FAIL))
4686 if ((reg_required_here (&str, 12) == FAIL
4687 || skip_past_comma (&str) == FAIL
4688 || reg_required_here (&str, 16) == FAIL
4689 || skip_past_comma (&str) == FAIL
4690 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
4695 if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
4696 || skip_past_comma (&str) == FAIL
4697 || reg_required_here (&str, 12) == FAIL))
4702 if ((reg_required_here (&str, 12) == FAIL
4703 || skip_past_comma (&str) == FAIL
4704 || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
4709 if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4710 || skip_past_comma (&str) == FAIL
4711 || reg_required_here (&str, 12) == FAIL
4712 || skip_past_comma (&str) == FAIL))
4717 if ((reg_required_here (&str, 12) == FAIL
4718 || skip_past_comma (&str) == FAIL))
4723 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4724 || skip_past_comma (&str) == FAIL
4725 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4726 || skip_past_comma (&str) == FAIL
4727 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
4728 || skip_past_comma (&str) == FAIL))
4733 if ((reg_required_here (&str, 12) == FAIL
4734 || skip_past_comma (&str) == FAIL
4735 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4736 || skip_past_comma (&str) == FAIL))
4741 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4742 || skip_past_comma (&str) == FAIL
4743 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4744 || skip_past_comma (&str) == FAIL))
4749 if (immediate_size == 0)
4752 inst.error = inst_error;
4757 skip_whitespace (str);
4759 /* Allow optional leading '#'. */
4760 if (is_immediate_prefix (* str))
4763 memset (& expr, '\0', sizeof (expr));
4765 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
4767 inst.error = _("bad or missing expression");
4771 number = expr.X_add_number;
4773 if (number != (number & immediate_size))
4775 inst.error = _("immediate value out of range");
4779 inst.error = inst_error;
4785 do_iwmmxt_byte_addr (str)
4788 int op = (inst.instruction & 0x300) >> 8;
4791 inst.instruction &= ~0x300;
4792 inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
4794 skip_whitespace (str);
4796 if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
4797 || skip_past_comma (& str) == FAIL
4798 || cp_byte_address_required_here (&str) == FAIL)
4801 inst.error = BAD_ARGS;
4806 if (wc_register (reg))
4808 inst.instruction |= 0xf0000100;
4809 inst.instruction &= ~0x00400000;
4814 do_iwmmxt_tandc (str)
4819 reg = check_iwmmxt_insn (str, check_rd, 0);
4821 if (reg != REG_PC && !inst.error)
4822 inst.error = _("only r15 allowed here");
4827 do_iwmmxt_tbcst (str)
4830 check_iwmmxt_insn (str, check_tbcst, 0);
4836 do_iwmmxt_textrc (str)
4839 unsigned long number;
4841 if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
4844 inst.instruction |= number & 0x7;
4849 do_iwmmxt_textrm (str)
4852 unsigned long number;
4854 if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
4857 inst.instruction |= number & 0x7;
4861 do_iwmmxt_tinsr (str)
4864 unsigned long number;
4866 if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
4869 inst.instruction |= number & 0x7;
4874 do_iwmmxt_tmcr (str)
4877 check_iwmmxt_insn (str, check_tmcr, 0);
4883 do_iwmmxt_tmcrr (str)
4886 check_iwmmxt_insn (str, check_tmcrr, 0);
4892 do_iwmmxt_tmia (str)
4895 check_iwmmxt_insn (str, check_tmia, 0);
4901 do_iwmmxt_tmovmsk (str)
4904 check_iwmmxt_insn (str, check_tmovmsk, 0);
4910 do_iwmmxt_tmrc (str)
4913 check_iwmmxt_insn (str, check_tmrc, 0);
4919 do_iwmmxt_tmrrc (str)
4922 check_iwmmxt_insn (str, check_tmrrc, 0);
4928 do_iwmmxt_torc (str)
4931 check_iwmmxt_insn (str, check_rd, 0);
4936 do_iwmmxt_waligni (str)
4939 unsigned long number;
4941 if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
4944 inst.instruction |= ((number & 0x7) << 20);
4949 do_iwmmxt_wmov (str)
4952 if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
4955 inst.instruction |= ((inst.instruction >> 16) & 0xf);
4960 do_iwmmxt_word_addr (str)
4963 int op = (inst.instruction & 0x300) >> 8;
4966 inst.instruction &= ~0x300;
4967 inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
4969 skip_whitespace (str);
4971 if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
4972 || skip_past_comma (& str) == FAIL
4973 || cp_address_required_here (& str, CP_WB_OK) == FAIL)
4976 inst.error = BAD_ARGS;
4981 if (wc_register (reg))
4983 inst.instruction |= 0xf0000100;
4984 inst.instruction &= ~0x00400000;
4989 do_iwmmxt_wrwr (str)
4992 check_iwmmxt_insn (str, check_wrwr, 0);
4998 do_iwmmxt_wrwrwcg (str)
5001 check_iwmmxt_insn (str, check_wrwrwcg, 0);
5007 do_iwmmxt_wrwrwr (str)
5010 check_iwmmxt_insn (str, check_wrwrwr, 0);
5016 do_iwmmxt_wshufh (str)
5019 unsigned long number;
5021 if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
5024 inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
5029 do_iwmmxt_wzero (str)
5032 if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
5035 inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
5039 /* Xscale multiply-accumulate (argument parse)
5042 MIAxycc acc0,Rm,Rs. */
5051 if (accum0_required_here (& str) == FAIL)
5052 inst.error = ERR_NO_ACCUM;
5054 else if (skip_past_comma (& str) == FAIL
5055 || (rm = reg_required_here (& str, 0)) == FAIL)
5056 inst.error = BAD_ARGS;
5058 else if (skip_past_comma (& str) == FAIL
5059 || (rs = reg_required_here (& str, 12)) == FAIL)
5060 inst.error = BAD_ARGS;
5062 /* inst.instruction has now been zapped with both rm and rs. */
5063 else if (rm == REG_PC || rs == REG_PC)
5064 inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */
5070 /* Xscale move-accumulator-register (argument parse)
5072 MARcc acc0,RdLo,RdHi. */
5080 if (accum0_required_here (& str) == FAIL)
5081 inst.error = ERR_NO_ACCUM;
5083 else if (skip_past_comma (& str) == FAIL
5084 || (rdlo = reg_required_here (& str, 12)) == FAIL)
5085 inst.error = BAD_ARGS;
5087 else if (skip_past_comma (& str) == FAIL
5088 || (rdhi = reg_required_here (& str, 16)) == FAIL)
5089 inst.error = BAD_ARGS;
5091 /* inst.instruction has now been zapped with both rdlo and rdhi. */
5092 else if (rdlo == REG_PC || rdhi == REG_PC)
5093 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
5099 /* Xscale move-register-accumulator (argument parse)
5101 MRAcc RdLo,RdHi,acc0. */
5110 skip_whitespace (str);
5112 if ((rdlo = reg_required_here (& str, 12)) == FAIL)
5113 inst.error = BAD_ARGS;
5115 else if (skip_past_comma (& str) == FAIL
5116 || (rdhi = reg_required_here (& str, 16)) == FAIL)
5117 inst.error = BAD_ARGS;
5119 else if (skip_past_comma (& str) == FAIL
5120 || accum0_required_here (& str) == FAIL)
5121 inst.error = ERR_NO_ACCUM;
5123 /* inst.instruction has now been zapped with both rdlo and rdhi. */
5124 else if (rdlo == rdhi)
5125 inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */
5127 else if (rdlo == REG_PC || rdhi == REG_PC)
5128 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
5133 /* ARMv5TE: Preload-Cache
5137 Syntactically, like LDR with B=1, W=0, L=1. */
5145 skip_whitespace (str);
5149 inst.error = _("'[' expected after PLD mnemonic");
5154 skip_whitespace (str);
5156 if ((rd = reg_required_here (& str, 16)) == FAIL)
5159 skip_whitespace (str);
5165 skip_whitespace (str);
5167 /* Post-indexed addressing is not allowed with PLD. */
5168 if (skip_past_comma (&str) == SUCCESS)
5171 = _("post-indexed expression used in preload instruction");
5174 else if (*str == '!') /* [Rn]! */
5176 inst.error = _("writeback used in preload instruction");
5180 inst.instruction |= INDEX_UP | PRE_INDEX;
5182 else /* [Rn, ...] */
5184 if (skip_past_comma (& str) == FAIL)
5186 inst.error = _("pre-indexed expression expected");
5190 if (ldst_extend (&str) == FAIL)
5193 skip_whitespace (str);
5197 inst.error = _("missing ]");
5202 skip_whitespace (str);
5204 if (* str == '!') /* [Rn]! */
5206 inst.error = _("writeback used in preload instruction");
5210 inst.instruction |= PRE_INDEX;
5216 /* ARMv5TE load-consecutive (argument parse)
5229 skip_whitespace (str);
5231 if ((rd = reg_required_here (& str, 12)) == FAIL)
5233 inst.error = BAD_ARGS;
5237 if (skip_past_comma (& str) == FAIL
5238 || (rn = ld_mode_required_here (& str)) == FAIL)
5241 inst.error = BAD_ARGS;
5245 /* inst.instruction has now been zapped with Rd and the addressing mode. */
5246 if (rd & 1) /* Unpredictable result if Rd is odd. */
5248 inst.error = _("destination register must be even");
5254 inst.error = _("r14 not allowed here");
5258 if (((rd == rn) || (rd + 1 == rn))
5259 && ((inst.instruction & WRITE_BACK)
5260 || (!(inst.instruction & PRE_INDEX))))
5261 as_warn (_("pre/post-indexing used when modified address register is destination"));
5263 /* For an index-register load, the index register must not overlap the
5264 destination (even if not write-back). */
5265 if ((inst.instruction & V4_STR_BIT) == 0
5266 && (inst.instruction & HWOFFSET_IMM) == 0)
5268 int rm = inst.instruction & 0x0000000f;
5270 if (rm == rd || (rm == rd + 1))
5271 as_warn (_("ldrd destination registers must not overlap index register"));
5277 /* Returns the index into fp_values of a floating point number,
5278 or -1 if not in the table. */
5281 my_get_float_expression (str)
5284 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5290 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
5292 /* Look for a raw floating point number. */
5293 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5294 && is_end_of_line[(unsigned char) *save_in])
5296 for (i = 0; i < NUM_FLOAT_VALS; i++)
5298 for (j = 0; j < MAX_LITTLENUMS; j++)
5300 if (words[j] != fp_values[i][j])
5304 if (j == MAX_LITTLENUMS)
5312 /* Try and parse a more complex expression, this will probably fail
5313 unless the code uses a floating point prefix (eg "0f"). */
5314 save_in = input_line_pointer;
5315 input_line_pointer = *str;
5316 if (expression (&exp) == absolute_section
5317 && exp.X_op == O_big
5318 && exp.X_add_number < 0)
5320 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5322 if (gen_to_words (words, 5, (long) 15) == 0)
5324 for (i = 0; i < NUM_FLOAT_VALS; i++)
5326 for (j = 0; j < MAX_LITTLENUMS; j++)
5328 if (words[j] != fp_values[i][j])
5332 if (j == MAX_LITTLENUMS)
5334 *str = input_line_pointer;
5335 input_line_pointer = save_in;
5342 *str = input_line_pointer;
5343 input_line_pointer = save_in;
5347 /* Return TRUE if anything in the expression is a bignum. */
5350 walk_no_bignums (sp)
5353 if (symbol_get_value_expression (sp)->X_op == O_big)
5356 if (symbol_get_value_expression (sp)->X_add_symbol)
5358 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
5359 || (symbol_get_value_expression (sp)->X_op_symbol
5360 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
5366 static int in_my_get_expression = 0;
5369 my_get_expression (ep, str)
5376 save_in = input_line_pointer;
5377 input_line_pointer = *str;
5378 in_my_get_expression = 1;
5379 seg = expression (ep);
5380 in_my_get_expression = 0;
5382 if (ep->X_op == O_illegal)
5384 /* We found a bad expression in md_operand(). */
5385 *str = input_line_pointer;
5386 input_line_pointer = save_in;
5391 if (seg != absolute_section
5392 && seg != text_section
5393 && seg != data_section
5394 && seg != bss_section
5395 && seg != undefined_section)
5397 inst.error = _("bad_segment");
5398 *str = input_line_pointer;
5399 input_line_pointer = save_in;
5404 /* Get rid of any bignums now, so that we don't generate an error for which
5405 we can't establish a line number later on. Big numbers are never valid
5406 in instructions, which is where this routine is always called. */
5407 if (ep->X_op == O_big
5408 || (ep->X_add_symbol
5409 && (walk_no_bignums (ep->X_add_symbol)
5411 && walk_no_bignums (ep->X_op_symbol)))))
5413 inst.error = _("invalid constant");
5414 *str = input_line_pointer;
5415 input_line_pointer = save_in;
5419 *str = input_line_pointer;
5420 input_line_pointer = save_in;
5424 /* We handle all bad expressions here, so that we can report the faulty
5425 instruction in the error message. */
5430 if (in_my_get_expression)
5432 expr->X_op = O_illegal;
5433 if (inst.error == NULL)
5434 inst.error = _("bad expression");
5438 /* UNRESTRICT should be one if <shift> <register> is permitted for this
5442 decode_shift (str, unrestrict)
5446 const struct asm_shift_name * shift;
5450 skip_whitespace (* str);
5452 for (p = * str; ISALPHA (* p); p ++)
5457 inst.error = _("shift expression expected");
5463 shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
5468 inst.error = _("shift expression expected");
5472 assert (shift->properties->index == shift_properties[shift->properties->index].index);
5474 if (shift->properties->index == SHIFT_RRX)
5477 inst.instruction |= shift->properties->bit_field;
5481 skip_whitespace (p);
5483 if (unrestrict && reg_required_here (& p, 8) != FAIL)
5485 inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
5489 else if (! is_immediate_prefix (* p))
5491 inst.error = (unrestrict
5492 ? _("shift requires register or #expression")
5493 : _("shift requires #expression"));
5501 if (my_get_expression (& inst.reloc.exp, & p))
5504 /* Validate some simple #expressions. */
5505 if (inst.reloc.exp.X_op == O_constant)
5507 unsigned num = inst.reloc.exp.X_add_number;
5509 /* Reject operations greater than 32. */
5511 /* Reject a shift of 0 unless the mode allows it. */
5512 || (num == 0 && shift->properties->allows_0 == 0)
5513 /* Reject a shift of 32 unless the mode allows it. */
5514 || (num == 32 && shift->properties->allows_32 == 0)
5517 /* As a special case we allow a shift of zero for
5518 modes that do not support it to be recoded as an
5519 logical shift left of zero (ie nothing). We warn
5520 about this though. */
5523 as_warn (_("shift of 0 ignored."));
5524 shift = & shift_names[0];
5525 assert (shift->properties->index == SHIFT_LSL);
5529 inst.error = _("invalid immediate shift");
5534 /* Shifts of 32 are encoded as 0, for those shifts that
5539 inst.instruction |= (num << 7) | shift->properties->bit_field;
5543 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
5544 inst.reloc.pc_rel = 0;
5545 inst.instruction |= shift->properties->bit_field;
5552 /* Do those data_ops which can take a negative immediate constant
5553 by altering the instuction. A bit of a hack really.
5557 by inverting the second operand, and
5560 by negating the second operand. */
5563 negate_data_op (instruction, value)
5564 unsigned long * instruction;
5565 unsigned long value;
5568 unsigned long negated, inverted;
5570 negated = validate_immediate (-value);
5571 inverted = validate_immediate (~value);
5573 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
5576 /* First negates. */
5577 case OPCODE_SUB: /* ADD <-> SUB */
5578 new_inst = OPCODE_ADD;
5583 new_inst = OPCODE_SUB;
5587 case OPCODE_CMP: /* CMP <-> CMN */
5588 new_inst = OPCODE_CMN;
5593 new_inst = OPCODE_CMP;
5597 /* Now Inverted ops. */
5598 case OPCODE_MOV: /* MOV <-> MVN */
5599 new_inst = OPCODE_MVN;
5604 new_inst = OPCODE_MOV;
5608 case OPCODE_AND: /* AND <-> BIC */
5609 new_inst = OPCODE_BIC;
5614 new_inst = OPCODE_AND;
5618 case OPCODE_ADC: /* ADC <-> SBC */
5619 new_inst = OPCODE_SBC;
5624 new_inst = OPCODE_ADC;
5628 /* We cannot do anything. */
5633 if (value == (unsigned) FAIL)
5636 *instruction &= OPCODE_MASK;
5637 *instruction |= new_inst << DATA_OP_SHIFT;
5648 skip_whitespace (* str);
5650 if (reg_required_here (str, 0) != FAIL)
5652 if (skip_past_comma (str) == SUCCESS)
5653 /* Shift operation on register. */
5654 return decode_shift (str, NO_SHIFT_RESTRICT);
5660 /* Immediate expression. */
5661 if (is_immediate_prefix (**str))
5666 if (my_get_expression (&inst.reloc.exp, str))
5669 if (inst.reloc.exp.X_add_symbol)
5671 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5672 inst.reloc.pc_rel = 0;
5676 if (skip_past_comma (str) == SUCCESS)
5678 /* #x, y -- ie explicit rotation by Y. */
5679 if (my_get_expression (&expr, str))
5682 if (expr.X_op != O_constant)
5684 inst.error = _("constant expression expected");
5688 /* Rotate must be a multiple of 2. */
5689 if (((unsigned) expr.X_add_number) > 30
5690 || (expr.X_add_number & 1) != 0
5691 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
5693 inst.error = _("invalid constant");
5696 inst.instruction |= INST_IMMEDIATE;
5697 inst.instruction |= inst.reloc.exp.X_add_number;
5698 inst.instruction |= expr.X_add_number << 7;
5702 /* Implicit rotation, select a suitable one. */
5703 value = validate_immediate (inst.reloc.exp.X_add_number);
5707 /* Can't be done. Perhaps the code reads something like
5708 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
5709 if ((value = negate_data_op (&inst.instruction,
5710 inst.reloc.exp.X_add_number))
5713 inst.error = _("invalid constant");
5718 inst.instruction |= value;
5721 inst.instruction |= INST_IMMEDIATE;
5726 inst.error = _("register or shift expression expected");
5735 skip_whitespace (* str);
5737 if (fp_reg_required_here (str, 0) != FAIL)
5741 /* Immediate expression. */
5742 if (*((*str)++) == '#')
5748 skip_whitespace (* str);
5750 /* First try and match exact strings, this is to guarantee
5751 that some formats will work even for cross assembly. */
5753 for (i = 0; fp_const[i]; i++)
5755 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
5759 *str += strlen (fp_const[i]);
5760 if (is_end_of_line[(unsigned char) **str])
5762 inst.instruction |= i + 8;
5769 /* Just because we didn't get a match doesn't mean that the
5770 constant isn't valid, just that it is in a format that we
5771 don't automatically recognize. Try parsing it with
5772 the standard expression routines. */
5773 if ((i = my_get_float_expression (str)) >= 0)
5775 inst.instruction |= i + 8;
5779 inst.error = _("invalid floating point immediate expression");
5783 _("floating point register or immediate expression expected");
5792 skip_whitespace (str);
5794 if (reg_required_here (&str, 12) == FAIL
5795 || skip_past_comma (&str) == FAIL
5796 || reg_required_here (&str, 16) == FAIL
5797 || skip_past_comma (&str) == FAIL
5798 || data_op2 (&str) == FAIL)
5801 inst.error = BAD_ARGS;
5813 /* This is a pseudo-op of the form "adr rd, label" to be converted
5814 into a relative address of the form "add rd, pc, #label-.-8". */
5815 skip_whitespace (str);
5817 if (reg_required_here (&str, 12) == FAIL
5818 || skip_past_comma (&str) == FAIL
5819 || my_get_expression (&inst.reloc.exp, &str))
5822 inst.error = BAD_ARGS;
5826 /* Frag hacking will turn this into a sub instruction if the offset turns
5827 out to be negative. */
5828 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5829 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
5830 inst.reloc.pc_rel = 1;
5839 /* This is a pseudo-op of the form "adrl rd, label" to be converted
5840 into a relative address of the form:
5841 add rd, pc, #low(label-.-8)"
5842 add rd, rd, #high(label-.-8)" */
5844 skip_whitespace (str);
5846 if (reg_required_here (&str, 12) == FAIL
5847 || skip_past_comma (&str) == FAIL
5848 || my_get_expression (&inst.reloc.exp, &str))
5851 inst.error = BAD_ARGS;
5857 /* Frag hacking will turn this into a sub instruction if the offset turns
5858 out to be negative. */
5859 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
5860 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
5861 inst.reloc.pc_rel = 1;
5862 inst.size = INSN_SIZE * 2;
5871 skip_whitespace (str);
5873 if (reg_required_here (&str, 16) == FAIL)
5876 inst.error = BAD_ARGS;
5880 if (skip_past_comma (&str) == FAIL
5881 || data_op2 (&str) == FAIL)
5884 inst.error = BAD_ARGS;
5896 skip_whitespace (str);
5898 if (reg_required_here (&str, 12) == FAIL)
5901 inst.error = BAD_ARGS;
5905 if (skip_past_comma (&str) == FAIL
5906 || data_op2 (&str) == FAIL)
5909 inst.error = BAD_ARGS;
5928 if (my_get_expression (& inst.reloc.exp, str))
5931 if (inst.reloc.exp.X_op == O_constant)
5933 int value = inst.reloc.exp.X_add_number;
5935 if (value < -4095 || value > 4095)
5937 inst.error = _("address offset too large");
5947 inst.instruction |= add | value;
5951 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5952 inst.reloc.pc_rel = 0;
5965 if (reg_required_here (str, 0) == FAIL)
5968 inst.instruction |= add | OFFSET_REG;
5969 if (skip_past_comma (str) == SUCCESS)
5970 return decode_shift (str, SHIFT_RESTRICT);
5984 skip_whitespace (str);
5986 if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
5989 inst.error = BAD_ARGS;
5993 if (skip_past_comma (&str) == FAIL)
5995 inst.error = _("address expected");
6005 skip_whitespace (str);
6007 if ((reg = reg_required_here (&str, 16)) == FAIL)
6010 /* Conflicts can occur on stores as well as loads. */
6011 conflict_reg = (conflict_reg == reg);
6013 skip_whitespace (str);
6019 if (skip_past_comma (&str) == SUCCESS)
6021 /* [Rn],... (post inc) */
6022 if (ldst_extend (&str) == FAIL)
6025 as_warn (_("%s register same as write-back base"),
6026 ((inst.instruction & LOAD_BIT)
6027 ? _("destination") : _("source")));
6032 skip_whitespace (str);
6037 as_warn (_("%s register same as write-back base"),
6038 ((inst.instruction & LOAD_BIT)
6039 ? _("destination") : _("source")));
6041 inst.instruction |= WRITE_BACK;
6044 inst.instruction |= INDEX_UP;
6051 if (skip_past_comma (&str) == FAIL)
6053 inst.error = _("pre-indexed expression expected");
6058 if (ldst_extend (&str) == FAIL)
6061 skip_whitespace (str);
6065 inst.error = _("missing ]");
6069 skip_whitespace (str);
6074 as_warn (_("%s register same as write-back base"),
6075 ((inst.instruction & LOAD_BIT)
6076 ? _("destination") : _("source")));
6078 inst.instruction |= WRITE_BACK;
6082 else if (*str == '=')
6084 if ((inst.instruction & LOAD_BIT) == 0)
6086 inst.error = _("invalid pseudo operation");
6090 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6093 skip_whitespace (str);
6095 if (my_get_expression (&inst.reloc.exp, &str))
6098 if (inst.reloc.exp.X_op != O_constant
6099 && inst.reloc.exp.X_op != O_symbol)
6101 inst.error = _("constant expression expected");
6105 if (inst.reloc.exp.X_op == O_constant)
6107 value = validate_immediate (inst.reloc.exp.X_add_number);
6111 /* This can be done with a mov instruction. */
6112 inst.instruction &= LITERAL_MASK;
6113 inst.instruction |= (INST_IMMEDIATE
6114 | (OPCODE_MOV << DATA_OP_SHIFT));
6115 inst.instruction |= value & 0xfff;
6120 value = validate_immediate (~inst.reloc.exp.X_add_number);
6124 /* This can be done with a mvn instruction. */
6125 inst.instruction &= LITERAL_MASK;
6126 inst.instruction |= (INST_IMMEDIATE
6127 | (OPCODE_MVN << DATA_OP_SHIFT));
6128 inst.instruction |= value & 0xfff;
6134 /* Insert into literal pool. */
6135 if (add_to_lit_pool () == FAIL)
6138 inst.error = _("literal pool insertion failed");
6142 /* Change the instruction exp to point to the pool. */
6143 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
6144 inst.reloc.pc_rel = 1;
6145 inst.instruction |= (REG_PC << 16);
6150 if (my_get_expression (&inst.reloc.exp, &str))
6153 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
6155 /* PC rel adjust. */
6156 inst.reloc.exp.X_add_number -= 8;
6158 inst.reloc.pc_rel = 1;
6159 inst.instruction |= (REG_PC << 16);
6163 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6174 skip_whitespace (str);
6176 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6179 inst.error = BAD_ARGS;
6183 if (skip_past_comma (& str) == FAIL)
6185 inst.error = _("address expected");
6195 skip_whitespace (str);
6197 if ((reg = reg_required_here (&str, 16)) == FAIL)
6200 /* ldrt/strt always use post-indexed addressing, so if the base is
6201 the same as Rd, we warn. */
6202 if (conflict_reg == reg)
6203 as_warn (_("%s register same as write-back base"),
6204 ((inst.instruction & LOAD_BIT)
6205 ? _("destination") : _("source")));
6207 skip_whitespace (str);
6213 if (skip_past_comma (&str) == SUCCESS)
6215 /* [Rn],... (post inc) */
6216 if (ldst_extend (&str) == FAIL)
6222 skip_whitespace (str);
6224 /* Skip a write-back '!'. */
6228 inst.instruction |= INDEX_UP;
6233 inst.error = _("post-indexed expression expected");
6239 inst.error = _("post-indexed expression expected");
6248 ldst_extend_v4 (str)
6258 if (my_get_expression (& inst.reloc.exp, str))
6261 if (inst.reloc.exp.X_op == O_constant)
6263 int value = inst.reloc.exp.X_add_number;
6265 if (value < -255 || value > 255)
6267 inst.error = _("address offset too large");
6277 /* Halfword and signextension instructions have the
6278 immediate value split across bits 11..8 and bits 3..0. */
6279 inst.instruction |= (add | HWOFFSET_IMM
6280 | ((value >> 4) << 8) | (value & 0xF));
6284 inst.instruction |= HWOFFSET_IMM;
6285 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6286 inst.reloc.pc_rel = 0;
6299 if (reg_required_here (str, 0) == FAIL)
6302 inst.instruction |= add;
6307 /* Halfword and signed-byte load/store operations. */
6316 skip_whitespace (str);
6318 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6321 inst.error = BAD_ARGS;
6325 if (skip_past_comma (& str) == FAIL)
6327 inst.error = _("address expected");
6337 skip_whitespace (str);
6339 if ((reg = reg_required_here (&str, 16)) == FAIL)
6342 /* Conflicts can occur on stores as well as loads. */
6343 conflict_reg = (conflict_reg == reg);
6345 skip_whitespace (str);
6351 if (skip_past_comma (&str) == SUCCESS)
6353 /* [Rn],... (post inc) */
6354 if (ldst_extend_v4 (&str) == FAIL)
6357 as_warn (_("%s register same as write-back base"),
6358 ((inst.instruction & LOAD_BIT)
6359 ? _("destination") : _("source")));
6364 inst.instruction |= HWOFFSET_IMM;
6366 skip_whitespace (str);
6371 as_warn (_("%s register same as write-back base"),
6372 ((inst.instruction & LOAD_BIT)
6373 ? _("destination") : _("source")));
6375 inst.instruction |= WRITE_BACK;
6378 inst.instruction |= INDEX_UP;
6385 if (skip_past_comma (&str) == FAIL)
6387 inst.error = _("pre-indexed expression expected");
6392 if (ldst_extend_v4 (&str) == FAIL)
6395 skip_whitespace (str);
6399 inst.error = _("missing ]");
6403 skip_whitespace (str);
6408 as_warn (_("%s register same as write-back base"),
6409 ((inst.instruction & LOAD_BIT)
6410 ? _("destination") : _("source")));
6412 inst.instruction |= WRITE_BACK;
6416 else if (*str == '=')
6418 if ((inst.instruction & LOAD_BIT) == 0)
6420 inst.error = _("invalid pseudo operation");
6424 /* XXX Does this work correctly for half-word/byte ops? */
6425 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6428 skip_whitespace (str);
6430 if (my_get_expression (&inst.reloc.exp, &str))
6433 if (inst.reloc.exp.X_op != O_constant
6434 && inst.reloc.exp.X_op != O_symbol)
6436 inst.error = _("constant expression expected");
6440 if (inst.reloc.exp.X_op == O_constant)
6442 value = validate_immediate (inst.reloc.exp.X_add_number);
6446 /* This can be done with a mov instruction. */
6447 inst.instruction &= LITERAL_MASK;
6448 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
6449 inst.instruction |= value & 0xfff;
6454 value = validate_immediate (~ inst.reloc.exp.X_add_number);
6458 /* This can be done with a mvn instruction. */
6459 inst.instruction &= LITERAL_MASK;
6460 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
6461 inst.instruction |= value & 0xfff;
6467 /* Insert into literal pool. */
6468 if (add_to_lit_pool () == FAIL)
6471 inst.error = _("literal pool insertion failed");
6475 /* Change the instruction exp to point to the pool. */
6476 inst.instruction |= HWOFFSET_IMM;
6477 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
6478 inst.reloc.pc_rel = 1;
6479 inst.instruction |= (REG_PC << 16);
6484 if (my_get_expression (&inst.reloc.exp, &str))
6487 inst.instruction |= HWOFFSET_IMM;
6488 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6490 /* PC rel adjust. */
6491 inst.reloc.exp.X_add_number -= 8;
6493 inst.reloc.pc_rel = 1;
6494 inst.instruction |= (REG_PC << 16);
6498 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6507 char * str = * strp;
6511 /* We come back here if we get ranges concatenated by '+' or '|'. */
6526 skip_whitespace (str);
6528 if ((reg = reg_required_here (& str, -1)) == FAIL)
6537 inst.error = _("bad range in register list");
6541 for (i = cur_reg + 1; i < reg; i++)
6543 if (range & (1 << i))
6545 (_("Warning: duplicated register (r%d) in register list"),
6553 if (range & (1 << reg))
6554 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
6556 else if (reg <= cur_reg)
6557 as_tsktsk (_("Warning: register range not in ascending order"));
6562 while (skip_past_comma (&str) != FAIL
6563 || (in_range = 1, *str++ == '-'));
6565 skip_whitespace (str);
6569 inst.error = _("missing `}'");
6577 if (my_get_expression (&expr, &str))
6580 if (expr.X_op == O_constant)
6582 if (expr.X_add_number
6583 != (expr.X_add_number & 0x0000ffff))
6585 inst.error = _("invalid register mask");
6589 if ((range & expr.X_add_number) != 0)
6591 int regno = range & expr.X_add_number;
6594 regno = (1 << regno) - 1;
6596 (_("Warning: duplicated register (r%d) in register list"),
6600 range |= expr.X_add_number;
6604 if (inst.reloc.type != 0)
6606 inst.error = _("expression too complex");
6610 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
6611 inst.reloc.type = BFD_RELOC_ARM_MULTI;
6612 inst.reloc.pc_rel = 0;
6616 skip_whitespace (str);
6618 if (*str == '|' || *str == '+')
6624 while (another_range);
6637 skip_whitespace (str);
6639 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
6642 if (base_reg == REG_PC)
6644 inst.error = _("r15 not allowed as base register");
6648 skip_whitespace (str);
6652 inst.instruction |= WRITE_BACK;
6656 if (skip_past_comma (&str) == FAIL
6657 || (range = reg_list (&str)) == FAIL)
6660 inst.error = BAD_ARGS;
6667 inst.instruction |= LDM_TYPE_2_OR_3;
6670 if (inst.instruction & WRITE_BACK)
6672 /* Check for unpredictable uses of writeback. */
6673 if (inst.instruction & LOAD_BIT)
6675 /* Not allowed in LDM type 2. */
6676 if ((inst.instruction & LDM_TYPE_2_OR_3)
6677 && ((range & (1 << REG_PC)) == 0))
6678 as_warn (_("writeback of base register is UNPREDICTABLE"));
6679 /* Only allowed if base reg not in list for other types. */
6680 else if (range & (1 << base_reg))
6681 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
6685 /* Not allowed for type 2. */
6686 if (inst.instruction & LDM_TYPE_2_OR_3)
6687 as_warn (_("writeback of base register is UNPREDICTABLE"));
6688 /* Only allowed if base reg not in list, or first in list. */
6689 else if ((range & (1 << base_reg))
6690 && (range & ((1 << base_reg) - 1)))
6691 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
6695 inst.instruction |= range;
6704 skip_whitespace (str);
6706 /* Allow optional leading '#'. */
6707 if (is_immediate_prefix (*str))
6710 if (my_get_expression (& inst.reloc.exp, & str))
6713 inst.reloc.type = BFD_RELOC_ARM_SWI;
6714 inst.reloc.pc_rel = 0;
6726 skip_whitespace (str);
6728 if ((reg = reg_required_here (&str, 12)) == FAIL)
6733 inst.error = _("r15 not allowed in swap");
6737 if (skip_past_comma (&str) == FAIL
6738 || (reg = reg_required_here (&str, 0)) == FAIL)
6741 inst.error = BAD_ARGS;
6747 inst.error = _("r15 not allowed in swap");
6751 if (skip_past_comma (&str) == FAIL
6754 inst.error = BAD_ARGS;
6758 skip_whitespace (str);
6760 if ((reg = reg_required_here (&str, 16)) == FAIL)
6765 inst.error = BAD_PC;
6769 skip_whitespace (str);
6773 inst.error = _("missing ]");
6785 if (my_get_expression (&inst.reloc.exp, &str))
6792 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
6793 required for the instruction. */
6795 /* arm_parse_reloc () works on input_line_pointer.
6796 We actually want to parse the operands to the branch instruction
6797 passed in 'str'. Save the input pointer and restore it later. */
6798 save_in = input_line_pointer;
6799 input_line_pointer = str;
6800 if (inst.reloc.exp.X_op == O_symbol
6802 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
6804 inst.reloc.type = BFD_RELOC_ARM_PLT32;
6805 inst.reloc.pc_rel = 0;
6806 /* Modify str to point to after parsed operands, otherwise
6807 end_of_line() will complain about the (PLT) left in str. */
6808 str = input_line_pointer;
6812 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
6813 inst.reloc.pc_rel = 1;
6815 input_line_pointer = save_in;
6818 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
6819 inst.reloc.pc_rel = 1;
6820 #endif /* OBJ_ELF */
6832 skip_whitespace (str);
6834 if ((reg = reg_required_here (&str, 0)) == FAIL)
6836 inst.error = BAD_ARGS;
6840 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
6842 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
6851 /* Co-processor data operation.
6852 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
6853 skip_whitespace (str);
6855 if (co_proc_number (&str) == FAIL)
6858 inst.error = BAD_ARGS;
6862 if (skip_past_comma (&str) == FAIL
6863 || cp_opc_expr (&str, 20,4) == FAIL)
6866 inst.error = BAD_ARGS;
6870 if (skip_past_comma (&str) == FAIL
6871 || cp_reg_required_here (&str, 12) == FAIL)
6874 inst.error = BAD_ARGS;
6878 if (skip_past_comma (&str) == FAIL
6879 || cp_reg_required_here (&str, 16) == FAIL)
6882 inst.error = BAD_ARGS;
6886 if (skip_past_comma (&str) == FAIL
6887 || cp_reg_required_here (&str, 0) == FAIL)
6890 inst.error = BAD_ARGS;
6894 if (skip_past_comma (&str) == SUCCESS)
6896 if (cp_opc_expr (&str, 5, 3) == FAIL)
6899 inst.error = BAD_ARGS;
6912 /* Co-processor register load/store.
6913 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
6915 skip_whitespace (str);
6917 if (co_proc_number (&str) == FAIL)
6920 inst.error = BAD_ARGS;
6924 if (skip_past_comma (&str) == FAIL
6925 || cp_reg_required_here (&str, 12) == FAIL)
6928 inst.error = BAD_ARGS;
6932 if (skip_past_comma (&str) == FAIL
6933 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6936 inst.error = BAD_ARGS;
6948 /* Co-processor register transfer.
6949 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
6951 skip_whitespace (str);
6953 if (co_proc_number (&str) == FAIL)
6956 inst.error = BAD_ARGS;
6960 if (skip_past_comma (&str) == FAIL
6961 || cp_opc_expr (&str, 21, 3) == FAIL)
6964 inst.error = BAD_ARGS;
6968 if (skip_past_comma (&str) == FAIL
6969 || reg_required_here (&str, 12) == FAIL)
6972 inst.error = BAD_ARGS;
6976 if (skip_past_comma (&str) == FAIL
6977 || cp_reg_required_here (&str, 16) == FAIL)
6980 inst.error = BAD_ARGS;
6984 if (skip_past_comma (&str) == FAIL
6985 || cp_reg_required_here (&str, 0) == FAIL)
6988 inst.error = BAD_ARGS;
6992 if (skip_past_comma (&str) == SUCCESS)
6994 if (cp_opc_expr (&str, 5, 3) == FAIL)
6997 inst.error = BAD_ARGS;
7010 /* FP control registers.
7011 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
7013 skip_whitespace (str);
7015 if (reg_required_here (&str, 12) == FAIL)
7018 inst.error = BAD_ARGS;
7030 skip_whitespace (str);
7032 if (fp_reg_required_here (&str, 12) == FAIL)
7035 inst.error = BAD_ARGS;
7039 if (skip_past_comma (&str) == FAIL
7040 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7043 inst.error = BAD_ARGS;
7056 skip_whitespace (str);
7058 if (fp_reg_required_here (&str, 12) == FAIL)
7061 inst.error = BAD_ARGS;
7065 /* Get Number of registers to transfer. */
7066 if (skip_past_comma (&str) == FAIL
7067 || my_get_expression (&inst.reloc.exp, &str))
7070 inst.error = _("constant expression expected");
7074 if (inst.reloc.exp.X_op != O_constant)
7076 inst.error = _("constant value required for number of registers");
7080 num_regs = inst.reloc.exp.X_add_number;
7082 if (num_regs < 1 || num_regs > 4)
7084 inst.error = _("number of registers must be in the range [1:4]");
7091 inst.instruction |= CP_T_X;
7094 inst.instruction |= CP_T_Y;
7097 inst.instruction |= CP_T_Y | CP_T_X;
7105 if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format. */
7111 /* The instruction specified "ea" or "fd", so we can only accept
7112 [Rn]{!}. The instruction does not really support stacking or
7113 unstacking, so we have to emulate these by setting appropriate
7114 bits and offsets. */
7115 if (skip_past_comma (&str) == FAIL
7119 inst.error = BAD_ARGS;
7124 skip_whitespace (str);
7126 if ((reg = reg_required_here (&str, 16)) == FAIL)
7129 skip_whitespace (str);
7133 inst.error = BAD_ARGS;
7145 _("r15 not allowed as base register with write-back");
7152 if (inst.instruction & CP_T_Pre)
7154 /* Pre-decrement. */
7155 offset = 3 * num_regs;
7157 inst.instruction |= CP_T_WB;
7161 /* Post-increment. */
7164 inst.instruction |= CP_T_WB;
7165 offset = 3 * num_regs;
7169 /* No write-back, so convert this into a standard pre-increment
7170 instruction -- aesthetically more pleasing. */
7171 inst.instruction |= CP_T_Pre | CP_T_UD;
7176 inst.instruction |= offset;
7178 else if (skip_past_comma (&str) == FAIL
7179 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7182 inst.error = BAD_ARGS;
7193 skip_whitespace (str);
7195 if (fp_reg_required_here (&str, 12) == FAIL)
7198 inst.error = BAD_ARGS;
7202 if (skip_past_comma (&str) == FAIL
7203 || fp_reg_required_here (&str, 16) == FAIL)
7206 inst.error = BAD_ARGS;
7210 if (skip_past_comma (&str) == FAIL
7211 || fp_op2 (&str) == FAIL)
7214 inst.error = BAD_ARGS;
7223 do_fpa_monadic (str)
7226 skip_whitespace (str);
7228 if (fp_reg_required_here (&str, 12) == FAIL)
7231 inst.error = BAD_ARGS;
7235 if (skip_past_comma (&str) == FAIL
7236 || fp_op2 (&str) == FAIL)
7239 inst.error = BAD_ARGS;
7251 skip_whitespace (str);
7253 if (fp_reg_required_here (&str, 16) == FAIL)
7256 inst.error = BAD_ARGS;
7260 if (skip_past_comma (&str) == FAIL
7261 || fp_op2 (&str) == FAIL)
7264 inst.error = BAD_ARGS;
7273 do_fpa_from_reg (str)
7276 skip_whitespace (str);
7278 if (fp_reg_required_here (&str, 16) == FAIL)
7281 inst.error = BAD_ARGS;
7285 if (skip_past_comma (&str) == FAIL
7286 || reg_required_here (&str, 12) == FAIL)
7289 inst.error = BAD_ARGS;
7301 skip_whitespace (str);
7303 if (reg_required_here (&str, 12) == FAIL)
7306 if (skip_past_comma (&str) == FAIL
7307 || fp_reg_required_here (&str, 0) == FAIL)
7310 inst.error = BAD_ARGS;
7319 vfp_sp_reg_required_here (str, pos)
7321 enum vfp_sp_reg_pos pos;
7326 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
7331 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7335 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7339 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7348 /* In the few cases where we might be able to accept something else
7349 this error can be overridden. */
7350 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
7352 /* Restore the start point. */
7358 vfp_dp_reg_required_here (str, pos)
7360 enum vfp_dp_reg_pos pos;
7365 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
7370 inst.instruction |= reg << 12;
7374 inst.instruction |= reg << 16;
7378 inst.instruction |= reg << 0;
7387 /* In the few cases where we might be able to accept something else
7388 this error can be overridden. */
7389 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7391 /* Restore the start point. */
7397 do_vfp_sp_monadic (str)
7400 skip_whitespace (str);
7402 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7405 if (skip_past_comma (&str) == FAIL
7406 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7409 inst.error = BAD_ARGS;
7418 do_vfp_dp_monadic (str)
7421 skip_whitespace (str);
7423 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7426 if (skip_past_comma (&str) == FAIL
7427 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7430 inst.error = BAD_ARGS;
7439 do_vfp_sp_dyadic (str)
7442 skip_whitespace (str);
7444 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7447 if (skip_past_comma (&str) == FAIL
7448 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
7449 || skip_past_comma (&str) == FAIL
7450 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7453 inst.error = BAD_ARGS;
7462 do_vfp_dp_dyadic (str)
7465 skip_whitespace (str);
7467 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7470 if (skip_past_comma (&str) == FAIL
7471 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
7472 || skip_past_comma (&str) == FAIL
7473 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7476 inst.error = BAD_ARGS;
7485 do_vfp_reg_from_sp (str)
7488 skip_whitespace (str);
7490 if (reg_required_here (&str, 12) == FAIL)
7493 if (skip_past_comma (&str) == FAIL
7494 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7497 inst.error = BAD_ARGS;
7506 do_vfp_sp_reg2 (str)
7509 skip_whitespace (str);
7511 if (reg_required_here (&str, 12) == FAIL)
7514 if (skip_past_comma (&str) == FAIL
7515 || reg_required_here (&str, 16) == FAIL
7516 || skip_past_comma (&str) == FAIL)
7519 inst.error = BAD_ARGS;
7523 /* We require exactly two consecutive SP registers. */
7524 if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
7527 inst.error = _("only two consecutive VFP SP registers allowed here");
7535 do_vfp_sp_from_reg (str)
7538 skip_whitespace (str);
7540 if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7543 if (skip_past_comma (&str) == FAIL
7544 || reg_required_here (&str, 12) == FAIL)
7547 inst.error = BAD_ARGS;
7556 do_vfp_reg_from_dp (str)
7559 skip_whitespace (str);
7561 if (reg_required_here (&str, 12) == FAIL)
7564 if (skip_past_comma (&str) == FAIL
7565 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7568 inst.error = BAD_ARGS;
7577 do_vfp_reg2_from_dp (str)
7580 skip_whitespace (str);
7582 if (reg_required_here (&str, 12) == FAIL)
7585 if (skip_past_comma (&str) == FAIL
7586 || reg_required_here (&str, 16) == FAIL
7587 || skip_past_comma (&str) == FAIL
7588 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7591 inst.error = BAD_ARGS;
7600 do_vfp_dp_from_reg (str)
7603 skip_whitespace (str);
7605 if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7608 if (skip_past_comma (&str) == FAIL
7609 || reg_required_here (&str, 12) == FAIL)
7612 inst.error = BAD_ARGS;
7621 do_vfp_dp_from_reg2 (str)
7624 skip_whitespace (str);
7626 if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7629 if (skip_past_comma (&str) == FAIL
7630 || reg_required_here (&str, 12) == FAIL
7631 || skip_past_comma (&str) == FAIL
7632 || reg_required_here (&str, 16))
7635 inst.error = BAD_ARGS;
7643 static const struct vfp_reg *
7650 const struct vfp_reg *vreg;
7654 /* Find the end of the current token. */
7659 while (ISALPHA (c));
7664 for (vreg = vfp_regs + 0;
7665 vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
7668 if (strcmp (start, vreg->name) == 0)
7681 vfp_psr_required_here (str)
7685 const struct vfp_reg *vreg;
7687 vreg = vfp_psr_parse (str);
7691 inst.instruction |= vreg->regno;
7695 inst.error = _("VFP system register expected");
7702 do_vfp_reg_from_ctrl (str)
7705 skip_whitespace (str);
7707 if (reg_required_here (&str, 12) == FAIL)
7710 if (skip_past_comma (&str) == FAIL
7711 || vfp_psr_required_here (&str) == FAIL)
7714 inst.error = BAD_ARGS;
7723 do_vfp_ctrl_from_reg (str)
7726 skip_whitespace (str);
7728 if (vfp_psr_required_here (&str) == FAIL)
7731 if (skip_past_comma (&str) == FAIL
7732 || reg_required_here (&str, 12) == FAIL)
7735 inst.error = BAD_ARGS;
7744 do_vfp_sp_ldst (str)
7747 skip_whitespace (str);
7749 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7752 inst.error = BAD_ARGS;
7756 if (skip_past_comma (&str) == FAIL
7757 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
7760 inst.error = BAD_ARGS;
7769 do_vfp_dp_ldst (str)
7772 skip_whitespace (str);
7774 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7777 inst.error = BAD_ARGS;
7781 if (skip_past_comma (&str) == FAIL
7782 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
7785 inst.error = BAD_ARGS;
7793 /* Parse and encode a VFP SP register list, storing the initial
7794 register in position POS and returning the range as the result. If
7795 the string is invalid return FAIL (an invalid range). */
7797 vfp_sp_reg_list (str, pos)
7799 enum vfp_sp_reg_pos pos;
7807 unsigned long mask = 0;
7814 skip_whitespace (*str);
7816 tempinst = inst.instruction;
7820 inst.instruction = 0;
7822 if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
7825 if (count == 0 || base_reg > new_base)
7827 base_reg = new_base;
7828 base_bits = inst.instruction;
7831 if (mask & (1 << new_base))
7833 inst.error = _("invalid register list");
7837 if ((mask >> new_base) != 0 && ! warned)
7839 as_tsktsk (_("register list not in ascending order"));
7843 mask |= 1 << new_base;
7846 skip_whitespace (*str);
7848 if (**str == '-') /* We have the start of a range expression */
7855 = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
7858 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
7862 if (high_range <= new_base)
7864 inst.error = _("register range not in ascending order");
7868 for (new_base++; new_base <= high_range; new_base++)
7870 if (mask & (1 << new_base))
7872 inst.error = _("invalid register list");
7876 mask |= 1 << new_base;
7881 while (skip_past_comma (str) != FAIL);
7885 inst.error = _("invalid register list");
7893 /* Sanity check -- should have raised a parse error above. */
7894 if (count == 0 || count > 32)
7897 /* Final test -- the registers must be consecutive. */
7900 if ((mask & (1 << base_reg++)) == 0)
7902 inst.error = _("non-contiguous register range");
7907 inst.instruction = tempinst | base_bits;
7912 vfp_dp_reg_list (str)
7920 unsigned long mask = 0;
7927 skip_whitespace (*str);
7929 tempinst = inst.instruction;
7933 inst.instruction = 0;
7935 if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
7938 if (count == 0 || base_reg > new_base)
7940 base_reg = new_base;
7941 range = inst.instruction;
7944 if (mask & (1 << new_base))
7946 inst.error = _("invalid register list");
7950 if ((mask >> new_base) != 0 && ! warned)
7952 as_tsktsk (_("register list not in ascending order"));
7956 mask |= 1 << new_base;
7959 skip_whitespace (*str);
7961 if (**str == '-') /* We have the start of a range expression */
7968 = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
7971 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7975 if (high_range <= new_base)
7977 inst.error = _("register range not in ascending order");
7981 for (new_base++; new_base <= high_range; new_base++)
7983 if (mask & (1 << new_base))
7985 inst.error = _("invalid register list");
7989 mask |= 1 << new_base;
7994 while (skip_past_comma (str) != FAIL);
7998 inst.error = _("invalid register list");
8006 /* Sanity check -- should have raised a parse error above. */
8007 if (count == 0 || count > 16)
8010 /* Final test -- the registers must be consecutive. */
8013 if ((mask & (1 << base_reg++)) == 0)
8015 inst.error = _("non-contiguous register range");
8020 inst.instruction = tempinst;
8025 vfp_sp_ldstm (str, ldstm_type)
8027 enum vfp_ldstm_type ldstm_type;
8031 skip_whitespace (str);
8033 if (reg_required_here (&str, 16) == FAIL)
8036 skip_whitespace (str);
8040 inst.instruction |= WRITE_BACK;
8043 else if (ldstm_type != VFP_LDSTMIA)
8045 inst.error = _("this addressing mode requires base-register writeback");
8049 if (skip_past_comma (&str) == FAIL
8050 || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
8053 inst.error = BAD_ARGS;
8057 inst.instruction |= range;
8062 vfp_dp_ldstm (str, ldstm_type)
8064 enum vfp_ldstm_type ldstm_type;
8068 skip_whitespace (str);
8070 if (reg_required_here (&str, 16) == FAIL)
8073 skip_whitespace (str);
8077 inst.instruction |= WRITE_BACK;
8080 else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
8082 inst.error = _("this addressing mode requires base-register writeback");
8086 if (skip_past_comma (&str) == FAIL
8087 || (range = vfp_dp_reg_list (&str)) == FAIL)
8090 inst.error = BAD_ARGS;
8094 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
8097 inst.instruction |= range;
8102 do_vfp_sp_ldstmia (str)
8105 vfp_sp_ldstm (str, VFP_LDSTMIA);
8109 do_vfp_sp_ldstmdb (str)
8112 vfp_sp_ldstm (str, VFP_LDSTMDB);
8116 do_vfp_dp_ldstmia (str)
8119 vfp_dp_ldstm (str, VFP_LDSTMIA);
8123 do_vfp_dp_ldstmdb (str)
8126 vfp_dp_ldstm (str, VFP_LDSTMDB);
8130 do_vfp_xp_ldstmia (str)
8133 vfp_dp_ldstm (str, VFP_LDSTMIAX);
8137 do_vfp_xp_ldstmdb (str)
8140 vfp_dp_ldstm (str, VFP_LDSTMDBX);
8144 do_vfp_sp_compare_z (str)
8147 skip_whitespace (str);
8149 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8152 inst.error = BAD_ARGS;
8161 do_vfp_dp_compare_z (str)
8164 skip_whitespace (str);
8166 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8169 inst.error = BAD_ARGS;
8178 do_vfp_dp_sp_cvt (str)
8181 skip_whitespace (str);
8183 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8186 if (skip_past_comma (&str) == FAIL
8187 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8190 inst.error = BAD_ARGS;
8199 do_vfp_sp_dp_cvt (str)
8202 skip_whitespace (str);
8204 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8207 if (skip_past_comma (&str) == FAIL
8208 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8211 inst.error = BAD_ARGS;
8219 /* Thumb specific routines. */
8221 /* Parse and validate that a register is of the right form, this saves
8222 repeated checking of this information in many similar cases.
8223 Unlike the 32-bit case we do not insert the register into the opcode
8224 here, since the position is often unknown until the full instruction
8228 thumb_reg (strp, hi_lo)
8234 if ((reg = reg_required_here (strp, -1)) == FAIL)
8242 inst.error = _("lo register required");
8250 inst.error = _("hi register required");
8262 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
8266 thumb_add_sub (str, subtract)
8270 int Rd, Rs, Rn = FAIL;
8272 skip_whitespace (str);
8274 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8275 || skip_past_comma (&str) == FAIL)
8278 inst.error = BAD_ARGS;
8282 if (is_immediate_prefix (*str))
8286 if (my_get_expression (&inst.reloc.exp, &str))
8291 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8294 if (skip_past_comma (&str) == FAIL)
8296 /* Two operand format, shuffle the registers
8297 and pretend there are 3. */
8301 else if (is_immediate_prefix (*str))
8304 if (my_get_expression (&inst.reloc.exp, &str))
8307 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8311 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8312 for the latter case, EXPR contains the immediate that was found. */
8315 /* All register format. */
8316 if (Rd > 7 || Rs > 7 || Rn > 7)
8320 inst.error = _("dest and source1 must be the same register");
8324 /* Can't do this for SUB. */
8327 inst.error = _("subtract valid only on lo regs");
8331 inst.instruction = (T_OPCODE_ADD_HI
8332 | (Rd > 7 ? THUMB_H1 : 0)
8333 | (Rn > 7 ? THUMB_H2 : 0));
8334 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
8338 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
8339 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
8344 /* Immediate expression, now things start to get nasty. */
8346 /* First deal with HI regs, only very restricted cases allowed:
8347 Adjusting SP, and using PC or SP to get an address. */
8348 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
8349 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
8351 inst.error = _("invalid Hi register with immediate");
8355 if (inst.reloc.exp.X_op != O_constant)
8357 /* Value isn't known yet, all we can do is store all the fragments
8358 we know about in the instruction and let the reloc hacking
8360 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
8361 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8365 int offset = inst.reloc.exp.X_add_number;
8375 /* Quick check, in case offset is MIN_INT. */
8378 inst.error = _("immediate value out of range");
8382 /* Note - you cannot convert a subtract of 0 into an
8383 add of 0 because the carry flag is set differently. */
8384 else if (offset > 0)
8389 if (offset & ~0x1fc)
8391 inst.error = _("invalid immediate value for stack adjust");
8394 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
8395 inst.instruction |= offset >> 2;
8397 else if (Rs == REG_PC || Rs == REG_SP)
8400 || (offset & ~0x3fc))
8402 inst.error = _("invalid immediate for address calculation");
8405 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
8407 inst.instruction |= (Rd << 8) | (offset >> 2);
8413 inst.error = _("immediate value out of range");
8416 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
8417 inst.instruction |= (Rd << 8) | offset;
8423 inst.error = _("immediate value out of range");
8426 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
8427 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
8436 thumb_shift (str, shift)
8440 int Rd, Rs, Rn = FAIL;
8442 skip_whitespace (str);
8444 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8445 || skip_past_comma (&str) == FAIL)
8448 inst.error = BAD_ARGS;
8452 if (is_immediate_prefix (*str))
8454 /* Two operand immediate format, set Rs to Rd. */
8457 if (my_get_expression (&inst.reloc.exp, &str))
8462 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8465 if (skip_past_comma (&str) == FAIL)
8467 /* Two operand format, shuffle the registers
8468 and pretend there are 3. */
8472 else if (is_immediate_prefix (*str))
8475 if (my_get_expression (&inst.reloc.exp, &str))
8478 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8482 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8483 for the latter case, EXPR contains the immediate that was found. */
8489 inst.error = _("source1 and dest must be same register");
8495 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
8496 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
8497 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
8500 inst.instruction |= Rd | (Rn << 3);
8506 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
8507 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
8508 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
8511 if (inst.reloc.exp.X_op != O_constant)
8513 /* Value isn't known yet, create a dummy reloc and let reloc
8514 hacking fix it up. */
8515 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
8519 unsigned shift_value = inst.reloc.exp.X_add_number;
8521 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
8523 inst.error = _("invalid immediate for shift");
8527 /* Shifts of zero are handled by converting to LSL. */
8528 if (shift_value == 0)
8529 inst.instruction = T_OPCODE_LSL_I;
8531 /* Shifts of 32 are encoded as a shift of zero. */
8532 if (shift_value == 32)
8535 inst.instruction |= shift_value << 6;
8538 inst.instruction |= Rd | (Rs << 3);
8545 thumb_mov_compare (str, move)
8551 skip_whitespace (str);
8553 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8554 || skip_past_comma (&str) == FAIL)
8557 inst.error = BAD_ARGS;
8561 if (is_immediate_prefix (*str))
8564 if (my_get_expression (&inst.reloc.exp, &str))
8567 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8572 if (Rs < 8 && Rd < 8)
8574 if (move == THUMB_MOVE)
8575 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
8576 since a MOV instruction produces unpredictable results. */
8577 inst.instruction = T_OPCODE_ADD_I3;
8579 inst.instruction = T_OPCODE_CMP_LR;
8580 inst.instruction |= Rd | (Rs << 3);
8584 if (move == THUMB_MOVE)
8585 inst.instruction = T_OPCODE_MOV_HR;
8587 inst.instruction = T_OPCODE_CMP_HR;
8590 inst.instruction |= THUMB_H1;
8593 inst.instruction |= THUMB_H2;
8595 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
8602 inst.error = _("only lo regs allowed with immediate");
8606 if (move == THUMB_MOVE)
8607 inst.instruction = T_OPCODE_MOV_I8;
8609 inst.instruction = T_OPCODE_CMP_I8;
8611 inst.instruction |= Rd << 8;
8613 if (inst.reloc.exp.X_op != O_constant)
8614 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
8617 unsigned value = inst.reloc.exp.X_add_number;
8621 inst.error = _("invalid immediate");
8625 inst.instruction |= value;
8633 thumb_load_store (str, load_store, size)
8638 int Rd, Rb, Ro = FAIL;
8640 skip_whitespace (str);
8642 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8643 || skip_past_comma (&str) == FAIL)
8646 inst.error = BAD_ARGS;
8653 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8656 if (skip_past_comma (&str) != FAIL)
8658 if (is_immediate_prefix (*str))
8661 if (my_get_expression (&inst.reloc.exp, &str))
8664 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8669 inst.reloc.exp.X_op = O_constant;
8670 inst.reloc.exp.X_add_number = 0;
8675 inst.error = _("expected ']'");
8680 else if (*str == '=')
8682 if (load_store != THUMB_LOAD)
8684 inst.error = _("invalid pseudo operation");
8688 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
8691 skip_whitespace (str);
8693 if (my_get_expression (& inst.reloc.exp, & str))
8698 if ( inst.reloc.exp.X_op != O_constant
8699 && inst.reloc.exp.X_op != O_symbol)
8701 inst.error = "Constant expression expected";
8705 if (inst.reloc.exp.X_op == O_constant
8706 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
8708 /* This can be done with a mov instruction. */
8710 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
8711 inst.instruction |= inst.reloc.exp.X_add_number;
8715 /* Insert into literal pool. */
8716 if (add_to_lit_pool () == FAIL)
8719 inst.error = "literal pool insertion failed";
8723 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8724 inst.reloc.pc_rel = 1;
8725 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
8726 /* Adjust ARM pipeline offset to Thumb. */
8727 inst.reloc.exp.X_add_number += 4;
8733 if (my_get_expression (&inst.reloc.exp, &str))
8736 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
8737 inst.reloc.pc_rel = 1;
8738 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
8739 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8744 if (Rb == REG_PC || Rb == REG_SP)
8746 if (size != THUMB_WORD)
8748 inst.error = _("byte or halfword not valid for base register");
8751 else if (Rb == REG_PC && load_store != THUMB_LOAD)
8753 inst.error = _("r15 based store not allowed");
8756 else if (Ro != FAIL)
8758 inst.error = _("invalid base register for register offset");
8763 inst.instruction = T_OPCODE_LDR_PC;
8764 else if (load_store == THUMB_LOAD)
8765 inst.instruction = T_OPCODE_LDR_SP;
8767 inst.instruction = T_OPCODE_STR_SP;
8769 inst.instruction |= Rd << 8;
8770 if (inst.reloc.exp.X_op == O_constant)
8772 unsigned offset = inst.reloc.exp.X_add_number;
8774 if (offset & ~0x3fc)
8776 inst.error = _("invalid offset");
8780 inst.instruction |= offset >> 2;
8783 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8787 inst.error = _("invalid base register in load/store");
8790 else if (Ro == FAIL)
8792 /* Immediate offset. */
8793 if (size == THUMB_WORD)
8794 inst.instruction = (load_store == THUMB_LOAD
8795 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
8796 else if (size == THUMB_HALFWORD)
8797 inst.instruction = (load_store == THUMB_LOAD
8798 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
8800 inst.instruction = (load_store == THUMB_LOAD
8801 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
8803 inst.instruction |= Rd | (Rb << 3);
8805 if (inst.reloc.exp.X_op == O_constant)
8807 unsigned offset = inst.reloc.exp.X_add_number;
8809 if (offset & ~(0x1f << size))
8811 inst.error = _("invalid offset");
8814 inst.instruction |= (offset >> size) << 6;
8817 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8821 /* Register offset. */
8822 if (size == THUMB_WORD)
8823 inst.instruction = (load_store == THUMB_LOAD
8824 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
8825 else if (size == THUMB_HALFWORD)
8826 inst.instruction = (load_store == THUMB_LOAD
8827 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
8829 inst.instruction = (load_store == THUMB_LOAD
8830 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
8832 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
8838 /* A register must be given at this point.
8840 Shift is the place to put it in inst.instruction.
8842 Restores input start point on err.
8843 Returns the reg#, or FAIL. */
8846 mav_reg_required_here (str, shift, regtype)
8849 enum arm_reg_type regtype;
8854 if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
8857 inst.instruction |= reg << shift;
8862 /* Restore the start point. */
8865 /* In the few cases where we might be able to accept something else
8866 this error can be overridden. */
8867 inst.error = _(all_reg_maps[regtype].expected);
8872 /* Cirrus Maverick Instructions. */
8874 /* Wrapper functions. */
8877 do_mav_binops_1a (str)
8880 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
8884 do_mav_binops_1b (str)
8887 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
8891 do_mav_binops_1c (str)
8894 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
8898 do_mav_binops_1d (str)
8901 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
8905 do_mav_binops_1e (str)
8908 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
8912 do_mav_binops_1f (str)
8915 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
8919 do_mav_binops_1g (str)
8922 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
8926 do_mav_binops_1h (str)
8929 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
8933 do_mav_binops_1i (str)
8936 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
8940 do_mav_binops_1j (str)
8943 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
8947 do_mav_binops_1k (str)
8950 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
8954 do_mav_binops_1l (str)
8957 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
8961 do_mav_binops_1m (str)
8964 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
8968 do_mav_binops_1n (str)
8971 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
8975 do_mav_binops_1o (str)
8978 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
8982 do_mav_binops_2a (str)
8985 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
8989 do_mav_binops_2b (str)
8992 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
8996 do_mav_binops_2c (str)
8999 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
9003 do_mav_binops_3a (str)
9006 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
9010 do_mav_binops_3b (str)
9013 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
9017 do_mav_binops_3c (str)
9020 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
9024 do_mav_binops_3d (str)
9027 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
9031 do_mav_triple_4a (str)
9034 do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
9038 do_mav_triple_4b (str)
9041 do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
9045 do_mav_triple_5a (str)
9048 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
9052 do_mav_triple_5b (str)
9055 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
9059 do_mav_triple_5c (str)
9062 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
9066 do_mav_triple_5d (str)
9069 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
9073 do_mav_triple_5e (str)
9076 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
9080 do_mav_triple_5f (str)
9083 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
9087 do_mav_triple_5g (str)
9090 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
9094 do_mav_triple_5h (str)
9097 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
9101 do_mav_quad_6a (str)
9104 do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
9109 do_mav_quad_6b (str)
9112 do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
9116 /* cfmvsc32<cond> DSPSC,MVFX[15:0]. */
9118 do_mav_dspsc_1 (str)
9121 skip_whitespace (str);
9124 if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
9125 || skip_past_comma (&str) == FAIL
9126 || mav_reg_required_here (&str, 16, REG_TYPE_MVFX) == FAIL)
9129 inst.error = BAD_ARGS;
9137 /* cfmv32sc<cond> MVFX[15:0],DSPSC. */
9139 do_mav_dspsc_2 (str)
9142 skip_whitespace (str);
9145 if (mav_reg_required_here (&str, 0, REG_TYPE_MVFX) == FAIL
9146 || skip_past_comma (&str) == FAIL
9147 || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
9150 inst.error = BAD_ARGS;
9159 do_mav_shift_1 (str)
9162 do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
9166 do_mav_shift_2 (str)
9169 do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
9176 do_mav_ldst (str, REG_TYPE_MVF);
9183 do_mav_ldst (str, REG_TYPE_MVD);
9190 do_mav_ldst (str, REG_TYPE_MVFX);
9197 do_mav_ldst (str, REG_TYPE_MVDX);
9200 /* Isnsn like "foo X,Y". */
9203 do_mav_binops (str, mode, reg0, reg1)
9206 enum arm_reg_type reg0;
9207 enum arm_reg_type reg1;
9211 shift0 = mode & 0xff;
9212 shift1 = (mode >> 8) & 0xff;
9214 skip_whitespace (str);
9216 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9217 || skip_past_comma (&str) == FAIL
9218 || mav_reg_required_here (&str, shift1, reg1) == FAIL)
9221 inst.error = BAD_ARGS;
9227 /* Isnsn like "foo X,Y,Z". */
9230 do_mav_triple (str, mode, reg0, reg1, reg2)
9233 enum arm_reg_type reg0;
9234 enum arm_reg_type reg1;
9235 enum arm_reg_type reg2;
9237 int shift0, shift1, shift2;
9239 shift0 = mode & 0xff;
9240 shift1 = (mode >> 8) & 0xff;
9241 shift2 = (mode >> 16) & 0xff;
9243 skip_whitespace (str);
9245 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9246 || skip_past_comma (&str) == FAIL
9247 || mav_reg_required_here (&str, shift1, reg1) == FAIL
9248 || skip_past_comma (&str) == FAIL
9249 || mav_reg_required_here (&str, shift2, reg2) == FAIL)
9252 inst.error = BAD_ARGS;
9258 /* Isnsn like "foo W,X,Y,Z".
9259 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
9262 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
9265 enum arm_reg_type reg0;
9266 enum arm_reg_type reg1;
9267 enum arm_reg_type reg2;
9268 enum arm_reg_type reg3;
9270 int shift0, shift1, shift2, shift3;
9272 shift0= mode & 0xff;
9273 shift1 = (mode >> 8) & 0xff;
9274 shift2 = (mode >> 16) & 0xff;
9275 shift3 = (mode >> 24) & 0xff;
9277 skip_whitespace (str);
9279 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9280 || skip_past_comma (&str) == FAIL
9281 || mav_reg_required_here (&str, shift1, reg1) == FAIL
9282 || skip_past_comma (&str) == FAIL
9283 || mav_reg_required_here (&str, shift2, reg2) == FAIL
9284 || skip_past_comma (&str) == FAIL
9285 || mav_reg_required_here (&str, shift3, reg3) == FAIL)
9288 inst.error = BAD_ARGS;
9294 /* Maverick shift immediate instructions.
9295 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
9296 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
9299 do_mav_shift (str, reg0, reg1)
9301 enum arm_reg_type reg0;
9302 enum arm_reg_type reg1;
9307 skip_whitespace (str);
9311 if (mav_reg_required_here (&str, 12, reg0) == FAIL
9312 || skip_past_comma (&str) == FAIL
9313 || mav_reg_required_here (&str, 16, reg1) == FAIL
9314 || skip_past_comma (&str) == FAIL)
9317 inst.error = BAD_ARGS;
9321 /* Calculate the immediate operand.
9322 The operand is a 7bit signed number. */
9323 skip_whitespace (str);
9328 if (!ISDIGIT (*str) && *str != '-')
9330 inst.error = _("expecting immediate, 7bit operand");
9340 for (imm = 0; *str && ISDIGIT (*str); ++str)
9341 imm = imm * 10 + *str - '0';
9345 inst.error = _("immediate out of range");
9349 /* Make negative imm's into 7bit signed numbers. */
9356 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
9357 Bits 5-7 of the insn should have bits 4-6 of the immediate.
9358 Bit 4 should be 0. */
9359 imm = (imm & 0xf) | ((imm & 0x70) << 1);
9361 inst.instruction |= imm;
9366 mav_parse_offset (str, negative)
9375 skip_whitespace (p);
9388 inst.error = _("offset expected");
9392 for (offset = 0; *p && ISDIGIT (*p); ++p)
9393 offset = offset * 10 + *p - '0';
9397 inst.error = _("offset out of range");
9403 return *negative ? -offset : offset;
9406 /* Maverick load/store instructions.
9407 <insn><cond> CRd,[Rn,<offset>]{!}.
9408 <insn><cond> CRd,[Rn],<offset>. */
9411 do_mav_ldst (str, reg0)
9413 enum arm_reg_type reg0;
9415 int offset, negative;
9417 skip_whitespace (str);
9419 if (mav_reg_required_here (&str, 12, reg0) == FAIL
9420 || skip_past_comma (&str) == FAIL
9422 || reg_required_here (&str, 16) == FAIL)
9425 if (skip_past_comma (&str) == SUCCESS)
9427 /* You are here: "<offset>]{!}". */
9428 inst.instruction |= PRE_INDEX;
9430 offset = mav_parse_offset (&str, &negative);
9437 inst.error = _("missing ]");
9443 inst.instruction |= WRITE_BACK;
9449 /* You are here: "], <offset>". */
9452 inst.error = _("missing ]");
9456 if (skip_past_comma (&str) == FAIL
9457 || (offset = mav_parse_offset (&str, &negative), inst.error))
9460 inst.instruction |= CP_T_WB; /* Post indexed, set bit W. */
9466 inst.instruction |= CP_T_UD; /* Postive, so set bit U. */
9468 inst.instruction |= offset >> 2;
9474 inst.error = BAD_ARGS;
9487 /* Handle the Format 4 instructions that do not have equivalents in other
9488 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
9497 skip_whitespace (str);
9499 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9500 || skip_past_comma (&str) == FAIL
9501 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9503 inst.error = BAD_ARGS;
9507 if (skip_past_comma (&str) != FAIL)
9509 /* Three operand format not allowed for TST, CMN, NEG and MVN.
9510 (It isn't allowed for CMP either, but that isn't handled by this
9512 if (inst.instruction == T_OPCODE_TST
9513 || inst.instruction == T_OPCODE_CMN
9514 || inst.instruction == T_OPCODE_NEG
9515 || inst.instruction == T_OPCODE_MVN)
9517 inst.error = BAD_ARGS;
9521 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9526 inst.error = _("dest and source1 must be the same register");
9532 if (inst.instruction == T_OPCODE_MUL
9534 as_tsktsk (_("Rs and Rd must be different in MUL"));
9536 inst.instruction |= Rd | (Rs << 3);
9544 thumb_add_sub (str, 0);
9551 thumb_shift (str, THUMB_ASR);
9558 if (my_get_expression (&inst.reloc.exp, &str))
9560 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
9561 inst.reloc.pc_rel = 1;
9569 if (my_get_expression (&inst.reloc.exp, &str))
9571 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
9572 inst.reloc.pc_rel = 1;
9576 /* Find the real, Thumb encoded start of a Thumb function. */
9579 find_real_start (symbolP)
9583 const char * name = S_GET_NAME (symbolP);
9584 symbolS * new_target;
9586 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
9587 #define STUB_NAME ".real_start_of"
9592 /* Names that start with '.' are local labels, not function entry points.
9593 The compiler may generate BL instructions to these labels because it
9594 needs to perform a branch to a far away location. */
9598 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
9599 sprintf (real_start, "%s%s", STUB_NAME, name);
9601 new_target = symbol_find (real_start);
9603 if (new_target == NULL)
9605 as_warn ("Failed to find real start of function: %s\n", name);
9606 new_target = symbolP;
9618 if (my_get_expression (& inst.reloc.exp, & str))
9621 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
9622 inst.reloc.pc_rel = 1;
9625 /* If the destination of the branch is a defined symbol which does not have
9626 the THUMB_FUNC attribute, then we must be calling a function which has
9627 the (interfacearm) attribute. We look for the Thumb entry point to that
9628 function and change the branch to refer to that function instead. */
9629 if ( inst.reloc.exp.X_op == O_symbol
9630 && inst.reloc.exp.X_add_symbol != NULL
9631 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
9632 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
9633 inst.reloc.exp.X_add_symbol =
9634 find_real_start (inst.reloc.exp.X_add_symbol);
9643 skip_whitespace (str);
9645 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9648 /* This sets THUMB_H2 from the top bit of reg. */
9649 inst.instruction |= reg << 3;
9651 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
9652 should cause the alignment to be checked once it is known. This is
9653 because BX PC only works if the instruction is word aligned. */
9662 thumb_mov_compare (str, THUMB_COMPARE);
9672 skip_whitespace (str);
9674 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9678 as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
9682 if (skip_past_comma (&str) == FAIL
9683 || (range = reg_list (&str)) == FAIL)
9686 inst.error = BAD_ARGS;
9690 if (inst.reloc.type != BFD_RELOC_NONE)
9692 /* This really doesn't seem worth it. */
9693 inst.reloc.type = BFD_RELOC_NONE;
9694 inst.error = _("expression too complex");
9700 inst.error = _("only lo-regs valid in load/store multiple");
9704 inst.instruction |= (Rb << 8) | range;
9712 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
9719 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
9726 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
9735 skip_whitespace (str);
9737 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9738 || skip_past_comma (&str) == FAIL
9740 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9741 || skip_past_comma (&str) == FAIL
9742 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9746 inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
9750 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
9758 thumb_shift (str, THUMB_LSL);
9765 thumb_shift (str, THUMB_LSR);
9772 thumb_mov_compare (str, THUMB_MOVE);
9781 skip_whitespace (str);
9783 if ((range = reg_list (&str)) == FAIL)
9786 inst.error = BAD_ARGS;
9790 if (inst.reloc.type != BFD_RELOC_NONE)
9792 /* This really doesn't seem worth it. */
9793 inst.reloc.type = BFD_RELOC_NONE;
9794 inst.error = _("expression too complex");
9800 if ((inst.instruction == T_OPCODE_PUSH
9801 && (range & ~0xff) == 1 << REG_LR)
9802 || (inst.instruction == T_OPCODE_POP
9803 && (range & ~0xff) == 1 << REG_PC))
9805 inst.instruction |= THUMB_PP_PC_LR;
9810 inst.error = _("invalid register list to push/pop instruction");
9815 inst.instruction |= range;
9823 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
9830 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
9837 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
9844 thumb_add_sub (str, 1);
9851 skip_whitespace (str);
9853 if (my_get_expression (&inst.reloc.exp, &str))
9856 inst.reloc.type = BFD_RELOC_ARM_SWI;
9867 /* This is a pseudo-op of the form "adr rd, label" to be converted
9868 into a relative address of the form "add rd, pc, #label-.-4". */
9869 skip_whitespace (str);
9871 /* Store Rd in temporary location inside instruction. */
9872 if ((reg = reg_required_here (&str, 4)) == FAIL
9873 || (reg > 7) /* For Thumb reg must be r0..r7. */
9874 || skip_past_comma (&str) == FAIL
9875 || my_get_expression (&inst.reloc.exp, &str))
9878 inst.error = BAD_ARGS;
9882 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9883 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
9884 inst.reloc.pc_rel = 1;
9885 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
9891 insert_reg (r, htab)
9892 const struct reg_entry *r;
9893 struct hash_control *htab;
9895 int len = strlen (r->name) + 2;
9896 char * buf = (char *) xmalloc (len);
9897 char * buf2 = (char *) xmalloc (len);
9900 #ifdef REGISTER_PREFIX
9901 buf[i++] = REGISTER_PREFIX;
9904 strcpy (buf + i, r->name);
9906 for (i = 0; buf[i]; i++)
9907 buf2[i] = TOUPPER (buf[i]);
9911 hash_insert (htab, buf, (PTR) r);
9912 hash_insert (htab, buf2, (PTR) r);
9917 struct reg_map *map;
9919 const struct reg_entry *r;
9921 if ((map->htab = hash_new ()) == NULL)
9922 as_fatal (_("virtual memory exhausted"));
9924 for (r = map->names; r->name != NULL; r++)
9925 insert_reg (r, map->htab);
9929 insert_reg_alias (str, regnum, htab)
9932 struct hash_control *htab;
9934 struct reg_entry *new =
9935 (struct reg_entry *) xmalloc (sizeof (struct reg_entry));
9936 char *name = xmalloc (strlen (str) + 1);
9940 new->number = regnum;
9942 hash_insert (htab, name, (PTR) new);
9945 /* Look for the .req directive. This is of the form:
9947 newname .req existing_name
9949 If we find one, or if it looks sufficiently like one that we want to
9950 handle any error here, return non-zero. Otherwise return zero. */
9952 create_register_alias (newname, p)
9960 skip_whitespace (q);
9965 if (*q && !strncmp (q, ".req ", 5))
9970 #ifdef IGNORE_OPCODE_CASE
9971 newname = original_case_string;
9973 copy_of_str = newname;
9976 skip_whitespace (q);
9978 for (r = q; *r != '\0'; r++)
9984 enum arm_reg_type new_type, old_type;
9989 old_type = arm_reg_parse_any (q);
9992 new_type = arm_reg_parse_any (newname);
9994 if (new_type == REG_TYPE_MAX)
9996 if (old_type != REG_TYPE_MAX)
9998 old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
9999 insert_reg_alias (newname, old_regno,
10000 all_reg_maps[old_type].htab);
10003 as_warn (_("register '%s' does not exist\n"), q);
10005 else if (old_type == REG_TYPE_MAX)
10007 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
10012 /* Do not warn about redefinitions to the same alias. */
10013 if (new_type != old_type
10014 || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
10015 != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
10016 as_warn (_("ignoring redefinition of register alias '%s'"),
10022 as_warn (_("ignoring incomplete .req pseuso op"));
10032 set_constant_flonums ()
10036 for (i = 0; i < NUM_FLOAT_VALS; i++)
10037 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
10041 /* Iterate over the base tables to create the instruction patterns. */
10043 build_arm_ops_hsh ()
10047 static struct obstack insn_obstack;
10049 obstack_begin (&insn_obstack, 4000);
10051 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
10053 const struct asm_opcode *insn = insns + i;
10055 if (insn->cond_offset != 0)
10057 /* Insn supports conditional execution. Build the varaints
10058 and insert them in the hash table. */
10059 for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
10061 unsigned len = strlen (insn->template);
10062 struct asm_opcode *new;
10065 new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
10066 /* All condition codes are two characters. */
10067 template = obstack_alloc (&insn_obstack, len + 3);
10069 strncpy (template, insn->template, insn->cond_offset);
10070 strcpy (template + insn->cond_offset, conds[j].template);
10071 if (len > insn->cond_offset)
10072 strcpy (template + insn->cond_offset + 2,
10073 insn->template + insn->cond_offset);
10074 new->template = template;
10075 new->cond_offset = 0;
10076 new->variant = insn->variant;
10077 new->parms = insn->parms;
10078 new->value = (insn->value & ~COND_MASK) | conds[j].value;
10080 hash_insert (arm_ops_hsh, new->template, (PTR) new);
10083 /* Finally, insert the unconditional insn in the table directly;
10084 no need to build a copy. */
10085 hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
10089 #if defined OBJ_ELF || defined OBJ_COFF
10092 #define arm_Note Elf_External_Note
10096 unsigned char namesz[4]; /* Size of entry's owner string. */
10097 unsigned char descsz[4]; /* Size of the note descriptor. */
10098 unsigned char type[4]; /* Interpretation of the descriptor. */
10099 char name[1]; /* Start of the name+desc data. */
10103 /* The description is kept to a fix sized in order to make updating
10104 it and merging it easier. */
10105 #define ARM_NOTE_DESCRIPTION_LENGTH 8
10108 arm_add_note (name, description, type)
10110 const char * description;
10113 arm_Note note ATTRIBUTE_UNUSED;
10115 unsigned int name_len;
10117 name_len = (strlen (name) + 1 + 3) & ~3;
10119 p = frag_more (sizeof (note.namesz));
10120 md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
10122 p = frag_more (sizeof (note.descsz));
10123 md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
10125 p = frag_more (sizeof (note.type));
10126 md_number_to_chars (p, (valueT) type, sizeof (note.type));
10128 p = frag_more (name_len);
10131 p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
10132 strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
10133 frag_align (2, 0, 0);
10143 if ( (arm_ops_hsh = hash_new ()) == NULL
10144 || (arm_tops_hsh = hash_new ()) == NULL
10145 || (arm_cond_hsh = hash_new ()) == NULL
10146 || (arm_shift_hsh = hash_new ()) == NULL
10147 || (arm_psr_hsh = hash_new ()) == NULL)
10148 as_fatal (_("virtual memory exhausted"));
10150 build_arm_ops_hsh ();
10151 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
10152 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
10153 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
10154 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
10155 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
10156 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
10157 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
10158 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
10160 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
10161 build_reg_hsh (all_reg_maps + i);
10163 set_constant_flonums ();
10165 /* Set the cpu variant based on the command-line options. We prefer
10166 -mcpu= over -march= if both are set (as for GCC); and we prefer
10167 -mfpu= over any other way of setting the floating point unit.
10168 Use of legacy options with new options are faulted. */
10169 if (legacy_cpu != -1)
10171 if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
10172 as_bad (_("use of old and new-style options to set CPU type"));
10174 mcpu_cpu_opt = legacy_cpu;
10176 else if (mcpu_cpu_opt == -1)
10177 mcpu_cpu_opt = march_cpu_opt;
10179 if (legacy_fpu != -1)
10181 if (mfpu_opt != -1)
10182 as_bad (_("use of old and new-style options to set FPU type"));
10184 mfpu_opt = legacy_fpu;
10186 else if (mfpu_opt == -1)
10188 if (mcpu_fpu_opt != -1)
10189 mfpu_opt = mcpu_fpu_opt;
10191 mfpu_opt = march_fpu_opt;
10194 if (mfpu_opt == -1)
10196 if (mcpu_cpu_opt == -1)
10197 mfpu_opt = FPU_DEFAULT;
10198 else if (mcpu_cpu_opt & ARM_EXT_V5)
10199 mfpu_opt = FPU_ARCH_VFP_V2;
10201 mfpu_opt = FPU_ARCH_FPA;
10204 if (mcpu_cpu_opt == -1)
10205 mcpu_cpu_opt = CPU_DEFAULT;
10207 cpu_variant = mcpu_cpu_opt | mfpu_opt;
10209 #if defined OBJ_COFF || defined OBJ_ELF
10211 unsigned int flags = 0;
10213 /* Set the flags in the private structure. */
10214 if (uses_apcs_26) flags |= F_APCS26;
10215 if (support_interwork) flags |= F_INTERWORK;
10216 if (uses_apcs_float) flags |= F_APCS_FLOAT;
10217 if (pic_code) flags |= F_PIC;
10218 if ((cpu_variant & FPU_ANY) == FPU_NONE
10219 || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only. */
10220 flags |= F_SOFT_FLOAT;
10221 /* Using VFP conventions (even if soft-float). */
10222 if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
10224 #if defined OBJ_ELF
10225 if (cpu_variant & ARM_CEXT_MAVERICK)
10227 flags ^= F_SOFT_FLOAT;
10228 flags |= EF_ARM_MAVERICK_FLOAT;
10232 bfd_set_private_flags (stdoutput, flags);
10234 /* We have run out flags in the COFF header to encode the
10235 status of ATPCS support, so instead we create a dummy,
10236 empty, debug section called .arm.atpcs. */
10241 sec = bfd_make_section (stdoutput, ".arm.atpcs");
10245 bfd_set_section_flags
10246 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
10247 bfd_set_section_size (stdoutput, sec, 0);
10248 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
10254 /* Record the CPU type as well. */
10255 switch (cpu_variant & ARM_CPU_MASK)
10258 mach = bfd_mach_arm_2;
10261 case ARM_3: /* Also ARM_250. */
10262 mach = bfd_mach_arm_2a;
10265 case ARM_6: /* Also ARM_7. */
10266 mach = bfd_mach_arm_3;
10270 mach = bfd_mach_arm_unknown;
10274 /* Catch special cases. */
10275 if (cpu_variant & ARM_CEXT_IWMMXT)
10276 mach = bfd_mach_arm_iWMMXt;
10277 else if (cpu_variant & ARM_CEXT_XSCALE)
10278 mach = bfd_mach_arm_XScale;
10279 else if (cpu_variant & ARM_CEXT_MAVERICK)
10280 mach = bfd_mach_arm_ep9312;
10281 else if (cpu_variant & ARM_EXT_V5E)
10282 mach = bfd_mach_arm_5TE;
10283 else if (cpu_variant & ARM_EXT_V5)
10285 if (cpu_variant & ARM_EXT_V4T)
10286 mach = bfd_mach_arm_5T;
10288 mach = bfd_mach_arm_5;
10290 else if (cpu_variant & ARM_EXT_V4)
10292 if (cpu_variant & ARM_EXT_V4T)
10293 mach = bfd_mach_arm_4T;
10295 mach = bfd_mach_arm_4;
10297 else if (cpu_variant & ARM_EXT_V3M)
10298 mach = bfd_mach_arm_3M;
10300 #if 0 /* Suppressed - for now. */
10301 #if defined (OBJ_ELF) || defined (OBJ_COFF)
10303 /* Create a .note section to fully identify this arm binary. */
10305 #define NOTE_ARCH_STRING "arch: "
10307 #if defined OBJ_COFF && ! defined NT_VERSION
10308 #define NT_VERSION 1
10313 segT current_seg = now_seg;
10314 subsegT current_subseg = now_subseg;
10315 asection * arm_arch;
10316 const char * arch_string;
10318 arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
10321 bfd_set_section_flags (stdoutput, arm_arch,
10322 SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
10323 | SEC_HAS_CONTENTS);
10325 arm_arch->output_section = arm_arch;
10326 subseg_set (arm_arch, 0);
10331 case bfd_mach_arm_unknown: arch_string = "unknown"; break;
10332 case bfd_mach_arm_2: arch_string = "armv2"; break;
10333 case bfd_mach_arm_2a: arch_string = "armv2a"; break;
10334 case bfd_mach_arm_3: arch_string = "armv3"; break;
10335 case bfd_mach_arm_3M: arch_string = "armv3M"; break;
10336 case bfd_mach_arm_4: arch_string = "armv4"; break;
10337 case bfd_mach_arm_4T: arch_string = "armv4t"; break;
10338 case bfd_mach_arm_5: arch_string = "armv5"; break;
10339 case bfd_mach_arm_5T: arch_string = "armv5t"; break;
10340 case bfd_mach_arm_5TE: arch_string = "armv5te"; break;
10341 case bfd_mach_arm_XScale: arch_string = "XScale"; break;
10342 case bfd_mach_arm_ep9312: arch_string = "ep9312"; break;
10343 case bfd_mach_arm_iWMMXt: arch_string = "iWMMXt"; break;
10346 arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
10348 subseg_set (current_seg, current_subseg);
10351 #endif /* Suppressed code. */
10353 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
10356 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
10357 for use in the a.out file, and stores them in the array pointed to by buf.
10358 This knows about the endian-ness of the target machine and does
10359 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
10360 2 (short) and 4 (long) Floating numbers are put out as a series of
10361 LITTLENUMS (shorts, here at least). */
10364 md_number_to_chars (buf, val, n)
10369 if (target_big_endian)
10370 number_to_chars_bigendian (buf, val, n);
10372 number_to_chars_littleendian (buf, val, n);
10376 md_chars_to_number (buf, n)
10381 unsigned char * where = (unsigned char *) buf;
10383 if (target_big_endian)
10388 result |= (*where++ & 255);
10396 result |= (where[n] & 255);
10403 /* Turn a string in input_line_pointer into a floating point constant
10404 of type TYPE, and store the appropriate bytes in *LITP. The number
10405 of LITTLENUMS emitted is stored in *SIZEP. An error message is
10406 returned, or NULL on OK.
10408 Note that fp constants aren't represent in the normal way on the ARM.
10409 In big endian mode, things are as expected. However, in little endian
10410 mode fp constants are big-endian word-wise, and little-endian byte-wise
10411 within the words. For example, (double) 1.1 in big endian mode is
10412 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
10413 the byte sequence 99 99 f1 3f 9a 99 99 99.
10415 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
10418 md_atof (type, litP, sizeP)
10424 LITTLENUM_TYPE words[MAX_LITTLENUMS];
10456 return _("bad call to MD_ATOF()");
10459 t = atof_ieee (input_line_pointer, type, words);
10461 input_line_pointer = t;
10464 if (target_big_endian)
10466 for (i = 0; i < prec; i++)
10468 md_number_to_chars (litP, (valueT) words[i], 2);
10474 if (cpu_variant & FPU_ARCH_VFP)
10475 for (i = prec - 1; i >= 0; i--)
10477 md_number_to_chars (litP, (valueT) words[i], 2);
10481 /* For a 4 byte float the order of elements in `words' is 1 0.
10482 For an 8 byte float the order is 1 0 3 2. */
10483 for (i = 0; i < prec; i += 2)
10485 md_number_to_chars (litP, (valueT) words[i + 1], 2);
10486 md_number_to_chars (litP + 2, (valueT) words[i], 2);
10494 /* The knowledge of the PC's pipeline offset is built into the insns
10498 md_pcrel_from (fixP)
10502 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
10503 && fixP->fx_subsy == NULL)
10506 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
10508 /* PC relative addressing on the Thumb is slightly odd
10509 as the bottom two bits of the PC are forced to zero
10510 for the calculation. */
10511 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
10515 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
10516 so we un-adjust here to compensate for the accomodation. */
10517 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
10519 return fixP->fx_where + fixP->fx_frag->fr_address;
10523 /* Round up a section size to the appropriate boundary. */
10526 md_section_align (segment, size)
10527 segT segment ATTRIBUTE_UNUSED;
10533 /* Round all sects to multiple of 4. */
10534 return (size + 3) & ~3;
10538 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
10539 Otherwise we have no need to default values of symbols. */
10542 md_undefined_symbol (name)
10543 char * name ATTRIBUTE_UNUSED;
10546 if (name[0] == '_' && name[1] == 'G'
10547 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
10551 if (symbol_find (name))
10552 as_bad ("GOT already in the symbol table");
10554 GOT_symbol = symbol_new (name, undefined_section,
10555 (valueT) 0, & zero_address_frag);
10565 /* arm_reg_parse () := if it looks like a register, return its token and
10566 advance the pointer. */
10569 arm_reg_parse (ccp, htab)
10570 register char ** ccp;
10571 struct hash_control *htab;
10573 char * start = * ccp;
10576 struct reg_entry * reg;
10578 #ifdef REGISTER_PREFIX
10579 if (*start != REGISTER_PREFIX)
10584 #ifdef OPTIONAL_REGISTER_PREFIX
10585 if (*p == OPTIONAL_REGISTER_PREFIX)
10589 if (!ISALPHA (*p) || !is_name_beginner (*p))
10593 while (ISALPHA (c) || ISDIGIT (c) || c == '_')
10597 reg = (struct reg_entry *) hash_find (htab, start);
10603 return reg->number;
10609 /* Search for the following register name in each of the possible reg name
10610 tables. Return the classification if found, or REG_TYPE_MAX if not
10612 static enum arm_reg_type
10613 arm_reg_parse_any (cp)
10618 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
10619 if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
10620 return (enum arm_reg_type) i;
10622 return REG_TYPE_MAX;
10626 md_apply_fix3 (fixP, valP, seg)
10631 offsetT value = * valP;
10633 unsigned int newimm;
10634 unsigned long temp;
10636 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
10637 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
10639 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
10641 /* Note whether this will delete the relocation. */
10643 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
10644 doesn't work fully.) */
10645 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
10646 && !fixP->fx_pcrel)
10648 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
10652 /* If this symbol is in a different section then we need to leave it for
10653 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
10654 so we have to undo it's effects here. */
10655 if (fixP->fx_pcrel)
10657 if (fixP->fx_addsy != NULL
10658 && S_IS_DEFINED (fixP->fx_addsy)
10659 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
10662 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
10663 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
10667 value += md_pcrel_from (fixP);
10671 /* Remember value for emit_reloc. */
10672 fixP->fx_addnumber = value;
10674 switch (fixP->fx_r_type)
10676 case BFD_RELOC_ARM_IMMEDIATE:
10677 newimm = validate_immediate (value);
10678 temp = md_chars_to_number (buf, INSN_SIZE);
10680 /* If the instruction will fail, see if we can fix things up by
10681 changing the opcode. */
10682 if (newimm == (unsigned int) FAIL
10683 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
10685 as_bad_where (fixP->fx_file, fixP->fx_line,
10686 _("invalid constant (%lx) after fixup"),
10687 (unsigned long) value);
10691 newimm |= (temp & 0xfffff000);
10692 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
10696 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
10698 unsigned int highpart = 0;
10699 unsigned int newinsn = 0xe1a00000; /* nop. */
10701 newimm = validate_immediate (value);
10702 temp = md_chars_to_number (buf, INSN_SIZE);
10704 /* If the instruction will fail, see if we can fix things up by
10705 changing the opcode. */
10706 if (newimm == (unsigned int) FAIL
10707 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
10709 /* No ? OK - try using two ADD instructions to generate
10711 newimm = validate_immediate_twopart (value, & highpart);
10713 /* Yes - then make sure that the second instruction is
10715 if (newimm != (unsigned int) FAIL)
10717 /* Still No ? Try using a negated value. */
10718 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
10719 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
10720 /* Otherwise - give up. */
10723 as_bad_where (fixP->fx_file, fixP->fx_line,
10724 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
10729 /* Replace the first operand in the 2nd instruction (which
10730 is the PC) with the destination register. We have
10731 already added in the PC in the first instruction and we
10732 do not want to do it again. */
10733 newinsn &= ~ 0xf0000;
10734 newinsn |= ((newinsn & 0x0f000) << 4);
10737 newimm |= (temp & 0xfffff000);
10738 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
10740 highpart |= (newinsn & 0xfffff000);
10741 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
10745 case BFD_RELOC_ARM_OFFSET_IMM:
10751 if (validate_offset_imm (value, 0) == FAIL)
10753 as_bad_where (fixP->fx_file, fixP->fx_line,
10754 _("bad immediate value for offset (%ld)"),
10759 newval = md_chars_to_number (buf, INSN_SIZE);
10760 newval &= 0xff7ff000;
10761 newval |= value | (sign ? INDEX_UP : 0);
10762 md_number_to_chars (buf, newval, INSN_SIZE);
10765 case BFD_RELOC_ARM_OFFSET_IMM8:
10766 case BFD_RELOC_ARM_HWLITERAL:
10772 if (validate_offset_imm (value, 1) == FAIL)
10774 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
10775 as_bad_where (fixP->fx_file, fixP->fx_line,
10776 _("invalid literal constant: pool needs to be closer"));
10778 as_bad (_("bad immediate value for half-word offset (%ld)"),
10783 newval = md_chars_to_number (buf, INSN_SIZE);
10784 newval &= 0xff7ff0f0;
10785 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
10786 md_number_to_chars (buf, newval, INSN_SIZE);
10789 case BFD_RELOC_ARM_LITERAL:
10795 if (validate_offset_imm (value, 0) == FAIL)
10797 as_bad_where (fixP->fx_file, fixP->fx_line,
10798 _("invalid literal constant: pool needs to be closer"));
10802 newval = md_chars_to_number (buf, INSN_SIZE);
10803 newval &= 0xff7ff000;
10804 newval |= value | (sign ? INDEX_UP : 0);
10805 md_number_to_chars (buf, newval, INSN_SIZE);
10808 case BFD_RELOC_ARM_SHIFT_IMM:
10809 newval = md_chars_to_number (buf, INSN_SIZE);
10810 if (((unsigned long) value) > 32
10812 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
10814 as_bad_where (fixP->fx_file, fixP->fx_line,
10815 _("shift expression is too large"));
10820 /* Shifts of zero must be done as lsl. */
10822 else if (value == 32)
10824 newval &= 0xfffff07f;
10825 newval |= (value & 0x1f) << 7;
10826 md_number_to_chars (buf, newval, INSN_SIZE);
10829 case BFD_RELOC_ARM_SWI:
10830 if (arm_data->thumb_mode)
10832 if (((unsigned long) value) > 0xff)
10833 as_bad_where (fixP->fx_file, fixP->fx_line,
10834 _("invalid swi expression"));
10835 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
10837 md_number_to_chars (buf, newval, THUMB_SIZE);
10841 if (((unsigned long) value) > 0x00ffffff)
10842 as_bad_where (fixP->fx_file, fixP->fx_line,
10843 _("invalid swi expression"));
10844 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
10846 md_number_to_chars (buf, newval, INSN_SIZE);
10850 case BFD_RELOC_ARM_MULTI:
10851 if (((unsigned long) value) > 0xffff)
10852 as_bad_where (fixP->fx_file, fixP->fx_line,
10853 _("invalid expression in load/store multiple"));
10854 newval = value | md_chars_to_number (buf, INSN_SIZE);
10855 md_number_to_chars (buf, newval, INSN_SIZE);
10858 case BFD_RELOC_ARM_PCREL_BRANCH:
10859 newval = md_chars_to_number (buf, INSN_SIZE);
10861 /* Sign-extend a 24-bit number. */
10862 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
10866 value = fixP->fx_offset;
10869 /* We are going to store value (shifted right by two) in the
10870 instruction, in a 24 bit, signed field. Thus we need to check
10871 that none of the top 8 bits of the shifted value (top 7 bits of
10872 the unshifted, unsigned value) are set, or that they are all set. */
10873 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
10874 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
10877 /* Normally we would be stuck at this point, since we cannot store
10878 the absolute address that is the destination of the branch in the
10879 24 bits of the branch instruction. If however, we happen to know
10880 that the destination of the branch is in the same section as the
10881 branch instruciton itself, then we can compute the relocation for
10882 ourselves and not have to bother the linker with it.
10884 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
10885 because I have not worked out how to do this for OBJ_COFF or
10888 && fixP->fx_addsy != NULL
10889 && S_IS_DEFINED (fixP->fx_addsy)
10890 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
10892 /* Get pc relative value to go into the branch. */
10895 /* Permit a backward branch provided that enough bits
10896 are set. Allow a forwards branch, provided that
10897 enough bits are clear. */
10898 if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
10899 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
10903 if (! fixP->fx_done)
10905 as_bad_where (fixP->fx_file, fixP->fx_line,
10906 _("GAS can't handle same-section branch dest >= 0x04000000"));
10910 value += SEXT24 (newval);
10912 if ( (value & ~ ((offsetT) 0xffffff)) != 0
10913 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
10914 as_bad_where (fixP->fx_file, fixP->fx_line,
10915 _("out of range branch"));
10917 newval = (value & 0x00ffffff) | (newval & 0xff000000);
10918 md_number_to_chars (buf, newval, INSN_SIZE);
10921 case BFD_RELOC_ARM_PCREL_BLX:
10924 newval = md_chars_to_number (buf, INSN_SIZE);
10928 value = fixP->fx_offset;
10930 hbit = (value >> 1) & 1;
10931 value = (value >> 2) & 0x00ffffff;
10932 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
10933 newval = value | (newval & 0xfe000000) | (hbit << 24);
10934 md_number_to_chars (buf, newval, INSN_SIZE);
10938 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
10939 newval = md_chars_to_number (buf, THUMB_SIZE);
10941 addressT diff = (newval & 0xff) << 1;
10946 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
10947 as_bad_where (fixP->fx_file, fixP->fx_line,
10948 _("branch out of range"));
10949 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
10951 md_number_to_chars (buf, newval, THUMB_SIZE);
10954 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
10955 newval = md_chars_to_number (buf, THUMB_SIZE);
10957 addressT diff = (newval & 0x7ff) << 1;
10962 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
10963 as_bad_where (fixP->fx_file, fixP->fx_line,
10964 _("branch out of range"));
10965 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
10967 md_number_to_chars (buf, newval, THUMB_SIZE);
10970 case BFD_RELOC_THUMB_PCREL_BLX:
10971 case BFD_RELOC_THUMB_PCREL_BRANCH23:
10976 newval = md_chars_to_number (buf, THUMB_SIZE);
10977 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
10978 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
10979 if (diff & 0x400000)
10982 value = fixP->fx_offset;
10986 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
10987 as_bad_where (fixP->fx_file, fixP->fx_line,
10988 _("branch with link out of range"));
10990 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
10991 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
10992 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
10993 /* For a BLX instruction, make sure that the relocation is rounded up
10994 to a word boundary. This follows the semantics of the instruction
10995 which specifies that bit 1 of the target address will come from bit
10996 1 of the base address. */
10997 newval2 = (newval2 + 1) & ~ 1;
10998 md_number_to_chars (buf, newval, THUMB_SIZE);
10999 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
11004 if (fixP->fx_done || fixP->fx_pcrel)
11005 md_number_to_chars (buf, value, 1);
11007 else if (!target_oabi)
11009 value = fixP->fx_offset;
11010 md_number_to_chars (buf, value, 1);
11016 if (fixP->fx_done || fixP->fx_pcrel)
11017 md_number_to_chars (buf, value, 2);
11019 else if (!target_oabi)
11021 value = fixP->fx_offset;
11022 md_number_to_chars (buf, value, 2);
11028 case BFD_RELOC_ARM_GOT32:
11029 case BFD_RELOC_ARM_GOTOFF:
11030 md_number_to_chars (buf, 0, 4);
11034 case BFD_RELOC_RVA:
11036 if (fixP->fx_done || fixP->fx_pcrel)
11037 md_number_to_chars (buf, value, 4);
11039 else if (!target_oabi)
11041 value = fixP->fx_offset;
11042 md_number_to_chars (buf, value, 4);
11048 case BFD_RELOC_ARM_PLT32:
11049 /* It appears the instruction is fully prepared at this point. */
11053 case BFD_RELOC_ARM_CP_OFF_IMM:
11055 if (value < -1023 || value > 1023 || (value & 3))
11056 as_bad_where (fixP->fx_file, fixP->fx_line,
11057 _("illegal value for co-processor offset"));
11060 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11061 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
11062 md_number_to_chars (buf, newval, INSN_SIZE);
11065 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
11067 if (value < -255 || value > 255)
11068 as_bad_where (fixP->fx_file, fixP->fx_line,
11069 _("Illegal value for co-processor offset"));
11072 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11073 newval |= value | (sign ? INDEX_UP : 0);
11074 md_number_to_chars (buf, newval , INSN_SIZE);
11077 case BFD_RELOC_ARM_THUMB_OFFSET:
11078 newval = md_chars_to_number (buf, THUMB_SIZE);
11079 /* Exactly what ranges, and where the offset is inserted depends
11080 on the type of instruction, we can establish this from the
11082 switch (newval >> 12)
11084 case 4: /* PC load. */
11085 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
11086 forced to zero for these loads, so we will need to round
11087 up the offset if the instruction address is not word
11088 aligned (since the final address produced must be, and
11089 we can only describe word-aligned immediate offsets). */
11091 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
11092 as_bad_where (fixP->fx_file, fixP->fx_line,
11093 _("invalid offset, target not word aligned (0x%08X)"),
11094 (unsigned int) (fixP->fx_frag->fr_address
11095 + fixP->fx_where + value));
11097 if ((value + 2) & ~0x3fe)
11098 as_bad_where (fixP->fx_file, fixP->fx_line,
11099 _("invalid offset, value too big (0x%08lX)"),
11102 /* Round up, since pc will be rounded down. */
11103 newval |= (value + 2) >> 2;
11106 case 9: /* SP load/store. */
11107 if (value & ~0x3fc)
11108 as_bad_where (fixP->fx_file, fixP->fx_line,
11109 _("invalid offset, value too big (0x%08lX)"),
11111 newval |= value >> 2;
11114 case 6: /* Word load/store. */
11116 as_bad_where (fixP->fx_file, fixP->fx_line,
11117 _("invalid offset, value too big (0x%08lX)"),
11119 newval |= value << 4; /* 6 - 2. */
11122 case 7: /* Byte load/store. */
11124 as_bad_where (fixP->fx_file, fixP->fx_line,
11125 _("invalid offset, value too big (0x%08lX)"),
11127 newval |= value << 6;
11130 case 8: /* Halfword load/store. */
11132 as_bad_where (fixP->fx_file, fixP->fx_line,
11133 _("invalid offset, value too big (0x%08lX)"),
11135 newval |= value << 5; /* 6 - 1. */
11139 as_bad_where (fixP->fx_file, fixP->fx_line,
11140 "Unable to process relocation for thumb opcode: %lx",
11141 (unsigned long) newval);
11144 md_number_to_chars (buf, newval, THUMB_SIZE);
11147 case BFD_RELOC_ARM_THUMB_ADD:
11148 /* This is a complicated relocation, since we use it for all of
11149 the following immediate relocations:
11153 9bit ADD/SUB SP word-aligned
11154 10bit ADD PC/SP word-aligned
11156 The type of instruction being processed is encoded in the
11163 newval = md_chars_to_number (buf, THUMB_SIZE);
11165 int rd = (newval >> 4) & 0xf;
11166 int rs = newval & 0xf;
11167 int subtract = newval & 0x8000;
11171 if (value & ~0x1fc)
11172 as_bad_where (fixP->fx_file, fixP->fx_line,
11173 _("invalid immediate for stack address calculation"));
11174 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
11175 newval |= value >> 2;
11177 else if (rs == REG_PC || rs == REG_SP)
11181 as_bad_where (fixP->fx_file, fixP->fx_line,
11182 _("invalid immediate for address calculation (value = 0x%08lX)"),
11183 (unsigned long) value);
11184 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
11186 newval |= value >> 2;
11191 as_bad_where (fixP->fx_file, fixP->fx_line,
11192 _("invalid 8bit immediate"));
11193 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
11194 newval |= (rd << 8) | value;
11199 as_bad_where (fixP->fx_file, fixP->fx_line,
11200 _("invalid 3bit immediate"));
11201 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
11202 newval |= rd | (rs << 3) | (value << 6);
11205 md_number_to_chars (buf, newval, THUMB_SIZE);
11208 case BFD_RELOC_ARM_THUMB_IMM:
11209 newval = md_chars_to_number (buf, THUMB_SIZE);
11210 switch (newval >> 11)
11212 case 0x04: /* 8bit immediate MOV. */
11213 case 0x05: /* 8bit immediate CMP. */
11214 if (value < 0 || value > 255)
11215 as_bad_where (fixP->fx_file, fixP->fx_line,
11216 _("invalid immediate: %ld is too large"),
11224 md_number_to_chars (buf, newval, THUMB_SIZE);
11227 case BFD_RELOC_ARM_THUMB_SHIFT:
11228 /* 5bit shift value (0..31). */
11229 if (value < 0 || value > 31)
11230 as_bad_where (fixP->fx_file, fixP->fx_line,
11231 _("illegal Thumb shift value: %ld"), (long) value);
11232 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
11233 newval |= value << 6;
11234 md_number_to_chars (buf, newval, THUMB_SIZE);
11237 case BFD_RELOC_VTABLE_INHERIT:
11238 case BFD_RELOC_VTABLE_ENTRY:
11242 case BFD_RELOC_NONE:
11244 as_bad_where (fixP->fx_file, fixP->fx_line,
11245 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
11249 /* Translate internal representation of relocation info to BFD target
11253 tc_gen_reloc (section, fixp)
11254 asection * section ATTRIBUTE_UNUSED;
11258 bfd_reloc_code_real_type code;
11260 reloc = (arelent *) xmalloc (sizeof (arelent));
11262 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
11263 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
11264 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
11266 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
11268 if (fixp->fx_pcrel == 0)
11269 reloc->addend = fixp->fx_offset;
11271 reloc->addend = fixp->fx_offset = reloc->address;
11272 #else /* OBJ_ELF */
11273 reloc->addend = fixp->fx_offset;
11276 switch (fixp->fx_r_type)
11279 if (fixp->fx_pcrel)
11281 code = BFD_RELOC_8_PCREL;
11286 if (fixp->fx_pcrel)
11288 code = BFD_RELOC_16_PCREL;
11293 if (fixp->fx_pcrel)
11295 code = BFD_RELOC_32_PCREL;
11299 case BFD_RELOC_ARM_PCREL_BRANCH:
11300 case BFD_RELOC_ARM_PCREL_BLX:
11301 case BFD_RELOC_RVA:
11302 case BFD_RELOC_THUMB_PCREL_BRANCH9:
11303 case BFD_RELOC_THUMB_PCREL_BRANCH12:
11304 case BFD_RELOC_THUMB_PCREL_BRANCH23:
11305 case BFD_RELOC_THUMB_PCREL_BLX:
11306 case BFD_RELOC_VTABLE_ENTRY:
11307 case BFD_RELOC_VTABLE_INHERIT:
11308 code = fixp->fx_r_type;
11311 case BFD_RELOC_ARM_LITERAL:
11312 case BFD_RELOC_ARM_HWLITERAL:
11313 /* If this is called then the a literal has
11314 been referenced across a section boundary. */
11315 as_bad_where (fixp->fx_file, fixp->fx_line,
11316 _("literal referenced across section boundary"));
11320 case BFD_RELOC_ARM_GOT32:
11321 case BFD_RELOC_ARM_GOTOFF:
11322 case BFD_RELOC_ARM_PLT32:
11323 code = fixp->fx_r_type;
11327 case BFD_RELOC_ARM_IMMEDIATE:
11328 as_bad_where (fixp->fx_file, fixp->fx_line,
11329 _("internal relocation (type: IMMEDIATE) not fixed up"));
11332 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11333 as_bad_where (fixp->fx_file, fixp->fx_line,
11334 _("ADRL used for a symbol not defined in the same file"));
11337 case BFD_RELOC_ARM_OFFSET_IMM:
11338 as_bad_where (fixp->fx_file, fixp->fx_line,
11339 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
11346 switch (fixp->fx_r_type)
11348 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
11349 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
11350 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
11351 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
11352 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
11353 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
11354 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
11355 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
11356 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
11357 default: type = _("<unknown>"); break;
11359 as_bad_where (fixp->fx_file, fixp->fx_line,
11360 _("cannot represent %s relocation in this object file format"),
11367 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
11369 && fixp->fx_addsy == GOT_symbol)
11371 code = BFD_RELOC_ARM_GOTPC;
11372 reloc->addend = fixp->fx_offset = reloc->address;
11376 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
11378 if (reloc->howto == NULL)
11380 as_bad_where (fixp->fx_file, fixp->fx_line,
11381 _("cannot represent %s relocation in this object file format"),
11382 bfd_get_reloc_code_name (code));
11386 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
11387 vtable entry to be used in the relocation's section offset. */
11388 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
11389 reloc->address = fixp->fx_offset;
11395 md_estimate_size_before_relax (fragP, segtype)
11396 fragS * fragP ATTRIBUTE_UNUSED;
11397 segT segtype ATTRIBUTE_UNUSED;
11399 as_fatal (_("md_estimate_size_before_relax\n"));
11411 as_bad ("%s -- `%s'", inst.error, str);
11415 to = frag_more (inst.size);
11417 if (thumb_mode && (inst.size > THUMB_SIZE))
11419 assert (inst.size == (2 * THUMB_SIZE));
11420 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
11421 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
11423 else if (inst.size > INSN_SIZE)
11425 assert (inst.size == (2 * INSN_SIZE));
11426 md_number_to_chars (to, inst.instruction, INSN_SIZE);
11427 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
11430 md_number_to_chars (to, inst.instruction, inst.size);
11432 if (inst.reloc.type != BFD_RELOC_NONE)
11433 fix_new_arm (frag_now, to - frag_now->fr_literal,
11434 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
11438 dwarf2_emit_insn (inst.size);
11450 /* Align the instruction.
11451 This may not be the right thing to do but ... */
11456 /* Align the previous label if needed. */
11457 if (last_label_seen != NULL)
11459 symbol_set_frag (last_label_seen, frag_now);
11460 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
11461 S_SET_SEGMENT (last_label_seen, now_seg);
11464 memset (&inst, '\0', sizeof (inst));
11465 inst.reloc.type = BFD_RELOC_NONE;
11467 skip_whitespace (str);
11469 /* Scan up to the end of the op-code, which must end in white space or
11471 for (start = p = str; *p != '\0'; p++)
11477 as_bad (_("no operator -- statement `%s'\n"), str);
11483 const struct thumb_opcode * opcode;
11487 opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
11492 /* Check that this instruction is supported for this CPU. */
11493 if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
11495 as_bad (_("selected processor does not support `%s'"), str);
11499 inst.instruction = opcode->value;
11500 inst.size = opcode->size;
11501 (*opcode->parms) (p);
11508 const struct asm_opcode * opcode;
11512 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
11517 /* Check that this instruction is supported for this CPU. */
11518 if ((opcode->variant & cpu_variant) == 0)
11520 as_bad (_("selected processor does not support `%s'"), str);
11524 inst.instruction = opcode->value;
11525 inst.size = INSN_SIZE;
11526 (*opcode->parms) (p);
11532 /* It wasn't an instruction, but it might be a register alias of the form
11534 if (create_register_alias (str, p))
11537 as_bad (_("bad instruction `%s'"), start);
11541 Invocation line includes a switch not recognized by the base assembler.
11542 See if it's a processor-specific option.
11544 This routine is somewhat complicated by the need for backwards
11545 compatibility (since older releases of gcc can't be changed).
11546 The new options try to make the interface as compatible as
11549 New options (supported) are:
11551 -mcpu=<cpu name> Assemble for selected processor
11552 -march=<architecture name> Assemble for selected architecture
11553 -mfpu=<fpu architecture> Assemble for selected FPU.
11554 -EB/-mbig-endian Big-endian
11555 -EL/-mlittle-endian Little-endian
11556 -k Generate PIC code
11557 -mthumb Start in Thumb mode
11558 -mthumb-interwork Code supports ARM/Thumb interworking
11560 For now we will also provide support for:
11562 -mapcs-32 32-bit Program counter
11563 -mapcs-26 26-bit Program counter
11564 -macps-float Floats passed in FP registers
11565 -mapcs-reentrant Reentrant code
11567 (sometime these will probably be replaced with -mapcs=<list of options>
11568 and -matpcs=<list of options>)
11570 The remaining options are only supported for back-wards compatibility.
11571 Cpu variants, the arm part is optional:
11572 -m[arm]1 Currently not supported.
11573 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
11574 -m[arm]3 Arm 3 processor
11575 -m[arm]6[xx], Arm 6 processors
11576 -m[arm]7[xx][t][[d]m] Arm 7 processors
11577 -m[arm]8[10] Arm 8 processors
11578 -m[arm]9[20][tdmi] Arm 9 processors
11579 -mstrongarm[110[0]] StrongARM processors
11580 -mxscale XScale processors
11581 -m[arm]v[2345[t[e]]] Arm architectures
11582 -mall All (except the ARM1)
11584 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
11585 -mfpe-old (No float load/store multiples)
11586 -mvfpxd VFP Single precision
11588 -mno-fpu Disable all floating point instructions
11590 The following CPU names are recognized:
11591 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
11592 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
11593 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
11594 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
11595 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
11596 arm10t arm10e, arm1020t, arm1020e, arm10200e,
11597 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
11601 const char * md_shortopts = "m:k";
11603 #ifdef ARM_BI_ENDIAN
11604 #define OPTION_EB (OPTION_MD_BASE + 0)
11605 #define OPTION_EL (OPTION_MD_BASE + 1)
11607 #if TARGET_BYTES_BIG_ENDIAN
11608 #define OPTION_EB (OPTION_MD_BASE + 0)
11610 #define OPTION_EL (OPTION_MD_BASE + 1)
11614 struct option md_longopts[] =
11617 {"EB", no_argument, NULL, OPTION_EB},
11620 {"EL", no_argument, NULL, OPTION_EL},
11622 {NULL, no_argument, NULL, 0}
11625 size_t md_longopts_size = sizeof (md_longopts);
11627 struct arm_option_table
11629 char *option; /* Option name to match. */
11630 char *help; /* Help information. */
11631 int *var; /* Variable to change. */
11632 int value; /* What to change it to. */
11633 char *deprecated; /* If non-null, print this message. */
11636 struct arm_option_table arm_opts[] =
11638 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
11639 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
11640 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
11641 &support_interwork, 1, NULL},
11642 {"moabi", N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
11643 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
11644 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
11645 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
11647 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
11648 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
11649 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
11650 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
11653 /* These are recognized by the assembler, but have no affect on code. */
11654 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
11655 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
11657 /* DON'T add any new processors to this list -- we want the whole list
11658 to go away... Add them to the processors table instead. */
11659 {"marm1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
11660 {"m1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
11661 {"marm2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
11662 {"m2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
11663 {"marm250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
11664 {"m250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
11665 {"marm3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
11666 {"m3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
11667 {"marm6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
11668 {"m6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
11669 {"marm600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
11670 {"m600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
11671 {"marm610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
11672 {"m610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
11673 {"marm620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
11674 {"m620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
11675 {"marm7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
11676 {"m7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
11677 {"marm70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
11678 {"m70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
11679 {"marm700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
11680 {"m700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
11681 {"marm700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
11682 {"m700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
11683 {"marm710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
11684 {"m710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
11685 {"marm710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
11686 {"m710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
11687 {"marm720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
11688 {"m720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
11689 {"marm7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
11690 {"m7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
11691 {"marm7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
11692 {"m7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
11693 {"marm7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
11694 {"m7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
11695 {"marm7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
11696 {"m7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
11697 {"marm7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
11698 {"m7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
11699 {"marm7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
11700 {"m7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
11701 {"marm7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
11702 {"m7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
11703 {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
11704 {"m7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
11705 {"marm7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
11706 {"m7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
11707 {"marm7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
11708 {"m7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
11709 {"marm710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
11710 {"m710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
11711 {"marm720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
11712 {"m720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
11713 {"marm740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
11714 {"m740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
11715 {"marm8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
11716 {"m8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
11717 {"marm810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
11718 {"m810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
11719 {"marm9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
11720 {"m9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
11721 {"marm9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
11722 {"m9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
11723 {"marm920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
11724 {"m920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
11725 {"marm940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
11726 {"m940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
11727 {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
11728 {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
11729 N_("use -mcpu=strongarm110")},
11730 {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
11731 N_("use -mcpu=strongarm1100")},
11732 {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
11733 N_("use -mcpu=strongarm1110")},
11734 {"mxscale", NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
11735 {"miwmmxt", NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
11736 {"mall", NULL, &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
11738 /* Architecture variants -- don't add any more to this list either. */
11739 {"mv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
11740 {"marmv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
11741 {"mv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
11742 {"marmv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
11743 {"mv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
11744 {"marmv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
11745 {"mv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
11746 {"marmv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
11747 {"mv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
11748 {"marmv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
11749 {"mv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
11750 {"marmv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
11751 {"mv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
11752 {"marmv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
11753 {"mv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
11754 {"marmv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
11755 {"mv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
11756 {"marmv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
11758 /* Floating point variants -- don't add any more to this list either. */
11759 {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
11760 {"mfpa10", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
11761 {"mfpa11", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
11762 {"mno-fpu", NULL, &legacy_fpu, 0,
11763 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
11765 {NULL, NULL, NULL, 0, NULL}
11768 struct arm_cpu_option_table
11772 /* For some CPUs we assume an FPU unless the user explicitly sets
11777 /* This list should, at a minimum, contain all the cpu names
11778 recognized by GCC. */
11779 static struct arm_cpu_option_table arm_cpus[] =
11781 {"all", ARM_ANY, FPU_ARCH_FPA},
11782 {"arm1", ARM_ARCH_V1, FPU_ARCH_FPA},
11783 {"arm2", ARM_ARCH_V2, FPU_ARCH_FPA},
11784 {"arm250", ARM_ARCH_V2S, FPU_ARCH_FPA},
11785 {"arm3", ARM_ARCH_V2S, FPU_ARCH_FPA},
11786 {"arm6", ARM_ARCH_V3, FPU_ARCH_FPA},
11787 {"arm60", ARM_ARCH_V3, FPU_ARCH_FPA},
11788 {"arm600", ARM_ARCH_V3, FPU_ARCH_FPA},
11789 {"arm610", ARM_ARCH_V3, FPU_ARCH_FPA},
11790 {"arm620", ARM_ARCH_V3, FPU_ARCH_FPA},
11791 {"arm7", ARM_ARCH_V3, FPU_ARCH_FPA},
11792 {"arm7m", ARM_ARCH_V3M, FPU_ARCH_FPA},
11793 {"arm7d", ARM_ARCH_V3, FPU_ARCH_FPA},
11794 {"arm7dm", ARM_ARCH_V3M, FPU_ARCH_FPA},
11795 {"arm7di", ARM_ARCH_V3, FPU_ARCH_FPA},
11796 {"arm7dmi", ARM_ARCH_V3M, FPU_ARCH_FPA},
11797 {"arm70", ARM_ARCH_V3, FPU_ARCH_FPA},
11798 {"arm700", ARM_ARCH_V3, FPU_ARCH_FPA},
11799 {"arm700i", ARM_ARCH_V3, FPU_ARCH_FPA},
11800 {"arm710", ARM_ARCH_V3, FPU_ARCH_FPA},
11801 {"arm710t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11802 {"arm720", ARM_ARCH_V3, FPU_ARCH_FPA},
11803 {"arm720t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11804 {"arm740t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11805 {"arm710c", ARM_ARCH_V3, FPU_ARCH_FPA},
11806 {"arm7100", ARM_ARCH_V3, FPU_ARCH_FPA},
11807 {"arm7500", ARM_ARCH_V3, FPU_ARCH_FPA},
11808 {"arm7500fe", ARM_ARCH_V3, FPU_ARCH_FPA},
11809 {"arm7t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11810 {"arm7tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
11811 {"arm8", ARM_ARCH_V4, FPU_ARCH_FPA},
11812 {"arm810", ARM_ARCH_V4, FPU_ARCH_FPA},
11813 {"strongarm", ARM_ARCH_V4, FPU_ARCH_FPA},
11814 {"strongarm1", ARM_ARCH_V4, FPU_ARCH_FPA},
11815 {"strongarm110", ARM_ARCH_V4, FPU_ARCH_FPA},
11816 {"strongarm1100", ARM_ARCH_V4, FPU_ARCH_FPA},
11817 {"strongarm1110", ARM_ARCH_V4, FPU_ARCH_FPA},
11818 {"arm9", ARM_ARCH_V4T, FPU_ARCH_FPA},
11819 {"arm920", ARM_ARCH_V4T, FPU_ARCH_FPA},
11820 {"arm920t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11821 {"arm922t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11822 {"arm940t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11823 {"arm9tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
11824 /* For V5 or later processors we default to using VFP; but the user
11825 should really set the FPU type explicitly. */
11826 {"arm9e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
11827 {"arm9e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11828 {"arm926ej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2},
11829 {"arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
11830 {"arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11831 {"arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
11832 {"arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11833 {"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
11834 {"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11835 {"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11836 {"arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
11837 {"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11838 /* ??? XSCALE is really an architecture. */
11839 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
11840 /* ??? iwmmxt is not a processor. */
11841 {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
11842 {"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
11844 {"ep9312", ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_NONE},
11848 struct arm_arch_option_table
11855 /* This list should, at a minimum, contain all the architecture names
11856 recognized by GCC. */
11857 static struct arm_arch_option_table arm_archs[] =
11859 {"all", ARM_ANY, FPU_ARCH_FPA},
11860 {"armv1", ARM_ARCH_V1, FPU_ARCH_FPA},
11861 {"armv2", ARM_ARCH_V2, FPU_ARCH_FPA},
11862 {"armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA},
11863 {"armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA},
11864 {"armv3", ARM_ARCH_V3, FPU_ARCH_FPA},
11865 {"armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA},
11866 {"armv4", ARM_ARCH_V4, FPU_ARCH_FPA},
11867 {"armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA},
11868 {"armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11869 {"armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA},
11870 {"armv5", ARM_ARCH_V5, FPU_ARCH_VFP},
11871 {"armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP},
11872 {"armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP},
11873 {"armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP},
11874 {"armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP},
11875 {"armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP},
11876 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
11880 /* ISA extensions in the co-processor space. */
11881 struct arm_arch_extension_table
11887 static struct arm_arch_extension_table arm_extensions[] =
11889 {"maverick", ARM_CEXT_MAVERICK},
11890 {"xscale", ARM_CEXT_XSCALE},
11891 {"iwmmxt", ARM_CEXT_IWMMXT},
11895 struct arm_fpu_option_table
11901 /* This list should, at a minimum, contain all the fpu names
11902 recognized by GCC. */
11903 static struct arm_fpu_option_table arm_fpus[] =
11905 {"softfpa", FPU_NONE},
11906 {"fpe", FPU_ARCH_FPE},
11907 {"fpe2", FPU_ARCH_FPE},
11908 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
11909 {"fpa", FPU_ARCH_FPA},
11910 {"fpa10", FPU_ARCH_FPA},
11911 {"fpa11", FPU_ARCH_FPA},
11912 {"arm7500fe", FPU_ARCH_FPA},
11913 {"softvfp", FPU_ARCH_VFP},
11914 {"softvfp+vfp", FPU_ARCH_VFP_V2},
11915 {"vfp", FPU_ARCH_VFP_V2},
11916 {"vfp9", FPU_ARCH_VFP_V2},
11917 {"vfp10", FPU_ARCH_VFP_V2},
11918 {"vfp10-r0", FPU_ARCH_VFP_V1},
11919 {"vfpxd", FPU_ARCH_VFP_V1xD},
11920 {"arm1020t", FPU_ARCH_VFP_V1},
11921 {"arm1020e", FPU_ARCH_VFP_V2},
11925 struct arm_long_option_table
11927 char *option; /* Substring to match. */
11928 char *help; /* Help information. */
11929 int (*func) PARAMS ((char *subopt)); /* Function to decode sub-option. */
11930 char *deprecated; /* If non-null, print this message. */
11934 arm_parse_extension (str, opt_p)
11938 while (str != NULL && *str != 0)
11940 struct arm_arch_extension_table *opt;
11946 as_bad (_("invalid architectural extension"));
11951 ext = strchr (str, '+');
11954 optlen = ext - str;
11956 optlen = strlen (str);
11960 as_bad (_("missing architectural extension"));
11964 for (opt = arm_extensions; opt->name != NULL; opt++)
11965 if (strncmp (opt->name, str, optlen) == 0)
11967 *opt_p |= opt->value;
11971 if (opt->name == NULL)
11973 as_bad (_("unknown architectural extnsion `%s'"), str);
11984 arm_parse_cpu (str)
11987 struct arm_cpu_option_table *opt;
11988 char *ext = strchr (str, '+');
11992 optlen = ext - str;
11994 optlen = strlen (str);
11998 as_bad (_("missing cpu name `%s'"), str);
12002 for (opt = arm_cpus; opt->name != NULL; opt++)
12003 if (strncmp (opt->name, str, optlen) == 0)
12005 mcpu_cpu_opt = opt->value;
12006 mcpu_fpu_opt = opt->default_fpu;
12009 return arm_parse_extension (ext, &mcpu_cpu_opt);
12014 as_bad (_("unknown cpu `%s'"), str);
12019 arm_parse_arch (str)
12022 struct arm_arch_option_table *opt;
12023 char *ext = strchr (str, '+');
12027 optlen = ext - str;
12029 optlen = strlen (str);
12033 as_bad (_("missing architecture name `%s'"), str);
12038 for (opt = arm_archs; opt->name != NULL; opt++)
12039 if (strcmp (opt->name, str) == 0)
12041 march_cpu_opt = opt->value;
12042 march_fpu_opt = opt->default_fpu;
12045 return arm_parse_extension (ext, &march_cpu_opt);
12050 as_bad (_("unknown architecture `%s'\n"), str);
12055 arm_parse_fpu (str)
12058 struct arm_fpu_option_table *opt;
12060 for (opt = arm_fpus; opt->name != NULL; opt++)
12061 if (strcmp (opt->name, str) == 0)
12063 mfpu_opt = opt->value;
12067 as_bad (_("unknown floating point format `%s'\n"), str);
12071 struct arm_long_option_table arm_long_opts[] =
12073 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
12074 arm_parse_cpu, NULL},
12075 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
12076 arm_parse_arch, NULL},
12077 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
12078 arm_parse_fpu, NULL},
12079 {NULL, NULL, 0, NULL}
12083 md_parse_option (c, arg)
12087 struct arm_option_table *opt;
12088 struct arm_long_option_table *lopt;
12094 target_big_endian = 1;
12100 target_big_endian = 0;
12105 /* Listing option. Just ignore these, we don't support additional
12110 for (opt = arm_opts; opt->option != NULL; opt++)
12112 if (c == opt->option[0]
12113 && ((arg == NULL && opt->option[1] == 0)
12114 || strcmp (arg, opt->option + 1) == 0))
12116 #if WARN_DEPRECATED
12117 /* If the option is deprecated, tell the user. */
12118 if (opt->deprecated != NULL)
12119 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
12120 arg ? arg : "", _(opt->deprecated));
12123 if (opt->var != NULL)
12124 *opt->var = opt->value;
12130 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
12132 /* These options are expected to have an argument. */
12133 if (c == lopt->option[0]
12135 && strncmp (arg, lopt->option + 1,
12136 strlen (lopt->option + 1)) == 0)
12138 #if WARN_DEPRECATED
12139 /* If the option is deprecated, tell the user. */
12140 if (lopt->deprecated != NULL)
12141 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
12142 _(lopt->deprecated));
12145 /* Call the sup-option parser. */
12146 return (*lopt->func)(arg + strlen (lopt->option) - 1);
12150 as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
12161 struct arm_option_table *opt;
12162 struct arm_long_option_table *lopt;
12164 fprintf (fp, _(" ARM-specific assembler options:\n"));
12166 for (opt = arm_opts; opt->option != NULL; opt++)
12167 if (opt->help != NULL)
12168 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
12170 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
12171 if (lopt->help != NULL)
12172 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
12176 -EB assemble code for a big-endian cpu\n"));
12181 -EL assemble code for a little-endian cpu\n"));
12185 /* We need to be able to fix up arbitrary expressions in some statements.
12186 This is so that we can handle symbols that are an arbitrary distance from
12187 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
12188 which returns part of an address in a form which will be valid for
12189 a data instruction. We do this by pushing the expression into a symbol
12190 in the expr_section, and creating a fix for that. */
12193 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
12202 arm_fix_data * arm_data;
12210 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
12214 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
12219 /* Mark whether the fix is to a THUMB instruction, or an ARM
12221 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
12222 new_fix->tc_fix_data = (PTR) arm_data;
12223 arm_data->thumb_mode = thumb_mode;
12228 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
12231 cons_fix_new_arm (frag, where, size, exp)
12237 bfd_reloc_code_real_type type;
12241 FIXME: @@ Should look at CPU word size. */
12245 type = BFD_RELOC_8;
12248 type = BFD_RELOC_16;
12252 type = BFD_RELOC_32;
12255 type = BFD_RELOC_64;
12259 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
12262 /* A good place to do this, although this was probably not intended
12263 for this kind of use. We need to dump the literal pool before
12264 references are made to a null symbol pointer. */
12269 literal_pool * pool;
12271 for (pool = list_of_pools; pool; pool = pool->next)
12273 /* Put it at the end of the relevent section. */
12274 subseg_set (pool->section, pool->sub_section);
12280 arm_start_line_hook ()
12282 last_label_seen = NULL;
12286 arm_frob_label (sym)
12289 last_label_seen = sym;
12291 ARM_SET_THUMB (sym, thumb_mode);
12293 #if defined OBJ_COFF || defined OBJ_ELF
12294 ARM_SET_INTERWORK (sym, support_interwork);
12297 /* Note - do not allow local symbols (.Lxxx) to be labeled
12298 as Thumb functions. This is because these labels, whilst
12299 they exist inside Thumb code, are not the entry points for
12300 possible ARM->Thumb calls. Also, these labels can be used
12301 as part of a computed goto or switch statement. eg gcc
12302 can generate code that looks like this:
12304 ldr r2, [pc, .Laaa]
12314 The first instruction loads the address of the jump table.
12315 The second instruction converts a table index into a byte offset.
12316 The third instruction gets the jump address out of the table.
12317 The fourth instruction performs the jump.
12319 If the address stored at .Laaa is that of a symbol which has the
12320 Thumb_Func bit set, then the linker will arrange for this address
12321 to have the bottom bit set, which in turn would mean that the
12322 address computation performed by the third instruction would end
12323 up with the bottom bit set. Since the ARM is capable of unaligned
12324 word loads, the instruction would then load the incorrect address
12325 out of the jump table, and chaos would ensue. */
12326 if (label_is_thumb_function_name
12327 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
12328 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
12330 /* When the address of a Thumb function is taken the bottom
12331 bit of that address should be set. This will allow
12332 interworking between Arm and Thumb functions to work
12335 THUMB_SET_FUNC (sym, 1);
12337 label_is_thumb_function_name = FALSE;
12341 /* Adjust the symbol table. This marks Thumb symbols as distinct from
12345 arm_adjust_symtab ()
12350 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
12352 if (ARM_IS_THUMB (sym))
12354 if (THUMB_IS_FUNC (sym))
12356 /* Mark the symbol as a Thumb function. */
12357 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
12358 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
12359 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
12361 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
12362 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
12364 as_bad (_("%s: unexpected function type: %d"),
12365 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
12367 else switch (S_GET_STORAGE_CLASS (sym))
12370 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
12373 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
12376 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
12384 if (ARM_IS_INTERWORK (sym))
12385 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
12392 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
12394 if (ARM_IS_THUMB (sym))
12396 elf_symbol_type * elf_sym;
12398 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
12399 bind = ELF_ST_BIND (elf_sym);
12401 /* If it's a .thumb_func, declare it as so,
12402 otherwise tag label as .code 16. */
12403 if (THUMB_IS_FUNC (sym))
12404 elf_sym->internal_elf_sym.st_info =
12405 ELF_ST_INFO (bind, STT_ARM_TFUNC);
12407 elf_sym->internal_elf_sym.st_info =
12408 ELF_ST_INFO (bind, STT_ARM_16BIT);
12415 arm_data_in_code ()
12417 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
12419 *input_line_pointer = '/';
12420 input_line_pointer += 5;
12421 *input_line_pointer = 0;
12429 arm_canonicalize_symbol_name (name)
12434 if (thumb_mode && (len = strlen (name)) > 5
12435 && streq (name + len - 5, "/data"))
12436 *(name + len - 5) = 0;
12441 #if defined OBJ_COFF || defined OBJ_ELF
12443 arm_validate_fix (fixP)
12446 /* If the destination of the branch is a defined symbol which does not have
12447 the THUMB_FUNC attribute, then we must be calling a function which has
12448 the (interfacearm) attribute. We look for the Thumb entry point to that
12449 function and change the branch to refer to that function instead. */
12450 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
12451 && fixP->fx_addsy != NULL
12452 && S_IS_DEFINED (fixP->fx_addsy)
12453 && ! THUMB_IS_FUNC (fixP->fx_addsy))
12455 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
12461 arm_force_relocation (fixp)
12464 #if defined (OBJ_COFF) && defined (TE_PE)
12465 if (fixp->fx_r_type == BFD_RELOC_RVA)
12469 if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
12470 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
12471 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
12472 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
12476 /* Resolve these relocations even if the symbol is extern or weak. */
12477 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
12478 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
12481 return generic_force_reloc (fixp);
12485 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
12486 local labels from being added to the output symbol table when they
12487 are used with the ADRL pseudo op. The ADRL relocation should always
12488 be resolved before the binbary is emitted, so it is safe to say that
12489 it is adjustable. */
12492 arm_fix_adjustable (fixP)
12495 if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
12502 /* Relocations against Thumb function names must be left unadjusted,
12503 so that the linker can use this information to correctly set the
12504 bottom bit of their addresses. The MIPS version of this function
12505 also prevents relocations that are mips-16 specific, but I do not
12506 know why it does this.
12509 There is one other problem that ought to be addressed here, but
12510 which currently is not: Taking the address of a label (rather
12511 than a function) and then later jumping to that address. Such
12512 addresses also ought to have their bottom bit set (assuming that
12513 they reside in Thumb code), but at the moment they will not. */
12516 arm_fix_adjustable (fixP)
12519 if (fixP->fx_addsy == NULL)
12522 if (THUMB_IS_FUNC (fixP->fx_addsy)
12523 && fixP->fx_subsy == NULL)
12526 /* We need the symbol name for the VTABLE entries. */
12527 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
12528 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12531 /* Don't allow symbols to be discarded on GOT related relocs. */
12532 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
12533 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
12534 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
12541 elf32_arm_target_format ()
12543 if (target_big_endian)
12546 return "elf32-bigarm-oabi";
12548 return "elf32-bigarm";
12553 return "elf32-littlearm-oabi";
12555 return "elf32-littlearm";
12560 armelf_frob_symbol (symp, puntp)
12564 elf_frob_symbol (symp, puntp);
12567 static bfd_reloc_code_real_type
12577 bfd_reloc_code_real_type reloc;
12581 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
12582 MAP ("(got)", BFD_RELOC_ARM_GOT32),
12583 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
12584 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
12585 branch instructions generated by GCC for PLT relocs. */
12586 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
12587 { NULL, 0, BFD_RELOC_UNUSED }
12591 for (i = 0, ip = input_line_pointer;
12592 i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
12594 id[i] = TOLOWER (*ip);
12596 for (i = 0; reloc_map[i].str; i++)
12597 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
12600 input_line_pointer += reloc_map[i].len;
12602 return reloc_map[i].reloc;
12606 s_arm_elf_cons (nbytes)
12611 #ifdef md_flush_pending_output
12612 md_flush_pending_output ();
12615 if (is_it_end_of_statement ())
12617 demand_empty_rest_of_line ();
12621 #ifdef md_cons_align
12622 md_cons_align (nbytes);
12627 bfd_reloc_code_real_type reloc;
12629 expression (& exp);
12631 if (exp.X_op == O_symbol
12632 && * input_line_pointer == '('
12633 && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
12635 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
12636 int size = bfd_get_reloc_size (howto);
12639 as_bad ("%s relocations do not fit in %d bytes",
12640 howto->name, nbytes);
12643 register char *p = frag_more ((int) nbytes);
12644 int offset = nbytes - size;
12646 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
12651 emit_expr (&exp, (unsigned int) nbytes);
12653 while (*input_line_pointer++ == ',');
12655 /* Put terminator back into stream. */
12656 input_line_pointer --;
12657 demand_empty_rest_of_line ();
12660 #endif /* OBJ_ELF */
12662 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
12663 of an rs_align_code fragment. */
12666 arm_handle_align (fragP)
12669 static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
12670 static char const thumb_noop[2] = { 0xc0, 0x46 };
12671 static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
12672 static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
12674 int bytes, fix, noop_size;
12678 if (fragP->fr_type != rs_align_code)
12681 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
12682 p = fragP->fr_literal + fragP->fr_fix;
12685 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
12686 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
12688 if (fragP->tc_frag_data)
12690 if (target_big_endian)
12691 noop = thumb_bigend_noop;
12694 noop_size = sizeof (thumb_noop);
12698 if (target_big_endian)
12699 noop = arm_bigend_noop;
12702 noop_size = sizeof (arm_noop);
12705 if (bytes & (noop_size - 1))
12707 fix = bytes & (noop_size - 1);
12708 memset (p, 0, fix);
12713 while (bytes >= noop_size)
12715 memcpy (p, noop, noop_size);
12717 bytes -= noop_size;
12721 fragP->fr_fix += fix;
12722 fragP->fr_var = noop_size;
12725 /* Called from md_do_align. Used to create an alignment
12726 frag in a code section. */
12729 arm_frag_align_code (n, max)
12735 /* We assume that there will never be a requirment
12736 to support alignments greater than 32 bytes. */
12737 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
12738 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
12740 p = frag_var (rs_align_code,
12741 MAX_MEM_FOR_RS_ALIGN_CODE,
12743 (relax_substateT) max,
12751 /* Perform target specific initialisation of a frag. */
12754 arm_init_frag (fragP)
12757 /* Record whether this frag is in an ARM or a THUMB area. */
12758 fragP->tc_frag_data = thumb_mode;