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.
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 },
2351 { "extend", float_cons, 'x' },
2352 { "ldouble", float_cons, 'x' },
2353 { "packed", float_cons, 'p' },
2357 /* Other internal functions. */
2358 static int arm_parse_extension PARAMS ((char *, int *));
2359 static int arm_parse_cpu PARAMS ((char *));
2360 static int arm_parse_arch PARAMS ((char *));
2361 static int arm_parse_fpu PARAMS ((char *));
2362 #if defined OBJ_COFF || defined OBJ_ELF
2363 static void arm_add_note PARAMS ((const char *, const char *, unsigned int));
2366 /* Stuff needed to resolve the label ambiguity
2376 symbolS * last_label_seen;
2377 static int label_is_thumb_function_name = FALSE;
2379 /* Literal Pool stuff. */
2381 #define MAX_LITERAL_POOL_SIZE 1024
2383 /* Literal pool structure. Held on a per-section
2384 and per-sub-section basis. */
2385 typedef struct literal_pool
2387 expressionS literals [MAX_LITERAL_POOL_SIZE];
2388 unsigned int next_free_entry;
2392 subsegT sub_section;
2393 struct literal_pool * next;
2396 /* Pointer to a linked list of literal pools. */
2397 literal_pool * list_of_pools = NULL;
2399 static literal_pool * find_literal_pool PARAMS ((void));
2400 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2402 static literal_pool *
2403 find_literal_pool ()
2405 literal_pool * pool;
2407 for (pool = list_of_pools; pool != NULL; pool = pool->next)
2409 if (pool->section == now_seg
2410 && pool->sub_section == now_subseg)
2417 static literal_pool *
2418 find_or_make_literal_pool ()
2420 /* Next literal pool ID number. */
2421 static unsigned int latest_pool_num = 1;
2422 literal_pool * pool;
2424 pool = find_literal_pool ();
2428 /* Create a new pool. */
2429 pool = (literal_pool *) xmalloc (sizeof (* pool));
2433 pool->next_free_entry = 0;
2434 pool->section = now_seg;
2435 pool->sub_section = now_subseg;
2436 pool->next = list_of_pools;
2437 pool->symbol = NULL;
2439 /* Add it to the list. */
2440 list_of_pools = pool;
2443 /* New pools, and emptied pools, will have a NULL symbol. */
2444 if (pool->symbol == NULL)
2446 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2447 (valueT) 0, &zero_address_frag);
2448 pool->id = latest_pool_num ++;
2455 /* Add the literal in the global 'inst'
2456 structure to the relevent literal pool. */
2460 literal_pool * pool;
2463 pool = find_or_make_literal_pool ();
2465 /* Check if this literal value is already in the pool. */
2466 for (entry = 0; entry < pool->next_free_entry; entry ++)
2468 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2469 && (inst.reloc.exp.X_op == O_constant)
2470 && (pool->literals[entry].X_add_number
2471 == inst.reloc.exp.X_add_number)
2472 && (pool->literals[entry].X_unsigned
2473 == inst.reloc.exp.X_unsigned))
2476 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2477 && (inst.reloc.exp.X_op == O_symbol)
2478 && (pool->literals[entry].X_add_number
2479 == inst.reloc.exp.X_add_number)
2480 && (pool->literals[entry].X_add_symbol
2481 == inst.reloc.exp.X_add_symbol)
2482 && (pool->literals[entry].X_op_symbol
2483 == inst.reloc.exp.X_op_symbol))
2487 /* Do we need to create a new entry? */
2488 if (entry == pool->next_free_entry)
2490 if (entry >= MAX_LITERAL_POOL_SIZE)
2492 inst.error = _("literal pool overflow");
2496 pool->literals[entry] = inst.reloc.exp;
2497 pool->next_free_entry += 1;
2500 inst.reloc.exp.X_op = O_symbol;
2501 inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2502 inst.reloc.exp.X_add_symbol = pool->symbol;
2507 /* Can't use symbol_new here, so have to create a symbol and then at
2508 a later date assign it a value. Thats what these functions do. */
2511 symbol_locate (symbolP, name, segment, valu, frag)
2513 const char * name; /* It is copied, the caller can modify. */
2514 segT segment; /* Segment identifier (SEG_<something>). */
2515 valueT valu; /* Symbol value. */
2516 fragS * frag; /* Associated fragment. */
2518 unsigned int name_length;
2519 char * preserved_copy_of_name;
2521 name_length = strlen (name) + 1; /* +1 for \0. */
2522 obstack_grow (¬es, name, name_length);
2523 preserved_copy_of_name = obstack_finish (¬es);
2524 #ifdef STRIP_UNDERSCORE
2525 if (preserved_copy_of_name[0] == '_')
2526 preserved_copy_of_name++;
2529 #ifdef tc_canonicalize_symbol_name
2530 preserved_copy_of_name =
2531 tc_canonicalize_symbol_name (preserved_copy_of_name);
2534 S_SET_NAME (symbolP, preserved_copy_of_name);
2536 S_SET_SEGMENT (symbolP, segment);
2537 S_SET_VALUE (symbolP, valu);
2538 symbol_clear_list_pointers (symbolP);
2540 symbol_set_frag (symbolP, frag);
2542 /* Link to end of symbol chain. */
2544 extern int symbol_table_frozen;
2545 if (symbol_table_frozen)
2549 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2551 obj_symbol_new_hook (symbolP);
2553 #ifdef tc_symbol_new_hook
2554 tc_symbol_new_hook (symbolP);
2558 verify_symbol_chain (symbol_rootP, symbol_lastP);
2559 #endif /* DEBUG_SYMS */
2562 /* Check that an immediate is valid.
2563 If so, convert it to the right format. */
2566 validate_immediate (val)
2572 #define rotate_left(v, n) (v << n | v >> (32 - n))
2574 for (i = 0; i < 32; i += 2)
2575 if ((a = rotate_left (val, i)) <= 0xff)
2576 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
2581 /* Check to see if an immediate can be computed as two seperate immediate
2582 values, added together. We already know that this value cannot be
2583 computed by just one ARM instruction. */
2586 validate_immediate_twopart (val, highpart)
2588 unsigned int * highpart;
2593 for (i = 0; i < 32; i += 2)
2594 if (((a = rotate_left (val, i)) & 0xff) != 0)
2600 * highpart = (a >> 8) | ((i + 24) << 7);
2602 else if (a & 0xff0000)
2606 * highpart = (a >> 16) | ((i + 16) << 7);
2610 assert (a & 0xff000000);
2611 * highpart = (a >> 24) | ((i + 8) << 7);
2614 return (a & 0xff) | (i << 7);
2621 validate_offset_imm (val, hwse)
2625 if ((hwse && val > 255) || val > 4095)
2632 int a ATTRIBUTE_UNUSED;
2634 as_bad (_("invalid syntax for .req directive"));
2639 int ignore ATTRIBUTE_UNUSED;
2641 /* We don't support putting frags in the BSS segment, we fake it by
2642 marking in_bss, then looking at s_skip for clues. */
2643 subseg_set (bss_section, 0);
2644 demand_empty_rest_of_line ();
2649 int ignore ATTRIBUTE_UNUSED;
2651 /* Never make frag if expect extra pass. */
2653 frag_align (1, 0, 0);
2655 record_alignment (now_seg, 1);
2657 demand_empty_rest_of_line ();
2662 int ignored ATTRIBUTE_UNUSED;
2665 literal_pool * pool;
2668 pool = find_literal_pool ();
2670 || pool->symbol == NULL
2671 || pool->next_free_entry == 0)
2674 /* Align pool as you have word accesses.
2675 Only make a frag if we have to. */
2677 frag_align (2, 0, 0);
2679 record_alignment (now_seg, 2);
2681 sprintf (sym_name, "$$lit_\002%x", pool->id);
2683 symbol_locate (pool->symbol, sym_name, now_seg,
2684 (valueT) frag_now_fix (), frag_now);
2685 symbol_table_insert (pool->symbol);
2687 ARM_SET_THUMB (pool->symbol, thumb_mode);
2689 #if defined OBJ_COFF || defined OBJ_ELF
2690 ARM_SET_INTERWORK (pool->symbol, support_interwork);
2693 for (entry = 0; entry < pool->next_free_entry; entry ++)
2694 /* First output the expression in the instruction to the pool. */
2695 emit_expr (&(pool->literals[entry]), 4); /* .word */
2697 /* Mark the pool as empty. */
2698 pool->next_free_entry = 0;
2699 pool->symbol = NULL;
2702 /* Same as s_align_ptwo but align 0 => align 2. */
2706 int unused ATTRIBUTE_UNUSED;
2709 register long temp_fill;
2710 long max_alignment = 15;
2712 temp = get_absolute_expression ();
2713 if (temp > max_alignment)
2714 as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
2717 as_bad (_("alignment negative. 0 assumed."));
2721 if (*input_line_pointer == ',')
2723 input_line_pointer++;
2724 temp_fill = get_absolute_expression ();
2732 /* Only make a frag if we HAVE to. */
2733 if (temp && !need_pass_2)
2734 frag_align (temp, (int) temp_fill, 0);
2735 demand_empty_rest_of_line ();
2737 record_alignment (now_seg, temp);
2741 s_force_thumb (ignore)
2742 int ignore ATTRIBUTE_UNUSED;
2744 /* If we are not already in thumb mode go into it, EVEN if
2745 the target processor does not support thumb instructions.
2746 This is used by gcc/config/arm/lib1funcs.asm for example
2747 to compile interworking support functions even if the
2748 target processor should not support interworking. */
2753 record_alignment (now_seg, 1);
2756 demand_empty_rest_of_line ();
2760 s_thumb_func (ignore)
2761 int ignore ATTRIBUTE_UNUSED;
2766 /* The following label is the name/address of the start of a Thumb function.
2767 We need to know this for the interworking support. */
2768 label_is_thumb_function_name = TRUE;
2770 demand_empty_rest_of_line ();
2773 /* Perform a .set directive, but also mark the alias as
2774 being a thumb function. */
2780 /* XXX the following is a duplicate of the code for s_set() in read.c
2781 We cannot just call that code as we need to get at the symbol that
2783 register char * name;
2784 register char delim;
2785 register char * end_name;
2786 register symbolS * symbolP;
2788 /* Especial apologies for the random logic:
2789 This just grew, and could be parsed much more simply!
2791 name = input_line_pointer;
2792 delim = get_symbol_end ();
2793 end_name = input_line_pointer;
2798 if (*input_line_pointer != ',')
2801 as_bad (_("expected comma after name \"%s\""), name);
2803 ignore_rest_of_line ();
2807 input_line_pointer++;
2810 if (name[0] == '.' && name[1] == '\0')
2812 /* XXX - this should not happen to .thumb_set. */
2816 if ((symbolP = symbol_find (name)) == NULL
2817 && (symbolP = md_undefined_symbol (name)) == NULL)
2820 /* When doing symbol listings, play games with dummy fragments living
2821 outside the normal fragment chain to record the file and line info
2823 if (listing & LISTING_SYMBOLS)
2825 extern struct list_info_struct * listing_tail;
2826 fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
2828 memset (dummy_frag, 0, sizeof (fragS));
2829 dummy_frag->fr_type = rs_fill;
2830 dummy_frag->line = listing_tail;
2831 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
2832 dummy_frag->fr_symbol = symbolP;
2836 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
2839 /* "set" symbols are local unless otherwise specified. */
2840 SF_SET_LOCAL (symbolP);
2841 #endif /* OBJ_COFF */
2842 } /* Make a new symbol. */
2844 symbol_table_insert (symbolP);
2849 && S_IS_DEFINED (symbolP)
2850 && S_GET_SEGMENT (symbolP) != reg_section)
2851 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
2853 pseudo_set (symbolP);
2855 demand_empty_rest_of_line ();
2857 /* XXX Now we come to the Thumb specific bit of code. */
2859 THUMB_SET_FUNC (symbolP, 1);
2860 ARM_SET_THUMB (symbolP, 1);
2861 #if defined OBJ_ELF || defined OBJ_COFF
2862 ARM_SET_INTERWORK (symbolP, support_interwork);
2867 opcode_select (width)
2875 if (! (cpu_variant & ARM_EXT_V4T))
2876 as_bad (_("selected processor does not support THUMB opcodes"));
2879 /* No need to force the alignment, since we will have been
2880 coming from ARM mode, which is word-aligned. */
2881 record_alignment (now_seg, 1);
2888 if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
2889 as_bad (_("selected processor does not support ARM opcodes"));
2894 frag_align (2, 0, 0);
2896 record_alignment (now_seg, 1);
2901 as_bad (_("invalid instruction size selected (%d)"), width);
2907 int ignore ATTRIBUTE_UNUSED;
2910 demand_empty_rest_of_line ();
2915 int ignore ATTRIBUTE_UNUSED;
2918 demand_empty_rest_of_line ();
2923 int unused ATTRIBUTE_UNUSED;
2927 temp = get_absolute_expression ();
2932 opcode_select (temp);
2936 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
2944 skip_whitespace (str);
2946 if (*str != '\0' && !inst.error)
2947 inst.error = _("garbage following instruction");
2951 skip_past_comma (str)
2954 char * p = * str, c;
2957 while ((c = *p) == ' ' || c == ',')
2960 if (c == ',' && comma++)
2968 return comma ? SUCCESS : FAIL;
2971 /* A standard register must be given at this point.
2972 SHIFT is the place to put it in inst.instruction.
2973 Restores input start point on error.
2974 Returns the reg#, or FAIL. */
2977 reg_required_here (str, shift)
2981 static char buff [128]; /* XXX */
2983 char * start = * str;
2985 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
2988 inst.instruction |= reg << shift;
2992 /* Restore the start point, we may have got a reg of the wrong class. */
2995 /* In the few cases where we might be able to accept something else
2996 this error can be overridden. */
2997 sprintf (buff, _("register expected, not '%.100s'"), start);
3003 /* A Intel Wireless MMX technology register
3004 must be given at this point.
3005 Shift is the place to put it in inst.instruction.
3006 Restores input start point on err.
3007 Returns the reg#, or FAIL. */
3010 wreg_required_here (str, shift, reg_type)
3013 enum wreg_type reg_type;
3015 static char buff [128];
3017 char * start = *str;
3019 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_IWMMXT].htab)) != FAIL)
3021 if (wr_register (reg)
3022 && (reg_type == IWMMXT_REG_WR || reg_type == IWMMXT_REG_WR_OR_WC))
3025 inst.instruction |= (reg ^ WR_PREFIX) << shift;
3028 else if (wc_register (reg)
3029 && (reg_type == IWMMXT_REG_WC || reg_type == IWMMXT_REG_WR_OR_WC))
3032 inst.instruction |= (reg ^ WC_PREFIX) << shift;
3035 else if ((wcg_register (reg) && reg_type == IWMMXT_REG_WCG))
3038 inst.instruction |= ((reg ^ WC_PREFIX) - 8) << shift;
3043 /* Restore the start point, we may have got a reg of the wrong class. */
3046 /* In the few cases where we might be able to accept
3047 something else this error can be overridden. */
3048 sprintf (buff, _("Intel Wireless MMX technology register expected, not '%.100s'"), start);
3054 static const struct asm_psr *
3056 register char ** ccp;
3058 char * start = * ccp;
3061 const struct asm_psr * psr;
3065 /* Skip to the end of the next word in the input stream. */
3070 while (ISALPHA (c) || c == '_');
3072 /* Terminate the word. */
3075 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
3076 feature for ease of use and backwards compatibility. */
3077 if (!strncmp (start, "cpsr", 4))
3078 strncpy (start, "CPSR", 4);
3079 else if (!strncmp (start, "spsr", 4))
3080 strncpy (start, "SPSR", 4);
3082 /* Now locate the word in the psr hash table. */
3083 psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
3085 /* Restore the input stream. */
3088 /* If we found a valid match, advance the
3089 stream pointer past the end of the word. */
3095 /* Parse the input looking for a PSR flag. */
3098 psr_required_here (str)
3101 char * start = * str;
3102 const struct asm_psr * psr;
3104 psr = arm_psr_parse (str);
3108 /* If this is the SPSR that is being modified, set the R bit. */
3110 inst.instruction |= SPSR_BIT;
3112 /* Set the psr flags in the MSR instruction. */
3113 inst.instruction |= psr->field << PSR_SHIFT;
3118 /* In the few cases where we might be able to accept
3119 something else this error can be overridden. */
3120 inst.error = _("flag for {c}psr instruction expected");
3122 /* Restore the start point. */
3128 co_proc_number (str)
3131 int processor, pchar;
3134 skip_whitespace (*str);
3137 /* The data sheet seems to imply that just a number on its own is valid
3138 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
3140 if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
3146 if (pchar >= '0' && pchar <= '9')
3148 processor = pchar - '0';
3149 if (**str >= '0' && **str <= '9')
3151 processor = processor * 10 + *(*str)++ - '0';
3154 inst.error = _("illegal co-processor number");
3161 inst.error = _("bad or missing co-processor number");
3166 inst.instruction |= processor << 8;
3171 cp_opc_expr (str, where, length)
3178 skip_whitespace (* str);
3180 memset (&expr, '\0', sizeof (expr));
3182 if (my_get_expression (&expr, str))
3184 if (expr.X_op != O_constant)
3186 inst.error = _("bad or missing expression");
3190 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
3192 inst.error = _("immediate co-processor expression too large");
3196 inst.instruction |= expr.X_add_number << where;
3201 cp_reg_required_here (str, where)
3206 char * start = *str;
3208 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
3210 inst.instruction |= reg << where;
3214 /* In the few cases where we might be able to accept something else
3215 this error can be overridden. */
3216 inst.error = _("co-processor register expected");
3218 /* Restore the start point. */
3224 fp_reg_required_here (str, where)
3229 char * start = * str;
3231 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
3233 inst.instruction |= reg << where;
3237 /* In the few cases where we might be able to accept something else
3238 this error can be overridden. */
3239 inst.error = _("floating point register expected");
3241 /* Restore the start point. */
3247 cp_address_offset (str)
3252 skip_whitespace (* str);
3254 if (! is_immediate_prefix (**str))
3256 inst.error = _("immediate expression expected");
3262 if (my_get_expression (& inst.reloc.exp, str))
3265 if (inst.reloc.exp.X_op == O_constant)
3267 offset = inst.reloc.exp.X_add_number;
3271 inst.error = _("co-processor address must be word aligned");
3275 if (offset > 1023 || offset < -1023)
3277 inst.error = _("offset too large");
3282 inst.instruction |= INDEX_UP;
3286 inst.instruction |= offset >> 2;
3289 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3295 cp_address_required_here (str, wb_ok)
3308 skip_whitespace (p);
3310 if ((reg = reg_required_here (& p, 16)) == FAIL)
3313 skip_whitespace (p);
3319 if (wb_ok && skip_past_comma (& p) == SUCCESS)
3322 write_back = WRITE_BACK;
3326 inst.error = _("pc may not be used in post-increment");
3330 if (cp_address_offset (& p) == FAIL)
3334 pre_inc = PRE_INDEX | INDEX_UP;
3338 /* '['Rn, #expr']'[!] */
3340 if (skip_past_comma (& p) == FAIL)
3342 inst.error = _("pre-indexed expression expected");
3346 pre_inc = PRE_INDEX;
3348 if (cp_address_offset (& p) == FAIL)
3351 skip_whitespace (p);
3355 inst.error = _("missing ]");
3359 skip_whitespace (p);
3361 if (wb_ok && *p == '!')
3365 inst.error = _("pc may not be used with write-back");
3370 write_back = WRITE_BACK;
3376 if (my_get_expression (&inst.reloc.exp, &p))
3379 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3380 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3381 inst.reloc.pc_rel = 1;
3382 inst.instruction |= (REG_PC << 16);
3383 pre_inc = PRE_INDEX;
3386 inst.instruction |= write_back | pre_inc;
3392 cp_byte_address_offset (str)
3397 skip_whitespace (* str);
3399 if (! is_immediate_prefix (**str))
3401 inst.error = _("immediate expression expected");
3407 if (my_get_expression (& inst.reloc.exp, str))
3410 if (inst.reloc.exp.X_op == O_constant)
3412 offset = inst.reloc.exp.X_add_number;
3414 if (offset > 255 || offset < -255)
3416 inst.error = _("offset too large");
3421 inst.instruction |= INDEX_UP;
3425 inst.instruction |= offset;
3428 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3434 cp_byte_address_required_here (str)
3446 skip_whitespace (p);
3448 if ((reg = reg_required_here (& p, 16)) == FAIL)
3451 skip_whitespace (p);
3457 if (skip_past_comma (& p) == SUCCESS)
3460 write_back = WRITE_BACK;
3464 inst.error = _("pc may not be used in post-increment");
3468 if (cp_byte_address_offset (& p) == FAIL)
3472 pre_inc = PRE_INDEX | INDEX_UP;
3476 /* '['Rn, #expr']'[!] */
3478 if (skip_past_comma (& p) == FAIL)
3480 inst.error = _("pre-indexed expression expected");
3484 pre_inc = PRE_INDEX;
3486 if (cp_byte_address_offset (& p) == FAIL)
3489 skip_whitespace (p);
3493 inst.error = _("missing ]");
3497 skip_whitespace (p);
3503 inst.error = _("pc may not be used with write-back");
3508 write_back = WRITE_BACK;
3514 if (my_get_expression (&inst.reloc.exp, &p))
3517 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM_S2;
3518 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3519 inst.reloc.pc_rel = 1;
3520 inst.instruction |= (REG_PC << 16);
3521 pre_inc = PRE_INDEX;
3524 inst.instruction |= write_back | pre_inc;
3533 /* Do nothing really. */
3544 /* Only one syntax. */
3545 skip_whitespace (str);
3547 if (reg_required_here (&str, 12) == FAIL)
3549 inst.error = BAD_ARGS;
3553 if (skip_past_comma (&str) == FAIL)
3555 inst.error = _("comma expected after register name");
3559 skip_whitespace (str);
3561 if ( strcmp (str, "CPSR") == 0
3562 || strcmp (str, "SPSR") == 0
3563 /* Lower case versions for backwards compatability. */
3564 || strcmp (str, "cpsr") == 0
3565 || strcmp (str, "spsr") == 0)
3568 /* This is for backwards compatability with older toolchains. */
3569 else if ( strcmp (str, "cpsr_all") == 0
3570 || strcmp (str, "spsr_all") == 0)
3574 inst.error = _("CPSR or SPSR expected");
3578 if (* str == 's' || * str == 'S')
3579 inst.instruction |= SPSR_BIT;
3585 /* Two possible forms:
3586 "{C|S}PSR_<field>, Rm",
3587 "{C|S}PSR_f, #expression". */
3593 skip_whitespace (str);
3595 if (psr_required_here (& str) == FAIL)
3598 if (skip_past_comma (& str) == FAIL)
3600 inst.error = _("comma missing after psr flags");
3604 skip_whitespace (str);
3606 if (reg_required_here (& str, 0) != FAIL)
3613 if (! is_immediate_prefix (* str))
3616 _("only a register or immediate value can follow a psr flag");
3623 if (my_get_expression (& inst.reloc.exp, & str))
3626 _("only a register or immediate value can follow a psr flag");
3630 #if 0 /* The first edition of the ARM architecture manual stated that
3631 writing anything other than the flags with an immediate operation
3632 had UNPREDICTABLE effects. This constraint was removed in the
3633 second edition of the specification. */
3634 if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
3635 && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
3637 inst.error = _("immediate value cannot be used to set this field");
3642 inst.instruction |= INST_IMMEDIATE;
3644 if (inst.reloc.exp.X_add_symbol)
3646 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
3647 inst.reloc.pc_rel = 0;
3651 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
3653 if (value == (unsigned) FAIL)
3655 inst.error = _("invalid constant");
3659 inst.instruction |= value;
3666 /* Long Multiply Parser
3667 UMULL RdLo, RdHi, Rm, Rs
3668 SMULL RdLo, RdHi, Rm, Rs
3669 UMLAL RdLo, RdHi, Rm, Rs
3670 SMLAL RdLo, RdHi, Rm, Rs. */
3676 int rdlo, rdhi, rm, rs;
3678 /* Only one format "rdlo, rdhi, rm, rs". */
3679 skip_whitespace (str);
3681 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
3683 inst.error = BAD_ARGS;
3687 if (skip_past_comma (&str) == FAIL
3688 || (rdhi = reg_required_here (&str, 16)) == FAIL)
3690 inst.error = BAD_ARGS;
3694 if (skip_past_comma (&str) == FAIL
3695 || (rm = reg_required_here (&str, 0)) == FAIL)
3697 inst.error = BAD_ARGS;
3701 /* rdhi, rdlo and rm must all be different. */
3702 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
3703 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
3705 if (skip_past_comma (&str) == FAIL
3706 || (rs = reg_required_here (&str, 8)) == FAIL)
3708 inst.error = BAD_ARGS;
3712 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
3714 inst.error = BAD_PC;
3728 /* Only one format "rd, rm, rs". */
3729 skip_whitespace (str);
3731 if ((rd = reg_required_here (&str, 16)) == FAIL)
3733 inst.error = BAD_ARGS;
3739 inst.error = BAD_PC;
3743 if (skip_past_comma (&str) == FAIL
3744 || (rm = reg_required_here (&str, 0)) == FAIL)
3746 inst.error = BAD_ARGS;
3752 inst.error = BAD_PC;
3757 as_tsktsk (_("rd and rm should be different in mul"));
3759 if (skip_past_comma (&str) == FAIL
3760 || (rm = reg_required_here (&str, 8)) == FAIL)
3762 inst.error = BAD_ARGS;
3768 inst.error = BAD_PC;
3782 /* Only one format "rd, rm, rs, rn". */
3783 skip_whitespace (str);
3785 if ((rd = reg_required_here (&str, 16)) == FAIL)
3787 inst.error = BAD_ARGS;
3793 inst.error = BAD_PC;
3797 if (skip_past_comma (&str) == FAIL
3798 || (rm = reg_required_here (&str, 0)) == FAIL)
3800 inst.error = BAD_ARGS;
3806 inst.error = BAD_PC;
3811 as_tsktsk (_("rd and rm should be different in mla"));
3813 if (skip_past_comma (&str) == FAIL
3814 || (rd = reg_required_here (&str, 8)) == FAIL
3815 || skip_past_comma (&str) == FAIL
3816 || (rm = reg_required_here (&str, 12)) == FAIL)
3818 inst.error = BAD_ARGS;
3822 if (rd == REG_PC || rm == REG_PC)
3824 inst.error = BAD_PC;
3832 /* Expects *str -> the characters "acc0", possibly with leading blanks.
3833 Advances *str to the next non-alphanumeric.
3834 Returns 0, or else FAIL (in which case sets inst.error).
3836 (In a future XScale, there may be accumulators other than zero.
3837 At that time this routine and its callers can be upgraded to suit.) */
3840 accum0_required_here (str)
3843 static char buff [128]; /* Note the address is taken. Hence, static. */
3846 int result = 0; /* The accum number. */
3848 skip_whitespace (p);
3850 *str = p; /* Advance caller's string pointer too. */
3855 *--p = 0; /* Aap nul into input buffer at non-alnum. */
3857 if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
3859 sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
3864 *p = c; /* Unzap. */
3865 *str = p; /* Caller's string pointer to after match. */
3869 /* Expects **str -> after a comma. May be leading blanks.
3870 Advances *str, recognizing a load mode, and setting inst.instruction.
3871 Returns rn, or else FAIL (in which case may set inst.error
3872 and not advance str)
3874 Note: doesn't know Rd, so no err checks that require such knowledge. */
3877 ld_mode_required_here (string)
3880 char * str = * string;
3884 skip_whitespace (str);
3890 skip_whitespace (str);
3892 if ((rn = reg_required_here (& str, 16)) == FAIL)
3895 skip_whitespace (str);
3901 if (skip_past_comma (& str) == SUCCESS)
3903 /* [Rn],... (post inc) */
3904 if (ldst_extend_v4 (&str) == FAIL)
3909 skip_whitespace (str);
3914 inst.instruction |= WRITE_BACK;
3917 inst.instruction |= INDEX_UP | HWOFFSET_IMM;
3923 if (skip_past_comma (& str) == FAIL)
3925 inst.error = _("pre-indexed expression expected");
3931 if (ldst_extend_v4 (&str) == FAIL)
3934 skip_whitespace (str);
3936 if (* str ++ != ']')
3938 inst.error = _("missing ]");
3942 skip_whitespace (str);
3947 inst.instruction |= WRITE_BACK;
3951 else if (* str == '=') /* ldr's "r,=label" syntax */
3952 /* We should never reach here, because <text> = <expression> is
3953 caught gas/read.c read_a_source_file() as a .set operation. */
3955 else /* PC +- 8 bit immediate offset. */
3957 if (my_get_expression (& inst.reloc.exp, & str))
3960 inst.instruction |= HWOFFSET_IMM; /* The I bit. */
3961 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
3962 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3963 inst.reloc.pc_rel = 1;
3964 inst.instruction |= (REG_PC << 16);
3970 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
3976 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3977 SMLAxy{cond} Rd,Rm,Rs,Rn
3978 SMLAWy{cond} Rd,Rm,Rs,Rn
3979 Error if any register is R15. */
3987 skip_whitespace (str);
3989 if ((rd = reg_required_here (& str, 16)) == FAIL
3990 || skip_past_comma (& str) == FAIL
3991 || (rm = reg_required_here (& str, 0)) == FAIL
3992 || skip_past_comma (& str) == FAIL
3993 || (rs = reg_required_here (& str, 8)) == FAIL
3994 || skip_past_comma (& str) == FAIL
3995 || (rn = reg_required_here (& str, 12)) == FAIL)
3996 inst.error = BAD_ARGS;
3998 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
3999 inst.error = BAD_PC;
4005 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4006 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4007 Error if any register is R15.
4008 Warning if Rdlo == Rdhi. */
4014 int rdlo, rdhi, rm, rs;
4016 skip_whitespace (str);
4018 if ((rdlo = reg_required_here (& str, 12)) == FAIL
4019 || skip_past_comma (& str) == FAIL
4020 || (rdhi = reg_required_here (& str, 16)) == FAIL
4021 || skip_past_comma (& str) == FAIL
4022 || (rm = reg_required_here (& str, 0)) == FAIL
4023 || skip_past_comma (& str) == FAIL
4024 || (rs = reg_required_here (& str, 8)) == FAIL)
4026 inst.error = BAD_ARGS;
4030 if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
4032 inst.error = BAD_PC;
4037 as_tsktsk (_("rdhi and rdlo must be different"));
4042 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4043 SMULxy{cond} Rd,Rm,Rs
4044 Error if any register is R15. */
4052 skip_whitespace (str);
4054 if ((rd = reg_required_here (& str, 16)) == FAIL
4055 || skip_past_comma (& str) == FAIL
4056 || (rm = reg_required_here (& str, 0)) == FAIL
4057 || skip_past_comma (& str) == FAIL
4058 || (rs = reg_required_here (& str, 8)) == FAIL)
4059 inst.error = BAD_ARGS;
4061 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
4062 inst.error = BAD_PC;
4068 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4069 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4070 Error if any register is R15. */
4078 skip_whitespace (str);
4080 if ((rd = reg_required_here (& str, 12)) == FAIL
4081 || skip_past_comma (& str) == FAIL
4082 || (rm = reg_required_here (& str, 0)) == FAIL
4083 || skip_past_comma (& str) == FAIL
4084 || (rn = reg_required_here (& str, 16)) == FAIL)
4085 inst.error = BAD_ARGS;
4087 else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
4088 inst.error = BAD_PC;
4094 /* ARM V5E (el Segundo)
4095 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4096 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4098 These are equivalent to the XScale instructions MAR and MRA,
4099 respectively, when coproc == 0, opcode == 0, and CRm == 0.
4101 Result unpredicatable if Rd or Rn is R15. */
4109 skip_whitespace (str);
4111 if (co_proc_number (& str) == FAIL)
4114 inst.error = BAD_ARGS;
4118 if (skip_past_comma (& str) == FAIL
4119 || cp_opc_expr (& str, 4, 4) == FAIL)
4122 inst.error = BAD_ARGS;
4126 if (skip_past_comma (& str) == FAIL
4127 || (rd = reg_required_here (& str, 12)) == FAIL)
4130 inst.error = BAD_ARGS;
4134 if (skip_past_comma (& str) == FAIL
4135 || (rn = reg_required_here (& str, 16)) == FAIL)
4138 inst.error = BAD_ARGS;
4142 /* Unpredictable result if rd or rn is R15. */
4143 if (rd == REG_PC || rn == REG_PC)
4145 (_("Warning: instruction unpredictable when using r15"));
4147 if (skip_past_comma (& str) == FAIL
4148 || cp_reg_required_here (& str, 0) == FAIL)
4151 inst.error = BAD_ARGS;
4158 /* ARM V5 count-leading-zeroes instruction (argument parse)
4159 CLZ{<cond>} <Rd>, <Rm>
4160 Condition defaults to COND_ALWAYS.
4161 Error if Rd or Rm are R15. */
4169 skip_whitespace (str);
4171 if (((rd = reg_required_here (& str, 12)) == FAIL)
4172 || (skip_past_comma (& str) == FAIL)
4173 || ((rm = reg_required_here (& str, 0)) == FAIL))
4174 inst.error = BAD_ARGS;
4176 else if (rd == REG_PC || rm == REG_PC )
4177 inst.error = BAD_PC;
4183 /* ARM V5 (argument parse)
4184 LDC2{L} <coproc>, <CRd>, <addressing mode>
4185 STC2{L} <coproc>, <CRd>, <addressing mode>
4186 Instruction is not conditional, and has 0xf in the codition field.
4187 Otherwise, it's the same as LDC/STC. */
4193 skip_whitespace (str);
4195 if (co_proc_number (& str) == FAIL)
4198 inst.error = BAD_ARGS;
4200 else if (skip_past_comma (& str) == FAIL
4201 || cp_reg_required_here (& str, 12) == FAIL)
4204 inst.error = BAD_ARGS;
4206 else if (skip_past_comma (& str) == FAIL
4207 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
4210 inst.error = BAD_ARGS;
4216 /* ARM V5 (argument parse)
4217 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4218 Instruction is not conditional, and has 0xf in the condition field.
4219 Otherwise, it's the same as CDP. */
4225 skip_whitespace (str);
4227 if (co_proc_number (& str) == FAIL)
4230 inst.error = BAD_ARGS;
4234 if (skip_past_comma (& str) == FAIL
4235 || cp_opc_expr (& str, 20,4) == FAIL)
4238 inst.error = BAD_ARGS;
4242 if (skip_past_comma (& str) == FAIL
4243 || cp_reg_required_here (& str, 12) == FAIL)
4246 inst.error = BAD_ARGS;
4250 if (skip_past_comma (& str) == FAIL
4251 || cp_reg_required_here (& str, 16) == FAIL)
4254 inst.error = BAD_ARGS;
4258 if (skip_past_comma (& str) == FAIL
4259 || cp_reg_required_here (& str, 0) == FAIL)
4262 inst.error = BAD_ARGS;
4266 if (skip_past_comma (& str) == SUCCESS)
4268 if (cp_opc_expr (& str, 5, 3) == FAIL)
4271 inst.error = BAD_ARGS;
4279 /* ARM V5 (argument parse)
4280 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4281 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4282 Instruction is not conditional, and has 0xf in the condition field.
4283 Otherwise, it's the same as MCR/MRC. */
4289 skip_whitespace (str);
4291 if (co_proc_number (& str) == FAIL)
4294 inst.error = BAD_ARGS;
4298 if (skip_past_comma (& str) == FAIL
4299 || cp_opc_expr (& str, 21, 3) == FAIL)
4302 inst.error = BAD_ARGS;
4306 if (skip_past_comma (& str) == FAIL
4307 || reg_required_here (& str, 12) == FAIL)
4310 inst.error = BAD_ARGS;
4314 if (skip_past_comma (& str) == FAIL
4315 || cp_reg_required_here (& str, 16) == FAIL)
4318 inst.error = BAD_ARGS;
4322 if (skip_past_comma (& str) == FAIL
4323 || cp_reg_required_here (& str, 0) == FAIL)
4326 inst.error = BAD_ARGS;
4330 if (skip_past_comma (& str) == SUCCESS)
4332 if (cp_opc_expr (& str, 5, 3) == FAIL)
4335 inst.error = BAD_ARGS;
4343 /* ARM v5TEJ. Jump to Jazelle code. */
4350 skip_whitespace (str);
4352 if ((reg = reg_required_here (&str, 0)) == FAIL)
4354 inst.error = BAD_ARGS;
4358 /* Note - it is not illegal to do a "bxj pc". Useless, but not illegal. */
4360 as_tsktsk (_("use of r15 in bxj is not really useful"));
4365 /* THUMB V5 breakpoint instruction (argument parse)
4373 unsigned long number;
4375 skip_whitespace (str);
4377 /* Allow optional leading '#'. */
4378 if (is_immediate_prefix (*str))
4381 memset (& expr, '\0', sizeof (expr));
4382 if (my_get_expression (& expr, & str)
4383 || (expr.X_op != O_constant
4384 /* As a convenience we allow 'bkpt' without an operand. */
4385 && expr.X_op != O_absent))
4387 inst.error = _("bad expression");
4391 number = expr.X_add_number;
4393 /* Check it fits an 8 bit unsigned. */
4394 if (number != (number & 0xff))
4396 inst.error = _("immediate value out of range");
4400 inst.instruction |= number;
4405 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
4406 Expects inst.instruction is set for BLX(1).
4407 Note: this is cloned from do_branch, and the reloc changed to be a
4408 new one that can cope with setting one extra bit (the H bit). */
4414 if (my_get_expression (& inst.reloc.exp, & str))
4421 /* ScottB: February 5, 1998 */
4422 /* Check to see of PLT32 reloc required for the instruction. */
4424 /* arm_parse_reloc() works on input_line_pointer.
4425 We actually want to parse the operands to the branch instruction
4426 passed in 'str'. Save the input pointer and restore it later. */
4427 save_in = input_line_pointer;
4428 input_line_pointer = str;
4430 if (inst.reloc.exp.X_op == O_symbol
4432 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4434 inst.reloc.type = BFD_RELOC_ARM_PLT32;
4435 inst.reloc.pc_rel = 0;
4436 /* Modify str to point to after parsed operands, otherwise
4437 end_of_line() will complain about the (PLT) left in str. */
4438 str = input_line_pointer;
4442 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
4443 inst.reloc.pc_rel = 1;
4446 input_line_pointer = save_in;
4449 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
4450 inst.reloc.pc_rel = 1;
4451 #endif /* OBJ_ELF */
4456 /* ARM V5 branch-link-exchange instruction (argument parse)
4457 BLX <target_addr> ie BLX(1)
4458 BLX{<condition>} <Rm> ie BLX(2)
4459 Unfortunately, there are two different opcodes for this mnemonic.
4460 So, the insns[].value is not used, and the code here zaps values
4461 into inst.instruction.
4462 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
4471 skip_whitespace (mystr);
4472 rm = reg_required_here (& mystr, 0);
4474 /* The above may set inst.error. Ignore his opinion. */
4479 /* Arg is a register.
4480 Use the condition code our caller put in inst.instruction.
4481 Pass ourselves off as a BX with a funny opcode. */
4482 inst.instruction |= 0x012fff30;
4487 /* This must be is BLX <target address>, no condition allowed. */
4488 if (inst.instruction != COND_ALWAYS)
4490 inst.error = BAD_COND;
4494 inst.instruction = 0xfafffffe;
4496 /* Process like a B/BL, but with a different reloc.
4497 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
4502 /* ARM V5 Thumb BLX (argument parse)
4503 BLX <target_addr> which is BLX(1)
4504 BLX <Rm> which is BLX(2)
4505 Unfortunately, there are two different opcodes for this mnemonic.
4506 So, the tinsns[].value is not used, and the code here zaps values
4507 into inst.instruction. */
4516 skip_whitespace (mystr);
4517 inst.instruction = 0x4780;
4519 /* Note that this call is to the ARM register recognizer. BLX(2)
4520 uses the ARM register space, not the Thumb one, so a call to
4521 thumb_reg() would be wrong. */
4522 rm = reg_required_here (& mystr, 3);
4527 /* It's BLX(2). The .instruction was zapped with rm & is final. */
4532 /* No ARM register. This must be BLX(1). Change the .instruction. */
4533 inst.instruction = 0xf7ffeffe;
4536 if (my_get_expression (& inst.reloc.exp, & mystr))
4539 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
4540 inst.reloc.pc_rel = 1;
4543 end_of_line (mystr);
4546 /* ARM V5 breakpoint instruction (argument parse)
4547 BKPT <16 bit unsigned immediate>
4548 Instruction is not conditional.
4549 The bit pattern given in insns[] has the COND_ALWAYS condition,
4550 and it is an error if the caller tried to override that. */
4557 unsigned long number;
4559 skip_whitespace (str);
4561 /* Allow optional leading '#'. */
4562 if (is_immediate_prefix (* str))
4565 memset (& expr, '\0', sizeof (expr));
4567 if (my_get_expression (& expr, & str)
4568 || (expr.X_op != O_constant
4569 /* As a convenience we allow 'bkpt' without an operand. */
4570 && expr.X_op != O_absent))
4572 inst.error = _("bad expression");
4576 number = expr.X_add_number;
4578 /* Check it fits a 16 bit unsigned. */
4579 if (number != (number & 0xffff))
4581 inst.error = _("immediate value out of range");
4585 /* Top 12 of 16 bits to bits 19:8. */
4586 inst.instruction |= (number & 0xfff0) << 4;
4588 /* Bottom 4 of 16 bits to bits 3:0. */
4589 inst.instruction |= number & 0xf;
4594 static unsigned long check_iwmmxt_insn PARAMS ((char *, enum iwmmxt_insn_type, int));
4596 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate. */
4598 static unsigned long
4599 check_iwmmxt_insn (str, insn_type, immediate_size)
4601 enum iwmmxt_insn_type insn_type;
4605 const char * inst_error;
4607 unsigned long number;
4609 inst_error = inst.error;
4611 inst.error = BAD_ARGS;
4612 skip_whitespace (str);
4617 if ((reg = reg_required_here (&str, 12)) == FAIL)
4622 if ((wreg_required_here (&str, 0, IWMMXT_REG_WR)) == FAIL)
4627 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4628 || skip_past_comma (&str) == FAIL
4629 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
4634 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4635 || skip_past_comma (&str) == FAIL
4636 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4637 || skip_past_comma (&str) == FAIL
4638 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
4643 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4644 || skip_past_comma (&str) == FAIL
4645 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4646 || skip_past_comma (&str) == FAIL
4647 || wreg_required_here (&str, 0, IWMMXT_REG_WCG) == FAIL))
4652 if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4653 || skip_past_comma (&str) == FAIL
4654 || reg_required_here (&str, 12) == FAIL))
4659 if ((reg_required_here (&str, 12) == FAIL
4660 || skip_past_comma (&str) == FAIL
4661 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
4666 if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
4667 || skip_past_comma (&str) == FAIL
4668 || reg_required_here (&str, 0) == FAIL
4669 || skip_past_comma (&str) == FAIL
4670 || reg_required_here (&str, 12) == FAIL))
4675 if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
4676 || skip_past_comma (&str) == FAIL
4677 || reg_required_here (&str, 12) == FAIL
4678 || skip_past_comma (&str) == FAIL
4679 || reg_required_here (&str, 16) == FAIL))
4684 if ((reg_required_here (&str, 12) == FAIL
4685 || skip_past_comma (&str) == FAIL
4686 || reg_required_here (&str, 16) == FAIL
4687 || skip_past_comma (&str) == FAIL
4688 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
4693 if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
4694 || skip_past_comma (&str) == FAIL
4695 || reg_required_here (&str, 12) == FAIL))
4700 if ((reg_required_here (&str, 12) == FAIL
4701 || skip_past_comma (&str) == FAIL
4702 || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
4707 if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4708 || skip_past_comma (&str) == FAIL
4709 || reg_required_here (&str, 12) == FAIL
4710 || skip_past_comma (&str) == FAIL))
4715 if ((reg_required_here (&str, 12) == FAIL
4716 || skip_past_comma (&str) == FAIL))
4721 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4722 || skip_past_comma (&str) == FAIL
4723 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4724 || skip_past_comma (&str) == FAIL
4725 || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
4726 || skip_past_comma (&str) == FAIL))
4731 if ((reg_required_here (&str, 12) == FAIL
4732 || skip_past_comma (&str) == FAIL
4733 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4734 || skip_past_comma (&str) == FAIL))
4739 if ((wreg_required_here (&str, 12, IWMMXT_REG_WR) == FAIL
4740 || skip_past_comma (&str) == FAIL
4741 || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
4742 || skip_past_comma (&str) == FAIL))
4747 if (immediate_size == 0)
4750 inst.error = inst_error;
4755 skip_whitespace (str);
4757 /* Allow optional leading '#'. */
4758 if (is_immediate_prefix (* str))
4761 memset (& expr, '\0', sizeof (expr));
4763 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
4765 inst.error = _("bad or missing expression");
4769 number = expr.X_add_number;
4771 if (number != (number & immediate_size))
4773 inst.error = _("immediate value out of range");
4777 inst.error = inst_error;
4783 do_iwmmxt_byte_addr (str)
4786 int op = (inst.instruction & 0x300) >> 8;
4789 inst.instruction &= ~0x300;
4790 inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
4792 skip_whitespace (str);
4794 if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
4795 || skip_past_comma (& str) == FAIL
4796 || cp_byte_address_required_here (&str) == FAIL)
4799 inst.error = BAD_ARGS;
4804 if (wc_register (reg))
4806 inst.instruction |= 0xf0000100;
4807 inst.instruction &= ~0x00400000;
4812 do_iwmmxt_tandc (str)
4817 reg = check_iwmmxt_insn (str, check_rd, 0);
4819 if (reg != REG_PC && !inst.error)
4820 inst.error = _("only r15 allowed here");
4825 do_iwmmxt_tbcst (str)
4828 check_iwmmxt_insn (str, check_tbcst, 0);
4834 do_iwmmxt_textrc (str)
4837 unsigned long number;
4839 if ((number = check_iwmmxt_insn (str, check_textrc, 7)) == (unsigned long) FAIL)
4842 inst.instruction |= number & 0x7;
4847 do_iwmmxt_textrm (str)
4850 unsigned long number;
4852 if ((number = check_iwmmxt_insn (str, check_textrm, 7)) == (unsigned long) FAIL)
4855 inst.instruction |= number & 0x7;
4859 do_iwmmxt_tinsr (str)
4862 unsigned long number;
4864 if ((number = check_iwmmxt_insn (str, check_tinsr, 7)) == (unsigned long) FAIL)
4867 inst.instruction |= number & 0x7;
4872 do_iwmmxt_tmcr (str)
4875 check_iwmmxt_insn (str, check_tmcr, 0);
4881 do_iwmmxt_tmcrr (str)
4884 check_iwmmxt_insn (str, check_tmcrr, 0);
4890 do_iwmmxt_tmia (str)
4893 check_iwmmxt_insn (str, check_tmia, 0);
4899 do_iwmmxt_tmovmsk (str)
4902 check_iwmmxt_insn (str, check_tmovmsk, 0);
4908 do_iwmmxt_tmrc (str)
4911 check_iwmmxt_insn (str, check_tmrc, 0);
4917 do_iwmmxt_tmrrc (str)
4920 check_iwmmxt_insn (str, check_tmrrc, 0);
4926 do_iwmmxt_torc (str)
4929 check_iwmmxt_insn (str, check_rd, 0);
4934 do_iwmmxt_waligni (str)
4937 unsigned long number;
4939 if ((number = check_iwmmxt_insn (str, check_waligni, 7)) == (unsigned long) FAIL)
4942 inst.instruction |= ((number & 0x7) << 20);
4947 do_iwmmxt_wmov (str)
4950 if (check_iwmmxt_insn (str, check_wrwr, 0) == (unsigned long) FAIL)
4953 inst.instruction |= ((inst.instruction >> 16) & 0xf);
4958 do_iwmmxt_word_addr (str)
4961 int op = (inst.instruction & 0x300) >> 8;
4964 inst.instruction &= ~0x300;
4965 inst.instruction |= (op & 1) << 22 | (op & 2) << 7;
4967 skip_whitespace (str);
4969 if ((reg = wreg_required_here (&str, 12, IWMMXT_REG_WR_OR_WC)) == FAIL
4970 || skip_past_comma (& str) == FAIL
4971 || cp_address_required_here (& str, CP_WB_OK) == FAIL)
4974 inst.error = BAD_ARGS;
4979 if (wc_register (reg))
4981 inst.instruction |= 0xf0000100;
4982 inst.instruction &= ~0x00400000;
4987 do_iwmmxt_wrwr (str)
4990 check_iwmmxt_insn (str, check_wrwr, 0);
4996 do_iwmmxt_wrwrwcg (str)
4999 check_iwmmxt_insn (str, check_wrwrwcg, 0);
5005 do_iwmmxt_wrwrwr (str)
5008 check_iwmmxt_insn (str, check_wrwrwr, 0);
5014 do_iwmmxt_wshufh (str)
5017 unsigned long number;
5019 if ((number = check_iwmmxt_insn (str, check_wshufh, 0xff)) == (unsigned long) FAIL)
5022 inst.instruction |= ((number & 0xf0) << 16) | (number & 0xf);
5027 do_iwmmxt_wzero (str)
5030 if (check_iwmmxt_insn (str, check_wr, 0) == (unsigned long) FAIL)
5033 inst.instruction |= ((inst.instruction & 0xf) << 12) | ((inst.instruction & 0xf) << 16);
5037 /* Xscale multiply-accumulate (argument parse)
5040 MIAxycc acc0,Rm,Rs. */
5049 if (accum0_required_here (& str) == FAIL)
5050 inst.error = ERR_NO_ACCUM;
5052 else if (skip_past_comma (& str) == FAIL
5053 || (rm = reg_required_here (& str, 0)) == FAIL)
5054 inst.error = BAD_ARGS;
5056 else if (skip_past_comma (& str) == FAIL
5057 || (rs = reg_required_here (& str, 12)) == FAIL)
5058 inst.error = BAD_ARGS;
5060 /* inst.instruction has now been zapped with both rm and rs. */
5061 else if (rm == REG_PC || rs == REG_PC)
5062 inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */
5068 /* Xscale move-accumulator-register (argument parse)
5070 MARcc acc0,RdLo,RdHi. */
5078 if (accum0_required_here (& str) == FAIL)
5079 inst.error = ERR_NO_ACCUM;
5081 else if (skip_past_comma (& str) == FAIL
5082 || (rdlo = reg_required_here (& str, 12)) == FAIL)
5083 inst.error = BAD_ARGS;
5085 else if (skip_past_comma (& str) == FAIL
5086 || (rdhi = reg_required_here (& str, 16)) == FAIL)
5087 inst.error = BAD_ARGS;
5089 /* inst.instruction has now been zapped with both rdlo and rdhi. */
5090 else if (rdlo == REG_PC || rdhi == REG_PC)
5091 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
5097 /* Xscale move-register-accumulator (argument parse)
5099 MRAcc RdLo,RdHi,acc0. */
5108 skip_whitespace (str);
5110 if ((rdlo = reg_required_here (& str, 12)) == FAIL)
5111 inst.error = BAD_ARGS;
5113 else if (skip_past_comma (& str) == FAIL
5114 || (rdhi = reg_required_here (& str, 16)) == FAIL)
5115 inst.error = BAD_ARGS;
5117 else if (skip_past_comma (& str) == FAIL
5118 || accum0_required_here (& str) == FAIL)
5119 inst.error = ERR_NO_ACCUM;
5121 /* inst.instruction has now been zapped with both rdlo and rdhi. */
5122 else if (rdlo == rdhi)
5123 inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */
5125 else if (rdlo == REG_PC || rdhi == REG_PC)
5126 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
5131 /* ARMv5TE: Preload-Cache
5135 Syntactically, like LDR with B=1, W=0, L=1. */
5143 skip_whitespace (str);
5147 inst.error = _("'[' expected after PLD mnemonic");
5152 skip_whitespace (str);
5154 if ((rd = reg_required_here (& str, 16)) == FAIL)
5157 skip_whitespace (str);
5163 skip_whitespace (str);
5165 /* Post-indexed addressing is not allowed with PLD. */
5166 if (skip_past_comma (&str) == SUCCESS)
5169 = _("post-indexed expression used in preload instruction");
5172 else if (*str == '!') /* [Rn]! */
5174 inst.error = _("writeback used in preload instruction");
5178 inst.instruction |= INDEX_UP | PRE_INDEX;
5180 else /* [Rn, ...] */
5182 if (skip_past_comma (& str) == FAIL)
5184 inst.error = _("pre-indexed expression expected");
5188 if (ldst_extend (&str) == FAIL)
5191 skip_whitespace (str);
5195 inst.error = _("missing ]");
5200 skip_whitespace (str);
5202 if (* str == '!') /* [Rn]! */
5204 inst.error = _("writeback used in preload instruction");
5208 inst.instruction |= PRE_INDEX;
5214 /* ARMv5TE load-consecutive (argument parse)
5227 skip_whitespace (str);
5229 if ((rd = reg_required_here (& str, 12)) == FAIL)
5231 inst.error = BAD_ARGS;
5235 if (skip_past_comma (& str) == FAIL
5236 || (rn = ld_mode_required_here (& str)) == FAIL)
5239 inst.error = BAD_ARGS;
5243 /* inst.instruction has now been zapped with Rd and the addressing mode. */
5244 if (rd & 1) /* Unpredictable result if Rd is odd. */
5246 inst.error = _("destination register must be even");
5252 inst.error = _("r14 not allowed here");
5256 if (((rd == rn) || (rd + 1 == rn))
5257 && ((inst.instruction & WRITE_BACK)
5258 || (!(inst.instruction & PRE_INDEX))))
5259 as_warn (_("pre/post-indexing used when modified address register is destination"));
5261 /* For an index-register load, the index register must not overlap the
5262 destination (even if not write-back). */
5263 if ((inst.instruction & V4_STR_BIT) == 0
5264 && (inst.instruction & HWOFFSET_IMM) == 0)
5266 int rm = inst.instruction & 0x0000000f;
5268 if (rm == rd || (rm == rd + 1))
5269 as_warn (_("ldrd destination registers must not overlap index register"));
5275 /* Returns the index into fp_values of a floating point number,
5276 or -1 if not in the table. */
5279 my_get_float_expression (str)
5282 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5288 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
5290 /* Look for a raw floating point number. */
5291 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5292 && is_end_of_line[(unsigned char) *save_in])
5294 for (i = 0; i < NUM_FLOAT_VALS; i++)
5296 for (j = 0; j < MAX_LITTLENUMS; j++)
5298 if (words[j] != fp_values[i][j])
5302 if (j == MAX_LITTLENUMS)
5310 /* Try and parse a more complex expression, this will probably fail
5311 unless the code uses a floating point prefix (eg "0f"). */
5312 save_in = input_line_pointer;
5313 input_line_pointer = *str;
5314 if (expression (&exp) == absolute_section
5315 && exp.X_op == O_big
5316 && exp.X_add_number < 0)
5318 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5320 if (gen_to_words (words, 5, (long) 15) == 0)
5322 for (i = 0; i < NUM_FLOAT_VALS; i++)
5324 for (j = 0; j < MAX_LITTLENUMS; j++)
5326 if (words[j] != fp_values[i][j])
5330 if (j == MAX_LITTLENUMS)
5332 *str = input_line_pointer;
5333 input_line_pointer = save_in;
5340 *str = input_line_pointer;
5341 input_line_pointer = save_in;
5345 /* Return TRUE if anything in the expression is a bignum. */
5348 walk_no_bignums (sp)
5351 if (symbol_get_value_expression (sp)->X_op == O_big)
5354 if (symbol_get_value_expression (sp)->X_add_symbol)
5356 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
5357 || (symbol_get_value_expression (sp)->X_op_symbol
5358 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
5364 static int in_my_get_expression = 0;
5367 my_get_expression (ep, str)
5374 save_in = input_line_pointer;
5375 input_line_pointer = *str;
5376 in_my_get_expression = 1;
5377 seg = expression (ep);
5378 in_my_get_expression = 0;
5380 if (ep->X_op == O_illegal)
5382 /* We found a bad expression in md_operand(). */
5383 *str = input_line_pointer;
5384 input_line_pointer = save_in;
5389 if (seg != absolute_section
5390 && seg != text_section
5391 && seg != data_section
5392 && seg != bss_section
5393 && seg != undefined_section)
5395 inst.error = _("bad_segment");
5396 *str = input_line_pointer;
5397 input_line_pointer = save_in;
5402 /* Get rid of any bignums now, so that we don't generate an error for which
5403 we can't establish a line number later on. Big numbers are never valid
5404 in instructions, which is where this routine is always called. */
5405 if (ep->X_op == O_big
5406 || (ep->X_add_symbol
5407 && (walk_no_bignums (ep->X_add_symbol)
5409 && walk_no_bignums (ep->X_op_symbol)))))
5411 inst.error = _("invalid constant");
5412 *str = input_line_pointer;
5413 input_line_pointer = save_in;
5417 *str = input_line_pointer;
5418 input_line_pointer = save_in;
5422 /* We handle all bad expressions here, so that we can report the faulty
5423 instruction in the error message. */
5428 if (in_my_get_expression)
5430 expr->X_op = O_illegal;
5431 if (inst.error == NULL)
5432 inst.error = _("bad expression");
5436 /* UNRESTRICT should be one if <shift> <register> is permitted for this
5440 decode_shift (str, unrestrict)
5444 const struct asm_shift_name * shift;
5448 skip_whitespace (* str);
5450 for (p = * str; ISALPHA (* p); p ++)
5455 inst.error = _("shift expression expected");
5461 shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
5466 inst.error = _("shift expression expected");
5470 assert (shift->properties->index == shift_properties[shift->properties->index].index);
5472 if (shift->properties->index == SHIFT_RRX)
5475 inst.instruction |= shift->properties->bit_field;
5479 skip_whitespace (p);
5481 if (unrestrict && reg_required_here (& p, 8) != FAIL)
5483 inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
5487 else if (! is_immediate_prefix (* p))
5489 inst.error = (unrestrict
5490 ? _("shift requires register or #expression")
5491 : _("shift requires #expression"));
5499 if (my_get_expression (& inst.reloc.exp, & p))
5502 /* Validate some simple #expressions. */
5503 if (inst.reloc.exp.X_op == O_constant)
5505 unsigned num = inst.reloc.exp.X_add_number;
5507 /* Reject operations greater than 32. */
5509 /* Reject a shift of 0 unless the mode allows it. */
5510 || (num == 0 && shift->properties->allows_0 == 0)
5511 /* Reject a shift of 32 unless the mode allows it. */
5512 || (num == 32 && shift->properties->allows_32 == 0)
5515 /* As a special case we allow a shift of zero for
5516 modes that do not support it to be recoded as an
5517 logical shift left of zero (ie nothing). We warn
5518 about this though. */
5521 as_warn (_("shift of 0 ignored."));
5522 shift = & shift_names[0];
5523 assert (shift->properties->index == SHIFT_LSL);
5527 inst.error = _("invalid immediate shift");
5532 /* Shifts of 32 are encoded as 0, for those shifts that
5537 inst.instruction |= (num << 7) | shift->properties->bit_field;
5541 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
5542 inst.reloc.pc_rel = 0;
5543 inst.instruction |= shift->properties->bit_field;
5550 /* Do those data_ops which can take a negative immediate constant
5551 by altering the instuction. A bit of a hack really.
5555 by inverting the second operand, and
5558 by negating the second operand. */
5561 negate_data_op (instruction, value)
5562 unsigned long * instruction;
5563 unsigned long value;
5566 unsigned long negated, inverted;
5568 negated = validate_immediate (-value);
5569 inverted = validate_immediate (~value);
5571 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
5574 /* First negates. */
5575 case OPCODE_SUB: /* ADD <-> SUB */
5576 new_inst = OPCODE_ADD;
5581 new_inst = OPCODE_SUB;
5585 case OPCODE_CMP: /* CMP <-> CMN */
5586 new_inst = OPCODE_CMN;
5591 new_inst = OPCODE_CMP;
5595 /* Now Inverted ops. */
5596 case OPCODE_MOV: /* MOV <-> MVN */
5597 new_inst = OPCODE_MVN;
5602 new_inst = OPCODE_MOV;
5606 case OPCODE_AND: /* AND <-> BIC */
5607 new_inst = OPCODE_BIC;
5612 new_inst = OPCODE_AND;
5616 case OPCODE_ADC: /* ADC <-> SBC */
5617 new_inst = OPCODE_SBC;
5622 new_inst = OPCODE_ADC;
5626 /* We cannot do anything. */
5631 if (value == (unsigned) FAIL)
5634 *instruction &= OPCODE_MASK;
5635 *instruction |= new_inst << DATA_OP_SHIFT;
5646 skip_whitespace (* str);
5648 if (reg_required_here (str, 0) != FAIL)
5650 if (skip_past_comma (str) == SUCCESS)
5651 /* Shift operation on register. */
5652 return decode_shift (str, NO_SHIFT_RESTRICT);
5658 /* Immediate expression. */
5659 if (is_immediate_prefix (**str))
5664 if (my_get_expression (&inst.reloc.exp, str))
5667 if (inst.reloc.exp.X_add_symbol)
5669 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5670 inst.reloc.pc_rel = 0;
5674 if (skip_past_comma (str) == SUCCESS)
5676 /* #x, y -- ie explicit rotation by Y. */
5677 if (my_get_expression (&expr, str))
5680 if (expr.X_op != O_constant)
5682 inst.error = _("constant expression expected");
5686 /* Rotate must be a multiple of 2. */
5687 if (((unsigned) expr.X_add_number) > 30
5688 || (expr.X_add_number & 1) != 0
5689 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
5691 inst.error = _("invalid constant");
5694 inst.instruction |= INST_IMMEDIATE;
5695 inst.instruction |= inst.reloc.exp.X_add_number;
5696 inst.instruction |= expr.X_add_number << 7;
5700 /* Implicit rotation, select a suitable one. */
5701 value = validate_immediate (inst.reloc.exp.X_add_number);
5705 /* Can't be done. Perhaps the code reads something like
5706 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
5707 if ((value = negate_data_op (&inst.instruction,
5708 inst.reloc.exp.X_add_number))
5711 inst.error = _("invalid constant");
5716 inst.instruction |= value;
5719 inst.instruction |= INST_IMMEDIATE;
5724 inst.error = _("register or shift expression expected");
5733 skip_whitespace (* str);
5735 if (fp_reg_required_here (str, 0) != FAIL)
5739 /* Immediate expression. */
5740 if (*((*str)++) == '#')
5746 skip_whitespace (* str);
5748 /* First try and match exact strings, this is to guarantee
5749 that some formats will work even for cross assembly. */
5751 for (i = 0; fp_const[i]; i++)
5753 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
5757 *str += strlen (fp_const[i]);
5758 if (is_end_of_line[(unsigned char) **str])
5760 inst.instruction |= i + 8;
5767 /* Just because we didn't get a match doesn't mean that the
5768 constant isn't valid, just that it is in a format that we
5769 don't automatically recognize. Try parsing it with
5770 the standard expression routines. */
5771 if ((i = my_get_float_expression (str)) >= 0)
5773 inst.instruction |= i + 8;
5777 inst.error = _("invalid floating point immediate expression");
5781 _("floating point register or immediate expression expected");
5790 skip_whitespace (str);
5792 if (reg_required_here (&str, 12) == FAIL
5793 || skip_past_comma (&str) == FAIL
5794 || reg_required_here (&str, 16) == FAIL
5795 || skip_past_comma (&str) == FAIL
5796 || data_op2 (&str) == FAIL)
5799 inst.error = BAD_ARGS;
5811 /* This is a pseudo-op of the form "adr rd, label" to be converted
5812 into a relative address of the form "add rd, pc, #label-.-8". */
5813 skip_whitespace (str);
5815 if (reg_required_here (&str, 12) == FAIL
5816 || skip_past_comma (&str) == FAIL
5817 || my_get_expression (&inst.reloc.exp, &str))
5820 inst.error = BAD_ARGS;
5824 /* Frag hacking will turn this into a sub instruction if the offset turns
5825 out to be negative. */
5826 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5827 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
5828 inst.reloc.pc_rel = 1;
5837 /* This is a pseudo-op of the form "adrl rd, label" to be converted
5838 into a relative address of the form:
5839 add rd, pc, #low(label-.-8)"
5840 add rd, rd, #high(label-.-8)" */
5842 skip_whitespace (str);
5844 if (reg_required_here (&str, 12) == FAIL
5845 || skip_past_comma (&str) == FAIL
5846 || my_get_expression (&inst.reloc.exp, &str))
5849 inst.error = BAD_ARGS;
5855 /* Frag hacking will turn this into a sub instruction if the offset turns
5856 out to be negative. */
5857 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
5858 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
5859 inst.reloc.pc_rel = 1;
5860 inst.size = INSN_SIZE * 2;
5869 skip_whitespace (str);
5871 if (reg_required_here (&str, 16) == FAIL)
5874 inst.error = BAD_ARGS;
5878 if (skip_past_comma (&str) == FAIL
5879 || data_op2 (&str) == FAIL)
5882 inst.error = BAD_ARGS;
5894 skip_whitespace (str);
5896 if (reg_required_here (&str, 12) == FAIL)
5899 inst.error = BAD_ARGS;
5903 if (skip_past_comma (&str) == FAIL
5904 || data_op2 (&str) == FAIL)
5907 inst.error = BAD_ARGS;
5926 if (my_get_expression (& inst.reloc.exp, str))
5929 if (inst.reloc.exp.X_op == O_constant)
5931 int value = inst.reloc.exp.X_add_number;
5933 if (value < -4095 || value > 4095)
5935 inst.error = _("address offset too large");
5945 inst.instruction |= add | value;
5949 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5950 inst.reloc.pc_rel = 0;
5963 if (reg_required_here (str, 0) == FAIL)
5966 inst.instruction |= add | OFFSET_REG;
5967 if (skip_past_comma (str) == SUCCESS)
5968 return decode_shift (str, SHIFT_RESTRICT);
5982 skip_whitespace (str);
5984 if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
5987 inst.error = BAD_ARGS;
5991 if (skip_past_comma (&str) == FAIL)
5993 inst.error = _("address expected");
6003 skip_whitespace (str);
6005 if ((reg = reg_required_here (&str, 16)) == FAIL)
6008 /* Conflicts can occur on stores as well as loads. */
6009 conflict_reg = (conflict_reg == reg);
6011 skip_whitespace (str);
6017 if (skip_past_comma (&str) == SUCCESS)
6019 /* [Rn],... (post inc) */
6020 if (ldst_extend (&str) == FAIL)
6023 as_warn (_("%s register same as write-back base"),
6024 ((inst.instruction & LOAD_BIT)
6025 ? _("destination") : _("source")));
6030 skip_whitespace (str);
6035 as_warn (_("%s register same as write-back base"),
6036 ((inst.instruction & LOAD_BIT)
6037 ? _("destination") : _("source")));
6039 inst.instruction |= WRITE_BACK;
6042 inst.instruction |= INDEX_UP;
6049 if (skip_past_comma (&str) == FAIL)
6051 inst.error = _("pre-indexed expression expected");
6056 if (ldst_extend (&str) == FAIL)
6059 skip_whitespace (str);
6063 inst.error = _("missing ]");
6067 skip_whitespace (str);
6072 as_warn (_("%s register same as write-back base"),
6073 ((inst.instruction & LOAD_BIT)
6074 ? _("destination") : _("source")));
6076 inst.instruction |= WRITE_BACK;
6080 else if (*str == '=')
6082 if ((inst.instruction & LOAD_BIT) == 0)
6084 inst.error = _("invalid pseudo operation");
6088 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6091 skip_whitespace (str);
6093 if (my_get_expression (&inst.reloc.exp, &str))
6096 if (inst.reloc.exp.X_op != O_constant
6097 && inst.reloc.exp.X_op != O_symbol)
6099 inst.error = _("constant expression expected");
6103 if (inst.reloc.exp.X_op == O_constant)
6105 value = validate_immediate (inst.reloc.exp.X_add_number);
6109 /* This can be done with a mov instruction. */
6110 inst.instruction &= LITERAL_MASK;
6111 inst.instruction |= (INST_IMMEDIATE
6112 | (OPCODE_MOV << DATA_OP_SHIFT));
6113 inst.instruction |= value & 0xfff;
6118 value = validate_immediate (~inst.reloc.exp.X_add_number);
6122 /* This can be done with a mvn instruction. */
6123 inst.instruction &= LITERAL_MASK;
6124 inst.instruction |= (INST_IMMEDIATE
6125 | (OPCODE_MVN << DATA_OP_SHIFT));
6126 inst.instruction |= value & 0xfff;
6132 /* Insert into literal pool. */
6133 if (add_to_lit_pool () == FAIL)
6136 inst.error = _("literal pool insertion failed");
6140 /* Change the instruction exp to point to the pool. */
6141 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
6142 inst.reloc.pc_rel = 1;
6143 inst.instruction |= (REG_PC << 16);
6148 if (my_get_expression (&inst.reloc.exp, &str))
6151 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
6153 /* PC rel adjust. */
6154 inst.reloc.exp.X_add_number -= 8;
6156 inst.reloc.pc_rel = 1;
6157 inst.instruction |= (REG_PC << 16);
6161 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6172 skip_whitespace (str);
6174 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6177 inst.error = BAD_ARGS;
6181 if (skip_past_comma (& str) == FAIL)
6183 inst.error = _("address expected");
6193 skip_whitespace (str);
6195 if ((reg = reg_required_here (&str, 16)) == FAIL)
6198 /* ldrt/strt always use post-indexed addressing, so if the base is
6199 the same as Rd, we warn. */
6200 if (conflict_reg == reg)
6201 as_warn (_("%s register same as write-back base"),
6202 ((inst.instruction & LOAD_BIT)
6203 ? _("destination") : _("source")));
6205 skip_whitespace (str);
6211 if (skip_past_comma (&str) == SUCCESS)
6213 /* [Rn],... (post inc) */
6214 if (ldst_extend (&str) == FAIL)
6220 skip_whitespace (str);
6222 /* Skip a write-back '!'. */
6226 inst.instruction |= INDEX_UP;
6231 inst.error = _("post-indexed expression expected");
6237 inst.error = _("post-indexed expression expected");
6246 ldst_extend_v4 (str)
6256 if (my_get_expression (& inst.reloc.exp, str))
6259 if (inst.reloc.exp.X_op == O_constant)
6261 int value = inst.reloc.exp.X_add_number;
6263 if (value < -255 || value > 255)
6265 inst.error = _("address offset too large");
6275 /* Halfword and signextension instructions have the
6276 immediate value split across bits 11..8 and bits 3..0. */
6277 inst.instruction |= (add | HWOFFSET_IMM
6278 | ((value >> 4) << 8) | (value & 0xF));
6282 inst.instruction |= HWOFFSET_IMM;
6283 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6284 inst.reloc.pc_rel = 0;
6297 if (reg_required_here (str, 0) == FAIL)
6300 inst.instruction |= add;
6305 /* Halfword and signed-byte load/store operations. */
6314 skip_whitespace (str);
6316 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
6319 inst.error = BAD_ARGS;
6323 if (skip_past_comma (& str) == FAIL)
6325 inst.error = _("address expected");
6335 skip_whitespace (str);
6337 if ((reg = reg_required_here (&str, 16)) == FAIL)
6340 /* Conflicts can occur on stores as well as loads. */
6341 conflict_reg = (conflict_reg == reg);
6343 skip_whitespace (str);
6349 if (skip_past_comma (&str) == SUCCESS)
6351 /* [Rn],... (post inc) */
6352 if (ldst_extend_v4 (&str) == FAIL)
6355 as_warn (_("%s register same as write-back base"),
6356 ((inst.instruction & LOAD_BIT)
6357 ? _("destination") : _("source")));
6362 inst.instruction |= HWOFFSET_IMM;
6364 skip_whitespace (str);
6369 as_warn (_("%s register same as write-back base"),
6370 ((inst.instruction & LOAD_BIT)
6371 ? _("destination") : _("source")));
6373 inst.instruction |= WRITE_BACK;
6376 inst.instruction |= INDEX_UP;
6383 if (skip_past_comma (&str) == FAIL)
6385 inst.error = _("pre-indexed expression expected");
6390 if (ldst_extend_v4 (&str) == FAIL)
6393 skip_whitespace (str);
6397 inst.error = _("missing ]");
6401 skip_whitespace (str);
6406 as_warn (_("%s register same as write-back base"),
6407 ((inst.instruction & LOAD_BIT)
6408 ? _("destination") : _("source")));
6410 inst.instruction |= WRITE_BACK;
6414 else if (*str == '=')
6416 if ((inst.instruction & LOAD_BIT) == 0)
6418 inst.error = _("invalid pseudo operation");
6422 /* XXX Does this work correctly for half-word/byte ops? */
6423 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6426 skip_whitespace (str);
6428 if (my_get_expression (&inst.reloc.exp, &str))
6431 if (inst.reloc.exp.X_op != O_constant
6432 && inst.reloc.exp.X_op != O_symbol)
6434 inst.error = _("constant expression expected");
6438 if (inst.reloc.exp.X_op == O_constant)
6440 value = validate_immediate (inst.reloc.exp.X_add_number);
6444 /* This can be done with a mov instruction. */
6445 inst.instruction &= LITERAL_MASK;
6446 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
6447 inst.instruction |= value & 0xfff;
6452 value = validate_immediate (~ inst.reloc.exp.X_add_number);
6456 /* This can be done with a mvn instruction. */
6457 inst.instruction &= LITERAL_MASK;
6458 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
6459 inst.instruction |= value & 0xfff;
6465 /* Insert into literal pool. */
6466 if (add_to_lit_pool () == FAIL)
6469 inst.error = _("literal pool insertion failed");
6473 /* Change the instruction exp to point to the pool. */
6474 inst.instruction |= HWOFFSET_IMM;
6475 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
6476 inst.reloc.pc_rel = 1;
6477 inst.instruction |= (REG_PC << 16);
6482 if (my_get_expression (&inst.reloc.exp, &str))
6485 inst.instruction |= HWOFFSET_IMM;
6486 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
6488 /* PC rel adjust. */
6489 inst.reloc.exp.X_add_number -= 8;
6491 inst.reloc.pc_rel = 1;
6492 inst.instruction |= (REG_PC << 16);
6496 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
6505 char * str = * strp;
6509 /* We come back here if we get ranges concatenated by '+' or '|'. */
6524 skip_whitespace (str);
6526 if ((reg = reg_required_here (& str, -1)) == FAIL)
6535 inst.error = _("bad range in register list");
6539 for (i = cur_reg + 1; i < reg; i++)
6541 if (range & (1 << i))
6543 (_("Warning: duplicated register (r%d) in register list"),
6551 if (range & (1 << reg))
6552 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
6554 else if (reg <= cur_reg)
6555 as_tsktsk (_("Warning: register range not in ascending order"));
6560 while (skip_past_comma (&str) != FAIL
6561 || (in_range = 1, *str++ == '-'));
6563 skip_whitespace (str);
6567 inst.error = _("missing `}'");
6575 if (my_get_expression (&expr, &str))
6578 if (expr.X_op == O_constant)
6580 if (expr.X_add_number
6581 != (expr.X_add_number & 0x0000ffff))
6583 inst.error = _("invalid register mask");
6587 if ((range & expr.X_add_number) != 0)
6589 int regno = range & expr.X_add_number;
6592 regno = (1 << regno) - 1;
6594 (_("Warning: duplicated register (r%d) in register list"),
6598 range |= expr.X_add_number;
6602 if (inst.reloc.type != 0)
6604 inst.error = _("expression too complex");
6608 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
6609 inst.reloc.type = BFD_RELOC_ARM_MULTI;
6610 inst.reloc.pc_rel = 0;
6614 skip_whitespace (str);
6616 if (*str == '|' || *str == '+')
6622 while (another_range);
6635 skip_whitespace (str);
6637 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
6640 if (base_reg == REG_PC)
6642 inst.error = _("r15 not allowed as base register");
6646 skip_whitespace (str);
6650 inst.instruction |= WRITE_BACK;
6654 if (skip_past_comma (&str) == FAIL
6655 || (range = reg_list (&str)) == FAIL)
6658 inst.error = BAD_ARGS;
6665 inst.instruction |= LDM_TYPE_2_OR_3;
6668 if (inst.instruction & WRITE_BACK)
6670 /* Check for unpredictable uses of writeback. */
6671 if (inst.instruction & LOAD_BIT)
6673 /* Not allowed in LDM type 2. */
6674 if ((inst.instruction & LDM_TYPE_2_OR_3)
6675 && ((range & (1 << REG_PC)) == 0))
6676 as_warn (_("writeback of base register is UNPREDICTABLE"));
6677 /* Only allowed if base reg not in list for other types. */
6678 else if (range & (1 << base_reg))
6679 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
6683 /* Not allowed for type 2. */
6684 if (inst.instruction & LDM_TYPE_2_OR_3)
6685 as_warn (_("writeback of base register is UNPREDICTABLE"));
6686 /* Only allowed if base reg not in list, or first in list. */
6687 else if ((range & (1 << base_reg))
6688 && (range & ((1 << base_reg) - 1)))
6689 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
6693 inst.instruction |= range;
6702 skip_whitespace (str);
6704 /* Allow optional leading '#'. */
6705 if (is_immediate_prefix (*str))
6708 if (my_get_expression (& inst.reloc.exp, & str))
6711 inst.reloc.type = BFD_RELOC_ARM_SWI;
6712 inst.reloc.pc_rel = 0;
6724 skip_whitespace (str);
6726 if ((reg = reg_required_here (&str, 12)) == FAIL)
6731 inst.error = _("r15 not allowed in swap");
6735 if (skip_past_comma (&str) == FAIL
6736 || (reg = reg_required_here (&str, 0)) == FAIL)
6739 inst.error = BAD_ARGS;
6745 inst.error = _("r15 not allowed in swap");
6749 if (skip_past_comma (&str) == FAIL
6752 inst.error = BAD_ARGS;
6756 skip_whitespace (str);
6758 if ((reg = reg_required_here (&str, 16)) == FAIL)
6763 inst.error = BAD_PC;
6767 skip_whitespace (str);
6771 inst.error = _("missing ]");
6783 if (my_get_expression (&inst.reloc.exp, &str))
6790 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
6791 required for the instruction. */
6793 /* arm_parse_reloc () works on input_line_pointer.
6794 We actually want to parse the operands to the branch instruction
6795 passed in 'str'. Save the input pointer and restore it later. */
6796 save_in = input_line_pointer;
6797 input_line_pointer = str;
6798 if (inst.reloc.exp.X_op == O_symbol
6800 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
6802 inst.reloc.type = BFD_RELOC_ARM_PLT32;
6803 inst.reloc.pc_rel = 0;
6804 /* Modify str to point to after parsed operands, otherwise
6805 end_of_line() will complain about the (PLT) left in str. */
6806 str = input_line_pointer;
6810 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
6811 inst.reloc.pc_rel = 1;
6813 input_line_pointer = save_in;
6816 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
6817 inst.reloc.pc_rel = 1;
6818 #endif /* OBJ_ELF */
6830 skip_whitespace (str);
6832 if ((reg = reg_required_here (&str, 0)) == FAIL)
6834 inst.error = BAD_ARGS;
6838 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
6840 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
6849 /* Co-processor data operation.
6850 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
6851 skip_whitespace (str);
6853 if (co_proc_number (&str) == FAIL)
6856 inst.error = BAD_ARGS;
6860 if (skip_past_comma (&str) == FAIL
6861 || cp_opc_expr (&str, 20,4) == FAIL)
6864 inst.error = BAD_ARGS;
6868 if (skip_past_comma (&str) == FAIL
6869 || cp_reg_required_here (&str, 12) == FAIL)
6872 inst.error = BAD_ARGS;
6876 if (skip_past_comma (&str) == FAIL
6877 || cp_reg_required_here (&str, 16) == FAIL)
6880 inst.error = BAD_ARGS;
6884 if (skip_past_comma (&str) == FAIL
6885 || cp_reg_required_here (&str, 0) == FAIL)
6888 inst.error = BAD_ARGS;
6892 if (skip_past_comma (&str) == SUCCESS)
6894 if (cp_opc_expr (&str, 5, 3) == FAIL)
6897 inst.error = BAD_ARGS;
6910 /* Co-processor register load/store.
6911 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
6913 skip_whitespace (str);
6915 if (co_proc_number (&str) == FAIL)
6918 inst.error = BAD_ARGS;
6922 if (skip_past_comma (&str) == FAIL
6923 || cp_reg_required_here (&str, 12) == FAIL)
6926 inst.error = BAD_ARGS;
6930 if (skip_past_comma (&str) == FAIL
6931 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6934 inst.error = BAD_ARGS;
6946 /* Co-processor register transfer.
6947 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
6949 skip_whitespace (str);
6951 if (co_proc_number (&str) == FAIL)
6954 inst.error = BAD_ARGS;
6958 if (skip_past_comma (&str) == FAIL
6959 || cp_opc_expr (&str, 21, 3) == FAIL)
6962 inst.error = BAD_ARGS;
6966 if (skip_past_comma (&str) == FAIL
6967 || reg_required_here (&str, 12) == FAIL)
6970 inst.error = BAD_ARGS;
6974 if (skip_past_comma (&str) == FAIL
6975 || cp_reg_required_here (&str, 16) == FAIL)
6978 inst.error = BAD_ARGS;
6982 if (skip_past_comma (&str) == FAIL
6983 || cp_reg_required_here (&str, 0) == FAIL)
6986 inst.error = BAD_ARGS;
6990 if (skip_past_comma (&str) == SUCCESS)
6992 if (cp_opc_expr (&str, 5, 3) == FAIL)
6995 inst.error = BAD_ARGS;
7008 /* FP control registers.
7009 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
7011 skip_whitespace (str);
7013 if (reg_required_here (&str, 12) == FAIL)
7016 inst.error = BAD_ARGS;
7028 skip_whitespace (str);
7030 if (fp_reg_required_here (&str, 12) == FAIL)
7033 inst.error = BAD_ARGS;
7037 if (skip_past_comma (&str) == FAIL
7038 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7041 inst.error = BAD_ARGS;
7054 skip_whitespace (str);
7056 if (fp_reg_required_here (&str, 12) == FAIL)
7059 inst.error = BAD_ARGS;
7063 /* Get Number of registers to transfer. */
7064 if (skip_past_comma (&str) == FAIL
7065 || my_get_expression (&inst.reloc.exp, &str))
7068 inst.error = _("constant expression expected");
7072 if (inst.reloc.exp.X_op != O_constant)
7074 inst.error = _("constant value required for number of registers");
7078 num_regs = inst.reloc.exp.X_add_number;
7080 if (num_regs < 1 || num_regs > 4)
7082 inst.error = _("number of registers must be in the range [1:4]");
7089 inst.instruction |= CP_T_X;
7092 inst.instruction |= CP_T_Y;
7095 inst.instruction |= CP_T_Y | CP_T_X;
7103 if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format. */
7109 /* The instruction specified "ea" or "fd", so we can only accept
7110 [Rn]{!}. The instruction does not really support stacking or
7111 unstacking, so we have to emulate these by setting appropriate
7112 bits and offsets. */
7113 if (skip_past_comma (&str) == FAIL
7117 inst.error = BAD_ARGS;
7122 skip_whitespace (str);
7124 if ((reg = reg_required_here (&str, 16)) == FAIL)
7127 skip_whitespace (str);
7131 inst.error = BAD_ARGS;
7143 _("r15 not allowed as base register with write-back");
7150 if (inst.instruction & CP_T_Pre)
7152 /* Pre-decrement. */
7153 offset = 3 * num_regs;
7155 inst.instruction |= CP_T_WB;
7159 /* Post-increment. */
7162 inst.instruction |= CP_T_WB;
7163 offset = 3 * num_regs;
7167 /* No write-back, so convert this into a standard pre-increment
7168 instruction -- aesthetically more pleasing. */
7169 inst.instruction |= CP_T_Pre | CP_T_UD;
7174 inst.instruction |= offset;
7176 else if (skip_past_comma (&str) == FAIL
7177 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
7180 inst.error = BAD_ARGS;
7191 skip_whitespace (str);
7193 if (fp_reg_required_here (&str, 12) == FAIL)
7196 inst.error = BAD_ARGS;
7200 if (skip_past_comma (&str) == FAIL
7201 || fp_reg_required_here (&str, 16) == FAIL)
7204 inst.error = BAD_ARGS;
7208 if (skip_past_comma (&str) == FAIL
7209 || fp_op2 (&str) == FAIL)
7212 inst.error = BAD_ARGS;
7221 do_fpa_monadic (str)
7224 skip_whitespace (str);
7226 if (fp_reg_required_here (&str, 12) == FAIL)
7229 inst.error = BAD_ARGS;
7233 if (skip_past_comma (&str) == FAIL
7234 || fp_op2 (&str) == FAIL)
7237 inst.error = BAD_ARGS;
7249 skip_whitespace (str);
7251 if (fp_reg_required_here (&str, 16) == FAIL)
7254 inst.error = BAD_ARGS;
7258 if (skip_past_comma (&str) == FAIL
7259 || fp_op2 (&str) == FAIL)
7262 inst.error = BAD_ARGS;
7271 do_fpa_from_reg (str)
7274 skip_whitespace (str);
7276 if (fp_reg_required_here (&str, 16) == FAIL)
7279 inst.error = BAD_ARGS;
7283 if (skip_past_comma (&str) == FAIL
7284 || reg_required_here (&str, 12) == FAIL)
7287 inst.error = BAD_ARGS;
7299 skip_whitespace (str);
7301 if (reg_required_here (&str, 12) == FAIL)
7304 if (skip_past_comma (&str) == FAIL
7305 || fp_reg_required_here (&str, 0) == FAIL)
7308 inst.error = BAD_ARGS;
7317 vfp_sp_reg_required_here (str, pos)
7319 enum vfp_sp_reg_pos pos;
7324 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
7329 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7333 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7337 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7346 /* In the few cases where we might be able to accept something else
7347 this error can be overridden. */
7348 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
7350 /* Restore the start point. */
7356 vfp_dp_reg_required_here (str, pos)
7358 enum vfp_dp_reg_pos pos;
7363 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
7368 inst.instruction |= reg << 12;
7372 inst.instruction |= reg << 16;
7376 inst.instruction |= reg << 0;
7385 /* In the few cases where we might be able to accept something else
7386 this error can be overridden. */
7387 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7389 /* Restore the start point. */
7395 do_vfp_sp_monadic (str)
7398 skip_whitespace (str);
7400 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7403 if (skip_past_comma (&str) == FAIL
7404 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7407 inst.error = BAD_ARGS;
7416 do_vfp_dp_monadic (str)
7419 skip_whitespace (str);
7421 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7424 if (skip_past_comma (&str) == FAIL
7425 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7428 inst.error = BAD_ARGS;
7437 do_vfp_sp_dyadic (str)
7440 skip_whitespace (str);
7442 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7445 if (skip_past_comma (&str) == FAIL
7446 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
7447 || skip_past_comma (&str) == FAIL
7448 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7451 inst.error = BAD_ARGS;
7460 do_vfp_dp_dyadic (str)
7463 skip_whitespace (str);
7465 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7468 if (skip_past_comma (&str) == FAIL
7469 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
7470 || skip_past_comma (&str) == FAIL
7471 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7474 inst.error = BAD_ARGS;
7483 do_vfp_reg_from_sp (str)
7486 skip_whitespace (str);
7488 if (reg_required_here (&str, 12) == FAIL)
7491 if (skip_past_comma (&str) == FAIL
7492 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7495 inst.error = BAD_ARGS;
7504 do_vfp_sp_reg2 (str)
7507 skip_whitespace (str);
7509 if (reg_required_here (&str, 12) == FAIL)
7512 if (skip_past_comma (&str) == FAIL
7513 || reg_required_here (&str, 16) == FAIL
7514 || skip_past_comma (&str) == FAIL)
7517 inst.error = BAD_ARGS;
7521 /* We require exactly two consecutive SP registers. */
7522 if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
7525 inst.error = _("only two consecutive VFP SP registers allowed here");
7533 do_vfp_sp_from_reg (str)
7536 skip_whitespace (str);
7538 if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
7541 if (skip_past_comma (&str) == FAIL
7542 || reg_required_here (&str, 12) == FAIL)
7545 inst.error = BAD_ARGS;
7554 do_vfp_reg_from_dp (str)
7557 skip_whitespace (str);
7559 if (reg_required_here (&str, 12) == FAIL)
7562 if (skip_past_comma (&str) == FAIL
7563 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7566 inst.error = BAD_ARGS;
7575 do_vfp_reg2_from_dp (str)
7578 skip_whitespace (str);
7580 if (reg_required_here (&str, 12) == FAIL)
7583 if (skip_past_comma (&str) == FAIL
7584 || reg_required_here (&str, 16) == FAIL
7585 || skip_past_comma (&str) == FAIL
7586 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7589 inst.error = BAD_ARGS;
7598 do_vfp_dp_from_reg (str)
7601 skip_whitespace (str);
7603 if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
7606 if (skip_past_comma (&str) == FAIL
7607 || reg_required_here (&str, 12) == FAIL)
7610 inst.error = BAD_ARGS;
7619 do_vfp_dp_from_reg2 (str)
7622 skip_whitespace (str);
7624 if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7627 if (skip_past_comma (&str) == FAIL
7628 || reg_required_here (&str, 12) == FAIL
7629 || skip_past_comma (&str) == FAIL
7630 || reg_required_here (&str, 16))
7633 inst.error = BAD_ARGS;
7641 static const struct vfp_reg *
7648 const struct vfp_reg *vreg;
7652 /* Find the end of the current token. */
7657 while (ISALPHA (c));
7662 for (vreg = vfp_regs + 0;
7663 vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
7666 if (strcmp (start, vreg->name) == 0)
7679 vfp_psr_required_here (str)
7683 const struct vfp_reg *vreg;
7685 vreg = vfp_psr_parse (str);
7689 inst.instruction |= vreg->regno;
7693 inst.error = _("VFP system register expected");
7700 do_vfp_reg_from_ctrl (str)
7703 skip_whitespace (str);
7705 if (reg_required_here (&str, 12) == FAIL)
7708 if (skip_past_comma (&str) == FAIL
7709 || vfp_psr_required_here (&str) == FAIL)
7712 inst.error = BAD_ARGS;
7721 do_vfp_ctrl_from_reg (str)
7724 skip_whitespace (str);
7726 if (vfp_psr_required_here (&str) == FAIL)
7729 if (skip_past_comma (&str) == FAIL
7730 || reg_required_here (&str, 12) == FAIL)
7733 inst.error = BAD_ARGS;
7742 do_vfp_sp_ldst (str)
7745 skip_whitespace (str);
7747 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7750 inst.error = BAD_ARGS;
7754 if (skip_past_comma (&str) == FAIL
7755 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
7758 inst.error = BAD_ARGS;
7767 do_vfp_dp_ldst (str)
7770 skip_whitespace (str);
7772 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7775 inst.error = BAD_ARGS;
7779 if (skip_past_comma (&str) == FAIL
7780 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
7783 inst.error = BAD_ARGS;
7791 /* Parse and encode a VFP SP register list, storing the initial
7792 register in position POS and returning the range as the result. If
7793 the string is invalid return FAIL (an invalid range). */
7795 vfp_sp_reg_list (str, pos)
7797 enum vfp_sp_reg_pos pos;
7805 unsigned long mask = 0;
7812 skip_whitespace (*str);
7814 tempinst = inst.instruction;
7818 inst.instruction = 0;
7820 if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
7823 if (count == 0 || base_reg > new_base)
7825 base_reg = new_base;
7826 base_bits = inst.instruction;
7829 if (mask & (1 << new_base))
7831 inst.error = _("invalid register list");
7835 if ((mask >> new_base) != 0 && ! warned)
7837 as_tsktsk (_("register list not in ascending order"));
7841 mask |= 1 << new_base;
7844 skip_whitespace (*str);
7846 if (**str == '-') /* We have the start of a range expression */
7853 = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
7856 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
7860 if (high_range <= new_base)
7862 inst.error = _("register range not in ascending order");
7866 for (new_base++; new_base <= high_range; new_base++)
7868 if (mask & (1 << new_base))
7870 inst.error = _("invalid register list");
7874 mask |= 1 << new_base;
7879 while (skip_past_comma (str) != FAIL);
7883 inst.error = _("invalid register list");
7891 /* Sanity check -- should have raised a parse error above. */
7892 if (count == 0 || count > 32)
7895 /* Final test -- the registers must be consecutive. */
7898 if ((mask & (1 << base_reg++)) == 0)
7900 inst.error = _("non-contiguous register range");
7905 inst.instruction = tempinst | base_bits;
7910 vfp_dp_reg_list (str)
7918 unsigned long mask = 0;
7925 skip_whitespace (*str);
7927 tempinst = inst.instruction;
7931 inst.instruction = 0;
7933 if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
7936 if (count == 0 || base_reg > new_base)
7938 base_reg = new_base;
7939 range = inst.instruction;
7942 if (mask & (1 << new_base))
7944 inst.error = _("invalid register list");
7948 if ((mask >> new_base) != 0 && ! warned)
7950 as_tsktsk (_("register list not in ascending order"));
7954 mask |= 1 << new_base;
7957 skip_whitespace (*str);
7959 if (**str == '-') /* We have the start of a range expression */
7966 = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
7969 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7973 if (high_range <= new_base)
7975 inst.error = _("register range not in ascending order");
7979 for (new_base++; new_base <= high_range; new_base++)
7981 if (mask & (1 << new_base))
7983 inst.error = _("invalid register list");
7987 mask |= 1 << new_base;
7992 while (skip_past_comma (str) != FAIL);
7996 inst.error = _("invalid register list");
8004 /* Sanity check -- should have raised a parse error above. */
8005 if (count == 0 || count > 16)
8008 /* Final test -- the registers must be consecutive. */
8011 if ((mask & (1 << base_reg++)) == 0)
8013 inst.error = _("non-contiguous register range");
8018 inst.instruction = tempinst;
8023 vfp_sp_ldstm (str, ldstm_type)
8025 enum vfp_ldstm_type ldstm_type;
8029 skip_whitespace (str);
8031 if (reg_required_here (&str, 16) == FAIL)
8034 skip_whitespace (str);
8038 inst.instruction |= WRITE_BACK;
8041 else if (ldstm_type != VFP_LDSTMIA)
8043 inst.error = _("this addressing mode requires base-register writeback");
8047 if (skip_past_comma (&str) == FAIL
8048 || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
8051 inst.error = BAD_ARGS;
8055 inst.instruction |= range;
8060 vfp_dp_ldstm (str, ldstm_type)
8062 enum vfp_ldstm_type ldstm_type;
8066 skip_whitespace (str);
8068 if (reg_required_here (&str, 16) == FAIL)
8071 skip_whitespace (str);
8075 inst.instruction |= WRITE_BACK;
8078 else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
8080 inst.error = _("this addressing mode requires base-register writeback");
8084 if (skip_past_comma (&str) == FAIL
8085 || (range = vfp_dp_reg_list (&str)) == FAIL)
8088 inst.error = BAD_ARGS;
8092 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
8095 inst.instruction |= range;
8100 do_vfp_sp_ldstmia (str)
8103 vfp_sp_ldstm (str, VFP_LDSTMIA);
8107 do_vfp_sp_ldstmdb (str)
8110 vfp_sp_ldstm (str, VFP_LDSTMDB);
8114 do_vfp_dp_ldstmia (str)
8117 vfp_dp_ldstm (str, VFP_LDSTMIA);
8121 do_vfp_dp_ldstmdb (str)
8124 vfp_dp_ldstm (str, VFP_LDSTMDB);
8128 do_vfp_xp_ldstmia (str)
8131 vfp_dp_ldstm (str, VFP_LDSTMIAX);
8135 do_vfp_xp_ldstmdb (str)
8138 vfp_dp_ldstm (str, VFP_LDSTMDBX);
8142 do_vfp_sp_compare_z (str)
8145 skip_whitespace (str);
8147 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8150 inst.error = BAD_ARGS;
8159 do_vfp_dp_compare_z (str)
8162 skip_whitespace (str);
8164 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8167 inst.error = BAD_ARGS;
8176 do_vfp_dp_sp_cvt (str)
8179 skip_whitespace (str);
8181 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
8184 if (skip_past_comma (&str) == FAIL
8185 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
8188 inst.error = BAD_ARGS;
8197 do_vfp_sp_dp_cvt (str)
8200 skip_whitespace (str);
8202 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
8205 if (skip_past_comma (&str) == FAIL
8206 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
8209 inst.error = BAD_ARGS;
8217 /* Thumb specific routines. */
8219 /* Parse and validate that a register is of the right form, this saves
8220 repeated checking of this information in many similar cases.
8221 Unlike the 32-bit case we do not insert the register into the opcode
8222 here, since the position is often unknown until the full instruction
8226 thumb_reg (strp, hi_lo)
8232 if ((reg = reg_required_here (strp, -1)) == FAIL)
8240 inst.error = _("lo register required");
8248 inst.error = _("hi register required");
8260 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
8264 thumb_add_sub (str, subtract)
8268 int Rd, Rs, Rn = FAIL;
8270 skip_whitespace (str);
8272 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8273 || skip_past_comma (&str) == FAIL)
8276 inst.error = BAD_ARGS;
8280 if (is_immediate_prefix (*str))
8284 if (my_get_expression (&inst.reloc.exp, &str))
8289 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8292 if (skip_past_comma (&str) == FAIL)
8294 /* Two operand format, shuffle the registers
8295 and pretend there are 3. */
8299 else if (is_immediate_prefix (*str))
8302 if (my_get_expression (&inst.reloc.exp, &str))
8305 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8309 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8310 for the latter case, EXPR contains the immediate that was found. */
8313 /* All register format. */
8314 if (Rd > 7 || Rs > 7 || Rn > 7)
8318 inst.error = _("dest and source1 must be the same register");
8322 /* Can't do this for SUB. */
8325 inst.error = _("subtract valid only on lo regs");
8329 inst.instruction = (T_OPCODE_ADD_HI
8330 | (Rd > 7 ? THUMB_H1 : 0)
8331 | (Rn > 7 ? THUMB_H2 : 0));
8332 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
8336 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
8337 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
8342 /* Immediate expression, now things start to get nasty. */
8344 /* First deal with HI regs, only very restricted cases allowed:
8345 Adjusting SP, and using PC or SP to get an address. */
8346 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
8347 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
8349 inst.error = _("invalid Hi register with immediate");
8353 if (inst.reloc.exp.X_op != O_constant)
8355 /* Value isn't known yet, all we can do is store all the fragments
8356 we know about in the instruction and let the reloc hacking
8358 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
8359 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8363 int offset = inst.reloc.exp.X_add_number;
8373 /* Quick check, in case offset is MIN_INT. */
8376 inst.error = _("immediate value out of range");
8380 /* Note - you cannot convert a subtract of 0 into an
8381 add of 0 because the carry flag is set differently. */
8382 else if (offset > 0)
8387 if (offset & ~0x1fc)
8389 inst.error = _("invalid immediate value for stack adjust");
8392 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
8393 inst.instruction |= offset >> 2;
8395 else if (Rs == REG_PC || Rs == REG_SP)
8398 || (offset & ~0x3fc))
8400 inst.error = _("invalid immediate for address calculation");
8403 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
8405 inst.instruction |= (Rd << 8) | (offset >> 2);
8411 inst.error = _("immediate value out of range");
8414 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
8415 inst.instruction |= (Rd << 8) | offset;
8421 inst.error = _("immediate value out of range");
8424 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
8425 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
8434 thumb_shift (str, shift)
8438 int Rd, Rs, Rn = FAIL;
8440 skip_whitespace (str);
8442 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8443 || skip_past_comma (&str) == FAIL)
8446 inst.error = BAD_ARGS;
8450 if (is_immediate_prefix (*str))
8452 /* Two operand immediate format, set Rs to Rd. */
8455 if (my_get_expression (&inst.reloc.exp, &str))
8460 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8463 if (skip_past_comma (&str) == FAIL)
8465 /* Two operand format, shuffle the registers
8466 and pretend there are 3. */
8470 else if (is_immediate_prefix (*str))
8473 if (my_get_expression (&inst.reloc.exp, &str))
8476 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8480 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
8481 for the latter case, EXPR contains the immediate that was found. */
8487 inst.error = _("source1 and dest must be same register");
8493 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
8494 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
8495 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
8498 inst.instruction |= Rd | (Rn << 3);
8504 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
8505 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
8506 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
8509 if (inst.reloc.exp.X_op != O_constant)
8511 /* Value isn't known yet, create a dummy reloc and let reloc
8512 hacking fix it up. */
8513 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
8517 unsigned shift_value = inst.reloc.exp.X_add_number;
8519 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
8521 inst.error = _("invalid immediate for shift");
8525 /* Shifts of zero are handled by converting to LSL. */
8526 if (shift_value == 0)
8527 inst.instruction = T_OPCODE_LSL_I;
8529 /* Shifts of 32 are encoded as a shift of zero. */
8530 if (shift_value == 32)
8533 inst.instruction |= shift_value << 6;
8536 inst.instruction |= Rd | (Rs << 3);
8543 thumb_mov_compare (str, move)
8549 skip_whitespace (str);
8551 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
8552 || skip_past_comma (&str) == FAIL)
8555 inst.error = BAD_ARGS;
8559 if (is_immediate_prefix (*str))
8562 if (my_get_expression (&inst.reloc.exp, &str))
8565 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8570 if (Rs < 8 && Rd < 8)
8572 if (move == THUMB_MOVE)
8573 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
8574 since a MOV instruction produces unpredictable results. */
8575 inst.instruction = T_OPCODE_ADD_I3;
8577 inst.instruction = T_OPCODE_CMP_LR;
8578 inst.instruction |= Rd | (Rs << 3);
8582 if (move == THUMB_MOVE)
8583 inst.instruction = T_OPCODE_MOV_HR;
8585 inst.instruction = T_OPCODE_CMP_HR;
8588 inst.instruction |= THUMB_H1;
8591 inst.instruction |= THUMB_H2;
8593 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
8600 inst.error = _("only lo regs allowed with immediate");
8604 if (move == THUMB_MOVE)
8605 inst.instruction = T_OPCODE_MOV_I8;
8607 inst.instruction = T_OPCODE_CMP_I8;
8609 inst.instruction |= Rd << 8;
8611 if (inst.reloc.exp.X_op != O_constant)
8612 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
8615 unsigned value = inst.reloc.exp.X_add_number;
8619 inst.error = _("invalid immediate");
8623 inst.instruction |= value;
8631 thumb_load_store (str, load_store, size)
8636 int Rd, Rb, Ro = FAIL;
8638 skip_whitespace (str);
8640 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8641 || skip_past_comma (&str) == FAIL)
8644 inst.error = BAD_ARGS;
8651 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8654 if (skip_past_comma (&str) != FAIL)
8656 if (is_immediate_prefix (*str))
8659 if (my_get_expression (&inst.reloc.exp, &str))
8662 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8667 inst.reloc.exp.X_op = O_constant;
8668 inst.reloc.exp.X_add_number = 0;
8673 inst.error = _("expected ']'");
8678 else if (*str == '=')
8680 if (load_store != THUMB_LOAD)
8682 inst.error = _("invalid pseudo operation");
8686 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
8689 skip_whitespace (str);
8691 if (my_get_expression (& inst.reloc.exp, & str))
8696 if ( inst.reloc.exp.X_op != O_constant
8697 && inst.reloc.exp.X_op != O_symbol)
8699 inst.error = "Constant expression expected";
8703 if (inst.reloc.exp.X_op == O_constant
8704 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
8706 /* This can be done with a mov instruction. */
8708 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
8709 inst.instruction |= inst.reloc.exp.X_add_number;
8713 /* Insert into literal pool. */
8714 if (add_to_lit_pool () == FAIL)
8717 inst.error = "literal pool insertion failed";
8721 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8722 inst.reloc.pc_rel = 1;
8723 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
8724 /* Adjust ARM pipeline offset to Thumb. */
8725 inst.reloc.exp.X_add_number += 4;
8731 if (my_get_expression (&inst.reloc.exp, &str))
8734 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
8735 inst.reloc.pc_rel = 1;
8736 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
8737 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8742 if (Rb == REG_PC || Rb == REG_SP)
8744 if (size != THUMB_WORD)
8746 inst.error = _("byte or halfword not valid for base register");
8749 else if (Rb == REG_PC && load_store != THUMB_LOAD)
8751 inst.error = _("r15 based store not allowed");
8754 else if (Ro != FAIL)
8756 inst.error = _("invalid base register for register offset");
8761 inst.instruction = T_OPCODE_LDR_PC;
8762 else if (load_store == THUMB_LOAD)
8763 inst.instruction = T_OPCODE_LDR_SP;
8765 inst.instruction = T_OPCODE_STR_SP;
8767 inst.instruction |= Rd << 8;
8768 if (inst.reloc.exp.X_op == O_constant)
8770 unsigned offset = inst.reloc.exp.X_add_number;
8772 if (offset & ~0x3fc)
8774 inst.error = _("invalid offset");
8778 inst.instruction |= offset >> 2;
8781 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8785 inst.error = _("invalid base register in load/store");
8788 else if (Ro == FAIL)
8790 /* Immediate offset. */
8791 if (size == THUMB_WORD)
8792 inst.instruction = (load_store == THUMB_LOAD
8793 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
8794 else if (size == THUMB_HALFWORD)
8795 inst.instruction = (load_store == THUMB_LOAD
8796 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
8798 inst.instruction = (load_store == THUMB_LOAD
8799 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
8801 inst.instruction |= Rd | (Rb << 3);
8803 if (inst.reloc.exp.X_op == O_constant)
8805 unsigned offset = inst.reloc.exp.X_add_number;
8807 if (offset & ~(0x1f << size))
8809 inst.error = _("invalid offset");
8812 inst.instruction |= (offset >> size) << 6;
8815 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
8819 /* Register offset. */
8820 if (size == THUMB_WORD)
8821 inst.instruction = (load_store == THUMB_LOAD
8822 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
8823 else if (size == THUMB_HALFWORD)
8824 inst.instruction = (load_store == THUMB_LOAD
8825 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
8827 inst.instruction = (load_store == THUMB_LOAD
8828 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
8830 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
8836 /* A register must be given at this point.
8838 Shift is the place to put it in inst.instruction.
8840 Restores input start point on err.
8841 Returns the reg#, or FAIL. */
8844 mav_reg_required_here (str, shift, regtype)
8847 enum arm_reg_type regtype;
8852 if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
8855 inst.instruction |= reg << shift;
8860 /* Restore the start point. */
8863 /* In the few cases where we might be able to accept something else
8864 this error can be overridden. */
8865 inst.error = _(all_reg_maps[regtype].expected);
8870 /* Cirrus Maverick Instructions. */
8872 /* Wrapper functions. */
8875 do_mav_binops_1a (str)
8878 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
8882 do_mav_binops_1b (str)
8885 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
8889 do_mav_binops_1c (str)
8892 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
8896 do_mav_binops_1d (str)
8899 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
8903 do_mav_binops_1e (str)
8906 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
8910 do_mav_binops_1f (str)
8913 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
8917 do_mav_binops_1g (str)
8920 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
8924 do_mav_binops_1h (str)
8927 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
8931 do_mav_binops_1i (str)
8934 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
8938 do_mav_binops_1j (str)
8941 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
8945 do_mav_binops_1k (str)
8948 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
8952 do_mav_binops_1l (str)
8955 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
8959 do_mav_binops_1m (str)
8962 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
8966 do_mav_binops_1n (str)
8969 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
8973 do_mav_binops_1o (str)
8976 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
8980 do_mav_binops_2a (str)
8983 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
8987 do_mav_binops_2b (str)
8990 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
8994 do_mav_binops_2c (str)
8997 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
9001 do_mav_binops_3a (str)
9004 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
9008 do_mav_binops_3b (str)
9011 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
9015 do_mav_binops_3c (str)
9018 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
9022 do_mav_binops_3d (str)
9025 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
9029 do_mav_triple_4a (str)
9032 do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
9036 do_mav_triple_4b (str)
9039 do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
9043 do_mav_triple_5a (str)
9046 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
9050 do_mav_triple_5b (str)
9053 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
9057 do_mav_triple_5c (str)
9060 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
9064 do_mav_triple_5d (str)
9067 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
9071 do_mav_triple_5e (str)
9074 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
9078 do_mav_triple_5f (str)
9081 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
9085 do_mav_triple_5g (str)
9088 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
9092 do_mav_triple_5h (str)
9095 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
9099 do_mav_quad_6a (str)
9102 do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
9107 do_mav_quad_6b (str)
9110 do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
9114 /* cfmvsc32<cond> DSPSC,MVFX[15:0]. */
9116 do_mav_dspsc_1 (str)
9119 skip_whitespace (str);
9122 if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
9123 || skip_past_comma (&str) == FAIL
9124 || mav_reg_required_here (&str, 16, REG_TYPE_MVFX) == FAIL)
9127 inst.error = BAD_ARGS;
9135 /* cfmv32sc<cond> MVFX[15:0],DSPSC. */
9137 do_mav_dspsc_2 (str)
9140 skip_whitespace (str);
9143 if (mav_reg_required_here (&str, 0, REG_TYPE_MVFX) == FAIL
9144 || skip_past_comma (&str) == FAIL
9145 || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
9148 inst.error = BAD_ARGS;
9157 do_mav_shift_1 (str)
9160 do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
9164 do_mav_shift_2 (str)
9167 do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
9174 do_mav_ldst (str, REG_TYPE_MVF);
9181 do_mav_ldst (str, REG_TYPE_MVD);
9188 do_mav_ldst (str, REG_TYPE_MVFX);
9195 do_mav_ldst (str, REG_TYPE_MVDX);
9198 /* Isnsn like "foo X,Y". */
9201 do_mav_binops (str, mode, reg0, reg1)
9204 enum arm_reg_type reg0;
9205 enum arm_reg_type reg1;
9209 shift0 = mode & 0xff;
9210 shift1 = (mode >> 8) & 0xff;
9212 skip_whitespace (str);
9214 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9215 || skip_past_comma (&str) == FAIL
9216 || mav_reg_required_here (&str, shift1, reg1) == FAIL)
9219 inst.error = BAD_ARGS;
9225 /* Isnsn like "foo X,Y,Z". */
9228 do_mav_triple (str, mode, reg0, reg1, reg2)
9231 enum arm_reg_type reg0;
9232 enum arm_reg_type reg1;
9233 enum arm_reg_type reg2;
9235 int shift0, shift1, shift2;
9237 shift0 = mode & 0xff;
9238 shift1 = (mode >> 8) & 0xff;
9239 shift2 = (mode >> 16) & 0xff;
9241 skip_whitespace (str);
9243 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9244 || skip_past_comma (&str) == FAIL
9245 || mav_reg_required_here (&str, shift1, reg1) == FAIL
9246 || skip_past_comma (&str) == FAIL
9247 || mav_reg_required_here (&str, shift2, reg2) == FAIL)
9250 inst.error = BAD_ARGS;
9256 /* Isnsn like "foo W,X,Y,Z".
9257 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
9260 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
9263 enum arm_reg_type reg0;
9264 enum arm_reg_type reg1;
9265 enum arm_reg_type reg2;
9266 enum arm_reg_type reg3;
9268 int shift0, shift1, shift2, shift3;
9270 shift0= mode & 0xff;
9271 shift1 = (mode >> 8) & 0xff;
9272 shift2 = (mode >> 16) & 0xff;
9273 shift3 = (mode >> 24) & 0xff;
9275 skip_whitespace (str);
9277 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
9278 || skip_past_comma (&str) == FAIL
9279 || mav_reg_required_here (&str, shift1, reg1) == FAIL
9280 || skip_past_comma (&str) == FAIL
9281 || mav_reg_required_here (&str, shift2, reg2) == FAIL
9282 || skip_past_comma (&str) == FAIL
9283 || mav_reg_required_here (&str, shift3, reg3) == FAIL)
9286 inst.error = BAD_ARGS;
9292 /* Maverick shift immediate instructions.
9293 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
9294 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
9297 do_mav_shift (str, reg0, reg1)
9299 enum arm_reg_type reg0;
9300 enum arm_reg_type reg1;
9305 skip_whitespace (str);
9309 if (mav_reg_required_here (&str, 12, reg0) == FAIL
9310 || skip_past_comma (&str) == FAIL
9311 || mav_reg_required_here (&str, 16, reg1) == FAIL
9312 || skip_past_comma (&str) == FAIL)
9315 inst.error = BAD_ARGS;
9319 /* Calculate the immediate operand.
9320 The operand is a 7bit signed number. */
9321 skip_whitespace (str);
9326 if (!ISDIGIT (*str) && *str != '-')
9328 inst.error = _("expecting immediate, 7bit operand");
9338 for (imm = 0; *str && ISDIGIT (*str); ++str)
9339 imm = imm * 10 + *str - '0';
9343 inst.error = _("immediate out of range");
9347 /* Make negative imm's into 7bit signed numbers. */
9354 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
9355 Bits 5-7 of the insn should have bits 4-6 of the immediate.
9356 Bit 4 should be 0. */
9357 imm = (imm & 0xf) | ((imm & 0x70) << 1);
9359 inst.instruction |= imm;
9364 mav_parse_offset (str, negative)
9373 skip_whitespace (p);
9386 inst.error = _("offset expected");
9390 for (offset = 0; *p && ISDIGIT (*p); ++p)
9391 offset = offset * 10 + *p - '0';
9395 inst.error = _("offset out of range");
9401 return *negative ? -offset : offset;
9404 /* Maverick load/store instructions.
9405 <insn><cond> CRd,[Rn,<offset>]{!}.
9406 <insn><cond> CRd,[Rn],<offset>. */
9409 do_mav_ldst (str, reg0)
9411 enum arm_reg_type reg0;
9413 int offset, negative;
9415 skip_whitespace (str);
9417 if (mav_reg_required_here (&str, 12, reg0) == FAIL
9418 || skip_past_comma (&str) == FAIL
9420 || reg_required_here (&str, 16) == FAIL)
9423 if (skip_past_comma (&str) == SUCCESS)
9425 /* You are here: "<offset>]{!}". */
9426 inst.instruction |= PRE_INDEX;
9428 offset = mav_parse_offset (&str, &negative);
9435 inst.error = _("missing ]");
9441 inst.instruction |= WRITE_BACK;
9447 /* You are here: "], <offset>". */
9450 inst.error = _("missing ]");
9454 if (skip_past_comma (&str) == FAIL
9455 || (offset = mav_parse_offset (&str, &negative), inst.error))
9458 inst.instruction |= CP_T_WB; /* Post indexed, set bit W. */
9464 inst.instruction |= CP_T_UD; /* Postive, so set bit U. */
9466 inst.instruction |= offset >> 2;
9472 inst.error = BAD_ARGS;
9485 /* Handle the Format 4 instructions that do not have equivalents in other
9486 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
9495 skip_whitespace (str);
9497 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9498 || skip_past_comma (&str) == FAIL
9499 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9501 inst.error = BAD_ARGS;
9505 if (skip_past_comma (&str) != FAIL)
9507 /* Three operand format not allowed for TST, CMN, NEG and MVN.
9508 (It isn't allowed for CMP either, but that isn't handled by this
9510 if (inst.instruction == T_OPCODE_TST
9511 || inst.instruction == T_OPCODE_CMN
9512 || inst.instruction == T_OPCODE_NEG
9513 || inst.instruction == T_OPCODE_MVN)
9515 inst.error = BAD_ARGS;
9519 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9524 inst.error = _("dest and source1 must be the same register");
9530 if (inst.instruction == T_OPCODE_MUL
9532 as_tsktsk (_("Rs and Rd must be different in MUL"));
9534 inst.instruction |= Rd | (Rs << 3);
9542 thumb_add_sub (str, 0);
9549 thumb_shift (str, THUMB_ASR);
9556 if (my_get_expression (&inst.reloc.exp, &str))
9558 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
9559 inst.reloc.pc_rel = 1;
9567 if (my_get_expression (&inst.reloc.exp, &str))
9569 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
9570 inst.reloc.pc_rel = 1;
9574 /* Find the real, Thumb encoded start of a Thumb function. */
9577 find_real_start (symbolP)
9581 const char * name = S_GET_NAME (symbolP);
9582 symbolS * new_target;
9584 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
9585 #define STUB_NAME ".real_start_of"
9590 /* Names that start with '.' are local labels, not function entry points.
9591 The compiler may generate BL instructions to these labels because it
9592 needs to perform a branch to a far away location. */
9596 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
9597 sprintf (real_start, "%s%s", STUB_NAME, name);
9599 new_target = symbol_find (real_start);
9601 if (new_target == NULL)
9603 as_warn ("Failed to find real start of function: %s\n", name);
9604 new_target = symbolP;
9616 if (my_get_expression (& inst.reloc.exp, & str))
9619 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
9620 inst.reloc.pc_rel = 1;
9623 /* If the destination of the branch is a defined symbol which does not have
9624 the THUMB_FUNC attribute, then we must be calling a function which has
9625 the (interfacearm) attribute. We look for the Thumb entry point to that
9626 function and change the branch to refer to that function instead. */
9627 if ( inst.reloc.exp.X_op == O_symbol
9628 && inst.reloc.exp.X_add_symbol != NULL
9629 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
9630 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
9631 inst.reloc.exp.X_add_symbol =
9632 find_real_start (inst.reloc.exp.X_add_symbol);
9641 skip_whitespace (str);
9643 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
9646 /* This sets THUMB_H2 from the top bit of reg. */
9647 inst.instruction |= reg << 3;
9649 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
9650 should cause the alignment to be checked once it is known. This is
9651 because BX PC only works if the instruction is word aligned. */
9660 thumb_mov_compare (str, THUMB_COMPARE);
9670 skip_whitespace (str);
9672 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
9676 as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
9680 if (skip_past_comma (&str) == FAIL
9681 || (range = reg_list (&str)) == FAIL)
9684 inst.error = BAD_ARGS;
9688 if (inst.reloc.type != BFD_RELOC_NONE)
9690 /* This really doesn't seem worth it. */
9691 inst.reloc.type = BFD_RELOC_NONE;
9692 inst.error = _("expression too complex");
9698 inst.error = _("only lo-regs valid in load/store multiple");
9702 inst.instruction |= (Rb << 8) | range;
9710 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
9717 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
9724 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
9733 skip_whitespace (str);
9735 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9736 || skip_past_comma (&str) == FAIL
9738 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9739 || skip_past_comma (&str) == FAIL
9740 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
9744 inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
9748 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
9756 thumb_shift (str, THUMB_LSL);
9763 thumb_shift (str, THUMB_LSR);
9770 thumb_mov_compare (str, THUMB_MOVE);
9779 skip_whitespace (str);
9781 if ((range = reg_list (&str)) == FAIL)
9784 inst.error = BAD_ARGS;
9788 if (inst.reloc.type != BFD_RELOC_NONE)
9790 /* This really doesn't seem worth it. */
9791 inst.reloc.type = BFD_RELOC_NONE;
9792 inst.error = _("expression too complex");
9798 if ((inst.instruction == T_OPCODE_PUSH
9799 && (range & ~0xff) == 1 << REG_LR)
9800 || (inst.instruction == T_OPCODE_POP
9801 && (range & ~0xff) == 1 << REG_PC))
9803 inst.instruction |= THUMB_PP_PC_LR;
9808 inst.error = _("invalid register list to push/pop instruction");
9813 inst.instruction |= range;
9821 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
9828 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
9835 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
9842 thumb_add_sub (str, 1);
9849 skip_whitespace (str);
9851 if (my_get_expression (&inst.reloc.exp, &str))
9854 inst.reloc.type = BFD_RELOC_ARM_SWI;
9865 /* This is a pseudo-op of the form "adr rd, label" to be converted
9866 into a relative address of the form "add rd, pc, #label-.-4". */
9867 skip_whitespace (str);
9869 /* Store Rd in temporary location inside instruction. */
9870 if ((reg = reg_required_here (&str, 4)) == FAIL
9871 || (reg > 7) /* For Thumb reg must be r0..r7. */
9872 || skip_past_comma (&str) == FAIL
9873 || my_get_expression (&inst.reloc.exp, &str))
9876 inst.error = BAD_ARGS;
9880 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
9881 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
9882 inst.reloc.pc_rel = 1;
9883 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
9889 insert_reg (r, htab)
9890 const struct reg_entry *r;
9891 struct hash_control *htab;
9893 int len = strlen (r->name) + 2;
9894 char * buf = (char *) xmalloc (len);
9895 char * buf2 = (char *) xmalloc (len);
9898 #ifdef REGISTER_PREFIX
9899 buf[i++] = REGISTER_PREFIX;
9902 strcpy (buf + i, r->name);
9904 for (i = 0; buf[i]; i++)
9905 buf2[i] = TOUPPER (buf[i]);
9909 hash_insert (htab, buf, (PTR) r);
9910 hash_insert (htab, buf2, (PTR) r);
9915 struct reg_map *map;
9917 const struct reg_entry *r;
9919 if ((map->htab = hash_new ()) == NULL)
9920 as_fatal (_("virtual memory exhausted"));
9922 for (r = map->names; r->name != NULL; r++)
9923 insert_reg (r, map->htab);
9927 insert_reg_alias (str, regnum, htab)
9930 struct hash_control *htab;
9932 struct reg_entry *new =
9933 (struct reg_entry *) xmalloc (sizeof (struct reg_entry));
9934 char *name = xmalloc (strlen (str) + 1);
9938 new->number = regnum;
9940 hash_insert (htab, name, (PTR) new);
9943 /* Look for the .req directive. This is of the form:
9945 newname .req existing_name
9947 If we find one, or if it looks sufficiently like one that we want to
9948 handle any error here, return non-zero. Otherwise return zero. */
9950 create_register_alias (newname, p)
9958 skip_whitespace (q);
9963 if (*q && !strncmp (q, ".req ", 5))
9968 #ifdef IGNORE_OPCODE_CASE
9969 newname = original_case_string;
9971 copy_of_str = newname;
9974 skip_whitespace (q);
9976 for (r = q; *r != '\0'; r++)
9982 enum arm_reg_type new_type, old_type;
9987 old_type = arm_reg_parse_any (q);
9990 new_type = arm_reg_parse_any (newname);
9992 if (new_type == REG_TYPE_MAX)
9994 if (old_type != REG_TYPE_MAX)
9996 old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
9997 insert_reg_alias (newname, old_regno,
9998 all_reg_maps[old_type].htab);
10001 as_warn (_("register '%s' does not exist\n"), q);
10003 else if (old_type == REG_TYPE_MAX)
10005 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
10010 /* Do not warn about redefinitions to the same alias. */
10011 if (new_type != old_type
10012 || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
10013 != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
10014 as_warn (_("ignoring redefinition of register alias '%s'"),
10020 as_warn (_("ignoring incomplete .req pseuso op"));
10030 set_constant_flonums ()
10034 for (i = 0; i < NUM_FLOAT_VALS; i++)
10035 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
10039 /* Iterate over the base tables to create the instruction patterns. */
10041 build_arm_ops_hsh ()
10045 static struct obstack insn_obstack;
10047 obstack_begin (&insn_obstack, 4000);
10049 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
10051 const struct asm_opcode *insn = insns + i;
10053 if (insn->cond_offset != 0)
10055 /* Insn supports conditional execution. Build the varaints
10056 and insert them in the hash table. */
10057 for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
10059 unsigned len = strlen (insn->template);
10060 struct asm_opcode *new;
10063 new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
10064 /* All condition codes are two characters. */
10065 template = obstack_alloc (&insn_obstack, len + 3);
10067 strncpy (template, insn->template, insn->cond_offset);
10068 strcpy (template + insn->cond_offset, conds[j].template);
10069 if (len > insn->cond_offset)
10070 strcpy (template + insn->cond_offset + 2,
10071 insn->template + insn->cond_offset);
10072 new->template = template;
10073 new->cond_offset = 0;
10074 new->variant = insn->variant;
10075 new->parms = insn->parms;
10076 new->value = (insn->value & ~COND_MASK) | conds[j].value;
10078 hash_insert (arm_ops_hsh, new->template, (PTR) new);
10081 /* Finally, insert the unconditional insn in the table directly;
10082 no need to build a copy. */
10083 hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
10087 #if defined OBJ_ELF || defined OBJ_COFF
10090 #define arm_Note Elf_External_Note
10094 unsigned char namesz[4]; /* Size of entry's owner string. */
10095 unsigned char descsz[4]; /* Size of the note descriptor. */
10096 unsigned char type[4]; /* Interpretation of the descriptor. */
10097 char name[1]; /* Start of the name+desc data. */
10101 /* The description is kept to a fix sized in order to make updating
10102 it and merging it easier. */
10103 #define ARM_NOTE_DESCRIPTION_LENGTH 8
10106 arm_add_note (name, description, type)
10108 const char * description;
10111 arm_Note note ATTRIBUTE_UNUSED;
10113 unsigned int name_len;
10115 name_len = (strlen (name) + 1 + 3) & ~3;
10117 p = frag_more (sizeof (note.namesz));
10118 md_number_to_chars (p, (valueT) name_len, sizeof (note.namesz));
10120 p = frag_more (sizeof (note.descsz));
10121 md_number_to_chars (p, (valueT) ARM_NOTE_DESCRIPTION_LENGTH, sizeof (note.descsz));
10123 p = frag_more (sizeof (note.type));
10124 md_number_to_chars (p, (valueT) type, sizeof (note.type));
10126 p = frag_more (name_len);
10129 p = frag_more (ARM_NOTE_DESCRIPTION_LENGTH);
10130 strncpy (p, description, ARM_NOTE_DESCRIPTION_LENGTH);
10131 frag_align (2, 0, 0);
10141 if ( (arm_ops_hsh = hash_new ()) == NULL
10142 || (arm_tops_hsh = hash_new ()) == NULL
10143 || (arm_cond_hsh = hash_new ()) == NULL
10144 || (arm_shift_hsh = hash_new ()) == NULL
10145 || (arm_psr_hsh = hash_new ()) == NULL)
10146 as_fatal (_("virtual memory exhausted"));
10148 build_arm_ops_hsh ();
10149 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
10150 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
10151 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
10152 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
10153 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
10154 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
10155 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
10156 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
10158 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
10159 build_reg_hsh (all_reg_maps + i);
10161 set_constant_flonums ();
10163 /* Set the cpu variant based on the command-line options. We prefer
10164 -mcpu= over -march= if both are set (as for GCC); and we prefer
10165 -mfpu= over any other way of setting the floating point unit.
10166 Use of legacy options with new options are faulted. */
10167 if (legacy_cpu != -1)
10169 if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
10170 as_bad (_("use of old and new-style options to set CPU type"));
10172 mcpu_cpu_opt = legacy_cpu;
10174 else if (mcpu_cpu_opt == -1)
10175 mcpu_cpu_opt = march_cpu_opt;
10177 if (legacy_fpu != -1)
10179 if (mfpu_opt != -1)
10180 as_bad (_("use of old and new-style options to set FPU type"));
10182 mfpu_opt = legacy_fpu;
10184 else if (mfpu_opt == -1)
10186 if (mcpu_fpu_opt != -1)
10187 mfpu_opt = mcpu_fpu_opt;
10189 mfpu_opt = march_fpu_opt;
10192 if (mfpu_opt == -1)
10194 if (mcpu_cpu_opt == -1)
10195 mfpu_opt = FPU_DEFAULT;
10196 else if (mcpu_cpu_opt & ARM_EXT_V5)
10197 mfpu_opt = FPU_ARCH_VFP_V2;
10199 mfpu_opt = FPU_ARCH_FPA;
10202 if (mcpu_cpu_opt == -1)
10203 mcpu_cpu_opt = CPU_DEFAULT;
10205 cpu_variant = mcpu_cpu_opt | mfpu_opt;
10207 #if defined OBJ_COFF || defined OBJ_ELF
10209 unsigned int flags = 0;
10211 /* Set the flags in the private structure. */
10212 if (uses_apcs_26) flags |= F_APCS26;
10213 if (support_interwork) flags |= F_INTERWORK;
10214 if (uses_apcs_float) flags |= F_APCS_FLOAT;
10215 if (pic_code) flags |= F_PIC;
10216 if ((cpu_variant & FPU_ANY) == FPU_NONE
10217 || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only. */
10218 flags |= F_SOFT_FLOAT;
10219 /* Using VFP conventions (even if soft-float). */
10220 if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
10222 #if defined OBJ_ELF
10223 if (cpu_variant & ARM_CEXT_MAVERICK)
10225 flags ^= F_SOFT_FLOAT;
10226 flags |= EF_ARM_MAVERICK_FLOAT;
10230 bfd_set_private_flags (stdoutput, flags);
10232 /* We have run out flags in the COFF header to encode the
10233 status of ATPCS support, so instead we create a dummy,
10234 empty, debug section called .arm.atpcs. */
10239 sec = bfd_make_section (stdoutput, ".arm.atpcs");
10243 bfd_set_section_flags
10244 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
10245 bfd_set_section_size (stdoutput, sec, 0);
10246 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
10252 /* Record the CPU type as well. */
10253 switch (cpu_variant & ARM_CPU_MASK)
10256 mach = bfd_mach_arm_2;
10259 case ARM_3: /* Also ARM_250. */
10260 mach = bfd_mach_arm_2a;
10263 case ARM_6: /* Also ARM_7. */
10264 mach = bfd_mach_arm_3;
10268 mach = bfd_mach_arm_unknown;
10272 /* Catch special cases. */
10273 if (cpu_variant & ARM_CEXT_IWMMXT)
10274 mach = bfd_mach_arm_iWMMXt;
10275 else if (cpu_variant & ARM_CEXT_XSCALE)
10276 mach = bfd_mach_arm_XScale;
10277 else if (cpu_variant & ARM_CEXT_MAVERICK)
10278 mach = bfd_mach_arm_ep9312;
10279 else if (cpu_variant & ARM_EXT_V5E)
10280 mach = bfd_mach_arm_5TE;
10281 else if (cpu_variant & ARM_EXT_V5)
10283 if (cpu_variant & ARM_EXT_V4T)
10284 mach = bfd_mach_arm_5T;
10286 mach = bfd_mach_arm_5;
10288 else if (cpu_variant & ARM_EXT_V4)
10290 if (cpu_variant & ARM_EXT_V4T)
10291 mach = bfd_mach_arm_4T;
10293 mach = bfd_mach_arm_4;
10295 else if (cpu_variant & ARM_EXT_V3M)
10296 mach = bfd_mach_arm_3M;
10298 #if 0 /* Suppressed - for now. */
10299 #if defined (OBJ_ELF) || defined (OBJ_COFF)
10301 /* Create a .note section to fully identify this arm binary. */
10303 #define NOTE_ARCH_STRING "arch: "
10305 #if defined OBJ_COFF && ! defined NT_VERSION
10306 #define NT_VERSION 1
10311 segT current_seg = now_seg;
10312 subsegT current_subseg = now_subseg;
10313 asection * arm_arch;
10314 const char * arch_string;
10316 arm_arch = bfd_make_section_old_way (stdoutput, ARM_NOTE_SECTION);
10319 bfd_set_section_flags (stdoutput, arm_arch,
10320 SEC_DATA | SEC_ALLOC | SEC_LOAD | SEC_LINK_ONCE \
10321 | SEC_HAS_CONTENTS);
10323 arm_arch->output_section = arm_arch;
10324 subseg_set (arm_arch, 0);
10329 case bfd_mach_arm_unknown: arch_string = "unknown"; break;
10330 case bfd_mach_arm_2: arch_string = "armv2"; break;
10331 case bfd_mach_arm_2a: arch_string = "armv2a"; break;
10332 case bfd_mach_arm_3: arch_string = "armv3"; break;
10333 case bfd_mach_arm_3M: arch_string = "armv3M"; break;
10334 case bfd_mach_arm_4: arch_string = "armv4"; break;
10335 case bfd_mach_arm_4T: arch_string = "armv4t"; break;
10336 case bfd_mach_arm_5: arch_string = "armv5"; break;
10337 case bfd_mach_arm_5T: arch_string = "armv5t"; break;
10338 case bfd_mach_arm_5TE: arch_string = "armv5te"; break;
10339 case bfd_mach_arm_XScale: arch_string = "XScale"; break;
10340 case bfd_mach_arm_ep9312: arch_string = "ep9312"; break;
10341 case bfd_mach_arm_iWMMXt: arch_string = "iWMMXt"; break;
10344 arm_add_note (NOTE_ARCH_STRING, arch_string, NT_ARCH);
10346 subseg_set (current_seg, current_subseg);
10349 #endif /* Suppressed code. */
10351 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
10354 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
10355 for use in the a.out file, and stores them in the array pointed to by buf.
10356 This knows about the endian-ness of the target machine and does
10357 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
10358 2 (short) and 4 (long) Floating numbers are put out as a series of
10359 LITTLENUMS (shorts, here at least). */
10362 md_number_to_chars (buf, val, n)
10367 if (target_big_endian)
10368 number_to_chars_bigendian (buf, val, n);
10370 number_to_chars_littleendian (buf, val, n);
10374 md_chars_to_number (buf, n)
10379 unsigned char * where = (unsigned char *) buf;
10381 if (target_big_endian)
10386 result |= (*where++ & 255);
10394 result |= (where[n] & 255);
10401 /* Turn a string in input_line_pointer into a floating point constant
10402 of type TYPE, and store the appropriate bytes in *LITP. The number
10403 of LITTLENUMS emitted is stored in *SIZEP. An error message is
10404 returned, or NULL on OK.
10406 Note that fp constants aren't represent in the normal way on the ARM.
10407 In big endian mode, things are as expected. However, in little endian
10408 mode fp constants are big-endian word-wise, and little-endian byte-wise
10409 within the words. For example, (double) 1.1 in big endian mode is
10410 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
10411 the byte sequence 99 99 f1 3f 9a 99 99 99.
10413 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
10416 md_atof (type, litP, sizeP)
10422 LITTLENUM_TYPE words[MAX_LITTLENUMS];
10454 return _("bad call to MD_ATOF()");
10457 t = atof_ieee (input_line_pointer, type, words);
10459 input_line_pointer = t;
10462 if (target_big_endian)
10464 for (i = 0; i < prec; i++)
10466 md_number_to_chars (litP, (valueT) words[i], 2);
10472 if (cpu_variant & FPU_ARCH_VFP)
10473 for (i = prec - 1; i >= 0; i--)
10475 md_number_to_chars (litP, (valueT) words[i], 2);
10479 /* For a 4 byte float the order of elements in `words' is 1 0.
10480 For an 8 byte float the order is 1 0 3 2. */
10481 for (i = 0; i < prec; i += 2)
10483 md_number_to_chars (litP, (valueT) words[i + 1], 2);
10484 md_number_to_chars (litP + 2, (valueT) words[i], 2);
10492 /* The knowledge of the PC's pipeline offset is built into the insns
10496 md_pcrel_from (fixP)
10500 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
10501 && fixP->fx_subsy == NULL)
10504 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
10506 /* PC relative addressing on the Thumb is slightly odd
10507 as the bottom two bits of the PC are forced to zero
10508 for the calculation. */
10509 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
10513 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
10514 so we un-adjust here to compensate for the accomodation. */
10515 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
10517 return fixP->fx_where + fixP->fx_frag->fr_address;
10521 /* Round up a section size to the appropriate boundary. */
10524 md_section_align (segment, size)
10525 segT segment ATTRIBUTE_UNUSED;
10531 /* Round all sects to multiple of 4. */
10532 return (size + 3) & ~3;
10536 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
10537 Otherwise we have no need to default values of symbols. */
10540 md_undefined_symbol (name)
10541 char * name ATTRIBUTE_UNUSED;
10544 if (name[0] == '_' && name[1] == 'G'
10545 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
10549 if (symbol_find (name))
10550 as_bad ("GOT already in the symbol table");
10552 GOT_symbol = symbol_new (name, undefined_section,
10553 (valueT) 0, & zero_address_frag);
10563 /* arm_reg_parse () := if it looks like a register, return its token and
10564 advance the pointer. */
10567 arm_reg_parse (ccp, htab)
10568 register char ** ccp;
10569 struct hash_control *htab;
10571 char * start = * ccp;
10574 struct reg_entry * reg;
10576 #ifdef REGISTER_PREFIX
10577 if (*start != REGISTER_PREFIX)
10582 #ifdef OPTIONAL_REGISTER_PREFIX
10583 if (*p == OPTIONAL_REGISTER_PREFIX)
10587 if (!ISALPHA (*p) || !is_name_beginner (*p))
10591 while (ISALPHA (c) || ISDIGIT (c) || c == '_')
10595 reg = (struct reg_entry *) hash_find (htab, start);
10601 return reg->number;
10607 /* Search for the following register name in each of the possible reg name
10608 tables. Return the classification if found, or REG_TYPE_MAX if not
10610 static enum arm_reg_type
10611 arm_reg_parse_any (cp)
10616 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
10617 if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
10618 return (enum arm_reg_type) i;
10620 return REG_TYPE_MAX;
10624 md_apply_fix3 (fixP, valP, seg)
10629 offsetT value = * valP;
10631 unsigned int newimm;
10632 unsigned long temp;
10634 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
10635 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
10637 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
10639 /* Note whether this will delete the relocation. */
10641 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
10642 doesn't work fully.) */
10643 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
10644 && !fixP->fx_pcrel)
10646 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
10650 /* If this symbol is in a different section then we need to leave it for
10651 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
10652 so we have to undo it's effects here. */
10653 if (fixP->fx_pcrel)
10655 if (fixP->fx_addsy != NULL
10656 && S_IS_DEFINED (fixP->fx_addsy)
10657 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
10660 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
10661 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
10665 value += md_pcrel_from (fixP);
10669 /* Remember value for emit_reloc. */
10670 fixP->fx_addnumber = value;
10672 switch (fixP->fx_r_type)
10674 case BFD_RELOC_ARM_IMMEDIATE:
10675 newimm = validate_immediate (value);
10676 temp = md_chars_to_number (buf, INSN_SIZE);
10678 /* If the instruction will fail, see if we can fix things up by
10679 changing the opcode. */
10680 if (newimm == (unsigned int) FAIL
10681 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
10683 as_bad_where (fixP->fx_file, fixP->fx_line,
10684 _("invalid constant (%lx) after fixup"),
10685 (unsigned long) value);
10689 newimm |= (temp & 0xfffff000);
10690 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
10694 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
10696 unsigned int highpart = 0;
10697 unsigned int newinsn = 0xe1a00000; /* nop. */
10699 newimm = validate_immediate (value);
10700 temp = md_chars_to_number (buf, INSN_SIZE);
10702 /* If the instruction will fail, see if we can fix things up by
10703 changing the opcode. */
10704 if (newimm == (unsigned int) FAIL
10705 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
10707 /* No ? OK - try using two ADD instructions to generate
10709 newimm = validate_immediate_twopart (value, & highpart);
10711 /* Yes - then make sure that the second instruction is
10713 if (newimm != (unsigned int) FAIL)
10715 /* Still No ? Try using a negated value. */
10716 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
10717 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
10718 /* Otherwise - give up. */
10721 as_bad_where (fixP->fx_file, fixP->fx_line,
10722 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
10727 /* Replace the first operand in the 2nd instruction (which
10728 is the PC) with the destination register. We have
10729 already added in the PC in the first instruction and we
10730 do not want to do it again. */
10731 newinsn &= ~ 0xf0000;
10732 newinsn |= ((newinsn & 0x0f000) << 4);
10735 newimm |= (temp & 0xfffff000);
10736 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
10738 highpart |= (newinsn & 0xfffff000);
10739 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
10743 case BFD_RELOC_ARM_OFFSET_IMM:
10749 if (validate_offset_imm (value, 0) == FAIL)
10751 as_bad_where (fixP->fx_file, fixP->fx_line,
10752 _("bad immediate value for offset (%ld)"),
10757 newval = md_chars_to_number (buf, INSN_SIZE);
10758 newval &= 0xff7ff000;
10759 newval |= value | (sign ? INDEX_UP : 0);
10760 md_number_to_chars (buf, newval, INSN_SIZE);
10763 case BFD_RELOC_ARM_OFFSET_IMM8:
10764 case BFD_RELOC_ARM_HWLITERAL:
10770 if (validate_offset_imm (value, 1) == FAIL)
10772 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
10773 as_bad_where (fixP->fx_file, fixP->fx_line,
10774 _("invalid literal constant: pool needs to be closer"));
10776 as_bad (_("bad immediate value for half-word offset (%ld)"),
10781 newval = md_chars_to_number (buf, INSN_SIZE);
10782 newval &= 0xff7ff0f0;
10783 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
10784 md_number_to_chars (buf, newval, INSN_SIZE);
10787 case BFD_RELOC_ARM_LITERAL:
10793 if (validate_offset_imm (value, 0) == FAIL)
10795 as_bad_where (fixP->fx_file, fixP->fx_line,
10796 _("invalid literal constant: pool needs to be closer"));
10800 newval = md_chars_to_number (buf, INSN_SIZE);
10801 newval &= 0xff7ff000;
10802 newval |= value | (sign ? INDEX_UP : 0);
10803 md_number_to_chars (buf, newval, INSN_SIZE);
10806 case BFD_RELOC_ARM_SHIFT_IMM:
10807 newval = md_chars_to_number (buf, INSN_SIZE);
10808 if (((unsigned long) value) > 32
10810 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
10812 as_bad_where (fixP->fx_file, fixP->fx_line,
10813 _("shift expression is too large"));
10818 /* Shifts of zero must be done as lsl. */
10820 else if (value == 32)
10822 newval &= 0xfffff07f;
10823 newval |= (value & 0x1f) << 7;
10824 md_number_to_chars (buf, newval, INSN_SIZE);
10827 case BFD_RELOC_ARM_SWI:
10828 if (arm_data->thumb_mode)
10830 if (((unsigned long) value) > 0xff)
10831 as_bad_where (fixP->fx_file, fixP->fx_line,
10832 _("invalid swi expression"));
10833 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
10835 md_number_to_chars (buf, newval, THUMB_SIZE);
10839 if (((unsigned long) value) > 0x00ffffff)
10840 as_bad_where (fixP->fx_file, fixP->fx_line,
10841 _("invalid swi expression"));
10842 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
10844 md_number_to_chars (buf, newval, INSN_SIZE);
10848 case BFD_RELOC_ARM_MULTI:
10849 if (((unsigned long) value) > 0xffff)
10850 as_bad_where (fixP->fx_file, fixP->fx_line,
10851 _("invalid expression in load/store multiple"));
10852 newval = value | md_chars_to_number (buf, INSN_SIZE);
10853 md_number_to_chars (buf, newval, INSN_SIZE);
10856 case BFD_RELOC_ARM_PCREL_BRANCH:
10857 newval = md_chars_to_number (buf, INSN_SIZE);
10859 /* Sign-extend a 24-bit number. */
10860 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
10864 value = fixP->fx_offset;
10867 /* We are going to store value (shifted right by two) in the
10868 instruction, in a 24 bit, signed field. Thus we need to check
10869 that none of the top 8 bits of the shifted value (top 7 bits of
10870 the unshifted, unsigned value) are set, or that they are all set. */
10871 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
10872 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
10875 /* Normally we would be stuck at this point, since we cannot store
10876 the absolute address that is the destination of the branch in the
10877 24 bits of the branch instruction. If however, we happen to know
10878 that the destination of the branch is in the same section as the
10879 branch instruciton itself, then we can compute the relocation for
10880 ourselves and not have to bother the linker with it.
10882 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
10883 because I have not worked out how to do this for OBJ_COFF or
10886 && fixP->fx_addsy != NULL
10887 && S_IS_DEFINED (fixP->fx_addsy)
10888 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
10890 /* Get pc relative value to go into the branch. */
10893 /* Permit a backward branch provided that enough bits
10894 are set. Allow a forwards branch, provided that
10895 enough bits are clear. */
10896 if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
10897 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
10901 if (! fixP->fx_done)
10903 as_bad_where (fixP->fx_file, fixP->fx_line,
10904 _("GAS can't handle same-section branch dest >= 0x04000000"));
10908 value += SEXT24 (newval);
10910 if ( (value & ~ ((offsetT) 0xffffff)) != 0
10911 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
10912 as_bad_where (fixP->fx_file, fixP->fx_line,
10913 _("out of range branch"));
10915 newval = (value & 0x00ffffff) | (newval & 0xff000000);
10916 md_number_to_chars (buf, newval, INSN_SIZE);
10919 case BFD_RELOC_ARM_PCREL_BLX:
10922 newval = md_chars_to_number (buf, INSN_SIZE);
10926 value = fixP->fx_offset;
10928 hbit = (value >> 1) & 1;
10929 value = (value >> 2) & 0x00ffffff;
10930 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
10931 newval = value | (newval & 0xfe000000) | (hbit << 24);
10932 md_number_to_chars (buf, newval, INSN_SIZE);
10936 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
10937 newval = md_chars_to_number (buf, THUMB_SIZE);
10939 addressT diff = (newval & 0xff) << 1;
10944 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
10945 as_bad_where (fixP->fx_file, fixP->fx_line,
10946 _("branch out of range"));
10947 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
10949 md_number_to_chars (buf, newval, THUMB_SIZE);
10952 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
10953 newval = md_chars_to_number (buf, THUMB_SIZE);
10955 addressT diff = (newval & 0x7ff) << 1;
10960 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
10961 as_bad_where (fixP->fx_file, fixP->fx_line,
10962 _("branch out of range"));
10963 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
10965 md_number_to_chars (buf, newval, THUMB_SIZE);
10968 case BFD_RELOC_THUMB_PCREL_BLX:
10969 case BFD_RELOC_THUMB_PCREL_BRANCH23:
10974 newval = md_chars_to_number (buf, THUMB_SIZE);
10975 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
10976 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
10977 if (diff & 0x400000)
10980 value = fixP->fx_offset;
10984 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
10985 as_bad_where (fixP->fx_file, fixP->fx_line,
10986 _("branch with link out of range"));
10988 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
10989 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
10990 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
10991 /* For a BLX instruction, make sure that the relocation is rounded up
10992 to a word boundary. This follows the semantics of the instruction
10993 which specifies that bit 1 of the target address will come from bit
10994 1 of the base address. */
10995 newval2 = (newval2 + 1) & ~ 1;
10996 md_number_to_chars (buf, newval, THUMB_SIZE);
10997 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
11002 if (fixP->fx_done || fixP->fx_pcrel)
11003 md_number_to_chars (buf, value, 1);
11005 else if (!target_oabi)
11007 value = fixP->fx_offset;
11008 md_number_to_chars (buf, value, 1);
11014 if (fixP->fx_done || fixP->fx_pcrel)
11015 md_number_to_chars (buf, value, 2);
11017 else if (!target_oabi)
11019 value = fixP->fx_offset;
11020 md_number_to_chars (buf, value, 2);
11026 case BFD_RELOC_ARM_GOT32:
11027 case BFD_RELOC_ARM_GOTOFF:
11028 md_number_to_chars (buf, 0, 4);
11032 case BFD_RELOC_RVA:
11034 if (fixP->fx_done || fixP->fx_pcrel)
11035 md_number_to_chars (buf, value, 4);
11037 else if (!target_oabi)
11039 value = fixP->fx_offset;
11040 md_number_to_chars (buf, value, 4);
11046 case BFD_RELOC_ARM_PLT32:
11047 /* It appears the instruction is fully prepared at this point. */
11051 case BFD_RELOC_ARM_CP_OFF_IMM:
11053 if (value < -1023 || value > 1023 || (value & 3))
11054 as_bad_where (fixP->fx_file, fixP->fx_line,
11055 _("illegal value for co-processor offset"));
11058 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11059 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
11060 md_number_to_chars (buf, newval, INSN_SIZE);
11063 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
11065 if (value < -255 || value > 255)
11066 as_bad_where (fixP->fx_file, fixP->fx_line,
11067 _("Illegal value for co-processor offset"));
11070 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
11071 newval |= value | (sign ? INDEX_UP : 0);
11072 md_number_to_chars (buf, newval , INSN_SIZE);
11075 case BFD_RELOC_ARM_THUMB_OFFSET:
11076 newval = md_chars_to_number (buf, THUMB_SIZE);
11077 /* Exactly what ranges, and where the offset is inserted depends
11078 on the type of instruction, we can establish this from the
11080 switch (newval >> 12)
11082 case 4: /* PC load. */
11083 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
11084 forced to zero for these loads, so we will need to round
11085 up the offset if the instruction address is not word
11086 aligned (since the final address produced must be, and
11087 we can only describe word-aligned immediate offsets). */
11089 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
11090 as_bad_where (fixP->fx_file, fixP->fx_line,
11091 _("invalid offset, target not word aligned (0x%08X)"),
11092 (unsigned int) (fixP->fx_frag->fr_address
11093 + fixP->fx_where + value));
11095 if ((value + 2) & ~0x3fe)
11096 as_bad_where (fixP->fx_file, fixP->fx_line,
11097 _("invalid offset, value too big (0x%08lX)"),
11100 /* Round up, since pc will be rounded down. */
11101 newval |= (value + 2) >> 2;
11104 case 9: /* SP load/store. */
11105 if (value & ~0x3fc)
11106 as_bad_where (fixP->fx_file, fixP->fx_line,
11107 _("invalid offset, value too big (0x%08lX)"),
11109 newval |= value >> 2;
11112 case 6: /* Word load/store. */
11114 as_bad_where (fixP->fx_file, fixP->fx_line,
11115 _("invalid offset, value too big (0x%08lX)"),
11117 newval |= value << 4; /* 6 - 2. */
11120 case 7: /* Byte load/store. */
11122 as_bad_where (fixP->fx_file, fixP->fx_line,
11123 _("invalid offset, value too big (0x%08lX)"),
11125 newval |= value << 6;
11128 case 8: /* Halfword load/store. */
11130 as_bad_where (fixP->fx_file, fixP->fx_line,
11131 _("invalid offset, value too big (0x%08lX)"),
11133 newval |= value << 5; /* 6 - 1. */
11137 as_bad_where (fixP->fx_file, fixP->fx_line,
11138 "Unable to process relocation for thumb opcode: %lx",
11139 (unsigned long) newval);
11142 md_number_to_chars (buf, newval, THUMB_SIZE);
11145 case BFD_RELOC_ARM_THUMB_ADD:
11146 /* This is a complicated relocation, since we use it for all of
11147 the following immediate relocations:
11151 9bit ADD/SUB SP word-aligned
11152 10bit ADD PC/SP word-aligned
11154 The type of instruction being processed is encoded in the
11161 newval = md_chars_to_number (buf, THUMB_SIZE);
11163 int rd = (newval >> 4) & 0xf;
11164 int rs = newval & 0xf;
11165 int subtract = newval & 0x8000;
11169 if (value & ~0x1fc)
11170 as_bad_where (fixP->fx_file, fixP->fx_line,
11171 _("invalid immediate for stack address calculation"));
11172 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
11173 newval |= value >> 2;
11175 else if (rs == REG_PC || rs == REG_SP)
11179 as_bad_where (fixP->fx_file, fixP->fx_line,
11180 _("invalid immediate for address calculation (value = 0x%08lX)"),
11181 (unsigned long) value);
11182 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
11184 newval |= value >> 2;
11189 as_bad_where (fixP->fx_file, fixP->fx_line,
11190 _("invalid 8bit immediate"));
11191 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
11192 newval |= (rd << 8) | value;
11197 as_bad_where (fixP->fx_file, fixP->fx_line,
11198 _("invalid 3bit immediate"));
11199 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
11200 newval |= rd | (rs << 3) | (value << 6);
11203 md_number_to_chars (buf, newval, THUMB_SIZE);
11206 case BFD_RELOC_ARM_THUMB_IMM:
11207 newval = md_chars_to_number (buf, THUMB_SIZE);
11208 switch (newval >> 11)
11210 case 0x04: /* 8bit immediate MOV. */
11211 case 0x05: /* 8bit immediate CMP. */
11212 if (value < 0 || value > 255)
11213 as_bad_where (fixP->fx_file, fixP->fx_line,
11214 _("invalid immediate: %ld is too large"),
11222 md_number_to_chars (buf, newval, THUMB_SIZE);
11225 case BFD_RELOC_ARM_THUMB_SHIFT:
11226 /* 5bit shift value (0..31). */
11227 if (value < 0 || value > 31)
11228 as_bad_where (fixP->fx_file, fixP->fx_line,
11229 _("illegal Thumb shift value: %ld"), (long) value);
11230 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
11231 newval |= value << 6;
11232 md_number_to_chars (buf, newval, THUMB_SIZE);
11235 case BFD_RELOC_VTABLE_INHERIT:
11236 case BFD_RELOC_VTABLE_ENTRY:
11240 case BFD_RELOC_NONE:
11242 as_bad_where (fixP->fx_file, fixP->fx_line,
11243 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
11247 /* Translate internal representation of relocation info to BFD target
11251 tc_gen_reloc (section, fixp)
11252 asection * section ATTRIBUTE_UNUSED;
11256 bfd_reloc_code_real_type code;
11258 reloc = (arelent *) xmalloc (sizeof (arelent));
11260 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
11261 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
11262 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
11264 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
11266 if (fixp->fx_pcrel == 0)
11267 reloc->addend = fixp->fx_offset;
11269 reloc->addend = fixp->fx_offset = reloc->address;
11270 #else /* OBJ_ELF */
11271 reloc->addend = fixp->fx_offset;
11274 switch (fixp->fx_r_type)
11277 if (fixp->fx_pcrel)
11279 code = BFD_RELOC_8_PCREL;
11284 if (fixp->fx_pcrel)
11286 code = BFD_RELOC_16_PCREL;
11291 if (fixp->fx_pcrel)
11293 code = BFD_RELOC_32_PCREL;
11297 case BFD_RELOC_ARM_PCREL_BRANCH:
11298 case BFD_RELOC_ARM_PCREL_BLX:
11299 case BFD_RELOC_RVA:
11300 case BFD_RELOC_THUMB_PCREL_BRANCH9:
11301 case BFD_RELOC_THUMB_PCREL_BRANCH12:
11302 case BFD_RELOC_THUMB_PCREL_BRANCH23:
11303 case BFD_RELOC_THUMB_PCREL_BLX:
11304 case BFD_RELOC_VTABLE_ENTRY:
11305 case BFD_RELOC_VTABLE_INHERIT:
11306 code = fixp->fx_r_type;
11309 case BFD_RELOC_ARM_LITERAL:
11310 case BFD_RELOC_ARM_HWLITERAL:
11311 /* If this is called then the a literal has
11312 been referenced across a section boundary. */
11313 as_bad_where (fixp->fx_file, fixp->fx_line,
11314 _("literal referenced across section boundary"));
11318 case BFD_RELOC_ARM_GOT32:
11319 case BFD_RELOC_ARM_GOTOFF:
11320 case BFD_RELOC_ARM_PLT32:
11321 code = fixp->fx_r_type;
11325 case BFD_RELOC_ARM_IMMEDIATE:
11326 as_bad_where (fixp->fx_file, fixp->fx_line,
11327 _("internal relocation (type: IMMEDIATE) not fixed up"));
11330 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11331 as_bad_where (fixp->fx_file, fixp->fx_line,
11332 _("ADRL used for a symbol not defined in the same file"));
11335 case BFD_RELOC_ARM_OFFSET_IMM:
11336 as_bad_where (fixp->fx_file, fixp->fx_line,
11337 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
11344 switch (fixp->fx_r_type)
11346 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
11347 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
11348 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
11349 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
11350 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
11351 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
11352 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
11353 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
11354 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
11355 default: type = _("<unknown>"); break;
11357 as_bad_where (fixp->fx_file, fixp->fx_line,
11358 _("cannot represent %s relocation in this object file format"),
11365 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
11367 && fixp->fx_addsy == GOT_symbol)
11369 code = BFD_RELOC_ARM_GOTPC;
11370 reloc->addend = fixp->fx_offset = reloc->address;
11374 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
11376 if (reloc->howto == NULL)
11378 as_bad_where (fixp->fx_file, fixp->fx_line,
11379 _("cannot represent %s relocation in this object file format"),
11380 bfd_get_reloc_code_name (code));
11384 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
11385 vtable entry to be used in the relocation's section offset. */
11386 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
11387 reloc->address = fixp->fx_offset;
11393 md_estimate_size_before_relax (fragP, segtype)
11394 fragS * fragP ATTRIBUTE_UNUSED;
11395 segT segtype ATTRIBUTE_UNUSED;
11397 as_fatal (_("md_estimate_size_before_relax\n"));
11409 as_bad ("%s -- `%s'", inst.error, str);
11413 to = frag_more (inst.size);
11415 if (thumb_mode && (inst.size > THUMB_SIZE))
11417 assert (inst.size == (2 * THUMB_SIZE));
11418 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
11419 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
11421 else if (inst.size > INSN_SIZE)
11423 assert (inst.size == (2 * INSN_SIZE));
11424 md_number_to_chars (to, inst.instruction, INSN_SIZE);
11425 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
11428 md_number_to_chars (to, inst.instruction, inst.size);
11430 if (inst.reloc.type != BFD_RELOC_NONE)
11431 fix_new_arm (frag_now, to - frag_now->fr_literal,
11432 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
11436 dwarf2_emit_insn (inst.size);
11448 /* Align the instruction.
11449 This may not be the right thing to do but ... */
11454 /* Align the previous label if needed. */
11455 if (last_label_seen != NULL)
11457 symbol_set_frag (last_label_seen, frag_now);
11458 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
11459 S_SET_SEGMENT (last_label_seen, now_seg);
11462 memset (&inst, '\0', sizeof (inst));
11463 inst.reloc.type = BFD_RELOC_NONE;
11465 skip_whitespace (str);
11467 /* Scan up to the end of the op-code, which must end in white space or
11469 for (start = p = str; *p != '\0'; p++)
11475 as_bad (_("no operator -- statement `%s'\n"), str);
11481 const struct thumb_opcode * opcode;
11485 opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
11490 /* Check that this instruction is supported for this CPU. */
11491 if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
11493 as_bad (_("selected processor does not support `%s'"), str);
11497 inst.instruction = opcode->value;
11498 inst.size = opcode->size;
11499 (*opcode->parms) (p);
11506 const struct asm_opcode * opcode;
11510 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
11515 /* Check that this instruction is supported for this CPU. */
11516 if ((opcode->variant & cpu_variant) == 0)
11518 as_bad (_("selected processor does not support `%s'"), str);
11522 inst.instruction = opcode->value;
11523 inst.size = INSN_SIZE;
11524 (*opcode->parms) (p);
11530 /* It wasn't an instruction, but it might be a register alias of the form
11532 if (create_register_alias (str, p))
11535 as_bad (_("bad instruction `%s'"), start);
11539 Invocation line includes a switch not recognized by the base assembler.
11540 See if it's a processor-specific option.
11542 This routine is somewhat complicated by the need for backwards
11543 compatibility (since older releases of gcc can't be changed).
11544 The new options try to make the interface as compatible as
11547 New options (supported) are:
11549 -mcpu=<cpu name> Assemble for selected processor
11550 -march=<architecture name> Assemble for selected architecture
11551 -mfpu=<fpu architecture> Assemble for selected FPU.
11552 -EB/-mbig-endian Big-endian
11553 -EL/-mlittle-endian Little-endian
11554 -k Generate PIC code
11555 -mthumb Start in Thumb mode
11556 -mthumb-interwork Code supports ARM/Thumb interworking
11558 For now we will also provide support for:
11560 -mapcs-32 32-bit Program counter
11561 -mapcs-26 26-bit Program counter
11562 -macps-float Floats passed in FP registers
11563 -mapcs-reentrant Reentrant code
11565 (sometime these will probably be replaced with -mapcs=<list of options>
11566 and -matpcs=<list of options>)
11568 The remaining options are only supported for back-wards compatibility.
11569 Cpu variants, the arm part is optional:
11570 -m[arm]1 Currently not supported.
11571 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
11572 -m[arm]3 Arm 3 processor
11573 -m[arm]6[xx], Arm 6 processors
11574 -m[arm]7[xx][t][[d]m] Arm 7 processors
11575 -m[arm]8[10] Arm 8 processors
11576 -m[arm]9[20][tdmi] Arm 9 processors
11577 -mstrongarm[110[0]] StrongARM processors
11578 -mxscale XScale processors
11579 -m[arm]v[2345[t[e]]] Arm architectures
11580 -mall All (except the ARM1)
11582 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
11583 -mfpe-old (No float load/store multiples)
11584 -mvfpxd VFP Single precision
11586 -mno-fpu Disable all floating point instructions
11588 The following CPU names are recognized:
11589 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
11590 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
11591 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
11592 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
11593 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
11594 arm10t arm10e, arm1020t, arm1020e, arm10200e,
11595 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
11599 const char * md_shortopts = "m:k";
11601 #ifdef ARM_BI_ENDIAN
11602 #define OPTION_EB (OPTION_MD_BASE + 0)
11603 #define OPTION_EL (OPTION_MD_BASE + 1)
11605 #if TARGET_BYTES_BIG_ENDIAN
11606 #define OPTION_EB (OPTION_MD_BASE + 0)
11608 #define OPTION_EL (OPTION_MD_BASE + 1)
11612 struct option md_longopts[] =
11615 {"EB", no_argument, NULL, OPTION_EB},
11618 {"EL", no_argument, NULL, OPTION_EL},
11620 {NULL, no_argument, NULL, 0}
11623 size_t md_longopts_size = sizeof (md_longopts);
11625 struct arm_option_table
11627 char *option; /* Option name to match. */
11628 char *help; /* Help information. */
11629 int *var; /* Variable to change. */
11630 int value; /* What to change it to. */
11631 char *deprecated; /* If non-null, print this message. */
11634 struct arm_option_table arm_opts[] =
11636 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
11637 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
11638 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
11639 &support_interwork, 1, NULL},
11640 {"moabi", N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
11641 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
11642 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
11643 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
11645 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
11646 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
11647 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
11648 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
11651 /* These are recognized by the assembler, but have no affect on code. */
11652 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
11653 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
11655 /* DON'T add any new processors to this list -- we want the whole list
11656 to go away... Add them to the processors table instead. */
11657 {"marm1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
11658 {"m1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
11659 {"marm2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
11660 {"m2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
11661 {"marm250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
11662 {"m250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
11663 {"marm3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
11664 {"m3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
11665 {"marm6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
11666 {"m6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
11667 {"marm600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
11668 {"m600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
11669 {"marm610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
11670 {"m610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
11671 {"marm620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
11672 {"m620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
11673 {"marm7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
11674 {"m7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
11675 {"marm70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
11676 {"m70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
11677 {"marm700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
11678 {"m700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
11679 {"marm700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
11680 {"m700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
11681 {"marm710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
11682 {"m710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
11683 {"marm710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
11684 {"m710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
11685 {"marm720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
11686 {"m720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
11687 {"marm7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
11688 {"m7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
11689 {"marm7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
11690 {"m7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
11691 {"marm7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
11692 {"m7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
11693 {"marm7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
11694 {"m7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
11695 {"marm7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
11696 {"m7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
11697 {"marm7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
11698 {"m7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
11699 {"marm7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
11700 {"m7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
11701 {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
11702 {"m7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
11703 {"marm7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
11704 {"m7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
11705 {"marm7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
11706 {"m7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
11707 {"marm710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
11708 {"m710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
11709 {"marm720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
11710 {"m720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
11711 {"marm740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
11712 {"m740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
11713 {"marm8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
11714 {"m8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
11715 {"marm810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
11716 {"m810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
11717 {"marm9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
11718 {"m9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
11719 {"marm9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
11720 {"m9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
11721 {"marm920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
11722 {"m920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
11723 {"marm940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
11724 {"m940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
11725 {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
11726 {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
11727 N_("use -mcpu=strongarm110")},
11728 {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
11729 N_("use -mcpu=strongarm1100")},
11730 {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
11731 N_("use -mcpu=strongarm1110")},
11732 {"mxscale", NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
11733 {"miwmmxt", NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
11734 {"mall", NULL, &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
11736 /* Architecture variants -- don't add any more to this list either. */
11737 {"mv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
11738 {"marmv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
11739 {"mv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
11740 {"marmv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
11741 {"mv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
11742 {"marmv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
11743 {"mv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
11744 {"marmv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
11745 {"mv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
11746 {"marmv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
11747 {"mv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
11748 {"marmv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
11749 {"mv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
11750 {"marmv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
11751 {"mv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
11752 {"marmv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
11753 {"mv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
11754 {"marmv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
11756 /* Floating point variants -- don't add any more to this list either. */
11757 {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
11758 {"mfpa10", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
11759 {"mfpa11", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
11760 {"mno-fpu", NULL, &legacy_fpu, 0,
11761 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
11763 {NULL, NULL, NULL, 0, NULL}
11766 struct arm_cpu_option_table
11770 /* For some CPUs we assume an FPU unless the user explicitly sets
11775 /* This list should, at a minimum, contain all the cpu names
11776 recognized by GCC. */
11777 static struct arm_cpu_option_table arm_cpus[] =
11779 {"all", ARM_ANY, FPU_ARCH_FPA},
11780 {"arm1", ARM_ARCH_V1, FPU_ARCH_FPA},
11781 {"arm2", ARM_ARCH_V2, FPU_ARCH_FPA},
11782 {"arm250", ARM_ARCH_V2S, FPU_ARCH_FPA},
11783 {"arm3", ARM_ARCH_V2S, FPU_ARCH_FPA},
11784 {"arm6", ARM_ARCH_V3, FPU_ARCH_FPA},
11785 {"arm60", ARM_ARCH_V3, FPU_ARCH_FPA},
11786 {"arm600", ARM_ARCH_V3, FPU_ARCH_FPA},
11787 {"arm610", ARM_ARCH_V3, FPU_ARCH_FPA},
11788 {"arm620", ARM_ARCH_V3, FPU_ARCH_FPA},
11789 {"arm7", ARM_ARCH_V3, FPU_ARCH_FPA},
11790 {"arm7m", ARM_ARCH_V3M, FPU_ARCH_FPA},
11791 {"arm7d", ARM_ARCH_V3, FPU_ARCH_FPA},
11792 {"arm7dm", ARM_ARCH_V3M, FPU_ARCH_FPA},
11793 {"arm7di", ARM_ARCH_V3, FPU_ARCH_FPA},
11794 {"arm7dmi", ARM_ARCH_V3M, FPU_ARCH_FPA},
11795 {"arm70", ARM_ARCH_V3, FPU_ARCH_FPA},
11796 {"arm700", ARM_ARCH_V3, FPU_ARCH_FPA},
11797 {"arm700i", ARM_ARCH_V3, FPU_ARCH_FPA},
11798 {"arm710", ARM_ARCH_V3, FPU_ARCH_FPA},
11799 {"arm710t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11800 {"arm720", ARM_ARCH_V3, FPU_ARCH_FPA},
11801 {"arm720t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11802 {"arm740t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11803 {"arm710c", ARM_ARCH_V3, FPU_ARCH_FPA},
11804 {"arm7100", ARM_ARCH_V3, FPU_ARCH_FPA},
11805 {"arm7500", ARM_ARCH_V3, FPU_ARCH_FPA},
11806 {"arm7500fe", ARM_ARCH_V3, FPU_ARCH_FPA},
11807 {"arm7t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11808 {"arm7tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
11809 {"arm8", ARM_ARCH_V4, FPU_ARCH_FPA},
11810 {"arm810", ARM_ARCH_V4, FPU_ARCH_FPA},
11811 {"strongarm", ARM_ARCH_V4, FPU_ARCH_FPA},
11812 {"strongarm1", ARM_ARCH_V4, FPU_ARCH_FPA},
11813 {"strongarm110", ARM_ARCH_V4, FPU_ARCH_FPA},
11814 {"strongarm1100", ARM_ARCH_V4, FPU_ARCH_FPA},
11815 {"strongarm1110", ARM_ARCH_V4, FPU_ARCH_FPA},
11816 {"arm9", ARM_ARCH_V4T, FPU_ARCH_FPA},
11817 {"arm920", ARM_ARCH_V4T, FPU_ARCH_FPA},
11818 {"arm920t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11819 {"arm922t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11820 {"arm940t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11821 {"arm9tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
11822 /* For V5 or later processors we default to using VFP; but the user
11823 should really set the FPU type explicitly. */
11824 {"arm9e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
11825 {"arm9e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11826 {"arm926ej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2},
11827 {"arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
11828 {"arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11829 {"arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
11830 {"arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11831 {"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
11832 {"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11833 {"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11834 {"arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
11835 {"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
11836 /* ??? XSCALE is really an architecture. */
11837 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
11838 /* ??? iwmmxt is not a processor. */
11839 {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2},
11840 {"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
11842 {"ep9312", ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_NONE},
11846 struct arm_arch_option_table
11853 /* This list should, at a minimum, contain all the architecture names
11854 recognized by GCC. */
11855 static struct arm_arch_option_table arm_archs[] =
11857 {"all", ARM_ANY, FPU_ARCH_FPA},
11858 {"armv1", ARM_ARCH_V1, FPU_ARCH_FPA},
11859 {"armv2", ARM_ARCH_V2, FPU_ARCH_FPA},
11860 {"armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA},
11861 {"armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA},
11862 {"armv3", ARM_ARCH_V3, FPU_ARCH_FPA},
11863 {"armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA},
11864 {"armv4", ARM_ARCH_V4, FPU_ARCH_FPA},
11865 {"armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA},
11866 {"armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA},
11867 {"armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA},
11868 {"armv5", ARM_ARCH_V5, FPU_ARCH_VFP},
11869 {"armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP},
11870 {"armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP},
11871 {"armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP},
11872 {"armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP},
11873 {"armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP},
11874 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
11878 /* ISA extensions in the co-processor space. */
11879 struct arm_arch_extension_table
11885 static struct arm_arch_extension_table arm_extensions[] =
11887 {"maverick", ARM_CEXT_MAVERICK},
11888 {"xscale", ARM_CEXT_XSCALE},
11889 {"iwmmxt", ARM_CEXT_IWMMXT},
11893 struct arm_fpu_option_table
11899 /* This list should, at a minimum, contain all the fpu names
11900 recognized by GCC. */
11901 static struct arm_fpu_option_table arm_fpus[] =
11903 {"softfpa", FPU_NONE},
11904 {"fpe", FPU_ARCH_FPE},
11905 {"fpe2", FPU_ARCH_FPE},
11906 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
11907 {"fpa", FPU_ARCH_FPA},
11908 {"fpa10", FPU_ARCH_FPA},
11909 {"fpa11", FPU_ARCH_FPA},
11910 {"arm7500fe", FPU_ARCH_FPA},
11911 {"softvfp", FPU_ARCH_VFP},
11912 {"softvfp+vfp", FPU_ARCH_VFP_V2},
11913 {"vfp", FPU_ARCH_VFP_V2},
11914 {"vfp9", FPU_ARCH_VFP_V2},
11915 {"vfp10", FPU_ARCH_VFP_V2},
11916 {"vfp10-r0", FPU_ARCH_VFP_V1},
11917 {"vfpxd", FPU_ARCH_VFP_V1xD},
11918 {"arm1020t", FPU_ARCH_VFP_V1},
11919 {"arm1020e", FPU_ARCH_VFP_V2},
11923 struct arm_long_option_table
11925 char *option; /* Substring to match. */
11926 char *help; /* Help information. */
11927 int (*func) PARAMS ((char *subopt)); /* Function to decode sub-option. */
11928 char *deprecated; /* If non-null, print this message. */
11932 arm_parse_extension (str, opt_p)
11936 while (str != NULL && *str != 0)
11938 struct arm_arch_extension_table *opt;
11944 as_bad (_("invalid architectural extension"));
11949 ext = strchr (str, '+');
11952 optlen = ext - str;
11954 optlen = strlen (str);
11958 as_bad (_("missing architectural extension"));
11962 for (opt = arm_extensions; opt->name != NULL; opt++)
11963 if (strncmp (opt->name, str, optlen) == 0)
11965 *opt_p |= opt->value;
11969 if (opt->name == NULL)
11971 as_bad (_("unknown architectural extnsion `%s'"), str);
11982 arm_parse_cpu (str)
11985 struct arm_cpu_option_table *opt;
11986 char *ext = strchr (str, '+');
11990 optlen = ext - str;
11992 optlen = strlen (str);
11996 as_bad (_("missing cpu name `%s'"), str);
12000 for (opt = arm_cpus; opt->name != NULL; opt++)
12001 if (strncmp (opt->name, str, optlen) == 0)
12003 mcpu_cpu_opt = opt->value;
12004 mcpu_fpu_opt = opt->default_fpu;
12007 return arm_parse_extension (ext, &mcpu_cpu_opt);
12012 as_bad (_("unknown cpu `%s'"), str);
12017 arm_parse_arch (str)
12020 struct arm_arch_option_table *opt;
12021 char *ext = strchr (str, '+');
12025 optlen = ext - str;
12027 optlen = strlen (str);
12031 as_bad (_("missing architecture name `%s'"), str);
12036 for (opt = arm_archs; opt->name != NULL; opt++)
12037 if (strcmp (opt->name, str) == 0)
12039 march_cpu_opt = opt->value;
12040 march_fpu_opt = opt->default_fpu;
12043 return arm_parse_extension (ext, &march_cpu_opt);
12048 as_bad (_("unknown architecture `%s'\n"), str);
12053 arm_parse_fpu (str)
12056 struct arm_fpu_option_table *opt;
12058 for (opt = arm_fpus; opt->name != NULL; opt++)
12059 if (strcmp (opt->name, str) == 0)
12061 mfpu_opt = opt->value;
12065 as_bad (_("unknown floating point format `%s'\n"), str);
12069 struct arm_long_option_table arm_long_opts[] =
12071 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
12072 arm_parse_cpu, NULL},
12073 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
12074 arm_parse_arch, NULL},
12075 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
12076 arm_parse_fpu, NULL},
12077 {NULL, NULL, 0, NULL}
12081 md_parse_option (c, arg)
12085 struct arm_option_table *opt;
12086 struct arm_long_option_table *lopt;
12092 target_big_endian = 1;
12098 target_big_endian = 0;
12103 /* Listing option. Just ignore these, we don't support additional
12108 for (opt = arm_opts; opt->option != NULL; opt++)
12110 if (c == opt->option[0]
12111 && ((arg == NULL && opt->option[1] == 0)
12112 || strcmp (arg, opt->option + 1) == 0))
12114 #if WARN_DEPRECATED
12115 /* If the option is deprecated, tell the user. */
12116 if (opt->deprecated != NULL)
12117 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
12118 arg ? arg : "", _(opt->deprecated));
12121 if (opt->var != NULL)
12122 *opt->var = opt->value;
12128 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
12130 /* These options are expected to have an argument. */
12131 if (c == lopt->option[0]
12133 && strncmp (arg, lopt->option + 1,
12134 strlen (lopt->option + 1)) == 0)
12136 #if WARN_DEPRECATED
12137 /* If the option is deprecated, tell the user. */
12138 if (lopt->deprecated != NULL)
12139 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
12140 _(lopt->deprecated));
12143 /* Call the sup-option parser. */
12144 return (*lopt->func)(arg + strlen (lopt->option) - 1);
12148 as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
12159 struct arm_option_table *opt;
12160 struct arm_long_option_table *lopt;
12162 fprintf (fp, _(" ARM-specific assembler options:\n"));
12164 for (opt = arm_opts; opt->option != NULL; opt++)
12165 if (opt->help != NULL)
12166 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
12168 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
12169 if (lopt->help != NULL)
12170 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
12174 -EB assemble code for a big-endian cpu\n"));
12179 -EL assemble code for a little-endian cpu\n"));
12183 /* We need to be able to fix up arbitrary expressions in some statements.
12184 This is so that we can handle symbols that are an arbitrary distance from
12185 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
12186 which returns part of an address in a form which will be valid for
12187 a data instruction. We do this by pushing the expression into a symbol
12188 in the expr_section, and creating a fix for that. */
12191 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
12200 arm_fix_data * arm_data;
12208 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
12212 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
12217 /* Mark whether the fix is to a THUMB instruction, or an ARM
12219 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
12220 new_fix->tc_fix_data = (PTR) arm_data;
12221 arm_data->thumb_mode = thumb_mode;
12226 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
12229 cons_fix_new_arm (frag, where, size, exp)
12235 bfd_reloc_code_real_type type;
12239 FIXME: @@ Should look at CPU word size. */
12243 type = BFD_RELOC_8;
12246 type = BFD_RELOC_16;
12250 type = BFD_RELOC_32;
12253 type = BFD_RELOC_64;
12257 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
12260 /* A good place to do this, although this was probably not intended
12261 for this kind of use. We need to dump the literal pool before
12262 references are made to a null symbol pointer. */
12267 literal_pool * pool;
12269 for (pool = list_of_pools; pool; pool = pool->next)
12271 /* Put it at the end of the relevent section. */
12272 subseg_set (pool->section, pool->sub_section);
12278 arm_start_line_hook ()
12280 last_label_seen = NULL;
12284 arm_frob_label (sym)
12287 last_label_seen = sym;
12289 ARM_SET_THUMB (sym, thumb_mode);
12291 #if defined OBJ_COFF || defined OBJ_ELF
12292 ARM_SET_INTERWORK (sym, support_interwork);
12295 /* Note - do not allow local symbols (.Lxxx) to be labeled
12296 as Thumb functions. This is because these labels, whilst
12297 they exist inside Thumb code, are not the entry points for
12298 possible ARM->Thumb calls. Also, these labels can be used
12299 as part of a computed goto or switch statement. eg gcc
12300 can generate code that looks like this:
12302 ldr r2, [pc, .Laaa]
12312 The first instruction loads the address of the jump table.
12313 The second instruction converts a table index into a byte offset.
12314 The third instruction gets the jump address out of the table.
12315 The fourth instruction performs the jump.
12317 If the address stored at .Laaa is that of a symbol which has the
12318 Thumb_Func bit set, then the linker will arrange for this address
12319 to have the bottom bit set, which in turn would mean that the
12320 address computation performed by the third instruction would end
12321 up with the bottom bit set. Since the ARM is capable of unaligned
12322 word loads, the instruction would then load the incorrect address
12323 out of the jump table, and chaos would ensue. */
12324 if (label_is_thumb_function_name
12325 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
12326 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
12328 /* When the address of a Thumb function is taken the bottom
12329 bit of that address should be set. This will allow
12330 interworking between Arm and Thumb functions to work
12333 THUMB_SET_FUNC (sym, 1);
12335 label_is_thumb_function_name = FALSE;
12339 /* Adjust the symbol table. This marks Thumb symbols as distinct from
12343 arm_adjust_symtab ()
12348 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
12350 if (ARM_IS_THUMB (sym))
12352 if (THUMB_IS_FUNC (sym))
12354 /* Mark the symbol as a Thumb function. */
12355 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
12356 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
12357 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
12359 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
12360 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
12362 as_bad (_("%s: unexpected function type: %d"),
12363 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
12365 else switch (S_GET_STORAGE_CLASS (sym))
12368 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
12371 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
12374 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
12382 if (ARM_IS_INTERWORK (sym))
12383 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
12390 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
12392 if (ARM_IS_THUMB (sym))
12394 elf_symbol_type * elf_sym;
12396 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
12397 bind = ELF_ST_BIND (elf_sym);
12399 /* If it's a .thumb_func, declare it as so,
12400 otherwise tag label as .code 16. */
12401 if (THUMB_IS_FUNC (sym))
12402 elf_sym->internal_elf_sym.st_info =
12403 ELF_ST_INFO (bind, STT_ARM_TFUNC);
12405 elf_sym->internal_elf_sym.st_info =
12406 ELF_ST_INFO (bind, STT_ARM_16BIT);
12413 arm_data_in_code ()
12415 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
12417 *input_line_pointer = '/';
12418 input_line_pointer += 5;
12419 *input_line_pointer = 0;
12427 arm_canonicalize_symbol_name (name)
12432 if (thumb_mode && (len = strlen (name)) > 5
12433 && streq (name + len - 5, "/data"))
12434 *(name + len - 5) = 0;
12439 #if defined OBJ_COFF || defined OBJ_ELF
12441 arm_validate_fix (fixP)
12444 /* If the destination of the branch is a defined symbol which does not have
12445 the THUMB_FUNC attribute, then we must be calling a function which has
12446 the (interfacearm) attribute. We look for the Thumb entry point to that
12447 function and change the branch to refer to that function instead. */
12448 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
12449 && fixP->fx_addsy != NULL
12450 && S_IS_DEFINED (fixP->fx_addsy)
12451 && ! THUMB_IS_FUNC (fixP->fx_addsy))
12453 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
12459 arm_force_relocation (fixp)
12462 #if defined (OBJ_COFF) && defined (TE_PE)
12463 if (fixp->fx_r_type == BFD_RELOC_RVA)
12467 if (fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
12468 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
12469 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
12470 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
12474 /* Resolve these relocations even if the symbol is extern or weak. */
12475 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
12476 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
12477 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
12480 return generic_force_reloc (fixp);
12484 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
12485 local labels from being added to the output symbol table when they
12486 are used with the ADRL pseudo op. The ADRL relocation should always
12487 be resolved before the binbary is emitted, so it is safe to say that
12488 it is adjustable. */
12491 arm_fix_adjustable (fixP)
12494 if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
12501 /* Relocations against Thumb function names must be left unadjusted,
12502 so that the linker can use this information to correctly set the
12503 bottom bit of their addresses. The MIPS version of this function
12504 also prevents relocations that are mips-16 specific, but I do not
12505 know why it does this.
12508 There is one other problem that ought to be addressed here, but
12509 which currently is not: Taking the address of a label (rather
12510 than a function) and then later jumping to that address. Such
12511 addresses also ought to have their bottom bit set (assuming that
12512 they reside in Thumb code), but at the moment they will not. */
12515 arm_fix_adjustable (fixP)
12518 if (fixP->fx_addsy == NULL)
12521 if (THUMB_IS_FUNC (fixP->fx_addsy)
12522 && fixP->fx_subsy == NULL)
12525 /* We need the symbol name for the VTABLE entries. */
12526 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
12527 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12530 /* Don't allow symbols to be discarded on GOT related relocs. */
12531 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
12532 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
12533 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
12540 elf32_arm_target_format ()
12542 if (target_big_endian)
12545 return "elf32-bigarm-oabi";
12547 return "elf32-bigarm";
12552 return "elf32-littlearm-oabi";
12554 return "elf32-littlearm";
12559 armelf_frob_symbol (symp, puntp)
12563 elf_frob_symbol (symp, puntp);
12566 static bfd_reloc_code_real_type
12576 bfd_reloc_code_real_type reloc;
12580 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
12581 MAP ("(got)", BFD_RELOC_ARM_GOT32),
12582 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
12583 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
12584 branch instructions generated by GCC for PLT relocs. */
12585 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
12586 { NULL, 0, BFD_RELOC_UNUSED }
12590 for (i = 0, ip = input_line_pointer;
12591 i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
12593 id[i] = TOLOWER (*ip);
12595 for (i = 0; reloc_map[i].str; i++)
12596 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
12599 input_line_pointer += reloc_map[i].len;
12601 return reloc_map[i].reloc;
12605 s_arm_elf_cons (nbytes)
12610 #ifdef md_flush_pending_output
12611 md_flush_pending_output ();
12614 if (is_it_end_of_statement ())
12616 demand_empty_rest_of_line ();
12620 #ifdef md_cons_align
12621 md_cons_align (nbytes);
12626 bfd_reloc_code_real_type reloc;
12628 expression (& exp);
12630 if (exp.X_op == O_symbol
12631 && * input_line_pointer == '('
12632 && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
12634 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
12635 int size = bfd_get_reloc_size (howto);
12638 as_bad ("%s relocations do not fit in %d bytes",
12639 howto->name, nbytes);
12642 register char *p = frag_more ((int) nbytes);
12643 int offset = nbytes - size;
12645 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
12650 emit_expr (&exp, (unsigned int) nbytes);
12652 while (*input_line_pointer++ == ',');
12654 /* Put terminator back into stream. */
12655 input_line_pointer --;
12656 demand_empty_rest_of_line ();
12659 #endif /* OBJ_ELF */
12661 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
12662 of an rs_align_code fragment. */
12665 arm_handle_align (fragP)
12668 static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
12669 static char const thumb_noop[2] = { 0xc0, 0x46 };
12670 static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
12671 static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
12673 int bytes, fix, noop_size;
12677 if (fragP->fr_type != rs_align_code)
12680 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
12681 p = fragP->fr_literal + fragP->fr_fix;
12684 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
12685 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
12687 if (fragP->tc_frag_data)
12689 if (target_big_endian)
12690 noop = thumb_bigend_noop;
12693 noop_size = sizeof (thumb_noop);
12697 if (target_big_endian)
12698 noop = arm_bigend_noop;
12701 noop_size = sizeof (arm_noop);
12704 if (bytes & (noop_size - 1))
12706 fix = bytes & (noop_size - 1);
12707 memset (p, 0, fix);
12712 while (bytes >= noop_size)
12714 memcpy (p, noop, noop_size);
12716 bytes -= noop_size;
12720 fragP->fr_fix += fix;
12721 fragP->fr_var = noop_size;
12724 /* Called from md_do_align. Used to create an alignment
12725 frag in a code section. */
12728 arm_frag_align_code (n, max)
12734 /* We assume that there will never be a requirment
12735 to support alignments greater than 32 bytes. */
12736 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
12737 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
12739 p = frag_var (rs_align_code,
12740 MAX_MEM_FOR_RS_ALIGN_CODE,
12742 (relax_substateT) max,
12750 /* Perform target specific initialisation of a frag. */
12753 arm_init_frag (fragP)
12756 /* Record whether this frag is in an ARM or a THUMB area. */
12757 fragP->tc_frag_data = thumb_mode;