1 /* tc-arm.c -- Assemble for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modified by David Taylor (dtaylor@armltd.co.uk)
6 Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
7 Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
8 Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
10 This file is part of GAS, the GNU Assembler.
12 GAS is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2, or (at your option)
17 GAS is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with GAS; see the file COPYING. If not, write to the Free
24 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
30 #include "safe-ctype.h"
32 /* Need TARGET_CPU. */
41 #include "dwarf2dbg.h"
44 /* XXX Set this to 1 after the next binutils release */
45 #define WARN_DEPRECATED 0
47 /* The following bitmasks control CPU extensions: */
48 #define ARM_EXT_V1 0x00000001 /* All processors (core set). */
49 #define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
50 #define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
51 #define ARM_EXT_V3 0x00000008 /* MSR MRS. */
52 #define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
53 #define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
54 #define ARM_EXT_V4T 0x00000040 /* Thumb v1. */
55 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
56 #define ARM_EXT_V5T 0x00000100 /* Thumb v2. */
57 #define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
58 #define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
59 #define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */
60 #define ARM_EXT_V6 0x00001000 /* ARM V6. */
62 /* Co-processor space extensions. */
63 #define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */
64 #define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. */
65 #define ARM_CEXT_IWMMXT 0x00200000 /* Intel Wireless MMX technology coprocessor. */
67 /* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
68 defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
69 ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
70 three more to cover cores prior to ARM6. Finally, there are cores which
71 implement further extensions in the co-processor space. */
72 #define ARM_ARCH_V1 ARM_EXT_V1
73 #define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)
74 #define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)
75 #define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)
76 #define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)
77 #define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)
78 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)
79 #define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)
80 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)
81 #define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)
82 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
83 #define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
84 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
85 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)
86 #define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)
87 #define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE | ARM_EXT_V5J)
88 #define ARM_ARCH_V6 (ARM_ARCH_V5TEJ | ARM_EXT_V6)
90 /* Processors with specific extensions in the co-processor space. */
91 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)
92 #define ARM_ARCH_IWMMXT (ARM_ARCH_XSCALE | ARM_CEXT_IWMMXT)
94 /* Some useful combinations: */
95 #define ARM_ANY 0x0000ffff /* Any basic core. */
96 #define ARM_ALL 0x00ffffff /* Any core + co-processor */
97 #define CPROC_ANY 0x00ff0000 /* Any co-processor */
98 #define FPU_ANY 0xff000000 /* Note this is ~ARM_ALL. */
101 #define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */
102 #define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */
103 #define FPU_VFP_EXT_NONE 0x20000000 /* Use VFP word-ordering. */
104 #define FPU_VFP_EXT_V1xD 0x10000000 /* Base VFP instruction set. */
105 #define FPU_VFP_EXT_V1 0x08000000 /* Double-precision insns. */
106 #define FPU_VFP_EXT_V2 0x04000000 /* ARM10E VFPr1. */
107 #define FPU_MAVERICK 0x02000000 /* Cirrus Maverick. */
110 #define FPU_ARCH_FPE FPU_FPA_EXT_V1
111 #define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
113 #define FPU_ARCH_VFP FPU_VFP_EXT_NONE
114 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
115 #define FPU_ARCH_VFP_V1 (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
116 #define FPU_ARCH_VFP_V2 (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
118 #define FPU_ARCH_MAVERICK FPU_MAVERICK
123 ARM_FLOAT_ABI_SOFTFP
,
127 /* Types of processor to assemble for. */
128 #define ARM_1 ARM_ARCH_V1
129 #define ARM_2 ARM_ARCH_V2
130 #define ARM_3 ARM_ARCH_V2S
131 #define ARM_250 ARM_ARCH_V2S
132 #define ARM_6 ARM_ARCH_V3
133 #define ARM_7 ARM_ARCH_V3
134 #define ARM_8 ARM_ARCH_V4
135 #define ARM_9 ARM_ARCH_V4T
136 #define ARM_STRONG ARM_ARCH_V4
137 #define ARM_CPU_MASK 0x0000000f /* XXX? */
140 #if defined __XSCALE__
141 #define CPU_DEFAULT (ARM_ARCH_XSCALE)
143 #if defined __thumb__
144 #define CPU_DEFAULT (ARM_ARCH_V5T)
146 #define CPU_DEFAULT ARM_ANY
152 #define FPU_DEFAULT FPU_ARCH_FPA
157 #define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, but VFP order. */
159 /* Legacy a.out format. */
160 #define FPU_DEFAULT FPU_ARCH_FPA /* Soft-float, but FPA order. */
164 /* For backwards compatibility we default to the FPA. */
166 #define FPU_DEFAULT FPU_ARCH_FPA
169 #define streq(a, b) (strcmp (a, b) == 0)
170 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
172 static unsigned long cpu_variant
;
173 static int target_oabi
= 0;
175 /* Flags stored in private area of BFD structure. */
176 static int uses_apcs_26
= FALSE
;
177 static int atpcs
= FALSE
;
178 static int support_interwork
= FALSE
;
179 static int uses_apcs_float
= FALSE
;
180 static int pic_code
= FALSE
;
182 /* Variables that we set while parsing command-line options. Once all
183 options have been read we re-process these values to set the real
185 static int legacy_cpu
= -1;
186 static int legacy_fpu
= -1;
188 static int mcpu_cpu_opt
= -1;
189 static int mcpu_fpu_opt
= -1;
190 static int march_cpu_opt
= -1;
191 static int march_fpu_opt
= -1;
192 static int mfpu_opt
= -1;
193 static int mfloat_abi_opt
= -1;
194 static int meabi_flags
= EF_ARM_EABI_UNKNOWN
;
196 /* This array holds the chars that always start a comment. If the
197 pre-processor is disabled, these aren't very useful. */
198 const char comment_chars
[] = "@";
200 /* This array holds the chars that only start a comment at the beginning of
201 a line. If the line seems to have the form '# 123 filename'
202 .line and .file directives will appear in the pre-processed output. */
203 /* Note that input_file.c hand checks for '#' at the beginning of the
204 first line of the input file. This is because the compiler outputs
205 #NO_APP at the beginning of its output. */
206 /* Also note that comments like this one will always work. */
207 const char line_comment_chars
[] = "#";
209 const char line_separator_chars
[] = ";";
211 /* Chars that can be used to separate mant
212 from exp in floating point numbers. */
213 const char EXP_CHARS
[] = "eE";
215 /* Chars that mean this number is a floating point constant. */
219 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
221 /* Prefix characters that indicate the start of an immediate
223 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
226 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
227 symbolS
* GOT_symbol
;
230 /* Size of relocation record. */
231 const int md_reloc_size
= 8;
233 /* 0: assemble for ARM,
234 1: assemble for Thumb,
235 2: assemble for Thumb even though target CPU does not support thumb
237 static int thumb_mode
= 0;
239 typedef struct arm_fix
247 unsigned long instruction
;
251 bfd_reloc_code_real_type type
;
268 struct asm_shift_properties
270 enum asm_shift_index index
;
271 unsigned long bit_field
;
272 unsigned int allows_0
: 1;
273 unsigned int allows_32
: 1;
276 static const struct asm_shift_properties shift_properties
[] =
278 { SHIFT_LSL
, 0, 1, 0},
279 { SHIFT_LSR
, 0x20, 0, 1},
280 { SHIFT_ASR
, 0x40, 0, 1},
281 { SHIFT_ROR
, 0x60, 0, 0},
282 { SHIFT_RRX
, 0x60, 0, 0}
285 struct asm_shift_name
288 const struct asm_shift_properties
* properties
;
291 static const struct asm_shift_name shift_names
[] =
293 { "asl", shift_properties
+ SHIFT_LSL
},
294 { "lsl", shift_properties
+ SHIFT_LSL
},
295 { "lsr", shift_properties
+ SHIFT_LSR
},
296 { "asr", shift_properties
+ SHIFT_ASR
},
297 { "ror", shift_properties
+ SHIFT_ROR
},
298 { "rrx", shift_properties
+ SHIFT_RRX
},
299 { "ASL", shift_properties
+ SHIFT_LSL
},
300 { "LSL", shift_properties
+ SHIFT_LSL
},
301 { "LSR", shift_properties
+ SHIFT_LSR
},
302 { "ASR", shift_properties
+ SHIFT_ASR
},
303 { "ROR", shift_properties
+ SHIFT_ROR
},
304 { "RRX", shift_properties
+ SHIFT_RRX
}
307 /* Any kind of shift is accepted. */
308 #define NO_SHIFT_RESTRICT 1
309 /* The shift operand must be an immediate value, not a register. */
310 #define SHIFT_IMMEDIATE 0
311 /* The shift must be LSL or ASR and the operand must be an immediate. */
312 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
313 /* The shift must be ASR and the operand must be an immediate. */
314 #define SHIFT_ASR_IMMEDIATE 3
315 /* The shift must be LSL and the operand must be an immediate. */
316 #define SHIFT_LSL_IMMEDIATE 4
318 #define NUM_FLOAT_VALS 8
320 const char * fp_const
[] =
322 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
325 /* Number of littlenums required to hold an extended precision number. */
326 #define MAX_LITTLENUMS 6
328 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
333 /* Whether a Co-processor load/store operation accepts write-back forms. */
342 #define CP_T_X 0x00008000
343 #define CP_T_Y 0x00400000
344 #define CP_T_Pre 0x01000000
345 #define CP_T_UD 0x00800000
346 #define CP_T_WB 0x00200000
348 #define CONDS_BIT 0x00100000
349 #define LOAD_BIT 0x00100000
351 #define DOUBLE_LOAD_FLAG 0x00000001
355 const char * template;
359 #define COND_ALWAYS 0xe0000000
360 #define COND_MASK 0xf0000000
362 static const struct asm_cond conds
[] =
366 {"cs", 0x20000000}, {"hs", 0x20000000},
367 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
384 const char *template;
389 /* The bit that distinguishes CPSR and SPSR. */
390 #define SPSR_BIT (1 << 22)
392 /* How many bits to shift the PSR_xxx bits up by. */
395 #define PSR_c (1 << 0)
396 #define PSR_x (1 << 1)
397 #define PSR_s (1 << 2)
398 #define PSR_f (1 << 3)
400 static const struct asm_psr psrs
[] =
402 {"CPSR", TRUE
, PSR_c
| PSR_f
},
403 {"CPSR_all", TRUE
, PSR_c
| PSR_f
},
404 {"SPSR", FALSE
, PSR_c
| PSR_f
},
405 {"SPSR_all", FALSE
, PSR_c
| PSR_f
},
406 {"CPSR_flg", TRUE
, PSR_f
},
407 {"CPSR_f", TRUE
, PSR_f
},
408 {"SPSR_flg", FALSE
, PSR_f
},
409 {"SPSR_f", FALSE
, PSR_f
},
410 {"CPSR_c", TRUE
, PSR_c
},
411 {"CPSR_ctl", TRUE
, PSR_c
},
412 {"SPSR_c", FALSE
, PSR_c
},
413 {"SPSR_ctl", FALSE
, PSR_c
},
414 {"CPSR_x", TRUE
, PSR_x
},
415 {"CPSR_s", TRUE
, PSR_s
},
416 {"SPSR_x", FALSE
, PSR_x
},
417 {"SPSR_s", FALSE
, PSR_s
},
418 /* Combinations of flags. */
419 {"CPSR_fs", TRUE
, PSR_f
| PSR_s
},
420 {"CPSR_fx", TRUE
, PSR_f
| PSR_x
},
421 {"CPSR_fc", TRUE
, PSR_f
| PSR_c
},
422 {"CPSR_sf", TRUE
, PSR_s
| PSR_f
},
423 {"CPSR_sx", TRUE
, PSR_s
| PSR_x
},
424 {"CPSR_sc", TRUE
, PSR_s
| PSR_c
},
425 {"CPSR_xf", TRUE
, PSR_x
| PSR_f
},
426 {"CPSR_xs", TRUE
, PSR_x
| PSR_s
},
427 {"CPSR_xc", TRUE
, PSR_x
| PSR_c
},
428 {"CPSR_cf", TRUE
, PSR_c
| PSR_f
},
429 {"CPSR_cs", TRUE
, PSR_c
| PSR_s
},
430 {"CPSR_cx", TRUE
, PSR_c
| PSR_x
},
431 {"CPSR_fsx", TRUE
, PSR_f
| PSR_s
| PSR_x
},
432 {"CPSR_fsc", TRUE
, PSR_f
| PSR_s
| PSR_c
},
433 {"CPSR_fxs", TRUE
, PSR_f
| PSR_x
| PSR_s
},
434 {"CPSR_fxc", TRUE
, PSR_f
| PSR_x
| PSR_c
},
435 {"CPSR_fcs", TRUE
, PSR_f
| PSR_c
| PSR_s
},
436 {"CPSR_fcx", TRUE
, PSR_f
| PSR_c
| PSR_x
},
437 {"CPSR_sfx", TRUE
, PSR_s
| PSR_f
| PSR_x
},
438 {"CPSR_sfc", TRUE
, PSR_s
| PSR_f
| PSR_c
},
439 {"CPSR_sxf", TRUE
, PSR_s
| PSR_x
| PSR_f
},
440 {"CPSR_sxc", TRUE
, PSR_s
| PSR_x
| PSR_c
},
441 {"CPSR_scf", TRUE
, PSR_s
| PSR_c
| PSR_f
},
442 {"CPSR_scx", TRUE
, PSR_s
| PSR_c
| PSR_x
},
443 {"CPSR_xfs", TRUE
, PSR_x
| PSR_f
| PSR_s
},
444 {"CPSR_xfc", TRUE
, PSR_x
| PSR_f
| PSR_c
},
445 {"CPSR_xsf", TRUE
, PSR_x
| PSR_s
| PSR_f
},
446 {"CPSR_xsc", TRUE
, PSR_x
| PSR_s
| PSR_c
},
447 {"CPSR_xcf", TRUE
, PSR_x
| PSR_c
| PSR_f
},
448 {"CPSR_xcs", TRUE
, PSR_x
| PSR_c
| PSR_s
},
449 {"CPSR_cfs", TRUE
, PSR_c
| PSR_f
| PSR_s
},
450 {"CPSR_cfx", TRUE
, PSR_c
| PSR_f
| PSR_x
},
451 {"CPSR_csf", TRUE
, PSR_c
| PSR_s
| PSR_f
},
452 {"CPSR_csx", TRUE
, PSR_c
| PSR_s
| PSR_x
},
453 {"CPSR_cxf", TRUE
, PSR_c
| PSR_x
| PSR_f
},
454 {"CPSR_cxs", TRUE
, PSR_c
| PSR_x
| PSR_s
},
455 {"CPSR_fsxc", TRUE
, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
456 {"CPSR_fscx", TRUE
, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
457 {"CPSR_fxsc", TRUE
, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
458 {"CPSR_fxcs", TRUE
, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
459 {"CPSR_fcsx", TRUE
, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
460 {"CPSR_fcxs", TRUE
, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
461 {"CPSR_sfxc", TRUE
, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
462 {"CPSR_sfcx", TRUE
, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
463 {"CPSR_sxfc", TRUE
, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
464 {"CPSR_sxcf", TRUE
, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
465 {"CPSR_scfx", TRUE
, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
466 {"CPSR_scxf", TRUE
, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
467 {"CPSR_xfsc", TRUE
, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
468 {"CPSR_xfcs", TRUE
, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
469 {"CPSR_xsfc", TRUE
, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
470 {"CPSR_xscf", TRUE
, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
471 {"CPSR_xcfs", TRUE
, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
472 {"CPSR_xcsf", TRUE
, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
473 {"CPSR_cfsx", TRUE
, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
474 {"CPSR_cfxs", TRUE
, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
475 {"CPSR_csfx", TRUE
, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
476 {"CPSR_csxf", TRUE
, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
477 {"CPSR_cxfs", TRUE
, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
478 {"CPSR_cxsf", TRUE
, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
479 {"SPSR_fs", FALSE
, PSR_f
| PSR_s
},
480 {"SPSR_fx", FALSE
, PSR_f
| PSR_x
},
481 {"SPSR_fc", FALSE
, PSR_f
| PSR_c
},
482 {"SPSR_sf", FALSE
, PSR_s
| PSR_f
},
483 {"SPSR_sx", FALSE
, PSR_s
| PSR_x
},
484 {"SPSR_sc", FALSE
, PSR_s
| PSR_c
},
485 {"SPSR_xf", FALSE
, PSR_x
| PSR_f
},
486 {"SPSR_xs", FALSE
, PSR_x
| PSR_s
},
487 {"SPSR_xc", FALSE
, PSR_x
| PSR_c
},
488 {"SPSR_cf", FALSE
, PSR_c
| PSR_f
},
489 {"SPSR_cs", FALSE
, PSR_c
| PSR_s
},
490 {"SPSR_cx", FALSE
, PSR_c
| PSR_x
},
491 {"SPSR_fsx", FALSE
, PSR_f
| PSR_s
| PSR_x
},
492 {"SPSR_fsc", FALSE
, PSR_f
| PSR_s
| PSR_c
},
493 {"SPSR_fxs", FALSE
, PSR_f
| PSR_x
| PSR_s
},
494 {"SPSR_fxc", FALSE
, PSR_f
| PSR_x
| PSR_c
},
495 {"SPSR_fcs", FALSE
, PSR_f
| PSR_c
| PSR_s
},
496 {"SPSR_fcx", FALSE
, PSR_f
| PSR_c
| PSR_x
},
497 {"SPSR_sfx", FALSE
, PSR_s
| PSR_f
| PSR_x
},
498 {"SPSR_sfc", FALSE
, PSR_s
| PSR_f
| PSR_c
},
499 {"SPSR_sxf", FALSE
, PSR_s
| PSR_x
| PSR_f
},
500 {"SPSR_sxc", FALSE
, PSR_s
| PSR_x
| PSR_c
},
501 {"SPSR_scf", FALSE
, PSR_s
| PSR_c
| PSR_f
},
502 {"SPSR_scx", FALSE
, PSR_s
| PSR_c
| PSR_x
},
503 {"SPSR_xfs", FALSE
, PSR_x
| PSR_f
| PSR_s
},
504 {"SPSR_xfc", FALSE
, PSR_x
| PSR_f
| PSR_c
},
505 {"SPSR_xsf", FALSE
, PSR_x
| PSR_s
| PSR_f
},
506 {"SPSR_xsc", FALSE
, PSR_x
| PSR_s
| PSR_c
},
507 {"SPSR_xcf", FALSE
, PSR_x
| PSR_c
| PSR_f
},
508 {"SPSR_xcs", FALSE
, PSR_x
| PSR_c
| PSR_s
},
509 {"SPSR_cfs", FALSE
, PSR_c
| PSR_f
| PSR_s
},
510 {"SPSR_cfx", FALSE
, PSR_c
| PSR_f
| PSR_x
},
511 {"SPSR_csf", FALSE
, PSR_c
| PSR_s
| PSR_f
},
512 {"SPSR_csx", FALSE
, PSR_c
| PSR_s
| PSR_x
},
513 {"SPSR_cxf", FALSE
, PSR_c
| PSR_x
| PSR_f
},
514 {"SPSR_cxs", FALSE
, PSR_c
| PSR_x
| PSR_s
},
515 {"SPSR_fsxc", FALSE
, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
516 {"SPSR_fscx", FALSE
, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
517 {"SPSR_fxsc", FALSE
, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
518 {"SPSR_fxcs", FALSE
, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
519 {"SPSR_fcsx", FALSE
, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
520 {"SPSR_fcxs", FALSE
, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
521 {"SPSR_sfxc", FALSE
, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
522 {"SPSR_sfcx", FALSE
, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
523 {"SPSR_sxfc", FALSE
, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
524 {"SPSR_sxcf", FALSE
, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
525 {"SPSR_scfx", FALSE
, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
526 {"SPSR_scxf", FALSE
, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
527 {"SPSR_xfsc", FALSE
, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
528 {"SPSR_xfcs", FALSE
, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
529 {"SPSR_xsfc", FALSE
, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
530 {"SPSR_xscf", FALSE
, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
531 {"SPSR_xcfs", FALSE
, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
532 {"SPSR_xcsf", FALSE
, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
533 {"SPSR_cfsx", FALSE
, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
534 {"SPSR_cfxs", FALSE
, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
535 {"SPSR_csfx", FALSE
, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
536 {"SPSR_csxf", FALSE
, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
537 {"SPSR_cxfs", FALSE
, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
538 {"SPSR_cxsf", FALSE
, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
545 IWMMXT_REG_WR_OR_WC
= 2,
549 enum iwmmxt_insn_type
572 VFP_REG_Dd
, VFP_REG_Dm
, VFP_REG_Dn
577 VFP_REG_Sd
, VFP_REG_Sm
, VFP_REG_Sn
582 VFP_LDSTMIA
, VFP_LDSTMDB
, VFP_LDSTMIAX
, VFP_LDSTMDBX
585 /* VFP system registers. */
592 static const struct vfp_reg vfp_regs
[] =
594 {"fpsid", 0x00000000},
595 {"FPSID", 0x00000000},
596 {"fpscr", 0x00010000},
597 {"FPSCR", 0x00010000},
598 {"fpexc", 0x00080000},
599 {"FPEXC", 0x00080000}
602 /* Structure for a hash table entry for a register. */
610 /* Some well known registers that we refer to directly elsewhere. */
615 #define wr_register(reg) ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
616 #define wc_register(reg) ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
617 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
619 /* These are the standard names. Users can add aliases with .req.
620 and delete them with .unreq. */
622 /* Integer Register Numbers. */
623 static const struct reg_entry rn_table
[] =
625 {"r0", 0, TRUE
}, {"r1", 1, TRUE
}, {"r2", 2, TRUE
}, {"r3", 3, TRUE
},
626 {"r4", 4, TRUE
}, {"r5", 5, TRUE
}, {"r6", 6, TRUE
}, {"r7", 7, TRUE
},
627 {"r8", 8, TRUE
}, {"r9", 9, TRUE
}, {"r10", 10, TRUE
}, {"r11", 11, TRUE
},
628 {"r12", 12, TRUE
}, {"r13", REG_SP
, TRUE
}, {"r14", REG_LR
, TRUE
}, {"r15", REG_PC
, TRUE
},
629 /* ATPCS Synonyms. */
630 {"a1", 0, TRUE
}, {"a2", 1, TRUE
}, {"a3", 2, TRUE
}, {"a4", 3, TRUE
},
631 {"v1", 4, TRUE
}, {"v2", 5, TRUE
}, {"v3", 6, TRUE
}, {"v4", 7, TRUE
},
632 {"v5", 8, TRUE
}, {"v6", 9, TRUE
}, {"v7", 10, TRUE
}, {"v8", 11, TRUE
},
633 /* Well-known aliases. */
634 {"wr", 7, TRUE
}, {"sb", 9, TRUE
}, {"sl", 10, TRUE
}, {"fp", 11, TRUE
},
635 {"ip", 12, TRUE
}, {"sp", REG_SP
, TRUE
}, {"lr", REG_LR
, TRUE
}, {"pc", REG_PC
, TRUE
},
639 #define WR_PREFIX 0x200
640 #define WC_PREFIX 0x400
642 static const struct reg_entry iwmmxt_table
[] =
644 /* Intel Wireless MMX technology register names. */
645 { "wr0", 0x0 | WR_PREFIX
, TRUE
}, {"wr1", 0x1 | WR_PREFIX
, TRUE
},
646 { "wr2", 0x2 | WR_PREFIX
, TRUE
}, {"wr3", 0x3 | WR_PREFIX
, TRUE
},
647 { "wr4", 0x4 | WR_PREFIX
, TRUE
}, {"wr5", 0x5 | WR_PREFIX
, TRUE
},
648 { "wr6", 0x6 | WR_PREFIX
, TRUE
}, {"wr7", 0x7 | WR_PREFIX
, TRUE
},
649 { "wr8", 0x8 | WR_PREFIX
, TRUE
}, {"wr9", 0x9 | WR_PREFIX
, TRUE
},
650 { "wr10", 0xa | WR_PREFIX
, TRUE
}, {"wr11", 0xb | WR_PREFIX
, TRUE
},
651 { "wr12", 0xc | WR_PREFIX
, TRUE
}, {"wr13", 0xd | WR_PREFIX
, TRUE
},
652 { "wr14", 0xe | WR_PREFIX
, TRUE
}, {"wr15", 0xf | WR_PREFIX
, TRUE
},
653 { "wcid", 0x0 | WC_PREFIX
, TRUE
}, {"wcon", 0x1 | WC_PREFIX
, TRUE
},
654 {"wcssf", 0x2 | WC_PREFIX
, TRUE
}, {"wcasf", 0x3 | WC_PREFIX
, TRUE
},
655 {"wcgr0", 0x8 | WC_PREFIX
, TRUE
}, {"wcgr1", 0x9 | WC_PREFIX
, TRUE
},
656 {"wcgr2", 0xa | WC_PREFIX
, TRUE
}, {"wcgr3", 0xb | WC_PREFIX
, TRUE
},
658 { "wR0", 0x0 | WR_PREFIX
, TRUE
}, {"wR1", 0x1 | WR_PREFIX
, TRUE
},
659 { "wR2", 0x2 | WR_PREFIX
, TRUE
}, {"wR3", 0x3 | WR_PREFIX
, TRUE
},
660 { "wR4", 0x4 | WR_PREFIX
, TRUE
}, {"wR5", 0x5 | WR_PREFIX
, TRUE
},
661 { "wR6", 0x6 | WR_PREFIX
, TRUE
}, {"wR7", 0x7 | WR_PREFIX
, TRUE
},
662 { "wR8", 0x8 | WR_PREFIX
, TRUE
}, {"wR9", 0x9 | WR_PREFIX
, TRUE
},
663 { "wR10", 0xa | WR_PREFIX
, TRUE
}, {"wR11", 0xb | WR_PREFIX
, TRUE
},
664 { "wR12", 0xc | WR_PREFIX
, TRUE
}, {"wR13", 0xd | WR_PREFIX
, TRUE
},
665 { "wR14", 0xe | WR_PREFIX
, TRUE
}, {"wR15", 0xf | WR_PREFIX
, TRUE
},
666 { "wCID", 0x0 | WC_PREFIX
, TRUE
}, {"wCon", 0x1 | WC_PREFIX
, TRUE
},
667 {"wCSSF", 0x2 | WC_PREFIX
, TRUE
}, {"wCASF", 0x3 | WC_PREFIX
, TRUE
},
668 {"wCGR0", 0x8 | WC_PREFIX
, TRUE
}, {"wCGR1", 0x9 | WC_PREFIX
, TRUE
},
669 {"wCGR2", 0xa | WC_PREFIX
, TRUE
}, {"wCGR3", 0xb | WC_PREFIX
, TRUE
},
673 /* Co-processor Numbers. */
674 static const struct reg_entry cp_table
[] =
676 {"p0", 0, TRUE
}, {"p1", 1, TRUE
}, {"p2", 2, TRUE
}, {"p3", 3, TRUE
},
677 {"p4", 4, TRUE
}, {"p5", 5, TRUE
}, {"p6", 6, TRUE
}, {"p7", 7, TRUE
},
678 {"p8", 8, TRUE
}, {"p9", 9, TRUE
}, {"p10", 10, TRUE
}, {"p11", 11, TRUE
},
679 {"p12", 12, TRUE
}, {"p13", 13, TRUE
}, {"p14", 14, TRUE
}, {"p15", 15, TRUE
},
683 /* Co-processor Register Numbers. */
684 static const struct reg_entry cn_table
[] =
686 {"c0", 0, TRUE
}, {"c1", 1, TRUE
}, {"c2", 2, TRUE
}, {"c3", 3, TRUE
},
687 {"c4", 4, TRUE
}, {"c5", 5, TRUE
}, {"c6", 6, TRUE
}, {"c7", 7, TRUE
},
688 {"c8", 8, TRUE
}, {"c9", 9, TRUE
}, {"c10", 10, TRUE
}, {"c11", 11, TRUE
},
689 {"c12", 12, TRUE
}, {"c13", 13, TRUE
}, {"c14", 14, TRUE
}, {"c15", 15, TRUE
},
690 /* Not really valid, but kept for back-wards compatibility. */
691 {"cr0", 0, TRUE
}, {"cr1", 1, TRUE
}, {"cr2", 2, TRUE
}, {"cr3", 3, TRUE
},
692 {"cr4", 4, TRUE
}, {"cr5", 5, TRUE
}, {"cr6", 6, TRUE
}, {"cr7", 7, TRUE
},
693 {"cr8", 8, TRUE
}, {"cr9", 9, TRUE
}, {"cr10", 10, TRUE
}, {"cr11", 11, TRUE
},
694 {"cr12", 12, TRUE
}, {"cr13", 13, TRUE
}, {"cr14", 14, TRUE
}, {"cr15", 15, TRUE
},
699 static const struct reg_entry fn_table
[] =
701 {"f0", 0, TRUE
}, {"f1", 1, TRUE
}, {"f2", 2, TRUE
}, {"f3", 3, TRUE
},
702 {"f4", 4, TRUE
}, {"f5", 5, TRUE
}, {"f6", 6, TRUE
}, {"f7", 7, TRUE
},
706 /* VFP SP Registers. */
707 static const struct reg_entry sn_table
[] =
709 {"s0", 0, TRUE
}, {"s1", 1, TRUE
}, {"s2", 2, TRUE
}, {"s3", 3, TRUE
},
710 {"s4", 4, TRUE
}, {"s5", 5, TRUE
}, {"s6", 6, TRUE
}, {"s7", 7, TRUE
},
711 {"s8", 8, TRUE
}, {"s9", 9, TRUE
}, {"s10", 10, TRUE
}, {"s11", 11, TRUE
},
712 {"s12", 12, TRUE
}, {"s13", 13, TRUE
}, {"s14", 14, TRUE
}, {"s15", 15, TRUE
},
713 {"s16", 16, TRUE
}, {"s17", 17, TRUE
}, {"s18", 18, TRUE
}, {"s19", 19, TRUE
},
714 {"s20", 20, TRUE
}, {"s21", 21, TRUE
}, {"s22", 22, TRUE
}, {"s23", 23, TRUE
},
715 {"s24", 24, TRUE
}, {"s25", 25, TRUE
}, {"s26", 26, TRUE
}, {"s27", 27, TRUE
},
716 {"s28", 28, TRUE
}, {"s29", 29, TRUE
}, {"s30", 30, TRUE
}, {"s31", 31, TRUE
},
720 /* VFP DP Registers. */
721 static const struct reg_entry dn_table
[] =
723 {"d0", 0, TRUE
}, {"d1", 1, TRUE
}, {"d2", 2, TRUE
}, {"d3", 3, TRUE
},
724 {"d4", 4, TRUE
}, {"d5", 5, TRUE
}, {"d6", 6, TRUE
}, {"d7", 7, TRUE
},
725 {"d8", 8, TRUE
}, {"d9", 9, TRUE
}, {"d10", 10, TRUE
}, {"d11", 11, TRUE
},
726 {"d12", 12, TRUE
}, {"d13", 13, TRUE
}, {"d14", 14, TRUE
}, {"d15", 15, TRUE
},
730 /* Maverick DSP coprocessor registers. */
731 static const struct reg_entry mav_mvf_table
[] =
733 {"mvf0", 0, TRUE
}, {"mvf1", 1, TRUE
}, {"mvf2", 2, TRUE
}, {"mvf3", 3, TRUE
},
734 {"mvf4", 4, TRUE
}, {"mvf5", 5, TRUE
}, {"mvf6", 6, TRUE
}, {"mvf7", 7, TRUE
},
735 {"mvf8", 8, TRUE
}, {"mvf9", 9, TRUE
}, {"mvf10", 10, TRUE
}, {"mvf11", 11, TRUE
},
736 {"mvf12", 12, TRUE
}, {"mvf13", 13, TRUE
}, {"mvf14", 14, TRUE
}, {"mvf15", 15, TRUE
},
740 static const struct reg_entry mav_mvd_table
[] =
742 {"mvd0", 0, TRUE
}, {"mvd1", 1, TRUE
}, {"mvd2", 2, TRUE
}, {"mvd3", 3, TRUE
},
743 {"mvd4", 4, TRUE
}, {"mvd5", 5, TRUE
}, {"mvd6", 6, TRUE
}, {"mvd7", 7, TRUE
},
744 {"mvd8", 8, TRUE
}, {"mvd9", 9, TRUE
}, {"mvd10", 10, TRUE
}, {"mvd11", 11, TRUE
},
745 {"mvd12", 12, TRUE
}, {"mvd13", 13, TRUE
}, {"mvd14", 14, TRUE
}, {"mvd15", 15, TRUE
},
749 static const struct reg_entry mav_mvfx_table
[] =
751 {"mvfx0", 0, TRUE
}, {"mvfx1", 1, TRUE
}, {"mvfx2", 2, TRUE
}, {"mvfx3", 3, TRUE
},
752 {"mvfx4", 4, TRUE
}, {"mvfx5", 5, TRUE
}, {"mvfx6", 6, TRUE
}, {"mvfx7", 7, TRUE
},
753 {"mvfx8", 8, TRUE
}, {"mvfx9", 9, TRUE
}, {"mvfx10", 10, TRUE
}, {"mvfx11", 11, TRUE
},
754 {"mvfx12", 12, TRUE
}, {"mvfx13", 13, TRUE
}, {"mvfx14", 14, TRUE
}, {"mvfx15", 15, TRUE
},
758 static const struct reg_entry mav_mvdx_table
[] =
760 {"mvdx0", 0, TRUE
}, {"mvdx1", 1, TRUE
}, {"mvdx2", 2, TRUE
}, {"mvdx3", 3, TRUE
},
761 {"mvdx4", 4, TRUE
}, {"mvdx5", 5, TRUE
}, {"mvdx6", 6, TRUE
}, {"mvdx7", 7, TRUE
},
762 {"mvdx8", 8, TRUE
}, {"mvdx9", 9, TRUE
}, {"mvdx10", 10, TRUE
}, {"mvdx11", 11, TRUE
},
763 {"mvdx12", 12, TRUE
}, {"mvdx13", 13, TRUE
}, {"mvdx14", 14, TRUE
}, {"mvdx15", 15, TRUE
},
767 static const struct reg_entry mav_mvax_table
[] =
769 {"mvax0", 0, TRUE
}, {"mvax1", 1, TRUE
}, {"mvax2", 2, TRUE
}, {"mvax3", 3, TRUE
},
773 static const struct reg_entry mav_dspsc_table
[] =
781 const struct reg_entry
*names
;
783 struct hash_control
*htab
;
784 const char *expected
;
787 struct reg_map all_reg_maps
[] =
789 {rn_table
, 15, NULL
, N_("ARM register expected")},
790 {cp_table
, 15, NULL
, N_("bad or missing co-processor number")},
791 {cn_table
, 15, NULL
, N_("co-processor register expected")},
792 {fn_table
, 7, NULL
, N_("FPA register expected")},
793 {sn_table
, 31, NULL
, N_("VFP single precision register expected")},
794 {dn_table
, 15, NULL
, N_("VFP double precision register expected")},
795 {mav_mvf_table
, 15, NULL
, N_("Maverick MVF register expected")},
796 {mav_mvd_table
, 15, NULL
, N_("Maverick MVD register expected")},
797 {mav_mvfx_table
, 15, NULL
, N_("Maverick MVFX register expected")},
798 {mav_mvdx_table
, 15, NULL
, N_("Maverick MVDX register expected")},
799 {mav_mvax_table
, 3, NULL
, N_("Maverick MVAX register expected")},
800 {mav_dspsc_table
, 0, NULL
, N_("Maverick DSPSC register expected")},
801 {iwmmxt_table
, 23, NULL
, N_("Intel Wireless MMX technology register expected")},
804 /* Enumeration matching entries in table above. */
808 #define REG_TYPE_FIRST REG_TYPE_RN
820 REG_TYPE_IWMMXT
= 12,
825 /* Functions called by parser. */
826 /* ARM instructions. */
827 static void do_arit
PARAMS ((char *));
828 static void do_cmp
PARAMS ((char *));
829 static void do_mov
PARAMS ((char *));
830 static void do_ldst
PARAMS ((char *));
831 static void do_ldstt
PARAMS ((char *));
832 static void do_ldmstm
PARAMS ((char *));
833 static void do_branch
PARAMS ((char *));
834 static void do_swi
PARAMS ((char *));
836 /* Pseudo Op codes. */
837 static void do_adr
PARAMS ((char *));
838 static void do_adrl
PARAMS ((char *));
839 static void do_empty
PARAMS ((char *));
842 static void do_mul
PARAMS ((char *));
843 static void do_mla
PARAMS ((char *));
846 static void do_swap
PARAMS ((char *));
849 static void do_msr
PARAMS ((char *));
850 static void do_mrs
PARAMS ((char *));
853 static void do_mull
PARAMS ((char *));
856 static void do_ldstv4
PARAMS ((char *));
859 static void do_bx
PARAMS ((char *));
862 static void do_blx
PARAMS ((char *));
863 static void do_bkpt
PARAMS ((char *));
864 static void do_clz
PARAMS ((char *));
865 static void do_lstc2
PARAMS ((char *));
866 static void do_cdp2
PARAMS ((char *));
867 static void do_co_reg2
PARAMS ((char *));
870 static void do_smla
PARAMS ((char *));
871 static void do_smlal
PARAMS ((char *));
872 static void do_smul
PARAMS ((char *));
873 static void do_qadd
PARAMS ((char *));
876 static void do_pld
PARAMS ((char *));
877 static void do_ldrd
PARAMS ((char *));
878 static void do_co_reg2c
PARAMS ((char *));
881 static void do_bxj
PARAMS ((char *));
884 static void do_cps
PARAMS ((char *));
885 static void do_cpsi
PARAMS ((char *));
886 static void do_ldrex
PARAMS ((char *));
887 static void do_pkhbt
PARAMS ((char *));
888 static void do_pkhtb
PARAMS ((char *));
889 static void do_qadd16
PARAMS ((char *));
890 static void do_rev
PARAMS ((char *));
891 static void do_rfe
PARAMS ((char *));
892 static void do_sxtah
PARAMS ((char *));
893 static void do_sxth
PARAMS ((char *));
894 static void do_setend
PARAMS ((char *));
895 static void do_smlad
PARAMS ((char *));
896 static void do_smlald
PARAMS ((char *));
897 static void do_smmul
PARAMS ((char *));
898 static void do_ssat
PARAMS ((char *));
899 static void do_usat
PARAMS ((char *));
900 static void do_srs
PARAMS ((char *));
901 static void do_ssat16
PARAMS ((char *));
902 static void do_usat16
PARAMS ((char *));
903 static void do_strex
PARAMS ((char *));
904 static void do_umaal
PARAMS ((char *));
906 static void do_cps_mode
PARAMS ((char **));
907 static void do_cps_flags
PARAMS ((char **, int));
908 static int do_endian_specifier
PARAMS ((char *));
909 static void do_pkh_core
PARAMS ((char *, int));
910 static void do_sat
PARAMS ((char **, int));
911 static void do_sat16
PARAMS ((char **, int));
913 /* Coprocessor Instructions. */
914 static void do_cdp
PARAMS ((char *));
915 static void do_lstc
PARAMS ((char *));
916 static void do_co_reg
PARAMS ((char *));
918 /* FPA instructions. */
919 static void do_fpa_ctrl
PARAMS ((char *));
920 static void do_fpa_ldst
PARAMS ((char *));
921 static void do_fpa_ldmstm
PARAMS ((char *));
922 static void do_fpa_dyadic
PARAMS ((char *));
923 static void do_fpa_monadic
PARAMS ((char *));
924 static void do_fpa_cmp
PARAMS ((char *));
925 static void do_fpa_from_reg
PARAMS ((char *));
926 static void do_fpa_to_reg
PARAMS ((char *));
928 /* VFP instructions. */
929 static void do_vfp_sp_monadic
PARAMS ((char *));
930 static void do_vfp_dp_monadic
PARAMS ((char *));
931 static void do_vfp_sp_dyadic
PARAMS ((char *));
932 static void do_vfp_dp_dyadic
PARAMS ((char *));
933 static void do_vfp_reg_from_sp
PARAMS ((char *));
934 static void do_vfp_sp_from_reg
PARAMS ((char *));
935 static void do_vfp_reg2_from_sp2
PARAMS ((char *));
936 static void do_vfp_sp2_from_reg2
PARAMS ((char *));
937 static void do_vfp_reg_from_dp
PARAMS ((char *));
938 static void do_vfp_reg2_from_dp
PARAMS ((char *));
939 static void do_vfp_dp_from_reg
PARAMS ((char *));
940 static void do_vfp_dp_from_reg2
PARAMS ((char *));
941 static void do_vfp_reg_from_ctrl
PARAMS ((char *));
942 static void do_vfp_ctrl_from_reg
PARAMS ((char *));
943 static void do_vfp_sp_ldst
PARAMS ((char *));
944 static void do_vfp_dp_ldst
PARAMS ((char *));
945 static void do_vfp_sp_ldstmia
PARAMS ((char *));
946 static void do_vfp_sp_ldstmdb
PARAMS ((char *));
947 static void do_vfp_dp_ldstmia
PARAMS ((char *));
948 static void do_vfp_dp_ldstmdb
PARAMS ((char *));
949 static void do_vfp_xp_ldstmia
PARAMS ((char *));
950 static void do_vfp_xp_ldstmdb
PARAMS ((char *));
951 static void do_vfp_sp_compare_z
PARAMS ((char *));
952 static void do_vfp_dp_compare_z
PARAMS ((char *));
953 static void do_vfp_dp_sp_cvt
PARAMS ((char *));
954 static void do_vfp_sp_dp_cvt
PARAMS ((char *));
957 static void do_xsc_mia
PARAMS ((char *));
958 static void do_xsc_mar
PARAMS ((char *));
959 static void do_xsc_mra
PARAMS ((char *));
962 static void do_mav_binops
PARAMS ((char *, int, enum arm_reg_type
,
964 static void do_mav_binops_1a
PARAMS ((char *));
965 static void do_mav_binops_1b
PARAMS ((char *));
966 static void do_mav_binops_1c
PARAMS ((char *));
967 static void do_mav_binops_1d
PARAMS ((char *));
968 static void do_mav_binops_1e
PARAMS ((char *));
969 static void do_mav_binops_1f
PARAMS ((char *));
970 static void do_mav_binops_1g
PARAMS ((char *));
971 static void do_mav_binops_1h
PARAMS ((char *));
972 static void do_mav_binops_1i
PARAMS ((char *));
973 static void do_mav_binops_1j
PARAMS ((char *));
974 static void do_mav_binops_1k
PARAMS ((char *));
975 static void do_mav_binops_1l
PARAMS ((char *));
976 static void do_mav_binops_1m
PARAMS ((char *));
977 static void do_mav_binops_1n
PARAMS ((char *));
978 static void do_mav_binops_1o
PARAMS ((char *));
979 static void do_mav_binops_2a
PARAMS ((char *));
980 static void do_mav_binops_2b
PARAMS ((char *));
981 static void do_mav_binops_2c
PARAMS ((char *));
982 static void do_mav_binops_3a
PARAMS ((char *));
983 static void do_mav_binops_3b
PARAMS ((char *));
984 static void do_mav_binops_3c
PARAMS ((char *));
985 static void do_mav_binops_3d
PARAMS ((char *));
986 static void do_mav_triple
PARAMS ((char *, int, enum arm_reg_type
,
989 static void do_mav_triple_4a
PARAMS ((char *));
990 static void do_mav_triple_4b
PARAMS ((char *));
991 static void do_mav_triple_5a
PARAMS ((char *));
992 static void do_mav_triple_5b
PARAMS ((char *));
993 static void do_mav_triple_5c
PARAMS ((char *));
994 static void do_mav_triple_5d
PARAMS ((char *));
995 static void do_mav_triple_5e
PARAMS ((char *));
996 static void do_mav_triple_5f
PARAMS ((char *));
997 static void do_mav_triple_5g
PARAMS ((char *));
998 static void do_mav_triple_5h
PARAMS ((char *));
999 static void do_mav_quad
PARAMS ((char *, int, enum arm_reg_type
,
1002 enum arm_reg_type
));
1003 static void do_mav_quad_6a
PARAMS ((char *));
1004 static void do_mav_quad_6b
PARAMS ((char *));
1005 static void do_mav_dspsc_1
PARAMS ((char *));
1006 static void do_mav_dspsc_2
PARAMS ((char *));
1007 static void do_mav_shift
PARAMS ((char *, enum arm_reg_type
,
1008 enum arm_reg_type
));
1009 static void do_mav_shift_1
PARAMS ((char *));
1010 static void do_mav_shift_2
PARAMS ((char *));
1011 static void do_mav_ldst
PARAMS ((char *, enum arm_reg_type
));
1012 static void do_mav_ldst_1
PARAMS ((char *));
1013 static void do_mav_ldst_2
PARAMS ((char *));
1014 static void do_mav_ldst_3
PARAMS ((char *));
1015 static void do_mav_ldst_4
PARAMS ((char *));
1017 static int mav_reg_required_here
PARAMS ((char **, int,
1018 enum arm_reg_type
));
1019 static int mav_parse_offset
PARAMS ((char **, int *));
1021 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*,
1023 static int arm_reg_parse
PARAMS ((char **, struct hash_control
*));
1024 static enum arm_reg_type arm_reg_parse_any
PARAMS ((char *));
1025 static const struct asm_psr
* arm_psr_parse
PARAMS ((char **));
1026 static void symbol_locate
PARAMS ((symbolS
*, const char *, segT
, valueT
,
1028 static int add_to_lit_pool
PARAMS ((void));
1029 static unsigned validate_immediate
PARAMS ((unsigned));
1030 static unsigned validate_immediate_twopart
PARAMS ((unsigned int,
1032 static int validate_offset_imm
PARAMS ((unsigned int, int));
1033 static void opcode_select
PARAMS ((int));
1034 static void end_of_line
PARAMS ((char *));
1035 static int reg_required_here
PARAMS ((char **, int));
1036 static int psr_required_here
PARAMS ((char **));
1037 static int co_proc_number
PARAMS ((char **));
1038 static int cp_opc_expr
PARAMS ((char **, int, int));
1039 static int cp_reg_required_here
PARAMS ((char **, int));
1040 static int fp_reg_required_here
PARAMS ((char **, int));
1041 static int vfp_sp_reg_required_here
PARAMS ((char **, enum vfp_sp_reg_pos
));
1042 static int vfp_dp_reg_required_here
PARAMS ((char **, enum vfp_dp_reg_pos
));
1043 static void vfp_sp_ldstm
PARAMS ((char *, enum vfp_ldstm_type
));
1044 static void vfp_dp_ldstm
PARAMS ((char *, enum vfp_ldstm_type
));
1045 static long vfp_sp_reg_list
PARAMS ((char **, enum vfp_sp_reg_pos
));
1046 static long vfp_dp_reg_list
PARAMS ((char **));
1047 static int vfp_psr_required_here
PARAMS ((char **str
));
1048 static const struct vfp_reg
*vfp_psr_parse
PARAMS ((char **str
));
1049 static int cp_address_offset
PARAMS ((char **));
1050 static int cp_address_required_here
PARAMS ((char **, int));
1051 static int my_get_float_expression
PARAMS ((char **));
1052 static int skip_past_comma
PARAMS ((char **));
1053 static int walk_no_bignums
PARAMS ((symbolS
*));
1054 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
1055 static int data_op2
PARAMS ((char **));
1056 static int fp_op2
PARAMS ((char **));
1057 static long reg_list
PARAMS ((char **));
1058 static void thumb_load_store
PARAMS ((char *, int, int));
1059 static int decode_shift
PARAMS ((char **, int));
1060 static int ldst_extend
PARAMS ((char **));
1061 static int ldst_extend_v4
PARAMS ((char **));
1062 static void thumb_add_sub
PARAMS ((char *, int));
1063 static void insert_reg
PARAMS ((const struct reg_entry
*,
1064 struct hash_control
*));
1065 static void thumb_shift
PARAMS ((char *, int));
1066 static void thumb_mov_compare
PARAMS ((char *, int));
1067 static void build_arm_ops_hsh
PARAMS ((void));
1068 static void set_constant_flonums
PARAMS ((void));
1069 static valueT md_chars_to_number
PARAMS ((char *, int));
1070 static void build_reg_hsh
PARAMS ((struct reg_map
*));
1071 static void insert_reg_alias
PARAMS ((char *, int, struct hash_control
*));
1072 static int create_register_alias
PARAMS ((char *, char *));
1073 static void output_inst
PARAMS ((const char *));
1074 static int accum0_required_here
PARAMS ((char **));
1075 static int ld_mode_required_here
PARAMS ((char **));
1076 static void do_branch25
PARAMS ((char *));
1077 static symbolS
* find_real_start
PARAMS ((symbolS
*));
1079 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
1082 static int wreg_required_here
PARAMS ((char **, int, enum wreg_type
));
1083 static void do_iwmmxt_byte_addr
PARAMS ((char *));
1084 static void do_iwmmxt_tandc
PARAMS ((char *));
1085 static void do_iwmmxt_tbcst
PARAMS ((char *));
1086 static void do_iwmmxt_textrc
PARAMS ((char *));
1087 static void do_iwmmxt_textrm
PARAMS ((char *));
1088 static void do_iwmmxt_tinsr
PARAMS ((char *));
1089 static void do_iwmmxt_tmcr
PARAMS ((char *));
1090 static void do_iwmmxt_tmcrr
PARAMS ((char *));
1091 static void do_iwmmxt_tmia
PARAMS ((char *));
1092 static void do_iwmmxt_tmovmsk
PARAMS ((char *));
1093 static void do_iwmmxt_tmrc
PARAMS ((char *));
1094 static void do_iwmmxt_tmrrc
PARAMS ((char *));
1095 static void do_iwmmxt_torc
PARAMS ((char *));
1096 static void do_iwmmxt_waligni
PARAMS ((char *));
1097 static void do_iwmmxt_wmov
PARAMS ((char *));
1098 static void do_iwmmxt_word_addr
PARAMS ((char *));
1099 static void do_iwmmxt_wrwr
PARAMS ((char *));
1100 static void do_iwmmxt_wrwrwcg
PARAMS ((char *));
1101 static void do_iwmmxt_wrwrwr
PARAMS ((char *));
1102 static void do_iwmmxt_wshufh
PARAMS ((char *));
1103 static void do_iwmmxt_wzero
PARAMS ((char *));
1104 static int cp_byte_address_offset
PARAMS ((char **));
1105 static int cp_byte_address_required_here
PARAMS ((char **));
1107 /* ARM instructions take 4bytes in the object file, Thumb instructions
1111 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
1112 #define MAV_MODE1 0x100c
1114 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
1115 #define MAV_MODE2 0x0c10
1117 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
1118 #define MAV_MODE3 0x100c
1120 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
1121 #define MAV_MODE4 0x0c0010
1123 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
1124 #define MAV_MODE5 0x00100c
1126 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
1127 #define MAV_MODE6 0x00100c05
1131 /* Basic string to match. */
1132 const char * template;
1134 /* Basic instruction code. */
1135 unsigned long value
;
1137 /* Offset into the template where the condition code (if any) will be.
1138 If zero, then the instruction is never conditional. */
1139 unsigned cond_offset
;
1141 /* Which architecture variant provides this instruction. */
1142 unsigned long variant
;
1144 /* Function to call to parse args. */
1145 void (* parms
) PARAMS ((char *));
1148 static const struct asm_opcode insns
[] =
1150 /* Core ARM Instructions. */
1151 {"and", 0xe0000000, 3, ARM_EXT_V1
, do_arit
},
1152 {"ands", 0xe0100000, 3, ARM_EXT_V1
, do_arit
},
1153 {"eor", 0xe0200000, 3, ARM_EXT_V1
, do_arit
},
1154 {"eors", 0xe0300000, 3, ARM_EXT_V1
, do_arit
},
1155 {"sub", 0xe0400000, 3, ARM_EXT_V1
, do_arit
},
1156 {"subs", 0xe0500000, 3, ARM_EXT_V1
, do_arit
},
1157 {"rsb", 0xe0600000, 3, ARM_EXT_V1
, do_arit
},
1158 {"rsbs", 0xe0700000, 3, ARM_EXT_V1
, do_arit
},
1159 {"add", 0xe0800000, 3, ARM_EXT_V1
, do_arit
},
1160 {"adds", 0xe0900000, 3, ARM_EXT_V1
, do_arit
},
1161 {"adc", 0xe0a00000, 3, ARM_EXT_V1
, do_arit
},
1162 {"adcs", 0xe0b00000, 3, ARM_EXT_V1
, do_arit
},
1163 {"sbc", 0xe0c00000, 3, ARM_EXT_V1
, do_arit
},
1164 {"sbcs", 0xe0d00000, 3, ARM_EXT_V1
, do_arit
},
1165 {"rsc", 0xe0e00000, 3, ARM_EXT_V1
, do_arit
},
1166 {"rscs", 0xe0f00000, 3, ARM_EXT_V1
, do_arit
},
1167 {"orr", 0xe1800000, 3, ARM_EXT_V1
, do_arit
},
1168 {"orrs", 0xe1900000, 3, ARM_EXT_V1
, do_arit
},
1169 {"bic", 0xe1c00000, 3, ARM_EXT_V1
, do_arit
},
1170 {"bics", 0xe1d00000, 3, ARM_EXT_V1
, do_arit
},
1172 {"tst", 0xe1100000, 3, ARM_EXT_V1
, do_cmp
},
1173 {"tsts", 0xe1100000, 3, ARM_EXT_V1
, do_cmp
},
1174 {"tstp", 0xe110f000, 3, ARM_EXT_V1
, do_cmp
},
1175 {"teq", 0xe1300000, 3, ARM_EXT_V1
, do_cmp
},
1176 {"teqs", 0xe1300000, 3, ARM_EXT_V1
, do_cmp
},
1177 {"teqp", 0xe130f000, 3, ARM_EXT_V1
, do_cmp
},
1178 {"cmp", 0xe1500000, 3, ARM_EXT_V1
, do_cmp
},
1179 {"cmps", 0xe1500000, 3, ARM_EXT_V1
, do_cmp
},
1180 {"cmpp", 0xe150f000, 3, ARM_EXT_V1
, do_cmp
},
1181 {"cmn", 0xe1700000, 3, ARM_EXT_V1
, do_cmp
},
1182 {"cmns", 0xe1700000, 3, ARM_EXT_V1
, do_cmp
},
1183 {"cmnp", 0xe170f000, 3, ARM_EXT_V1
, do_cmp
},
1185 {"mov", 0xe1a00000, 3, ARM_EXT_V1
, do_mov
},
1186 {"movs", 0xe1b00000, 3, ARM_EXT_V1
, do_mov
},
1187 {"mvn", 0xe1e00000, 3, ARM_EXT_V1
, do_mov
},
1188 {"mvns", 0xe1f00000, 3, ARM_EXT_V1
, do_mov
},
1190 {"ldr", 0xe4100000, 3, ARM_EXT_V1
, do_ldst
},
1191 {"ldrb", 0xe4500000, 3, ARM_EXT_V1
, do_ldst
},
1192 {"ldrt", 0xe4300000, 3, ARM_EXT_V1
, do_ldstt
},
1193 {"ldrbt", 0xe4700000, 3, ARM_EXT_V1
, do_ldstt
},
1194 {"str", 0xe4000000, 3, ARM_EXT_V1
, do_ldst
},
1195 {"strb", 0xe4400000, 3, ARM_EXT_V1
, do_ldst
},
1196 {"strt", 0xe4200000, 3, ARM_EXT_V1
, do_ldstt
},
1197 {"strbt", 0xe4600000, 3, ARM_EXT_V1
, do_ldstt
},
1199 {"stmia", 0xe8800000, 3, ARM_EXT_V1
, do_ldmstm
},
1200 {"stmib", 0xe9800000, 3, ARM_EXT_V1
, do_ldmstm
},
1201 {"stmda", 0xe8000000, 3, ARM_EXT_V1
, do_ldmstm
},
1202 {"stmdb", 0xe9000000, 3, ARM_EXT_V1
, do_ldmstm
},
1203 {"stmfd", 0xe9000000, 3, ARM_EXT_V1
, do_ldmstm
},
1204 {"stmfa", 0xe9800000, 3, ARM_EXT_V1
, do_ldmstm
},
1205 {"stmea", 0xe8800000, 3, ARM_EXT_V1
, do_ldmstm
},
1206 {"stmed", 0xe8000000, 3, ARM_EXT_V1
, do_ldmstm
},
1208 {"ldmia", 0xe8900000, 3, ARM_EXT_V1
, do_ldmstm
},
1209 {"ldmib", 0xe9900000, 3, ARM_EXT_V1
, do_ldmstm
},
1210 {"ldmda", 0xe8100000, 3, ARM_EXT_V1
, do_ldmstm
},
1211 {"ldmdb", 0xe9100000, 3, ARM_EXT_V1
, do_ldmstm
},
1212 {"ldmfd", 0xe8900000, 3, ARM_EXT_V1
, do_ldmstm
},
1213 {"ldmfa", 0xe8100000, 3, ARM_EXT_V1
, do_ldmstm
},
1214 {"ldmea", 0xe9100000, 3, ARM_EXT_V1
, do_ldmstm
},
1215 {"ldmed", 0xe9900000, 3, ARM_EXT_V1
, do_ldmstm
},
1217 {"swi", 0xef000000, 3, ARM_EXT_V1
, do_swi
},
1219 /* XXX This is the wrong place to do this. Think multi-arch. */
1220 {"bl", 0xeb000000, 2, ARM_EXT_V1
, do_branch
},
1221 {"b", 0xea000000, 1, ARM_EXT_V1
, do_branch
},
1223 {"bl", 0xebfffffe, 2, ARM_EXT_V1
, do_branch
},
1224 {"b", 0xeafffffe, 1, ARM_EXT_V1
, do_branch
},
1228 {"adr", 0xe28f0000, 3, ARM_EXT_V1
, do_adr
},
1229 {"adrl", 0xe28f0000, 3, ARM_EXT_V1
, do_adrl
},
1230 {"nop", 0xe1a00000, 3, ARM_EXT_V1
, do_empty
},
1232 /* ARM 2 multiplies. */
1233 {"mul", 0xe0000090, 3, ARM_EXT_V2
, do_mul
},
1234 {"muls", 0xe0100090, 3, ARM_EXT_V2
, do_mul
},
1235 {"mla", 0xe0200090, 3, ARM_EXT_V2
, do_mla
},
1236 {"mlas", 0xe0300090, 3, ARM_EXT_V2
, do_mla
},
1238 /* Generic coprocessor instructions. */
1239 {"cdp", 0xee000000, 3, ARM_EXT_V2
, do_cdp
},
1240 {"ldc", 0xec100000, 3, ARM_EXT_V2
, do_lstc
},
1241 {"ldcl", 0xec500000, 3, ARM_EXT_V2
, do_lstc
},
1242 {"stc", 0xec000000, 3, ARM_EXT_V2
, do_lstc
},
1243 {"stcl", 0xec400000, 3, ARM_EXT_V2
, do_lstc
},
1244 {"mcr", 0xee000010, 3, ARM_EXT_V2
, do_co_reg
},
1245 {"mrc", 0xee100010, 3, ARM_EXT_V2
, do_co_reg
},
1247 /* ARM 3 - swp instructions. */
1248 {"swp", 0xe1000090, 3, ARM_EXT_V2S
, do_swap
},
1249 {"swpb", 0xe1400090, 3, ARM_EXT_V2S
, do_swap
},
1251 /* ARM 6 Status register instructions. */
1252 {"mrs", 0xe10f0000, 3, ARM_EXT_V3
, do_mrs
},
1253 {"msr", 0xe120f000, 3, ARM_EXT_V3
, do_msr
},
1254 /* ScottB: our code uses 0xe128f000 for msr.
1255 NickC: but this is wrong because the bits 16 through 19 are
1256 handled by the PSR_xxx defines above. */
1258 /* ARM 7M long multiplies. */
1259 {"smull", 0xe0c00090, 5, ARM_EXT_V3M
, do_mull
},
1260 {"smulls", 0xe0d00090, 5, ARM_EXT_V3M
, do_mull
},
1261 {"umull", 0xe0800090, 5, ARM_EXT_V3M
, do_mull
},
1262 {"umulls", 0xe0900090, 5, ARM_EXT_V3M
, do_mull
},
1263 {"smlal", 0xe0e00090, 5, ARM_EXT_V3M
, do_mull
},
1264 {"smlals", 0xe0f00090, 5, ARM_EXT_V3M
, do_mull
},
1265 {"umlal", 0xe0a00090, 5, ARM_EXT_V3M
, do_mull
},
1266 {"umlals", 0xe0b00090, 5, ARM_EXT_V3M
, do_mull
},
1268 /* ARM Architecture 4. */
1269 {"ldrh", 0xe01000b0, 3, ARM_EXT_V4
, do_ldstv4
},
1270 {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4
, do_ldstv4
},
1271 {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4
, do_ldstv4
},
1272 {"strh", 0xe00000b0, 3, ARM_EXT_V4
, do_ldstv4
},
1274 /* ARM Architecture 4T. */
1275 /* Note: bx (and blx) are required on V5, even if the processor does
1276 not support Thumb. */
1277 {"bx", 0xe12fff10, 2, ARM_EXT_V4T
| ARM_EXT_V5
, do_bx
},
1279 /* ARM Architecture 5T. */
1280 /* Note: blx has 2 variants, so the .value is set dynamically.
1281 Only one of the variants has conditional execution. */
1282 {"blx", 0xe0000000, 3, ARM_EXT_V5
, do_blx
},
1283 {"clz", 0xe16f0f10, 3, ARM_EXT_V5
, do_clz
},
1284 {"bkpt", 0xe1200070, 0, ARM_EXT_V5
, do_bkpt
},
1285 {"ldc2", 0xfc100000, 0, ARM_EXT_V5
, do_lstc2
},
1286 {"ldc2l", 0xfc500000, 0, ARM_EXT_V5
, do_lstc2
},
1287 {"stc2", 0xfc000000, 0, ARM_EXT_V5
, do_lstc2
},
1288 {"stc2l", 0xfc400000, 0, ARM_EXT_V5
, do_lstc2
},
1289 {"cdp2", 0xfe000000, 0, ARM_EXT_V5
, do_cdp2
},
1290 {"mcr2", 0xfe000010, 0, ARM_EXT_V5
, do_co_reg2
},
1291 {"mrc2", 0xfe100010, 0, ARM_EXT_V5
, do_co_reg2
},
1293 /* ARM Architecture 5TExP. */
1294 {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP
, do_smla
},
1295 {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP
, do_smla
},
1296 {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP
, do_smla
},
1297 {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP
, do_smla
},
1299 {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP
, do_smla
},
1300 {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP
, do_smla
},
1302 {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP
, do_smlal
},
1303 {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP
, do_smlal
},
1304 {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP
, do_smlal
},
1305 {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP
, do_smlal
},
1307 {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP
, do_smul
},
1308 {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP
, do_smul
},
1309 {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP
, do_smul
},
1310 {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP
, do_smul
},
1312 {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP
, do_smul
},
1313 {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP
, do_smul
},
1315 {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP
, do_qadd
},
1316 {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP
, do_qadd
},
1317 {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP
, do_qadd
},
1318 {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP
, do_qadd
},
1320 /* ARM Architecture 5TE. */
1321 {"pld", 0xf450f000, 0, ARM_EXT_V5E
, do_pld
},
1322 {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E
, do_ldrd
},
1323 {"strd", 0xe00000f0, 3, ARM_EXT_V5E
, do_ldrd
},
1325 {"mcrr", 0xec400000, 4, ARM_EXT_V5E
, do_co_reg2c
},
1326 {"mrrc", 0xec500000, 4, ARM_EXT_V5E
, do_co_reg2c
},
1328 /* ARM Architecture 5TEJ. */
1329 {"bxj", 0xe12fff20, 3, ARM_EXT_V5J
, do_bxj
},
1332 { "cps", 0xf1020000, 0, ARM_EXT_V6
, do_cps
},
1333 { "cpsie", 0xf1080000, 0, ARM_EXT_V6
, do_cpsi
},
1334 { "cpsid", 0xf10C0000, 0, ARM_EXT_V6
, do_cpsi
},
1335 { "ldrex", 0xe1900f9f, 5, ARM_EXT_V6
, do_ldrex
},
1336 { "mcrr2", 0xfc400000, 0, ARM_EXT_V6
, do_co_reg2c
},
1337 { "mrrc2", 0xfc500000, 0, ARM_EXT_V6
, do_co_reg2c
},
1338 { "pkhbt", 0xe6800010, 5, ARM_EXT_V6
, do_pkhbt
},
1339 { "pkhtb", 0xe6800050, 5, ARM_EXT_V6
, do_pkhtb
},
1340 { "qadd16", 0xe6200f10, 6, ARM_EXT_V6
, do_qadd16
},
1341 { "qadd8", 0xe6200f90, 5, ARM_EXT_V6
, do_qadd16
},
1342 { "qaddsubx", 0xe6200f30, 8, ARM_EXT_V6
, do_qadd16
},
1343 { "qsub16", 0xe6200f70, 6, ARM_EXT_V6
, do_qadd16
},
1344 { "qsub8", 0xe6200ff0, 5, ARM_EXT_V6
, do_qadd16
},
1345 { "qsubaddx", 0xe6200f50, 8, ARM_EXT_V6
, do_qadd16
},
1346 { "sadd16", 0xe6100f10, 6, ARM_EXT_V6
, do_qadd16
},
1347 { "sadd8", 0xe6100f90, 5, ARM_EXT_V6
, do_qadd16
},
1348 { "saddsubx", 0xe6100f30, 8, ARM_EXT_V6
, do_qadd16
},
1349 { "shadd16", 0xe6300f10, 7, ARM_EXT_V6
, do_qadd16
},
1350 { "shadd8", 0xe6300f90, 6, ARM_EXT_V6
, do_qadd16
},
1351 { "shaddsubx", 0xe6300f30, 9, ARM_EXT_V6
, do_qadd16
},
1352 { "shsub16", 0xe6300f70, 7, ARM_EXT_V6
, do_qadd16
},
1353 { "shsub8", 0xe6300ff0, 6, ARM_EXT_V6
, do_qadd16
},
1354 { "shsubaddx", 0xe6300f50, 9, ARM_EXT_V6
, do_qadd16
},
1355 { "ssub16", 0xe6100f70, 6, ARM_EXT_V6
, do_qadd16
},
1356 { "ssub8", 0xe6100ff0, 5, ARM_EXT_V6
, do_qadd16
},
1357 { "ssubaddx", 0xe6100f50, 8, ARM_EXT_V6
, do_qadd16
},
1358 { "uadd16", 0xe6500f10, 6, ARM_EXT_V6
, do_qadd16
},
1359 { "uadd8", 0xe6500f90, 5, ARM_EXT_V6
, do_qadd16
},
1360 { "uaddsubx", 0xe6500f30, 8, ARM_EXT_V6
, do_qadd16
},
1361 { "uhadd16", 0xe6700f10, 7, ARM_EXT_V6
, do_qadd16
},
1362 { "uhadd8", 0xe6700f90, 6, ARM_EXT_V6
, do_qadd16
},
1363 { "uhaddsubx", 0xe6700f30, 9, ARM_EXT_V6
, do_qadd16
},
1364 { "uhsub16", 0xe6700f70, 7, ARM_EXT_V6
, do_qadd16
},
1365 { "uhsub8", 0xe6700ff0, 6, ARM_EXT_V6
, do_qadd16
},
1366 { "uhsubaddx", 0xe6700f50, 9, ARM_EXT_V6
, do_qadd16
},
1367 { "uqadd16", 0xe6600f10, 7, ARM_EXT_V6
, do_qadd16
},
1368 { "uqadd8", 0xe6600f90, 6, ARM_EXT_V6
, do_qadd16
},
1369 { "uqaddsubx", 0xe6600f30, 9, ARM_EXT_V6
, do_qadd16
},
1370 { "uqsub16", 0xe6600f70, 7, ARM_EXT_V6
, do_qadd16
},
1371 { "uqsub8", 0xe6600ff0, 6, ARM_EXT_V6
, do_qadd16
},
1372 { "uqsubaddx", 0xe6600f50, 9, ARM_EXT_V6
, do_qadd16
},
1373 { "usub16", 0xe6500f70, 6, ARM_EXT_V6
, do_qadd16
},
1374 { "usub8", 0xe6500ff0, 5, ARM_EXT_V6
, do_qadd16
},
1375 { "usubaddx", 0xe6500f50, 8, ARM_EXT_V6
, do_qadd16
},
1376 { "rev", 0xe6bf0f30, 3, ARM_EXT_V6
, do_rev
},
1377 { "rev16", 0xe6bf0fb0, 5, ARM_EXT_V6
, do_rev
},
1378 { "revsh", 0xe6ff0fb0, 5, ARM_EXT_V6
, do_rev
},
1379 { "rfeia", 0xf8900a00, 0, ARM_EXT_V6
, do_rfe
},
1380 { "rfeib", 0xf9900a00, 0, ARM_EXT_V6
, do_rfe
},
1381 { "rfeda", 0xf8100a00, 0, ARM_EXT_V6
, do_rfe
},
1382 { "rfedb", 0xf9100a00, 0, ARM_EXT_V6
, do_rfe
},
1383 { "rfefd", 0xf8900a00, 0, ARM_EXT_V6
, do_rfe
},
1384 { "rfefa", 0xf9900a00, 0, ARM_EXT_V6
, do_rfe
},
1385 { "rfeea", 0xf8100a00, 0, ARM_EXT_V6
, do_rfe
},
1386 { "rfeed", 0xf9100a00, 0, ARM_EXT_V6
, do_rfe
},
1387 { "sxtah", 0xe6b00070, 5, ARM_EXT_V6
, do_sxtah
},
1388 { "sxtab16", 0xe6800070, 7, ARM_EXT_V6
, do_sxtah
},
1389 { "sxtab", 0xe6a00070, 5, ARM_EXT_V6
, do_sxtah
},
1390 { "sxth", 0xe6bf0070, 4, ARM_EXT_V6
, do_sxth
},
1391 { "sxtb16", 0xe68f0070, 6, ARM_EXT_V6
, do_sxth
},
1392 { "sxtb", 0xe6af0070, 4, ARM_EXT_V6
, do_sxth
},
1393 { "uxtah", 0xe6f00070, 5, ARM_EXT_V6
, do_sxtah
},
1394 { "uxtab16", 0xe6c00070, 7, ARM_EXT_V6
, do_sxtah
},
1395 { "uxtab", 0xe6e00070, 5, ARM_EXT_V6
, do_sxtah
},
1396 { "uxth", 0xe6ff0070, 4, ARM_EXT_V6
, do_sxth
},
1397 { "uxtb16", 0xe6cf0070, 6, ARM_EXT_V6
, do_sxth
},
1398 { "uxtb", 0xe6ef0070, 4, ARM_EXT_V6
, do_sxth
},
1399 { "sel", 0xe68000b0, 3, ARM_EXT_V6
, do_qadd16
},
1400 { "setend", 0xf1010000, 0, ARM_EXT_V6
, do_setend
},
1401 { "smlad", 0xe7000010, 5, ARM_EXT_V6
, do_smlad
},
1402 { "smladx", 0xe7000030, 6, ARM_EXT_V6
, do_smlad
},
1403 { "smlald", 0xe7400010, 6, ARM_EXT_V6
, do_smlald
},
1404 { "smlaldx", 0xe7400030, 7, ARM_EXT_V6
, do_smlald
},
1405 { "smlsd", 0xe7000050, 5, ARM_EXT_V6
, do_smlad
},
1406 { "smlsdx", 0xe7000070, 6, ARM_EXT_V6
, do_smlad
},
1407 { "smlsld", 0xe7400050, 6, ARM_EXT_V6
, do_smlald
},
1408 { "smlsldx", 0xe7400070, 7, ARM_EXT_V6
, do_smlald
},
1409 { "smmla", 0xe7500010, 5, ARM_EXT_V6
, do_smlad
},
1410 { "smmlar", 0xe7500030, 6, ARM_EXT_V6
, do_smlad
},
1411 { "smmls", 0xe75000d0, 5, ARM_EXT_V6
, do_smlad
},
1412 { "smmlsr", 0xe75000f0, 6, ARM_EXT_V6
, do_smlad
},
1413 { "smmul", 0xe750f010, 5, ARM_EXT_V6
, do_smmul
},
1414 { "smmulr", 0xe750f030, 6, ARM_EXT_V6
, do_smmul
},
1415 { "smuad", 0xe700f010, 5, ARM_EXT_V6
, do_smmul
},
1416 { "smuadx", 0xe700f030, 6, ARM_EXT_V6
, do_smmul
},
1417 { "smusd", 0xe700f050, 5, ARM_EXT_V6
, do_smmul
},
1418 { "smusdx", 0xe700f070, 6, ARM_EXT_V6
, do_smmul
},
1419 { "srsia", 0xf8cd0500, 0, ARM_EXT_V6
, do_srs
},
1420 { "srsib", 0xf9cd0500, 0, ARM_EXT_V6
, do_srs
},
1421 { "srsda", 0xf84d0500, 0, ARM_EXT_V6
, do_srs
},
1422 { "srsdb", 0xf94d0500, 0, ARM_EXT_V6
, do_srs
},
1423 { "ssat", 0xe6a00010, 4, ARM_EXT_V6
, do_ssat
},
1424 { "ssat16", 0xe6a00f30, 6, ARM_EXT_V6
, do_ssat16
},
1425 { "strex", 0xe1800f90, 5, ARM_EXT_V6
, do_strex
},
1426 { "umaal", 0xe0400090, 5, ARM_EXT_V6
, do_umaal
},
1427 { "usad8", 0xe780f010, 5, ARM_EXT_V6
, do_smmul
},
1428 { "usada8", 0xe7800010, 6, ARM_EXT_V6
, do_smlad
},
1429 { "usat", 0xe6e00010, 4, ARM_EXT_V6
, do_usat
},
1430 { "usat16", 0xe6e00f30, 6, ARM_EXT_V6
, do_usat16
},
1432 /* Core FPA instruction set (V1). */
1433 {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1434 {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1435 {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1436 {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1438 {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1439 {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1440 {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1441 {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1443 {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1444 {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1445 {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1446 {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1448 {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1449 {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1450 {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1451 {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1452 {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1453 {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1454 {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1455 {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1456 {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1457 {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1458 {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1459 {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1461 {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1462 {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1463 {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1464 {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1465 {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1466 {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1467 {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1468 {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1469 {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1470 {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1471 {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1472 {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1474 {"abss", 0xee208100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1475 {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1476 {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1477 {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1478 {"absd", 0xee208180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1479 {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1480 {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1481 {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1482 {"abse", 0xee288100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1483 {"absep", 0xee288120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1484 {"absem", 0xee288140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1485 {"absez", 0xee288160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1487 {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1488 {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1489 {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1490 {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1491 {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1492 {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1493 {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1494 {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1495 {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1496 {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1497 {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1498 {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1500 {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1501 {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1502 {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1503 {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1504 {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1505 {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1506 {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1507 {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1508 {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1509 {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1510 {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1511 {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1513 {"logs", 0xee508100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1514 {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1515 {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1516 {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1517 {"logd", 0xee508180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1518 {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1519 {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1520 {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1521 {"loge", 0xee588100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1522 {"logep", 0xee588120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1523 {"logem", 0xee588140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1524 {"logez", 0xee588160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1526 {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1527 {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1528 {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1529 {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1530 {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1531 {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1532 {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1533 {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1534 {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1535 {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1536 {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1537 {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1539 {"exps", 0xee708100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1540 {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1541 {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1542 {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1543 {"expd", 0xee708180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1544 {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1545 {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1546 {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1547 {"expe", 0xee788100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1548 {"expep", 0xee788120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1549 {"expem", 0xee788140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1550 {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1552 {"sins", 0xee808100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1553 {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1554 {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1555 {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1556 {"sind", 0xee808180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1557 {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1558 {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1559 {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1560 {"sine", 0xee888100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1561 {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1562 {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1563 {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1565 {"coss", 0xee908100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1566 {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1567 {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1568 {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1569 {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1570 {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1571 {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1572 {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1573 {"cose", 0xee988100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1574 {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1575 {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1576 {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1578 {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1579 {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1580 {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1581 {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1582 {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1583 {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1584 {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1585 {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1586 {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1587 {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1588 {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1589 {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1591 {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1592 {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1593 {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1594 {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1595 {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1596 {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1597 {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1598 {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1599 {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1600 {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1601 {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1602 {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1604 {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1605 {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1606 {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1607 {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1608 {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1609 {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1610 {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1611 {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1612 {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1613 {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1614 {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1615 {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1617 {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1618 {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1619 {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1620 {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1621 {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1622 {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1623 {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1624 {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1625 {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1626 {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1627 {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1628 {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1630 {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1631 {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1632 {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1633 {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1634 {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1635 {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1636 {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1637 {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1638 {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1639 {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1640 {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1641 {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1643 {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1644 {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1645 {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1646 {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1647 {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1648 {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1649 {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1650 {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1651 {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1652 {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1653 {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1654 {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1656 {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1657 {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1658 {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1659 {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1660 {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1661 {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1662 {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1663 {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1664 {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1665 {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1666 {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1667 {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1669 {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1670 {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1671 {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1672 {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1673 {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1674 {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1675 {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1676 {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1677 {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1678 {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1679 {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1680 {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1682 {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1683 {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1684 {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1685 {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1686 {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1687 {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1688 {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1689 {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1690 {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1691 {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1692 {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1693 {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1695 {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1696 {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1697 {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1698 {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1699 {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1700 {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1701 {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1702 {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1703 {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1704 {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1705 {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1706 {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1708 {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1709 {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1710 {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1711 {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1712 {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1713 {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1714 {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1715 {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1716 {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1717 {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1718 {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1719 {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1721 {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1722 {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1723 {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1724 {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1725 {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1726 {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1727 {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1728 {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1729 {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1730 {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1731 {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1732 {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1734 {"pows", 0xee600100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1735 {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1736 {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1737 {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1738 {"powd", 0xee600180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1739 {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1740 {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1741 {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1742 {"powe", 0xee680100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1743 {"powep", 0xee680120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1744 {"powem", 0xee680140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1745 {"powez", 0xee680160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1747 {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1748 {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1749 {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1750 {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1751 {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1752 {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1753 {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1754 {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1755 {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1756 {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1757 {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1758 {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1760 {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1761 {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1762 {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1763 {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1764 {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1765 {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1766 {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1767 {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1768 {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1769 {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1770 {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1771 {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1773 {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1774 {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1775 {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1776 {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1777 {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1778 {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1779 {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1780 {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1781 {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1782 {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1783 {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1784 {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1786 {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1787 {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1788 {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1789 {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1790 {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1791 {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1792 {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1793 {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1794 {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1795 {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1796 {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1797 {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1799 {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1800 {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1801 {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1802 {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1803 {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1804 {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1805 {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1806 {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1807 {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1808 {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1809 {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1810 {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1812 {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1813 {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1814 {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1815 {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1816 {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1817 {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1818 {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1819 {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1820 {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1821 {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1822 {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1823 {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1825 {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1826 {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1827 {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1828 {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1829 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1830 not be an optional suffix, but part of the instruction. To be
1831 compatible, we accept either. */
1832 {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1833 {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1835 {"flts", 0xee000110, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1836 {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1837 {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1838 {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1839 {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1840 {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1841 {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1842 {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1843 {"flte", 0xee080110, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1844 {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1845 {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1846 {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1848 /* The implementation of the FIX instruction is broken on some
1849 assemblers, in that it accepts a precision specifier as well as a
1850 rounding specifier, despite the fact that this is meaningless.
1851 To be more compatible, we accept it as well, though of course it
1852 does not set any bits. */
1853 {"fix", 0xee100110, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1854 {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1855 {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1856 {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1857 {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1858 {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1859 {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1860 {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1861 {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1862 {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1863 {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1864 {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1865 {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1867 /* Instructions that were new with the real FPA, call them V2. */
1868 {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1869 {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1870 {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1871 {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1872 {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1873 {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1875 /* VFP V1xD (single precision). */
1876 /* Moves and type conversions. */
1877 {"fcpys", 0xeeb00a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1878 {"fmrs", 0xee100a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_reg_from_sp
},
1879 {"fmsr", 0xee000a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_sp_from_reg
},
1880 {"fmstat", 0xeef1fa10, 6, FPU_VFP_EXT_V1xD
, do_empty
},
1881 {"fsitos", 0xeeb80ac0, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1882 {"fuitos", 0xeeb80a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1883 {"ftosis", 0xeebd0a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1884 {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1885 {"ftouis", 0xeebc0a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1886 {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1887 {"fmrx", 0xeef00a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_reg_from_ctrl
},
1888 {"fmxr", 0xeee00a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_ctrl_from_reg
},
1890 /* Memory operations. */
1891 {"flds", 0xed100a00, 4, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldst
},
1892 {"fsts", 0xed000a00, 4, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldst
},
1893 {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1894 {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1895 {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1896 {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1897 {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1898 {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1899 {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1900 {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1901 {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1902 {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1903 {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1904 {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1905 {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1906 {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1907 {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1908 {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1910 /* Monadic operations. */
1911 {"fabss", 0xeeb00ac0, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1912 {"fnegs", 0xeeb10a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1913 {"fsqrts", 0xeeb10ac0, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1915 /* Dyadic operations. */
1916 {"fadds", 0xee300a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1917 {"fsubs", 0xee300a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1918 {"fmuls", 0xee200a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1919 {"fdivs", 0xee800a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1920 {"fmacs", 0xee000a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1921 {"fmscs", 0xee100a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1922 {"fnmuls", 0xee200a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1923 {"fnmacs", 0xee000a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1924 {"fnmscs", 0xee100a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1927 {"fcmps", 0xeeb40a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1928 {"fcmpzs", 0xeeb50a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_compare_z
},
1929 {"fcmpes", 0xeeb40ac0, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1930 {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_compare_z
},
1932 /* VFP V1 (Double precision). */
1933 /* Moves and type conversions. */
1934 {"fcpyd", 0xeeb00b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1935 {"fcvtds", 0xeeb70ac0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_sp_cvt
},
1936 {"fcvtsd", 0xeeb70bc0, 6, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1937 {"fmdhr", 0xee200b10, 5, FPU_VFP_EXT_V1
, do_vfp_dp_from_reg
},
1938 {"fmdlr", 0xee000b10, 5, FPU_VFP_EXT_V1
, do_vfp_dp_from_reg
},
1939 {"fmrdh", 0xee300b10, 5, FPU_VFP_EXT_V1
, do_vfp_reg_from_dp
},
1940 {"fmrdl", 0xee100b10, 5, FPU_VFP_EXT_V1
, do_vfp_reg_from_dp
},
1941 {"fsitod", 0xeeb80bc0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_sp_cvt
},
1942 {"fuitod", 0xeeb80b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_sp_cvt
},
1943 {"ftosid", 0xeebd0b40, 6, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1944 {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1945 {"ftouid", 0xeebc0b40, 6, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1946 {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1948 /* Memory operations. */
1949 {"fldd", 0xed100b00, 4, FPU_VFP_EXT_V1
, do_vfp_dp_ldst
},
1950 {"fstd", 0xed000b00, 4, FPU_VFP_EXT_V1
, do_vfp_dp_ldst
},
1951 {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1952 {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1953 {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1954 {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1955 {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1956 {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1957 {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1958 {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1960 /* Monadic operations. */
1961 {"fabsd", 0xeeb00bc0, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1962 {"fnegd", 0xeeb10b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1963 {"fsqrtd", 0xeeb10bc0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1965 /* Dyadic operations. */
1966 {"faddd", 0xee300b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1967 {"fsubd", 0xee300b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1968 {"fmuld", 0xee200b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1969 {"fdivd", 0xee800b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1970 {"fmacd", 0xee000b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1971 {"fmscd", 0xee100b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1972 {"fnmuld", 0xee200b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1973 {"fnmacd", 0xee000b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1974 {"fnmscd", 0xee100b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1977 {"fcmpd", 0xeeb40b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1978 {"fcmpzd", 0xeeb50b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_compare_z
},
1979 {"fcmped", 0xeeb40bc0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1980 {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1
, do_vfp_dp_compare_z
},
1983 {"fmsrr", 0xec400a10, 5, FPU_VFP_EXT_V2
, do_vfp_sp2_from_reg2
},
1984 {"fmrrs", 0xec500a10, 5, FPU_VFP_EXT_V2
, do_vfp_reg2_from_sp2
},
1985 {"fmdrr", 0xec400b10, 5, FPU_VFP_EXT_V2
, do_vfp_dp_from_reg2
},
1986 {"fmrrd", 0xec500b10, 5, FPU_VFP_EXT_V2
, do_vfp_reg2_from_dp
},
1988 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
1989 {"mia", 0xee200010, 3, ARM_CEXT_XSCALE
, do_xsc_mia
},
1990 {"miaph", 0xee280010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1991 {"miabb", 0xee2c0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1992 {"miabt", 0xee2d0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1993 {"miatb", 0xee2e0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1994 {"miatt", 0xee2f0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1995 {"mar", 0xec400000, 3, ARM_CEXT_XSCALE
, do_xsc_mar
},
1996 {"mra", 0xec500000, 3, ARM_CEXT_XSCALE
, do_xsc_mra
},
1998 /* Intel Wireless MMX technology instructions. */
1999 {"tandcb", 0xee130130, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tandc
},
2000 {"tandch", 0xee530130, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tandc
},
2001 {"tandcw", 0xee930130, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tandc
},
2002 {"tbcstb", 0xee400010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tbcst
},
2003 {"tbcsth", 0xee400050, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tbcst
},
2004 {"tbcstw", 0xee400090, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tbcst
},
2005 {"textrcb", 0xee130170, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_textrc
},
2006 {"textrch", 0xee530170, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_textrc
},
2007 {"textrcw", 0xee930170, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_textrc
},
2008 {"textrmub", 0xee100070, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2009 {"textrmuh", 0xee500070, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2010 {"textrmuw", 0xee900070, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2011 {"textrmsb", 0xee100078, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2012 {"textrmsh", 0xee500078, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2013 {"textrmsw", 0xee900078, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2014 {"tinsrb", 0xee600010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tinsr
},
2015 {"tinsrh", 0xee600050, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tinsr
},
2016 {"tinsrw", 0xee600090, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tinsr
},
2017 {"tmcr", 0xee000110, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_tmcr
},
2018 {"tmcrr", 0xec400000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_tmcrr
},
2019 {"tmia", 0xee200010, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2020 {"tmiaph", 0xee280010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2021 {"tmiabb", 0xee2c0010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2022 {"tmiabt", 0xee2d0010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2023 {"tmiatb", 0xee2e0010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2024 {"tmiatt", 0xee2f0010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2025 {"tmovmskb", 0xee100030, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_tmovmsk
},
2026 {"tmovmskh", 0xee500030, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_tmovmsk
},
2027 {"tmovmskw", 0xee900030, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_tmovmsk
},
2028 {"tmrc", 0xee100110, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_tmrc
},
2029 {"tmrrc", 0xec500000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_tmrrc
},
2030 {"torcb", 0xee130150, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_torc
},
2031 {"torch", 0xee530150, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_torc
},
2032 {"torcw", 0xee930150, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_torc
},
2033 {"waccb", 0xee0001c0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2034 {"wacch", 0xee4001c0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2035 {"waccw", 0xee8001c0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2036 {"waddbss", 0xee300180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2037 {"waddb", 0xee000180, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2038 {"waddbus", 0xee100180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2039 {"waddhss", 0xee700180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2040 {"waddh", 0xee400180, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2041 {"waddhus", 0xee500180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2042 {"waddwss", 0xeeb00180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2043 {"waddw", 0xee800180, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2044 {"waddwus", 0xee900180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2045 {"waligni", 0xee000020, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_waligni
},
2046 {"walignr0", 0xee800020, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2047 {"walignr1", 0xee900020, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2048 {"walignr2", 0xeea00020, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2049 {"walignr3", 0xeeb00020, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2050 {"wand", 0xee200000, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2051 {"wandn", 0xee300000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2052 {"wavg2b", 0xee800000, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2053 {"wavg2br", 0xee900000, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2054 {"wavg2h", 0xeec00000, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2055 {"wavg2hr", 0xeed00000, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2056 {"wcmpeqb", 0xee000060, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2057 {"wcmpeqh", 0xee400060, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2058 {"wcmpeqw", 0xee800060, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2059 {"wcmpgtub", 0xee100060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2060 {"wcmpgtuh", 0xee500060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2061 {"wcmpgtuw", 0xee900060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2062 {"wcmpgtsb", 0xee300060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2063 {"wcmpgtsh", 0xee700060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2064 {"wcmpgtsw", 0xeeb00060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2065 {"wldrb", 0xec100000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_byte_addr
},
2066 {"wldrh", 0xec100100, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_byte_addr
},
2067 {"wldrw", 0xec100200, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_word_addr
},
2068 {"wldrd", 0xec100300, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_word_addr
},
2069 {"wmacs", 0xee600100, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2070 {"wmacsz", 0xee700100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2071 {"wmacu", 0xee400100, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2072 {"wmacuz", 0xee500100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2073 {"wmadds", 0xeea00100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2074 {"wmaddu", 0xee800100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2075 {"wmaxsb", 0xee200160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2076 {"wmaxsh", 0xee600160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2077 {"wmaxsw", 0xeea00160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2078 {"wmaxub", 0xee000160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2079 {"wmaxuh", 0xee400160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2080 {"wmaxuw", 0xee800160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2081 {"wminsb", 0xee300160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2082 {"wminsh", 0xee700160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2083 {"wminsw", 0xeeb00160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2084 {"wminub", 0xee100160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2085 {"wminuh", 0xee500160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2086 {"wminuw", 0xee900160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2087 {"wmov", 0xee000000, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_wmov
},
2088 {"wmulsm", 0xee300100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2089 {"wmulsl", 0xee200100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2090 {"wmulum", 0xee100100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2091 {"wmulul", 0xee000100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2092 {"wor", 0xee000000, 3, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2093 {"wpackhss", 0xee700080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2094 {"wpackhus", 0xee500080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2095 {"wpackwss", 0xeeb00080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2096 {"wpackwus", 0xee900080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2097 {"wpackdss", 0xeef00080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2098 {"wpackdus", 0xeed00080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2099 {"wrorh", 0xee700040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2100 {"wrorhg", 0xee700148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2101 {"wrorw", 0xeeb00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2102 {"wrorwg", 0xeeb00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2103 {"wrord", 0xeef00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2104 {"wrordg", 0xeef00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2105 {"wsadb", 0xee000120, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2106 {"wsadbz", 0xee100120, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2107 {"wsadh", 0xee400120, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2108 {"wsadhz", 0xee500120, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2109 {"wshufh", 0xee0001e0, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wshufh
},
2110 {"wsllh", 0xee500040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2111 {"wsllhg", 0xee500148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2112 {"wsllw", 0xee900040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2113 {"wsllwg", 0xee900148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2114 {"wslld", 0xeed00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2115 {"wslldg", 0xeed00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2116 {"wsrah", 0xee400040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2117 {"wsrahg", 0xee400148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2118 {"wsraw", 0xee800040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2119 {"wsrawg", 0xee800148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2120 {"wsrad", 0xeec00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2121 {"wsradg", 0xeec00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2122 {"wsrlh", 0xee600040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2123 {"wsrlhg", 0xee600148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2124 {"wsrlw", 0xeea00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2125 {"wsrlwg", 0xeea00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2126 {"wsrld", 0xeee00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2127 {"wsrldg", 0xeee00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2128 {"wstrb", 0xec000000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_byte_addr
},
2129 {"wstrh", 0xec000100, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_byte_addr
},
2130 {"wstrw", 0xec000200, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_word_addr
},
2131 {"wstrd", 0xec000300, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_word_addr
},
2132 {"wsubbss", 0xee3001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2133 {"wsubb", 0xee0001a0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2134 {"wsubbus", 0xee1001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2135 {"wsubhss", 0xee7001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2136 {"wsubh", 0xee4001a0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2137 {"wsubhus", 0xee5001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2138 {"wsubwss", 0xeeb001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2139 {"wsubw", 0xee8001a0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2140 {"wsubwus", 0xee9001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2141 {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2142 {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2143 {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2144 {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2145 {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2146 {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2147 {"wunpckihb", 0xee1000c0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2148 {"wunpckihh", 0xee5000c0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2149 {"wunpckihw", 0xee9000c0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2150 {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2151 {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2152 {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2153 {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2154 {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2155 {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2156 {"wunpckilb", 0xee1000e0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2157 {"wunpckilh", 0xee5000e0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2158 {"wunpckilw", 0xee9000e0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2159 {"wxor", 0xee100000, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2160 {"wzero", 0xee300000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wzero
},
2162 /* Cirrus Maverick instructions. */
2163 {"cfldrs", 0xec100400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_1
},
2164 {"cfldrd", 0xec500400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_2
},
2165 {"cfldr32", 0xec100500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_3
},
2166 {"cfldr64", 0xec500500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_4
},
2167 {"cfstrs", 0xec000400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_1
},
2168 {"cfstrd", 0xec400400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_2
},
2169 {"cfstr32", 0xec000500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_3
},
2170 {"cfstr64", 0xec400500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_4
},
2171 {"cfmvsr", 0xee000450, 6, ARM_CEXT_MAVERICK
, do_mav_binops_2a
},
2172 {"cfmvrs", 0xee100450, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1a
},
2173 {"cfmvdlr", 0xee000410, 7, ARM_CEXT_MAVERICK
, do_mav_binops_2b
},
2174 {"cfmvrdl", 0xee100410, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1b
},
2175 {"cfmvdhr", 0xee000430, 7, ARM_CEXT_MAVERICK
, do_mav_binops_2b
},
2176 {"cfmvrdh", 0xee100430, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1b
},
2177 {"cfmv64lr", 0xee000510, 8, ARM_CEXT_MAVERICK
, do_mav_binops_2c
},
2178 {"cfmvr64l", 0xee100510, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1c
},
2179 {"cfmv64hr", 0xee000530, 8, ARM_CEXT_MAVERICK
, do_mav_binops_2c
},
2180 {"cfmvr64h", 0xee100530, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1c
},
2181 {"cfmval32", 0xee200440, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
2182 {"cfmv32al", 0xee100440, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
2183 {"cfmvam32", 0xee200460, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
2184 {"cfmv32am", 0xee100460, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
2185 {"cfmvah32", 0xee200480, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
2186 {"cfmv32ah", 0xee100480, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
2187 {"cfmva32", 0xee2004a0, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
2188 {"cfmv32a", 0xee1004a0, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
2189 {"cfmva64", 0xee2004c0, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3c
},
2190 {"cfmv64a", 0xee1004c0, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3d
},
2191 {"cfmvsc32", 0xee2004e0, 8, ARM_CEXT_MAVERICK
, do_mav_dspsc_1
},
2192 {"cfmv32sc", 0xee1004e0, 8, ARM_CEXT_MAVERICK
, do_mav_dspsc_2
},
2193 {"cfcpys", 0xee000400, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1d
},
2194 {"cfcpyd", 0xee000420, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1e
},
2195 {"cfcvtsd", 0xee000460, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1f
},
2196 {"cfcvtds", 0xee000440, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1g
},
2197 {"cfcvt32s", 0xee000480, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1h
},
2198 {"cfcvt32d", 0xee0004a0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1i
},
2199 {"cfcvt64s", 0xee0004c0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1j
},
2200 {"cfcvt64d", 0xee0004e0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1k
},
2201 {"cfcvts32", 0xee100580, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1l
},
2202 {"cfcvtd32", 0xee1005a0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1m
},
2203 {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK
, do_mav_binops_1l
},
2204 {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK
, do_mav_binops_1m
},
2205 {"cfrshl32", 0xee000550, 8, ARM_CEXT_MAVERICK
, do_mav_triple_4a
},
2206 {"cfrshl64", 0xee000570, 8, ARM_CEXT_MAVERICK
, do_mav_triple_4b
},
2207 {"cfsh32", 0xee000500, 6, ARM_CEXT_MAVERICK
, do_mav_shift_1
},
2208 {"cfsh64", 0xee200500, 6, ARM_CEXT_MAVERICK
, do_mav_shift_2
},
2209 {"cfcmps", 0xee100490, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5a
},
2210 {"cfcmpd", 0xee1004b0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5b
},
2211 {"cfcmp32", 0xee100590, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5c
},
2212 {"cfcmp64", 0xee1005b0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5d
},
2213 {"cfabss", 0xee300400, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1d
},
2214 {"cfabsd", 0xee300420, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1e
},
2215 {"cfnegs", 0xee300440, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1d
},
2216 {"cfnegd", 0xee300460, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1e
},
2217 {"cfadds", 0xee300480, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5e
},
2218 {"cfaddd", 0xee3004a0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5f
},
2219 {"cfsubs", 0xee3004c0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5e
},
2220 {"cfsubd", 0xee3004e0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5f
},
2221 {"cfmuls", 0xee100400, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5e
},
2222 {"cfmuld", 0xee100420, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5f
},
2223 {"cfabs32", 0xee300500, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1n
},
2224 {"cfabs64", 0xee300520, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1o
},
2225 {"cfneg32", 0xee300540, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1n
},
2226 {"cfneg64", 0xee300560, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1o
},
2227 {"cfadd32", 0xee300580, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
2228 {"cfadd64", 0xee3005a0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5h
},
2229 {"cfsub32", 0xee3005c0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
2230 {"cfsub64", 0xee3005e0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5h
},
2231 {"cfmul32", 0xee100500, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
2232 {"cfmul64", 0xee100520, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5h
},
2233 {"cfmac32", 0xee100540, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
2234 {"cfmsc32", 0xee100560, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
2235 {"cfmadd32", 0xee000600, 8, ARM_CEXT_MAVERICK
, do_mav_quad_6a
},
2236 {"cfmsub32", 0xee100600, 8, ARM_CEXT_MAVERICK
, do_mav_quad_6a
},
2237 {"cfmadda32", 0xee200600, 9, ARM_CEXT_MAVERICK
, do_mav_quad_6b
},
2238 {"cfmsuba32", 0xee300600, 9, ARM_CEXT_MAVERICK
, do_mav_quad_6b
},
2241 /* Defines for various bits that we will want to toggle. */
2242 #define INST_IMMEDIATE 0x02000000
2243 #define OFFSET_REG 0x02000000
2244 #define HWOFFSET_IMM 0x00400000
2245 #define SHIFT_BY_REG 0x00000010
2246 #define PRE_INDEX 0x01000000
2247 #define INDEX_UP 0x00800000
2248 #define WRITE_BACK 0x00200000
2249 #define LDM_TYPE_2_OR_3 0x00400000
2251 #define LITERAL_MASK 0xf000f000
2252 #define OPCODE_MASK 0xfe1fffff
2253 #define V4_STR_BIT 0x00000020
2255 #define DATA_OP_SHIFT 21
2257 /* Codes to distinguish the arithmetic instructions. */
2258 #define OPCODE_AND 0
2259 #define OPCODE_EOR 1
2260 #define OPCODE_SUB 2
2261 #define OPCODE_RSB 3
2262 #define OPCODE_ADD 4
2263 #define OPCODE_ADC 5
2264 #define OPCODE_SBC 6
2265 #define OPCODE_RSC 7
2266 #define OPCODE_TST 8
2267 #define OPCODE_TEQ 9
2268 #define OPCODE_CMP 10
2269 #define OPCODE_CMN 11
2270 #define OPCODE_ORR 12
2271 #define OPCODE_MOV 13
2272 #define OPCODE_BIC 14
2273 #define OPCODE_MVN 15
2275 /* Thumb v1 (ARMv4T). */
2276 static void do_t_nop
PARAMS ((char *));
2277 static void do_t_arit
PARAMS ((char *));
2278 static void do_t_add
PARAMS ((char *));
2279 static void do_t_asr
PARAMS ((char *));
2280 static void do_t_branch9
PARAMS ((char *));
2281 static void do_t_branch12
PARAMS ((char *));
2282 static void do_t_branch23
PARAMS ((char *));
2283 static void do_t_bx
PARAMS ((char *));
2284 static void do_t_compare
PARAMS ((char *));
2285 static void do_t_ldmstm
PARAMS ((char *));
2286 static void do_t_ldr
PARAMS ((char *));
2287 static void do_t_ldrb
PARAMS ((char *));
2288 static void do_t_ldrh
PARAMS ((char *));
2289 static void do_t_lds
PARAMS ((char *));
2290 static void do_t_lsl
PARAMS ((char *));
2291 static void do_t_lsr
PARAMS ((char *));
2292 static void do_t_mov
PARAMS ((char *));
2293 static void do_t_push_pop
PARAMS ((char *));
2294 static void do_t_str
PARAMS ((char *));
2295 static void do_t_strb
PARAMS ((char *));
2296 static void do_t_strh
PARAMS ((char *));
2297 static void do_t_sub
PARAMS ((char *));
2298 static void do_t_swi
PARAMS ((char *));
2299 static void do_t_adr
PARAMS ((char *));
2301 /* Thumb v2 (ARMv5T). */
2302 static void do_t_blx
PARAMS ((char *));
2303 static void do_t_bkpt
PARAMS ((char *));
2306 static void do_t_cps
PARAMS ((char *));
2307 static void do_t_cpy
PARAMS ((char *));
2308 static void do_t_setend
PARAMS ((char *));;
2310 #define T_OPCODE_MUL 0x4340
2311 #define T_OPCODE_TST 0x4200
2312 #define T_OPCODE_CMN 0x42c0
2313 #define T_OPCODE_NEG 0x4240
2314 #define T_OPCODE_MVN 0x43c0
2316 #define T_OPCODE_ADD_R3 0x1800
2317 #define T_OPCODE_SUB_R3 0x1a00
2318 #define T_OPCODE_ADD_HI 0x4400
2319 #define T_OPCODE_ADD_ST 0xb000
2320 #define T_OPCODE_SUB_ST 0xb080
2321 #define T_OPCODE_ADD_SP 0xa800
2322 #define T_OPCODE_ADD_PC 0xa000
2323 #define T_OPCODE_ADD_I8 0x3000
2324 #define T_OPCODE_SUB_I8 0x3800
2325 #define T_OPCODE_ADD_I3 0x1c00
2326 #define T_OPCODE_SUB_I3 0x1e00
2328 #define T_OPCODE_ASR_R 0x4100
2329 #define T_OPCODE_LSL_R 0x4080
2330 #define T_OPCODE_LSR_R 0x40c0
2331 #define T_OPCODE_ASR_I 0x1000
2332 #define T_OPCODE_LSL_I 0x0000
2333 #define T_OPCODE_LSR_I 0x0800
2335 #define T_OPCODE_MOV_I8 0x2000
2336 #define T_OPCODE_CMP_I8 0x2800
2337 #define T_OPCODE_CMP_LR 0x4280
2338 #define T_OPCODE_MOV_HR 0x4600
2339 #define T_OPCODE_CMP_HR 0x4500
2341 #define T_OPCODE_LDR_PC 0x4800
2342 #define T_OPCODE_LDR_SP 0x9800
2343 #define T_OPCODE_STR_SP 0x9000
2344 #define T_OPCODE_LDR_IW 0x6800
2345 #define T_OPCODE_STR_IW 0x6000
2346 #define T_OPCODE_LDR_IH 0x8800
2347 #define T_OPCODE_STR_IH 0x8000
2348 #define T_OPCODE_LDR_IB 0x7800
2349 #define T_OPCODE_STR_IB 0x7000
2350 #define T_OPCODE_LDR_RW 0x5800
2351 #define T_OPCODE_STR_RW 0x5000
2352 #define T_OPCODE_LDR_RH 0x5a00
2353 #define T_OPCODE_STR_RH 0x5200
2354 #define T_OPCODE_LDR_RB 0x5c00
2355 #define T_OPCODE_STR_RB 0x5400
2357 #define T_OPCODE_PUSH 0xb400
2358 #define T_OPCODE_POP 0xbc00
2360 #define T_OPCODE_BRANCH 0xe7fe
2362 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
2364 #define THUMB_SIZE 2 /* Size of thumb instruction. */
2365 #define THUMB_REG_LO 0x1
2366 #define THUMB_REG_HI 0x2
2367 #define THUMB_REG_ANY 0x3
2369 #define THUMB_H1 0x0080
2370 #define THUMB_H2 0x0040
2376 #define THUMB_MOVE 0
2377 #define THUMB_COMPARE 1
2380 #define THUMB_LOAD 0
2381 #define THUMB_STORE 1
2383 #define THUMB_PP_PC_LR 0x0100
2385 /* These three are used for immediate shifts, do not alter. */
2386 #define THUMB_WORD 2
2387 #define THUMB_HALFWORD 1
2388 #define THUMB_BYTE 0
2392 /* Basic string to match. */
2393 const char * template;
2395 /* Basic instruction code. */
2396 unsigned long value
;
2400 /* Which CPU variants this exists for. */
2401 unsigned long variant
;
2403 /* Function to call to parse args. */
2404 void (* parms
) PARAMS ((char *));
2407 static const struct thumb_opcode tinsns
[] =
2409 /* Thumb v1 (ARMv4T). */
2410 {"adc", 0x4140, 2, ARM_EXT_V4T
, do_t_arit
},
2411 {"add", 0x0000, 2, ARM_EXT_V4T
, do_t_add
},
2412 {"and", 0x4000, 2, ARM_EXT_V4T
, do_t_arit
},
2413 {"asr", 0x0000, 2, ARM_EXT_V4T
, do_t_asr
},
2414 {"b", T_OPCODE_BRANCH
, 2, ARM_EXT_V4T
, do_t_branch12
},
2415 {"beq", 0xd0fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2416 {"bne", 0xd1fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2417 {"bcs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2418 {"bhs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2419 {"bcc", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2420 {"bul", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2421 {"blo", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2422 {"bmi", 0xd4fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2423 {"bpl", 0xd5fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2424 {"bvs", 0xd6fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2425 {"bvc", 0xd7fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2426 {"bhi", 0xd8fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2427 {"bls", 0xd9fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2428 {"bge", 0xdafe, 2, ARM_EXT_V4T
, do_t_branch9
},
2429 {"blt", 0xdbfe, 2, ARM_EXT_V4T
, do_t_branch9
},
2430 {"bgt", 0xdcfe, 2, ARM_EXT_V4T
, do_t_branch9
},
2431 {"ble", 0xddfe, 2, ARM_EXT_V4T
, do_t_branch9
},
2432 {"bal", 0xdefe, 2, ARM_EXT_V4T
, do_t_branch9
},
2433 {"bic", 0x4380, 2, ARM_EXT_V4T
, do_t_arit
},
2434 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T
, do_t_branch23
},
2435 {"bx", 0x4700, 2, ARM_EXT_V4T
, do_t_bx
},
2436 {"cmn", T_OPCODE_CMN
, 2, ARM_EXT_V4T
, do_t_arit
},
2437 {"cmp", 0x0000, 2, ARM_EXT_V4T
, do_t_compare
},
2438 {"eor", 0x4040, 2, ARM_EXT_V4T
, do_t_arit
},
2439 {"ldmia", 0xc800, 2, ARM_EXT_V4T
, do_t_ldmstm
},
2440 {"ldr", 0x0000, 2, ARM_EXT_V4T
, do_t_ldr
},
2441 {"ldrb", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrb
},
2442 {"ldrh", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrh
},
2443 {"ldrsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
2444 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
2445 {"ldsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
2446 {"ldsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
2447 {"lsl", 0x0000, 2, ARM_EXT_V4T
, do_t_lsl
},
2448 {"lsr", 0x0000, 2, ARM_EXT_V4T
, do_t_lsr
},
2449 {"mov", 0x0000, 2, ARM_EXT_V4T
, do_t_mov
},
2450 {"mul", T_OPCODE_MUL
, 2, ARM_EXT_V4T
, do_t_arit
},
2451 {"mvn", T_OPCODE_MVN
, 2, ARM_EXT_V4T
, do_t_arit
},
2452 {"neg", T_OPCODE_NEG
, 2, ARM_EXT_V4T
, do_t_arit
},
2453 {"orr", 0x4300, 2, ARM_EXT_V4T
, do_t_arit
},
2454 {"pop", 0xbc00, 2, ARM_EXT_V4T
, do_t_push_pop
},
2455 {"push", 0xb400, 2, ARM_EXT_V4T
, do_t_push_pop
},
2456 {"ror", 0x41c0, 2, ARM_EXT_V4T
, do_t_arit
},
2457 {"sbc", 0x4180, 2, ARM_EXT_V4T
, do_t_arit
},
2458 {"stmia", 0xc000, 2, ARM_EXT_V4T
, do_t_ldmstm
},
2459 {"str", 0x0000, 2, ARM_EXT_V4T
, do_t_str
},
2460 {"strb", 0x0000, 2, ARM_EXT_V4T
, do_t_strb
},
2461 {"strh", 0x0000, 2, ARM_EXT_V4T
, do_t_strh
},
2462 {"swi", 0xdf00, 2, ARM_EXT_V4T
, do_t_swi
},
2463 {"sub", 0x0000, 2, ARM_EXT_V4T
, do_t_sub
},
2464 {"tst", T_OPCODE_TST
, 2, ARM_EXT_V4T
, do_t_arit
},
2466 {"adr", 0x0000, 2, ARM_EXT_V4T
, do_t_adr
},
2467 {"nop", 0x46C0, 2, ARM_EXT_V4T
, do_t_nop
}, /* mov r8,r8 */
2468 /* Thumb v2 (ARMv5T). */
2469 {"blx", 0, 0, ARM_EXT_V5T
, do_t_blx
},
2470 {"bkpt", 0xbe00, 2, ARM_EXT_V5T
, do_t_bkpt
},
2473 {"cpsie", 0xb660, 2, ARM_EXT_V6
, do_t_cps
},
2474 {"cpsid", 0xb670, 2, ARM_EXT_V6
, do_t_cps
},
2475 {"cpy", 0x4600, 2, ARM_EXT_V6
, do_t_cpy
},
2476 {"rev", 0xba00, 2, ARM_EXT_V6
, do_t_arit
},
2477 {"rev16", 0xba40, 2, ARM_EXT_V6
, do_t_arit
},
2478 {"revsh", 0xbac0, 2, ARM_EXT_V6
, do_t_arit
},
2479 {"setend", 0xb650, 2, ARM_EXT_V6
, do_t_setend
},
2480 {"sxth", 0xb200, 2, ARM_EXT_V6
, do_t_arit
},
2481 {"sxtb", 0xb240, 2, ARM_EXT_V6
, do_t_arit
},
2482 {"uxth", 0xb280, 2, ARM_EXT_V6
, do_t_arit
},
2483 {"uxtb", 0xb2c0, 2, ARM_EXT_V6
, do_t_arit
},
2486 #define BAD_ARGS _("bad arguments to instruction")
2487 #define BAD_PC _("r15 not allowed here")
2488 #define BAD_COND _("instruction is not conditional")
2489 #define ERR_NO_ACCUM _("acc0 expected")
2491 static struct hash_control
* arm_ops_hsh
= NULL
;
2492 static struct hash_control
* arm_tops_hsh
= NULL
;
2493 static struct hash_control
* arm_cond_hsh
= NULL
;
2494 static struct hash_control
* arm_shift_hsh
= NULL
;
2495 static struct hash_control
* arm_psr_hsh
= NULL
;
2497 /* This table describes all the machine specific pseudo-ops the assembler
2498 has to support. The fields are:
2499 pseudo-op name without dot
2500 function to call to execute this pseudo-op
2501 Integer arg to pass to the function. */
2503 static void s_req
PARAMS ((int));
2504 static void s_unreq
PARAMS ((int));
2505 static void s_align
PARAMS ((int));
2506 static void s_bss
PARAMS ((int));
2507 static void s_even
PARAMS ((int));
2508 static void s_ltorg
PARAMS ((int));
2509 static void s_arm
PARAMS ((int));
2510 static void s_thumb
PARAMS ((int));
2511 static void s_code
PARAMS ((int));
2512 static void s_force_thumb
PARAMS ((int));
2513 static void s_thumb_func
PARAMS ((int));
2514 static void s_thumb_set
PARAMS ((int));
2516 static void s_arm_elf_cons
PARAMS ((int));
2519 static int my_get_expression
PARAMS ((expressionS
*, char **));
2521 const pseudo_typeS md_pseudo_table
[] =
2523 /* Never called because '.req' does not start a line. */
2524 { "req", s_req
, 0 },
2525 { "unreq", s_unreq
, 0 },
2526 { "bss", s_bss
, 0 },
2527 { "align", s_align
, 0 },
2528 { "arm", s_arm
, 0 },
2529 { "thumb", s_thumb
, 0 },
2530 { "code", s_code
, 0 },
2531 { "force_thumb", s_force_thumb
, 0 },
2532 { "thumb_func", s_thumb_func
, 0 },
2533 { "thumb_set", s_thumb_set
, 0 },
2534 { "even", s_even
, 0 },
2535 { "ltorg", s_ltorg
, 0 },
2536 { "pool", s_ltorg
, 0 },
2538 { "word", s_arm_elf_cons
, 4 },
2539 { "long", s_arm_elf_cons
, 4 },
2543 { "extend", float_cons
, 'x' },
2544 { "ldouble", float_cons
, 'x' },
2545 { "packed", float_cons
, 'p' },
2549 /* Other internal functions. */
2550 static int arm_parse_extension
PARAMS ((char *, int *));
2551 static int arm_parse_cpu
PARAMS ((char *));
2552 static int arm_parse_arch
PARAMS ((char *));
2553 static int arm_parse_fpu
PARAMS ((char *));
2554 static int arm_parse_float_abi
PARAMS ((char *));
2555 static int arm_parse_eabi
PARAMS ((char *));
2556 #if 0 /* Suppressed - for now. */
2557 #if defined OBJ_COFF || defined OBJ_ELF
2558 static void arm_add_note
PARAMS ((const char *, const char *, unsigned int));
2562 /* Stuff needed to resolve the label ambiguity
2572 symbolS
* last_label_seen
;
2573 static int label_is_thumb_function_name
= FALSE
;
2575 /* Literal Pool stuff. */
2577 #define MAX_LITERAL_POOL_SIZE 1024
2579 /* Literal pool structure. Held on a per-section
2580 and per-sub-section basis. */
2581 typedef struct literal_pool
2583 expressionS literals
[MAX_LITERAL_POOL_SIZE
];
2584 unsigned int next_free_entry
;
2588 subsegT sub_section
;
2589 struct literal_pool
* next
;
2592 /* Pointer to a linked list of literal pools. */
2593 literal_pool
* list_of_pools
= NULL
;
2595 static literal_pool
* find_literal_pool
PARAMS ((void));
2596 static literal_pool
* find_or_make_literal_pool
PARAMS ((void));
2598 static literal_pool
*
2599 find_literal_pool ()
2601 literal_pool
* pool
;
2603 for (pool
= list_of_pools
; pool
!= NULL
; pool
= pool
->next
)
2605 if (pool
->section
== now_seg
2606 && pool
->sub_section
== now_subseg
)
2613 static literal_pool
*
2614 find_or_make_literal_pool ()
2616 /* Next literal pool ID number. */
2617 static unsigned int latest_pool_num
= 1;
2618 literal_pool
* pool
;
2620 pool
= find_literal_pool ();
2624 /* Create a new pool. */
2625 pool
= (literal_pool
*) xmalloc (sizeof (* pool
));
2629 pool
->next_free_entry
= 0;
2630 pool
->section
= now_seg
;
2631 pool
->sub_section
= now_subseg
;
2632 pool
->next
= list_of_pools
;
2633 pool
->symbol
= NULL
;
2635 /* Add it to the list. */
2636 list_of_pools
= pool
;
2639 /* New pools, and emptied pools, will have a NULL symbol. */
2640 if (pool
->symbol
== NULL
)
2642 pool
->symbol
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
2643 (valueT
) 0, &zero_address_frag
);
2644 pool
->id
= latest_pool_num
++;
2651 /* Add the literal in the global 'inst'
2652 structure to the relevent literal pool. */
2656 literal_pool
* pool
;
2659 pool
= find_or_make_literal_pool ();
2661 /* Check if this literal value is already in the pool. */
2662 for (entry
= 0; entry
< pool
->next_free_entry
; entry
++)
2664 if ((pool
->literals
[entry
].X_op
== inst
.reloc
.exp
.X_op
)
2665 && (inst
.reloc
.exp
.X_op
== O_constant
)
2666 && (pool
->literals
[entry
].X_add_number
2667 == inst
.reloc
.exp
.X_add_number
)
2668 && (pool
->literals
[entry
].X_unsigned
2669 == inst
.reloc
.exp
.X_unsigned
))
2672 if ((pool
->literals
[entry
].X_op
== inst
.reloc
.exp
.X_op
)
2673 && (inst
.reloc
.exp
.X_op
== O_symbol
)
2674 && (pool
->literals
[entry
].X_add_number
2675 == inst
.reloc
.exp
.X_add_number
)
2676 && (pool
->literals
[entry
].X_add_symbol
2677 == inst
.reloc
.exp
.X_add_symbol
)
2678 && (pool
->literals
[entry
].X_op_symbol
2679 == inst
.reloc
.exp
.X_op_symbol
))
2683 /* Do we need to create a new entry? */
2684 if (entry
== pool
->next_free_entry
)
2686 if (entry
>= MAX_LITERAL_POOL_SIZE
)
2688 inst
.error
= _("literal pool overflow");
2692 pool
->literals
[entry
] = inst
.reloc
.exp
;
2693 pool
->next_free_entry
+= 1;
2696 inst
.reloc
.exp
.X_op
= O_symbol
;
2697 inst
.reloc
.exp
.X_add_number
= ((int) entry
) * 4 - 8;
2698 inst
.reloc
.exp
.X_add_symbol
= pool
->symbol
;
2703 /* Can't use symbol_new here, so have to create a symbol and then at
2704 a later date assign it a value. Thats what these functions do. */
2707 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
2709 const char * name
; /* It is copied, the caller can modify. */
2710 segT segment
; /* Segment identifier (SEG_<something>). */
2711 valueT valu
; /* Symbol value. */
2712 fragS
* frag
; /* Associated fragment. */
2714 unsigned int name_length
;
2715 char * preserved_copy_of_name
;
2717 name_length
= strlen (name
) + 1; /* +1 for \0. */
2718 obstack_grow (¬es
, name
, name_length
);
2719 preserved_copy_of_name
= obstack_finish (¬es
);
2720 #ifdef STRIP_UNDERSCORE
2721 if (preserved_copy_of_name
[0] == '_')
2722 preserved_copy_of_name
++;
2725 #ifdef tc_canonicalize_symbol_name
2726 preserved_copy_of_name
=
2727 tc_canonicalize_symbol_name (preserved_copy_of_name
);
2730 S_SET_NAME (symbolP
, preserved_copy_of_name
);
2732 S_SET_SEGMENT (symbolP
, segment
);
2733 S_SET_VALUE (symbolP
, valu
);
2734 symbol_clear_list_pointers (symbolP
);
2736 symbol_set_frag (symbolP
, frag
);
2738 /* Link to end of symbol chain. */
2740 extern int symbol_table_frozen
;
2741 if (symbol_table_frozen
)
2745 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
2747 obj_symbol_new_hook (symbolP
);
2749 #ifdef tc_symbol_new_hook
2750 tc_symbol_new_hook (symbolP
);
2754 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
2755 #endif /* DEBUG_SYMS */
2758 /* Check that an immediate is valid.
2759 If so, convert it to the right format. */
2762 validate_immediate (val
)
2768 #define rotate_left(v, n) (v << n | v >> (32 - n))
2770 for (i
= 0; i
< 32; i
+= 2)
2771 if ((a
= rotate_left (val
, i
)) <= 0xff)
2772 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
2777 /* Check to see if an immediate can be computed as two separate immediate
2778 values, added together. We already know that this value cannot be
2779 computed by just one ARM instruction. */
2782 validate_immediate_twopart (val
, highpart
)
2784 unsigned int * highpart
;
2789 for (i
= 0; i
< 32; i
+= 2)
2790 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
2796 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
2798 else if (a
& 0xff0000)
2802 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
2806 assert (a
& 0xff000000);
2807 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
2810 return (a
& 0xff) | (i
<< 7);
2817 validate_offset_imm (val
, hwse
)
2821 if ((hwse
&& val
> 255) || val
> 4095)
2835 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
2836 (This text is taken from version B-02 of the spec):
2838 4.4.7 Mapping and tagging symbols
2840 A section of an ARM ELF file can contain a mixture of ARM code,
2841 Thumb code, and data. There are inline transitions between code
2842 and data at literal pool boundaries. There can also be inline
2843 transitions between ARM code and Thumb code, for example in
2844 ARM-Thumb inter-working veneers. Linkers, machine-level
2845 debuggers, profiling tools, and disassembly tools need to map
2846 images accurately. For example, setting an ARM breakpoint on a
2847 Thumb location, or in a literal pool, can crash the program
2848 being debugged, ruining the debugging session.
2850 ARM ELF entities are mapped (see section 4.4.7.1 below) and
2851 tagged (see section 4.4.7.2 below) using local symbols (with
2852 binding STB_LOCAL). To assist consumers, mapping and tagging
2853 symbols should be collated first in the symbol table, before
2854 other symbols with binding STB_LOCAL.
2856 To allow properly collated mapping and tagging symbols to be
2857 skipped by consumers that have no interest in them, the first
2858 such symbol should have the name $m and its st_value field equal
2859 to the total number of mapping and tagging symbols (including
2860 the $m) in the symbol table.
2862 4.4.7.1 Mapping symbols
2864 $a Labels the first byte of a sequence of ARM instructions.
2865 Its type is STT_FUNC.
2867 $d Labels the first byte of a sequence of data items.
2868 Its type is STT_OBJECT.
2870 $t Labels the first byte of a sequence of Thumb instructions.
2871 Its type is STT_FUNC.
2873 This list of mapping symbols may be extended in the future.
2875 Section-relative mapping symbols
2877 Mapping symbols defined in a section define a sequence of
2878 half-open address intervals that cover the address range of the
2879 section. Each interval starts at the address defined by a
2880 mapping symbol, and continues up to, but not including, the
2881 address defined by the next (in address order) mapping symbol or
2882 the end of the section. A corollary is that there must be a
2883 mapping symbol defined at the beginning of each section.
2884 Consumers can ignore the size of a section-relative mapping
2885 symbol. Producers can set it to 0.
2887 Absolute mapping symbols
2889 Because of the need to crystallize a Thumb address with the
2890 Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
2891 STT_FUNC defined in section SHN_ABS) need to be mapped with $a
2894 The extent of a mapping symbol defined in SHN_ABS is [st_value,
2895 st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
2896 where [x, y) denotes the half-open address range from x,
2897 inclusive, to y, exclusive.
2899 In the absence of a mapping symbol, a consumer can interpret a
2900 function symbol with an odd value as the Thumb code address
2901 obtained by clearing the least significant bit of the
2902 value. This interpretation is deprecated, and it may not work in
2905 Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
2906 the EABI (which is still under development), so they are not
2907 implemented here. */
2910 mapping_state (enum mstate state
)
2912 static enum mstate mapstate
= MAP_DATA
;
2914 const char * symname
;
2917 if (mapstate
== state
)
2918 /* The mapping symbol has already been emitted.
2919 There is nothing else to do. */
2932 type
= BSF_FUNCTION
;
2936 type
= BSF_FUNCTION
;
2942 symbolP
= symbol_new (symname
, now_seg
, (valueT
) frag_now_fix (), frag_now
);
2943 symbol_table_insert (symbolP
);
2944 symbol_get_bfdsym (symbolP
)->flags
|= type
| BSF_LOCAL
;
2949 THUMB_SET_FUNC (symbolP
, 0);
2950 ARM_SET_THUMB (symbolP
, 0);
2951 ARM_SET_INTERWORK (symbolP
, support_interwork
);
2955 THUMB_SET_FUNC (symbolP
, 1);
2956 ARM_SET_THUMB (symbolP
, 1);
2957 ARM_SET_INTERWORK (symbolP
, support_interwork
);
2966 /* When we change sections we need to issue a new mapping symbol. */
2969 arm_elf_change_section (void)
2973 if (!SEG_NORMAL (now_seg
))
2976 flags
= bfd_get_section_flags (stdoutput
, now_seg
);
2978 /* We can ignore sections that only contain debug info. */
2979 if ((flags
& SEC_ALLOC
) == 0)
2982 if (flags
& SEC_CODE
)
2985 mapping_state (MAP_THUMB
);
2987 mapping_state (MAP_ARM
);
2990 /* This section does not contain code. Therefore it must contain data. */
2991 mapping_state (MAP_DATA
);
2994 #define mapping_state(a)
2995 #endif /* OBJ_ELF */
3000 int a ATTRIBUTE_UNUSED
;
3002 as_bad (_("invalid syntax for .req directive"));
3005 /* The .unreq directive deletes an alias which was previously defined
3006 by .req. For example:
3012 s_unreq (int a ATTRIBUTE_UNUSED
)
3017 skip_whitespace (input_line_pointer
);
3018 name
= input_line_pointer
;
3020 while (*input_line_pointer
!= 0
3021 && *input_line_pointer
!= ' '
3022 && *input_line_pointer
!= '\n')
3023 ++input_line_pointer
;
3025 saved_char
= *input_line_pointer
;
3026 *input_line_pointer
= 0;
3030 enum arm_reg_type req_type
= arm_reg_parse_any (name
);
3032 if (req_type
!= REG_TYPE_MAX
)
3034 char *temp_name
= name
;
3035 int req_no
= arm_reg_parse (&temp_name
, all_reg_maps
[req_type
].htab
);
3039 struct reg_entry
*req_entry
;
3041 /* Check to see if this alias is a builtin one. */
3042 req_entry
= hash_delete (all_reg_maps
[req_type
].htab
, name
);
3045 as_bad (_("unreq: missing hash entry for \"%s\""), name
);
3046 else if (req_entry
->builtin
)
3047 /* FIXME: We are deleting a built in register alias which
3048 points to a const data structure, so we only need to
3049 free up the memory used by the key in the hash table.
3050 Unfortunately we have not recorded this value, so this
3051 is a memory leak. */
3052 /* FIXME: Should we issue a warning message ? */
3056 /* Deleting a user defined alias. We need to free the
3057 key and the value, but fortunately the key is the same
3058 as the value->name field. */
3059 free ((char *) req_entry
->name
);
3064 as_bad (_(".unreq: unrecognized symbol \"%s\""), name
);
3067 as_bad (_(".unreq: unrecognized symbol \"%s\""), name
);
3070 as_bad (_("invalid syntax for .unreq directive"));
3072 *input_line_pointer
= saved_char
;
3073 demand_empty_rest_of_line ();
3078 int ignore ATTRIBUTE_UNUSED
;
3080 /* We don't support putting frags in the BSS segment, we fake it by
3081 marking in_bss, then looking at s_skip for clues. */
3082 subseg_set (bss_section
, 0);
3083 demand_empty_rest_of_line ();
3084 mapping_state (MAP_DATA
);
3089 int ignore ATTRIBUTE_UNUSED
;
3091 /* Never make frag if expect extra pass. */
3093 frag_align (1, 0, 0);
3095 record_alignment (now_seg
, 1);
3097 demand_empty_rest_of_line ();
3102 int ignored ATTRIBUTE_UNUSED
;
3105 literal_pool
* pool
;
3108 pool
= find_literal_pool ();
3110 || pool
->symbol
== NULL
3111 || pool
->next_free_entry
== 0)
3114 /* Align pool as you have word accesses.
3115 Only make a frag if we have to. */
3117 frag_align (2, 0, 0);
3119 record_alignment (now_seg
, 2);
3121 sprintf (sym_name
, "$$lit_\002%x", pool
->id
);
3123 symbol_locate (pool
->symbol
, sym_name
, now_seg
,
3124 (valueT
) frag_now_fix (), frag_now
);
3125 symbol_table_insert (pool
->symbol
);
3127 ARM_SET_THUMB (pool
->symbol
, thumb_mode
);
3129 #if defined OBJ_COFF || defined OBJ_ELF
3130 ARM_SET_INTERWORK (pool
->symbol
, support_interwork
);
3133 for (entry
= 0; entry
< pool
->next_free_entry
; entry
++)
3134 /* First output the expression in the instruction to the pool. */
3135 emit_expr (&(pool
->literals
[entry
]), 4); /* .word */
3137 /* Mark the pool as empty. */
3138 pool
->next_free_entry
= 0;
3139 pool
->symbol
= NULL
;
3142 /* Same as s_align_ptwo but align 0 => align 2. */
3146 int unused ATTRIBUTE_UNUSED
;
3149 register long temp_fill
;
3150 long max_alignment
= 15;
3152 temp
= get_absolute_expression ();
3153 if (temp
> max_alignment
)
3154 as_bad (_("alignment too large: %d assumed"), temp
= max_alignment
);
3157 as_bad (_("alignment negative. 0 assumed."));
3161 if (*input_line_pointer
== ',')
3163 input_line_pointer
++;
3164 temp_fill
= get_absolute_expression ();
3172 /* Only make a frag if we HAVE to. */
3173 if (temp
&& !need_pass_2
)
3174 frag_align (temp
, (int) temp_fill
, 0);
3175 demand_empty_rest_of_line ();
3177 record_alignment (now_seg
, temp
);
3181 s_force_thumb (ignore
)
3182 int ignore ATTRIBUTE_UNUSED
;
3184 /* If we are not already in thumb mode go into it, EVEN if
3185 the target processor does not support thumb instructions.
3186 This is used by gcc/config/arm/lib1funcs.asm for example
3187 to compile interworking support functions even if the
3188 target processor should not support interworking. */
3193 record_alignment (now_seg
, 1);
3196 demand_empty_rest_of_line ();
3200 s_thumb_func (ignore
)
3201 int ignore ATTRIBUTE_UNUSED
;
3206 /* The following label is the name/address of the start of a Thumb function.
3207 We need to know this for the interworking support. */
3208 label_is_thumb_function_name
= TRUE
;
3210 demand_empty_rest_of_line ();
3213 /* Perform a .set directive, but also mark the alias as
3214 being a thumb function. */
3220 /* XXX the following is a duplicate of the code for s_set() in read.c
3221 We cannot just call that code as we need to get at the symbol that
3223 register char * name
;
3224 register char delim
;
3225 register char * end_name
;
3226 register symbolS
* symbolP
;
3228 /* Especial apologies for the random logic:
3229 This just grew, and could be parsed much more simply!
3231 name
= input_line_pointer
;
3232 delim
= get_symbol_end ();
3233 end_name
= input_line_pointer
;
3238 if (*input_line_pointer
!= ',')
3241 as_bad (_("expected comma after name \"%s\""), name
);
3243 ignore_rest_of_line ();
3247 input_line_pointer
++;
3250 if (name
[0] == '.' && name
[1] == '\0')
3252 /* XXX - this should not happen to .thumb_set. */
3256 if ((symbolP
= symbol_find (name
)) == NULL
3257 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
3260 /* When doing symbol listings, play games with dummy fragments living
3261 outside the normal fragment chain to record the file and line info
3263 if (listing
& LISTING_SYMBOLS
)
3265 extern struct list_info_struct
* listing_tail
;
3266 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
3268 memset (dummy_frag
, 0, sizeof (fragS
));
3269 dummy_frag
->fr_type
= rs_fill
;
3270 dummy_frag
->line
= listing_tail
;
3271 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
3272 dummy_frag
->fr_symbol
= symbolP
;
3276 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
3279 /* "set" symbols are local unless otherwise specified. */
3280 SF_SET_LOCAL (symbolP
);
3281 #endif /* OBJ_COFF */
3282 } /* Make a new symbol. */
3284 symbol_table_insert (symbolP
);
3289 && S_IS_DEFINED (symbolP
)
3290 && S_GET_SEGMENT (symbolP
) != reg_section
)
3291 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
3293 pseudo_set (symbolP
);
3295 demand_empty_rest_of_line ();
3297 /* XXX Now we come to the Thumb specific bit of code. */
3299 THUMB_SET_FUNC (symbolP
, 1);
3300 ARM_SET_THUMB (symbolP
, 1);
3301 #if defined OBJ_ELF || defined OBJ_COFF
3302 ARM_SET_INTERWORK (symbolP
, support_interwork
);
3307 opcode_select (width
)
3315 if (! (cpu_variant
& ARM_EXT_V4T
))
3316 as_bad (_("selected processor does not support THUMB opcodes"));
3319 /* No need to force the alignment, since we will have been
3320 coming from ARM mode, which is word-aligned. */
3321 record_alignment (now_seg
, 1);
3323 mapping_state (MAP_THUMB
);
3329 if ((cpu_variant
& ARM_ALL
) == ARM_EXT_V4T
)
3330 as_bad (_("selected processor does not support ARM opcodes"));
3335 frag_align (2, 0, 0);
3337 record_alignment (now_seg
, 1);
3339 mapping_state (MAP_ARM
);
3343 as_bad (_("invalid instruction size selected (%d)"), width
);
3349 int ignore ATTRIBUTE_UNUSED
;
3352 demand_empty_rest_of_line ();
3357 int ignore ATTRIBUTE_UNUSED
;
3360 demand_empty_rest_of_line ();
3365 int unused ATTRIBUTE_UNUSED
;
3369 temp
= get_absolute_expression ();
3374 opcode_select (temp
);
3378 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
3386 skip_whitespace (str
);
3388 if (*str
!= '\0' && !inst
.error
)
3389 inst
.error
= _("garbage following instruction");
3393 skip_past_comma (str
)
3396 char * p
= * str
, c
;
3399 while ((c
= *p
) == ' ' || c
== ',')
3402 if (c
== ',' && comma
++)
3410 return comma
? SUCCESS
: FAIL
;
3413 /* A standard register must be given at this point.
3414 SHIFT is the place to put it in inst.instruction.
3415 Restores input start point on error.
3416 Returns the reg#, or FAIL. */
3419 reg_required_here (str
, shift
)
3423 static char buff
[128]; /* XXX */
3425 char * start
= * str
;
3427 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_RN
].htab
)) != FAIL
)
3430 inst
.instruction
|= reg
<< shift
;
3434 /* Restore the start point, we may have got a reg of the wrong class. */
3437 /* In the few cases where we might be able to accept something else
3438 this error can be overridden. */
3439 sprintf (buff
, _("register expected, not '%.100s'"), start
);
3445 /* A Intel Wireless MMX technology register
3446 must be given at this point.
3447 Shift is the place to put it in inst.instruction.
3448 Restores input start point on err.
3449 Returns the reg#, or FAIL. */
3452 wreg_required_here (str
, shift
, reg_type
)
3455 enum wreg_type reg_type
;
3457 static char buff
[128];
3459 char * start
= *str
;
3461 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_IWMMXT
].htab
)) != FAIL
)
3463 if (wr_register (reg
)
3464 && (reg_type
== IWMMXT_REG_WR
|| reg_type
== IWMMXT_REG_WR_OR_WC
))
3467 inst
.instruction
|= (reg
^ WR_PREFIX
) << shift
;
3470 else if (wc_register (reg
)
3471 && (reg_type
== IWMMXT_REG_WC
|| reg_type
== IWMMXT_REG_WR_OR_WC
))
3474 inst
.instruction
|= (reg
^ WC_PREFIX
) << shift
;
3477 else if ((wcg_register (reg
) && reg_type
== IWMMXT_REG_WCG
))
3480 inst
.instruction
|= ((reg
^ WC_PREFIX
) - 8) << shift
;
3485 /* Restore the start point, we may have got a reg of the wrong class. */
3488 /* In the few cases where we might be able to accept
3489 something else this error can be overridden. */
3490 sprintf (buff
, _("Intel Wireless MMX technology register expected, not '%.100s'"), start
);
3496 static const struct asm_psr
*
3498 register char ** ccp
;
3500 char * start
= * ccp
;
3503 const struct asm_psr
* psr
;
3507 /* Skip to the end of the next word in the input stream. */
3512 while (ISALPHA (c
) || c
== '_');
3514 /* Terminate the word. */
3517 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
3518 feature for ease of use and backwards compatibility. */
3519 if (!strncmp (start
, "cpsr", 4))
3520 strncpy (start
, "CPSR", 4);
3521 else if (!strncmp (start
, "spsr", 4))
3522 strncpy (start
, "SPSR", 4);
3524 /* Now locate the word in the psr hash table. */
3525 psr
= (const struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
3527 /* Restore the input stream. */
3530 /* If we found a valid match, advance the
3531 stream pointer past the end of the word. */
3537 /* Parse the input looking for a PSR flag. */
3540 psr_required_here (str
)
3543 char * start
= * str
;
3544 const struct asm_psr
* psr
;
3546 psr
= arm_psr_parse (str
);
3550 /* If this is the SPSR that is being modified, set the R bit. */
3552 inst
.instruction
|= SPSR_BIT
;
3554 /* Set the psr flags in the MSR instruction. */
3555 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
3560 /* In the few cases where we might be able to accept
3561 something else this error can be overridden. */
3562 inst
.error
= _("flag for {c}psr instruction expected");
3564 /* Restore the start point. */
3570 co_proc_number (str
)
3573 int processor
, pchar
;
3576 skip_whitespace (*str
);
3579 /* The data sheet seems to imply that just a number on its own is valid
3580 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
3582 if ((processor
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_CP
].htab
))
3588 if (pchar
>= '0' && pchar
<= '9')
3590 processor
= pchar
- '0';
3591 if (**str
>= '0' && **str
<= '9')
3593 processor
= processor
* 10 + *(*str
)++ - '0';
3596 inst
.error
= _("illegal co-processor number");
3603 inst
.error
= _("bad or missing co-processor number");
3608 inst
.instruction
|= processor
<< 8;
3613 cp_opc_expr (str
, where
, length
)
3620 skip_whitespace (* str
);
3622 memset (&expr
, '\0', sizeof (expr
));
3624 if (my_get_expression (&expr
, str
))
3626 if (expr
.X_op
!= O_constant
)
3628 inst
.error
= _("bad or missing expression");
3632 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
3634 inst
.error
= _("immediate co-processor expression too large");
3638 inst
.instruction
|= expr
.X_add_number
<< where
;
3643 cp_reg_required_here (str
, where
)
3648 char * start
= *str
;
3650 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_CN
].htab
)) != FAIL
)
3652 inst
.instruction
|= reg
<< where
;
3656 /* In the few cases where we might be able to accept something else
3657 this error can be overridden. */
3658 inst
.error
= _("co-processor register expected");
3660 /* Restore the start point. */
3666 fp_reg_required_here (str
, where
)
3671 char * start
= * str
;
3673 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_FN
].htab
)) != FAIL
)
3675 inst
.instruction
|= reg
<< where
;
3679 /* In the few cases where we might be able to accept something else
3680 this error can be overridden. */
3681 inst
.error
= _("floating point register expected");
3683 /* Restore the start point. */
3689 cp_address_offset (str
)
3694 skip_whitespace (* str
);
3696 if (! is_immediate_prefix (**str
))
3698 inst
.error
= _("immediate expression expected");
3704 if (my_get_expression (& inst
.reloc
.exp
, str
))
3707 if (inst
.reloc
.exp
.X_op
== O_constant
)
3709 offset
= inst
.reloc
.exp
.X_add_number
;
3713 inst
.error
= _("co-processor address must be word aligned");
3717 if (offset
> 1023 || offset
< -1023)
3719 inst
.error
= _("offset too large");
3724 inst
.instruction
|= INDEX_UP
;
3728 inst
.instruction
|= offset
>> 2;
3731 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
3737 cp_address_required_here (str
, wb_ok
)
3750 skip_whitespace (p
);
3752 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
3755 skip_whitespace (p
);
3761 skip_whitespace (p
);
3765 /* As an extension to the official ARM syntax we allow:
3769 as a short hand for:
3772 inst
.instruction
|= PRE_INDEX
| INDEX_UP
;
3777 if (skip_past_comma (& p
) == FAIL
)
3779 inst
.error
= _("comma expected after closing square bracket");
3783 skip_whitespace (p
);
3790 write_back
= WRITE_BACK
;
3794 inst
.error
= _("pc may not be used in post-increment");
3798 if (cp_address_offset (& p
) == FAIL
)
3802 pre_inc
= PRE_INDEX
| INDEX_UP
;
3808 /* [Rn], {<expr>} */
3811 skip_whitespace (p
);
3813 if (my_get_expression (& inst
.reloc
.exp
, & p
))
3816 if (inst
.reloc
.exp
.X_op
== O_constant
)
3818 option
= inst
.reloc
.exp
.X_add_number
;
3820 if (option
> 255 || option
< 0)
3822 inst
.error
= _("'option' field too large");
3826 skip_whitespace (p
);
3830 inst
.error
= _("'}' expected at end of 'option' field");
3836 inst
.instruction
|= option
;
3837 inst
.instruction
|= INDEX_UP
;
3842 inst
.error
= _("non-constant expressions for 'option' field not supported");
3848 inst
.error
= _("# or { expected after comma");
3854 /* '['Rn, #expr']'[!] */
3856 if (skip_past_comma (& p
) == FAIL
)
3858 inst
.error
= _("pre-indexed expression expected");
3862 pre_inc
= PRE_INDEX
;
3864 if (cp_address_offset (& p
) == FAIL
)
3867 skip_whitespace (p
);
3871 inst
.error
= _("missing ]");
3875 skip_whitespace (p
);
3877 if (wb_ok
&& *p
== '!')
3881 inst
.error
= _("pc may not be used with write-back");
3886 write_back
= WRITE_BACK
;
3892 if (my_get_expression (&inst
.reloc
.exp
, &p
))
3895 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
3896 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
3897 inst
.reloc
.pc_rel
= 1;
3898 inst
.instruction
|= (REG_PC
<< 16);
3899 pre_inc
= PRE_INDEX
;
3902 inst
.instruction
|= write_back
| pre_inc
;
3908 cp_byte_address_offset (str
)
3913 skip_whitespace (* str
);
3915 if (! is_immediate_prefix (**str
))
3917 inst
.error
= _("immediate expression expected");
3923 if (my_get_expression (& inst
.reloc
.exp
, str
))
3926 if (inst
.reloc
.exp
.X_op
== O_constant
)
3928 offset
= inst
.reloc
.exp
.X_add_number
;
3930 if (offset
> 255 || offset
< -255)
3932 inst
.error
= _("offset too large");
3937 inst
.instruction
|= INDEX_UP
;
3941 inst
.instruction
|= offset
;
3944 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM_S2
;
3950 cp_byte_address_required_here (str
)
3962 skip_whitespace (p
);
3964 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
3967 skip_whitespace (p
);
3973 if (skip_past_comma (& p
) == SUCCESS
)
3976 write_back
= WRITE_BACK
;
3980 inst
.error
= _("pc may not be used in post-increment");
3984 if (cp_byte_address_offset (& p
) == FAIL
)
3988 pre_inc
= PRE_INDEX
| INDEX_UP
;
3992 /* '['Rn, #expr']'[!] */
3994 if (skip_past_comma (& p
) == FAIL
)
3996 inst
.error
= _("pre-indexed expression expected");
4000 pre_inc
= PRE_INDEX
;
4002 if (cp_byte_address_offset (& p
) == FAIL
)
4005 skip_whitespace (p
);
4009 inst
.error
= _("missing ]");
4013 skip_whitespace (p
);
4019 inst
.error
= _("pc may not be used with write-back");
4024 write_back
= WRITE_BACK
;
4030 if (my_get_expression (&inst
.reloc
.exp
, &p
))
4033 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM_S2
;
4034 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
4035 inst
.reloc
.pc_rel
= 1;
4036 inst
.instruction
|= (REG_PC
<< 16);
4037 pre_inc
= PRE_INDEX
;
4040 inst
.instruction
|= write_back
| pre_inc
;
4049 /* Do nothing really. */
4059 /* Only one syntax. */
4060 skip_whitespace (str
);
4062 if (reg_required_here (&str
, 12) == FAIL
)
4064 inst
.error
= BAD_ARGS
;
4068 if (skip_past_comma (&str
) == FAIL
)
4070 inst
.error
= _("comma expected after register name");
4074 skip_whitespace (str
);
4076 if ( strcmp (str
, "CPSR") == 0
4077 || strcmp (str
, "SPSR") == 0
4078 /* Lower case versions for backwards compatibility. */
4079 || strcmp (str
, "cpsr") == 0
4080 || strcmp (str
, "spsr") == 0)
4083 /* This is for backwards compatibility with older toolchains. */
4084 else if ( strcmp (str
, "cpsr_all") == 0
4085 || strcmp (str
, "spsr_all") == 0)
4089 inst
.error
= _("CPSR or SPSR expected");
4093 if (* str
== 's' || * str
== 'S')
4094 inst
.instruction
|= SPSR_BIT
;
4100 /* Two possible forms:
4101 "{C|S}PSR_<field>, Rm",
4102 "{C|S}PSR_f, #expression". */
4108 skip_whitespace (str
);
4110 if (psr_required_here (& str
) == FAIL
)
4113 if (skip_past_comma (& str
) == FAIL
)
4115 inst
.error
= _("comma missing after psr flags");
4119 skip_whitespace (str
);
4121 if (reg_required_here (& str
, 0) != FAIL
)
4128 if (! is_immediate_prefix (* str
))
4131 _("only a register or immediate value can follow a psr flag");
4138 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4141 _("only a register or immediate value can follow a psr flag");
4145 #if 0 /* The first edition of the ARM architecture manual stated that
4146 writing anything other than the flags with an immediate operation
4147 had UNPREDICTABLE effects. This constraint was removed in the
4148 second edition of the specification. */
4149 if ((cpu_variant
& ARM_EXT_V5
) != ARM_EXT_V5
4150 && inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
4152 inst
.error
= _("immediate value cannot be used to set this field");
4157 inst
.instruction
|= INST_IMMEDIATE
;
4159 if (inst
.reloc
.exp
.X_add_symbol
)
4161 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4162 inst
.reloc
.pc_rel
= 0;
4166 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4168 if (value
== (unsigned) FAIL
)
4170 inst
.error
= _("invalid constant");
4174 inst
.instruction
|= value
;
4181 /* Long Multiply Parser
4182 UMULL RdLo, RdHi, Rm, Rs
4183 SMULL RdLo, RdHi, Rm, Rs
4184 UMLAL RdLo, RdHi, Rm, Rs
4185 SMLAL RdLo, RdHi, Rm, Rs. */
4191 int rdlo
, rdhi
, rm
, rs
;
4193 /* Only one format "rdlo, rdhi, rm, rs". */
4194 skip_whitespace (str
);
4196 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
4198 inst
.error
= BAD_ARGS
;
4202 if (skip_past_comma (&str
) == FAIL
4203 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
4205 inst
.error
= BAD_ARGS
;
4209 if (skip_past_comma (&str
) == FAIL
4210 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
4212 inst
.error
= BAD_ARGS
;
4216 /* rdhi, rdlo and rm must all be different. */
4217 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
4218 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
4220 if (skip_past_comma (&str
) == FAIL
4221 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
4223 inst
.error
= BAD_ARGS
;
4227 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
4229 inst
.error
= BAD_PC
;
4242 /* Only one format "rd, rm, rs". */
4243 skip_whitespace (str
);
4245 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
4247 inst
.error
= BAD_ARGS
;
4253 inst
.error
= BAD_PC
;
4257 if (skip_past_comma (&str
) == FAIL
4258 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
4260 inst
.error
= BAD_ARGS
;
4266 inst
.error
= BAD_PC
;
4271 as_tsktsk (_("rd and rm should be different in mul"));
4273 if (skip_past_comma (&str
) == FAIL
4274 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
4276 inst
.error
= BAD_ARGS
;
4282 inst
.error
= BAD_PC
;
4295 /* Only one format "rd, rm, rs, rn". */
4296 skip_whitespace (str
);
4298 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
4300 inst
.error
= BAD_ARGS
;
4306 inst
.error
= BAD_PC
;
4310 if (skip_past_comma (&str
) == FAIL
4311 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
4313 inst
.error
= BAD_ARGS
;
4319 inst
.error
= BAD_PC
;
4324 as_tsktsk (_("rd and rm should be different in mla"));
4326 if (skip_past_comma (&str
) == FAIL
4327 || (rd
= reg_required_here (&str
, 8)) == FAIL
4328 || skip_past_comma (&str
) == FAIL
4329 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
4331 inst
.error
= BAD_ARGS
;
4335 if (rd
== REG_PC
|| rm
== REG_PC
)
4337 inst
.error
= BAD_PC
;
4344 /* Expects *str -> the characters "acc0", possibly with leading blanks.
4345 Advances *str to the next non-alphanumeric.
4346 Returns 0, or else FAIL (in which case sets inst.error).
4348 (In a future XScale, there may be accumulators other than zero.
4349 At that time this routine and its callers can be upgraded to suit.) */
4352 accum0_required_here (str
)
4355 static char buff
[128]; /* Note the address is taken. Hence, static. */
4358 int result
= 0; /* The accum number. */
4360 skip_whitespace (p
);
4362 *str
= p
; /* Advance caller's string pointer too. */
4367 *--p
= 0; /* Aap nul into input buffer at non-alnum. */
4369 if (! ( streq (*str
, "acc0") || streq (*str
, "ACC0")))
4371 sprintf (buff
, _("acc0 expected, not '%.100s'"), *str
);
4376 *p
= c
; /* Unzap. */
4377 *str
= p
; /* Caller's string pointer to after match. */
4381 /* Expects **str -> after a comma. May be leading blanks.
4382 Advances *str, recognizing a load mode, and setting inst.instruction.
4383 Returns rn, or else FAIL (in which case may set inst.error
4384 and not advance str)
4386 Note: doesn't know Rd, so no err checks that require such knowledge. */
4389 ld_mode_required_here (string
)
4392 char * str
= * string
;
4396 skip_whitespace (str
);
4402 skip_whitespace (str
);
4404 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
4407 skip_whitespace (str
);
4413 if (skip_past_comma (& str
) == SUCCESS
)
4415 /* [Rn],... (post inc) */
4416 if (ldst_extend_v4 (&str
) == FAIL
)
4421 skip_whitespace (str
);
4426 inst
.instruction
|= WRITE_BACK
;
4429 inst
.instruction
|= INDEX_UP
| HWOFFSET_IMM
;
4435 if (skip_past_comma (& str
) == FAIL
)
4437 inst
.error
= _("pre-indexed expression expected");
4443 if (ldst_extend_v4 (&str
) == FAIL
)
4446 skip_whitespace (str
);
4448 if (* str
++ != ']')
4450 inst
.error
= _("missing ]");
4454 skip_whitespace (str
);
4459 inst
.instruction
|= WRITE_BACK
;
4463 else if (* str
== '=') /* ldr's "r,=label" syntax */
4464 /* We should never reach here, because <text> = <expression> is
4465 caught gas/read.c read_a_source_file() as a .set operation. */
4467 else /* PC +- 8 bit immediate offset. */
4469 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4472 inst
.instruction
|= HWOFFSET_IMM
; /* The I bit. */
4473 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
4474 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
4475 inst
.reloc
.pc_rel
= 1;
4476 inst
.instruction
|= (REG_PC
<< 16);
4482 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
4488 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
4489 SMLAxy{cond} Rd,Rm,Rs,Rn
4490 SMLAWy{cond} Rd,Rm,Rs,Rn
4491 Error if any register is R15. */
4499 skip_whitespace (str
);
4501 if ((rd
= reg_required_here (& str
, 16)) == FAIL
4502 || skip_past_comma (& str
) == FAIL
4503 || (rm
= reg_required_here (& str
, 0)) == FAIL
4504 || skip_past_comma (& str
) == FAIL
4505 || (rs
= reg_required_here (& str
, 8)) == FAIL
4506 || skip_past_comma (& str
) == FAIL
4507 || (rn
= reg_required_here (& str
, 12)) == FAIL
)
4508 inst
.error
= BAD_ARGS
;
4510 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
|| rn
== REG_PC
)
4511 inst
.error
= BAD_PC
;
4517 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4518 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4519 Error if any register is R15.
4520 Warning if Rdlo == Rdhi. */
4526 int rdlo
, rdhi
, rm
, rs
;
4528 skip_whitespace (str
);
4530 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
4531 || skip_past_comma (& str
) == FAIL
4532 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
4533 || skip_past_comma (& str
) == FAIL
4534 || (rm
= reg_required_here (& str
, 0)) == FAIL
4535 || skip_past_comma (& str
) == FAIL
4536 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
4538 inst
.error
= BAD_ARGS
;
4542 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
4544 inst
.error
= BAD_PC
;
4549 as_tsktsk (_("rdhi and rdlo must be different"));
4554 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4555 SMULxy{cond} Rd,Rm,Rs
4556 Error if any register is R15. */
4564 skip_whitespace (str
);
4566 if ((rd
= reg_required_here (& str
, 16)) == FAIL
4567 || skip_past_comma (& str
) == FAIL
4568 || (rm
= reg_required_here (& str
, 0)) == FAIL
4569 || skip_past_comma (& str
) == FAIL
4570 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
4571 inst
.error
= BAD_ARGS
;
4573 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
4574 inst
.error
= BAD_PC
;
4580 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4581 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4582 Error if any register is R15. */
4590 skip_whitespace (str
);
4592 if ((rd
= reg_required_here (& str
, 12)) == FAIL
4593 || skip_past_comma (& str
) == FAIL
4594 || (rm
= reg_required_here (& str
, 0)) == FAIL
4595 || skip_past_comma (& str
) == FAIL
4596 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
4597 inst
.error
= BAD_ARGS
;
4599 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
4600 inst
.error
= BAD_PC
;
4606 /* ARM V5E (el Segundo)
4607 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4608 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4610 These are equivalent to the XScale instructions MAR and MRA,
4611 respectively, when coproc == 0, opcode == 0, and CRm == 0.
4613 Result unpredicatable if Rd or Rn is R15. */
4621 skip_whitespace (str
);
4623 if (co_proc_number (& str
) == FAIL
)
4626 inst
.error
= BAD_ARGS
;
4630 if (skip_past_comma (& str
) == FAIL
4631 || cp_opc_expr (& str
, 4, 4) == FAIL
)
4634 inst
.error
= BAD_ARGS
;
4638 if (skip_past_comma (& str
) == FAIL
4639 || (rd
= reg_required_here (& str
, 12)) == FAIL
)
4642 inst
.error
= BAD_ARGS
;
4646 if (skip_past_comma (& str
) == FAIL
4647 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
4650 inst
.error
= BAD_ARGS
;
4654 /* Unpredictable result if rd or rn is R15. */
4655 if (rd
== REG_PC
|| rn
== REG_PC
)
4657 (_("Warning: instruction unpredictable when using r15"));
4659 if (skip_past_comma (& str
) == FAIL
4660 || cp_reg_required_here (& str
, 0) == FAIL
)
4663 inst
.error
= BAD_ARGS
;
4670 /* ARM V5 count-leading-zeroes instruction (argument parse)
4671 CLZ{<cond>} <Rd>, <Rm>
4672 Condition defaults to COND_ALWAYS.
4673 Error if Rd or Rm are R15. */
4681 skip_whitespace (str
);
4683 if (((rd
= reg_required_here (& str
, 12)) == FAIL
)
4684 || (skip_past_comma (& str
) == FAIL
)
4685 || ((rm
= reg_required_here (& str
, 0)) == FAIL
))
4686 inst
.error
= BAD_ARGS
;
4688 else if (rd
== REG_PC
|| rm
== REG_PC
)
4689 inst
.error
= BAD_PC
;
4695 /* ARM V5 (argument parse)
4696 LDC2{L} <coproc>, <CRd>, <addressing mode>
4697 STC2{L} <coproc>, <CRd>, <addressing mode>
4698 Instruction is not conditional, and has 0xf in the condition field.
4699 Otherwise, it's the same as LDC/STC. */
4705 skip_whitespace (str
);
4707 if (co_proc_number (& str
) == FAIL
)
4710 inst
.error
= BAD_ARGS
;
4712 else if (skip_past_comma (& str
) == FAIL
4713 || cp_reg_required_here (& str
, 12) == FAIL
)
4716 inst
.error
= BAD_ARGS
;
4718 else if (skip_past_comma (& str
) == FAIL
4719 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
4722 inst
.error
= BAD_ARGS
;
4728 /* ARM V5 (argument parse)
4729 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4730 Instruction is not conditional, and has 0xf in the condition field.
4731 Otherwise, it's the same as CDP. */
4737 skip_whitespace (str
);
4739 if (co_proc_number (& str
) == FAIL
)
4742 inst
.error
= BAD_ARGS
;
4746 if (skip_past_comma (& str
) == FAIL
4747 || cp_opc_expr (& str
, 20,4) == FAIL
)
4750 inst
.error
= BAD_ARGS
;
4754 if (skip_past_comma (& str
) == FAIL
4755 || cp_reg_required_here (& str
, 12) == FAIL
)
4758 inst
.error
= BAD_ARGS
;
4762 if (skip_past_comma (& str
) == FAIL
4763 || cp_reg_required_here (& str
, 16) == FAIL
)
4766 inst
.error
= BAD_ARGS
;
4770 if (skip_past_comma (& str
) == FAIL
4771 || cp_reg_required_here (& str
, 0) == FAIL
)
4774 inst
.error
= BAD_ARGS
;
4778 if (skip_past_comma (& str
) == SUCCESS
)
4780 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
4783 inst
.error
= BAD_ARGS
;
4791 /* ARM V5 (argument parse)
4792 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4793 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4794 Instruction is not conditional, and has 0xf in the condition field.
4795 Otherwise, it's the same as MCR/MRC. */
4801 skip_whitespace (str
);
4803 if (co_proc_number (& str
) == FAIL
)
4806 inst
.error
= BAD_ARGS
;
4810 if (skip_past_comma (& str
) == FAIL
4811 || cp_opc_expr (& str
, 21, 3) == FAIL
)
4814 inst
.error
= BAD_ARGS
;
4818 if (skip_past_comma (& str
) == FAIL
4819 || reg_required_here (& str
, 12) == FAIL
)
4822 inst
.error
= BAD_ARGS
;
4826 if (skip_past_comma (& str
) == FAIL
4827 || cp_reg_required_here (& str
, 16) == FAIL
)
4830 inst
.error
= BAD_ARGS
;
4834 if (skip_past_comma (& str
) == FAIL
4835 || cp_reg_required_here (& str
, 0) == FAIL
)
4838 inst
.error
= BAD_ARGS
;
4842 if (skip_past_comma (& str
) == SUCCESS
)
4844 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
4847 inst
.error
= BAD_ARGS
;
4855 /* ARM v5TEJ. Jump to Jazelle code. */
4862 skip_whitespace (str
);
4864 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
4866 inst
.error
= BAD_ARGS
;
4870 /* Note - it is not illegal to do a "bxj pc". Useless, but not illegal. */
4872 as_tsktsk (_("use of r15 in bxj is not really useful"));
4877 /* ARM V6 umaal (argument parse). */
4884 int rdlo
, rdhi
, rm
, rs
;
4886 skip_whitespace (str
);
4887 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
4888 || skip_past_comma (& str
) == FAIL
4889 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
4890 || skip_past_comma (& str
) == FAIL
4891 || (rm
= reg_required_here (& str
, 0)) == FAIL
4892 || skip_past_comma (& str
) == FAIL
4893 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
4895 inst
.error
= BAD_ARGS
;
4899 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
4901 inst
.error
= BAD_PC
;
4908 /* ARM V6 strex (argument parse). */
4916 /* Parse Rd, Rm,. */
4917 skip_whitespace (str
);
4918 if ((rd
= reg_required_here (& str
, 12)) == FAIL
4919 || skip_past_comma (& str
) == FAIL
4920 || (rm
= reg_required_here (& str
, 0)) == FAIL
4921 || skip_past_comma (& str
) == FAIL
)
4923 inst
.error
= BAD_ARGS
;
4926 if (rd
== REG_PC
|| rm
== REG_PC
)
4928 inst
.error
= BAD_PC
;
4933 inst
.error
= _("Rd equal to Rm or Rn yields unpredictable results");
4937 /* Skip past '['. */
4938 if ((strlen (str
) >= 1)
4939 && strncmp (str
, "[", 1) == 0)
4941 skip_whitespace (str
);
4944 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
4946 inst
.error
= BAD_ARGS
;
4949 else if (rn
== REG_PC
)
4951 inst
.error
= BAD_PC
;
4956 inst
.error
= _("Rd equal to Rm or Rn yields unpredictable results");
4959 skip_whitespace (str
);
4961 /* Skip past ']'. */
4962 if ((strlen (str
) >= 1)
4963 && strncmp (str
, "]", 1) == 0)
4969 /* ARM V6 ssat (argument parse). */
4975 do_sat (&str
, /*bias=*/-1);
4979 /* ARM V6 usat (argument parse). */
4985 do_sat (&str
, /*bias=*/0);
4997 skip_whitespace (*str
);
4999 /* Parse <Rd>, field. */
5000 if ((rd
= reg_required_here (str
, 12)) == FAIL
5001 || skip_past_comma (str
) == FAIL
)
5003 inst
.error
= BAD_ARGS
;
5008 inst
.error
= BAD_PC
;
5012 /* Parse #<immed>, field. */
5013 if (is_immediate_prefix (**str
))
5017 inst
.error
= _("immediate expression expected");
5020 if (my_get_expression (&expr
, str
))
5022 inst
.error
= _("bad expression");
5025 if (expr
.X_op
!= O_constant
)
5027 inst
.error
= _("constant expression expected");
5030 if (expr
.X_add_number
+ bias
< 0
5031 || expr
.X_add_number
+ bias
> 31)
5033 inst
.error
= _("immediate value out of range");
5036 inst
.instruction
|= (expr
.X_add_number
+ bias
) << 16;
5037 if (skip_past_comma (str
) == FAIL
)
5039 inst
.error
= BAD_ARGS
;
5043 /* Parse <Rm> field. */
5044 if ((rm
= reg_required_here (str
, 0)) == FAIL
)
5046 inst
.error
= BAD_ARGS
;
5051 inst
.error
= BAD_PC
;
5055 if (skip_past_comma (str
) == SUCCESS
)
5056 decode_shift (str
, SHIFT_LSL_OR_ASR_IMMEDIATE
);
5059 /* ARM V6 ssat16 (argument parse). */
5065 do_sat16 (&str
, /*bias=*/-1);
5073 do_sat16 (&str
, /*bias=*/0);
5078 do_sat16 (str
, bias
)
5085 skip_whitespace (*str
);
5087 /* Parse the <Rd> field. */
5088 if ((rd
= reg_required_here (str
, 12)) == FAIL
5089 || skip_past_comma (str
) == FAIL
)
5091 inst
.error
= BAD_ARGS
;
5096 inst
.error
= BAD_PC
;
5100 /* Parse #<immed>, field. */
5101 if (is_immediate_prefix (**str
))
5105 inst
.error
= _("immediate expression expected");
5108 if (my_get_expression (&expr
, str
))
5110 inst
.error
= _("bad expression");
5113 if (expr
.X_op
!= O_constant
)
5115 inst
.error
= _("constant expression expected");
5118 if (expr
.X_add_number
+ bias
< 0
5119 || expr
.X_add_number
+ bias
> 15)
5121 inst
.error
= _("immediate value out of range");
5124 inst
.instruction
|= (expr
.X_add_number
+ bias
) << 16;
5125 if (skip_past_comma (str
) == FAIL
)
5127 inst
.error
= BAD_ARGS
;
5131 /* Parse <Rm> field. */
5132 if ((rm
= reg_required_here (str
, 0)) == FAIL
)
5134 inst
.error
= BAD_ARGS
;
5139 inst
.error
= BAD_PC
;
5144 /* ARM V6 srs (argument parse). */
5151 skip_whitespace (str
);
5152 exclam
= strchr (str
, '!');
5160 inst
.instruction
|= WRITE_BACK
;
5166 /* ARM V6 SMMUL (argument parse). */
5174 skip_whitespace (str
);
5175 if ((rd
= reg_required_here (&str
, 16)) == FAIL
5176 || skip_past_comma (&str
) == FAIL
5177 || (rm
= reg_required_here (&str
, 0)) == FAIL
5178 || skip_past_comma (&str
) == FAIL
5179 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
5181 inst
.error
= BAD_ARGS
;
5189 inst
.error
= BAD_PC
;
5197 /* ARM V6 SMLALD (argument parse). */
5203 int rdlo
, rdhi
, rm
, rs
;
5204 skip_whitespace (str
);
5205 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
5206 || skip_past_comma (&str
) == FAIL
5207 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
5208 || skip_past_comma (&str
) == FAIL
5209 || (rm
= reg_required_here (&str
, 0)) == FAIL
5210 || skip_past_comma (&str
) == FAIL
5211 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
5213 inst
.error
= BAD_ARGS
;
5222 inst
.error
= BAD_PC
;
5229 /* ARM V6 SMLAD (argument parse). Signed multiply accumulate dual.
5230 smlad{x}{<cond>} Rd, Rm, Rs, Rn */
5238 skip_whitespace (str
);
5239 if ((rd
= reg_required_here (&str
, 16)) == FAIL
5240 || skip_past_comma (&str
) == FAIL
5241 || (rm
= reg_required_here (&str
, 0)) == FAIL
5242 || skip_past_comma (&str
) == FAIL
5243 || (rs
= reg_required_here (&str
, 8)) == FAIL
5244 || skip_past_comma (&str
) == FAIL
5245 || (rn
= reg_required_here (&str
, 12)) == FAIL
)
5247 inst
.error
= BAD_ARGS
;
5256 inst
.error
= BAD_PC
;
5263 /* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
5264 preserving the other bits.
5266 setend <endian_specifier>, where <endian_specifier> is either
5273 if (do_endian_specifier (str
))
5274 inst
.instruction
|= 0x200;
5277 /* Returns true if the endian-specifier indicates big-endianness. */
5280 do_endian_specifier (str
)
5285 skip_whitespace (str
);
5286 if (strlen (str
) < 2)
5287 inst
.error
= _("missing endian specifier");
5288 else if (strncasecmp (str
, "BE", 2) == 0)
5293 else if (strncasecmp (str
, "LE", 2) == 0)
5296 inst
.error
= _("valid endian specifiers are be or le");
5305 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
5306 Condition defaults to COND_ALWAYS.
5307 Error if any register uses R15. */
5315 int rotation_clear_mask
= 0xfffff3ff;
5316 int rotation_eight_mask
= 0x00000400;
5317 int rotation_sixteen_mask
= 0x00000800;
5318 int rotation_twenty_four_mask
= 0x00000c00;
5320 skip_whitespace (str
);
5321 if ((rd
= reg_required_here (&str
, 12)) == FAIL
5322 || skip_past_comma (&str
) == FAIL
5323 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
5325 inst
.error
= BAD_ARGS
;
5329 else if (rd
== REG_PC
|| rm
== REG_PC
)
5331 inst
.error
= BAD_PC
;
5335 /* Zero out the rotation field. */
5336 inst
.instruction
&= rotation_clear_mask
;
5338 /* Check for lack of optional rotation field. */
5339 if (skip_past_comma (&str
) == FAIL
)
5345 /* Move past 'ROR'. */
5346 skip_whitespace (str
);
5347 if (strncasecmp (str
, "ROR", 3) == 0)
5351 inst
.error
= _("missing rotation field after comma");
5355 /* Get the immediate constant. */
5356 skip_whitespace (str
);
5357 if (is_immediate_prefix (* str
))
5361 inst
.error
= _("immediate expression expected");
5365 if (my_get_expression (&expr
, &str
))
5367 inst
.error
= _("bad expression");
5371 if (expr
.X_op
!= O_constant
)
5373 inst
.error
= _("constant expression expected");
5377 switch (expr
.X_add_number
)
5380 /* Rotation field has already been zeroed. */
5383 inst
.instruction
|= rotation_eight_mask
;
5387 inst
.instruction
|= rotation_sixteen_mask
;
5391 inst
.instruction
|= rotation_twenty_four_mask
;
5395 inst
.error
= _("rotation can be 8, 16, 24 or 0 when field is ommited");
5403 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
5404 extends it to 32-bits, and adds the result to a value in another
5405 register. You can specify a rotation by 0, 8, 16, or 24 bits
5406 before extracting the 16-bit value.
5407 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
5408 Condition defaults to COND_ALWAYS.
5409 Error if any register uses R15. */
5417 int rotation_clear_mask
= 0xfffff3ff;
5418 int rotation_eight_mask
= 0x00000400;
5419 int rotation_sixteen_mask
= 0x00000800;
5420 int rotation_twenty_four_mask
= 0x00000c00;
5422 skip_whitespace (str
);
5423 if ((rd
= reg_required_here (&str
, 12)) == FAIL
5424 || skip_past_comma (&str
) == FAIL
5425 || (rn
= reg_required_here (&str
, 16)) == FAIL
5426 || skip_past_comma (&str
) == FAIL
5427 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
5429 inst
.error
= BAD_ARGS
;
5433 else if (rd
== REG_PC
|| rn
== REG_PC
|| rm
== REG_PC
)
5435 inst
.error
= BAD_PC
;
5439 /* Zero out the rotation field. */
5440 inst
.instruction
&= rotation_clear_mask
;
5442 /* Check for lack of optional rotation field. */
5443 if (skip_past_comma (&str
) == FAIL
)
5449 /* Move past 'ROR'. */
5450 skip_whitespace (str
);
5451 if (strncasecmp (str
, "ROR", 3) == 0)
5455 inst
.error
= _("missing rotation field after comma");
5459 /* Get the immediate constant. */
5460 skip_whitespace (str
);
5461 if (is_immediate_prefix (* str
))
5465 inst
.error
= _("immediate expression expected");
5469 if (my_get_expression (&expr
, &str
))
5471 inst
.error
= _("bad expression");
5475 if (expr
.X_op
!= O_constant
)
5477 inst
.error
= _("constant expression expected");
5481 switch (expr
.X_add_number
)
5484 /* Rotation field has already been zeroed. */
5488 inst
.instruction
|= rotation_eight_mask
;
5492 inst
.instruction
|= rotation_sixteen_mask
;
5496 inst
.instruction
|= rotation_twenty_four_mask
;
5500 inst
.error
= _("rotation can be 8, 16, 24 or 0 when field is ommited");
5509 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
5510 word at the specified address and the following word
5512 Unconditionally executed.
5522 skip_whitespace (str
);
5524 if ((rn
= reg_required_here (&str
, 16)) == FAIL
)
5529 inst
.error
= BAD_PC
;
5533 skip_whitespace (str
);
5537 inst
.instruction
|= WRITE_BACK
;
5543 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
5544 register (argument parse).
5546 Condition defaults to COND_ALWAYS.
5547 Error if Rd or Rm are R15. */
5555 skip_whitespace (str
);
5557 if ((rd
= reg_required_here (&str
, 12)) == FAIL
5558 || skip_past_comma (&str
) == FAIL
5559 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
5560 inst
.error
= BAD_ARGS
;
5562 else if (rd
== REG_PC
|| rm
== REG_PC
)
5563 inst
.error
= BAD_PC
;
5569 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
5570 QADD16{<cond>} <Rd>, <Rn>, <Rm>
5571 Condition defaults to COND_ALWAYS.
5572 Error if Rd, Rn or Rm are R15. */
5580 skip_whitespace (str
);
5582 if ((rd
= reg_required_here (&str
, 12)) == FAIL
5583 || skip_past_comma (&str
) == FAIL
5584 || (rn
= reg_required_here (&str
, 16)) == FAIL
5585 || skip_past_comma (&str
) == FAIL
5586 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
5587 inst
.error
= BAD_ARGS
;
5589 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
5590 inst
.error
= BAD_PC
;
5596 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
5597 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
5598 Condition defaults to COND_ALWAYS.
5599 Error if Rd, Rn or Rm are R15. */
5605 do_pkh_core (str
, SHIFT_LSL_IMMEDIATE
);
5608 /* ARM V6 PKHTB (Argument Parse). */
5614 do_pkh_core (str
, SHIFT_ASR_IMMEDIATE
);
5618 do_pkh_core (str
, shift
)
5624 skip_whitespace (str
);
5625 if (((rd
= reg_required_here (&str
, 12)) == FAIL
)
5626 || (skip_past_comma (&str
) == FAIL
)
5627 || ((rn
= reg_required_here (&str
, 16)) == FAIL
)
5628 || (skip_past_comma (&str
) == FAIL
)
5629 || ((rm
= reg_required_here (&str
, 0)) == FAIL
))
5631 inst
.error
= BAD_ARGS
;
5635 else if (rd
== REG_PC
|| rn
== REG_PC
|| rm
== REG_PC
)
5637 inst
.error
= BAD_PC
;
5641 /* Check for optional shift immediate constant. */
5642 if (skip_past_comma (&str
) == FAIL
)
5644 if (shift
== SHIFT_ASR_IMMEDIATE
)
5646 /* If the shift specifier is ommited, turn the instruction
5647 into pkhbt rd, rm, rn. First, switch the instruction
5648 code, and clear the rn and rm fields. */
5649 inst
.instruction
&= 0xfff0f010;
5650 /* Now, re-encode the registers. */
5651 inst
.instruction
|= (rm
<< 16) | rn
;
5656 decode_shift (&str
, shift
);
5659 /* ARM V6 Load Register Exclusive instruction (argument parse).
5660 LDREX{<cond>} <Rd, [<Rn>]
5661 Condition defaults to COND_ALWAYS.
5662 Error if Rd or Rn are R15.
5663 See ARMARMv6 A4.1.27: LDREX. */
5672 skip_whitespace (str
);
5675 if (((rd
= reg_required_here (&str
, 12)) == FAIL
)
5676 || (skip_past_comma (&str
) == FAIL
))
5678 inst
.error
= BAD_ARGS
;
5681 else if (rd
== REG_PC
)
5683 inst
.error
= BAD_PC
;
5686 skip_whitespace (str
);
5688 /* Skip past '['. */
5689 if ((strlen (str
) >= 1)
5690 &&strncmp (str
, "[", 1) == 0)
5692 skip_whitespace (str
);
5695 if ((rn
= reg_required_here (&str
, 16)) == FAIL
)
5697 inst
.error
= BAD_ARGS
;
5700 else if (rn
== REG_PC
)
5702 inst
.error
= BAD_PC
;
5705 skip_whitespace (str
);
5707 /* Skip past ']'. */
5708 if ((strlen (str
) >= 1)
5709 && strncmp (str
, "]", 1) == 0)
5715 /* ARM V6 change processor state instruction (argument parse)
5716 CPS, CPSIE, CSPID . */
5730 do_cps_flags (&str
, /*thumb_p=*/0);
5732 if (skip_past_comma (&str
) == SUCCESS
)
5734 skip_whitespace (str
);
5746 skip_whitespace (*str
);
5748 if (! is_immediate_prefix (**str
))
5750 inst
.error
= _("immediate expression expected");
5754 (*str
)++; /* Strip off the immediate signifier. */
5755 if (my_get_expression (&expr
, str
))
5757 inst
.error
= _("bad expression");
5761 if (expr
.X_op
!= O_constant
)
5763 inst
.error
= _("constant expression expected");
5767 /* The mode is a 5 bit field. Valid values are 0-31. */
5768 if (((unsigned) expr
.X_add_number
) > 31
5769 || (inst
.reloc
.exp
.X_add_number
) < 0)
5771 inst
.error
= _("invalid constant");
5775 inst
.instruction
|= expr
.X_add_number
;
5779 do_cps_flags (str
, thumb_p
)
5785 unsigned long arm_value
;
5786 unsigned long thumb_value
;
5788 static struct cps_flag flag_table
[] = {
5796 skip_whitespace (*str
);
5798 /* Get the a, f and i flags. */
5799 while (**str
&& **str
!= ',')
5802 struct cps_flag
*q
= flag_table
+ sizeof (flag_table
)/sizeof (*p
);
5803 for (p
= flag_table
; p
< q
; ++p
)
5804 if (strncasecmp (*str
, &p
->character
, 1) == 0)
5806 inst
.instruction
|= (thumb_p
? p
->thumb_value
: p
->arm_value
);
5812 inst
.error
= _("unrecognized flag");
5818 inst
.error
= _("no 'a', 'i', or 'f' flags for 'cps'");
5821 /* THUMB V5 breakpoint instruction (argument parse)
5829 unsigned long number
;
5831 skip_whitespace (str
);
5833 /* Allow optional leading '#'. */
5834 if (is_immediate_prefix (*str
))
5837 memset (& expr
, '\0', sizeof (expr
));
5838 if (my_get_expression (& expr
, & str
)
5839 || (expr
.X_op
!= O_constant
5840 /* As a convenience we allow 'bkpt' without an operand. */
5841 && expr
.X_op
!= O_absent
))
5843 inst
.error
= _("bad expression");
5847 number
= expr
.X_add_number
;
5849 /* Check it fits an 8 bit unsigned. */
5850 if (number
!= (number
& 0xff))
5852 inst
.error
= _("immediate value out of range");
5856 inst
.instruction
|= number
;
5861 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
5862 Expects inst.instruction is set for BLX(1).
5863 Note: this is cloned from do_branch, and the reloc changed to be a
5864 new one that can cope with setting one extra bit (the H bit). */
5870 if (my_get_expression (& inst
.reloc
.exp
, & str
))
5877 /* ScottB: February 5, 1998 */
5878 /* Check to see of PLT32 reloc required for the instruction. */
5880 /* arm_parse_reloc() works on input_line_pointer.
5881 We actually want to parse the operands to the branch instruction
5882 passed in 'str'. Save the input pointer and restore it later. */
5883 save_in
= input_line_pointer
;
5884 input_line_pointer
= str
;
5886 if (inst
.reloc
.exp
.X_op
== O_symbol
5888 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
5890 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
5891 inst
.reloc
.pc_rel
= 0;
5892 /* Modify str to point to after parsed operands, otherwise
5893 end_of_line() will complain about the (PLT) left in str. */
5894 str
= input_line_pointer
;
5898 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
5899 inst
.reloc
.pc_rel
= 1;
5902 input_line_pointer
= save_in
;
5905 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
5906 inst
.reloc
.pc_rel
= 1;
5907 #endif /* OBJ_ELF */
5912 /* ARM V5 branch-link-exchange instruction (argument parse)
5913 BLX <target_addr> ie BLX(1)
5914 BLX{<condition>} <Rm> ie BLX(2)
5915 Unfortunately, there are two different opcodes for this mnemonic.
5916 So, the insns[].value is not used, and the code here zaps values
5917 into inst.instruction.
5918 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
5927 skip_whitespace (mystr
);
5928 rm
= reg_required_here (& mystr
, 0);
5930 /* The above may set inst.error. Ignore his opinion. */
5935 /* Arg is a register.
5936 Use the condition code our caller put in inst.instruction.
5937 Pass ourselves off as a BX with a funny opcode. */
5938 inst
.instruction
|= 0x012fff30;
5943 /* This must be is BLX <target address>, no condition allowed. */
5944 if (inst
.instruction
!= COND_ALWAYS
)
5946 inst
.error
= BAD_COND
;
5950 inst
.instruction
= 0xfafffffe;
5952 /* Process like a B/BL, but with a different reloc.
5953 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
5958 /* ARM V5 Thumb BLX (argument parse)
5959 BLX <target_addr> which is BLX(1)
5960 BLX <Rm> which is BLX(2)
5961 Unfortunately, there are two different opcodes for this mnemonic.
5962 So, the tinsns[].value is not used, and the code here zaps values
5963 into inst.instruction. */
5972 skip_whitespace (mystr
);
5973 inst
.instruction
= 0x4780;
5975 /* Note that this call is to the ARM register recognizer. BLX(2)
5976 uses the ARM register space, not the Thumb one, so a call to
5977 thumb_reg() would be wrong. */
5978 rm
= reg_required_here (& mystr
, 3);
5983 /* It's BLX(2). The .instruction was zapped with rm & is final. */
5988 /* No ARM register. This must be BLX(1). Change the .instruction. */
5989 inst
.instruction
= 0xf7ffeffe;
5992 if (my_get_expression (& inst
.reloc
.exp
, & mystr
))
5995 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BLX
;
5996 inst
.reloc
.pc_rel
= 1;
5999 end_of_line (mystr
);
6002 /* ARM V5 breakpoint instruction (argument parse)
6003 BKPT <16 bit unsigned immediate>
6004 Instruction is not conditional.
6005 The bit pattern given in insns[] has the COND_ALWAYS condition,
6006 and it is an error if the caller tried to override that. */
6013 unsigned long number
;
6015 skip_whitespace (str
);
6017 /* Allow optional leading '#'. */
6018 if (is_immediate_prefix (* str
))
6021 memset (& expr
, '\0', sizeof (expr
));
6023 if (my_get_expression (& expr
, & str
)
6024 || (expr
.X_op
!= O_constant
6025 /* As a convenience we allow 'bkpt' without an operand. */
6026 && expr
.X_op
!= O_absent
))
6028 inst
.error
= _("bad expression");
6032 number
= expr
.X_add_number
;
6034 /* Check it fits a 16 bit unsigned. */
6035 if (number
!= (number
& 0xffff))
6037 inst
.error
= _("immediate value out of range");
6041 /* Top 12 of 16 bits to bits 19:8. */
6042 inst
.instruction
|= (number
& 0xfff0) << 4;
6044 /* Bottom 4 of 16 bits to bits 3:0. */
6045 inst
.instruction
|= number
& 0xf;
6050 /* THUMB CPS instruction (argument parse). */
6056 do_cps_flags (&str
, /*thumb_p=*/1);
6060 /* THUMB CPY instruction (argument parse). */
6066 thumb_mov_compare (str
, THUMB_CPY
);
6069 /* THUMB SETEND instruction (argument parse). */
6075 if (do_endian_specifier (str
))
6076 inst
.instruction
|= 0x8;
6079 static unsigned long check_iwmmxt_insn
PARAMS ((char *, enum iwmmxt_insn_type
, int));
6081 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate. */
6083 static unsigned long
6084 check_iwmmxt_insn (str
, insn_type
, immediate_size
)
6086 enum iwmmxt_insn_type insn_type
;
6090 const char * inst_error
;
6092 unsigned long number
;
6094 inst_error
= inst
.error
;
6096 inst
.error
= BAD_ARGS
;
6097 skip_whitespace (str
);
6102 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
6107 if ((wreg_required_here (&str
, 0, IWMMXT_REG_WR
)) == FAIL
)
6112 if ((wreg_required_here (&str
, 12, IWMMXT_REG_WR
) == FAIL
6113 || skip_past_comma (&str
) == FAIL
6114 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
))
6119 if ((wreg_required_here (&str
, 12, IWMMXT_REG_WR
) == FAIL
6120 || skip_past_comma (&str
) == FAIL
6121 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6122 || skip_past_comma (&str
) == FAIL
6123 || wreg_required_here (&str
, 0, IWMMXT_REG_WR
) == FAIL
))
6128 if ((wreg_required_here (&str
, 12, IWMMXT_REG_WR
) == FAIL
6129 || skip_past_comma (&str
) == FAIL
6130 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6131 || skip_past_comma (&str
) == FAIL
6132 || wreg_required_here (&str
, 0, IWMMXT_REG_WCG
) == FAIL
))
6137 if ((wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6138 || skip_past_comma (&str
) == FAIL
6139 || reg_required_here (&str
, 12) == FAIL
))
6144 if ((reg_required_here (&str
, 12) == FAIL
6145 || skip_past_comma (&str
) == FAIL
6146 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
))
6151 if ((wreg_required_here (&str
, 5, IWMMXT_REG_WR
) == FAIL
6152 || skip_past_comma (&str
) == FAIL
6153 || reg_required_here (&str
, 0) == FAIL
6154 || skip_past_comma (&str
) == FAIL
6155 || reg_required_here (&str
, 12) == FAIL
))
6160 if ((wreg_required_here (&str
, 0, IWMMXT_REG_WR
) == FAIL
6161 || skip_past_comma (&str
) == FAIL
6162 || reg_required_here (&str
, 12) == FAIL
6163 || skip_past_comma (&str
) == FAIL
6164 || reg_required_here (&str
, 16) == FAIL
))
6169 if ((reg_required_here (&str
, 12) == FAIL
6170 || skip_past_comma (&str
) == FAIL
6171 || reg_required_here (&str
, 16) == FAIL
6172 || skip_past_comma (&str
) == FAIL
6173 || wreg_required_here (&str
, 0, IWMMXT_REG_WR
) == FAIL
))
6178 if ((wreg_required_here (&str
, 16, IWMMXT_REG_WC
) == FAIL
6179 || skip_past_comma (&str
) == FAIL
6180 || reg_required_here (&str
, 12) == FAIL
))
6185 if ((reg_required_here (&str
, 12) == FAIL
6186 || skip_past_comma (&str
) == FAIL
6187 || wreg_required_here (&str
, 16, IWMMXT_REG_WC
) == FAIL
))
6192 if ((wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6193 || skip_past_comma (&str
) == FAIL
6194 || reg_required_here (&str
, 12) == FAIL
6195 || skip_past_comma (&str
) == FAIL
))
6200 if ((reg_required_here (&str
, 12) == FAIL
6201 || skip_past_comma (&str
) == FAIL
))
6206 if ((wreg_required_here (&str
, 12, IWMMXT_REG_WR
) == FAIL
6207 || skip_past_comma (&str
) == FAIL
6208 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6209 || skip_past_comma (&str
) == FAIL
6210 || wreg_required_here (&str
, 0, IWMMXT_REG_WR
) == FAIL
6211 || skip_past_comma (&str
) == FAIL
))
6216 if ((reg_required_here (&str
, 12) == FAIL
6217 || skip_past_comma (&str
) == FAIL
6218 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6219 || skip_past_comma (&str
) == FAIL
))
6224 if ((wreg_required_here (&str
, 12, IWMMXT_REG_WR
) == FAIL
6225 || skip_past_comma (&str
) == FAIL
6226 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6227 || skip_past_comma (&str
) == FAIL
))
6232 if (immediate_size
== 0)
6235 inst
.error
= inst_error
;
6240 skip_whitespace (str
);
6242 /* Allow optional leading '#'. */
6243 if (is_immediate_prefix (* str
))
6246 memset (& expr
, '\0', sizeof (expr
));
6248 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
6250 inst
.error
= _("bad or missing expression");
6254 number
= expr
.X_add_number
;
6256 if (number
!= (number
& immediate_size
))
6258 inst
.error
= _("immediate value out of range");
6262 inst
.error
= inst_error
;
6268 do_iwmmxt_byte_addr (str
)
6271 int op
= (inst
.instruction
& 0x300) >> 8;
6274 inst
.instruction
&= ~0x300;
6275 inst
.instruction
|= (op
& 1) << 22 | (op
& 2) << 7;
6277 skip_whitespace (str
);
6279 if ((reg
= wreg_required_here (&str
, 12, IWMMXT_REG_WR_OR_WC
)) == FAIL
6280 || skip_past_comma (& str
) == FAIL
6281 || cp_byte_address_required_here (&str
) == FAIL
)
6284 inst
.error
= BAD_ARGS
;
6289 if (wc_register (reg
))
6291 as_bad (_("non-word size not supported with control register"));
6292 inst
.instruction
|= 0xf0000100;
6293 inst
.instruction
&= ~0x00400000;
6298 do_iwmmxt_tandc (str
)
6303 reg
= check_iwmmxt_insn (str
, check_rd
, 0);
6305 if (reg
!= REG_PC
&& !inst
.error
)
6306 inst
.error
= _("only r15 allowed here");
6310 do_iwmmxt_tbcst (str
)
6313 check_iwmmxt_insn (str
, check_tbcst
, 0);
6317 do_iwmmxt_textrc (str
)
6320 unsigned long number
;
6322 if ((number
= check_iwmmxt_insn (str
, check_textrc
, 7)) == (unsigned long) FAIL
)
6325 inst
.instruction
|= number
& 0x7;
6329 do_iwmmxt_textrm (str
)
6332 unsigned long number
;
6334 if ((number
= check_iwmmxt_insn (str
, check_textrm
, 7)) == (unsigned long) FAIL
)
6337 inst
.instruction
|= number
& 0x7;
6341 do_iwmmxt_tinsr (str
)
6344 unsigned long number
;
6346 if ((number
= check_iwmmxt_insn (str
, check_tinsr
, 7)) == (unsigned long) FAIL
)
6349 inst
.instruction
|= number
& 0x7;
6353 do_iwmmxt_tmcr (str
)
6356 check_iwmmxt_insn (str
, check_tmcr
, 0);
6360 do_iwmmxt_tmcrr (str
)
6363 check_iwmmxt_insn (str
, check_tmcrr
, 0);
6367 do_iwmmxt_tmia (str
)
6370 check_iwmmxt_insn (str
, check_tmia
, 0);
6374 do_iwmmxt_tmovmsk (str
)
6377 check_iwmmxt_insn (str
, check_tmovmsk
, 0);
6381 do_iwmmxt_tmrc (str
)
6384 check_iwmmxt_insn (str
, check_tmrc
, 0);
6388 do_iwmmxt_tmrrc (str
)
6391 check_iwmmxt_insn (str
, check_tmrrc
, 0);
6395 do_iwmmxt_torc (str
)
6398 check_iwmmxt_insn (str
, check_rd
, 0);
6402 do_iwmmxt_waligni (str
)
6405 unsigned long number
;
6407 if ((number
= check_iwmmxt_insn (str
, check_waligni
, 7)) == (unsigned long) FAIL
)
6410 inst
.instruction
|= ((number
& 0x7) << 20);
6414 do_iwmmxt_wmov (str
)
6417 if (check_iwmmxt_insn (str
, check_wrwr
, 0) == (unsigned long) FAIL
)
6420 inst
.instruction
|= ((inst
.instruction
>> 16) & 0xf);
6424 do_iwmmxt_word_addr (str
)
6427 int op
= (inst
.instruction
& 0x300) >> 8;
6430 inst
.instruction
&= ~0x300;
6431 inst
.instruction
|= (op
& 1) << 22 | (op
& 2) << 7;
6433 skip_whitespace (str
);
6435 if ((reg
= wreg_required_here (&str
, 12, IWMMXT_REG_WR_OR_WC
)) == FAIL
6436 || skip_past_comma (& str
) == FAIL
6437 || cp_address_required_here (& str
, CP_WB_OK
) == FAIL
)
6440 inst
.error
= BAD_ARGS
;
6445 if (wc_register (reg
))
6447 if ((inst
.instruction
& COND_MASK
) != COND_ALWAYS
)
6448 as_bad (_("conditional execution not supported with control register"));
6450 as_bad (_("non-word size not supported with control register"));
6451 inst
.instruction
|= 0xf0000100;
6452 inst
.instruction
&= ~0x00400000;
6457 do_iwmmxt_wrwr (str
)
6460 check_iwmmxt_insn (str
, check_wrwr
, 0);
6464 do_iwmmxt_wrwrwcg (str
)
6467 check_iwmmxt_insn (str
, check_wrwrwcg
, 0);
6471 do_iwmmxt_wrwrwr (str
)
6474 check_iwmmxt_insn (str
, check_wrwrwr
, 0);
6478 do_iwmmxt_wshufh (str
)
6481 unsigned long number
;
6483 if ((number
= check_iwmmxt_insn (str
, check_wshufh
, 0xff)) == (unsigned long) FAIL
)
6486 inst
.instruction
|= ((number
& 0xf0) << 16) | (number
& 0xf);
6490 do_iwmmxt_wzero (str
)
6493 if (check_iwmmxt_insn (str
, check_wr
, 0) == (unsigned long) FAIL
)
6496 inst
.instruction
|= ((inst
.instruction
& 0xf) << 12) | ((inst
.instruction
& 0xf) << 16);
6499 /* Xscale multiply-accumulate (argument parse)
6502 MIAxycc acc0,Rm,Rs. */
6511 if (accum0_required_here (& str
) == FAIL
)
6512 inst
.error
= ERR_NO_ACCUM
;
6514 else if (skip_past_comma (& str
) == FAIL
6515 || (rm
= reg_required_here (& str
, 0)) == FAIL
)
6516 inst
.error
= BAD_ARGS
;
6518 else if (skip_past_comma (& str
) == FAIL
6519 || (rs
= reg_required_here (& str
, 12)) == FAIL
)
6520 inst
.error
= BAD_ARGS
;
6522 /* inst.instruction has now been zapped with both rm and rs. */
6523 else if (rm
== REG_PC
|| rs
== REG_PC
)
6524 inst
.error
= BAD_PC
; /* Undefined result if rm or rs is R15. */
6530 /* Xscale move-accumulator-register (argument parse)
6532 MARcc acc0,RdLo,RdHi. */
6540 if (accum0_required_here (& str
) == FAIL
)
6541 inst
.error
= ERR_NO_ACCUM
;
6543 else if (skip_past_comma (& str
) == FAIL
6544 || (rdlo
= reg_required_here (& str
, 12)) == FAIL
)
6545 inst
.error
= BAD_ARGS
;
6547 else if (skip_past_comma (& str
) == FAIL
6548 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
6549 inst
.error
= BAD_ARGS
;
6551 /* inst.instruction has now been zapped with both rdlo and rdhi. */
6552 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
6553 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
6559 /* Xscale move-register-accumulator (argument parse)
6561 MRAcc RdLo,RdHi,acc0. */
6570 skip_whitespace (str
);
6572 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
)
6573 inst
.error
= BAD_ARGS
;
6575 else if (skip_past_comma (& str
) == FAIL
6576 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
6577 inst
.error
= BAD_ARGS
;
6579 else if (skip_past_comma (& str
) == FAIL
6580 || accum0_required_here (& str
) == FAIL
)
6581 inst
.error
= ERR_NO_ACCUM
;
6583 /* inst.instruction has now been zapped with both rdlo and rdhi. */
6584 else if (rdlo
== rdhi
)
6585 inst
.error
= BAD_ARGS
; /* Undefined result if 2 writes to same reg. */
6587 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
6588 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
6593 /* ARMv5TE: Preload-Cache
6597 Syntactically, like LDR with B=1, W=0, L=1. */
6605 skip_whitespace (str
);
6609 inst
.error
= _("'[' expected after PLD mnemonic");
6614 skip_whitespace (str
);
6616 if ((rd
= reg_required_here (& str
, 16)) == FAIL
)
6619 skip_whitespace (str
);
6625 skip_whitespace (str
);
6627 /* Post-indexed addressing is not allowed with PLD. */
6628 if (skip_past_comma (&str
) == SUCCESS
)
6631 = _("post-indexed expression used in preload instruction");
6634 else if (*str
== '!') /* [Rn]! */
6636 inst
.error
= _("writeback used in preload instruction");
6640 inst
.instruction
|= INDEX_UP
| PRE_INDEX
;
6642 else /* [Rn, ...] */
6644 if (skip_past_comma (& str
) == FAIL
)
6646 inst
.error
= _("pre-indexed expression expected");
6650 if (ldst_extend (&str
) == FAIL
)
6653 skip_whitespace (str
);
6657 inst
.error
= _("missing ]");
6662 skip_whitespace (str
);
6664 if (* str
== '!') /* [Rn]! */
6666 inst
.error
= _("writeback used in preload instruction");
6670 inst
.instruction
|= PRE_INDEX
;
6676 /* ARMv5TE load-consecutive (argument parse)
6689 skip_whitespace (str
);
6691 if ((rd
= reg_required_here (& str
, 12)) == FAIL
)
6693 inst
.error
= BAD_ARGS
;
6697 if (skip_past_comma (& str
) == FAIL
6698 || (rn
= ld_mode_required_here (& str
)) == FAIL
)
6701 inst
.error
= BAD_ARGS
;
6705 /* inst.instruction has now been zapped with Rd and the addressing mode. */
6706 if (rd
& 1) /* Unpredictable result if Rd is odd. */
6708 inst
.error
= _("destination register must be even");
6714 inst
.error
= _("r14 not allowed here");
6718 if (((rd
== rn
) || (rd
+ 1 == rn
))
6719 && ((inst
.instruction
& WRITE_BACK
)
6720 || (!(inst
.instruction
& PRE_INDEX
))))
6721 as_warn (_("pre/post-indexing used when modified address register is destination"));
6723 /* For an index-register load, the index register must not overlap the
6724 destination (even if not write-back). */
6725 if ((inst
.instruction
& V4_STR_BIT
) == 0
6726 && (inst
.instruction
& HWOFFSET_IMM
) == 0)
6728 int rm
= inst
.instruction
& 0x0000000f;
6730 if (rm
== rd
|| (rm
== rd
+ 1))
6731 as_warn (_("ldrd destination registers must not overlap index register"));
6737 /* Returns the index into fp_values of a floating point number,
6738 or -1 if not in the table. */
6741 my_get_float_expression (str
)
6744 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6750 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
6752 /* Look for a raw floating point number. */
6753 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
6754 && is_end_of_line
[(unsigned char) *save_in
])
6756 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
6758 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
6760 if (words
[j
] != fp_values
[i
][j
])
6764 if (j
== MAX_LITTLENUMS
)
6772 /* Try and parse a more complex expression, this will probably fail
6773 unless the code uses a floating point prefix (eg "0f"). */
6774 save_in
= input_line_pointer
;
6775 input_line_pointer
= *str
;
6776 if (expression (&exp
) == absolute_section
6777 && exp
.X_op
== O_big
6778 && exp
.X_add_number
< 0)
6780 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
6782 if (gen_to_words (words
, 5, (long) 15) == 0)
6784 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
6786 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
6788 if (words
[j
] != fp_values
[i
][j
])
6792 if (j
== MAX_LITTLENUMS
)
6794 *str
= input_line_pointer
;
6795 input_line_pointer
= save_in
;
6802 *str
= input_line_pointer
;
6803 input_line_pointer
= save_in
;
6807 /* Return TRUE if anything in the expression is a bignum. */
6810 walk_no_bignums (sp
)
6813 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
6816 if (symbol_get_value_expression (sp
)->X_add_symbol
)
6818 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
6819 || (symbol_get_value_expression (sp
)->X_op_symbol
6820 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
6826 static int in_my_get_expression
= 0;
6829 my_get_expression (ep
, str
)
6836 save_in
= input_line_pointer
;
6837 input_line_pointer
= *str
;
6838 in_my_get_expression
= 1;
6839 seg
= expression (ep
);
6840 in_my_get_expression
= 0;
6842 if (ep
->X_op
== O_illegal
)
6844 /* We found a bad expression in md_operand(). */
6845 *str
= input_line_pointer
;
6846 input_line_pointer
= save_in
;
6851 if (seg
!= absolute_section
6852 && seg
!= text_section
6853 && seg
!= data_section
6854 && seg
!= bss_section
6855 && seg
!= undefined_section
)
6857 inst
.error
= _("bad_segment");
6858 *str
= input_line_pointer
;
6859 input_line_pointer
= save_in
;
6864 /* Get rid of any bignums now, so that we don't generate an error for which
6865 we can't establish a line number later on. Big numbers are never valid
6866 in instructions, which is where this routine is always called. */
6867 if (ep
->X_op
== O_big
6868 || (ep
->X_add_symbol
6869 && (walk_no_bignums (ep
->X_add_symbol
)
6871 && walk_no_bignums (ep
->X_op_symbol
)))))
6873 inst
.error
= _("invalid constant");
6874 *str
= input_line_pointer
;
6875 input_line_pointer
= save_in
;
6879 *str
= input_line_pointer
;
6880 input_line_pointer
= save_in
;
6884 /* We handle all bad expressions here, so that we can report the faulty
6885 instruction in the error message. */
6890 if (in_my_get_expression
)
6892 expr
->X_op
= O_illegal
;
6893 if (inst
.error
== NULL
)
6894 inst
.error
= _("bad expression");
6898 /* KIND indicates what kind of shifts are accepted. */
6901 decode_shift (str
, kind
)
6905 const struct asm_shift_name
* shift
;
6909 skip_whitespace (* str
);
6911 for (p
= * str
; ISALPHA (* p
); p
++)
6916 inst
.error
= _("shift expression expected");
6922 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
6927 inst
.error
= _("shift expression expected");
6931 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
6933 if (kind
== SHIFT_LSL_OR_ASR_IMMEDIATE
6934 && shift
->properties
->index
!= SHIFT_LSL
6935 && shift
->properties
->index
!= SHIFT_ASR
)
6937 inst
.error
= _("'LSL' or 'ASR' required");
6940 else if (kind
== SHIFT_LSL_IMMEDIATE
6941 && shift
->properties
->index
!= SHIFT_LSL
)
6943 inst
.error
= _("'LSL' required");
6946 else if (kind
== SHIFT_ASR_IMMEDIATE
6947 && shift
->properties
->index
!= SHIFT_ASR
)
6949 inst
.error
= _("'ASR' required");
6953 if (shift
->properties
->index
== SHIFT_RRX
)
6956 inst
.instruction
|= shift
->properties
->bit_field
;
6960 skip_whitespace (p
);
6962 if (kind
== NO_SHIFT_RESTRICT
&& reg_required_here (& p
, 8) != FAIL
)
6964 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
6968 else if (! is_immediate_prefix (* p
))
6970 inst
.error
= (NO_SHIFT_RESTRICT
6971 ? _("shift requires register or #expression")
6972 : _("shift requires #expression"));
6980 if (my_get_expression (& inst
.reloc
.exp
, & p
))
6983 /* Validate some simple #expressions. */
6984 if (inst
.reloc
.exp
.X_op
== O_constant
)
6986 unsigned num
= inst
.reloc
.exp
.X_add_number
;
6988 /* Reject operations greater than 32. */
6990 /* Reject a shift of 0 unless the mode allows it. */
6991 || (num
== 0 && shift
->properties
->allows_0
== 0)
6992 /* Reject a shift of 32 unless the mode allows it. */
6993 || (num
== 32 && shift
->properties
->allows_32
== 0)
6996 /* As a special case we allow a shift of zero for
6997 modes that do not support it to be recoded as an
6998 logical shift left of zero (ie nothing). We warn
6999 about this though. */
7002 as_warn (_("shift of 0 ignored."));
7003 shift
= & shift_names
[0];
7004 assert (shift
->properties
->index
== SHIFT_LSL
);
7008 inst
.error
= _("invalid immediate shift");
7013 /* Shifts of 32 are encoded as 0, for those shifts that
7018 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
7022 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
7023 inst
.reloc
.pc_rel
= 0;
7024 inst
.instruction
|= shift
->properties
->bit_field
;
7031 /* Do those data_ops which can take a negative immediate constant
7032 by altering the instruction. A bit of a hack really.
7036 by inverting the second operand, and
7039 by negating the second operand. */
7042 negate_data_op (instruction
, value
)
7043 unsigned long * instruction
;
7044 unsigned long value
;
7047 unsigned long negated
, inverted
;
7049 negated
= validate_immediate (-value
);
7050 inverted
= validate_immediate (~value
);
7052 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
7055 /* First negates. */
7056 case OPCODE_SUB
: /* ADD <-> SUB */
7057 new_inst
= OPCODE_ADD
;
7062 new_inst
= OPCODE_SUB
;
7066 case OPCODE_CMP
: /* CMP <-> CMN */
7067 new_inst
= OPCODE_CMN
;
7072 new_inst
= OPCODE_CMP
;
7076 /* Now Inverted ops. */
7077 case OPCODE_MOV
: /* MOV <-> MVN */
7078 new_inst
= OPCODE_MVN
;
7083 new_inst
= OPCODE_MOV
;
7087 case OPCODE_AND
: /* AND <-> BIC */
7088 new_inst
= OPCODE_BIC
;
7093 new_inst
= OPCODE_AND
;
7097 case OPCODE_ADC
: /* ADC <-> SBC */
7098 new_inst
= OPCODE_SBC
;
7103 new_inst
= OPCODE_ADC
;
7107 /* We cannot do anything. */
7112 if (value
== (unsigned) FAIL
)
7115 *instruction
&= OPCODE_MASK
;
7116 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
7127 skip_whitespace (* str
);
7129 if (reg_required_here (str
, 0) != FAIL
)
7131 if (skip_past_comma (str
) == SUCCESS
)
7132 /* Shift operation on register. */
7133 return decode_shift (str
, NO_SHIFT_RESTRICT
);
7139 /* Immediate expression. */
7140 if (is_immediate_prefix (**str
))
7145 if (my_get_expression (&inst
.reloc
.exp
, str
))
7148 if (inst
.reloc
.exp
.X_add_symbol
)
7150 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
7151 inst
.reloc
.pc_rel
= 0;
7155 if (skip_past_comma (str
) == SUCCESS
)
7157 /* #x, y -- ie explicit rotation by Y. */
7158 if (my_get_expression (&expr
, str
))
7161 if (expr
.X_op
!= O_constant
)
7163 inst
.error
= _("constant expression expected");
7167 /* Rotate must be a multiple of 2. */
7168 if (((unsigned) expr
.X_add_number
) > 30
7169 || (expr
.X_add_number
& 1) != 0
7170 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
7172 inst
.error
= _("invalid constant");
7175 inst
.instruction
|= INST_IMMEDIATE
;
7176 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
7177 inst
.instruction
|= expr
.X_add_number
<< 7;
7181 /* Implicit rotation, select a suitable one. */
7182 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
7186 /* Can't be done. Perhaps the code reads something like
7187 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
7188 if ((value
= negate_data_op (&inst
.instruction
,
7189 inst
.reloc
.exp
.X_add_number
))
7192 inst
.error
= _("invalid constant");
7197 inst
.instruction
|= value
;
7200 inst
.instruction
|= INST_IMMEDIATE
;
7205 inst
.error
= _("register or shift expression expected");
7214 skip_whitespace (* str
);
7216 if (fp_reg_required_here (str
, 0) != FAIL
)
7220 /* Immediate expression. */
7221 if (*((*str
)++) == '#')
7227 skip_whitespace (* str
);
7229 /* First try and match exact strings, this is to guarantee
7230 that some formats will work even for cross assembly. */
7232 for (i
= 0; fp_const
[i
]; i
++)
7234 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
7238 *str
+= strlen (fp_const
[i
]);
7239 if (is_end_of_line
[(unsigned char) **str
])
7241 inst
.instruction
|= i
+ 8;
7248 /* Just because we didn't get a match doesn't mean that the
7249 constant isn't valid, just that it is in a format that we
7250 don't automatically recognize. Try parsing it with
7251 the standard expression routines. */
7252 if ((i
= my_get_float_expression (str
)) >= 0)
7254 inst
.instruction
|= i
+ 8;
7258 inst
.error
= _("invalid floating point immediate expression");
7262 _("floating point register or immediate expression expected");
7271 skip_whitespace (str
);
7273 if (reg_required_here (&str
, 12) == FAIL
7274 || skip_past_comma (&str
) == FAIL
7275 || reg_required_here (&str
, 16) == FAIL
7276 || skip_past_comma (&str
) == FAIL
7277 || data_op2 (&str
) == FAIL
)
7280 inst
.error
= BAD_ARGS
;
7291 /* This is a pseudo-op of the form "adr rd, label" to be converted
7292 into a relative address of the form "add rd, pc, #label-.-8". */
7293 skip_whitespace (str
);
7295 if (reg_required_here (&str
, 12) == FAIL
7296 || skip_past_comma (&str
) == FAIL
7297 || my_get_expression (&inst
.reloc
.exp
, &str
))
7300 inst
.error
= BAD_ARGS
;
7304 /* Frag hacking will turn this into a sub instruction if the offset turns
7305 out to be negative. */
7306 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
7308 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
7310 inst
.reloc
.pc_rel
= 1;
7319 /* This is a pseudo-op of the form "adrl rd, label" to be converted
7320 into a relative address of the form:
7321 add rd, pc, #low(label-.-8)"
7322 add rd, rd, #high(label-.-8)" */
7324 skip_whitespace (str
);
7326 if (reg_required_here (&str
, 12) == FAIL
7327 || skip_past_comma (&str
) == FAIL
7328 || my_get_expression (&inst
.reloc
.exp
, &str
))
7331 inst
.error
= BAD_ARGS
;
7337 /* Frag hacking will turn this into a sub instruction if the offset turns
7338 out to be negative. */
7339 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
7341 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
7343 inst
.reloc
.pc_rel
= 1;
7344 inst
.size
= INSN_SIZE
* 2;
7351 skip_whitespace (str
);
7353 if (reg_required_here (&str
, 16) == FAIL
)
7356 inst
.error
= BAD_ARGS
;
7360 if (skip_past_comma (&str
) == FAIL
7361 || data_op2 (&str
) == FAIL
)
7364 inst
.error
= BAD_ARGS
;
7375 skip_whitespace (str
);
7377 if (reg_required_here (&str
, 12) == FAIL
)
7380 inst
.error
= BAD_ARGS
;
7384 if (skip_past_comma (&str
) == FAIL
7385 || data_op2 (&str
) == FAIL
)
7388 inst
.error
= BAD_ARGS
;
7406 if (my_get_expression (& inst
.reloc
.exp
, str
))
7409 if (inst
.reloc
.exp
.X_op
== O_constant
)
7411 int value
= inst
.reloc
.exp
.X_add_number
;
7413 if (value
< -4095 || value
> 4095)
7415 inst
.error
= _("address offset too large");
7425 inst
.instruction
|= add
| value
;
7429 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
7430 inst
.reloc
.pc_rel
= 0;
7443 if (reg_required_here (str
, 0) == FAIL
)
7446 inst
.instruction
|= add
| OFFSET_REG
;
7447 if (skip_past_comma (str
) == SUCCESS
)
7448 return decode_shift (str
, SHIFT_IMMEDIATE
);
7462 skip_whitespace (str
);
7464 if ((conflict_reg
= reg_required_here (&str
, 12)) == FAIL
)
7467 inst
.error
= BAD_ARGS
;
7471 if (skip_past_comma (&str
) == FAIL
)
7473 inst
.error
= _("address expected");
7483 skip_whitespace (str
);
7485 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
7488 /* Conflicts can occur on stores as well as loads. */
7489 conflict_reg
= (conflict_reg
== reg
);
7491 skip_whitespace (str
);
7497 if (skip_past_comma (&str
) == SUCCESS
)
7499 /* [Rn],... (post inc) */
7500 if (ldst_extend (&str
) == FAIL
)
7503 as_warn (_("%s register same as write-back base"),
7504 ((inst
.instruction
& LOAD_BIT
)
7505 ? _("destination") : _("source")));
7510 skip_whitespace (str
);
7515 as_warn (_("%s register same as write-back base"),
7516 ((inst
.instruction
& LOAD_BIT
)
7517 ? _("destination") : _("source")));
7519 inst
.instruction
|= WRITE_BACK
;
7522 inst
.instruction
|= INDEX_UP
;
7529 if (skip_past_comma (&str
) == FAIL
)
7531 inst
.error
= _("pre-indexed expression expected");
7536 if (ldst_extend (&str
) == FAIL
)
7539 skip_whitespace (str
);
7543 inst
.error
= _("missing ]");
7547 skip_whitespace (str
);
7552 as_warn (_("%s register same as write-back base"),
7553 ((inst
.instruction
& LOAD_BIT
)
7554 ? _("destination") : _("source")));
7556 inst
.instruction
|= WRITE_BACK
;
7560 else if (*str
== '=')
7562 if ((inst
.instruction
& LOAD_BIT
) == 0)
7564 inst
.error
= _("invalid pseudo operation");
7568 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
7571 skip_whitespace (str
);
7573 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7576 if (inst
.reloc
.exp
.X_op
!= O_constant
7577 && inst
.reloc
.exp
.X_op
!= O_symbol
)
7579 inst
.error
= _("constant expression expected");
7583 if (inst
.reloc
.exp
.X_op
== O_constant
)
7585 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
7589 /* This can be done with a mov instruction. */
7590 inst
.instruction
&= LITERAL_MASK
;
7591 inst
.instruction
|= (INST_IMMEDIATE
7592 | (OPCODE_MOV
<< DATA_OP_SHIFT
));
7593 inst
.instruction
|= value
& 0xfff;
7598 value
= validate_immediate (~inst
.reloc
.exp
.X_add_number
);
7602 /* This can be done with a mvn instruction. */
7603 inst
.instruction
&= LITERAL_MASK
;
7604 inst
.instruction
|= (INST_IMMEDIATE
7605 | (OPCODE_MVN
<< DATA_OP_SHIFT
));
7606 inst
.instruction
|= value
& 0xfff;
7612 /* Insert into literal pool. */
7613 if (add_to_lit_pool () == FAIL
)
7616 inst
.error
= _("literal pool insertion failed");
7620 /* Change the instruction exp to point to the pool. */
7621 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
7622 inst
.reloc
.pc_rel
= 1;
7623 inst
.instruction
|= (REG_PC
<< 16);
7628 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7631 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
7633 /* PC rel adjust. */
7634 inst
.reloc
.exp
.X_add_number
-= 8;
7636 inst
.reloc
.pc_rel
= 1;
7637 inst
.instruction
|= (REG_PC
<< 16);
7641 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
7651 skip_whitespace (str
);
7653 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
7656 inst
.error
= BAD_ARGS
;
7660 if (skip_past_comma (& str
) == FAIL
)
7662 inst
.error
= _("address expected");
7672 skip_whitespace (str
);
7674 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
7677 /* ldrt/strt always use post-indexed addressing, so if the base is
7678 the same as Rd, we warn. */
7679 if (conflict_reg
== reg
)
7680 as_warn (_("%s register same as write-back base"),
7681 ((inst
.instruction
& LOAD_BIT
)
7682 ? _("destination") : _("source")));
7684 skip_whitespace (str
);
7690 if (skip_past_comma (&str
) == SUCCESS
)
7692 /* [Rn],... (post inc) */
7693 if (ldst_extend (&str
) == FAIL
)
7699 skip_whitespace (str
);
7701 /* Skip a write-back '!'. */
7705 inst
.instruction
|= INDEX_UP
;
7710 inst
.error
= _("post-indexed expression expected");
7716 inst
.error
= _("post-indexed expression expected");
7724 ldst_extend_v4 (str
)
7734 if (my_get_expression (& inst
.reloc
.exp
, str
))
7737 if (inst
.reloc
.exp
.X_op
== O_constant
)
7739 int value
= inst
.reloc
.exp
.X_add_number
;
7741 if (value
< -255 || value
> 255)
7743 inst
.error
= _("address offset too large");
7753 /* Halfword and signextension instructions have the
7754 immediate value split across bits 11..8 and bits 3..0. */
7755 inst
.instruction
|= (add
| HWOFFSET_IMM
7756 | ((value
>> 4) << 8) | (value
& 0xF));
7760 inst
.instruction
|= HWOFFSET_IMM
;
7761 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
7762 inst
.reloc
.pc_rel
= 0;
7775 if (reg_required_here (str
, 0) == FAIL
)
7778 inst
.instruction
|= add
;
7783 /* Halfword and signed-byte load/store operations. */
7792 skip_whitespace (str
);
7794 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
7797 inst
.error
= BAD_ARGS
;
7801 if (skip_past_comma (& str
) == FAIL
)
7803 inst
.error
= _("address expected");
7813 skip_whitespace (str
);
7815 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
7818 /* Conflicts can occur on stores as well as loads. */
7819 conflict_reg
= (conflict_reg
== reg
);
7821 skip_whitespace (str
);
7827 if (skip_past_comma (&str
) == SUCCESS
)
7829 /* [Rn],... (post inc) */
7830 if (ldst_extend_v4 (&str
) == FAIL
)
7833 as_warn (_("%s register same as write-back base"),
7834 ((inst
.instruction
& LOAD_BIT
)
7835 ? _("destination") : _("source")));
7840 inst
.instruction
|= HWOFFSET_IMM
;
7842 skip_whitespace (str
);
7847 as_warn (_("%s register same as write-back base"),
7848 ((inst
.instruction
& LOAD_BIT
)
7849 ? _("destination") : _("source")));
7851 inst
.instruction
|= WRITE_BACK
;
7854 inst
.instruction
|= INDEX_UP
;
7861 if (skip_past_comma (&str
) == FAIL
)
7863 inst
.error
= _("pre-indexed expression expected");
7868 if (ldst_extend_v4 (&str
) == FAIL
)
7871 skip_whitespace (str
);
7875 inst
.error
= _("missing ]");
7879 skip_whitespace (str
);
7884 as_warn (_("%s register same as write-back base"),
7885 ((inst
.instruction
& LOAD_BIT
)
7886 ? _("destination") : _("source")));
7888 inst
.instruction
|= WRITE_BACK
;
7892 else if (*str
== '=')
7894 if ((inst
.instruction
& LOAD_BIT
) == 0)
7896 inst
.error
= _("invalid pseudo operation");
7900 /* XXX Does this work correctly for half-word/byte ops? */
7901 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
7904 skip_whitespace (str
);
7906 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7909 if (inst
.reloc
.exp
.X_op
!= O_constant
7910 && inst
.reloc
.exp
.X_op
!= O_symbol
)
7912 inst
.error
= _("constant expression expected");
7916 if (inst
.reloc
.exp
.X_op
== O_constant
)
7918 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
7922 /* This can be done with a mov instruction. */
7923 inst
.instruction
&= LITERAL_MASK
;
7924 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
7925 inst
.instruction
|= value
& 0xfff;
7930 value
= validate_immediate (~ inst
.reloc
.exp
.X_add_number
);
7934 /* This can be done with a mvn instruction. */
7935 inst
.instruction
&= LITERAL_MASK
;
7936 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MVN
<< DATA_OP_SHIFT
);
7937 inst
.instruction
|= value
& 0xfff;
7943 /* Insert into literal pool. */
7944 if (add_to_lit_pool () == FAIL
)
7947 inst
.error
= _("literal pool insertion failed");
7951 /* Change the instruction exp to point to the pool. */
7952 inst
.instruction
|= HWOFFSET_IMM
;
7953 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
7954 inst
.reloc
.pc_rel
= 1;
7955 inst
.instruction
|= (REG_PC
<< 16);
7960 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7963 inst
.instruction
|= HWOFFSET_IMM
;
7964 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
7966 /* PC rel adjust. */
7967 inst
.reloc
.exp
.X_add_number
-= 8;
7969 inst
.reloc
.pc_rel
= 1;
7970 inst
.instruction
|= (REG_PC
<< 16);
7974 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
7982 char * str
= * strp
;
7986 /* We come back here if we get ranges concatenated by '+' or '|'. */
8001 skip_whitespace (str
);
8003 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
8012 inst
.error
= _("bad range in register list");
8016 for (i
= cur_reg
+ 1; i
< reg
; i
++)
8018 if (range
& (1 << i
))
8020 (_("Warning: duplicated register (r%d) in register list"),
8028 if (range
& (1 << reg
))
8029 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
8031 else if (reg
<= cur_reg
)
8032 as_tsktsk (_("Warning: register range not in ascending order"));
8037 while (skip_past_comma (&str
) != FAIL
8038 || (in_range
= 1, *str
++ == '-'));
8040 skip_whitespace (str
);
8044 inst
.error
= _("missing `}'");
8052 if (my_get_expression (&expr
, &str
))
8055 if (expr
.X_op
== O_constant
)
8057 if (expr
.X_add_number
8058 != (expr
.X_add_number
& 0x0000ffff))
8060 inst
.error
= _("invalid register mask");
8064 if ((range
& expr
.X_add_number
) != 0)
8066 int regno
= range
& expr
.X_add_number
;
8069 regno
= (1 << regno
) - 1;
8071 (_("Warning: duplicated register (r%d) in register list"),
8075 range
|= expr
.X_add_number
;
8079 if (inst
.reloc
.type
!= 0)
8081 inst
.error
= _("expression too complex");
8085 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
8086 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
8087 inst
.reloc
.pc_rel
= 0;
8091 skip_whitespace (str
);
8093 if (*str
== '|' || *str
== '+')
8099 while (another_range
);
8112 skip_whitespace (str
);
8114 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
8117 if (base_reg
== REG_PC
)
8119 inst
.error
= _("r15 not allowed as base register");
8123 skip_whitespace (str
);
8127 inst
.instruction
|= WRITE_BACK
;
8131 if (skip_past_comma (&str
) == FAIL
8132 || (range
= reg_list (&str
)) == FAIL
)
8135 inst
.error
= BAD_ARGS
;
8142 inst
.instruction
|= LDM_TYPE_2_OR_3
;
8145 if (inst
.instruction
& WRITE_BACK
)
8147 /* Check for unpredictable uses of writeback. */
8148 if (inst
.instruction
& LOAD_BIT
)
8150 /* Not allowed in LDM type 2. */
8151 if ((inst
.instruction
& LDM_TYPE_2_OR_3
)
8152 && ((range
& (1 << REG_PC
)) == 0))
8153 as_warn (_("writeback of base register is UNPREDICTABLE"));
8154 /* Only allowed if base reg not in list for other types. */
8155 else if (range
& (1 << base_reg
))
8156 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
8160 /* Not allowed for type 2. */
8161 if (inst
.instruction
& LDM_TYPE_2_OR_3
)
8162 as_warn (_("writeback of base register is UNPREDICTABLE"));
8163 /* Only allowed if base reg not in list, or first in list. */
8164 else if ((range
& (1 << base_reg
))
8165 && (range
& ((1 << base_reg
) - 1)))
8166 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
8170 inst
.instruction
|= range
;
8178 skip_whitespace (str
);
8180 /* Allow optional leading '#'. */
8181 if (is_immediate_prefix (*str
))
8184 if (my_get_expression (& inst
.reloc
.exp
, & str
))
8187 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
8188 inst
.reloc
.pc_rel
= 0;
8198 skip_whitespace (str
);
8200 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
8205 inst
.error
= _("r15 not allowed in swap");
8209 if (skip_past_comma (&str
) == FAIL
8210 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
8213 inst
.error
= BAD_ARGS
;
8219 inst
.error
= _("r15 not allowed in swap");
8223 if (skip_past_comma (&str
) == FAIL
8226 inst
.error
= BAD_ARGS
;
8230 skip_whitespace (str
);
8232 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
8237 inst
.error
= BAD_PC
;
8241 skip_whitespace (str
);
8245 inst
.error
= _("missing ]");
8256 if (my_get_expression (&inst
.reloc
.exp
, &str
))
8263 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
8264 required for the instruction. */
8266 /* arm_parse_reloc () works on input_line_pointer.
8267 We actually want to parse the operands to the branch instruction
8268 passed in 'str'. Save the input pointer and restore it later. */
8269 save_in
= input_line_pointer
;
8270 input_line_pointer
= str
;
8271 if (inst
.reloc
.exp
.X_op
== O_symbol
8273 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
8275 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
8276 inst
.reloc
.pc_rel
= 0;
8277 /* Modify str to point to after parsed operands, otherwise
8278 end_of_line() will complain about the (PLT) left in str. */
8279 str
= input_line_pointer
;
8283 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
8284 inst
.reloc
.pc_rel
= 1;
8286 input_line_pointer
= save_in
;
8289 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
8290 inst
.reloc
.pc_rel
= 1;
8291 #endif /* OBJ_ELF */
8302 skip_whitespace (str
);
8304 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
8306 inst
.error
= BAD_ARGS
;
8310 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
8312 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
8321 /* Co-processor data operation.
8322 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
8323 skip_whitespace (str
);
8325 if (co_proc_number (&str
) == FAIL
)
8328 inst
.error
= BAD_ARGS
;
8332 if (skip_past_comma (&str
) == FAIL
8333 || cp_opc_expr (&str
, 20,4) == FAIL
)
8336 inst
.error
= BAD_ARGS
;
8340 if (skip_past_comma (&str
) == FAIL
8341 || cp_reg_required_here (&str
, 12) == FAIL
)
8344 inst
.error
= BAD_ARGS
;
8348 if (skip_past_comma (&str
) == FAIL
8349 || cp_reg_required_here (&str
, 16) == FAIL
)
8352 inst
.error
= BAD_ARGS
;
8356 if (skip_past_comma (&str
) == FAIL
8357 || cp_reg_required_here (&str
, 0) == FAIL
)
8360 inst
.error
= BAD_ARGS
;
8364 if (skip_past_comma (&str
) == SUCCESS
)
8366 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
8369 inst
.error
= BAD_ARGS
;
8381 /* Co-processor register load/store.
8382 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
8384 skip_whitespace (str
);
8386 if (co_proc_number (&str
) == FAIL
)
8389 inst
.error
= BAD_ARGS
;
8393 if (skip_past_comma (&str
) == FAIL
8394 || cp_reg_required_here (&str
, 12) == FAIL
)
8397 inst
.error
= BAD_ARGS
;
8401 if (skip_past_comma (&str
) == FAIL
8402 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
8405 inst
.error
= BAD_ARGS
;
8416 /* Co-processor register transfer.
8417 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
8419 skip_whitespace (str
);
8421 if (co_proc_number (&str
) == FAIL
)
8424 inst
.error
= BAD_ARGS
;
8428 if (skip_past_comma (&str
) == FAIL
8429 || cp_opc_expr (&str
, 21, 3) == FAIL
)
8432 inst
.error
= BAD_ARGS
;
8436 if (skip_past_comma (&str
) == FAIL
8437 || reg_required_here (&str
, 12) == FAIL
)
8440 inst
.error
= BAD_ARGS
;
8444 if (skip_past_comma (&str
) == FAIL
8445 || cp_reg_required_here (&str
, 16) == FAIL
)
8448 inst
.error
= BAD_ARGS
;
8452 if (skip_past_comma (&str
) == FAIL
8453 || cp_reg_required_here (&str
, 0) == FAIL
)
8456 inst
.error
= BAD_ARGS
;
8460 if (skip_past_comma (&str
) == SUCCESS
)
8462 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
8465 inst
.error
= BAD_ARGS
;
8477 /* FP control registers.
8478 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
8480 skip_whitespace (str
);
8482 if (reg_required_here (&str
, 12) == FAIL
)
8485 inst
.error
= BAD_ARGS
;
8496 skip_whitespace (str
);
8498 if (fp_reg_required_here (&str
, 12) == FAIL
)
8501 inst
.error
= BAD_ARGS
;
8505 if (skip_past_comma (&str
) == FAIL
8506 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
8509 inst
.error
= BAD_ARGS
;
8522 skip_whitespace (str
);
8524 if (fp_reg_required_here (&str
, 12) == FAIL
)
8527 inst
.error
= BAD_ARGS
;
8531 /* Get Number of registers to transfer. */
8532 if (skip_past_comma (&str
) == FAIL
8533 || my_get_expression (&inst
.reloc
.exp
, &str
))
8536 inst
.error
= _("constant expression expected");
8540 if (inst
.reloc
.exp
.X_op
!= O_constant
)
8542 inst
.error
= _("constant value required for number of registers");
8546 num_regs
= inst
.reloc
.exp
.X_add_number
;
8548 if (num_regs
< 1 || num_regs
> 4)
8550 inst
.error
= _("number of registers must be in the range [1:4]");
8557 inst
.instruction
|= CP_T_X
;
8560 inst
.instruction
|= CP_T_Y
;
8563 inst
.instruction
|= CP_T_Y
| CP_T_X
;
8571 if (inst
.instruction
& (CP_T_Pre
| CP_T_UD
)) /* ea/fd format. */
8577 /* The instruction specified "ea" or "fd", so we can only accept
8578 [Rn]{!}. The instruction does not really support stacking or
8579 unstacking, so we have to emulate these by setting appropriate
8580 bits and offsets. */
8581 if (skip_past_comma (&str
) == FAIL
8585 inst
.error
= BAD_ARGS
;
8590 skip_whitespace (str
);
8592 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
8595 skip_whitespace (str
);
8599 inst
.error
= BAD_ARGS
;
8611 _("r15 not allowed as base register with write-back");
8618 if (inst
.instruction
& CP_T_Pre
)
8620 /* Pre-decrement. */
8621 offset
= 3 * num_regs
;
8623 inst
.instruction
|= CP_T_WB
;
8627 /* Post-increment. */
8630 inst
.instruction
|= CP_T_WB
;
8631 offset
= 3 * num_regs
;
8635 /* No write-back, so convert this into a standard pre-increment
8636 instruction -- aesthetically more pleasing. */
8637 inst
.instruction
|= CP_T_Pre
| CP_T_UD
;
8642 inst
.instruction
|= offset
;
8644 else if (skip_past_comma (&str
) == FAIL
8645 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
8648 inst
.error
= BAD_ARGS
;
8659 skip_whitespace (str
);
8661 if (fp_reg_required_here (&str
, 12) == FAIL
)
8664 inst
.error
= BAD_ARGS
;
8668 if (skip_past_comma (&str
) == FAIL
8669 || fp_reg_required_here (&str
, 16) == FAIL
)
8672 inst
.error
= BAD_ARGS
;
8676 if (skip_past_comma (&str
) == FAIL
8677 || fp_op2 (&str
) == FAIL
)
8680 inst
.error
= BAD_ARGS
;
8688 do_fpa_monadic (str
)
8691 skip_whitespace (str
);
8693 if (fp_reg_required_here (&str
, 12) == FAIL
)
8696 inst
.error
= BAD_ARGS
;
8700 if (skip_past_comma (&str
) == FAIL
8701 || fp_op2 (&str
) == FAIL
)
8704 inst
.error
= BAD_ARGS
;
8715 skip_whitespace (str
);
8717 if (fp_reg_required_here (&str
, 16) == FAIL
)
8720 inst
.error
= BAD_ARGS
;
8724 if (skip_past_comma (&str
) == FAIL
8725 || fp_op2 (&str
) == FAIL
)
8728 inst
.error
= BAD_ARGS
;
8736 do_fpa_from_reg (str
)
8739 skip_whitespace (str
);
8741 if (fp_reg_required_here (&str
, 16) == FAIL
)
8744 inst
.error
= BAD_ARGS
;
8748 if (skip_past_comma (&str
) == FAIL
8749 || reg_required_here (&str
, 12) == FAIL
)
8752 inst
.error
= BAD_ARGS
;
8763 skip_whitespace (str
);
8765 if (reg_required_here (&str
, 12) == FAIL
)
8768 if (skip_past_comma (&str
) == FAIL
8769 || fp_reg_required_here (&str
, 0) == FAIL
)
8772 inst
.error
= BAD_ARGS
;
8780 vfp_sp_reg_required_here (str
, pos
)
8782 enum vfp_sp_reg_pos pos
;
8787 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_SN
].htab
)) != FAIL
)
8792 inst
.instruction
|= ((reg
>> 1) << 12) | ((reg
& 1) << 22);
8796 inst
.instruction
|= ((reg
>> 1) << 16) | ((reg
& 1) << 7);
8800 inst
.instruction
|= ((reg
>> 1) << 0) | ((reg
& 1) << 5);
8809 /* In the few cases where we might be able to accept something else
8810 this error can be overridden. */
8811 inst
.error
= _(all_reg_maps
[REG_TYPE_SN
].expected
);
8813 /* Restore the start point. */
8819 vfp_dp_reg_required_here (str
, pos
)
8821 enum vfp_dp_reg_pos pos
;
8826 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_DN
].htab
)) != FAIL
)
8831 inst
.instruction
|= reg
<< 12;
8835 inst
.instruction
|= reg
<< 16;
8839 inst
.instruction
|= reg
<< 0;
8848 /* In the few cases where we might be able to accept something else
8849 this error can be overridden. */
8850 inst
.error
= _(all_reg_maps
[REG_TYPE_DN
].expected
);
8852 /* Restore the start point. */
8858 do_vfp_sp_monadic (str
)
8861 skip_whitespace (str
);
8863 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
8866 if (skip_past_comma (&str
) == FAIL
8867 || vfp_sp_reg_required_here (&str
, VFP_REG_Sm
) == FAIL
)
8870 inst
.error
= BAD_ARGS
;
8878 do_vfp_dp_monadic (str
)
8881 skip_whitespace (str
);
8883 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
8886 if (skip_past_comma (&str
) == FAIL
8887 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
8890 inst
.error
= BAD_ARGS
;
8898 do_vfp_sp_dyadic (str
)
8901 skip_whitespace (str
);
8903 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
8906 if (skip_past_comma (&str
) == FAIL
8907 || vfp_sp_reg_required_here (&str
, VFP_REG_Sn
) == FAIL
8908 || skip_past_comma (&str
) == FAIL
8909 || vfp_sp_reg_required_here (&str
, VFP_REG_Sm
) == FAIL
)
8912 inst
.error
= BAD_ARGS
;
8920 do_vfp_dp_dyadic (str
)
8923 skip_whitespace (str
);
8925 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
8928 if (skip_past_comma (&str
) == FAIL
8929 || vfp_dp_reg_required_here (&str
, VFP_REG_Dn
) == FAIL
8930 || skip_past_comma (&str
) == FAIL
8931 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
8934 inst
.error
= BAD_ARGS
;
8942 do_vfp_reg_from_sp (str
)
8945 skip_whitespace (str
);
8947 if (reg_required_here (&str
, 12) == FAIL
)
8950 if (skip_past_comma (&str
) == FAIL
8951 || vfp_sp_reg_required_here (&str
, VFP_REG_Sn
) == FAIL
)
8954 inst
.error
= BAD_ARGS
;
8962 do_vfp_reg2_from_sp2 (str
)
8965 skip_whitespace (str
);
8967 if (reg_required_here (&str
, 12) == FAIL
8968 || skip_past_comma (&str
) == FAIL
8969 || reg_required_here (&str
, 16) == FAIL
8970 || skip_past_comma (&str
) == FAIL
)
8973 inst
.error
= BAD_ARGS
;
8977 /* We require exactly two consecutive SP registers. */
8978 if (vfp_sp_reg_list (&str
, VFP_REG_Sm
) != 2)
8981 inst
.error
= _("only two consecutive VFP SP registers allowed here");
8988 do_vfp_sp_from_reg (str
)
8991 skip_whitespace (str
);
8993 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sn
) == FAIL
)
8996 if (skip_past_comma (&str
) == FAIL
8997 || reg_required_here (&str
, 12) == FAIL
)
9000 inst
.error
= BAD_ARGS
;
9008 do_vfp_sp2_from_reg2 (str
)
9011 skip_whitespace (str
);
9013 /* We require exactly two consecutive SP registers. */
9014 if (vfp_sp_reg_list (&str
, VFP_REG_Sm
) != 2)
9017 inst
.error
= _("only two consecutive VFP SP registers allowed here");
9020 if (skip_past_comma (&str
) == FAIL
9021 || reg_required_here (&str
, 12) == FAIL
9022 || skip_past_comma (&str
) == FAIL
9023 || reg_required_here (&str
, 16) == FAIL
)
9026 inst
.error
= BAD_ARGS
;
9034 do_vfp_reg_from_dp (str
)
9037 skip_whitespace (str
);
9039 if (reg_required_here (&str
, 12) == FAIL
)
9042 if (skip_past_comma (&str
) == FAIL
9043 || vfp_dp_reg_required_here (&str
, VFP_REG_Dn
) == FAIL
)
9046 inst
.error
= BAD_ARGS
;
9054 do_vfp_reg2_from_dp (str
)
9057 skip_whitespace (str
);
9059 if (reg_required_here (&str
, 12) == FAIL
)
9062 if (skip_past_comma (&str
) == FAIL
9063 || reg_required_here (&str
, 16) == FAIL
9064 || skip_past_comma (&str
) == FAIL
9065 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
9068 inst
.error
= BAD_ARGS
;
9076 do_vfp_dp_from_reg (str
)
9079 skip_whitespace (str
);
9081 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dn
) == FAIL
)
9084 if (skip_past_comma (&str
) == FAIL
9085 || reg_required_here (&str
, 12) == FAIL
)
9088 inst
.error
= BAD_ARGS
;
9096 do_vfp_dp_from_reg2 (str
)
9099 skip_whitespace (str
);
9101 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
9104 if (skip_past_comma (&str
) == FAIL
9105 || reg_required_here (&str
, 12) == FAIL
9106 || skip_past_comma (&str
) == FAIL
9107 || reg_required_here (&str
, 16) == FAIL
)
9110 inst
.error
= BAD_ARGS
;
9117 static const struct vfp_reg
*
9124 const struct vfp_reg
*vreg
;
9128 /* Find the end of the current token. */
9133 while (ISALPHA (c
));
9138 for (vreg
= vfp_regs
+ 0;
9139 vreg
< vfp_regs
+ sizeof (vfp_regs
) / sizeof (struct vfp_reg
);
9142 if (strcmp (start
, vreg
->name
) == 0)
9155 vfp_psr_required_here (str
)
9159 const struct vfp_reg
*vreg
;
9161 vreg
= vfp_psr_parse (str
);
9165 inst
.instruction
|= vreg
->regno
;
9169 inst
.error
= _("VFP system register expected");
9176 do_vfp_reg_from_ctrl (str
)
9179 skip_whitespace (str
);
9181 if (reg_required_here (&str
, 12) == FAIL
)
9184 if (skip_past_comma (&str
) == FAIL
9185 || vfp_psr_required_here (&str
) == FAIL
)
9188 inst
.error
= BAD_ARGS
;
9196 do_vfp_ctrl_from_reg (str
)
9199 skip_whitespace (str
);
9201 if (vfp_psr_required_here (&str
) == FAIL
)
9204 if (skip_past_comma (&str
) == FAIL
9205 || reg_required_here (&str
, 12) == FAIL
)
9208 inst
.error
= BAD_ARGS
;
9216 do_vfp_sp_ldst (str
)
9219 skip_whitespace (str
);
9221 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
9224 inst
.error
= BAD_ARGS
;
9228 if (skip_past_comma (&str
) == FAIL
9229 || cp_address_required_here (&str
, CP_NO_WB
) == FAIL
)
9232 inst
.error
= BAD_ARGS
;
9240 do_vfp_dp_ldst (str
)
9243 skip_whitespace (str
);
9245 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
9248 inst
.error
= BAD_ARGS
;
9252 if (skip_past_comma (&str
) == FAIL
9253 || cp_address_required_here (&str
, CP_NO_WB
) == FAIL
)
9256 inst
.error
= BAD_ARGS
;
9263 /* Parse and encode a VFP SP register list, storing the initial
9264 register in position POS and returning the range as the result. If
9265 the string is invalid return FAIL (an invalid range). */
9267 vfp_sp_reg_list (str
, pos
)
9269 enum vfp_sp_reg_pos pos
;
9277 unsigned long mask
= 0;
9284 skip_whitespace (*str
);
9286 tempinst
= inst
.instruction
;
9290 inst
.instruction
= 0;
9292 if ((new_base
= vfp_sp_reg_required_here (str
, pos
)) == FAIL
)
9295 if (count
== 0 || base_reg
> new_base
)
9297 base_reg
= new_base
;
9298 base_bits
= inst
.instruction
;
9301 if (mask
& (1 << new_base
))
9303 inst
.error
= _("invalid register list");
9307 if ((mask
>> new_base
) != 0 && ! warned
)
9309 as_tsktsk (_("register list not in ascending order"));
9313 mask
|= 1 << new_base
;
9316 skip_whitespace (*str
);
9318 if (**str
== '-') /* We have the start of a range expression */
9325 = arm_reg_parse (str
, all_reg_maps
[REG_TYPE_SN
].htab
))
9328 inst
.error
= _(all_reg_maps
[REG_TYPE_SN
].expected
);
9332 if (high_range
<= new_base
)
9334 inst
.error
= _("register range not in ascending order");
9338 for (new_base
++; new_base
<= high_range
; new_base
++)
9340 if (mask
& (1 << new_base
))
9342 inst
.error
= _("invalid register list");
9346 mask
|= 1 << new_base
;
9351 while (skip_past_comma (str
) != FAIL
);
9355 inst
.error
= _("invalid register list");
9363 /* Sanity check -- should have raised a parse error above. */
9364 if (count
== 0 || count
> 32)
9367 /* Final test -- the registers must be consecutive. */
9370 if ((mask
& (1 << base_reg
++)) == 0)
9372 inst
.error
= _("non-contiguous register range");
9377 inst
.instruction
= tempinst
| base_bits
;
9382 vfp_dp_reg_list (str
)
9390 unsigned long mask
= 0;
9397 skip_whitespace (*str
);
9399 tempinst
= inst
.instruction
;
9403 inst
.instruction
= 0;
9405 if ((new_base
= vfp_dp_reg_required_here (str
, VFP_REG_Dd
)) == FAIL
)
9408 if (count
== 0 || base_reg
> new_base
)
9410 base_reg
= new_base
;
9411 range
= inst
.instruction
;
9414 if (mask
& (1 << new_base
))
9416 inst
.error
= _("invalid register list");
9420 if ((mask
>> new_base
) != 0 && ! warned
)
9422 as_tsktsk (_("register list not in ascending order"));
9426 mask
|= 1 << new_base
;
9429 skip_whitespace (*str
);
9431 if (**str
== '-') /* We have the start of a range expression */
9438 = arm_reg_parse (str
, all_reg_maps
[REG_TYPE_DN
].htab
))
9441 inst
.error
= _(all_reg_maps
[REG_TYPE_DN
].expected
);
9445 if (high_range
<= new_base
)
9447 inst
.error
= _("register range not in ascending order");
9451 for (new_base
++; new_base
<= high_range
; new_base
++)
9453 if (mask
& (1 << new_base
))
9455 inst
.error
= _("invalid register list");
9459 mask
|= 1 << new_base
;
9464 while (skip_past_comma (str
) != FAIL
);
9468 inst
.error
= _("invalid register list");
9476 /* Sanity check -- should have raised a parse error above. */
9477 if (count
== 0 || count
> 16)
9480 /* Final test -- the registers must be consecutive. */
9483 if ((mask
& (1 << base_reg
++)) == 0)
9485 inst
.error
= _("non-contiguous register range");
9490 inst
.instruction
= tempinst
;
9495 vfp_sp_ldstm (str
, ldstm_type
)
9497 enum vfp_ldstm_type ldstm_type
;
9501 skip_whitespace (str
);
9503 if (reg_required_here (&str
, 16) == FAIL
)
9506 skip_whitespace (str
);
9510 inst
.instruction
|= WRITE_BACK
;
9513 else if (ldstm_type
!= VFP_LDSTMIA
)
9515 inst
.error
= _("this addressing mode requires base-register writeback");
9519 if (skip_past_comma (&str
) == FAIL
9520 || (range
= vfp_sp_reg_list (&str
, VFP_REG_Sd
)) == FAIL
)
9523 inst
.error
= BAD_ARGS
;
9527 inst
.instruction
|= range
;
9532 vfp_dp_ldstm (str
, ldstm_type
)
9534 enum vfp_ldstm_type ldstm_type
;
9538 skip_whitespace (str
);
9540 if (reg_required_here (&str
, 16) == FAIL
)
9543 skip_whitespace (str
);
9547 inst
.instruction
|= WRITE_BACK
;
9550 else if (ldstm_type
!= VFP_LDSTMIA
&& ldstm_type
!= VFP_LDSTMIAX
)
9552 inst
.error
= _("this addressing mode requires base-register writeback");
9556 if (skip_past_comma (&str
) == FAIL
9557 || (range
= vfp_dp_reg_list (&str
)) == FAIL
)
9560 inst
.error
= BAD_ARGS
;
9564 if (ldstm_type
== VFP_LDSTMIAX
|| ldstm_type
== VFP_LDSTMDBX
)
9567 inst
.instruction
|= range
;
9572 do_vfp_sp_ldstmia (str
)
9575 vfp_sp_ldstm (str
, VFP_LDSTMIA
);
9579 do_vfp_sp_ldstmdb (str
)
9582 vfp_sp_ldstm (str
, VFP_LDSTMDB
);
9586 do_vfp_dp_ldstmia (str
)
9589 vfp_dp_ldstm (str
, VFP_LDSTMIA
);
9593 do_vfp_dp_ldstmdb (str
)
9596 vfp_dp_ldstm (str
, VFP_LDSTMDB
);
9600 do_vfp_xp_ldstmia (str
)
9603 vfp_dp_ldstm (str
, VFP_LDSTMIAX
);
9607 do_vfp_xp_ldstmdb (str
)
9610 vfp_dp_ldstm (str
, VFP_LDSTMDBX
);
9614 do_vfp_sp_compare_z (str
)
9617 skip_whitespace (str
);
9619 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
9622 inst
.error
= BAD_ARGS
;
9630 do_vfp_dp_compare_z (str
)
9633 skip_whitespace (str
);
9635 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
9638 inst
.error
= BAD_ARGS
;
9646 do_vfp_dp_sp_cvt (str
)
9649 skip_whitespace (str
);
9651 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
9654 if (skip_past_comma (&str
) == FAIL
9655 || vfp_sp_reg_required_here (&str
, VFP_REG_Sm
) == FAIL
)
9658 inst
.error
= BAD_ARGS
;
9666 do_vfp_sp_dp_cvt (str
)
9669 skip_whitespace (str
);
9671 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
9674 if (skip_past_comma (&str
) == FAIL
9675 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
9678 inst
.error
= BAD_ARGS
;
9685 /* Thumb specific routines. */
9687 /* Parse and validate that a register is of the right form, this saves
9688 repeated checking of this information in many similar cases.
9689 Unlike the 32-bit case we do not insert the register into the opcode
9690 here, since the position is often unknown until the full instruction
9694 thumb_reg (strp
, hi_lo
)
9700 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
9708 inst
.error
= _("lo register required");
9716 inst
.error
= _("hi register required");
9728 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
9732 thumb_add_sub (str
, subtract
)
9736 int Rd
, Rs
, Rn
= FAIL
;
9738 skip_whitespace (str
);
9740 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
9741 || skip_past_comma (&str
) == FAIL
)
9744 inst
.error
= BAD_ARGS
;
9748 if (is_immediate_prefix (*str
))
9752 if (my_get_expression (&inst
.reloc
.exp
, &str
))
9757 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
9760 if (skip_past_comma (&str
) == FAIL
)
9762 /* Two operand format, shuffle the registers
9763 and pretend there are 3. */
9767 else if (is_immediate_prefix (*str
))
9770 if (my_get_expression (&inst
.reloc
.exp
, &str
))
9773 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
9777 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9778 for the latter case, EXPR contains the immediate that was found. */
9781 /* All register format. */
9782 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
9786 inst
.error
= _("dest and source1 must be the same register");
9790 /* Can't do this for SUB. */
9793 inst
.error
= _("subtract valid only on lo regs");
9797 inst
.instruction
= (T_OPCODE_ADD_HI
9798 | (Rd
> 7 ? THUMB_H1
: 0)
9799 | (Rn
> 7 ? THUMB_H2
: 0));
9800 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
9804 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
9805 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
9810 /* Immediate expression, now things start to get nasty. */
9812 /* First deal with HI regs, only very restricted cases allowed:
9813 Adjusting SP, and using PC or SP to get an address. */
9814 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
9815 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
9817 inst
.error
= _("invalid Hi register with immediate");
9821 if (inst
.reloc
.exp
.X_op
!= O_constant
)
9823 /* Value isn't known yet, all we can do is store all the fragments
9824 we know about in the instruction and let the reloc hacking
9826 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
9827 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
9831 int offset
= inst
.reloc
.exp
.X_add_number
;
9841 /* Quick check, in case offset is MIN_INT. */
9844 inst
.error
= _("immediate value out of range");
9848 /* Note - you cannot convert a subtract of 0 into an
9849 add of 0 because the carry flag is set differently. */
9850 else if (offset
> 0)
9855 if (offset
& ~0x1fc)
9857 inst
.error
= _("invalid immediate value for stack adjust");
9860 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
9861 inst
.instruction
|= offset
>> 2;
9863 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
9866 || (offset
& ~0x3fc))
9868 inst
.error
= _("invalid immediate for address calculation");
9871 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
9873 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
9879 inst
.error
= _("immediate value out of range");
9882 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
9883 inst
.instruction
|= (Rd
<< 8) | offset
;
9889 inst
.error
= _("immediate value out of range");
9892 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
9893 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
9902 thumb_shift (str
, shift
)
9906 int Rd
, Rs
, Rn
= FAIL
;
9908 skip_whitespace (str
);
9910 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
9911 || skip_past_comma (&str
) == FAIL
)
9914 inst
.error
= BAD_ARGS
;
9918 if (is_immediate_prefix (*str
))
9920 /* Two operand immediate format, set Rs to Rd. */
9923 if (my_get_expression (&inst
.reloc
.exp
, &str
))
9928 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
9931 if (skip_past_comma (&str
) == FAIL
)
9933 /* Two operand format, shuffle the registers
9934 and pretend there are 3. */
9938 else if (is_immediate_prefix (*str
))
9941 if (my_get_expression (&inst
.reloc
.exp
, &str
))
9944 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
9948 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9949 for the latter case, EXPR contains the immediate that was found. */
9955 inst
.error
= _("source1 and dest must be same register");
9961 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
9962 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
9963 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
9966 inst
.instruction
|= Rd
| (Rn
<< 3);
9972 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
9973 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
9974 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
9977 if (inst
.reloc
.exp
.X_op
!= O_constant
)
9979 /* Value isn't known yet, create a dummy reloc and let reloc
9980 hacking fix it up. */
9981 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
9985 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
9987 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
9989 inst
.error
= _("invalid immediate for shift");
9993 /* Shifts of zero are handled by converting to LSL. */
9994 if (shift_value
== 0)
9995 inst
.instruction
= T_OPCODE_LSL_I
;
9997 /* Shifts of 32 are encoded as a shift of zero. */
9998 if (shift_value
== 32)
10001 inst
.instruction
|= shift_value
<< 6;
10004 inst
.instruction
|= Rd
| (Rs
<< 3);
10011 thumb_mov_compare (str
, move
)
10017 skip_whitespace (str
);
10019 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
10020 || skip_past_comma (&str
) == FAIL
)
10023 inst
.error
= BAD_ARGS
;
10027 if (move
!= THUMB_CPY
&& is_immediate_prefix (*str
))
10030 if (my_get_expression (&inst
.reloc
.exp
, &str
))
10033 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
10038 if (move
!= THUMB_CPY
&& Rs
< 8 && Rd
< 8)
10040 if (move
== THUMB_MOVE
)
10041 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
10042 since a MOV instruction produces unpredictable results. */
10043 inst
.instruction
= T_OPCODE_ADD_I3
;
10045 inst
.instruction
= T_OPCODE_CMP_LR
;
10046 inst
.instruction
|= Rd
| (Rs
<< 3);
10050 if (move
== THUMB_MOVE
)
10051 inst
.instruction
= T_OPCODE_MOV_HR
;
10052 else if (move
!= THUMB_CPY
)
10053 inst
.instruction
= T_OPCODE_CMP_HR
;
10056 inst
.instruction
|= THUMB_H1
;
10059 inst
.instruction
|= THUMB_H2
;
10061 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
10068 inst
.error
= _("only lo regs allowed with immediate");
10072 if (move
== THUMB_MOVE
)
10073 inst
.instruction
= T_OPCODE_MOV_I8
;
10075 inst
.instruction
= T_OPCODE_CMP_I8
;
10077 inst
.instruction
|= Rd
<< 8;
10079 if (inst
.reloc
.exp
.X_op
!= O_constant
)
10080 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
10083 unsigned value
= inst
.reloc
.exp
.X_add_number
;
10087 inst
.error
= _("invalid immediate");
10091 inst
.instruction
|= value
;
10099 thumb_load_store (str
, load_store
, size
)
10104 int Rd
, Rb
, Ro
= FAIL
;
10106 skip_whitespace (str
);
10108 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
10109 || skip_past_comma (&str
) == FAIL
)
10112 inst
.error
= BAD_ARGS
;
10119 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
10122 if (skip_past_comma (&str
) != FAIL
)
10124 if (is_immediate_prefix (*str
))
10127 if (my_get_expression (&inst
.reloc
.exp
, &str
))
10130 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
10135 inst
.reloc
.exp
.X_op
= O_constant
;
10136 inst
.reloc
.exp
.X_add_number
= 0;
10141 inst
.error
= _("expected ']'");
10146 else if (*str
== '=')
10148 if (load_store
!= THUMB_LOAD
)
10150 inst
.error
= _("invalid pseudo operation");
10154 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
10157 skip_whitespace (str
);
10159 if (my_get_expression (& inst
.reloc
.exp
, & str
))
10164 if ( inst
.reloc
.exp
.X_op
!= O_constant
10165 && inst
.reloc
.exp
.X_op
!= O_symbol
)
10167 inst
.error
= "Constant expression expected";
10171 if (inst
.reloc
.exp
.X_op
== O_constant
10172 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
10174 /* This can be done with a mov instruction. */
10176 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
10177 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
10181 /* Insert into literal pool. */
10182 if (add_to_lit_pool () == FAIL
)
10185 inst
.error
= "literal pool insertion failed";
10189 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
10190 inst
.reloc
.pc_rel
= 1;
10191 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
10192 /* Adjust ARM pipeline offset to Thumb. */
10193 inst
.reloc
.exp
.X_add_number
+= 4;
10199 if (my_get_expression (&inst
.reloc
.exp
, &str
))
10202 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
10203 inst
.reloc
.pc_rel
= 1;
10204 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
10205 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
10210 if (Rb
== REG_PC
|| Rb
== REG_SP
)
10212 if (size
!= THUMB_WORD
)
10214 inst
.error
= _("byte or halfword not valid for base register");
10217 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
10219 inst
.error
= _("r15 based store not allowed");
10222 else if (Ro
!= FAIL
)
10224 inst
.error
= _("invalid base register for register offset");
10229 inst
.instruction
= T_OPCODE_LDR_PC
;
10230 else if (load_store
== THUMB_LOAD
)
10231 inst
.instruction
= T_OPCODE_LDR_SP
;
10233 inst
.instruction
= T_OPCODE_STR_SP
;
10235 inst
.instruction
|= Rd
<< 8;
10236 if (inst
.reloc
.exp
.X_op
== O_constant
)
10238 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
10240 if (offset
& ~0x3fc)
10242 inst
.error
= _("invalid offset");
10246 inst
.instruction
|= offset
>> 2;
10249 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
10253 inst
.error
= _("invalid base register in load/store");
10256 else if (Ro
== FAIL
)
10258 /* Immediate offset. */
10259 if (size
== THUMB_WORD
)
10260 inst
.instruction
= (load_store
== THUMB_LOAD
10261 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
10262 else if (size
== THUMB_HALFWORD
)
10263 inst
.instruction
= (load_store
== THUMB_LOAD
10264 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
10266 inst
.instruction
= (load_store
== THUMB_LOAD
10267 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
10269 inst
.instruction
|= Rd
| (Rb
<< 3);
10271 if (inst
.reloc
.exp
.X_op
== O_constant
)
10273 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
10275 if (offset
& ~(0x1f << size
))
10277 inst
.error
= _("invalid offset");
10280 inst
.instruction
|= (offset
>> size
) << 6;
10283 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
10287 /* Register offset. */
10288 if (size
== THUMB_WORD
)
10289 inst
.instruction
= (load_store
== THUMB_LOAD
10290 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
10291 else if (size
== THUMB_HALFWORD
)
10292 inst
.instruction
= (load_store
== THUMB_LOAD
10293 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
10295 inst
.instruction
= (load_store
== THUMB_LOAD
10296 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
10298 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
10304 /* A register must be given at this point.
10306 Shift is the place to put it in inst.instruction.
10308 Restores input start point on err.
10309 Returns the reg#, or FAIL. */
10312 mav_reg_required_here (str
, shift
, regtype
)
10315 enum arm_reg_type regtype
;
10318 char *start
= *str
;
10320 if ((reg
= arm_reg_parse (str
, all_reg_maps
[regtype
].htab
)) != FAIL
)
10323 inst
.instruction
|= reg
<< shift
;
10328 /* Restore the start point. */
10331 /* In the few cases where we might be able to accept something else
10332 this error can be overridden. */
10333 inst
.error
= _(all_reg_maps
[regtype
].expected
);
10338 /* Cirrus Maverick Instructions. */
10340 /* Wrapper functions. */
10343 do_mav_binops_1a (str
)
10346 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_RN
, REG_TYPE_MVF
);
10350 do_mav_binops_1b (str
)
10353 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_RN
, REG_TYPE_MVD
);
10357 do_mav_binops_1c (str
)
10360 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_RN
, REG_TYPE_MVDX
);
10364 do_mav_binops_1d (str
)
10367 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVF
);
10371 do_mav_binops_1e (str
)
10374 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVD
);
10378 do_mav_binops_1f (str
)
10381 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVF
);
10385 do_mav_binops_1g (str
)
10388 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVD
);
10392 do_mav_binops_1h (str
)
10395 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVFX
);
10399 do_mav_binops_1i (str
)
10402 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVFX
);
10406 do_mav_binops_1j (str
)
10409 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVDX
);
10413 do_mav_binops_1k (str
)
10416 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVDX
);
10420 do_mav_binops_1l (str
)
10423 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVF
);
10427 do_mav_binops_1m (str
)
10430 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVD
);
10434 do_mav_binops_1n (str
)
10437 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
10441 do_mav_binops_1o (str
)
10444 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
10448 do_mav_binops_2a (str
)
10451 do_mav_binops (str
, MAV_MODE2
, REG_TYPE_MVF
, REG_TYPE_RN
);
10455 do_mav_binops_2b (str
)
10458 do_mav_binops (str
, MAV_MODE2
, REG_TYPE_MVD
, REG_TYPE_RN
);
10462 do_mav_binops_2c (str
)
10465 do_mav_binops (str
, MAV_MODE2
, REG_TYPE_MVDX
, REG_TYPE_RN
);
10469 do_mav_binops_3a (str
)
10472 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVAX
, REG_TYPE_MVFX
);
10476 do_mav_binops_3b (str
)
10479 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVFX
, REG_TYPE_MVAX
);
10483 do_mav_binops_3c (str
)
10486 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVAX
, REG_TYPE_MVDX
);
10490 do_mav_binops_3d (str
)
10493 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVDX
, REG_TYPE_MVAX
);
10497 do_mav_triple_4a (str
)
10500 do_mav_triple (str
, MAV_MODE4
, REG_TYPE_MVFX
, REG_TYPE_MVFX
, REG_TYPE_RN
);
10504 do_mav_triple_4b (str
)
10507 do_mav_triple (str
, MAV_MODE4
, REG_TYPE_MVDX
, REG_TYPE_MVDX
, REG_TYPE_RN
);
10511 do_mav_triple_5a (str
)
10514 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVF
, REG_TYPE_MVF
);
10518 do_mav_triple_5b (str
)
10521 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVD
, REG_TYPE_MVD
);
10525 do_mav_triple_5c (str
)
10528 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
10532 do_mav_triple_5d (str
)
10535 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
10539 do_mav_triple_5e (str
)
10542 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVF
, REG_TYPE_MVF
, REG_TYPE_MVF
);
10546 do_mav_triple_5f (str
)
10549 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVD
, REG_TYPE_MVD
, REG_TYPE_MVD
);
10553 do_mav_triple_5g (str
)
10556 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVFX
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
10560 do_mav_triple_5h (str
)
10563 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVDX
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
10567 do_mav_quad_6a (str
)
10570 do_mav_quad (str
, MAV_MODE6
, REG_TYPE_MVAX
, REG_TYPE_MVFX
, REG_TYPE_MVFX
,
10575 do_mav_quad_6b (str
)
10578 do_mav_quad (str
, MAV_MODE6
, REG_TYPE_MVAX
, REG_TYPE_MVAX
, REG_TYPE_MVFX
,
10582 /* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
10584 do_mav_dspsc_1 (str
)
10587 skip_whitespace (str
);
10590 if (mav_reg_required_here (&str
, -1, REG_TYPE_DSPSC
) == FAIL
10591 || skip_past_comma (&str
) == FAIL
10592 || mav_reg_required_here (&str
, 12, REG_TYPE_MVDX
) == FAIL
)
10595 inst
.error
= BAD_ARGS
;
10603 /* cfmv32sc<cond> MVDX[15:0],DSPSC. */
10605 do_mav_dspsc_2 (str
)
10608 skip_whitespace (str
);
10611 if (mav_reg_required_here (&str
, 12, REG_TYPE_MVDX
) == FAIL
10612 || skip_past_comma (&str
) == FAIL
10613 || mav_reg_required_here (&str
, -1, REG_TYPE_DSPSC
) == FAIL
)
10616 inst
.error
= BAD_ARGS
;
10625 do_mav_shift_1 (str
)
10628 do_mav_shift (str
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
10632 do_mav_shift_2 (str
)
10635 do_mav_shift (str
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
10639 do_mav_ldst_1 (str
)
10642 do_mav_ldst (str
, REG_TYPE_MVF
);
10646 do_mav_ldst_2 (str
)
10649 do_mav_ldst (str
, REG_TYPE_MVD
);
10653 do_mav_ldst_3 (str
)
10656 do_mav_ldst (str
, REG_TYPE_MVFX
);
10660 do_mav_ldst_4 (str
)
10663 do_mav_ldst (str
, REG_TYPE_MVDX
);
10666 /* Isnsn like "foo X,Y". */
10669 do_mav_binops (str
, mode
, reg0
, reg1
)
10672 enum arm_reg_type reg0
;
10673 enum arm_reg_type reg1
;
10675 int shift0
, shift1
;
10677 shift0
= mode
& 0xff;
10678 shift1
= (mode
>> 8) & 0xff;
10680 skip_whitespace (str
);
10682 if (mav_reg_required_here (&str
, shift0
, reg0
) == FAIL
10683 || skip_past_comma (&str
) == FAIL
10684 || mav_reg_required_here (&str
, shift1
, reg1
) == FAIL
)
10687 inst
.error
= BAD_ARGS
;
10693 /* Isnsn like "foo X,Y,Z". */
10696 do_mav_triple (str
, mode
, reg0
, reg1
, reg2
)
10699 enum arm_reg_type reg0
;
10700 enum arm_reg_type reg1
;
10701 enum arm_reg_type reg2
;
10703 int shift0
, shift1
, shift2
;
10705 shift0
= mode
& 0xff;
10706 shift1
= (mode
>> 8) & 0xff;
10707 shift2
= (mode
>> 16) & 0xff;
10709 skip_whitespace (str
);
10711 if (mav_reg_required_here (&str
, shift0
, reg0
) == FAIL
10712 || skip_past_comma (&str
) == FAIL
10713 || mav_reg_required_here (&str
, shift1
, reg1
) == FAIL
10714 || skip_past_comma (&str
) == FAIL
10715 || mav_reg_required_here (&str
, shift2
, reg2
) == FAIL
)
10718 inst
.error
= BAD_ARGS
;
10724 /* Isnsn like "foo W,X,Y,Z".
10725 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
10728 do_mav_quad (str
, mode
, reg0
, reg1
, reg2
, reg3
)
10731 enum arm_reg_type reg0
;
10732 enum arm_reg_type reg1
;
10733 enum arm_reg_type reg2
;
10734 enum arm_reg_type reg3
;
10736 int shift0
, shift1
, shift2
, shift3
;
10738 shift0
= mode
& 0xff;
10739 shift1
= (mode
>> 8) & 0xff;
10740 shift2
= (mode
>> 16) & 0xff;
10741 shift3
= (mode
>> 24) & 0xff;
10743 skip_whitespace (str
);
10745 if (mav_reg_required_here (&str
, shift0
, reg0
) == FAIL
10746 || skip_past_comma (&str
) == FAIL
10747 || mav_reg_required_here (&str
, shift1
, reg1
) == FAIL
10748 || skip_past_comma (&str
) == FAIL
10749 || mav_reg_required_here (&str
, shift2
, reg2
) == FAIL
10750 || skip_past_comma (&str
) == FAIL
10751 || mav_reg_required_here (&str
, shift3
, reg3
) == FAIL
)
10754 inst
.error
= BAD_ARGS
;
10760 /* Maverick shift immediate instructions.
10761 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10762 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
10765 do_mav_shift (str
, reg0
, reg1
)
10767 enum arm_reg_type reg0
;
10768 enum arm_reg_type reg1
;
10773 skip_whitespace (str
);
10777 if (mav_reg_required_here (&str
, 12, reg0
) == FAIL
10778 || skip_past_comma (&str
) == FAIL
10779 || mav_reg_required_here (&str
, 16, reg1
) == FAIL
10780 || skip_past_comma (&str
) == FAIL
)
10783 inst
.error
= BAD_ARGS
;
10787 /* Calculate the immediate operand.
10788 The operand is a 7bit signed number. */
10789 skip_whitespace (str
);
10794 if (!ISDIGIT (*str
) && *str
!= '-')
10796 inst
.error
= _("expecting immediate, 7bit operand");
10806 for (imm
= 0; *str
&& ISDIGIT (*str
); ++str
)
10807 imm
= imm
* 10 + *str
- '0';
10811 inst
.error
= _("immediate out of range");
10815 /* Make negative imm's into 7bit signed numbers. */
10822 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10823 Bits 5-7 of the insn should have bits 4-6 of the immediate.
10824 Bit 4 should be 0. */
10825 imm
= (imm
& 0xf) | ((imm
& 0x70) << 1);
10827 inst
.instruction
|= imm
;
10832 mav_parse_offset (str
, negative
)
10841 skip_whitespace (p
);
10854 inst
.error
= _("offset expected");
10858 for (offset
= 0; *p
&& ISDIGIT (*p
); ++p
)
10859 offset
= offset
* 10 + *p
- '0';
10863 inst
.error
= _("offset out of range");
10869 return *negative
? -offset
: offset
;
10872 /* Maverick load/store instructions.
10873 <insn><cond> CRd,[Rn,<offset>]{!}.
10874 <insn><cond> CRd,[Rn],<offset>. */
10877 do_mav_ldst (str
, reg0
)
10879 enum arm_reg_type reg0
;
10881 int offset
, negative
;
10883 skip_whitespace (str
);
10885 if (mav_reg_required_here (&str
, 12, reg0
) == FAIL
10886 || skip_past_comma (&str
) == FAIL
10888 || reg_required_here (&str
, 16) == FAIL
)
10891 if (skip_past_comma (&str
) == SUCCESS
)
10893 /* You are here: "<offset>]{!}". */
10894 inst
.instruction
|= PRE_INDEX
;
10896 offset
= mav_parse_offset (&str
, &negative
);
10903 inst
.error
= _("missing ]");
10909 inst
.instruction
|= WRITE_BACK
;
10915 /* You are here: "], <offset>". */
10918 inst
.error
= _("missing ]");
10922 if (skip_past_comma (&str
) == FAIL
10923 || (offset
= mav_parse_offset (&str
, &negative
), inst
.error
))
10926 inst
.instruction
|= CP_T_WB
; /* Post indexed, set bit W. */
10932 inst
.instruction
|= CP_T_UD
; /* Positive, so set bit U. */
10934 inst
.instruction
|= offset
>> 2;
10940 inst
.error
= BAD_ARGS
;
10951 /* Handle the Format 4 instructions that do not have equivalents in other
10952 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
10961 skip_whitespace (str
);
10963 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
10964 || skip_past_comma (&str
) == FAIL
10965 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
10967 inst
.error
= BAD_ARGS
;
10971 if (skip_past_comma (&str
) != FAIL
)
10973 /* Three operand format not allowed for TST, CMN, NEG and MVN.
10974 (It isn't allowed for CMP either, but that isn't handled by this
10976 if (inst
.instruction
== T_OPCODE_TST
10977 || inst
.instruction
== T_OPCODE_CMN
10978 || inst
.instruction
== T_OPCODE_NEG
10979 || inst
.instruction
== T_OPCODE_MVN
)
10981 inst
.error
= BAD_ARGS
;
10985 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
10990 inst
.error
= _("dest and source1 must be the same register");
10996 if (inst
.instruction
== T_OPCODE_MUL
10998 as_tsktsk (_("Rs and Rd must be different in MUL"));
11000 inst
.instruction
|= Rd
| (Rs
<< 3);
11008 thumb_add_sub (str
, 0);
11015 thumb_shift (str
, THUMB_ASR
);
11022 if (my_get_expression (&inst
.reloc
.exp
, &str
))
11024 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
11025 inst
.reloc
.pc_rel
= 1;
11030 do_t_branch12 (str
)
11033 if (my_get_expression (&inst
.reloc
.exp
, &str
))
11035 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
11036 inst
.reloc
.pc_rel
= 1;
11040 /* Find the real, Thumb encoded start of a Thumb function. */
11043 find_real_start (symbolP
)
11047 const char * name
= S_GET_NAME (symbolP
);
11048 symbolS
* new_target
;
11050 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
11051 #define STUB_NAME ".real_start_of"
11056 /* Names that start with '.' are local labels, not function entry points.
11057 The compiler may generate BL instructions to these labels because it
11058 needs to perform a branch to a far away location. */
11059 if (name
[0] == '.')
11062 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
11063 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
11065 new_target
= symbol_find (real_start
);
11067 if (new_target
== NULL
)
11069 as_warn ("Failed to find real start of function: %s\n", name
);
11070 new_target
= symbolP
;
11079 do_t_branch23 (str
)
11082 if (my_get_expression (& inst
.reloc
.exp
, & str
))
11085 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
11086 inst
.reloc
.pc_rel
= 1;
11089 /* If the destination of the branch is a defined symbol which does not have
11090 the THUMB_FUNC attribute, then we must be calling a function which has
11091 the (interfacearm) attribute. We look for the Thumb entry point to that
11092 function and change the branch to refer to that function instead. */
11093 if ( inst
.reloc
.exp
.X_op
== O_symbol
11094 && inst
.reloc
.exp
.X_add_symbol
!= NULL
11095 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
11096 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
11097 inst
.reloc
.exp
.X_add_symbol
=
11098 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
11107 skip_whitespace (str
);
11109 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
11112 /* This sets THUMB_H2 from the top bit of reg. */
11113 inst
.instruction
|= reg
<< 3;
11115 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
11116 should cause the alignment to be checked once it is known. This is
11117 because BX PC only works if the instruction is word aligned. */
11126 thumb_mov_compare (str
, THUMB_COMPARE
);
11136 skip_whitespace (str
);
11138 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
11142 as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
11146 if (skip_past_comma (&str
) == FAIL
11147 || (range
= reg_list (&str
)) == FAIL
)
11150 inst
.error
= BAD_ARGS
;
11154 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
11156 /* This really doesn't seem worth it. */
11157 inst
.reloc
.type
= BFD_RELOC_NONE
;
11158 inst
.error
= _("expression too complex");
11164 inst
.error
= _("only lo-regs valid in load/store multiple");
11168 inst
.instruction
|= (Rb
<< 8) | range
;
11176 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
11183 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
11190 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
11199 skip_whitespace (str
);
11201 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
11202 || skip_past_comma (&str
) == FAIL
11204 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
11205 || skip_past_comma (&str
) == FAIL
11206 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
11210 inst
.error
= _("syntax: ldrs[b] Rd, [Rb, Ro]");
11214 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
11222 thumb_shift (str
, THUMB_LSL
);
11229 thumb_shift (str
, THUMB_LSR
);
11236 thumb_mov_compare (str
, THUMB_MOVE
);
11240 do_t_push_pop (str
)
11245 skip_whitespace (str
);
11247 if ((range
= reg_list (&str
)) == FAIL
)
11250 inst
.error
= BAD_ARGS
;
11254 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
11256 /* This really doesn't seem worth it. */
11257 inst
.reloc
.type
= BFD_RELOC_NONE
;
11258 inst
.error
= _("expression too complex");
11264 if ((inst
.instruction
== T_OPCODE_PUSH
11265 && (range
& ~0xff) == 1 << REG_LR
)
11266 || (inst
.instruction
== T_OPCODE_POP
11267 && (range
& ~0xff) == 1 << REG_PC
))
11269 inst
.instruction
|= THUMB_PP_PC_LR
;
11274 inst
.error
= _("invalid register list to push/pop instruction");
11279 inst
.instruction
|= range
;
11287 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
11294 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
11301 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
11308 thumb_add_sub (str
, 1);
11315 skip_whitespace (str
);
11317 if (my_get_expression (&inst
.reloc
.exp
, &str
))
11320 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
11330 /* This is a pseudo-op of the form "adr rd, label" to be converted
11331 into a relative address of the form "add rd, pc, #label-.-4". */
11332 skip_whitespace (str
);
11334 /* Store Rd in temporary location inside instruction. */
11335 if ((reg
= reg_required_here (&str
, 4)) == FAIL
11336 || (reg
> 7) /* For Thumb reg must be r0..r7. */
11337 || skip_past_comma (&str
) == FAIL
11338 || my_get_expression (&inst
.reloc
.exp
, &str
))
11341 inst
.error
= BAD_ARGS
;
11345 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
11346 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
11347 inst
.reloc
.pc_rel
= 1;
11348 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
11354 insert_reg (r
, htab
)
11355 const struct reg_entry
*r
;
11356 struct hash_control
*htab
;
11358 int len
= strlen (r
->name
) + 2;
11359 char * buf
= (char *) xmalloc (len
);
11360 char * buf2
= (char *) xmalloc (len
);
11363 #ifdef REGISTER_PREFIX
11364 buf
[i
++] = REGISTER_PREFIX
;
11367 strcpy (buf
+ i
, r
->name
);
11369 for (i
= 0; buf
[i
]; i
++)
11370 buf2
[i
] = TOUPPER (buf
[i
]);
11374 hash_insert (htab
, buf
, (PTR
) r
);
11375 hash_insert (htab
, buf2
, (PTR
) r
);
11379 build_reg_hsh (map
)
11380 struct reg_map
*map
;
11382 const struct reg_entry
*r
;
11384 if ((map
->htab
= hash_new ()) == NULL
)
11385 as_fatal (_("virtual memory exhausted"));
11387 for (r
= map
->names
; r
->name
!= NULL
; r
++)
11388 insert_reg (r
, map
->htab
);
11392 insert_reg_alias (str
, regnum
, htab
)
11395 struct hash_control
*htab
;
11398 struct reg_entry
*new = xmalloc (sizeof (struct reg_entry
));
11399 const char *name
= xmalloc (strlen (str
) + 1);
11401 strcpy ((char *) name
, str
);
11404 new->number
= regnum
;
11405 new->builtin
= FALSE
;
11407 error
= hash_insert (htab
, name
, (PTR
) new);
11410 as_bad (_("failed to create an alias for %s, reason: %s"),
11412 free ((char *) name
);
11417 /* Look for the .req directive. This is of the form:
11419 new_register_name .req existing_register_name
11421 If we find one, or if it looks sufficiently like one that we want to
11422 handle any error here, return non-zero. Otherwise return zero. */
11424 create_register_alias (newname
, p
)
11432 skip_whitespace (q
);
11437 if (*q
&& !strncmp (q
, ".req ", 5))
11442 #ifdef IGNORE_OPCODE_CASE
11443 newname
= original_case_string
;
11445 copy_of_str
= newname
;
11448 skip_whitespace (q
);
11450 for (r
= q
; *r
!= '\0'; r
++)
11456 enum arm_reg_type new_type
, old_type
;
11461 old_type
= arm_reg_parse_any (q
);
11464 new_type
= arm_reg_parse_any (newname
);
11466 if (new_type
== REG_TYPE_MAX
)
11468 if (old_type
!= REG_TYPE_MAX
)
11470 old_regno
= arm_reg_parse (&q
, all_reg_maps
[old_type
].htab
);
11471 insert_reg_alias (newname
, old_regno
,
11472 all_reg_maps
[old_type
].htab
);
11475 as_warn (_("register '%s' does not exist\n"), q
);
11477 else if (old_type
== REG_TYPE_MAX
)
11479 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
11484 /* Do not warn about redefinitions to the same alias. */
11485 if (new_type
!= old_type
11486 || (arm_reg_parse (&q
, all_reg_maps
[old_type
].htab
)
11487 != arm_reg_parse (&q
, all_reg_maps
[new_type
].htab
)))
11488 as_warn (_("ignoring redefinition of register alias '%s'"),
11494 as_warn (_("ignoring incomplete .req pseuso op"));
11505 set_constant_flonums ()
11509 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
11510 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
11514 /* Iterate over the base tables to create the instruction patterns. */
11516 build_arm_ops_hsh ()
11520 static struct obstack insn_obstack
;
11522 obstack_begin (&insn_obstack
, 4000);
11524 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
11526 const struct asm_opcode
*insn
= insns
+ i
;
11528 if (insn
->cond_offset
!= 0)
11530 /* Insn supports conditional execution. Build the varaints
11531 and insert them in the hash table. */
11532 for (j
= 0; j
< sizeof (conds
) / sizeof (struct asm_cond
); j
++)
11534 unsigned len
= strlen (insn
->template);
11535 struct asm_opcode
*new;
11538 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
11539 /* All condition codes are two characters. */
11540 template = obstack_alloc (&insn_obstack
, len
+ 3);
11542 strncpy (template, insn
->template, insn
->cond_offset
);
11543 strcpy (template + insn
->cond_offset
, conds
[j
].template);
11544 if (len
> insn
->cond_offset
)
11545 strcpy (template + insn
->cond_offset
+ 2,
11546 insn
->template + insn
->cond_offset
);
11547 new->template = template;
11548 new->cond_offset
= 0;
11549 new->variant
= insn
->variant
;
11550 new->parms
= insn
->parms
;
11551 new->value
= (insn
->value
& ~COND_MASK
) | conds
[j
].value
;
11553 hash_insert (arm_ops_hsh
, new->template, (PTR
) new);
11556 /* Finally, insert the unconditional insn in the table directly;
11557 no need to build a copy. */
11558 hash_insert (arm_ops_hsh
, insn
->template, (PTR
) insn
);
11562 #if 0 /* Suppressed - for now. */
11563 #if defined OBJ_ELF || defined OBJ_COFF
11566 #define arm_Note Elf_External_Note
11570 unsigned char namesz
[4]; /* Size of entry's owner string. */
11571 unsigned char descsz
[4]; /* Size of the note descriptor. */
11572 unsigned char type
[4]; /* Interpretation of the descriptor. */
11573 char name
[1]; /* Start of the name+desc data. */
11577 /* The description is kept to a fix sized in order to make updating
11578 it and merging it easier. */
11579 #define ARM_NOTE_DESCRIPTION_LENGTH 8
11582 arm_add_note (name
, description
, type
)
11584 const char * description
;
11587 arm_Note note ATTRIBUTE_UNUSED
;
11589 unsigned int name_len
;
11591 name_len
= (strlen (name
) + 1 + 3) & ~3;
11593 p
= frag_more (sizeof (note
.namesz
));
11594 md_number_to_chars (p
, (valueT
) name_len
, sizeof (note
.namesz
));
11596 p
= frag_more (sizeof (note
.descsz
));
11597 md_number_to_chars (p
, (valueT
) ARM_NOTE_DESCRIPTION_LENGTH
, sizeof (note
.descsz
));
11599 p
= frag_more (sizeof (note
.type
));
11600 md_number_to_chars (p
, (valueT
) type
, sizeof (note
.type
));
11602 p
= frag_more (name_len
);
11605 p
= frag_more (ARM_NOTE_DESCRIPTION_LENGTH
);
11606 strncpy (p
, description
, ARM_NOTE_DESCRIPTION_LENGTH
);
11607 frag_align (2, 0, 0);
11618 if ( (arm_ops_hsh
= hash_new ()) == NULL
11619 || (arm_tops_hsh
= hash_new ()) == NULL
11620 || (arm_cond_hsh
= hash_new ()) == NULL
11621 || (arm_shift_hsh
= hash_new ()) == NULL
11622 || (arm_psr_hsh
= hash_new ()) == NULL
)
11623 as_fatal (_("virtual memory exhausted"));
11625 build_arm_ops_hsh ();
11626 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
11627 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
11628 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
11629 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
11630 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
11631 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
11632 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
11633 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
11635 for (i
= (int) REG_TYPE_FIRST
; i
< (int) REG_TYPE_MAX
; i
++)
11636 build_reg_hsh (all_reg_maps
+ i
);
11638 set_constant_flonums ();
11640 /* Set the cpu variant based on the command-line options. We prefer
11641 -mcpu= over -march= if both are set (as for GCC); and we prefer
11642 -mfpu= over any other way of setting the floating point unit.
11643 Use of legacy options with new options are faulted. */
11644 if (legacy_cpu
!= -1)
11646 if (mcpu_cpu_opt
!= -1 || march_cpu_opt
!= -1)
11647 as_bad (_("use of old and new-style options to set CPU type"));
11649 mcpu_cpu_opt
= legacy_cpu
;
11651 else if (mcpu_cpu_opt
== -1)
11652 mcpu_cpu_opt
= march_cpu_opt
;
11654 if (legacy_fpu
!= -1)
11656 if (mfpu_opt
!= -1)
11657 as_bad (_("use of old and new-style options to set FPU type"));
11659 mfpu_opt
= legacy_fpu
;
11661 else if (mfpu_opt
== -1)
11663 #if !(defined (TE_LINUX) || defined (TE_NetBSD))
11664 /* Some environments specify a default FPU. If they don't, infer it
11665 from the processor. */
11666 if (mcpu_fpu_opt
!= -1)
11667 mfpu_opt
= mcpu_fpu_opt
;
11669 mfpu_opt
= march_fpu_opt
;
11671 mfpu_opt
= FPU_DEFAULT
;
11675 if (mfpu_opt
== -1)
11677 if (mcpu_cpu_opt
== -1)
11678 mfpu_opt
= FPU_DEFAULT
;
11679 else if (mcpu_cpu_opt
& ARM_EXT_V5
)
11680 mfpu_opt
= FPU_ARCH_VFP_V2
;
11682 mfpu_opt
= FPU_ARCH_FPA
;
11685 if (mcpu_cpu_opt
== -1)
11686 mcpu_cpu_opt
= CPU_DEFAULT
;
11688 cpu_variant
= mcpu_cpu_opt
| mfpu_opt
;
11690 #if defined OBJ_COFF || defined OBJ_ELF
11692 unsigned int flags
= meabi_flags
;
11694 switch (meabi_flags
)
11696 case EF_ARM_EABI_UNKNOWN
:
11697 /* Set the flags in the private structure. */
11698 if (uses_apcs_26
) flags
|= F_APCS26
;
11699 if (support_interwork
) flags
|= F_INTERWORK
;
11700 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
11701 if (pic_code
) flags
|= F_PIC
;
11702 if ((cpu_variant
& FPU_ANY
) == FPU_NONE
11703 || (cpu_variant
& FPU_ANY
) == FPU_ARCH_VFP
) /* VFP layout only. */
11705 flags
|= F_SOFT_FLOAT
;
11707 switch (mfloat_abi_opt
)
11709 case ARM_FLOAT_ABI_SOFT
:
11710 case ARM_FLOAT_ABI_SOFTFP
:
11711 flags
|= F_SOFT_FLOAT
;
11714 case ARM_FLOAT_ABI_HARD
:
11715 if (flags
& F_SOFT_FLOAT
)
11716 as_bad (_("hard-float conflicts with specified fpu"));
11719 /* Using VFP conventions (even if soft-float). */
11720 if (cpu_variant
& FPU_VFP_EXT_NONE
) flags
|= F_VFP_FLOAT
;
11722 #if defined OBJ_ELF
11723 if (cpu_variant
& FPU_ARCH_MAVERICK
)
11724 flags
|= EF_ARM_MAVERICK_FLOAT
;
11728 case EF_ARM_EABI_VER3
:
11729 /* No additional flags to set. */
11736 bfd_set_private_flags (stdoutput
, flags
);
11738 /* We have run out flags in the COFF header to encode the
11739 status of ATPCS support, so instead we create a dummy,
11740 empty, debug section called .arm.atpcs. */
11745 sec
= bfd_make_section (stdoutput
, ".arm.atpcs");
11749 bfd_set_section_flags
11750 (stdoutput
, sec
, SEC_READONLY
| SEC_DEBUGGING
/* | SEC_HAS_CONTENTS */);
11751 bfd_set_section_size (stdoutput
, sec
, 0);
11752 bfd_set_section_contents (stdoutput
, sec
, NULL
, 0, 0);
11758 /* Record the CPU type as well. */
11759 switch (cpu_variant
& ARM_CPU_MASK
)
11762 mach
= bfd_mach_arm_2
;
11765 case ARM_3
: /* Also ARM_250. */
11766 mach
= bfd_mach_arm_2a
;
11769 case ARM_6
: /* Also ARM_7. */
11770 mach
= bfd_mach_arm_3
;
11774 mach
= bfd_mach_arm_unknown
;
11778 /* Catch special cases. */
11779 if (cpu_variant
& ARM_CEXT_IWMMXT
)
11780 mach
= bfd_mach_arm_iWMMXt
;
11781 else if (cpu_variant
& ARM_CEXT_XSCALE
)
11782 mach
= bfd_mach_arm_XScale
;
11783 else if (cpu_variant
& ARM_CEXT_MAVERICK
)
11784 mach
= bfd_mach_arm_ep9312
;
11785 else if (cpu_variant
& ARM_EXT_V5E
)
11786 mach
= bfd_mach_arm_5TE
;
11787 else if (cpu_variant
& ARM_EXT_V5
)
11789 if (cpu_variant
& ARM_EXT_V4T
)
11790 mach
= bfd_mach_arm_5T
;
11792 mach
= bfd_mach_arm_5
;
11794 else if (cpu_variant
& ARM_EXT_V4
)
11796 if (cpu_variant
& ARM_EXT_V4T
)
11797 mach
= bfd_mach_arm_4T
;
11799 mach
= bfd_mach_arm_4
;
11801 else if (cpu_variant
& ARM_EXT_V3M
)
11802 mach
= bfd_mach_arm_3M
;
11804 #if 0 /* Suppressed - for now. */
11805 #if defined (OBJ_ELF) || defined (OBJ_COFF)
11807 /* Create a .note section to fully identify this arm binary. */
11809 #define NOTE_ARCH_STRING "arch: "
11811 #if defined OBJ_COFF && ! defined NT_VERSION
11812 #define NT_VERSION 1
11817 segT current_seg
= now_seg
;
11818 subsegT current_subseg
= now_subseg
;
11819 asection
* arm_arch
;
11820 const char * arch_string
;
11822 arm_arch
= bfd_make_section_old_way (stdoutput
, ARM_NOTE_SECTION
);
11825 bfd_set_section_flags (stdoutput
, arm_arch
,
11826 SEC_DATA
| SEC_ALLOC
| SEC_LOAD
| SEC_LINK_ONCE \
11827 | SEC_HAS_CONTENTS
);
11829 bfd_set_section_flags (stdoutput
, arm_arch
,
11830 SEC_READONLY
| SEC_HAS_CONTENTS
);
11832 arm_arch
->output_section
= arm_arch
;
11833 subseg_set (arm_arch
, 0);
11838 case bfd_mach_arm_unknown
: arch_string
= "unknown"; break;
11839 case bfd_mach_arm_2
: arch_string
= "armv2"; break;
11840 case bfd_mach_arm_2a
: arch_string
= "armv2a"; break;
11841 case bfd_mach_arm_3
: arch_string
= "armv3"; break;
11842 case bfd_mach_arm_3M
: arch_string
= "armv3M"; break;
11843 case bfd_mach_arm_4
: arch_string
= "armv4"; break;
11844 case bfd_mach_arm_4T
: arch_string
= "armv4t"; break;
11845 case bfd_mach_arm_5
: arch_string
= "armv5"; break;
11846 case bfd_mach_arm_5T
: arch_string
= "armv5t"; break;
11847 case bfd_mach_arm_5TE
: arch_string
= "armv5te"; break;
11848 case bfd_mach_arm_XScale
: arch_string
= "XScale"; break;
11849 case bfd_mach_arm_ep9312
: arch_string
= "ep9312"; break;
11850 case bfd_mach_arm_iWMMXt
: arch_string
= "iWMMXt"; break;
11853 arm_add_note (NOTE_ARCH_STRING
, arch_string
, NT_ARCH
);
11855 subseg_set (current_seg
, current_subseg
);
11858 #endif /* Suppressed code. */
11860 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
11863 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11864 for use in the a.out file, and stores them in the array pointed to by buf.
11865 This knows about the endian-ness of the target machine and does
11866 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
11867 2 (short) and 4 (long) Floating numbers are put out as a series of
11868 LITTLENUMS (shorts, here at least). */
11871 md_number_to_chars (buf
, val
, n
)
11876 if (target_big_endian
)
11877 number_to_chars_bigendian (buf
, val
, n
);
11879 number_to_chars_littleendian (buf
, val
, n
);
11883 md_chars_to_number (buf
, n
)
11888 unsigned char * where
= (unsigned char *) buf
;
11890 if (target_big_endian
)
11895 result
|= (*where
++ & 255);
11903 result
|= (where
[n
] & 255);
11910 /* Turn a string in input_line_pointer into a floating point constant
11911 of type TYPE, and store the appropriate bytes in *LITP. The number
11912 of LITTLENUMS emitted is stored in *SIZEP. An error message is
11913 returned, or NULL on OK.
11915 Note that fp constants aren't represent in the normal way on the ARM.
11916 In big endian mode, things are as expected. However, in little endian
11917 mode fp constants are big-endian word-wise, and little-endian byte-wise
11918 within the words. For example, (double) 1.1 in big endian mode is
11919 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11920 the byte sequence 99 99 f1 3f 9a 99 99 99.
11922 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
11925 md_atof (type
, litP
, sizeP
)
11931 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
11963 return _("bad call to MD_ATOF()");
11966 t
= atof_ieee (input_line_pointer
, type
, words
);
11968 input_line_pointer
= t
;
11971 if (target_big_endian
)
11973 for (i
= 0; i
< prec
; i
++)
11975 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
11981 if (cpu_variant
& FPU_ARCH_VFP
)
11982 for (i
= prec
- 1; i
>= 0; i
--)
11984 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
11988 /* For a 4 byte float the order of elements in `words' is 1 0.
11989 For an 8 byte float the order is 1 0 3 2. */
11990 for (i
= 0; i
< prec
; i
+= 2)
11992 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
11993 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
12001 /* The knowledge of the PC's pipeline offset is built into the insns
12005 md_pcrel_from (fixP
)
12009 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
12010 && fixP
->fx_subsy
== NULL
)
12013 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
12015 /* PC relative addressing on the Thumb is slightly odd
12016 as the bottom two bits of the PC are forced to zero
12017 for the calculation. */
12018 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
12022 /* The pattern was adjusted to accommodate CE's off-by-one fixups,
12023 so we un-adjust here to compensate for the accommodation. */
12024 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
12026 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
12030 /* Round up a section size to the appropriate boundary. */
12033 md_section_align (segment
, size
)
12034 segT segment ATTRIBUTE_UNUSED
;
12040 /* Round all sects to multiple of 4. */
12041 return (size
+ 3) & ~3;
12045 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
12046 Otherwise we have no need to default values of symbols. */
12049 md_undefined_symbol (name
)
12050 char * name ATTRIBUTE_UNUSED
;
12053 if (name
[0] == '_' && name
[1] == 'G'
12054 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
12058 if (symbol_find (name
))
12059 as_bad ("GOT already in the symbol table");
12061 GOT_symbol
= symbol_new (name
, undefined_section
,
12062 (valueT
) 0, & zero_address_frag
);
12072 /* arm_reg_parse () := if it looks like a register, return its token and
12073 advance the pointer. */
12076 arm_reg_parse (ccp
, htab
)
12077 register char ** ccp
;
12078 struct hash_control
*htab
;
12080 char * start
= * ccp
;
12083 struct reg_entry
* reg
;
12085 #ifdef REGISTER_PREFIX
12086 if (*start
!= REGISTER_PREFIX
)
12091 #ifdef OPTIONAL_REGISTER_PREFIX
12092 if (*p
== OPTIONAL_REGISTER_PREFIX
)
12096 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
12100 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
12104 reg
= (struct reg_entry
*) hash_find (htab
, start
);
12110 return reg
->number
;
12116 /* Search for the following register name in each of the possible reg name
12117 tables. Return the classification if found, or REG_TYPE_MAX if not
12119 static enum arm_reg_type
12120 arm_reg_parse_any (cp
)
12125 for (i
= (int) REG_TYPE_FIRST
; i
< (int) REG_TYPE_MAX
; i
++)
12126 if (arm_reg_parse (&cp
, all_reg_maps
[i
].htab
) != FAIL
)
12127 return (enum arm_reg_type
) i
;
12129 return REG_TYPE_MAX
;
12133 md_apply_fix3 (fixP
, valP
, seg
)
12138 offsetT value
= * valP
;
12140 unsigned int newimm
;
12141 unsigned long temp
;
12143 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
12144 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
12146 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
12148 /* Note whether this will delete the relocation. */
12150 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
12151 doesn't work fully.) */
12152 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
12153 && !fixP
->fx_pcrel
)
12155 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
12159 /* If this symbol is in a different section then we need to leave it for
12160 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
12161 so we have to undo it's effects here. */
12162 if (fixP
->fx_pcrel
)
12164 if (fixP
->fx_addsy
!= NULL
12165 && S_IS_DEFINED (fixP
->fx_addsy
)
12166 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
12169 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
12170 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
12174 value
+= md_pcrel_from (fixP
);
12178 /* Remember value for emit_reloc. */
12179 fixP
->fx_addnumber
= value
;
12181 switch (fixP
->fx_r_type
)
12183 case BFD_RELOC_ARM_IMMEDIATE
:
12184 newimm
= validate_immediate (value
);
12185 temp
= md_chars_to_number (buf
, INSN_SIZE
);
12187 /* If the instruction will fail, see if we can fix things up by
12188 changing the opcode. */
12189 if (newimm
== (unsigned int) FAIL
12190 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
12192 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12193 _("invalid constant (%lx) after fixup"),
12194 (unsigned long) value
);
12198 newimm
|= (temp
& 0xfffff000);
12199 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
12203 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
12205 unsigned int highpart
= 0;
12206 unsigned int newinsn
= 0xe1a00000; /* nop. */
12208 newimm
= validate_immediate (value
);
12209 temp
= md_chars_to_number (buf
, INSN_SIZE
);
12211 /* If the instruction will fail, see if we can fix things up by
12212 changing the opcode. */
12213 if (newimm
== (unsigned int) FAIL
12214 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
12216 /* No ? OK - try using two ADD instructions to generate
12218 newimm
= validate_immediate_twopart (value
, & highpart
);
12220 /* Yes - then make sure that the second instruction is
12222 if (newimm
!= (unsigned int) FAIL
)
12224 /* Still No ? Try using a negated value. */
12225 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
12226 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
12227 /* Otherwise - give up. */
12230 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12231 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
12236 /* Replace the first operand in the 2nd instruction (which
12237 is the PC) with the destination register. We have
12238 already added in the PC in the first instruction and we
12239 do not want to do it again. */
12240 newinsn
&= ~ 0xf0000;
12241 newinsn
|= ((newinsn
& 0x0f000) << 4);
12244 newimm
|= (temp
& 0xfffff000);
12245 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
12247 highpart
|= (newinsn
& 0xfffff000);
12248 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
12252 case BFD_RELOC_ARM_OFFSET_IMM
:
12258 if (validate_offset_imm (value
, 0) == FAIL
)
12260 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12261 _("bad immediate value for offset (%ld)"),
12266 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12267 newval
&= 0xff7ff000;
12268 newval
|= value
| (sign
? INDEX_UP
: 0);
12269 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12272 case BFD_RELOC_ARM_OFFSET_IMM8
:
12273 case BFD_RELOC_ARM_HWLITERAL
:
12279 if (validate_offset_imm (value
, 1) == FAIL
)
12281 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
12282 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12283 _("invalid literal constant: pool needs to be closer"));
12285 as_bad (_("bad immediate value for half-word offset (%ld)"),
12290 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12291 newval
&= 0xff7ff0f0;
12292 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
12293 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12296 case BFD_RELOC_ARM_LITERAL
:
12302 if (validate_offset_imm (value
, 0) == FAIL
)
12304 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12305 _("invalid literal constant: pool needs to be closer"));
12309 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12310 newval
&= 0xff7ff000;
12311 newval
|= value
| (sign
? INDEX_UP
: 0);
12312 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12315 case BFD_RELOC_ARM_SHIFT_IMM
:
12316 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12317 if (((unsigned long) value
) > 32
12319 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
12321 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12322 _("shift expression is too large"));
12327 /* Shifts of zero must be done as lsl. */
12329 else if (value
== 32)
12331 newval
&= 0xfffff07f;
12332 newval
|= (value
& 0x1f) << 7;
12333 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12336 case BFD_RELOC_ARM_SWI
:
12337 if (arm_data
->thumb_mode
)
12339 if (((unsigned long) value
) > 0xff)
12340 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12341 _("invalid swi expression"));
12342 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
12344 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12348 if (((unsigned long) value
) > 0x00ffffff)
12349 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12350 _("invalid swi expression"));
12351 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
12353 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12357 case BFD_RELOC_ARM_MULTI
:
12358 if (((unsigned long) value
) > 0xffff)
12359 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12360 _("invalid expression in load/store multiple"));
12361 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
12362 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12365 case BFD_RELOC_ARM_PCREL_BRANCH
:
12366 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12368 /* Sign-extend a 24-bit number. */
12369 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
12373 value
= fixP
->fx_offset
;
12376 /* We are going to store value (shifted right by two) in the
12377 instruction, in a 24 bit, signed field. Thus we need to check
12378 that none of the top 8 bits of the shifted value (top 7 bits of
12379 the unshifted, unsigned value) are set, or that they are all set. */
12380 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
12381 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
12384 /* Normally we would be stuck at this point, since we cannot store
12385 the absolute address that is the destination of the branch in the
12386 24 bits of the branch instruction. If however, we happen to know
12387 that the destination of the branch is in the same section as the
12388 branch instruction itself, then we can compute the relocation for
12389 ourselves and not have to bother the linker with it.
12391 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
12392 because I have not worked out how to do this for OBJ_COFF or
12395 && fixP
->fx_addsy
!= NULL
12396 && S_IS_DEFINED (fixP
->fx_addsy
)
12397 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
12399 /* Get pc relative value to go into the branch. */
12402 /* Permit a backward branch provided that enough bits
12403 are set. Allow a forwards branch, provided that
12404 enough bits are clear. */
12405 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
12406 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
12410 if (! fixP
->fx_done
)
12412 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12413 _("GAS can't handle same-section branch dest >= 0x04000000"));
12417 value
+= SEXT24 (newval
);
12419 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
12420 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
12421 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12422 _("out of range branch"));
12424 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
12425 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12428 case BFD_RELOC_ARM_PCREL_BLX
:
12431 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12435 value
= fixP
->fx_offset
;
12437 hbit
= (value
>> 1) & 1;
12438 value
= (value
>> 2) & 0x00ffffff;
12439 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
12440 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
12441 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12445 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
12446 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12448 addressT diff
= (newval
& 0xff) << 1;
12453 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
12454 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12455 _("branch out of range"));
12456 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
12458 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12461 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
12462 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12464 addressT diff
= (newval
& 0x7ff) << 1;
12469 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
12470 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12471 _("branch out of range"));
12472 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
12474 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12477 case BFD_RELOC_THUMB_PCREL_BLX
:
12478 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
12483 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12484 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
12485 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
12486 if (diff
& 0x400000)
12489 value
= fixP
->fx_offset
;
12493 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
12494 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12495 _("branch with link out of range"));
12497 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
12498 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
12499 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
)
12500 /* For a BLX instruction, make sure that the relocation is rounded up
12501 to a word boundary. This follows the semantics of the instruction
12502 which specifies that bit 1 of the target address will come from bit
12503 1 of the base address. */
12504 newval2
= (newval2
+ 1) & ~ 1;
12505 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12506 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
12511 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
12512 md_number_to_chars (buf
, value
, 1);
12514 else if (!target_oabi
)
12516 value
= fixP
->fx_offset
;
12517 md_number_to_chars (buf
, value
, 1);
12523 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
12524 md_number_to_chars (buf
, value
, 2);
12526 else if (!target_oabi
)
12528 value
= fixP
->fx_offset
;
12529 md_number_to_chars (buf
, value
, 2);
12535 case BFD_RELOC_ARM_GOT32
:
12536 case BFD_RELOC_ARM_GOTOFF
:
12537 md_number_to_chars (buf
, 0, 4);
12541 case BFD_RELOC_RVA
:
12543 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
12544 md_number_to_chars (buf
, value
, 4);
12546 else if (!target_oabi
)
12548 value
= fixP
->fx_offset
;
12549 md_number_to_chars (buf
, value
, 4);
12555 case BFD_RELOC_ARM_PLT32
:
12556 /* It appears the instruction is fully prepared at this point. */
12560 case BFD_RELOC_ARM_CP_OFF_IMM
:
12562 if (value
< -1023 || value
> 1023 || (value
& 3))
12563 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12564 _("illegal value for co-processor offset"));
12567 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
12568 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
12569 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12572 case BFD_RELOC_ARM_CP_OFF_IMM_S2
:
12574 if (value
< -255 || value
> 255)
12575 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12576 _("Illegal value for co-processor offset"));
12579 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
12580 newval
|= value
| (sign
? INDEX_UP
: 0);
12581 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12584 case BFD_RELOC_ARM_THUMB_OFFSET
:
12585 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12586 /* Exactly what ranges, and where the offset is inserted depends
12587 on the type of instruction, we can establish this from the
12589 switch (newval
>> 12)
12591 case 4: /* PC load. */
12592 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12593 forced to zero for these loads, so we will need to round
12594 up the offset if the instruction address is not word
12595 aligned (since the final address produced must be, and
12596 we can only describe word-aligned immediate offsets). */
12598 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
12599 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12600 _("invalid offset, target not word aligned (0x%08X)"),
12601 (unsigned int) (fixP
->fx_frag
->fr_address
12602 + fixP
->fx_where
+ value
));
12604 if ((value
+ 2) & ~0x3fe)
12605 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12606 _("invalid offset, value too big (0x%08lX)"),
12609 /* Round up, since pc will be rounded down. */
12610 newval
|= (value
+ 2) >> 2;
12613 case 9: /* SP load/store. */
12614 if (value
& ~0x3fc)
12615 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12616 _("invalid offset, value too big (0x%08lX)"),
12618 newval
|= value
>> 2;
12621 case 6: /* Word load/store. */
12623 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12624 _("invalid offset, value too big (0x%08lX)"),
12626 newval
|= value
<< 4; /* 6 - 2. */
12629 case 7: /* Byte load/store. */
12631 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12632 _("invalid offset, value too big (0x%08lX)"),
12634 newval
|= value
<< 6;
12637 case 8: /* Halfword load/store. */
12639 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12640 _("invalid offset, value too big (0x%08lX)"),
12642 newval
|= value
<< 5; /* 6 - 1. */
12646 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12647 "Unable to process relocation for thumb opcode: %lx",
12648 (unsigned long) newval
);
12651 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12654 case BFD_RELOC_ARM_THUMB_ADD
:
12655 /* This is a complicated relocation, since we use it for all of
12656 the following immediate relocations:
12660 9bit ADD/SUB SP word-aligned
12661 10bit ADD PC/SP word-aligned
12663 The type of instruction being processed is encoded in the
12670 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12672 int rd
= (newval
>> 4) & 0xf;
12673 int rs
= newval
& 0xf;
12674 int subtract
= newval
& 0x8000;
12678 if (value
& ~0x1fc)
12679 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12680 _("invalid immediate for stack address calculation"));
12681 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
12682 newval
|= value
>> 2;
12684 else if (rs
== REG_PC
|| rs
== REG_SP
)
12688 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12689 _("invalid immediate for address calculation (value = 0x%08lX)"),
12690 (unsigned long) value
);
12691 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
12693 newval
|= value
>> 2;
12698 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12699 _("invalid 8bit immediate"));
12700 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
12701 newval
|= (rd
<< 8) | value
;
12706 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12707 _("invalid 3bit immediate"));
12708 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
12709 newval
|= rd
| (rs
<< 3) | (value
<< 6);
12712 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12715 case BFD_RELOC_ARM_THUMB_IMM
:
12716 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12717 switch (newval
>> 11)
12719 case 0x04: /* 8bit immediate MOV. */
12720 case 0x05: /* 8bit immediate CMP. */
12721 if (value
< 0 || value
> 255)
12722 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12723 _("invalid immediate: %ld is too large"),
12731 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12734 case BFD_RELOC_ARM_THUMB_SHIFT
:
12735 /* 5bit shift value (0..31). */
12736 if (value
< 0 || value
> 31)
12737 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12738 _("illegal Thumb shift value: %ld"), (long) value
);
12739 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
12740 newval
|= value
<< 6;
12741 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12744 case BFD_RELOC_VTABLE_INHERIT
:
12745 case BFD_RELOC_VTABLE_ENTRY
:
12749 case BFD_RELOC_NONE
:
12751 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12752 _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
12756 /* Translate internal representation of relocation info to BFD target
12760 tc_gen_reloc (section
, fixp
)
12761 asection
* section ATTRIBUTE_UNUSED
;
12765 bfd_reloc_code_real_type code
;
12767 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
12769 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
12770 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
12771 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
12773 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
12775 if (fixp
->fx_pcrel
== 0)
12776 reloc
->addend
= fixp
->fx_offset
;
12778 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
12779 #else /* OBJ_ELF */
12780 reloc
->addend
= fixp
->fx_offset
;
12783 switch (fixp
->fx_r_type
)
12786 if (fixp
->fx_pcrel
)
12788 code
= BFD_RELOC_8_PCREL
;
12793 if (fixp
->fx_pcrel
)
12795 code
= BFD_RELOC_16_PCREL
;
12800 if (fixp
->fx_pcrel
)
12802 code
= BFD_RELOC_32_PCREL
;
12806 case BFD_RELOC_ARM_PCREL_BRANCH
:
12807 case BFD_RELOC_ARM_PCREL_BLX
:
12808 case BFD_RELOC_RVA
:
12809 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
12810 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
12811 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
12812 case BFD_RELOC_THUMB_PCREL_BLX
:
12813 case BFD_RELOC_VTABLE_ENTRY
:
12814 case BFD_RELOC_VTABLE_INHERIT
:
12815 code
= fixp
->fx_r_type
;
12818 case BFD_RELOC_ARM_LITERAL
:
12819 case BFD_RELOC_ARM_HWLITERAL
:
12820 /* If this is called then the a literal has
12821 been referenced across a section boundary. */
12822 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12823 _("literal referenced across section boundary"));
12827 case BFD_RELOC_ARM_GOT32
:
12828 case BFD_RELOC_ARM_GOTOFF
:
12829 case BFD_RELOC_ARM_PLT32
:
12830 code
= fixp
->fx_r_type
;
12834 case BFD_RELOC_ARM_IMMEDIATE
:
12835 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12836 _("internal relocation (type: IMMEDIATE) not fixed up"));
12839 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
12840 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12841 _("ADRL used for a symbol not defined in the same file"));
12844 case BFD_RELOC_ARM_OFFSET_IMM
:
12845 if (fixp
->fx_addsy
!= NULL
12846 && !S_IS_DEFINED (fixp
->fx_addsy
)
12847 && S_IS_LOCAL (fixp
->fx_addsy
))
12849 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12850 _("undefined local label `%s'"),
12851 S_GET_NAME (fixp
->fx_addsy
));
12855 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12856 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12863 switch (fixp
->fx_r_type
)
12865 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
12866 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
12867 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
12868 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
12869 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
12870 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
12871 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
12872 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
12873 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
12874 default: type
= _("<unknown>"); break;
12876 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12877 _("cannot represent %s relocation in this object file format"),
12884 if ((code
== BFD_RELOC_32_PCREL
|| code
== BFD_RELOC_32
)
12886 && fixp
->fx_addsy
== GOT_symbol
)
12888 code
= BFD_RELOC_ARM_GOTPC
;
12889 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
12893 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
12895 if (reloc
->howto
== NULL
)
12897 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12898 _("cannot represent %s relocation in this object file format"),
12899 bfd_get_reloc_code_name (code
));
12903 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12904 vtable entry to be used in the relocation's section offset. */
12905 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
12906 reloc
->address
= fixp
->fx_offset
;
12912 md_estimate_size_before_relax (fragP
, segtype
)
12913 fragS
* fragP ATTRIBUTE_UNUSED
;
12914 segT segtype ATTRIBUTE_UNUSED
;
12916 as_fatal (_("md_estimate_size_before_relax\n"));
12928 as_bad ("%s -- `%s'", inst
.error
, str
);
12932 to
= frag_more (inst
.size
);
12934 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
12936 assert (inst
.size
== (2 * THUMB_SIZE
));
12937 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
12938 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
12940 else if (inst
.size
> INSN_SIZE
)
12942 assert (inst
.size
== (2 * INSN_SIZE
));
12943 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
12944 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
12947 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
12949 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
12950 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
12951 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
12955 dwarf2_emit_insn (inst
.size
);
12967 /* Align the instruction.
12968 This may not be the right thing to do but ... */
12973 /* Align the previous label if needed. */
12974 if (last_label_seen
!= NULL
)
12976 symbol_set_frag (last_label_seen
, frag_now
);
12977 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
12978 S_SET_SEGMENT (last_label_seen
, now_seg
);
12981 memset (&inst
, '\0', sizeof (inst
));
12982 inst
.reloc
.type
= BFD_RELOC_NONE
;
12984 skip_whitespace (str
);
12986 /* Scan up to the end of the op-code, which must end in white space or
12988 for (start
= p
= str
; *p
!= '\0'; p
++)
12994 as_bad (_("no operator -- statement `%s'\n"), str
);
13000 const struct thumb_opcode
* opcode
;
13004 opcode
= (const struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
13009 /* Check that this instruction is supported for this CPU. */
13010 if (thumb_mode
== 1 && (opcode
->variant
& cpu_variant
) == 0)
13012 as_bad (_("selected processor does not support `%s'"), str
);
13016 mapping_state (MAP_THUMB
);
13017 inst
.instruction
= opcode
->value
;
13018 inst
.size
= opcode
->size
;
13019 (*opcode
->parms
) (p
);
13026 const struct asm_opcode
* opcode
;
13030 opcode
= (const struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
13035 /* Check that this instruction is supported for this CPU. */
13036 if ((opcode
->variant
& cpu_variant
) == 0)
13038 as_bad (_("selected processor does not support `%s'"), str
);
13042 mapping_state (MAP_ARM
);
13043 inst
.instruction
= opcode
->value
;
13044 inst
.size
= INSN_SIZE
;
13045 (*opcode
->parms
) (p
);
13051 /* It wasn't an instruction, but it might be a register alias of the form
13053 if (create_register_alias (str
, p
))
13056 as_bad (_("bad instruction `%s'"), start
);
13060 Invocation line includes a switch not recognized by the base assembler.
13061 See if it's a processor-specific option.
13063 This routine is somewhat complicated by the need for backwards
13064 compatibility (since older releases of gcc can't be changed).
13065 The new options try to make the interface as compatible as
13068 New options (supported) are:
13070 -mcpu=<cpu name> Assemble for selected processor
13071 -march=<architecture name> Assemble for selected architecture
13072 -mfpu=<fpu architecture> Assemble for selected FPU.
13073 -EB/-mbig-endian Big-endian
13074 -EL/-mlittle-endian Little-endian
13075 -k Generate PIC code
13076 -mthumb Start in Thumb mode
13077 -mthumb-interwork Code supports ARM/Thumb interworking
13079 For now we will also provide support for:
13081 -mapcs-32 32-bit Program counter
13082 -mapcs-26 26-bit Program counter
13083 -macps-float Floats passed in FP registers
13084 -mapcs-reentrant Reentrant code
13086 (sometime these will probably be replaced with -mapcs=<list of options>
13087 and -matpcs=<list of options>)
13089 The remaining options are only supported for back-wards compatibility.
13090 Cpu variants, the arm part is optional:
13091 -m[arm]1 Currently not supported.
13092 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
13093 -m[arm]3 Arm 3 processor
13094 -m[arm]6[xx], Arm 6 processors
13095 -m[arm]7[xx][t][[d]m] Arm 7 processors
13096 -m[arm]8[10] Arm 8 processors
13097 -m[arm]9[20][tdmi] Arm 9 processors
13098 -mstrongarm[110[0]] StrongARM processors
13099 -mxscale XScale processors
13100 -m[arm]v[2345[t[e]]] Arm architectures
13101 -mall All (except the ARM1)
13103 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
13104 -mfpe-old (No float load/store multiples)
13105 -mvfpxd VFP Single precision
13107 -mno-fpu Disable all floating point instructions
13109 The following CPU names are recognized:
13110 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
13111 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
13112 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
13113 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
13114 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
13115 arm10t arm10e, arm1020t, arm1020e, arm10200e,
13116 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
13120 const char * md_shortopts
= "m:k";
13122 #ifdef ARM_BI_ENDIAN
13123 #define OPTION_EB (OPTION_MD_BASE + 0)
13124 #define OPTION_EL (OPTION_MD_BASE + 1)
13126 #if TARGET_BYTES_BIG_ENDIAN
13127 #define OPTION_EB (OPTION_MD_BASE + 0)
13129 #define OPTION_EL (OPTION_MD_BASE + 1)
13133 struct option md_longopts
[] =
13136 {"EB", no_argument
, NULL
, OPTION_EB
},
13139 {"EL", no_argument
, NULL
, OPTION_EL
},
13141 {NULL
, no_argument
, NULL
, 0}
13144 size_t md_longopts_size
= sizeof (md_longopts
);
13146 struct arm_option_table
13148 char *option
; /* Option name to match. */
13149 char *help
; /* Help information. */
13150 int *var
; /* Variable to change. */
13151 int value
; /* What to change it to. */
13152 char *deprecated
; /* If non-null, print this message. */
13155 struct arm_option_table arm_opts
[] =
13157 {"k", N_("generate PIC code"), &pic_code
, 1, NULL
},
13158 {"mthumb", N_("assemble Thumb code"), &thumb_mode
, 1, NULL
},
13159 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
13160 &support_interwork
, 1, NULL
},
13161 {"moabi", N_("use old ABI (ELF only)"), &target_oabi
, 1, NULL
},
13162 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26
, 0, NULL
},
13163 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26
, 1, NULL
},
13164 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float
,
13166 {"mapcs-reentrant", N_("re-entrant code"), &pic_code
, 1, NULL
},
13167 {"matpcs", N_("code is ATPCS conformant"), &atpcs
, 1, NULL
},
13168 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian
, 1, NULL
},
13169 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian
, 1,
13172 /* These are recognized by the assembler, but have no affect on code. */
13173 {"mapcs-frame", N_("use frame pointer"), NULL
, 0, NULL
},
13174 {"mapcs-stack-check", N_("use stack size checking"), NULL
, 0, NULL
},
13176 /* DON'T add any new processors to this list -- we want the whole list
13177 to go away... Add them to the processors table instead. */
13178 {"marm1", NULL
, &legacy_cpu
, ARM_ARCH_V1
, N_("use -mcpu=arm1")},
13179 {"m1", NULL
, &legacy_cpu
, ARM_ARCH_V1
, N_("use -mcpu=arm1")},
13180 {"marm2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -mcpu=arm2")},
13181 {"m2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -mcpu=arm2")},
13182 {"marm250", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm250")},
13183 {"m250", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm250")},
13184 {"marm3", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm3")},
13185 {"m3", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm3")},
13186 {"marm6", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm6")},
13187 {"m6", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm6")},
13188 {"marm600", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm600")},
13189 {"m600", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm600")},
13190 {"marm610", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm610")},
13191 {"m610", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm610")},
13192 {"marm620", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm620")},
13193 {"m620", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm620")},
13194 {"marm7", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7")},
13195 {"m7", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7")},
13196 {"marm70", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm70")},
13197 {"m70", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm70")},
13198 {"marm700", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700")},
13199 {"m700", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700")},
13200 {"marm700i", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700i")},
13201 {"m700i", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700i")},
13202 {"marm710", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710")},
13203 {"m710", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710")},
13204 {"marm710c", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710c")},
13205 {"m710c", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710c")},
13206 {"marm720", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm720")},
13207 {"m720", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm720")},
13208 {"marm7d", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7d")},
13209 {"m7d", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7d")},
13210 {"marm7di", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7di")},
13211 {"m7di", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7di")},
13212 {"marm7m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7m")},
13213 {"m7m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7m")},
13214 {"marm7dm", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dm")},
13215 {"m7dm", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dm")},
13216 {"marm7dmi", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dmi")},
13217 {"m7dmi", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dmi")},
13218 {"marm7100", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7100")},
13219 {"m7100", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7100")},
13220 {"marm7500", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500")},
13221 {"m7500", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500")},
13222 {"marm7500fe", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500fe")},
13223 {"m7500fe", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500fe")},
13224 {"marm7t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
13225 {"m7t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
13226 {"marm7tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
13227 {"m7tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
13228 {"marm710t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm710t")},
13229 {"m710t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm710t")},
13230 {"marm720t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm720t")},
13231 {"m720t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm720t")},
13232 {"marm740t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm740t")},
13233 {"m740t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm740t")},
13234 {"marm8", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm8")},
13235 {"m8", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm8")},
13236 {"marm810", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm810")},
13237 {"m810", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm810")},
13238 {"marm9", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9")},
13239 {"m9", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9")},
13240 {"marm9tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9tdmi")},
13241 {"m9tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9tdmi")},
13242 {"marm920", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm920")},
13243 {"m920", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm920")},
13244 {"marm940", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm940")},
13245 {"m940", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm940")},
13246 {"mstrongarm", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=strongarm")},
13247 {"mstrongarm110", NULL
, &legacy_cpu
, ARM_ARCH_V4
,
13248 N_("use -mcpu=strongarm110")},
13249 {"mstrongarm1100", NULL
, &legacy_cpu
, ARM_ARCH_V4
,
13250 N_("use -mcpu=strongarm1100")},
13251 {"mstrongarm1110", NULL
, &legacy_cpu
, ARM_ARCH_V4
,
13252 N_("use -mcpu=strongarm1110")},
13253 {"mxscale", NULL
, &legacy_cpu
, ARM_ARCH_XSCALE
, N_("use -mcpu=xscale")},
13254 {"miwmmxt", NULL
, &legacy_cpu
, ARM_ARCH_IWMMXT
, N_("use -mcpu=iwmmxt")},
13255 {"mall", NULL
, &legacy_cpu
, ARM_ANY
, N_("use -mcpu=all")},
13257 /* Architecture variants -- don't add any more to this list either. */
13258 {"mv2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -march=armv2")},
13259 {"marmv2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -march=armv2")},
13260 {"mv2a", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -march=armv2a")},
13261 {"marmv2a", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -march=armv2a")},
13262 {"mv3", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -march=armv3")},
13263 {"marmv3", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -march=armv3")},
13264 {"mv3m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -march=armv3m")},
13265 {"marmv3m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -march=armv3m")},
13266 {"mv4", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -march=armv4")},
13267 {"marmv4", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -march=armv4")},
13268 {"mv4t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -march=armv4t")},
13269 {"marmv4t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -march=armv4t")},
13270 {"mv5", NULL
, &legacy_cpu
, ARM_ARCH_V5
, N_("use -march=armv5")},
13271 {"marmv5", NULL
, &legacy_cpu
, ARM_ARCH_V5
, N_("use -march=armv5")},
13272 {"mv5t", NULL
, &legacy_cpu
, ARM_ARCH_V5T
, N_("use -march=armv5t")},
13273 {"marmv5t", NULL
, &legacy_cpu
, ARM_ARCH_V5T
, N_("use -march=armv5t")},
13274 {"mv5e", NULL
, &legacy_cpu
, ARM_ARCH_V5TE
, N_("use -march=armv5te")},
13275 {"marmv5e", NULL
, &legacy_cpu
, ARM_ARCH_V5TE
, N_("use -march=armv5te")},
13277 /* Floating point variants -- don't add any more to this list either. */
13278 {"mfpe-old", NULL
, &legacy_fpu
, FPU_ARCH_FPE
, N_("use -mfpu=fpe")},
13279 {"mfpa10", NULL
, &legacy_fpu
, FPU_ARCH_FPA
, N_("use -mfpu=fpa10")},
13280 {"mfpa11", NULL
, &legacy_fpu
, FPU_ARCH_FPA
, N_("use -mfpu=fpa11")},
13281 {"mno-fpu", NULL
, &legacy_fpu
, 0,
13282 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
13284 {NULL
, NULL
, NULL
, 0, NULL
}
13287 struct arm_cpu_option_table
13291 /* For some CPUs we assume an FPU unless the user explicitly sets
13296 /* This list should, at a minimum, contain all the cpu names
13297 recognized by GCC. */
13298 static struct arm_cpu_option_table arm_cpus
[] =
13300 {"all", ARM_ANY
, FPU_ARCH_FPA
},
13301 {"arm1", ARM_ARCH_V1
, FPU_ARCH_FPA
},
13302 {"arm2", ARM_ARCH_V2
, FPU_ARCH_FPA
},
13303 {"arm250", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
13304 {"arm3", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
13305 {"arm6", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13306 {"arm60", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13307 {"arm600", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13308 {"arm610", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13309 {"arm620", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13310 {"arm7", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13311 {"arm7m", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
13312 {"arm7d", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13313 {"arm7dm", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
13314 {"arm7di", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13315 {"arm7dmi", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
13316 {"arm70", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13317 {"arm700", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13318 {"arm700i", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13319 {"arm710", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13320 {"arm710t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13321 {"arm720", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13322 {"arm720t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13323 {"arm740t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13324 {"arm710c", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13325 {"arm7100", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13326 {"arm7500", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13327 {"arm7500fe", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13328 {"arm7t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13329 {"arm7tdmi", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13330 {"arm8", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13331 {"arm810", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13332 {"strongarm", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13333 {"strongarm1", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13334 {"strongarm110", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13335 {"strongarm1100", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13336 {"strongarm1110", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13337 {"arm9", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13338 {"arm920", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13339 {"arm920t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13340 {"arm922t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13341 {"arm940t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13342 {"arm9tdmi", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13343 /* For V5 or later processors we default to using VFP; but the user
13344 should really set the FPU type explicitly. */
13345 {"arm9e-r0", ARM_ARCH_V5TExP
, FPU_ARCH_VFP_V2
},
13346 {"arm9e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13347 {"arm926ej", ARM_ARCH_V5TEJ
, FPU_ARCH_VFP_V2
},
13348 {"arm926ejs", ARM_ARCH_V5TEJ
, FPU_ARCH_VFP_V2
},
13349 {"arm946e-r0", ARM_ARCH_V5TExP
, FPU_ARCH_VFP_V2
},
13350 {"arm946e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13351 {"arm966e-r0", ARM_ARCH_V5TExP
, FPU_ARCH_VFP_V2
},
13352 {"arm966e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13353 {"arm10t", ARM_ARCH_V5T
, FPU_ARCH_VFP_V1
},
13354 {"arm10e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13355 {"arm1020", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13356 {"arm1020t", ARM_ARCH_V5T
, FPU_ARCH_VFP_V1
},
13357 {"arm1020e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13358 {"arm1026ejs", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13359 {"arm1136js", ARM_ARCH_V6
, FPU_NONE
},
13360 {"arm1136jfs", ARM_ARCH_V6
, FPU_ARCH_VFP_V2
},
13361 /* ??? XSCALE is really an architecture. */
13362 {"xscale", ARM_ARCH_XSCALE
, FPU_ARCH_VFP_V2
},
13363 /* ??? iwmmxt is not a processor. */
13364 {"iwmmxt", ARM_ARCH_IWMMXT
, FPU_ARCH_VFP_V2
},
13365 {"i80200", ARM_ARCH_XSCALE
, FPU_ARCH_VFP_V2
},
13367 {"ep9312", ARM_ARCH_V4T
| ARM_CEXT_MAVERICK
, FPU_ARCH_MAVERICK
},
13371 struct arm_arch_option_table
13378 /* This list should, at a minimum, contain all the architecture names
13379 recognized by GCC. */
13380 static struct arm_arch_option_table arm_archs
[] =
13382 {"all", ARM_ANY
, FPU_ARCH_FPA
},
13383 {"armv1", ARM_ARCH_V1
, FPU_ARCH_FPA
},
13384 {"armv2", ARM_ARCH_V2
, FPU_ARCH_FPA
},
13385 {"armv2a", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
13386 {"armv2s", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
13387 {"armv3", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13388 {"armv3m", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
13389 {"armv4", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13390 {"armv4xm", ARM_ARCH_V4xM
, FPU_ARCH_FPA
},
13391 {"armv4t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13392 {"armv4txm", ARM_ARCH_V4TxM
, FPU_ARCH_FPA
},
13393 {"armv5", ARM_ARCH_V5
, FPU_ARCH_VFP
},
13394 {"armv5t", ARM_ARCH_V5T
, FPU_ARCH_VFP
},
13395 {"armv5txm", ARM_ARCH_V5TxM
, FPU_ARCH_VFP
},
13396 {"armv5te", ARM_ARCH_V5TE
, FPU_ARCH_VFP
},
13397 {"armv5texp", ARM_ARCH_V5TExP
, FPU_ARCH_VFP
},
13398 {"armv5tej", ARM_ARCH_V5TEJ
, FPU_ARCH_VFP
},
13399 {"armv6", ARM_ARCH_V6
, FPU_ARCH_VFP
},
13400 {"armv6j", ARM_ARCH_V6
, FPU_ARCH_VFP
},
13401 {"xscale", ARM_ARCH_XSCALE
, FPU_ARCH_VFP
},
13402 {"iwmmxt", ARM_ARCH_IWMMXT
, FPU_ARCH_VFP
},
13406 /* ISA extensions in the co-processor space. */
13407 struct arm_arch_extension_table
13413 static struct arm_arch_extension_table arm_extensions
[] =
13415 {"maverick", ARM_CEXT_MAVERICK
},
13416 {"xscale", ARM_CEXT_XSCALE
},
13417 {"iwmmxt", ARM_CEXT_IWMMXT
},
13421 struct arm_fpu_option_table
13427 /* This list should, at a minimum, contain all the fpu names
13428 recognized by GCC. */
13429 static struct arm_fpu_option_table arm_fpus
[] =
13431 {"softfpa", FPU_NONE
},
13432 {"fpe", FPU_ARCH_FPE
},
13433 {"fpe2", FPU_ARCH_FPE
},
13434 {"fpe3", FPU_ARCH_FPA
}, /* Third release supports LFM/SFM. */
13435 {"fpa", FPU_ARCH_FPA
},
13436 {"fpa10", FPU_ARCH_FPA
},
13437 {"fpa11", FPU_ARCH_FPA
},
13438 {"arm7500fe", FPU_ARCH_FPA
},
13439 {"softvfp", FPU_ARCH_VFP
},
13440 {"softvfp+vfp", FPU_ARCH_VFP_V2
},
13441 {"vfp", FPU_ARCH_VFP_V2
},
13442 {"vfp9", FPU_ARCH_VFP_V2
},
13443 {"vfp10", FPU_ARCH_VFP_V2
},
13444 {"vfp10-r0", FPU_ARCH_VFP_V1
},
13445 {"vfpxd", FPU_ARCH_VFP_V1xD
},
13446 {"arm1020t", FPU_ARCH_VFP_V1
},
13447 {"arm1020e", FPU_ARCH_VFP_V2
},
13448 {"arm1136jfs", FPU_ARCH_VFP_V2
},
13449 {"maverick", FPU_ARCH_MAVERICK
},
13453 struct arm_float_abi_option_table
13459 static struct arm_float_abi_option_table arm_float_abis
[] =
13461 {"hard", ARM_FLOAT_ABI_HARD
},
13462 {"softfp", ARM_FLOAT_ABI_SOFTFP
},
13463 {"soft", ARM_FLOAT_ABI_SOFT
},
13467 struct arm_eabi_option_table
13470 unsigned int value
;
13473 /* We only know hot to output GNU and ver 3 (AAELF) formats. */
13474 static struct arm_eabi_option_table arm_eabis
[] =
13476 {"gnu", EF_ARM_EABI_UNKNOWN
},
13477 {"3", EF_ARM_EABI_VER3
},
13481 struct arm_long_option_table
13483 char *option
; /* Substring to match. */
13484 char *help
; /* Help information. */
13485 int (*func
) PARAMS ((char *subopt
)); /* Function to decode sub-option. */
13486 char *deprecated
; /* If non-null, print this message. */
13490 arm_parse_extension (str
, opt_p
)
13494 while (str
!= NULL
&& *str
!= 0)
13496 struct arm_arch_extension_table
*opt
;
13502 as_bad (_("invalid architectural extension"));
13507 ext
= strchr (str
, '+');
13510 optlen
= ext
- str
;
13512 optlen
= strlen (str
);
13516 as_bad (_("missing architectural extension"));
13520 for (opt
= arm_extensions
; opt
->name
!= NULL
; opt
++)
13521 if (strncmp (opt
->name
, str
, optlen
) == 0)
13523 *opt_p
|= opt
->value
;
13527 if (opt
->name
== NULL
)
13529 as_bad (_("unknown architectural extnsion `%s'"), str
);
13540 arm_parse_cpu (str
)
13543 struct arm_cpu_option_table
*opt
;
13544 char *ext
= strchr (str
, '+');
13548 optlen
= ext
- str
;
13550 optlen
= strlen (str
);
13554 as_bad (_("missing cpu name `%s'"), str
);
13558 for (opt
= arm_cpus
; opt
->name
!= NULL
; opt
++)
13559 if (strncmp (opt
->name
, str
, optlen
) == 0)
13561 mcpu_cpu_opt
= opt
->value
;
13562 mcpu_fpu_opt
= opt
->default_fpu
;
13565 return arm_parse_extension (ext
, &mcpu_cpu_opt
);
13570 as_bad (_("unknown cpu `%s'"), str
);
13575 arm_parse_arch (str
)
13578 struct arm_arch_option_table
*opt
;
13579 char *ext
= strchr (str
, '+');
13583 optlen
= ext
- str
;
13585 optlen
= strlen (str
);
13589 as_bad (_("missing architecture name `%s'"), str
);
13594 for (opt
= arm_archs
; opt
->name
!= NULL
; opt
++)
13595 if (strcmp (opt
->name
, str
) == 0)
13597 march_cpu_opt
= opt
->value
;
13598 march_fpu_opt
= opt
->default_fpu
;
13601 return arm_parse_extension (ext
, &march_cpu_opt
);
13606 as_bad (_("unknown architecture `%s'\n"), str
);
13611 arm_parse_fpu (str
)
13614 struct arm_fpu_option_table
*opt
;
13616 for (opt
= arm_fpus
; opt
->name
!= NULL
; opt
++)
13617 if (strcmp (opt
->name
, str
) == 0)
13619 mfpu_opt
= opt
->value
;
13623 as_bad (_("unknown floating point format `%s'\n"), str
);
13628 arm_parse_float_abi (str
)
13631 struct arm_float_abi_option_table
*opt
;
13633 for (opt
= arm_float_abis
; opt
->name
!= NULL
; opt
++)
13634 if (strcmp (opt
->name
, str
) == 0)
13636 mfloat_abi_opt
= opt
->value
;
13640 as_bad (_("unknown floating point abi `%s'\n"), str
);
13645 arm_parse_eabi (str
)
13648 struct arm_eabi_option_table
*opt
;
13650 for (opt
= arm_eabis
; opt
->name
!= NULL
; opt
++)
13651 if (strcmp (opt
->name
, str
) == 0)
13653 meabi_flags
= opt
->value
;
13656 as_bad (_("unknown EABI `%s'\n"), str
);
13660 struct arm_long_option_table arm_long_opts
[] =
13662 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
13663 arm_parse_cpu
, NULL
},
13664 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
13665 arm_parse_arch
, NULL
},
13666 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
13667 arm_parse_fpu
, NULL
},
13668 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
13669 arm_parse_float_abi
, NULL
},
13670 {"meabi=", N_("<ver>\t assemble for eabi version <ver>"),
13671 arm_parse_eabi
, NULL
},
13672 {NULL
, NULL
, 0, NULL
}
13676 md_parse_option (c
, arg
)
13680 struct arm_option_table
*opt
;
13681 struct arm_long_option_table
*lopt
;
13687 target_big_endian
= 1;
13693 target_big_endian
= 0;
13698 /* Listing option. Just ignore these, we don't support additional
13703 for (opt
= arm_opts
; opt
->option
!= NULL
; opt
++)
13705 if (c
== opt
->option
[0]
13706 && ((arg
== NULL
&& opt
->option
[1] == 0)
13707 || strcmp (arg
, opt
->option
+ 1) == 0))
13709 #if WARN_DEPRECATED
13710 /* If the option is deprecated, tell the user. */
13711 if (opt
->deprecated
!= NULL
)
13712 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c
,
13713 arg
? arg
: "", _(opt
->deprecated
));
13716 if (opt
->var
!= NULL
)
13717 *opt
->var
= opt
->value
;
13723 for (lopt
= arm_long_opts
; lopt
->option
!= NULL
; lopt
++)
13725 /* These options are expected to have an argument. */
13726 if (c
== lopt
->option
[0]
13728 && strncmp (arg
, lopt
->option
+ 1,
13729 strlen (lopt
->option
+ 1)) == 0)
13731 #if WARN_DEPRECATED
13732 /* If the option is deprecated, tell the user. */
13733 if (lopt
->deprecated
!= NULL
)
13734 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c
, arg
,
13735 _(lopt
->deprecated
));
13738 /* Call the sup-option parser. */
13739 return (*lopt
->func
)(arg
+ strlen (lopt
->option
) - 1);
13743 as_bad (_("unrecognized option `-%c%s'"), c
, arg
? arg
: "");
13754 struct arm_option_table
*opt
;
13755 struct arm_long_option_table
*lopt
;
13757 fprintf (fp
, _(" ARM-specific assembler options:\n"));
13759 for (opt
= arm_opts
; opt
->option
!= NULL
; opt
++)
13760 if (opt
->help
!= NULL
)
13761 fprintf (fp
, " -%-23s%s\n", opt
->option
, _(opt
->help
));
13763 for (lopt
= arm_long_opts
; lopt
->option
!= NULL
; lopt
++)
13764 if (lopt
->help
!= NULL
)
13765 fprintf (fp
, " -%s%s\n", lopt
->option
, _(lopt
->help
));
13769 -EB assemble code for a big-endian cpu\n"));
13774 -EL assemble code for a little-endian cpu\n"));
13778 /* We need to be able to fix up arbitrary expressions in some statements.
13779 This is so that we can handle symbols that are an arbitrary distance from
13780 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
13781 which returns part of an address in a form which will be valid for
13782 a data instruction. We do this by pushing the expression into a symbol
13783 in the expr_section, and creating a fix for that. */
13786 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
13795 arm_fix_data
* arm_data
;
13803 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
13807 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
13812 /* Mark whether the fix is to a THUMB instruction, or an ARM
13814 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
13815 new_fix
->tc_fix_data
= (PTR
) arm_data
;
13816 arm_data
->thumb_mode
= thumb_mode
;
13819 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
13822 cons_fix_new_arm (frag
, where
, size
, exp
)
13828 bfd_reloc_code_real_type type
;
13832 FIXME: @@ Should look at CPU word size. */
13836 type
= BFD_RELOC_8
;
13839 type
= BFD_RELOC_16
;
13843 type
= BFD_RELOC_32
;
13846 type
= BFD_RELOC_64
;
13850 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
13853 /* A good place to do this, although this was probably not intended
13854 for this kind of use. We need to dump the literal pool before
13855 references are made to a null symbol pointer. */
13860 literal_pool
* pool
;
13862 for (pool
= list_of_pools
; pool
; pool
= pool
->next
)
13864 /* Put it at the end of the relevent section. */
13865 subseg_set (pool
->section
, pool
->sub_section
);
13871 arm_start_line_hook ()
13873 last_label_seen
= NULL
;
13877 arm_frob_label (sym
)
13880 last_label_seen
= sym
;
13882 ARM_SET_THUMB (sym
, thumb_mode
);
13884 #if defined OBJ_COFF || defined OBJ_ELF
13885 ARM_SET_INTERWORK (sym
, support_interwork
);
13888 /* Note - do not allow local symbols (.Lxxx) to be labeled
13889 as Thumb functions. This is because these labels, whilst
13890 they exist inside Thumb code, are not the entry points for
13891 possible ARM->Thumb calls. Also, these labels can be used
13892 as part of a computed goto or switch statement. eg gcc
13893 can generate code that looks like this:
13895 ldr r2, [pc, .Laaa]
13905 The first instruction loads the address of the jump table.
13906 The second instruction converts a table index into a byte offset.
13907 The third instruction gets the jump address out of the table.
13908 The fourth instruction performs the jump.
13910 If the address stored at .Laaa is that of a symbol which has the
13911 Thumb_Func bit set, then the linker will arrange for this address
13912 to have the bottom bit set, which in turn would mean that the
13913 address computation performed by the third instruction would end
13914 up with the bottom bit set. Since the ARM is capable of unaligned
13915 word loads, the instruction would then load the incorrect address
13916 out of the jump table, and chaos would ensue. */
13917 if (label_is_thumb_function_name
13918 && (S_GET_NAME (sym
)[0] != '.' || S_GET_NAME (sym
)[1] != 'L')
13919 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
13921 /* When the address of a Thumb function is taken the bottom
13922 bit of that address should be set. This will allow
13923 interworking between Arm and Thumb functions to work
13926 THUMB_SET_FUNC (sym
, 1);
13928 label_is_thumb_function_name
= FALSE
;
13932 /* Adjust the symbol table. This marks Thumb symbols as distinct from
13936 arm_adjust_symtab ()
13941 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
13943 if (ARM_IS_THUMB (sym
))
13945 if (THUMB_IS_FUNC (sym
))
13947 /* Mark the symbol as a Thumb function. */
13948 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
13949 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
13950 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
13952 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
13953 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
13955 as_bad (_("%s: unexpected function type: %d"),
13956 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
13958 else switch (S_GET_STORAGE_CLASS (sym
))
13961 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
13964 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
13967 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
13975 if (ARM_IS_INTERWORK (sym
))
13976 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
13983 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
13985 if (ARM_IS_THUMB (sym
))
13987 elf_symbol_type
* elf_sym
;
13989 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
13990 bind
= ELF_ST_BIND (elf_sym
);
13992 /* If it's a .thumb_func, declare it as so,
13993 otherwise tag label as .code 16. */
13994 if (THUMB_IS_FUNC (sym
))
13995 elf_sym
->internal_elf_sym
.st_info
=
13996 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
13998 elf_sym
->internal_elf_sym
.st_info
=
13999 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
14006 arm_data_in_code ()
14008 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
14010 *input_line_pointer
= '/';
14011 input_line_pointer
+= 5;
14012 *input_line_pointer
= 0;
14020 arm_canonicalize_symbol_name (name
)
14025 if (thumb_mode
&& (len
= strlen (name
)) > 5
14026 && streq (name
+ len
- 5, "/data"))
14027 *(name
+ len
- 5) = 0;
14032 #if defined OBJ_COFF || defined OBJ_ELF
14034 arm_validate_fix (fixP
)
14037 /* If the destination of the branch is a defined symbol which does not have
14038 the THUMB_FUNC attribute, then we must be calling a function which has
14039 the (interfacearm) attribute. We look for the Thumb entry point to that
14040 function and change the branch to refer to that function instead. */
14041 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
14042 && fixP
->fx_addsy
!= NULL
14043 && S_IS_DEFINED (fixP
->fx_addsy
)
14044 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
14046 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
14052 arm_force_relocation (fixp
)
14055 #if defined (OBJ_COFF) && defined (TE_PE)
14056 if (fixp
->fx_r_type
== BFD_RELOC_RVA
)
14060 if (fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
14061 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
14062 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
14063 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
14067 /* Resolve these relocations even if the symbol is extern or weak. */
14068 if (fixp
->fx_r_type
== BFD_RELOC_ARM_IMMEDIATE
14069 || fixp
->fx_r_type
== BFD_RELOC_ARM_OFFSET_IMM
14070 || fixp
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
14073 return generic_force_reloc (fixp
);
14077 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
14078 local labels from being added to the output symbol table when they
14079 are used with the ADRL pseudo op. The ADRL relocation should always
14080 be resolved before the binbary is emitted, so it is safe to say that
14081 it is adjustable. */
14084 arm_fix_adjustable (fixP
)
14087 if (fixP
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
14094 /* Relocations against Thumb function names must be left unadjusted,
14095 so that the linker can use this information to correctly set the
14096 bottom bit of their addresses. The MIPS version of this function
14097 also prevents relocations that are mips-16 specific, but I do not
14098 know why it does this.
14101 There is one other problem that ought to be addressed here, but
14102 which currently is not: Taking the address of a label (rather
14103 than a function) and then later jumping to that address. Such
14104 addresses also ought to have their bottom bit set (assuming that
14105 they reside in Thumb code), but at the moment they will not. */
14108 arm_fix_adjustable (fixP
)
14111 if (fixP
->fx_addsy
== NULL
)
14114 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
14115 && fixP
->fx_subsy
== NULL
)
14118 /* We need the symbol name for the VTABLE entries. */
14119 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
14120 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
14123 /* Don't allow symbols to be discarded on GOT related relocs. */
14124 if (fixP
->fx_r_type
== BFD_RELOC_ARM_PLT32
14125 || fixP
->fx_r_type
== BFD_RELOC_ARM_GOT32
14126 || fixP
->fx_r_type
== BFD_RELOC_ARM_GOTOFF
)
14133 elf32_arm_target_format ()
14135 if (target_big_endian
)
14138 return "elf32-bigarm-oabi";
14140 return "elf32-bigarm";
14145 return "elf32-littlearm-oabi";
14147 return "elf32-littlearm";
14152 armelf_frob_symbol (symp
, puntp
)
14156 elf_frob_symbol (symp
, puntp
);
14159 static bfd_reloc_code_real_type
14169 bfd_reloc_code_real_type reloc
;
14173 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
14174 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
14175 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
14176 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
14177 branch instructions generated by GCC for PLT relocs. */
14178 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
14179 { NULL
, 0, BFD_RELOC_UNUSED
}
14183 for (i
= 0, ip
= input_line_pointer
;
14184 i
< sizeof (id
) && (ISALNUM (*ip
) || ISPUNCT (*ip
));
14186 id
[i
] = TOLOWER (*ip
);
14188 for (i
= 0; reloc_map
[i
].str
; i
++)
14189 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
14192 input_line_pointer
+= reloc_map
[i
].len
;
14194 return reloc_map
[i
].reloc
;
14198 s_arm_elf_cons (nbytes
)
14203 #ifdef md_flush_pending_output
14204 md_flush_pending_output ();
14207 if (is_it_end_of_statement ())
14209 demand_empty_rest_of_line ();
14213 #ifdef md_cons_align
14214 md_cons_align (nbytes
);
14217 mapping_state (MAP_DATA
);
14220 bfd_reloc_code_real_type reloc
;
14222 expression (& exp
);
14224 if (exp
.X_op
== O_symbol
14225 && * input_line_pointer
== '('
14226 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
14228 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
14229 int size
= bfd_get_reloc_size (howto
);
14232 as_bad ("%s relocations do not fit in %d bytes",
14233 howto
->name
, nbytes
);
14236 register char *p
= frag_more ((int) nbytes
);
14237 int offset
= nbytes
- size
;
14239 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
14244 emit_expr (&exp
, (unsigned int) nbytes
);
14246 while (*input_line_pointer
++ == ',');
14248 /* Put terminator back into stream. */
14249 input_line_pointer
--;
14250 demand_empty_rest_of_line ();
14253 #endif /* OBJ_ELF */
14255 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
14256 of an rs_align_code fragment. */
14259 arm_handle_align (fragP
)
14262 static char const arm_noop
[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14263 static char const thumb_noop
[2] = { 0xc0, 0x46 };
14264 static char const arm_bigend_noop
[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14265 static char const thumb_bigend_noop
[2] = { 0x46, 0xc0 };
14267 int bytes
, fix
, noop_size
;
14271 if (fragP
->fr_type
!= rs_align_code
)
14274 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
14275 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
14278 if (bytes
> MAX_MEM_FOR_RS_ALIGN_CODE
)
14279 bytes
&= MAX_MEM_FOR_RS_ALIGN_CODE
;
14281 if (fragP
->tc_frag_data
)
14283 if (target_big_endian
)
14284 noop
= thumb_bigend_noop
;
14287 noop_size
= sizeof (thumb_noop
);
14291 if (target_big_endian
)
14292 noop
= arm_bigend_noop
;
14295 noop_size
= sizeof (arm_noop
);
14298 if (bytes
& (noop_size
- 1))
14300 fix
= bytes
& (noop_size
- 1);
14301 memset (p
, 0, fix
);
14306 while (bytes
>= noop_size
)
14308 memcpy (p
, noop
, noop_size
);
14310 bytes
-= noop_size
;
14314 fragP
->fr_fix
+= fix
;
14315 fragP
->fr_var
= noop_size
;
14318 /* Called from md_do_align. Used to create an alignment
14319 frag in a code section. */
14322 arm_frag_align_code (n
, max
)
14328 /* We assume that there will never be a requirement
14329 to support alignments greater than 32 bytes. */
14330 if (max
> MAX_MEM_FOR_RS_ALIGN_CODE
)
14331 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14333 p
= frag_var (rs_align_code
,
14334 MAX_MEM_FOR_RS_ALIGN_CODE
,
14336 (relax_substateT
) max
,
14344 /* Perform target specific initialisation of a frag. */
14347 arm_init_frag (fragP
)
14350 /* Record whether this frag is in an ARM or a THUMB area. */
14351 fragP
->tc_frag_data
= thumb_mode
;