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;
195 /* This array holds the chars that always start a comment. If the
196 pre-processor is disabled, these aren't very useful. */
197 const char comment_chars
[] = "@";
199 /* This array holds the chars that only start a comment at the beginning of
200 a line. If the line seems to have the form '# 123 filename'
201 .line and .file directives will appear in the pre-processed output. */
202 /* Note that input_file.c hand checks for '#' at the beginning of the
203 first line of the input file. This is because the compiler outputs
204 #NO_APP at the beginning of its output. */
205 /* Also note that comments like this one will always work. */
206 const char line_comment_chars
[] = "#";
208 const char line_separator_chars
[] = ";";
210 /* Chars that can be used to separate mant
211 from exp in floating point numbers. */
212 const char EXP_CHARS
[] = "eE";
214 /* Chars that mean this number is a floating point constant. */
218 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
220 /* Prefix characters that indicate the start of an immediate
222 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
225 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
226 symbolS
* GOT_symbol
;
229 /* Size of relocation record. */
230 const int md_reloc_size
= 8;
232 /* 0: assemble for ARM,
233 1: assemble for Thumb,
234 2: assemble for Thumb even though target CPU does not support thumb
236 static int thumb_mode
= 0;
238 typedef struct arm_fix
246 unsigned long instruction
;
250 bfd_reloc_code_real_type type
;
267 struct asm_shift_properties
269 enum asm_shift_index index
;
270 unsigned long bit_field
;
271 unsigned int allows_0
: 1;
272 unsigned int allows_32
: 1;
275 static const struct asm_shift_properties shift_properties
[] =
277 { SHIFT_LSL
, 0, 1, 0},
278 { SHIFT_LSR
, 0x20, 0, 1},
279 { SHIFT_ASR
, 0x40, 0, 1},
280 { SHIFT_ROR
, 0x60, 0, 0},
281 { SHIFT_RRX
, 0x60, 0, 0}
284 struct asm_shift_name
287 const struct asm_shift_properties
* properties
;
290 static const struct asm_shift_name shift_names
[] =
292 { "asl", shift_properties
+ SHIFT_LSL
},
293 { "lsl", shift_properties
+ SHIFT_LSL
},
294 { "lsr", shift_properties
+ SHIFT_LSR
},
295 { "asr", shift_properties
+ SHIFT_ASR
},
296 { "ror", shift_properties
+ SHIFT_ROR
},
297 { "rrx", shift_properties
+ SHIFT_RRX
},
298 { "ASL", shift_properties
+ SHIFT_LSL
},
299 { "LSL", shift_properties
+ SHIFT_LSL
},
300 { "LSR", shift_properties
+ SHIFT_LSR
},
301 { "ASR", shift_properties
+ SHIFT_ASR
},
302 { "ROR", shift_properties
+ SHIFT_ROR
},
303 { "RRX", shift_properties
+ SHIFT_RRX
}
306 /* Any kind of shift is accepted. */
307 #define NO_SHIFT_RESTRICT 1
308 /* The shift operand must be an immediate value, not a register. */
309 #define SHIFT_IMMEDIATE 0
310 /* The shift must be LSL or ASR and the operand must be an immediate. */
311 #define SHIFT_LSL_OR_ASR_IMMEDIATE 2
312 /* The shift must be ASR and the operand must be an immediate. */
313 #define SHIFT_ASR_IMMEDIATE 3
314 /* The shift must be LSL and the operand must be an immediate. */
315 #define SHIFT_LSL_IMMEDIATE 4
317 #define NUM_FLOAT_VALS 8
319 const char * fp_const
[] =
321 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
324 /* Number of littlenums required to hold an extended precision number. */
325 #define MAX_LITTLENUMS 6
327 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
332 /* Whether a Co-processor load/store operation accepts write-back forms. */
341 #define CP_T_X 0x00008000
342 #define CP_T_Y 0x00400000
343 #define CP_T_Pre 0x01000000
344 #define CP_T_UD 0x00800000
345 #define CP_T_WB 0x00200000
347 #define CONDS_BIT 0x00100000
348 #define LOAD_BIT 0x00100000
350 #define DOUBLE_LOAD_FLAG 0x00000001
354 const char * template;
358 #define COND_ALWAYS 0xe0000000
359 #define COND_MASK 0xf0000000
361 static const struct asm_cond conds
[] =
365 {"cs", 0x20000000}, {"hs", 0x20000000},
366 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
383 const char *template;
388 /* The bit that distinguishes CPSR and SPSR. */
389 #define SPSR_BIT (1 << 22)
391 /* How many bits to shift the PSR_xxx bits up by. */
394 #define PSR_c (1 << 0)
395 #define PSR_x (1 << 1)
396 #define PSR_s (1 << 2)
397 #define PSR_f (1 << 3)
399 static const struct asm_psr psrs
[] =
401 {"CPSR", TRUE
, PSR_c
| PSR_f
},
402 {"CPSR_all", TRUE
, PSR_c
| PSR_f
},
403 {"SPSR", FALSE
, PSR_c
| PSR_f
},
404 {"SPSR_all", FALSE
, PSR_c
| PSR_f
},
405 {"CPSR_flg", TRUE
, PSR_f
},
406 {"CPSR_f", TRUE
, PSR_f
},
407 {"SPSR_flg", FALSE
, PSR_f
},
408 {"SPSR_f", FALSE
, PSR_f
},
409 {"CPSR_c", TRUE
, PSR_c
},
410 {"CPSR_ctl", TRUE
, PSR_c
},
411 {"SPSR_c", FALSE
, PSR_c
},
412 {"SPSR_ctl", FALSE
, PSR_c
},
413 {"CPSR_x", TRUE
, PSR_x
},
414 {"CPSR_s", TRUE
, PSR_s
},
415 {"SPSR_x", FALSE
, PSR_x
},
416 {"SPSR_s", FALSE
, PSR_s
},
417 /* Combinations of flags. */
418 {"CPSR_fs", TRUE
, PSR_f
| PSR_s
},
419 {"CPSR_fx", TRUE
, PSR_f
| PSR_x
},
420 {"CPSR_fc", TRUE
, PSR_f
| PSR_c
},
421 {"CPSR_sf", TRUE
, PSR_s
| PSR_f
},
422 {"CPSR_sx", TRUE
, PSR_s
| PSR_x
},
423 {"CPSR_sc", TRUE
, PSR_s
| PSR_c
},
424 {"CPSR_xf", TRUE
, PSR_x
| PSR_f
},
425 {"CPSR_xs", TRUE
, PSR_x
| PSR_s
},
426 {"CPSR_xc", TRUE
, PSR_x
| PSR_c
},
427 {"CPSR_cf", TRUE
, PSR_c
| PSR_f
},
428 {"CPSR_cs", TRUE
, PSR_c
| PSR_s
},
429 {"CPSR_cx", TRUE
, PSR_c
| PSR_x
},
430 {"CPSR_fsx", TRUE
, PSR_f
| PSR_s
| PSR_x
},
431 {"CPSR_fsc", TRUE
, PSR_f
| PSR_s
| PSR_c
},
432 {"CPSR_fxs", TRUE
, PSR_f
| PSR_x
| PSR_s
},
433 {"CPSR_fxc", TRUE
, PSR_f
| PSR_x
| PSR_c
},
434 {"CPSR_fcs", TRUE
, PSR_f
| PSR_c
| PSR_s
},
435 {"CPSR_fcx", TRUE
, PSR_f
| PSR_c
| PSR_x
},
436 {"CPSR_sfx", TRUE
, PSR_s
| PSR_f
| PSR_x
},
437 {"CPSR_sfc", TRUE
, PSR_s
| PSR_f
| PSR_c
},
438 {"CPSR_sxf", TRUE
, PSR_s
| PSR_x
| PSR_f
},
439 {"CPSR_sxc", TRUE
, PSR_s
| PSR_x
| PSR_c
},
440 {"CPSR_scf", TRUE
, PSR_s
| PSR_c
| PSR_f
},
441 {"CPSR_scx", TRUE
, PSR_s
| PSR_c
| PSR_x
},
442 {"CPSR_xfs", TRUE
, PSR_x
| PSR_f
| PSR_s
},
443 {"CPSR_xfc", TRUE
, PSR_x
| PSR_f
| PSR_c
},
444 {"CPSR_xsf", TRUE
, PSR_x
| PSR_s
| PSR_f
},
445 {"CPSR_xsc", TRUE
, PSR_x
| PSR_s
| PSR_c
},
446 {"CPSR_xcf", TRUE
, PSR_x
| PSR_c
| PSR_f
},
447 {"CPSR_xcs", TRUE
, PSR_x
| PSR_c
| PSR_s
},
448 {"CPSR_cfs", TRUE
, PSR_c
| PSR_f
| PSR_s
},
449 {"CPSR_cfx", TRUE
, PSR_c
| PSR_f
| PSR_x
},
450 {"CPSR_csf", TRUE
, PSR_c
| PSR_s
| PSR_f
},
451 {"CPSR_csx", TRUE
, PSR_c
| PSR_s
| PSR_x
},
452 {"CPSR_cxf", TRUE
, PSR_c
| PSR_x
| PSR_f
},
453 {"CPSR_cxs", TRUE
, PSR_c
| PSR_x
| PSR_s
},
454 {"CPSR_fsxc", TRUE
, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
455 {"CPSR_fscx", TRUE
, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
456 {"CPSR_fxsc", TRUE
, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
457 {"CPSR_fxcs", TRUE
, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
458 {"CPSR_fcsx", TRUE
, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
459 {"CPSR_fcxs", TRUE
, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
460 {"CPSR_sfxc", TRUE
, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
461 {"CPSR_sfcx", TRUE
, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
462 {"CPSR_sxfc", TRUE
, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
463 {"CPSR_sxcf", TRUE
, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
464 {"CPSR_scfx", TRUE
, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
465 {"CPSR_scxf", TRUE
, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
466 {"CPSR_xfsc", TRUE
, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
467 {"CPSR_xfcs", TRUE
, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
468 {"CPSR_xsfc", TRUE
, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
469 {"CPSR_xscf", TRUE
, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
470 {"CPSR_xcfs", TRUE
, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
471 {"CPSR_xcsf", TRUE
, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
472 {"CPSR_cfsx", TRUE
, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
473 {"CPSR_cfxs", TRUE
, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
474 {"CPSR_csfx", TRUE
, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
475 {"CPSR_csxf", TRUE
, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
476 {"CPSR_cxfs", TRUE
, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
477 {"CPSR_cxsf", TRUE
, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
478 {"SPSR_fs", FALSE
, PSR_f
| PSR_s
},
479 {"SPSR_fx", FALSE
, PSR_f
| PSR_x
},
480 {"SPSR_fc", FALSE
, PSR_f
| PSR_c
},
481 {"SPSR_sf", FALSE
, PSR_s
| PSR_f
},
482 {"SPSR_sx", FALSE
, PSR_s
| PSR_x
},
483 {"SPSR_sc", FALSE
, PSR_s
| PSR_c
},
484 {"SPSR_xf", FALSE
, PSR_x
| PSR_f
},
485 {"SPSR_xs", FALSE
, PSR_x
| PSR_s
},
486 {"SPSR_xc", FALSE
, PSR_x
| PSR_c
},
487 {"SPSR_cf", FALSE
, PSR_c
| PSR_f
},
488 {"SPSR_cs", FALSE
, PSR_c
| PSR_s
},
489 {"SPSR_cx", FALSE
, PSR_c
| PSR_x
},
490 {"SPSR_fsx", FALSE
, PSR_f
| PSR_s
| PSR_x
},
491 {"SPSR_fsc", FALSE
, PSR_f
| PSR_s
| PSR_c
},
492 {"SPSR_fxs", FALSE
, PSR_f
| PSR_x
| PSR_s
},
493 {"SPSR_fxc", FALSE
, PSR_f
| PSR_x
| PSR_c
},
494 {"SPSR_fcs", FALSE
, PSR_f
| PSR_c
| PSR_s
},
495 {"SPSR_fcx", FALSE
, PSR_f
| PSR_c
| PSR_x
},
496 {"SPSR_sfx", FALSE
, PSR_s
| PSR_f
| PSR_x
},
497 {"SPSR_sfc", FALSE
, PSR_s
| PSR_f
| PSR_c
},
498 {"SPSR_sxf", FALSE
, PSR_s
| PSR_x
| PSR_f
},
499 {"SPSR_sxc", FALSE
, PSR_s
| PSR_x
| PSR_c
},
500 {"SPSR_scf", FALSE
, PSR_s
| PSR_c
| PSR_f
},
501 {"SPSR_scx", FALSE
, PSR_s
| PSR_c
| PSR_x
},
502 {"SPSR_xfs", FALSE
, PSR_x
| PSR_f
| PSR_s
},
503 {"SPSR_xfc", FALSE
, PSR_x
| PSR_f
| PSR_c
},
504 {"SPSR_xsf", FALSE
, PSR_x
| PSR_s
| PSR_f
},
505 {"SPSR_xsc", FALSE
, PSR_x
| PSR_s
| PSR_c
},
506 {"SPSR_xcf", FALSE
, PSR_x
| PSR_c
| PSR_f
},
507 {"SPSR_xcs", FALSE
, PSR_x
| PSR_c
| PSR_s
},
508 {"SPSR_cfs", FALSE
, PSR_c
| PSR_f
| PSR_s
},
509 {"SPSR_cfx", FALSE
, PSR_c
| PSR_f
| PSR_x
},
510 {"SPSR_csf", FALSE
, PSR_c
| PSR_s
| PSR_f
},
511 {"SPSR_csx", FALSE
, PSR_c
| PSR_s
| PSR_x
},
512 {"SPSR_cxf", FALSE
, PSR_c
| PSR_x
| PSR_f
},
513 {"SPSR_cxs", FALSE
, PSR_c
| PSR_x
| PSR_s
},
514 {"SPSR_fsxc", FALSE
, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
515 {"SPSR_fscx", FALSE
, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
516 {"SPSR_fxsc", FALSE
, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
517 {"SPSR_fxcs", FALSE
, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
518 {"SPSR_fcsx", FALSE
, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
519 {"SPSR_fcxs", FALSE
, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
520 {"SPSR_sfxc", FALSE
, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
521 {"SPSR_sfcx", FALSE
, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
522 {"SPSR_sxfc", FALSE
, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
523 {"SPSR_sxcf", FALSE
, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
524 {"SPSR_scfx", FALSE
, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
525 {"SPSR_scxf", FALSE
, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
526 {"SPSR_xfsc", FALSE
, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
527 {"SPSR_xfcs", FALSE
, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
528 {"SPSR_xsfc", FALSE
, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
529 {"SPSR_xscf", FALSE
, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
530 {"SPSR_xcfs", FALSE
, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
531 {"SPSR_xcsf", FALSE
, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
532 {"SPSR_cfsx", FALSE
, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
533 {"SPSR_cfxs", FALSE
, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
534 {"SPSR_csfx", FALSE
, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
535 {"SPSR_csxf", FALSE
, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
536 {"SPSR_cxfs", FALSE
, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
537 {"SPSR_cxsf", FALSE
, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
544 IWMMXT_REG_WR_OR_WC
= 2,
548 enum iwmmxt_insn_type
571 VFP_REG_Dd
, VFP_REG_Dm
, VFP_REG_Dn
576 VFP_REG_Sd
, VFP_REG_Sm
, VFP_REG_Sn
581 VFP_LDSTMIA
, VFP_LDSTMDB
, VFP_LDSTMIAX
, VFP_LDSTMDBX
584 /* VFP system registers. */
591 static const struct vfp_reg vfp_regs
[] =
593 {"fpsid", 0x00000000},
594 {"FPSID", 0x00000000},
595 {"fpscr", 0x00010000},
596 {"FPSCR", 0x00010000},
597 {"fpexc", 0x00080000},
598 {"FPEXC", 0x00080000}
601 /* Structure for a hash table entry for a register. */
609 /* Some well known registers that we refer to directly elsewhere. */
614 #define wr_register(reg) ((reg ^ WR_PREFIX) >= 0 && (reg ^ WR_PREFIX) <= 15)
615 #define wc_register(reg) ((reg ^ WC_PREFIX) >= 0 && (reg ^ WC_PREFIX) <= 15)
616 #define wcg_register(reg) ((reg ^ WC_PREFIX) >= 8 && (reg ^ WC_PREFIX) <= 11)
618 /* These are the standard names. Users can add aliases with .req.
619 and delete them with .unreq. */
621 /* Integer Register Numbers. */
622 static const struct reg_entry rn_table
[] =
624 {"r0", 0, TRUE
}, {"r1", 1, TRUE
}, {"r2", 2, TRUE
}, {"r3", 3, TRUE
},
625 {"r4", 4, TRUE
}, {"r5", 5, TRUE
}, {"r6", 6, TRUE
}, {"r7", 7, TRUE
},
626 {"r8", 8, TRUE
}, {"r9", 9, TRUE
}, {"r10", 10, TRUE
}, {"r11", 11, TRUE
},
627 {"r12", 12, TRUE
}, {"r13", REG_SP
, TRUE
}, {"r14", REG_LR
, TRUE
}, {"r15", REG_PC
, TRUE
},
628 /* ATPCS Synonyms. */
629 {"a1", 0, TRUE
}, {"a2", 1, TRUE
}, {"a3", 2, TRUE
}, {"a4", 3, TRUE
},
630 {"v1", 4, TRUE
}, {"v2", 5, TRUE
}, {"v3", 6, TRUE
}, {"v4", 7, TRUE
},
631 {"v5", 8, TRUE
}, {"v6", 9, TRUE
}, {"v7", 10, TRUE
}, {"v8", 11, TRUE
},
632 /* Well-known aliases. */
633 {"wr", 7, TRUE
}, {"sb", 9, TRUE
}, {"sl", 10, TRUE
}, {"fp", 11, TRUE
},
634 {"ip", 12, TRUE
}, {"sp", REG_SP
, TRUE
}, {"lr", REG_LR
, TRUE
}, {"pc", REG_PC
, TRUE
},
638 #define WR_PREFIX 0x200
639 #define WC_PREFIX 0x400
641 static const struct reg_entry iwmmxt_table
[] =
643 /* Intel Wireless MMX technology register names. */
644 { "wr0", 0x0 | WR_PREFIX
, TRUE
}, {"wr1", 0x1 | WR_PREFIX
, TRUE
},
645 { "wr2", 0x2 | WR_PREFIX
, TRUE
}, {"wr3", 0x3 | WR_PREFIX
, TRUE
},
646 { "wr4", 0x4 | WR_PREFIX
, TRUE
}, {"wr5", 0x5 | WR_PREFIX
, TRUE
},
647 { "wr6", 0x6 | WR_PREFIX
, TRUE
}, {"wr7", 0x7 | WR_PREFIX
, TRUE
},
648 { "wr8", 0x8 | WR_PREFIX
, TRUE
}, {"wr9", 0x9 | WR_PREFIX
, TRUE
},
649 { "wr10", 0xa | WR_PREFIX
, TRUE
}, {"wr11", 0xb | WR_PREFIX
, TRUE
},
650 { "wr12", 0xc | WR_PREFIX
, TRUE
}, {"wr13", 0xd | WR_PREFIX
, TRUE
},
651 { "wr14", 0xe | WR_PREFIX
, TRUE
}, {"wr15", 0xf | WR_PREFIX
, TRUE
},
652 { "wcid", 0x0 | WC_PREFIX
, TRUE
}, {"wcon", 0x1 | WC_PREFIX
, TRUE
},
653 {"wcssf", 0x2 | WC_PREFIX
, TRUE
}, {"wcasf", 0x3 | WC_PREFIX
, TRUE
},
654 {"wcgr0", 0x8 | WC_PREFIX
, TRUE
}, {"wcgr1", 0x9 | WC_PREFIX
, TRUE
},
655 {"wcgr2", 0xa | WC_PREFIX
, TRUE
}, {"wcgr3", 0xb | WC_PREFIX
, TRUE
},
657 { "wR0", 0x0 | WR_PREFIX
, TRUE
}, {"wR1", 0x1 | WR_PREFIX
, TRUE
},
658 { "wR2", 0x2 | WR_PREFIX
, TRUE
}, {"wR3", 0x3 | WR_PREFIX
, TRUE
},
659 { "wR4", 0x4 | WR_PREFIX
, TRUE
}, {"wR5", 0x5 | WR_PREFIX
, TRUE
},
660 { "wR6", 0x6 | WR_PREFIX
, TRUE
}, {"wR7", 0x7 | WR_PREFIX
, TRUE
},
661 { "wR8", 0x8 | WR_PREFIX
, TRUE
}, {"wR9", 0x9 | WR_PREFIX
, TRUE
},
662 { "wR10", 0xa | WR_PREFIX
, TRUE
}, {"wR11", 0xb | WR_PREFIX
, TRUE
},
663 { "wR12", 0xc | WR_PREFIX
, TRUE
}, {"wR13", 0xd | WR_PREFIX
, TRUE
},
664 { "wR14", 0xe | WR_PREFIX
, TRUE
}, {"wR15", 0xf | WR_PREFIX
, TRUE
},
665 { "wCID", 0x0 | WC_PREFIX
, TRUE
}, {"wCon", 0x1 | WC_PREFIX
, TRUE
},
666 {"wCSSF", 0x2 | WC_PREFIX
, TRUE
}, {"wCASF", 0x3 | WC_PREFIX
, TRUE
},
667 {"wCGR0", 0x8 | WC_PREFIX
, TRUE
}, {"wCGR1", 0x9 | WC_PREFIX
, TRUE
},
668 {"wCGR2", 0xa | WC_PREFIX
, TRUE
}, {"wCGR3", 0xb | WC_PREFIX
, TRUE
},
672 /* Co-processor Numbers. */
673 static const struct reg_entry cp_table
[] =
675 {"p0", 0, TRUE
}, {"p1", 1, TRUE
}, {"p2", 2, TRUE
}, {"p3", 3, TRUE
},
676 {"p4", 4, TRUE
}, {"p5", 5, TRUE
}, {"p6", 6, TRUE
}, {"p7", 7, TRUE
},
677 {"p8", 8, TRUE
}, {"p9", 9, TRUE
}, {"p10", 10, TRUE
}, {"p11", 11, TRUE
},
678 {"p12", 12, TRUE
}, {"p13", 13, TRUE
}, {"p14", 14, TRUE
}, {"p15", 15, TRUE
},
682 /* Co-processor Register Numbers. */
683 static const struct reg_entry cn_table
[] =
685 {"c0", 0, TRUE
}, {"c1", 1, TRUE
}, {"c2", 2, TRUE
}, {"c3", 3, TRUE
},
686 {"c4", 4, TRUE
}, {"c5", 5, TRUE
}, {"c6", 6, TRUE
}, {"c7", 7, TRUE
},
687 {"c8", 8, TRUE
}, {"c9", 9, TRUE
}, {"c10", 10, TRUE
}, {"c11", 11, TRUE
},
688 {"c12", 12, TRUE
}, {"c13", 13, TRUE
}, {"c14", 14, TRUE
}, {"c15", 15, TRUE
},
689 /* Not really valid, but kept for back-wards compatibility. */
690 {"cr0", 0, TRUE
}, {"cr1", 1, TRUE
}, {"cr2", 2, TRUE
}, {"cr3", 3, TRUE
},
691 {"cr4", 4, TRUE
}, {"cr5", 5, TRUE
}, {"cr6", 6, TRUE
}, {"cr7", 7, TRUE
},
692 {"cr8", 8, TRUE
}, {"cr9", 9, TRUE
}, {"cr10", 10, TRUE
}, {"cr11", 11, TRUE
},
693 {"cr12", 12, TRUE
}, {"cr13", 13, TRUE
}, {"cr14", 14, TRUE
}, {"cr15", 15, TRUE
},
698 static const struct reg_entry fn_table
[] =
700 {"f0", 0, TRUE
}, {"f1", 1, TRUE
}, {"f2", 2, TRUE
}, {"f3", 3, TRUE
},
701 {"f4", 4, TRUE
}, {"f5", 5, TRUE
}, {"f6", 6, TRUE
}, {"f7", 7, TRUE
},
705 /* VFP SP Registers. */
706 static const struct reg_entry sn_table
[] =
708 {"s0", 0, TRUE
}, {"s1", 1, TRUE
}, {"s2", 2, TRUE
}, {"s3", 3, TRUE
},
709 {"s4", 4, TRUE
}, {"s5", 5, TRUE
}, {"s6", 6, TRUE
}, {"s7", 7, TRUE
},
710 {"s8", 8, TRUE
}, {"s9", 9, TRUE
}, {"s10", 10, TRUE
}, {"s11", 11, TRUE
},
711 {"s12", 12, TRUE
}, {"s13", 13, TRUE
}, {"s14", 14, TRUE
}, {"s15", 15, TRUE
},
712 {"s16", 16, TRUE
}, {"s17", 17, TRUE
}, {"s18", 18, TRUE
}, {"s19", 19, TRUE
},
713 {"s20", 20, TRUE
}, {"s21", 21, TRUE
}, {"s22", 22, TRUE
}, {"s23", 23, TRUE
},
714 {"s24", 24, TRUE
}, {"s25", 25, TRUE
}, {"s26", 26, TRUE
}, {"s27", 27, TRUE
},
715 {"s28", 28, TRUE
}, {"s29", 29, TRUE
}, {"s30", 30, TRUE
}, {"s31", 31, TRUE
},
719 /* VFP DP Registers. */
720 static const struct reg_entry dn_table
[] =
722 {"d0", 0, TRUE
}, {"d1", 1, TRUE
}, {"d2", 2, TRUE
}, {"d3", 3, TRUE
},
723 {"d4", 4, TRUE
}, {"d5", 5, TRUE
}, {"d6", 6, TRUE
}, {"d7", 7, TRUE
},
724 {"d8", 8, TRUE
}, {"d9", 9, TRUE
}, {"d10", 10, TRUE
}, {"d11", 11, TRUE
},
725 {"d12", 12, TRUE
}, {"d13", 13, TRUE
}, {"d14", 14, TRUE
}, {"d15", 15, TRUE
},
729 /* Maverick DSP coprocessor registers. */
730 static const struct reg_entry mav_mvf_table
[] =
732 {"mvf0", 0, TRUE
}, {"mvf1", 1, TRUE
}, {"mvf2", 2, TRUE
}, {"mvf3", 3, TRUE
},
733 {"mvf4", 4, TRUE
}, {"mvf5", 5, TRUE
}, {"mvf6", 6, TRUE
}, {"mvf7", 7, TRUE
},
734 {"mvf8", 8, TRUE
}, {"mvf9", 9, TRUE
}, {"mvf10", 10, TRUE
}, {"mvf11", 11, TRUE
},
735 {"mvf12", 12, TRUE
}, {"mvf13", 13, TRUE
}, {"mvf14", 14, TRUE
}, {"mvf15", 15, TRUE
},
739 static const struct reg_entry mav_mvd_table
[] =
741 {"mvd0", 0, TRUE
}, {"mvd1", 1, TRUE
}, {"mvd2", 2, TRUE
}, {"mvd3", 3, TRUE
},
742 {"mvd4", 4, TRUE
}, {"mvd5", 5, TRUE
}, {"mvd6", 6, TRUE
}, {"mvd7", 7, TRUE
},
743 {"mvd8", 8, TRUE
}, {"mvd9", 9, TRUE
}, {"mvd10", 10, TRUE
}, {"mvd11", 11, TRUE
},
744 {"mvd12", 12, TRUE
}, {"mvd13", 13, TRUE
}, {"mvd14", 14, TRUE
}, {"mvd15", 15, TRUE
},
748 static const struct reg_entry mav_mvfx_table
[] =
750 {"mvfx0", 0, TRUE
}, {"mvfx1", 1, TRUE
}, {"mvfx2", 2, TRUE
}, {"mvfx3", 3, TRUE
},
751 {"mvfx4", 4, TRUE
}, {"mvfx5", 5, TRUE
}, {"mvfx6", 6, TRUE
}, {"mvfx7", 7, TRUE
},
752 {"mvfx8", 8, TRUE
}, {"mvfx9", 9, TRUE
}, {"mvfx10", 10, TRUE
}, {"mvfx11", 11, TRUE
},
753 {"mvfx12", 12, TRUE
}, {"mvfx13", 13, TRUE
}, {"mvfx14", 14, TRUE
}, {"mvfx15", 15, TRUE
},
757 static const struct reg_entry mav_mvdx_table
[] =
759 {"mvdx0", 0, TRUE
}, {"mvdx1", 1, TRUE
}, {"mvdx2", 2, TRUE
}, {"mvdx3", 3, TRUE
},
760 {"mvdx4", 4, TRUE
}, {"mvdx5", 5, TRUE
}, {"mvdx6", 6, TRUE
}, {"mvdx7", 7, TRUE
},
761 {"mvdx8", 8, TRUE
}, {"mvdx9", 9, TRUE
}, {"mvdx10", 10, TRUE
}, {"mvdx11", 11, TRUE
},
762 {"mvdx12", 12, TRUE
}, {"mvdx13", 13, TRUE
}, {"mvdx14", 14, TRUE
}, {"mvdx15", 15, TRUE
},
766 static const struct reg_entry mav_mvax_table
[] =
768 {"mvax0", 0, TRUE
}, {"mvax1", 1, TRUE
}, {"mvax2", 2, TRUE
}, {"mvax3", 3, TRUE
},
772 static const struct reg_entry mav_dspsc_table
[] =
780 const struct reg_entry
*names
;
782 struct hash_control
*htab
;
783 const char *expected
;
786 struct reg_map all_reg_maps
[] =
788 {rn_table
, 15, NULL
, N_("ARM register expected")},
789 {cp_table
, 15, NULL
, N_("bad or missing co-processor number")},
790 {cn_table
, 15, NULL
, N_("co-processor register expected")},
791 {fn_table
, 7, NULL
, N_("FPA register expected")},
792 {sn_table
, 31, NULL
, N_("VFP single precision register expected")},
793 {dn_table
, 15, NULL
, N_("VFP double precision register expected")},
794 {mav_mvf_table
, 15, NULL
, N_("Maverick MVF register expected")},
795 {mav_mvd_table
, 15, NULL
, N_("Maverick MVD register expected")},
796 {mav_mvfx_table
, 15, NULL
, N_("Maverick MVFX register expected")},
797 {mav_mvdx_table
, 15, NULL
, N_("Maverick MVDX register expected")},
798 {mav_mvax_table
, 3, NULL
, N_("Maverick MVAX register expected")},
799 {mav_dspsc_table
, 0, NULL
, N_("Maverick DSPSC register expected")},
800 {iwmmxt_table
, 23, NULL
, N_("Intel Wireless MMX technology register expected")},
803 /* Enumeration matching entries in table above. */
807 #define REG_TYPE_FIRST REG_TYPE_RN
819 REG_TYPE_IWMMXT
= 12,
824 /* Functions called by parser. */
825 /* ARM instructions. */
826 static void do_arit
PARAMS ((char *));
827 static void do_cmp
PARAMS ((char *));
828 static void do_mov
PARAMS ((char *));
829 static void do_ldst
PARAMS ((char *));
830 static void do_ldstt
PARAMS ((char *));
831 static void do_ldmstm
PARAMS ((char *));
832 static void do_branch
PARAMS ((char *));
833 static void do_swi
PARAMS ((char *));
835 /* Pseudo Op codes. */
836 static void do_adr
PARAMS ((char *));
837 static void do_adrl
PARAMS ((char *));
838 static void do_empty
PARAMS ((char *));
841 static void do_mul
PARAMS ((char *));
842 static void do_mla
PARAMS ((char *));
845 static void do_swap
PARAMS ((char *));
848 static void do_msr
PARAMS ((char *));
849 static void do_mrs
PARAMS ((char *));
852 static void do_mull
PARAMS ((char *));
855 static void do_ldstv4
PARAMS ((char *));
858 static void do_bx
PARAMS ((char *));
861 static void do_blx
PARAMS ((char *));
862 static void do_bkpt
PARAMS ((char *));
863 static void do_clz
PARAMS ((char *));
864 static void do_lstc2
PARAMS ((char *));
865 static void do_cdp2
PARAMS ((char *));
866 static void do_co_reg2
PARAMS ((char *));
869 static void do_smla
PARAMS ((char *));
870 static void do_smlal
PARAMS ((char *));
871 static void do_smul
PARAMS ((char *));
872 static void do_qadd
PARAMS ((char *));
875 static void do_pld
PARAMS ((char *));
876 static void do_ldrd
PARAMS ((char *));
877 static void do_co_reg2c
PARAMS ((char *));
880 static void do_bxj
PARAMS ((char *));
883 static void do_cps
PARAMS ((char *));
884 static void do_cpsi
PARAMS ((char *));
885 static void do_ldrex
PARAMS ((char *));
886 static void do_pkhbt
PARAMS ((char *));
887 static void do_pkhtb
PARAMS ((char *));
888 static void do_qadd16
PARAMS ((char *));
889 static void do_rev
PARAMS ((char *));
890 static void do_rfe
PARAMS ((char *));
891 static void do_sxtah
PARAMS ((char *));
892 static void do_sxth
PARAMS ((char *));
893 static void do_setend
PARAMS ((char *));
894 static void do_smlad
PARAMS ((char *));
895 static void do_smlald
PARAMS ((char *));
896 static void do_smmul
PARAMS ((char *));
897 static void do_ssat
PARAMS ((char *));
898 static void do_usat
PARAMS ((char *));
899 static void do_srs
PARAMS ((char *));
900 static void do_ssat16
PARAMS ((char *));
901 static void do_usat16
PARAMS ((char *));
902 static void do_strex
PARAMS ((char *));
903 static void do_umaal
PARAMS ((char *));
905 static void do_cps_mode
PARAMS ((char **));
906 static void do_cps_flags
PARAMS ((char **, int));
907 static int do_endian_specifier
PARAMS ((char *));
908 static void do_pkh_core
PARAMS ((char *, int));
909 static void do_sat
PARAMS ((char **, int));
910 static void do_sat16
PARAMS ((char **, int));
912 /* Coprocessor Instructions. */
913 static void do_cdp
PARAMS ((char *));
914 static void do_lstc
PARAMS ((char *));
915 static void do_co_reg
PARAMS ((char *));
917 /* FPA instructions. */
918 static void do_fpa_ctrl
PARAMS ((char *));
919 static void do_fpa_ldst
PARAMS ((char *));
920 static void do_fpa_ldmstm
PARAMS ((char *));
921 static void do_fpa_dyadic
PARAMS ((char *));
922 static void do_fpa_monadic
PARAMS ((char *));
923 static void do_fpa_cmp
PARAMS ((char *));
924 static void do_fpa_from_reg
PARAMS ((char *));
925 static void do_fpa_to_reg
PARAMS ((char *));
927 /* VFP instructions. */
928 static void do_vfp_sp_monadic
PARAMS ((char *));
929 static void do_vfp_dp_monadic
PARAMS ((char *));
930 static void do_vfp_sp_dyadic
PARAMS ((char *));
931 static void do_vfp_dp_dyadic
PARAMS ((char *));
932 static void do_vfp_reg_from_sp
PARAMS ((char *));
933 static void do_vfp_sp_from_reg
PARAMS ((char *));
934 static void do_vfp_reg2_from_sp2
PARAMS ((char *));
935 static void do_vfp_sp2_from_reg2
PARAMS ((char *));
936 static void do_vfp_reg_from_dp
PARAMS ((char *));
937 static void do_vfp_reg2_from_dp
PARAMS ((char *));
938 static void do_vfp_dp_from_reg
PARAMS ((char *));
939 static void do_vfp_dp_from_reg2
PARAMS ((char *));
940 static void do_vfp_reg_from_ctrl
PARAMS ((char *));
941 static void do_vfp_ctrl_from_reg
PARAMS ((char *));
942 static void do_vfp_sp_ldst
PARAMS ((char *));
943 static void do_vfp_dp_ldst
PARAMS ((char *));
944 static void do_vfp_sp_ldstmia
PARAMS ((char *));
945 static void do_vfp_sp_ldstmdb
PARAMS ((char *));
946 static void do_vfp_dp_ldstmia
PARAMS ((char *));
947 static void do_vfp_dp_ldstmdb
PARAMS ((char *));
948 static void do_vfp_xp_ldstmia
PARAMS ((char *));
949 static void do_vfp_xp_ldstmdb
PARAMS ((char *));
950 static void do_vfp_sp_compare_z
PARAMS ((char *));
951 static void do_vfp_dp_compare_z
PARAMS ((char *));
952 static void do_vfp_dp_sp_cvt
PARAMS ((char *));
953 static void do_vfp_sp_dp_cvt
PARAMS ((char *));
956 static void do_xsc_mia
PARAMS ((char *));
957 static void do_xsc_mar
PARAMS ((char *));
958 static void do_xsc_mra
PARAMS ((char *));
961 static void do_mav_binops
PARAMS ((char *, int, enum arm_reg_type
,
963 static void do_mav_binops_1a
PARAMS ((char *));
964 static void do_mav_binops_1b
PARAMS ((char *));
965 static void do_mav_binops_1c
PARAMS ((char *));
966 static void do_mav_binops_1d
PARAMS ((char *));
967 static void do_mav_binops_1e
PARAMS ((char *));
968 static void do_mav_binops_1f
PARAMS ((char *));
969 static void do_mav_binops_1g
PARAMS ((char *));
970 static void do_mav_binops_1h
PARAMS ((char *));
971 static void do_mav_binops_1i
PARAMS ((char *));
972 static void do_mav_binops_1j
PARAMS ((char *));
973 static void do_mav_binops_1k
PARAMS ((char *));
974 static void do_mav_binops_1l
PARAMS ((char *));
975 static void do_mav_binops_1m
PARAMS ((char *));
976 static void do_mav_binops_1n
PARAMS ((char *));
977 static void do_mav_binops_1o
PARAMS ((char *));
978 static void do_mav_binops_2a
PARAMS ((char *));
979 static void do_mav_binops_2b
PARAMS ((char *));
980 static void do_mav_binops_2c
PARAMS ((char *));
981 static void do_mav_binops_3a
PARAMS ((char *));
982 static void do_mav_binops_3b
PARAMS ((char *));
983 static void do_mav_binops_3c
PARAMS ((char *));
984 static void do_mav_binops_3d
PARAMS ((char *));
985 static void do_mav_triple
PARAMS ((char *, int, enum arm_reg_type
,
988 static void do_mav_triple_4a
PARAMS ((char *));
989 static void do_mav_triple_4b
PARAMS ((char *));
990 static void do_mav_triple_5a
PARAMS ((char *));
991 static void do_mav_triple_5b
PARAMS ((char *));
992 static void do_mav_triple_5c
PARAMS ((char *));
993 static void do_mav_triple_5d
PARAMS ((char *));
994 static void do_mav_triple_5e
PARAMS ((char *));
995 static void do_mav_triple_5f
PARAMS ((char *));
996 static void do_mav_triple_5g
PARAMS ((char *));
997 static void do_mav_triple_5h
PARAMS ((char *));
998 static void do_mav_quad
PARAMS ((char *, int, enum arm_reg_type
,
1001 enum arm_reg_type
));
1002 static void do_mav_quad_6a
PARAMS ((char *));
1003 static void do_mav_quad_6b
PARAMS ((char *));
1004 static void do_mav_dspsc_1
PARAMS ((char *));
1005 static void do_mav_dspsc_2
PARAMS ((char *));
1006 static void do_mav_shift
PARAMS ((char *, enum arm_reg_type
,
1007 enum arm_reg_type
));
1008 static void do_mav_shift_1
PARAMS ((char *));
1009 static void do_mav_shift_2
PARAMS ((char *));
1010 static void do_mav_ldst
PARAMS ((char *, enum arm_reg_type
));
1011 static void do_mav_ldst_1
PARAMS ((char *));
1012 static void do_mav_ldst_2
PARAMS ((char *));
1013 static void do_mav_ldst_3
PARAMS ((char *));
1014 static void do_mav_ldst_4
PARAMS ((char *));
1016 static int mav_reg_required_here
PARAMS ((char **, int,
1017 enum arm_reg_type
));
1018 static int mav_parse_offset
PARAMS ((char **, int *));
1020 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*,
1022 static int arm_reg_parse
PARAMS ((char **, struct hash_control
*));
1023 static enum arm_reg_type arm_reg_parse_any
PARAMS ((char *));
1024 static const struct asm_psr
* arm_psr_parse
PARAMS ((char **));
1025 static void symbol_locate
PARAMS ((symbolS
*, const char *, segT
, valueT
,
1027 static int add_to_lit_pool
PARAMS ((void));
1028 static unsigned validate_immediate
PARAMS ((unsigned));
1029 static unsigned validate_immediate_twopart
PARAMS ((unsigned int,
1031 static int validate_offset_imm
PARAMS ((unsigned int, int));
1032 static void opcode_select
PARAMS ((int));
1033 static void end_of_line
PARAMS ((char *));
1034 static int reg_required_here
PARAMS ((char **, int));
1035 static int psr_required_here
PARAMS ((char **));
1036 static int co_proc_number
PARAMS ((char **));
1037 static int cp_opc_expr
PARAMS ((char **, int, int));
1038 static int cp_reg_required_here
PARAMS ((char **, int));
1039 static int fp_reg_required_here
PARAMS ((char **, int));
1040 static int vfp_sp_reg_required_here
PARAMS ((char **, enum vfp_sp_reg_pos
));
1041 static int vfp_dp_reg_required_here
PARAMS ((char **, enum vfp_dp_reg_pos
));
1042 static void vfp_sp_ldstm
PARAMS ((char *, enum vfp_ldstm_type
));
1043 static void vfp_dp_ldstm
PARAMS ((char *, enum vfp_ldstm_type
));
1044 static long vfp_sp_reg_list
PARAMS ((char **, enum vfp_sp_reg_pos
));
1045 static long vfp_dp_reg_list
PARAMS ((char **));
1046 static int vfp_psr_required_here
PARAMS ((char **str
));
1047 static const struct vfp_reg
*vfp_psr_parse
PARAMS ((char **str
));
1048 static int cp_address_offset
PARAMS ((char **));
1049 static int cp_address_required_here
PARAMS ((char **, int));
1050 static int my_get_float_expression
PARAMS ((char **));
1051 static int skip_past_comma
PARAMS ((char **));
1052 static int walk_no_bignums
PARAMS ((symbolS
*));
1053 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
1054 static int data_op2
PARAMS ((char **));
1055 static int fp_op2
PARAMS ((char **));
1056 static long reg_list
PARAMS ((char **));
1057 static void thumb_load_store
PARAMS ((char *, int, int));
1058 static int decode_shift
PARAMS ((char **, int));
1059 static int ldst_extend
PARAMS ((char **));
1060 static int ldst_extend_v4
PARAMS ((char **));
1061 static void thumb_add_sub
PARAMS ((char *, int));
1062 static void insert_reg
PARAMS ((const struct reg_entry
*,
1063 struct hash_control
*));
1064 static void thumb_shift
PARAMS ((char *, int));
1065 static void thumb_mov_compare
PARAMS ((char *, int));
1066 static void build_arm_ops_hsh
PARAMS ((void));
1067 static void set_constant_flonums
PARAMS ((void));
1068 static valueT md_chars_to_number
PARAMS ((char *, int));
1069 static void build_reg_hsh
PARAMS ((struct reg_map
*));
1070 static void insert_reg_alias
PARAMS ((char *, int, struct hash_control
*));
1071 static int create_register_alias
PARAMS ((char *, char *));
1072 static void output_inst
PARAMS ((const char *));
1073 static int accum0_required_here
PARAMS ((char **));
1074 static int ld_mode_required_here
PARAMS ((char **));
1075 static void do_branch25
PARAMS ((char *));
1076 static symbolS
* find_real_start
PARAMS ((symbolS
*));
1078 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
1081 static int wreg_required_here
PARAMS ((char **, int, enum wreg_type
));
1082 static void do_iwmmxt_byte_addr
PARAMS ((char *));
1083 static void do_iwmmxt_tandc
PARAMS ((char *));
1084 static void do_iwmmxt_tbcst
PARAMS ((char *));
1085 static void do_iwmmxt_textrc
PARAMS ((char *));
1086 static void do_iwmmxt_textrm
PARAMS ((char *));
1087 static void do_iwmmxt_tinsr
PARAMS ((char *));
1088 static void do_iwmmxt_tmcr
PARAMS ((char *));
1089 static void do_iwmmxt_tmcrr
PARAMS ((char *));
1090 static void do_iwmmxt_tmia
PARAMS ((char *));
1091 static void do_iwmmxt_tmovmsk
PARAMS ((char *));
1092 static void do_iwmmxt_tmrc
PARAMS ((char *));
1093 static void do_iwmmxt_tmrrc
PARAMS ((char *));
1094 static void do_iwmmxt_torc
PARAMS ((char *));
1095 static void do_iwmmxt_waligni
PARAMS ((char *));
1096 static void do_iwmmxt_wmov
PARAMS ((char *));
1097 static void do_iwmmxt_word_addr
PARAMS ((char *));
1098 static void do_iwmmxt_wrwr
PARAMS ((char *));
1099 static void do_iwmmxt_wrwrwcg
PARAMS ((char *));
1100 static void do_iwmmxt_wrwrwr
PARAMS ((char *));
1101 static void do_iwmmxt_wshufh
PARAMS ((char *));
1102 static void do_iwmmxt_wzero
PARAMS ((char *));
1103 static int cp_byte_address_offset
PARAMS ((char **));
1104 static int cp_byte_address_required_here
PARAMS ((char **));
1106 /* ARM instructions take 4bytes in the object file, Thumb instructions
1110 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
1111 #define MAV_MODE1 0x100c
1113 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
1114 #define MAV_MODE2 0x0c10
1116 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
1117 #define MAV_MODE3 0x100c
1119 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
1120 #define MAV_MODE4 0x0c0010
1122 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
1123 #define MAV_MODE5 0x00100c
1125 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
1126 #define MAV_MODE6 0x00100c05
1130 /* Basic string to match. */
1131 const char * template;
1133 /* Basic instruction code. */
1134 unsigned long value
;
1136 /* Offset into the template where the condition code (if any) will be.
1137 If zero, then the instruction is never conditional. */
1138 unsigned cond_offset
;
1140 /* Which architecture variant provides this instruction. */
1141 unsigned long variant
;
1143 /* Function to call to parse args. */
1144 void (* parms
) PARAMS ((char *));
1147 static const struct asm_opcode insns
[] =
1149 /* Core ARM Instructions. */
1150 {"and", 0xe0000000, 3, ARM_EXT_V1
, do_arit
},
1151 {"ands", 0xe0100000, 3, ARM_EXT_V1
, do_arit
},
1152 {"eor", 0xe0200000, 3, ARM_EXT_V1
, do_arit
},
1153 {"eors", 0xe0300000, 3, ARM_EXT_V1
, do_arit
},
1154 {"sub", 0xe0400000, 3, ARM_EXT_V1
, do_arit
},
1155 {"subs", 0xe0500000, 3, ARM_EXT_V1
, do_arit
},
1156 {"rsb", 0xe0600000, 3, ARM_EXT_V1
, do_arit
},
1157 {"rsbs", 0xe0700000, 3, ARM_EXT_V1
, do_arit
},
1158 {"add", 0xe0800000, 3, ARM_EXT_V1
, do_arit
},
1159 {"adds", 0xe0900000, 3, ARM_EXT_V1
, do_arit
},
1160 {"adc", 0xe0a00000, 3, ARM_EXT_V1
, do_arit
},
1161 {"adcs", 0xe0b00000, 3, ARM_EXT_V1
, do_arit
},
1162 {"sbc", 0xe0c00000, 3, ARM_EXT_V1
, do_arit
},
1163 {"sbcs", 0xe0d00000, 3, ARM_EXT_V1
, do_arit
},
1164 {"rsc", 0xe0e00000, 3, ARM_EXT_V1
, do_arit
},
1165 {"rscs", 0xe0f00000, 3, ARM_EXT_V1
, do_arit
},
1166 {"orr", 0xe1800000, 3, ARM_EXT_V1
, do_arit
},
1167 {"orrs", 0xe1900000, 3, ARM_EXT_V1
, do_arit
},
1168 {"bic", 0xe1c00000, 3, ARM_EXT_V1
, do_arit
},
1169 {"bics", 0xe1d00000, 3, ARM_EXT_V1
, do_arit
},
1171 {"tst", 0xe1100000, 3, ARM_EXT_V1
, do_cmp
},
1172 {"tsts", 0xe1100000, 3, ARM_EXT_V1
, do_cmp
},
1173 {"tstp", 0xe110f000, 3, ARM_EXT_V1
, do_cmp
},
1174 {"teq", 0xe1300000, 3, ARM_EXT_V1
, do_cmp
},
1175 {"teqs", 0xe1300000, 3, ARM_EXT_V1
, do_cmp
},
1176 {"teqp", 0xe130f000, 3, ARM_EXT_V1
, do_cmp
},
1177 {"cmp", 0xe1500000, 3, ARM_EXT_V1
, do_cmp
},
1178 {"cmps", 0xe1500000, 3, ARM_EXT_V1
, do_cmp
},
1179 {"cmpp", 0xe150f000, 3, ARM_EXT_V1
, do_cmp
},
1180 {"cmn", 0xe1700000, 3, ARM_EXT_V1
, do_cmp
},
1181 {"cmns", 0xe1700000, 3, ARM_EXT_V1
, do_cmp
},
1182 {"cmnp", 0xe170f000, 3, ARM_EXT_V1
, do_cmp
},
1184 {"mov", 0xe1a00000, 3, ARM_EXT_V1
, do_mov
},
1185 {"movs", 0xe1b00000, 3, ARM_EXT_V1
, do_mov
},
1186 {"mvn", 0xe1e00000, 3, ARM_EXT_V1
, do_mov
},
1187 {"mvns", 0xe1f00000, 3, ARM_EXT_V1
, do_mov
},
1189 {"ldr", 0xe4100000, 3, ARM_EXT_V1
, do_ldst
},
1190 {"ldrb", 0xe4500000, 3, ARM_EXT_V1
, do_ldst
},
1191 {"ldrt", 0xe4300000, 3, ARM_EXT_V1
, do_ldstt
},
1192 {"ldrbt", 0xe4700000, 3, ARM_EXT_V1
, do_ldstt
},
1193 {"str", 0xe4000000, 3, ARM_EXT_V1
, do_ldst
},
1194 {"strb", 0xe4400000, 3, ARM_EXT_V1
, do_ldst
},
1195 {"strt", 0xe4200000, 3, ARM_EXT_V1
, do_ldstt
},
1196 {"strbt", 0xe4600000, 3, ARM_EXT_V1
, do_ldstt
},
1198 {"stmia", 0xe8800000, 3, ARM_EXT_V1
, do_ldmstm
},
1199 {"stmib", 0xe9800000, 3, ARM_EXT_V1
, do_ldmstm
},
1200 {"stmda", 0xe8000000, 3, ARM_EXT_V1
, do_ldmstm
},
1201 {"stmdb", 0xe9000000, 3, ARM_EXT_V1
, do_ldmstm
},
1202 {"stmfd", 0xe9000000, 3, ARM_EXT_V1
, do_ldmstm
},
1203 {"stmfa", 0xe9800000, 3, ARM_EXT_V1
, do_ldmstm
},
1204 {"stmea", 0xe8800000, 3, ARM_EXT_V1
, do_ldmstm
},
1205 {"stmed", 0xe8000000, 3, ARM_EXT_V1
, do_ldmstm
},
1207 {"ldmia", 0xe8900000, 3, ARM_EXT_V1
, do_ldmstm
},
1208 {"ldmib", 0xe9900000, 3, ARM_EXT_V1
, do_ldmstm
},
1209 {"ldmda", 0xe8100000, 3, ARM_EXT_V1
, do_ldmstm
},
1210 {"ldmdb", 0xe9100000, 3, ARM_EXT_V1
, do_ldmstm
},
1211 {"ldmfd", 0xe8900000, 3, ARM_EXT_V1
, do_ldmstm
},
1212 {"ldmfa", 0xe8100000, 3, ARM_EXT_V1
, do_ldmstm
},
1213 {"ldmea", 0xe9100000, 3, ARM_EXT_V1
, do_ldmstm
},
1214 {"ldmed", 0xe9900000, 3, ARM_EXT_V1
, do_ldmstm
},
1216 {"swi", 0xef000000, 3, ARM_EXT_V1
, do_swi
},
1218 /* XXX This is the wrong place to do this. Think multi-arch. */
1219 {"bl", 0xeb000000, 2, ARM_EXT_V1
, do_branch
},
1220 {"b", 0xea000000, 1, ARM_EXT_V1
, do_branch
},
1222 {"bl", 0xebfffffe, 2, ARM_EXT_V1
, do_branch
},
1223 {"b", 0xeafffffe, 1, ARM_EXT_V1
, do_branch
},
1227 {"adr", 0xe28f0000, 3, ARM_EXT_V1
, do_adr
},
1228 {"adrl", 0xe28f0000, 3, ARM_EXT_V1
, do_adrl
},
1229 {"nop", 0xe1a00000, 3, ARM_EXT_V1
, do_empty
},
1231 /* ARM 2 multiplies. */
1232 {"mul", 0xe0000090, 3, ARM_EXT_V2
, do_mul
},
1233 {"muls", 0xe0100090, 3, ARM_EXT_V2
, do_mul
},
1234 {"mla", 0xe0200090, 3, ARM_EXT_V2
, do_mla
},
1235 {"mlas", 0xe0300090, 3, ARM_EXT_V2
, do_mla
},
1237 /* Generic coprocessor instructions. */
1238 {"cdp", 0xee000000, 3, ARM_EXT_V2
, do_cdp
},
1239 {"ldc", 0xec100000, 3, ARM_EXT_V2
, do_lstc
},
1240 {"ldcl", 0xec500000, 3, ARM_EXT_V2
, do_lstc
},
1241 {"stc", 0xec000000, 3, ARM_EXT_V2
, do_lstc
},
1242 {"stcl", 0xec400000, 3, ARM_EXT_V2
, do_lstc
},
1243 {"mcr", 0xee000010, 3, ARM_EXT_V2
, do_co_reg
},
1244 {"mrc", 0xee100010, 3, ARM_EXT_V2
, do_co_reg
},
1246 /* ARM 3 - swp instructions. */
1247 {"swp", 0xe1000090, 3, ARM_EXT_V2S
, do_swap
},
1248 {"swpb", 0xe1400090, 3, ARM_EXT_V2S
, do_swap
},
1250 /* ARM 6 Status register instructions. */
1251 {"mrs", 0xe10f0000, 3, ARM_EXT_V3
, do_mrs
},
1252 {"msr", 0xe120f000, 3, ARM_EXT_V3
, do_msr
},
1253 /* ScottB: our code uses 0xe128f000 for msr.
1254 NickC: but this is wrong because the bits 16 through 19 are
1255 handled by the PSR_xxx defines above. */
1257 /* ARM 7M long multiplies. */
1258 {"smull", 0xe0c00090, 5, ARM_EXT_V3M
, do_mull
},
1259 {"smulls", 0xe0d00090, 5, ARM_EXT_V3M
, do_mull
},
1260 {"umull", 0xe0800090, 5, ARM_EXT_V3M
, do_mull
},
1261 {"umulls", 0xe0900090, 5, ARM_EXT_V3M
, do_mull
},
1262 {"smlal", 0xe0e00090, 5, ARM_EXT_V3M
, do_mull
},
1263 {"smlals", 0xe0f00090, 5, ARM_EXT_V3M
, do_mull
},
1264 {"umlal", 0xe0a00090, 5, ARM_EXT_V3M
, do_mull
},
1265 {"umlals", 0xe0b00090, 5, ARM_EXT_V3M
, do_mull
},
1267 /* ARM Architecture 4. */
1268 {"ldrh", 0xe01000b0, 3, ARM_EXT_V4
, do_ldstv4
},
1269 {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4
, do_ldstv4
},
1270 {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4
, do_ldstv4
},
1271 {"strh", 0xe00000b0, 3, ARM_EXT_V4
, do_ldstv4
},
1273 /* ARM Architecture 4T. */
1274 /* Note: bx (and blx) are required on V5, even if the processor does
1275 not support Thumb. */
1276 {"bx", 0xe12fff10, 2, ARM_EXT_V4T
| ARM_EXT_V5
, do_bx
},
1278 /* ARM Architecture 5T. */
1279 /* Note: blx has 2 variants, so the .value is set dynamically.
1280 Only one of the variants has conditional execution. */
1281 {"blx", 0xe0000000, 3, ARM_EXT_V5
, do_blx
},
1282 {"clz", 0xe16f0f10, 3, ARM_EXT_V5
, do_clz
},
1283 {"bkpt", 0xe1200070, 0, ARM_EXT_V5
, do_bkpt
},
1284 {"ldc2", 0xfc100000, 0, ARM_EXT_V5
, do_lstc2
},
1285 {"ldc2l", 0xfc500000, 0, ARM_EXT_V5
, do_lstc2
},
1286 {"stc2", 0xfc000000, 0, ARM_EXT_V5
, do_lstc2
},
1287 {"stc2l", 0xfc400000, 0, ARM_EXT_V5
, do_lstc2
},
1288 {"cdp2", 0xfe000000, 0, ARM_EXT_V5
, do_cdp2
},
1289 {"mcr2", 0xfe000010, 0, ARM_EXT_V5
, do_co_reg2
},
1290 {"mrc2", 0xfe100010, 0, ARM_EXT_V5
, do_co_reg2
},
1292 /* ARM Architecture 5TExP. */
1293 {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP
, do_smla
},
1294 {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP
, do_smla
},
1295 {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP
, do_smla
},
1296 {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP
, do_smla
},
1298 {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP
, do_smla
},
1299 {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP
, do_smla
},
1301 {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP
, do_smlal
},
1302 {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP
, do_smlal
},
1303 {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP
, do_smlal
},
1304 {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP
, do_smlal
},
1306 {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP
, do_smul
},
1307 {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP
, do_smul
},
1308 {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP
, do_smul
},
1309 {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP
, do_smul
},
1311 {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP
, do_smul
},
1312 {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP
, do_smul
},
1314 {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP
, do_qadd
},
1315 {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP
, do_qadd
},
1316 {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP
, do_qadd
},
1317 {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP
, do_qadd
},
1319 /* ARM Architecture 5TE. */
1320 {"pld", 0xf450f000, 0, ARM_EXT_V5E
, do_pld
},
1321 {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E
, do_ldrd
},
1322 {"strd", 0xe00000f0, 3, ARM_EXT_V5E
, do_ldrd
},
1324 {"mcrr", 0xec400000, 4, ARM_EXT_V5E
, do_co_reg2c
},
1325 {"mrrc", 0xec500000, 4, ARM_EXT_V5E
, do_co_reg2c
},
1327 /* ARM Architecture 5TEJ. */
1328 {"bxj", 0xe12fff20, 3, ARM_EXT_V5J
, do_bxj
},
1331 { "cps", 0xf1020000, 0, ARM_EXT_V6
, do_cps
},
1332 { "cpsie", 0xf1080000, 0, ARM_EXT_V6
, do_cpsi
},
1333 { "cpsid", 0xf10C0000, 0, ARM_EXT_V6
, do_cpsi
},
1334 { "ldrex", 0xe1900f9f, 5, ARM_EXT_V6
, do_ldrex
},
1335 { "mcrr2", 0xfc400000, 0, ARM_EXT_V6
, do_co_reg2c
},
1336 { "mrrc2", 0xfc500000, 0, ARM_EXT_V6
, do_co_reg2c
},
1337 { "pkhbt", 0xe6800010, 5, ARM_EXT_V6
, do_pkhbt
},
1338 { "pkhtb", 0xe6800050, 5, ARM_EXT_V6
, do_pkhtb
},
1339 { "qadd16", 0xe6200f10, 6, ARM_EXT_V6
, do_qadd16
},
1340 { "qadd8", 0xe6200f90, 5, ARM_EXT_V6
, do_qadd16
},
1341 { "qaddsubx", 0xe6200f30, 8, ARM_EXT_V6
, do_qadd16
},
1342 { "qsub16", 0xe6200f70, 6, ARM_EXT_V6
, do_qadd16
},
1343 { "qsub8", 0xe6200ff0, 5, ARM_EXT_V6
, do_qadd16
},
1344 { "qsubaddx", 0xe6200f50, 8, ARM_EXT_V6
, do_qadd16
},
1345 { "sadd16", 0xe6100f10, 6, ARM_EXT_V6
, do_qadd16
},
1346 { "sadd8", 0xe6100f90, 5, ARM_EXT_V6
, do_qadd16
},
1347 { "saddsubx", 0xe6100f30, 8, ARM_EXT_V6
, do_qadd16
},
1348 { "shadd16", 0xe6300f10, 7, ARM_EXT_V6
, do_qadd16
},
1349 { "shadd8", 0xe6300f90, 6, ARM_EXT_V6
, do_qadd16
},
1350 { "shaddsubx", 0xe6300f30, 9, ARM_EXT_V6
, do_qadd16
},
1351 { "shsub16", 0xe6300f70, 7, ARM_EXT_V6
, do_qadd16
},
1352 { "shsub8", 0xe6300ff0, 6, ARM_EXT_V6
, do_qadd16
},
1353 { "shsubaddx", 0xe6300f50, 9, ARM_EXT_V6
, do_qadd16
},
1354 { "ssub16", 0xe6100f70, 6, ARM_EXT_V6
, do_qadd16
},
1355 { "ssub8", 0xe6100ff0, 5, ARM_EXT_V6
, do_qadd16
},
1356 { "ssubaddx", 0xe6100f50, 8, ARM_EXT_V6
, do_qadd16
},
1357 { "uadd16", 0xe6500f10, 6, ARM_EXT_V6
, do_qadd16
},
1358 { "uadd8", 0xe6500f90, 5, ARM_EXT_V6
, do_qadd16
},
1359 { "uaddsubx", 0xe6500f30, 8, ARM_EXT_V6
, do_qadd16
},
1360 { "uhadd16", 0xe6700f10, 7, ARM_EXT_V6
, do_qadd16
},
1361 { "uhadd8", 0xe6700f90, 6, ARM_EXT_V6
, do_qadd16
},
1362 { "uhaddsubx", 0xe6700f30, 9, ARM_EXT_V6
, do_qadd16
},
1363 { "uhsub16", 0xe6700f70, 7, ARM_EXT_V6
, do_qadd16
},
1364 { "uhsub8", 0xe6700ff0, 6, ARM_EXT_V6
, do_qadd16
},
1365 { "uhsubaddx", 0xe6700f50, 9, ARM_EXT_V6
, do_qadd16
},
1366 { "uqadd16", 0xe6600f10, 7, ARM_EXT_V6
, do_qadd16
},
1367 { "uqadd8", 0xe6600f90, 6, ARM_EXT_V6
, do_qadd16
},
1368 { "uqaddsubx", 0xe6600f30, 9, ARM_EXT_V6
, do_qadd16
},
1369 { "uqsub16", 0xe6600f70, 7, ARM_EXT_V6
, do_qadd16
},
1370 { "uqsub8", 0xe6600ff0, 6, ARM_EXT_V6
, do_qadd16
},
1371 { "uqsubaddx", 0xe6600f50, 9, ARM_EXT_V6
, do_qadd16
},
1372 { "usub16", 0xe6500f70, 6, ARM_EXT_V6
, do_qadd16
},
1373 { "usub8", 0xe6500ff0, 5, ARM_EXT_V6
, do_qadd16
},
1374 { "usubaddx", 0xe6500f50, 8, ARM_EXT_V6
, do_qadd16
},
1375 { "rev", 0xe6bf0f30, 3, ARM_EXT_V6
, do_rev
},
1376 { "rev16", 0xe6bf0fb0, 5, ARM_EXT_V6
, do_rev
},
1377 { "revsh", 0xe6ff0fb0, 5, ARM_EXT_V6
, do_rev
},
1378 { "rfeia", 0xf8900a00, 0, ARM_EXT_V6
, do_rfe
},
1379 { "rfeib", 0xf9900a00, 0, ARM_EXT_V6
, do_rfe
},
1380 { "rfeda", 0xf8100a00, 0, ARM_EXT_V6
, do_rfe
},
1381 { "rfedb", 0xf9100a00, 0, ARM_EXT_V6
, do_rfe
},
1382 { "rfefd", 0xf8900a00, 0, ARM_EXT_V6
, do_rfe
},
1383 { "rfefa", 0xf9900a00, 0, ARM_EXT_V6
, do_rfe
},
1384 { "rfeea", 0xf8100a00, 0, ARM_EXT_V6
, do_rfe
},
1385 { "rfeed", 0xf9100a00, 0, ARM_EXT_V6
, do_rfe
},
1386 { "sxtah", 0xe6b00070, 5, ARM_EXT_V6
, do_sxtah
},
1387 { "sxtab16", 0xe6800070, 7, ARM_EXT_V6
, do_sxtah
},
1388 { "sxtab", 0xe6a00070, 5, ARM_EXT_V6
, do_sxtah
},
1389 { "sxth", 0xe6bf0070, 4, ARM_EXT_V6
, do_sxth
},
1390 { "sxtb16", 0xe68f0070, 6, ARM_EXT_V6
, do_sxth
},
1391 { "sxtb", 0xe6af0070, 4, ARM_EXT_V6
, do_sxth
},
1392 { "uxtah", 0xe6f00070, 5, ARM_EXT_V6
, do_sxtah
},
1393 { "uxtab16", 0xe6c00070, 7, ARM_EXT_V6
, do_sxtah
},
1394 { "uxtab", 0xe6e00070, 5, ARM_EXT_V6
, do_sxtah
},
1395 { "uxth", 0xe6ff0070, 4, ARM_EXT_V6
, do_sxth
},
1396 { "uxtb16", 0xe6cf0070, 6, ARM_EXT_V6
, do_sxth
},
1397 { "uxtb", 0xe6ef0070, 4, ARM_EXT_V6
, do_sxth
},
1398 { "sel", 0xe68000b0, 3, ARM_EXT_V6
, do_qadd16
},
1399 { "setend", 0xf1010000, 0, ARM_EXT_V6
, do_setend
},
1400 { "smlad", 0xe7000010, 5, ARM_EXT_V6
, do_smlad
},
1401 { "smladx", 0xe7000030, 6, ARM_EXT_V6
, do_smlad
},
1402 { "smlald", 0xe7400010, 6, ARM_EXT_V6
, do_smlald
},
1403 { "smlaldx", 0xe7400030, 7, ARM_EXT_V6
, do_smlald
},
1404 { "smlsd", 0xe7000050, 5, ARM_EXT_V6
, do_smlad
},
1405 { "smlsdx", 0xe7000070, 6, ARM_EXT_V6
, do_smlad
},
1406 { "smlsld", 0xe7400050, 6, ARM_EXT_V6
, do_smlald
},
1407 { "smlsldx", 0xe7400070, 7, ARM_EXT_V6
, do_smlald
},
1408 { "smmla", 0xe7500010, 5, ARM_EXT_V6
, do_smlad
},
1409 { "smmlar", 0xe7500030, 6, ARM_EXT_V6
, do_smlad
},
1410 { "smmls", 0xe75000d0, 5, ARM_EXT_V6
, do_smlad
},
1411 { "smmlsr", 0xe75000f0, 6, ARM_EXT_V6
, do_smlad
},
1412 { "smmul", 0xe750f010, 5, ARM_EXT_V6
, do_smmul
},
1413 { "smmulr", 0xe750f030, 6, ARM_EXT_V6
, do_smmul
},
1414 { "smuad", 0xe700f010, 5, ARM_EXT_V6
, do_smmul
},
1415 { "smuadx", 0xe700f030, 6, ARM_EXT_V6
, do_smmul
},
1416 { "smusd", 0xe700f050, 5, ARM_EXT_V6
, do_smmul
},
1417 { "smusdx", 0xe700f070, 6, ARM_EXT_V6
, do_smmul
},
1418 { "srsia", 0xf8cd0500, 0, ARM_EXT_V6
, do_srs
},
1419 { "srsib", 0xf9cd0500, 0, ARM_EXT_V6
, do_srs
},
1420 { "srsda", 0xf84d0500, 0, ARM_EXT_V6
, do_srs
},
1421 { "srsdb", 0xf94d0500, 0, ARM_EXT_V6
, do_srs
},
1422 { "ssat", 0xe6a00010, 4, ARM_EXT_V6
, do_ssat
},
1423 { "ssat16", 0xe6a00f30, 6, ARM_EXT_V6
, do_ssat16
},
1424 { "strex", 0xe1800f90, 5, ARM_EXT_V6
, do_strex
},
1425 { "umaal", 0xe0400090, 5, ARM_EXT_V6
, do_umaal
},
1426 { "usad8", 0xe780f010, 5, ARM_EXT_V6
, do_smmul
},
1427 { "usada8", 0xe7800010, 6, ARM_EXT_V6
, do_smlad
},
1428 { "usat", 0xe6e00010, 4, ARM_EXT_V6
, do_usat
},
1429 { "usat16", 0xe6e00f30, 6, ARM_EXT_V6
, do_usat16
},
1431 /* Core FPA instruction set (V1). */
1432 {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1433 {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1434 {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1435 {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1437 {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1438 {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1439 {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1440 {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1442 {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1443 {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1444 {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1445 {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1447 {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1448 {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1449 {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1450 {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1451 {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1452 {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1453 {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1454 {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1455 {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1456 {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1457 {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1458 {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1460 {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1461 {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1462 {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1463 {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1464 {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1465 {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1466 {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1467 {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1468 {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1469 {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1470 {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1471 {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1473 {"abss", 0xee208100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1474 {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1475 {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1476 {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1477 {"absd", 0xee208180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1478 {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1479 {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1480 {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1481 {"abse", 0xee288100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1482 {"absep", 0xee288120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1483 {"absem", 0xee288140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1484 {"absez", 0xee288160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1486 {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1487 {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1488 {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1489 {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1490 {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1491 {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1492 {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1493 {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1494 {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1495 {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1496 {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1497 {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1499 {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1500 {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1501 {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1502 {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1503 {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1504 {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1505 {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1506 {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1507 {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1508 {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1509 {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1510 {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1512 {"logs", 0xee508100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1513 {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1514 {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1515 {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1516 {"logd", 0xee508180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1517 {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1518 {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1519 {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1520 {"loge", 0xee588100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1521 {"logep", 0xee588120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1522 {"logem", 0xee588140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1523 {"logez", 0xee588160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1525 {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1526 {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1527 {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1528 {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1529 {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1530 {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1531 {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1532 {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1533 {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1534 {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1535 {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1536 {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1538 {"exps", 0xee708100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1539 {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1540 {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1541 {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1542 {"expd", 0xee708180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1543 {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1544 {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1545 {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1546 {"expe", 0xee788100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1547 {"expep", 0xee788120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1548 {"expem", 0xee788140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1549 {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1551 {"sins", 0xee808100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1552 {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1553 {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1554 {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1555 {"sind", 0xee808180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1556 {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1557 {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1558 {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1559 {"sine", 0xee888100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1560 {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1561 {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1562 {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1564 {"coss", 0xee908100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1565 {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1566 {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1567 {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1568 {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1569 {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1570 {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1571 {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1572 {"cose", 0xee988100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1573 {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1574 {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1575 {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1577 {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1578 {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1579 {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1580 {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1581 {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1582 {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1583 {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1584 {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1585 {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1586 {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1587 {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1588 {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1590 {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1591 {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1592 {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1593 {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1594 {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1595 {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1596 {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1597 {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1598 {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1599 {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1600 {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1601 {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1603 {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1604 {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1605 {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1606 {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1607 {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1608 {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1609 {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1610 {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1611 {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1612 {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1613 {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1614 {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1616 {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1617 {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1618 {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1619 {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1620 {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1621 {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1622 {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1623 {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1624 {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1625 {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1626 {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1627 {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1629 {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1630 {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1631 {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1632 {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1633 {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1634 {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1635 {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1636 {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1637 {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1638 {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1639 {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1640 {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1642 {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1643 {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1644 {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1645 {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1646 {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1647 {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1648 {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1649 {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1650 {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1651 {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1652 {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1653 {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1655 {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1656 {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1657 {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1658 {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1659 {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1660 {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1661 {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1662 {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1663 {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1664 {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1665 {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1666 {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1668 {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1669 {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1670 {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1671 {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1672 {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1673 {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1674 {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1675 {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1676 {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1677 {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1678 {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1679 {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1681 {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1682 {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1683 {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1684 {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1685 {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1686 {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1687 {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1688 {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1689 {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1690 {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1691 {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1692 {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1694 {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1695 {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1696 {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1697 {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1698 {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1699 {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1700 {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1701 {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1702 {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1703 {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1704 {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1705 {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1707 {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1708 {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1709 {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1710 {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1711 {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1712 {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1713 {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1714 {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1715 {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1716 {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1717 {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1718 {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1720 {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1721 {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1722 {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1723 {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1724 {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1725 {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1726 {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1727 {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1728 {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1729 {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1730 {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1731 {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1733 {"pows", 0xee600100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1734 {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1735 {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1736 {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1737 {"powd", 0xee600180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1738 {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1739 {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1740 {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1741 {"powe", 0xee680100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1742 {"powep", 0xee680120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1743 {"powem", 0xee680140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1744 {"powez", 0xee680160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1746 {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1747 {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1748 {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1749 {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1750 {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1751 {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1752 {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1753 {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1754 {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1755 {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1756 {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1757 {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1759 {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1760 {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1761 {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1762 {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1763 {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1764 {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1765 {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1766 {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1767 {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1768 {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1769 {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1770 {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1772 {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1773 {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1774 {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1775 {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1776 {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1777 {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1778 {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1779 {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1780 {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1781 {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1782 {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1783 {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1785 {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1786 {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1787 {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1788 {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1789 {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1790 {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1791 {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1792 {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1793 {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1794 {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1795 {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1796 {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1798 {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1799 {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1800 {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1801 {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1802 {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1803 {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1804 {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1805 {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1806 {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1807 {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1808 {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1809 {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1811 {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1812 {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1813 {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1814 {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1815 {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1816 {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1817 {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1818 {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1819 {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1820 {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1821 {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1822 {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1824 {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1825 {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1826 {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1827 {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1828 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1829 not be an optional suffix, but part of the instruction. To be
1830 compatible, we accept either. */
1831 {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1832 {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1834 {"flts", 0xee000110, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1835 {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1836 {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1837 {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1838 {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1839 {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1840 {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1841 {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1842 {"flte", 0xee080110, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1843 {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1844 {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1845 {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1847 /* The implementation of the FIX instruction is broken on some
1848 assemblers, in that it accepts a precision specifier as well as a
1849 rounding specifier, despite the fact that this is meaningless.
1850 To be more compatible, we accept it as well, though of course it
1851 does not set any bits. */
1852 {"fix", 0xee100110, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1853 {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1854 {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1855 {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1856 {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1857 {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1858 {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1859 {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1860 {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1861 {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1862 {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1863 {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1864 {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1866 /* Instructions that were new with the real FPA, call them V2. */
1867 {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1868 {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1869 {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1870 {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1871 {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1872 {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1874 /* VFP V1xD (single precision). */
1875 /* Moves and type conversions. */
1876 {"fcpys", 0xeeb00a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1877 {"fmrs", 0xee100a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_reg_from_sp
},
1878 {"fmsr", 0xee000a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_sp_from_reg
},
1879 {"fmstat", 0xeef1fa10, 6, FPU_VFP_EXT_V1xD
, do_empty
},
1880 {"fsitos", 0xeeb80ac0, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1881 {"fuitos", 0xeeb80a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1882 {"ftosis", 0xeebd0a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1883 {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1884 {"ftouis", 0xeebc0a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1885 {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1886 {"fmrx", 0xeef00a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_reg_from_ctrl
},
1887 {"fmxr", 0xeee00a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_ctrl_from_reg
},
1889 /* Memory operations. */
1890 {"flds", 0xed100a00, 4, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldst
},
1891 {"fsts", 0xed000a00, 4, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldst
},
1892 {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1893 {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1894 {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1895 {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1896 {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1897 {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1898 {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1899 {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1900 {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1901 {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1902 {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1903 {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1904 {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1905 {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1906 {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1907 {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1909 /* Monadic operations. */
1910 {"fabss", 0xeeb00ac0, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1911 {"fnegs", 0xeeb10a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1912 {"fsqrts", 0xeeb10ac0, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1914 /* Dyadic operations. */
1915 {"fadds", 0xee300a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1916 {"fsubs", 0xee300a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1917 {"fmuls", 0xee200a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1918 {"fdivs", 0xee800a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1919 {"fmacs", 0xee000a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1920 {"fmscs", 0xee100a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1921 {"fnmuls", 0xee200a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1922 {"fnmacs", 0xee000a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1923 {"fnmscs", 0xee100a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1926 {"fcmps", 0xeeb40a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1927 {"fcmpzs", 0xeeb50a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_compare_z
},
1928 {"fcmpes", 0xeeb40ac0, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1929 {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_compare_z
},
1931 /* VFP V1 (Double precision). */
1932 /* Moves and type conversions. */
1933 {"fcpyd", 0xeeb00b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1934 {"fcvtds", 0xeeb70ac0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_sp_cvt
},
1935 {"fcvtsd", 0xeeb70bc0, 6, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1936 {"fmdhr", 0xee200b10, 5, FPU_VFP_EXT_V1
, do_vfp_dp_from_reg
},
1937 {"fmdlr", 0xee000b10, 5, FPU_VFP_EXT_V1
, do_vfp_dp_from_reg
},
1938 {"fmrdh", 0xee300b10, 5, FPU_VFP_EXT_V1
, do_vfp_reg_from_dp
},
1939 {"fmrdl", 0xee100b10, 5, FPU_VFP_EXT_V1
, do_vfp_reg_from_dp
},
1940 {"fsitod", 0xeeb80bc0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_sp_cvt
},
1941 {"fuitod", 0xeeb80b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_sp_cvt
},
1942 {"ftosid", 0xeebd0b40, 6, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1943 {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1944 {"ftouid", 0xeebc0b40, 6, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1945 {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1947 /* Memory operations. */
1948 {"fldd", 0xed100b00, 4, FPU_VFP_EXT_V1
, do_vfp_dp_ldst
},
1949 {"fstd", 0xed000b00, 4, FPU_VFP_EXT_V1
, do_vfp_dp_ldst
},
1950 {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1951 {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1952 {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1953 {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1954 {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1955 {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1956 {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1957 {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1959 /* Monadic operations. */
1960 {"fabsd", 0xeeb00bc0, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1961 {"fnegd", 0xeeb10b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1962 {"fsqrtd", 0xeeb10bc0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1964 /* Dyadic operations. */
1965 {"faddd", 0xee300b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1966 {"fsubd", 0xee300b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1967 {"fmuld", 0xee200b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1968 {"fdivd", 0xee800b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1969 {"fmacd", 0xee000b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1970 {"fmscd", 0xee100b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1971 {"fnmuld", 0xee200b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1972 {"fnmacd", 0xee000b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1973 {"fnmscd", 0xee100b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1976 {"fcmpd", 0xeeb40b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1977 {"fcmpzd", 0xeeb50b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_compare_z
},
1978 {"fcmped", 0xeeb40bc0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1979 {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1
, do_vfp_dp_compare_z
},
1982 {"fmsrr", 0xec400a10, 5, FPU_VFP_EXT_V2
, do_vfp_sp2_from_reg2
},
1983 {"fmrrs", 0xec500a10, 5, FPU_VFP_EXT_V2
, do_vfp_reg2_from_sp2
},
1984 {"fmdrr", 0xec400b10, 5, FPU_VFP_EXT_V2
, do_vfp_dp_from_reg2
},
1985 {"fmrrd", 0xec500b10, 5, FPU_VFP_EXT_V2
, do_vfp_reg2_from_dp
},
1987 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
1988 {"mia", 0xee200010, 3, ARM_CEXT_XSCALE
, do_xsc_mia
},
1989 {"miaph", 0xee280010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1990 {"miabb", 0xee2c0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1991 {"miabt", 0xee2d0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1992 {"miatb", 0xee2e0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1993 {"miatt", 0xee2f0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1994 {"mar", 0xec400000, 3, ARM_CEXT_XSCALE
, do_xsc_mar
},
1995 {"mra", 0xec500000, 3, ARM_CEXT_XSCALE
, do_xsc_mra
},
1997 /* Intel Wireless MMX technology instructions. */
1998 {"tandcb", 0xee130130, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tandc
},
1999 {"tandch", 0xee530130, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tandc
},
2000 {"tandcw", 0xee930130, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tandc
},
2001 {"tbcstb", 0xee400010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tbcst
},
2002 {"tbcsth", 0xee400050, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tbcst
},
2003 {"tbcstw", 0xee400090, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tbcst
},
2004 {"textrcb", 0xee130170, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_textrc
},
2005 {"textrch", 0xee530170, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_textrc
},
2006 {"textrcw", 0xee930170, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_textrc
},
2007 {"textrmub", 0xee100070, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2008 {"textrmuh", 0xee500070, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2009 {"textrmuw", 0xee900070, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2010 {"textrmsb", 0xee100078, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2011 {"textrmsh", 0xee500078, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2012 {"textrmsw", 0xee900078, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_textrm
},
2013 {"tinsrb", 0xee600010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tinsr
},
2014 {"tinsrh", 0xee600050, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tinsr
},
2015 {"tinsrw", 0xee600090, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tinsr
},
2016 {"tmcr", 0xee000110, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_tmcr
},
2017 {"tmcrr", 0xec400000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_tmcrr
},
2018 {"tmia", 0xee200010, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2019 {"tmiaph", 0xee280010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2020 {"tmiabb", 0xee2c0010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2021 {"tmiabt", 0xee2d0010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2022 {"tmiatb", 0xee2e0010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2023 {"tmiatt", 0xee2f0010, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_tmia
},
2024 {"tmovmskb", 0xee100030, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_tmovmsk
},
2025 {"tmovmskh", 0xee500030, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_tmovmsk
},
2026 {"tmovmskw", 0xee900030, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_tmovmsk
},
2027 {"tmrc", 0xee100110, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_tmrc
},
2028 {"tmrrc", 0xec500000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_tmrrc
},
2029 {"torcb", 0xee130150, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_torc
},
2030 {"torch", 0xee530150, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_torc
},
2031 {"torcw", 0xee930150, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_torc
},
2032 {"waccb", 0xee0001c0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2033 {"wacch", 0xee4001c0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2034 {"waccw", 0xee8001c0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2035 {"waddbss", 0xee300180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2036 {"waddb", 0xee000180, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2037 {"waddbus", 0xee100180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2038 {"waddhss", 0xee700180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2039 {"waddh", 0xee400180, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2040 {"waddhus", 0xee500180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2041 {"waddwss", 0xeeb00180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2042 {"waddw", 0xee800180, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2043 {"waddwus", 0xee900180, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2044 {"waligni", 0xee000020, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_waligni
},
2045 {"walignr0", 0xee800020, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2046 {"walignr1", 0xee900020, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2047 {"walignr2", 0xeea00020, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2048 {"walignr3", 0xeeb00020, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2049 {"wand", 0xee200000, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2050 {"wandn", 0xee300000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2051 {"wavg2b", 0xee800000, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2052 {"wavg2br", 0xee900000, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2053 {"wavg2h", 0xeec00000, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2054 {"wavg2hr", 0xeed00000, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2055 {"wcmpeqb", 0xee000060, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2056 {"wcmpeqh", 0xee400060, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2057 {"wcmpeqw", 0xee800060, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2058 {"wcmpgtub", 0xee100060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2059 {"wcmpgtuh", 0xee500060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2060 {"wcmpgtuw", 0xee900060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2061 {"wcmpgtsb", 0xee300060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2062 {"wcmpgtsh", 0xee700060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2063 {"wcmpgtsw", 0xeeb00060, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2064 {"wldrb", 0xec100000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_byte_addr
},
2065 {"wldrh", 0xec100100, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_byte_addr
},
2066 {"wldrw", 0xec100200, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_word_addr
},
2067 {"wldrd", 0xec100300, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_word_addr
},
2068 {"wmacs", 0xee600100, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2069 {"wmacsz", 0xee700100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2070 {"wmacu", 0xee400100, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2071 {"wmacuz", 0xee500100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2072 {"wmadds", 0xeea00100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2073 {"wmaddu", 0xee800100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2074 {"wmaxsb", 0xee200160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2075 {"wmaxsh", 0xee600160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2076 {"wmaxsw", 0xeea00160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2077 {"wmaxub", 0xee000160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2078 {"wmaxuh", 0xee400160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2079 {"wmaxuw", 0xee800160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2080 {"wminsb", 0xee300160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2081 {"wminsh", 0xee700160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2082 {"wminsw", 0xeeb00160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2083 {"wminub", 0xee100160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2084 {"wminuh", 0xee500160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2085 {"wminuw", 0xee900160, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2086 {"wmov", 0xee000000, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_wmov
},
2087 {"wmulsm", 0xee300100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2088 {"wmulsl", 0xee200100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2089 {"wmulum", 0xee100100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2090 {"wmulul", 0xee000100, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2091 {"wor", 0xee000000, 3, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2092 {"wpackhss", 0xee700080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2093 {"wpackhus", 0xee500080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2094 {"wpackwss", 0xeeb00080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2095 {"wpackwus", 0xee900080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2096 {"wpackdss", 0xeef00080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2097 {"wpackdus", 0xeed00080, 8, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2098 {"wrorh", 0xee700040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2099 {"wrorhg", 0xee700148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2100 {"wrorw", 0xeeb00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2101 {"wrorwg", 0xeeb00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2102 {"wrord", 0xeef00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2103 {"wrordg", 0xeef00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2104 {"wsadb", 0xee000120, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2105 {"wsadbz", 0xee100120, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2106 {"wsadh", 0xee400120, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2107 {"wsadhz", 0xee500120, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2108 {"wshufh", 0xee0001e0, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wshufh
},
2109 {"wsllh", 0xee500040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2110 {"wsllhg", 0xee500148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2111 {"wsllw", 0xee900040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2112 {"wsllwg", 0xee900148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2113 {"wslld", 0xeed00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2114 {"wslldg", 0xeed00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2115 {"wsrah", 0xee400040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2116 {"wsrahg", 0xee400148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2117 {"wsraw", 0xee800040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2118 {"wsrawg", 0xee800148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2119 {"wsrad", 0xeec00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2120 {"wsradg", 0xeec00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2121 {"wsrlh", 0xee600040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2122 {"wsrlhg", 0xee600148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2123 {"wsrlw", 0xeea00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2124 {"wsrlwg", 0xeea00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2125 {"wsrld", 0xeee00040, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2126 {"wsrldg", 0xeee00148, 6, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwcg
},
2127 {"wstrb", 0xec000000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_byte_addr
},
2128 {"wstrh", 0xec000100, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_byte_addr
},
2129 {"wstrw", 0xec000200, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_word_addr
},
2130 {"wstrd", 0xec000300, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_word_addr
},
2131 {"wsubbss", 0xee3001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2132 {"wsubb", 0xee0001a0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2133 {"wsubbus", 0xee1001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2134 {"wsubhss", 0xee7001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2135 {"wsubh", 0xee4001a0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2136 {"wsubhus", 0xee5001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2137 {"wsubwss", 0xeeb001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2138 {"wsubw", 0xee8001a0, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2139 {"wsubwus", 0xee9001a0, 7, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2140 {"wunpckehub", 0xee0000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2141 {"wunpckehuh", 0xee4000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2142 {"wunpckehuw", 0xee8000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2143 {"wunpckehsb", 0xee2000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2144 {"wunpckehsh", 0xee6000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2145 {"wunpckehsw", 0xeea000c0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2146 {"wunpckihb", 0xee1000c0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2147 {"wunpckihh", 0xee5000c0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2148 {"wunpckihw", 0xee9000c0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2149 {"wunpckelub", 0xee0000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2150 {"wunpckeluh", 0xee4000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2151 {"wunpckeluw", 0xee8000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2152 {"wunpckelsb", 0xee2000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2153 {"wunpckelsh", 0xee6000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2154 {"wunpckelsw", 0xeea000e0, 10, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwr
},
2155 {"wunpckilb", 0xee1000e0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2156 {"wunpckilh", 0xee5000e0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2157 {"wunpckilw", 0xee9000e0, 9, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2158 {"wxor", 0xee100000, 4, ARM_CEXT_IWMMXT
, do_iwmmxt_wrwrwr
},
2159 {"wzero", 0xee300000, 5, ARM_CEXT_IWMMXT
, do_iwmmxt_wzero
},
2161 /* Cirrus Maverick instructions. */
2162 {"cfldrs", 0xec100400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_1
},
2163 {"cfldrd", 0xec500400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_2
},
2164 {"cfldr32", 0xec100500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_3
},
2165 {"cfldr64", 0xec500500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_4
},
2166 {"cfstrs", 0xec000400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_1
},
2167 {"cfstrd", 0xec400400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_2
},
2168 {"cfstr32", 0xec000500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_3
},
2169 {"cfstr64", 0xec400500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_4
},
2170 {"cfmvsr", 0xee000450, 6, ARM_CEXT_MAVERICK
, do_mav_binops_2a
},
2171 {"cfmvrs", 0xee100450, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1a
},
2172 {"cfmvdlr", 0xee000410, 7, ARM_CEXT_MAVERICK
, do_mav_binops_2b
},
2173 {"cfmvrdl", 0xee100410, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1b
},
2174 {"cfmvdhr", 0xee000430, 7, ARM_CEXT_MAVERICK
, do_mav_binops_2b
},
2175 {"cfmvrdh", 0xee100430, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1b
},
2176 {"cfmv64lr", 0xee000510, 8, ARM_CEXT_MAVERICK
, do_mav_binops_2c
},
2177 {"cfmvr64l", 0xee100510, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1c
},
2178 {"cfmv64hr", 0xee000530, 8, ARM_CEXT_MAVERICK
, do_mav_binops_2c
},
2179 {"cfmvr64h", 0xee100530, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1c
},
2180 {"cfmval32", 0xee200440, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
2181 {"cfmv32al", 0xee100440, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
2182 {"cfmvam32", 0xee200460, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
2183 {"cfmv32am", 0xee100460, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
2184 {"cfmvah32", 0xee200480, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
2185 {"cfmv32ah", 0xee100480, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
2186 {"cfmva32", 0xee2004a0, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
2187 {"cfmv32a", 0xee1004a0, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
2188 {"cfmva64", 0xee2004c0, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3c
},
2189 {"cfmv64a", 0xee1004c0, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3d
},
2190 {"cfmvsc32", 0xee2004e0, 8, ARM_CEXT_MAVERICK
, do_mav_dspsc_1
},
2191 {"cfmv32sc", 0xee1004e0, 8, ARM_CEXT_MAVERICK
, do_mav_dspsc_2
},
2192 {"cfcpys", 0xee000400, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1d
},
2193 {"cfcpyd", 0xee000420, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1e
},
2194 {"cfcvtsd", 0xee000460, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1f
},
2195 {"cfcvtds", 0xee000440, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1g
},
2196 {"cfcvt32s", 0xee000480, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1h
},
2197 {"cfcvt32d", 0xee0004a0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1i
},
2198 {"cfcvt64s", 0xee0004c0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1j
},
2199 {"cfcvt64d", 0xee0004e0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1k
},
2200 {"cfcvts32", 0xee100580, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1l
},
2201 {"cfcvtd32", 0xee1005a0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1m
},
2202 {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK
, do_mav_binops_1l
},
2203 {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK
, do_mav_binops_1m
},
2204 {"cfrshl32", 0xee000550, 8, ARM_CEXT_MAVERICK
, do_mav_triple_4a
},
2205 {"cfrshl64", 0xee000570, 8, ARM_CEXT_MAVERICK
, do_mav_triple_4b
},
2206 {"cfsh32", 0xee000500, 6, ARM_CEXT_MAVERICK
, do_mav_shift_1
},
2207 {"cfsh64", 0xee200500, 6, ARM_CEXT_MAVERICK
, do_mav_shift_2
},
2208 {"cfcmps", 0xee100490, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5a
},
2209 {"cfcmpd", 0xee1004b0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5b
},
2210 {"cfcmp32", 0xee100590, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5c
},
2211 {"cfcmp64", 0xee1005b0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5d
},
2212 {"cfabss", 0xee300400, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1d
},
2213 {"cfabsd", 0xee300420, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1e
},
2214 {"cfnegs", 0xee300440, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1d
},
2215 {"cfnegd", 0xee300460, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1e
},
2216 {"cfadds", 0xee300480, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5e
},
2217 {"cfaddd", 0xee3004a0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5f
},
2218 {"cfsubs", 0xee3004c0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5e
},
2219 {"cfsubd", 0xee3004e0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5f
},
2220 {"cfmuls", 0xee100400, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5e
},
2221 {"cfmuld", 0xee100420, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5f
},
2222 {"cfabs32", 0xee300500, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1n
},
2223 {"cfabs64", 0xee300520, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1o
},
2224 {"cfneg32", 0xee300540, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1n
},
2225 {"cfneg64", 0xee300560, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1o
},
2226 {"cfadd32", 0xee300580, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
2227 {"cfadd64", 0xee3005a0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5h
},
2228 {"cfsub32", 0xee3005c0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
2229 {"cfsub64", 0xee3005e0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5h
},
2230 {"cfmul32", 0xee100500, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
2231 {"cfmul64", 0xee100520, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5h
},
2232 {"cfmac32", 0xee100540, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
2233 {"cfmsc32", 0xee100560, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
2234 {"cfmadd32", 0xee000600, 8, ARM_CEXT_MAVERICK
, do_mav_quad_6a
},
2235 {"cfmsub32", 0xee100600, 8, ARM_CEXT_MAVERICK
, do_mav_quad_6a
},
2236 {"cfmadda32", 0xee200600, 9, ARM_CEXT_MAVERICK
, do_mav_quad_6b
},
2237 {"cfmsuba32", 0xee300600, 9, ARM_CEXT_MAVERICK
, do_mav_quad_6b
},
2240 /* Defines for various bits that we will want to toggle. */
2241 #define INST_IMMEDIATE 0x02000000
2242 #define OFFSET_REG 0x02000000
2243 #define HWOFFSET_IMM 0x00400000
2244 #define SHIFT_BY_REG 0x00000010
2245 #define PRE_INDEX 0x01000000
2246 #define INDEX_UP 0x00800000
2247 #define WRITE_BACK 0x00200000
2248 #define LDM_TYPE_2_OR_3 0x00400000
2250 #define LITERAL_MASK 0xf000f000
2251 #define OPCODE_MASK 0xfe1fffff
2252 #define V4_STR_BIT 0x00000020
2254 #define DATA_OP_SHIFT 21
2256 /* Codes to distinguish the arithmetic instructions. */
2257 #define OPCODE_AND 0
2258 #define OPCODE_EOR 1
2259 #define OPCODE_SUB 2
2260 #define OPCODE_RSB 3
2261 #define OPCODE_ADD 4
2262 #define OPCODE_ADC 5
2263 #define OPCODE_SBC 6
2264 #define OPCODE_RSC 7
2265 #define OPCODE_TST 8
2266 #define OPCODE_TEQ 9
2267 #define OPCODE_CMP 10
2268 #define OPCODE_CMN 11
2269 #define OPCODE_ORR 12
2270 #define OPCODE_MOV 13
2271 #define OPCODE_BIC 14
2272 #define OPCODE_MVN 15
2274 /* Thumb v1 (ARMv4T). */
2275 static void do_t_nop
PARAMS ((char *));
2276 static void do_t_arit
PARAMS ((char *));
2277 static void do_t_add
PARAMS ((char *));
2278 static void do_t_asr
PARAMS ((char *));
2279 static void do_t_branch9
PARAMS ((char *));
2280 static void do_t_branch12
PARAMS ((char *));
2281 static void do_t_branch23
PARAMS ((char *));
2282 static void do_t_bx
PARAMS ((char *));
2283 static void do_t_compare
PARAMS ((char *));
2284 static void do_t_ldmstm
PARAMS ((char *));
2285 static void do_t_ldr
PARAMS ((char *));
2286 static void do_t_ldrb
PARAMS ((char *));
2287 static void do_t_ldrh
PARAMS ((char *));
2288 static void do_t_lds
PARAMS ((char *));
2289 static void do_t_lsl
PARAMS ((char *));
2290 static void do_t_lsr
PARAMS ((char *));
2291 static void do_t_mov
PARAMS ((char *));
2292 static void do_t_push_pop
PARAMS ((char *));
2293 static void do_t_str
PARAMS ((char *));
2294 static void do_t_strb
PARAMS ((char *));
2295 static void do_t_strh
PARAMS ((char *));
2296 static void do_t_sub
PARAMS ((char *));
2297 static void do_t_swi
PARAMS ((char *));
2298 static void do_t_adr
PARAMS ((char *));
2300 /* Thumb v2 (ARMv5T). */
2301 static void do_t_blx
PARAMS ((char *));
2302 static void do_t_bkpt
PARAMS ((char *));
2305 static void do_t_cps
PARAMS ((char *));
2306 static void do_t_cpy
PARAMS ((char *));
2307 static void do_t_setend
PARAMS ((char *));;
2309 #define T_OPCODE_MUL 0x4340
2310 #define T_OPCODE_TST 0x4200
2311 #define T_OPCODE_CMN 0x42c0
2312 #define T_OPCODE_NEG 0x4240
2313 #define T_OPCODE_MVN 0x43c0
2315 #define T_OPCODE_ADD_R3 0x1800
2316 #define T_OPCODE_SUB_R3 0x1a00
2317 #define T_OPCODE_ADD_HI 0x4400
2318 #define T_OPCODE_ADD_ST 0xb000
2319 #define T_OPCODE_SUB_ST 0xb080
2320 #define T_OPCODE_ADD_SP 0xa800
2321 #define T_OPCODE_ADD_PC 0xa000
2322 #define T_OPCODE_ADD_I8 0x3000
2323 #define T_OPCODE_SUB_I8 0x3800
2324 #define T_OPCODE_ADD_I3 0x1c00
2325 #define T_OPCODE_SUB_I3 0x1e00
2327 #define T_OPCODE_ASR_R 0x4100
2328 #define T_OPCODE_LSL_R 0x4080
2329 #define T_OPCODE_LSR_R 0x40c0
2330 #define T_OPCODE_ASR_I 0x1000
2331 #define T_OPCODE_LSL_I 0x0000
2332 #define T_OPCODE_LSR_I 0x0800
2334 #define T_OPCODE_MOV_I8 0x2000
2335 #define T_OPCODE_CMP_I8 0x2800
2336 #define T_OPCODE_CMP_LR 0x4280
2337 #define T_OPCODE_MOV_HR 0x4600
2338 #define T_OPCODE_CMP_HR 0x4500
2340 #define T_OPCODE_LDR_PC 0x4800
2341 #define T_OPCODE_LDR_SP 0x9800
2342 #define T_OPCODE_STR_SP 0x9000
2343 #define T_OPCODE_LDR_IW 0x6800
2344 #define T_OPCODE_STR_IW 0x6000
2345 #define T_OPCODE_LDR_IH 0x8800
2346 #define T_OPCODE_STR_IH 0x8000
2347 #define T_OPCODE_LDR_IB 0x7800
2348 #define T_OPCODE_STR_IB 0x7000
2349 #define T_OPCODE_LDR_RW 0x5800
2350 #define T_OPCODE_STR_RW 0x5000
2351 #define T_OPCODE_LDR_RH 0x5a00
2352 #define T_OPCODE_STR_RH 0x5200
2353 #define T_OPCODE_LDR_RB 0x5c00
2354 #define T_OPCODE_STR_RB 0x5400
2356 #define T_OPCODE_PUSH 0xb400
2357 #define T_OPCODE_POP 0xbc00
2359 #define T_OPCODE_BRANCH 0xe7fe
2361 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
2363 #define THUMB_SIZE 2 /* Size of thumb instruction. */
2364 #define THUMB_REG_LO 0x1
2365 #define THUMB_REG_HI 0x2
2366 #define THUMB_REG_ANY 0x3
2368 #define THUMB_H1 0x0080
2369 #define THUMB_H2 0x0040
2375 #define THUMB_MOVE 0
2376 #define THUMB_COMPARE 1
2379 #define THUMB_LOAD 0
2380 #define THUMB_STORE 1
2382 #define THUMB_PP_PC_LR 0x0100
2384 /* These three are used for immediate shifts, do not alter. */
2385 #define THUMB_WORD 2
2386 #define THUMB_HALFWORD 1
2387 #define THUMB_BYTE 0
2391 /* Basic string to match. */
2392 const char * template;
2394 /* Basic instruction code. */
2395 unsigned long value
;
2399 /* Which CPU variants this exists for. */
2400 unsigned long variant
;
2402 /* Function to call to parse args. */
2403 void (* parms
) PARAMS ((char *));
2406 static const struct thumb_opcode tinsns
[] =
2408 /* Thumb v1 (ARMv4T). */
2409 {"adc", 0x4140, 2, ARM_EXT_V4T
, do_t_arit
},
2410 {"add", 0x0000, 2, ARM_EXT_V4T
, do_t_add
},
2411 {"and", 0x4000, 2, ARM_EXT_V4T
, do_t_arit
},
2412 {"asr", 0x0000, 2, ARM_EXT_V4T
, do_t_asr
},
2413 {"b", T_OPCODE_BRANCH
, 2, ARM_EXT_V4T
, do_t_branch12
},
2414 {"beq", 0xd0fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2415 {"bne", 0xd1fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2416 {"bcs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2417 {"bhs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2418 {"bcc", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2419 {"bul", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2420 {"blo", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2421 {"bmi", 0xd4fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2422 {"bpl", 0xd5fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2423 {"bvs", 0xd6fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2424 {"bvc", 0xd7fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2425 {"bhi", 0xd8fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2426 {"bls", 0xd9fe, 2, ARM_EXT_V4T
, do_t_branch9
},
2427 {"bge", 0xdafe, 2, ARM_EXT_V4T
, do_t_branch9
},
2428 {"blt", 0xdbfe, 2, ARM_EXT_V4T
, do_t_branch9
},
2429 {"bgt", 0xdcfe, 2, ARM_EXT_V4T
, do_t_branch9
},
2430 {"ble", 0xddfe, 2, ARM_EXT_V4T
, do_t_branch9
},
2431 {"bal", 0xdefe, 2, ARM_EXT_V4T
, do_t_branch9
},
2432 {"bic", 0x4380, 2, ARM_EXT_V4T
, do_t_arit
},
2433 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T
, do_t_branch23
},
2434 {"bx", 0x4700, 2, ARM_EXT_V4T
, do_t_bx
},
2435 {"cmn", T_OPCODE_CMN
, 2, ARM_EXT_V4T
, do_t_arit
},
2436 {"cmp", 0x0000, 2, ARM_EXT_V4T
, do_t_compare
},
2437 {"eor", 0x4040, 2, ARM_EXT_V4T
, do_t_arit
},
2438 {"ldmia", 0xc800, 2, ARM_EXT_V4T
, do_t_ldmstm
},
2439 {"ldr", 0x0000, 2, ARM_EXT_V4T
, do_t_ldr
},
2440 {"ldrb", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrb
},
2441 {"ldrh", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrh
},
2442 {"ldrsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
2443 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
2444 {"ldsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
2445 {"ldsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
2446 {"lsl", 0x0000, 2, ARM_EXT_V4T
, do_t_lsl
},
2447 {"lsr", 0x0000, 2, ARM_EXT_V4T
, do_t_lsr
},
2448 {"mov", 0x0000, 2, ARM_EXT_V4T
, do_t_mov
},
2449 {"mul", T_OPCODE_MUL
, 2, ARM_EXT_V4T
, do_t_arit
},
2450 {"mvn", T_OPCODE_MVN
, 2, ARM_EXT_V4T
, do_t_arit
},
2451 {"neg", T_OPCODE_NEG
, 2, ARM_EXT_V4T
, do_t_arit
},
2452 {"orr", 0x4300, 2, ARM_EXT_V4T
, do_t_arit
},
2453 {"pop", 0xbc00, 2, ARM_EXT_V4T
, do_t_push_pop
},
2454 {"push", 0xb400, 2, ARM_EXT_V4T
, do_t_push_pop
},
2455 {"ror", 0x41c0, 2, ARM_EXT_V4T
, do_t_arit
},
2456 {"sbc", 0x4180, 2, ARM_EXT_V4T
, do_t_arit
},
2457 {"stmia", 0xc000, 2, ARM_EXT_V4T
, do_t_ldmstm
},
2458 {"str", 0x0000, 2, ARM_EXT_V4T
, do_t_str
},
2459 {"strb", 0x0000, 2, ARM_EXT_V4T
, do_t_strb
},
2460 {"strh", 0x0000, 2, ARM_EXT_V4T
, do_t_strh
},
2461 {"swi", 0xdf00, 2, ARM_EXT_V4T
, do_t_swi
},
2462 {"sub", 0x0000, 2, ARM_EXT_V4T
, do_t_sub
},
2463 {"tst", T_OPCODE_TST
, 2, ARM_EXT_V4T
, do_t_arit
},
2465 {"adr", 0x0000, 2, ARM_EXT_V4T
, do_t_adr
},
2466 {"nop", 0x46C0, 2, ARM_EXT_V4T
, do_t_nop
}, /* mov r8,r8 */
2467 /* Thumb v2 (ARMv5T). */
2468 {"blx", 0, 0, ARM_EXT_V5T
, do_t_blx
},
2469 {"bkpt", 0xbe00, 2, ARM_EXT_V5T
, do_t_bkpt
},
2472 {"cpsie", 0xb660, 2, ARM_EXT_V6
, do_t_cps
},
2473 {"cpsid", 0xb670, 2, ARM_EXT_V6
, do_t_cps
},
2474 {"cpy", 0x4600, 2, ARM_EXT_V6
, do_t_cpy
},
2475 {"rev", 0xba00, 2, ARM_EXT_V6
, do_t_arit
},
2476 {"rev16", 0xba40, 2, ARM_EXT_V6
, do_t_arit
},
2477 {"revsh", 0xbac0, 2, ARM_EXT_V6
, do_t_arit
},
2478 {"setend", 0xb650, 2, ARM_EXT_V6
, do_t_setend
},
2479 {"sxth", 0xb200, 2, ARM_EXT_V6
, do_t_arit
},
2480 {"sxtb", 0xb240, 2, ARM_EXT_V6
, do_t_arit
},
2481 {"uxth", 0xb280, 2, ARM_EXT_V6
, do_t_arit
},
2482 {"uxtb", 0xb2c0, 2, ARM_EXT_V6
, do_t_arit
},
2485 #define BAD_ARGS _("bad arguments to instruction")
2486 #define BAD_PC _("r15 not allowed here")
2487 #define BAD_COND _("instruction is not conditional")
2488 #define ERR_NO_ACCUM _("acc0 expected")
2490 static struct hash_control
* arm_ops_hsh
= NULL
;
2491 static struct hash_control
* arm_tops_hsh
= NULL
;
2492 static struct hash_control
* arm_cond_hsh
= NULL
;
2493 static struct hash_control
* arm_shift_hsh
= NULL
;
2494 static struct hash_control
* arm_psr_hsh
= NULL
;
2496 /* This table describes all the machine specific pseudo-ops the assembler
2497 has to support. The fields are:
2498 pseudo-op name without dot
2499 function to call to execute this pseudo-op
2500 Integer arg to pass to the function. */
2502 static void s_req
PARAMS ((int));
2503 static void s_unreq
PARAMS ((int));
2504 static void s_align
PARAMS ((int));
2505 static void s_bss
PARAMS ((int));
2506 static void s_even
PARAMS ((int));
2507 static void s_ltorg
PARAMS ((int));
2508 static void s_arm
PARAMS ((int));
2509 static void s_thumb
PARAMS ((int));
2510 static void s_code
PARAMS ((int));
2511 static void s_force_thumb
PARAMS ((int));
2512 static void s_thumb_func
PARAMS ((int));
2513 static void s_thumb_set
PARAMS ((int));
2515 static void s_arm_elf_cons
PARAMS ((int));
2518 static int my_get_expression
PARAMS ((expressionS
*, char **));
2520 const pseudo_typeS md_pseudo_table
[] =
2522 /* Never called because '.req' does not start a line. */
2523 { "req", s_req
, 0 },
2524 { "unreq", s_unreq
, 0 },
2525 { "bss", s_bss
, 0 },
2526 { "align", s_align
, 0 },
2527 { "arm", s_arm
, 0 },
2528 { "thumb", s_thumb
, 0 },
2529 { "code", s_code
, 0 },
2530 { "force_thumb", s_force_thumb
, 0 },
2531 { "thumb_func", s_thumb_func
, 0 },
2532 { "thumb_set", s_thumb_set
, 0 },
2533 { "even", s_even
, 0 },
2534 { "ltorg", s_ltorg
, 0 },
2535 { "pool", s_ltorg
, 0 },
2537 { "word", s_arm_elf_cons
, 4 },
2538 { "long", s_arm_elf_cons
, 4 },
2542 { "extend", float_cons
, 'x' },
2543 { "ldouble", float_cons
, 'x' },
2544 { "packed", float_cons
, 'p' },
2548 /* Other internal functions. */
2549 static int arm_parse_extension
PARAMS ((char *, int *));
2550 static int arm_parse_cpu
PARAMS ((char *));
2551 static int arm_parse_arch
PARAMS ((char *));
2552 static int arm_parse_fpu
PARAMS ((char *));
2553 static int arm_parse_float_abi
PARAMS ((char *));
2554 #if 0 /* Suppressed - for now. */
2555 #if defined OBJ_COFF || defined OBJ_ELF
2556 static void arm_add_note
PARAMS ((const char *, const char *, unsigned int));
2560 /* Stuff needed to resolve the label ambiguity
2570 symbolS
* last_label_seen
;
2571 static int label_is_thumb_function_name
= FALSE
;
2573 /* Literal Pool stuff. */
2575 #define MAX_LITERAL_POOL_SIZE 1024
2577 /* Literal pool structure. Held on a per-section
2578 and per-sub-section basis. */
2579 typedef struct literal_pool
2581 expressionS literals
[MAX_LITERAL_POOL_SIZE
];
2582 unsigned int next_free_entry
;
2586 subsegT sub_section
;
2587 struct literal_pool
* next
;
2590 /* Pointer to a linked list of literal pools. */
2591 literal_pool
* list_of_pools
= NULL
;
2593 static literal_pool
* find_literal_pool
PARAMS ((void));
2594 static literal_pool
* find_or_make_literal_pool
PARAMS ((void));
2596 static literal_pool
*
2597 find_literal_pool ()
2599 literal_pool
* pool
;
2601 for (pool
= list_of_pools
; pool
!= NULL
; pool
= pool
->next
)
2603 if (pool
->section
== now_seg
2604 && pool
->sub_section
== now_subseg
)
2611 static literal_pool
*
2612 find_or_make_literal_pool ()
2614 /* Next literal pool ID number. */
2615 static unsigned int latest_pool_num
= 1;
2616 literal_pool
* pool
;
2618 pool
= find_literal_pool ();
2622 /* Create a new pool. */
2623 pool
= (literal_pool
*) xmalloc (sizeof (* pool
));
2627 pool
->next_free_entry
= 0;
2628 pool
->section
= now_seg
;
2629 pool
->sub_section
= now_subseg
;
2630 pool
->next
= list_of_pools
;
2631 pool
->symbol
= NULL
;
2633 /* Add it to the list. */
2634 list_of_pools
= pool
;
2637 /* New pools, and emptied pools, will have a NULL symbol. */
2638 if (pool
->symbol
== NULL
)
2640 pool
->symbol
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
2641 (valueT
) 0, &zero_address_frag
);
2642 pool
->id
= latest_pool_num
++;
2649 /* Add the literal in the global 'inst'
2650 structure to the relevent literal pool. */
2654 literal_pool
* pool
;
2657 pool
= find_or_make_literal_pool ();
2659 /* Check if this literal value is already in the pool. */
2660 for (entry
= 0; entry
< pool
->next_free_entry
; entry
++)
2662 if ((pool
->literals
[entry
].X_op
== inst
.reloc
.exp
.X_op
)
2663 && (inst
.reloc
.exp
.X_op
== O_constant
)
2664 && (pool
->literals
[entry
].X_add_number
2665 == inst
.reloc
.exp
.X_add_number
)
2666 && (pool
->literals
[entry
].X_unsigned
2667 == inst
.reloc
.exp
.X_unsigned
))
2670 if ((pool
->literals
[entry
].X_op
== inst
.reloc
.exp
.X_op
)
2671 && (inst
.reloc
.exp
.X_op
== O_symbol
)
2672 && (pool
->literals
[entry
].X_add_number
2673 == inst
.reloc
.exp
.X_add_number
)
2674 && (pool
->literals
[entry
].X_add_symbol
2675 == inst
.reloc
.exp
.X_add_symbol
)
2676 && (pool
->literals
[entry
].X_op_symbol
2677 == inst
.reloc
.exp
.X_op_symbol
))
2681 /* Do we need to create a new entry? */
2682 if (entry
== pool
->next_free_entry
)
2684 if (entry
>= MAX_LITERAL_POOL_SIZE
)
2686 inst
.error
= _("literal pool overflow");
2690 pool
->literals
[entry
] = inst
.reloc
.exp
;
2691 pool
->next_free_entry
+= 1;
2694 inst
.reloc
.exp
.X_op
= O_symbol
;
2695 inst
.reloc
.exp
.X_add_number
= ((int) entry
) * 4 - 8;
2696 inst
.reloc
.exp
.X_add_symbol
= pool
->symbol
;
2701 /* Can't use symbol_new here, so have to create a symbol and then at
2702 a later date assign it a value. Thats what these functions do. */
2705 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
2707 const char * name
; /* It is copied, the caller can modify. */
2708 segT segment
; /* Segment identifier (SEG_<something>). */
2709 valueT valu
; /* Symbol value. */
2710 fragS
* frag
; /* Associated fragment. */
2712 unsigned int name_length
;
2713 char * preserved_copy_of_name
;
2715 name_length
= strlen (name
) + 1; /* +1 for \0. */
2716 obstack_grow (¬es
, name
, name_length
);
2717 preserved_copy_of_name
= obstack_finish (¬es
);
2718 #ifdef STRIP_UNDERSCORE
2719 if (preserved_copy_of_name
[0] == '_')
2720 preserved_copy_of_name
++;
2723 #ifdef tc_canonicalize_symbol_name
2724 preserved_copy_of_name
=
2725 tc_canonicalize_symbol_name (preserved_copy_of_name
);
2728 S_SET_NAME (symbolP
, preserved_copy_of_name
);
2730 S_SET_SEGMENT (symbolP
, segment
);
2731 S_SET_VALUE (symbolP
, valu
);
2732 symbol_clear_list_pointers (symbolP
);
2734 symbol_set_frag (symbolP
, frag
);
2736 /* Link to end of symbol chain. */
2738 extern int symbol_table_frozen
;
2739 if (symbol_table_frozen
)
2743 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
2745 obj_symbol_new_hook (symbolP
);
2747 #ifdef tc_symbol_new_hook
2748 tc_symbol_new_hook (symbolP
);
2752 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
2753 #endif /* DEBUG_SYMS */
2756 /* Check that an immediate is valid.
2757 If so, convert it to the right format. */
2760 validate_immediate (val
)
2766 #define rotate_left(v, n) (v << n | v >> (32 - n))
2768 for (i
= 0; i
< 32; i
+= 2)
2769 if ((a
= rotate_left (val
, i
)) <= 0xff)
2770 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
2775 /* Check to see if an immediate can be computed as two separate immediate
2776 values, added together. We already know that this value cannot be
2777 computed by just one ARM instruction. */
2780 validate_immediate_twopart (val
, highpart
)
2782 unsigned int * highpart
;
2787 for (i
= 0; i
< 32; i
+= 2)
2788 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
2794 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
2796 else if (a
& 0xff0000)
2800 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
2804 assert (a
& 0xff000000);
2805 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
2808 return (a
& 0xff) | (i
<< 7);
2815 validate_offset_imm (val
, hwse
)
2819 if ((hwse
&& val
> 255) || val
> 4095)
2833 /* This code is to handle mapping symbols as defined in the ARM ELF spec.
2834 (This text is taken from version B-02 of the spec):
2836 4.4.7 Mapping and tagging symbols
2838 A section of an ARM ELF file can contain a mixture of ARM code,
2839 Thumb code, and data. There are inline transitions between code
2840 and data at literal pool boundaries. There can also be inline
2841 transitions between ARM code and Thumb code, for example in
2842 ARM-Thumb inter-working veneers. Linkers, machine-level
2843 debuggers, profiling tools, and disassembly tools need to map
2844 images accurately. For example, setting an ARM breakpoint on a
2845 Thumb location, or in a literal pool, can crash the program
2846 being debugged, ruining the debugging session.
2848 ARM ELF entities are mapped (see section 4.4.7.1 below) and
2849 tagged (see section 4.4.7.2 below) using local symbols (with
2850 binding STB_LOCAL). To assist consumers, mapping and tagging
2851 symbols should be collated first in the symbol table, before
2852 other symbols with binding STB_LOCAL.
2854 To allow properly collated mapping and tagging symbols to be
2855 skipped by consumers that have no interest in them, the first
2856 such symbol should have the name $m and its st_value field equal
2857 to the total number of mapping and tagging symbols (including
2858 the $m) in the symbol table.
2860 4.4.7.1 Mapping symbols
2862 $a Labels the first byte of a sequence of ARM instructions.
2863 Its type is STT_FUNC.
2865 $d Labels the first byte of a sequence of data items.
2866 Its type is STT_OBJECT.
2868 $t Labels the first byte of a sequence of Thumb instructions.
2869 Its type is STT_FUNC.
2871 This list of mapping symbols may be extended in the future.
2873 Section-relative mapping symbols
2875 Mapping symbols defined in a section define a sequence of
2876 half-open address intervals that cover the address range of the
2877 section. Each interval starts at the address defined by a
2878 mapping symbol, and continues up to, but not including, the
2879 address defined by the next (in address order) mapping symbol or
2880 the end of the section. A corollary is that there must be a
2881 mapping symbol defined at the beginning of each section.
2882 Consumers can ignore the size of a section-relative mapping
2883 symbol. Producers can set it to 0.
2885 Absolute mapping symbols
2887 Because of the need to crystallize a Thumb address with the
2888 Thumb-bit set, absolute symbol of type STT_FUNC (symbols of type
2889 STT_FUNC defined in section SHN_ABS) need to be mapped with $a
2892 The extent of a mapping symbol defined in SHN_ABS is [st_value,
2893 st_value + st_size), or [st_value, st_value + 1) if st_size = 0,
2894 where [x, y) denotes the half-open address range from x,
2895 inclusive, to y, exclusive.
2897 In the absence of a mapping symbol, a consumer can interpret a
2898 function symbol with an odd value as the Thumb code address
2899 obtained by clearing the least significant bit of the
2900 value. This interpretation is deprecated, and it may not work in
2903 Note - the Tagging symbols ($b, $f, $p $m) have been dropped from
2904 the EABI (which is still under development), so they are not
2905 implemented here. */
2908 mapping_state (enum mstate state
)
2910 static enum mstate mapstate
= MAP_DATA
;
2912 const char * symname
;
2915 if (mapstate
== state
)
2916 /* The mapping symbol has already been emitted.
2917 There is nothing else to do. */
2930 type
= BSF_FUNCTION
;
2934 type
= BSF_FUNCTION
;
2940 symbolP
= symbol_new (symname
, now_seg
, (valueT
) frag_now_fix (), frag_now
);
2941 symbol_table_insert (symbolP
);
2942 symbol_get_bfdsym (symbolP
)->flags
|= type
| BSF_LOCAL
;
2947 THUMB_SET_FUNC (symbolP
, 0);
2948 ARM_SET_THUMB (symbolP
, 0);
2949 ARM_SET_INTERWORK (symbolP
, support_interwork
);
2953 THUMB_SET_FUNC (symbolP
, 1);
2954 ARM_SET_THUMB (symbolP
, 1);
2955 ARM_SET_INTERWORK (symbolP
, support_interwork
);
2964 /* When we change sections we need to issue a new mapping symbol. */
2967 arm_elf_change_section (void)
2971 if (!SEG_NORMAL (now_seg
))
2974 flags
= bfd_get_section_flags (stdoutput
, now_seg
);
2976 /* We can ignore sections that only contain debug info. */
2977 if ((flags
& SEC_ALLOC
) == 0)
2980 if (flags
& SEC_CODE
)
2983 mapping_state (MAP_THUMB
);
2985 mapping_state (MAP_ARM
);
2988 /* This section does not contain code. Therefore it must contain data. */
2989 mapping_state (MAP_DATA
);
2992 #define mapping_state(a)
2993 #endif /* OBJ_ELF */
2998 int a ATTRIBUTE_UNUSED
;
3000 as_bad (_("invalid syntax for .req directive"));
3003 /* The .unreq directive deletes an alias which was previously defined
3004 by .req. For example:
3010 s_unreq (int a ATTRIBUTE_UNUSED
)
3015 skip_whitespace (input_line_pointer
);
3016 name
= input_line_pointer
;
3018 while (*input_line_pointer
!= 0
3019 && *input_line_pointer
!= ' '
3020 && *input_line_pointer
!= '\n')
3021 ++input_line_pointer
;
3023 saved_char
= *input_line_pointer
;
3024 *input_line_pointer
= 0;
3028 enum arm_reg_type req_type
= arm_reg_parse_any (name
);
3030 if (req_type
!= REG_TYPE_MAX
)
3032 char *temp_name
= name
;
3033 int req_no
= arm_reg_parse (&temp_name
, all_reg_maps
[req_type
].htab
);
3037 struct reg_entry
*req_entry
;
3039 /* Check to see if this alias is a builtin one. */
3040 req_entry
= hash_delete (all_reg_maps
[req_type
].htab
, name
);
3043 as_bad (_("unreq: missing hash entry for \"%s\""), name
);
3044 else if (req_entry
->builtin
)
3045 /* FIXME: We are deleting a built in register alias which
3046 points to a const data structure, so we only need to
3047 free up the memory used by the key in the hash table.
3048 Unfortunately we have not recorded this value, so this
3049 is a memory leak. */
3050 /* FIXME: Should we issue a warning message ? */
3054 /* Deleting a user defined alias. We need to free the
3055 key and the value, but fortunately the key is the same
3056 as the value->name field. */
3057 free ((char *) req_entry
->name
);
3062 as_bad (_(".unreq: unrecognized symbol \"%s\""), name
);
3065 as_bad (_(".unreq: unrecognized symbol \"%s\""), name
);
3068 as_bad (_("invalid syntax for .unreq directive"));
3070 *input_line_pointer
= saved_char
;
3071 demand_empty_rest_of_line ();
3076 int ignore ATTRIBUTE_UNUSED
;
3078 /* We don't support putting frags in the BSS segment, we fake it by
3079 marking in_bss, then looking at s_skip for clues. */
3080 subseg_set (bss_section
, 0);
3081 demand_empty_rest_of_line ();
3082 mapping_state (MAP_DATA
);
3087 int ignore ATTRIBUTE_UNUSED
;
3089 /* Never make frag if expect extra pass. */
3091 frag_align (1, 0, 0);
3093 record_alignment (now_seg
, 1);
3095 demand_empty_rest_of_line ();
3100 int ignored ATTRIBUTE_UNUSED
;
3103 literal_pool
* pool
;
3106 pool
= find_literal_pool ();
3108 || pool
->symbol
== NULL
3109 || pool
->next_free_entry
== 0)
3112 /* Align pool as you have word accesses.
3113 Only make a frag if we have to. */
3115 frag_align (2, 0, 0);
3117 record_alignment (now_seg
, 2);
3119 sprintf (sym_name
, "$$lit_\002%x", pool
->id
);
3121 symbol_locate (pool
->symbol
, sym_name
, now_seg
,
3122 (valueT
) frag_now_fix (), frag_now
);
3123 symbol_table_insert (pool
->symbol
);
3125 ARM_SET_THUMB (pool
->symbol
, thumb_mode
);
3127 #if defined OBJ_COFF || defined OBJ_ELF
3128 ARM_SET_INTERWORK (pool
->symbol
, support_interwork
);
3131 for (entry
= 0; entry
< pool
->next_free_entry
; entry
++)
3132 /* First output the expression in the instruction to the pool. */
3133 emit_expr (&(pool
->literals
[entry
]), 4); /* .word */
3135 /* Mark the pool as empty. */
3136 pool
->next_free_entry
= 0;
3137 pool
->symbol
= NULL
;
3140 /* Same as s_align_ptwo but align 0 => align 2. */
3144 int unused ATTRIBUTE_UNUSED
;
3147 register long temp_fill
;
3148 long max_alignment
= 15;
3150 temp
= get_absolute_expression ();
3151 if (temp
> max_alignment
)
3152 as_bad (_("alignment too large: %d assumed"), temp
= max_alignment
);
3155 as_bad (_("alignment negative. 0 assumed."));
3159 if (*input_line_pointer
== ',')
3161 input_line_pointer
++;
3162 temp_fill
= get_absolute_expression ();
3170 /* Only make a frag if we HAVE to. */
3171 if (temp
&& !need_pass_2
)
3172 frag_align (temp
, (int) temp_fill
, 0);
3173 demand_empty_rest_of_line ();
3175 record_alignment (now_seg
, temp
);
3179 s_force_thumb (ignore
)
3180 int ignore ATTRIBUTE_UNUSED
;
3182 /* If we are not already in thumb mode go into it, EVEN if
3183 the target processor does not support thumb instructions.
3184 This is used by gcc/config/arm/lib1funcs.asm for example
3185 to compile interworking support functions even if the
3186 target processor should not support interworking. */
3191 record_alignment (now_seg
, 1);
3194 demand_empty_rest_of_line ();
3198 s_thumb_func (ignore
)
3199 int ignore ATTRIBUTE_UNUSED
;
3204 /* The following label is the name/address of the start of a Thumb function.
3205 We need to know this for the interworking support. */
3206 label_is_thumb_function_name
= TRUE
;
3208 demand_empty_rest_of_line ();
3211 /* Perform a .set directive, but also mark the alias as
3212 being a thumb function. */
3218 /* XXX the following is a duplicate of the code for s_set() in read.c
3219 We cannot just call that code as we need to get at the symbol that
3221 register char * name
;
3222 register char delim
;
3223 register char * end_name
;
3224 register symbolS
* symbolP
;
3226 /* Especial apologies for the random logic:
3227 This just grew, and could be parsed much more simply!
3229 name
= input_line_pointer
;
3230 delim
= get_symbol_end ();
3231 end_name
= input_line_pointer
;
3236 if (*input_line_pointer
!= ',')
3239 as_bad (_("expected comma after name \"%s\""), name
);
3241 ignore_rest_of_line ();
3245 input_line_pointer
++;
3248 if (name
[0] == '.' && name
[1] == '\0')
3250 /* XXX - this should not happen to .thumb_set. */
3254 if ((symbolP
= symbol_find (name
)) == NULL
3255 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
3258 /* When doing symbol listings, play games with dummy fragments living
3259 outside the normal fragment chain to record the file and line info
3261 if (listing
& LISTING_SYMBOLS
)
3263 extern struct list_info_struct
* listing_tail
;
3264 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
3266 memset (dummy_frag
, 0, sizeof (fragS
));
3267 dummy_frag
->fr_type
= rs_fill
;
3268 dummy_frag
->line
= listing_tail
;
3269 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
3270 dummy_frag
->fr_symbol
= symbolP
;
3274 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
3277 /* "set" symbols are local unless otherwise specified. */
3278 SF_SET_LOCAL (symbolP
);
3279 #endif /* OBJ_COFF */
3280 } /* Make a new symbol. */
3282 symbol_table_insert (symbolP
);
3287 && S_IS_DEFINED (symbolP
)
3288 && S_GET_SEGMENT (symbolP
) != reg_section
)
3289 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
3291 pseudo_set (symbolP
);
3293 demand_empty_rest_of_line ();
3295 /* XXX Now we come to the Thumb specific bit of code. */
3297 THUMB_SET_FUNC (symbolP
, 1);
3298 ARM_SET_THUMB (symbolP
, 1);
3299 #if defined OBJ_ELF || defined OBJ_COFF
3300 ARM_SET_INTERWORK (symbolP
, support_interwork
);
3305 opcode_select (width
)
3313 if (! (cpu_variant
& ARM_EXT_V4T
))
3314 as_bad (_("selected processor does not support THUMB opcodes"));
3317 /* No need to force the alignment, since we will have been
3318 coming from ARM mode, which is word-aligned. */
3319 record_alignment (now_seg
, 1);
3321 mapping_state (MAP_THUMB
);
3327 if ((cpu_variant
& ARM_ALL
) == ARM_EXT_V4T
)
3328 as_bad (_("selected processor does not support ARM opcodes"));
3333 frag_align (2, 0, 0);
3335 record_alignment (now_seg
, 1);
3337 mapping_state (MAP_ARM
);
3341 as_bad (_("invalid instruction size selected (%d)"), width
);
3347 int ignore ATTRIBUTE_UNUSED
;
3350 demand_empty_rest_of_line ();
3355 int ignore ATTRIBUTE_UNUSED
;
3358 demand_empty_rest_of_line ();
3363 int unused ATTRIBUTE_UNUSED
;
3367 temp
= get_absolute_expression ();
3372 opcode_select (temp
);
3376 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
3384 skip_whitespace (str
);
3386 if (*str
!= '\0' && !inst
.error
)
3387 inst
.error
= _("garbage following instruction");
3391 skip_past_comma (str
)
3394 char * p
= * str
, c
;
3397 while ((c
= *p
) == ' ' || c
== ',')
3400 if (c
== ',' && comma
++)
3408 return comma
? SUCCESS
: FAIL
;
3411 /* A standard register must be given at this point.
3412 SHIFT is the place to put it in inst.instruction.
3413 Restores input start point on error.
3414 Returns the reg#, or FAIL. */
3417 reg_required_here (str
, shift
)
3421 static char buff
[128]; /* XXX */
3423 char * start
= * str
;
3425 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_RN
].htab
)) != FAIL
)
3428 inst
.instruction
|= reg
<< shift
;
3432 /* Restore the start point, we may have got a reg of the wrong class. */
3435 /* In the few cases where we might be able to accept something else
3436 this error can be overridden. */
3437 sprintf (buff
, _("register expected, not '%.100s'"), start
);
3443 /* A Intel Wireless MMX technology register
3444 must be given at this point.
3445 Shift is the place to put it in inst.instruction.
3446 Restores input start point on err.
3447 Returns the reg#, or FAIL. */
3450 wreg_required_here (str
, shift
, reg_type
)
3453 enum wreg_type reg_type
;
3455 static char buff
[128];
3457 char * start
= *str
;
3459 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_IWMMXT
].htab
)) != FAIL
)
3461 if (wr_register (reg
)
3462 && (reg_type
== IWMMXT_REG_WR
|| reg_type
== IWMMXT_REG_WR_OR_WC
))
3465 inst
.instruction
|= (reg
^ WR_PREFIX
) << shift
;
3468 else if (wc_register (reg
)
3469 && (reg_type
== IWMMXT_REG_WC
|| reg_type
== IWMMXT_REG_WR_OR_WC
))
3472 inst
.instruction
|= (reg
^ WC_PREFIX
) << shift
;
3475 else if ((wcg_register (reg
) && reg_type
== IWMMXT_REG_WCG
))
3478 inst
.instruction
|= ((reg
^ WC_PREFIX
) - 8) << shift
;
3483 /* Restore the start point, we may have got a reg of the wrong class. */
3486 /* In the few cases where we might be able to accept
3487 something else this error can be overridden. */
3488 sprintf (buff
, _("Intel Wireless MMX technology register expected, not '%.100s'"), start
);
3494 static const struct asm_psr
*
3496 register char ** ccp
;
3498 char * start
= * ccp
;
3501 const struct asm_psr
* psr
;
3505 /* Skip to the end of the next word in the input stream. */
3510 while (ISALPHA (c
) || c
== '_');
3512 /* Terminate the word. */
3515 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
3516 feature for ease of use and backwards compatibility. */
3517 if (!strncmp (start
, "cpsr", 4))
3518 strncpy (start
, "CPSR", 4);
3519 else if (!strncmp (start
, "spsr", 4))
3520 strncpy (start
, "SPSR", 4);
3522 /* Now locate the word in the psr hash table. */
3523 psr
= (const struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
3525 /* Restore the input stream. */
3528 /* If we found a valid match, advance the
3529 stream pointer past the end of the word. */
3535 /* Parse the input looking for a PSR flag. */
3538 psr_required_here (str
)
3541 char * start
= * str
;
3542 const struct asm_psr
* psr
;
3544 psr
= arm_psr_parse (str
);
3548 /* If this is the SPSR that is being modified, set the R bit. */
3550 inst
.instruction
|= SPSR_BIT
;
3552 /* Set the psr flags in the MSR instruction. */
3553 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
3558 /* In the few cases where we might be able to accept
3559 something else this error can be overridden. */
3560 inst
.error
= _("flag for {c}psr instruction expected");
3562 /* Restore the start point. */
3568 co_proc_number (str
)
3571 int processor
, pchar
;
3574 skip_whitespace (*str
);
3577 /* The data sheet seems to imply that just a number on its own is valid
3578 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
3580 if ((processor
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_CP
].htab
))
3586 if (pchar
>= '0' && pchar
<= '9')
3588 processor
= pchar
- '0';
3589 if (**str
>= '0' && **str
<= '9')
3591 processor
= processor
* 10 + *(*str
)++ - '0';
3594 inst
.error
= _("illegal co-processor number");
3601 inst
.error
= _("bad or missing co-processor number");
3606 inst
.instruction
|= processor
<< 8;
3611 cp_opc_expr (str
, where
, length
)
3618 skip_whitespace (* str
);
3620 memset (&expr
, '\0', sizeof (expr
));
3622 if (my_get_expression (&expr
, str
))
3624 if (expr
.X_op
!= O_constant
)
3626 inst
.error
= _("bad or missing expression");
3630 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
3632 inst
.error
= _("immediate co-processor expression too large");
3636 inst
.instruction
|= expr
.X_add_number
<< where
;
3641 cp_reg_required_here (str
, where
)
3646 char * start
= *str
;
3648 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_CN
].htab
)) != FAIL
)
3650 inst
.instruction
|= reg
<< where
;
3654 /* In the few cases where we might be able to accept something else
3655 this error can be overridden. */
3656 inst
.error
= _("co-processor register expected");
3658 /* Restore the start point. */
3664 fp_reg_required_here (str
, where
)
3669 char * start
= * str
;
3671 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_FN
].htab
)) != FAIL
)
3673 inst
.instruction
|= reg
<< where
;
3677 /* In the few cases where we might be able to accept something else
3678 this error can be overridden. */
3679 inst
.error
= _("floating point register expected");
3681 /* Restore the start point. */
3687 cp_address_offset (str
)
3692 skip_whitespace (* str
);
3694 if (! is_immediate_prefix (**str
))
3696 inst
.error
= _("immediate expression expected");
3702 if (my_get_expression (& inst
.reloc
.exp
, str
))
3705 if (inst
.reloc
.exp
.X_op
== O_constant
)
3707 offset
= inst
.reloc
.exp
.X_add_number
;
3711 inst
.error
= _("co-processor address must be word aligned");
3715 if (offset
> 1023 || offset
< -1023)
3717 inst
.error
= _("offset too large");
3722 inst
.instruction
|= INDEX_UP
;
3726 inst
.instruction
|= offset
>> 2;
3729 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
3735 cp_address_required_here (str
, wb_ok
)
3748 skip_whitespace (p
);
3750 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
3753 skip_whitespace (p
);
3759 skip_whitespace (p
);
3763 /* As an extension to the official ARM syntax we allow:
3767 as a short hand for:
3770 inst
.instruction
|= PRE_INDEX
| INDEX_UP
;
3775 if (skip_past_comma (& p
) == FAIL
)
3777 inst
.error
= _("comma expected after closing square bracket");
3781 skip_whitespace (p
);
3788 write_back
= WRITE_BACK
;
3792 inst
.error
= _("pc may not be used in post-increment");
3796 if (cp_address_offset (& p
) == FAIL
)
3800 pre_inc
= PRE_INDEX
| INDEX_UP
;
3806 /* [Rn], {<expr>} */
3809 skip_whitespace (p
);
3811 if (my_get_expression (& inst
.reloc
.exp
, & p
))
3814 if (inst
.reloc
.exp
.X_op
== O_constant
)
3816 option
= inst
.reloc
.exp
.X_add_number
;
3818 if (option
> 255 || option
< 0)
3820 inst
.error
= _("'option' field too large");
3824 skip_whitespace (p
);
3828 inst
.error
= _("'}' expected at end of 'option' field");
3834 inst
.instruction
|= option
;
3835 inst
.instruction
|= INDEX_UP
;
3840 inst
.error
= _("non-constant expressions for 'option' field not supported");
3846 inst
.error
= _("# or { expected after comma");
3852 /* '['Rn, #expr']'[!] */
3854 if (skip_past_comma (& p
) == FAIL
)
3856 inst
.error
= _("pre-indexed expression expected");
3860 pre_inc
= PRE_INDEX
;
3862 if (cp_address_offset (& p
) == FAIL
)
3865 skip_whitespace (p
);
3869 inst
.error
= _("missing ]");
3873 skip_whitespace (p
);
3875 if (wb_ok
&& *p
== '!')
3879 inst
.error
= _("pc may not be used with write-back");
3884 write_back
= WRITE_BACK
;
3890 if (my_get_expression (&inst
.reloc
.exp
, &p
))
3893 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
3894 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
3895 inst
.reloc
.pc_rel
= 1;
3896 inst
.instruction
|= (REG_PC
<< 16);
3897 pre_inc
= PRE_INDEX
;
3900 inst
.instruction
|= write_back
| pre_inc
;
3906 cp_byte_address_offset (str
)
3911 skip_whitespace (* str
);
3913 if (! is_immediate_prefix (**str
))
3915 inst
.error
= _("immediate expression expected");
3921 if (my_get_expression (& inst
.reloc
.exp
, str
))
3924 if (inst
.reloc
.exp
.X_op
== O_constant
)
3926 offset
= inst
.reloc
.exp
.X_add_number
;
3928 if (offset
> 255 || offset
< -255)
3930 inst
.error
= _("offset too large");
3935 inst
.instruction
|= INDEX_UP
;
3939 inst
.instruction
|= offset
;
3942 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM_S2
;
3948 cp_byte_address_required_here (str
)
3960 skip_whitespace (p
);
3962 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
3965 skip_whitespace (p
);
3971 if (skip_past_comma (& p
) == SUCCESS
)
3974 write_back
= WRITE_BACK
;
3978 inst
.error
= _("pc may not be used in post-increment");
3982 if (cp_byte_address_offset (& p
) == FAIL
)
3986 pre_inc
= PRE_INDEX
| INDEX_UP
;
3990 /* '['Rn, #expr']'[!] */
3992 if (skip_past_comma (& p
) == FAIL
)
3994 inst
.error
= _("pre-indexed expression expected");
3998 pre_inc
= PRE_INDEX
;
4000 if (cp_byte_address_offset (& p
) == FAIL
)
4003 skip_whitespace (p
);
4007 inst
.error
= _("missing ]");
4011 skip_whitespace (p
);
4017 inst
.error
= _("pc may not be used with write-back");
4022 write_back
= WRITE_BACK
;
4028 if (my_get_expression (&inst
.reloc
.exp
, &p
))
4031 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM_S2
;
4032 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
4033 inst
.reloc
.pc_rel
= 1;
4034 inst
.instruction
|= (REG_PC
<< 16);
4035 pre_inc
= PRE_INDEX
;
4038 inst
.instruction
|= write_back
| pre_inc
;
4047 /* Do nothing really. */
4057 /* Only one syntax. */
4058 skip_whitespace (str
);
4060 if (reg_required_here (&str
, 12) == FAIL
)
4062 inst
.error
= BAD_ARGS
;
4066 if (skip_past_comma (&str
) == FAIL
)
4068 inst
.error
= _("comma expected after register name");
4072 skip_whitespace (str
);
4074 if ( strcmp (str
, "CPSR") == 0
4075 || strcmp (str
, "SPSR") == 0
4076 /* Lower case versions for backwards compatibility. */
4077 || strcmp (str
, "cpsr") == 0
4078 || strcmp (str
, "spsr") == 0)
4081 /* This is for backwards compatibility with older toolchains. */
4082 else if ( strcmp (str
, "cpsr_all") == 0
4083 || strcmp (str
, "spsr_all") == 0)
4087 inst
.error
= _("CPSR or SPSR expected");
4091 if (* str
== 's' || * str
== 'S')
4092 inst
.instruction
|= SPSR_BIT
;
4098 /* Two possible forms:
4099 "{C|S}PSR_<field>, Rm",
4100 "{C|S}PSR_f, #expression". */
4106 skip_whitespace (str
);
4108 if (psr_required_here (& str
) == FAIL
)
4111 if (skip_past_comma (& str
) == FAIL
)
4113 inst
.error
= _("comma missing after psr flags");
4117 skip_whitespace (str
);
4119 if (reg_required_here (& str
, 0) != FAIL
)
4126 if (! is_immediate_prefix (* str
))
4129 _("only a register or immediate value can follow a psr flag");
4136 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4139 _("only a register or immediate value can follow a psr flag");
4143 #if 0 /* The first edition of the ARM architecture manual stated that
4144 writing anything other than the flags with an immediate operation
4145 had UNPREDICTABLE effects. This constraint was removed in the
4146 second edition of the specification. */
4147 if ((cpu_variant
& ARM_EXT_V5
) != ARM_EXT_V5
4148 && inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
4150 inst
.error
= _("immediate value cannot be used to set this field");
4155 inst
.instruction
|= INST_IMMEDIATE
;
4157 if (inst
.reloc
.exp
.X_add_symbol
)
4159 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4160 inst
.reloc
.pc_rel
= 0;
4164 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4166 if (value
== (unsigned) FAIL
)
4168 inst
.error
= _("invalid constant");
4172 inst
.instruction
|= value
;
4179 /* Long Multiply Parser
4180 UMULL RdLo, RdHi, Rm, Rs
4181 SMULL RdLo, RdHi, Rm, Rs
4182 UMLAL RdLo, RdHi, Rm, Rs
4183 SMLAL RdLo, RdHi, Rm, Rs. */
4189 int rdlo
, rdhi
, rm
, rs
;
4191 /* Only one format "rdlo, rdhi, rm, rs". */
4192 skip_whitespace (str
);
4194 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
4196 inst
.error
= BAD_ARGS
;
4200 if (skip_past_comma (&str
) == FAIL
4201 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
4203 inst
.error
= BAD_ARGS
;
4207 if (skip_past_comma (&str
) == FAIL
4208 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
4210 inst
.error
= BAD_ARGS
;
4214 /* rdhi, rdlo and rm must all be different. */
4215 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
4216 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
4218 if (skip_past_comma (&str
) == FAIL
4219 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
4221 inst
.error
= BAD_ARGS
;
4225 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
4227 inst
.error
= BAD_PC
;
4240 /* Only one format "rd, rm, rs". */
4241 skip_whitespace (str
);
4243 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
4245 inst
.error
= BAD_ARGS
;
4251 inst
.error
= BAD_PC
;
4255 if (skip_past_comma (&str
) == FAIL
4256 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
4258 inst
.error
= BAD_ARGS
;
4264 inst
.error
= BAD_PC
;
4269 as_tsktsk (_("rd and rm should be different in mul"));
4271 if (skip_past_comma (&str
) == FAIL
4272 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
4274 inst
.error
= BAD_ARGS
;
4280 inst
.error
= BAD_PC
;
4293 /* Only one format "rd, rm, rs, rn". */
4294 skip_whitespace (str
);
4296 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
4298 inst
.error
= BAD_ARGS
;
4304 inst
.error
= BAD_PC
;
4308 if (skip_past_comma (&str
) == FAIL
4309 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
4311 inst
.error
= BAD_ARGS
;
4317 inst
.error
= BAD_PC
;
4322 as_tsktsk (_("rd and rm should be different in mla"));
4324 if (skip_past_comma (&str
) == FAIL
4325 || (rd
= reg_required_here (&str
, 8)) == FAIL
4326 || skip_past_comma (&str
) == FAIL
4327 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
4329 inst
.error
= BAD_ARGS
;
4333 if (rd
== REG_PC
|| rm
== REG_PC
)
4335 inst
.error
= BAD_PC
;
4342 /* Expects *str -> the characters "acc0", possibly with leading blanks.
4343 Advances *str to the next non-alphanumeric.
4344 Returns 0, or else FAIL (in which case sets inst.error).
4346 (In a future XScale, there may be accumulators other than zero.
4347 At that time this routine and its callers can be upgraded to suit.) */
4350 accum0_required_here (str
)
4353 static char buff
[128]; /* Note the address is taken. Hence, static. */
4356 int result
= 0; /* The accum number. */
4358 skip_whitespace (p
);
4360 *str
= p
; /* Advance caller's string pointer too. */
4365 *--p
= 0; /* Aap nul into input buffer at non-alnum. */
4367 if (! ( streq (*str
, "acc0") || streq (*str
, "ACC0")))
4369 sprintf (buff
, _("acc0 expected, not '%.100s'"), *str
);
4374 *p
= c
; /* Unzap. */
4375 *str
= p
; /* Caller's string pointer to after match. */
4379 /* Expects **str -> after a comma. May be leading blanks.
4380 Advances *str, recognizing a load mode, and setting inst.instruction.
4381 Returns rn, or else FAIL (in which case may set inst.error
4382 and not advance str)
4384 Note: doesn't know Rd, so no err checks that require such knowledge. */
4387 ld_mode_required_here (string
)
4390 char * str
= * string
;
4394 skip_whitespace (str
);
4400 skip_whitespace (str
);
4402 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
4405 skip_whitespace (str
);
4411 if (skip_past_comma (& str
) == SUCCESS
)
4413 /* [Rn],... (post inc) */
4414 if (ldst_extend_v4 (&str
) == FAIL
)
4419 skip_whitespace (str
);
4424 inst
.instruction
|= WRITE_BACK
;
4427 inst
.instruction
|= INDEX_UP
| HWOFFSET_IMM
;
4433 if (skip_past_comma (& str
) == FAIL
)
4435 inst
.error
= _("pre-indexed expression expected");
4441 if (ldst_extend_v4 (&str
) == FAIL
)
4444 skip_whitespace (str
);
4446 if (* str
++ != ']')
4448 inst
.error
= _("missing ]");
4452 skip_whitespace (str
);
4457 inst
.instruction
|= WRITE_BACK
;
4461 else if (* str
== '=') /* ldr's "r,=label" syntax */
4462 /* We should never reach here, because <text> = <expression> is
4463 caught gas/read.c read_a_source_file() as a .set operation. */
4465 else /* PC +- 8 bit immediate offset. */
4467 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4470 inst
.instruction
|= HWOFFSET_IMM
; /* The I bit. */
4471 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
4472 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
4473 inst
.reloc
.pc_rel
= 1;
4474 inst
.instruction
|= (REG_PC
<< 16);
4480 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
4486 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
4487 SMLAxy{cond} Rd,Rm,Rs,Rn
4488 SMLAWy{cond} Rd,Rm,Rs,Rn
4489 Error if any register is R15. */
4497 skip_whitespace (str
);
4499 if ((rd
= reg_required_here (& str
, 16)) == FAIL
4500 || skip_past_comma (& str
) == FAIL
4501 || (rm
= reg_required_here (& str
, 0)) == FAIL
4502 || skip_past_comma (& str
) == FAIL
4503 || (rs
= reg_required_here (& str
, 8)) == FAIL
4504 || skip_past_comma (& str
) == FAIL
4505 || (rn
= reg_required_here (& str
, 12)) == FAIL
)
4506 inst
.error
= BAD_ARGS
;
4508 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
|| rn
== REG_PC
)
4509 inst
.error
= BAD_PC
;
4515 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
4516 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
4517 Error if any register is R15.
4518 Warning if Rdlo == Rdhi. */
4524 int rdlo
, rdhi
, rm
, rs
;
4526 skip_whitespace (str
);
4528 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
4529 || skip_past_comma (& str
) == FAIL
4530 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
4531 || skip_past_comma (& str
) == FAIL
4532 || (rm
= reg_required_here (& str
, 0)) == FAIL
4533 || skip_past_comma (& str
) == FAIL
4534 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
4536 inst
.error
= BAD_ARGS
;
4540 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
4542 inst
.error
= BAD_PC
;
4547 as_tsktsk (_("rdhi and rdlo must be different"));
4552 /* ARM V5E (El Segundo) signed-multiply (argument parse)
4553 SMULxy{cond} Rd,Rm,Rs
4554 Error if any register is R15. */
4562 skip_whitespace (str
);
4564 if ((rd
= reg_required_here (& str
, 16)) == FAIL
4565 || skip_past_comma (& str
) == FAIL
4566 || (rm
= reg_required_here (& str
, 0)) == FAIL
4567 || skip_past_comma (& str
) == FAIL
4568 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
4569 inst
.error
= BAD_ARGS
;
4571 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
4572 inst
.error
= BAD_PC
;
4578 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
4579 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
4580 Error if any register is R15. */
4588 skip_whitespace (str
);
4590 if ((rd
= reg_required_here (& str
, 12)) == FAIL
4591 || skip_past_comma (& str
) == FAIL
4592 || (rm
= reg_required_here (& str
, 0)) == FAIL
4593 || skip_past_comma (& str
) == FAIL
4594 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
4595 inst
.error
= BAD_ARGS
;
4597 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
4598 inst
.error
= BAD_PC
;
4604 /* ARM V5E (el Segundo)
4605 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4606 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4608 These are equivalent to the XScale instructions MAR and MRA,
4609 respectively, when coproc == 0, opcode == 0, and CRm == 0.
4611 Result unpredicatable if Rd or Rn is R15. */
4619 skip_whitespace (str
);
4621 if (co_proc_number (& str
) == FAIL
)
4624 inst
.error
= BAD_ARGS
;
4628 if (skip_past_comma (& str
) == FAIL
4629 || cp_opc_expr (& str
, 4, 4) == FAIL
)
4632 inst
.error
= BAD_ARGS
;
4636 if (skip_past_comma (& str
) == FAIL
4637 || (rd
= reg_required_here (& str
, 12)) == FAIL
)
4640 inst
.error
= BAD_ARGS
;
4644 if (skip_past_comma (& str
) == FAIL
4645 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
4648 inst
.error
= BAD_ARGS
;
4652 /* Unpredictable result if rd or rn is R15. */
4653 if (rd
== REG_PC
|| rn
== REG_PC
)
4655 (_("Warning: instruction unpredictable when using r15"));
4657 if (skip_past_comma (& str
) == FAIL
4658 || cp_reg_required_here (& str
, 0) == FAIL
)
4661 inst
.error
= BAD_ARGS
;
4668 /* ARM V5 count-leading-zeroes instruction (argument parse)
4669 CLZ{<cond>} <Rd>, <Rm>
4670 Condition defaults to COND_ALWAYS.
4671 Error if Rd or Rm are R15. */
4679 skip_whitespace (str
);
4681 if (((rd
= reg_required_here (& str
, 12)) == FAIL
)
4682 || (skip_past_comma (& str
) == FAIL
)
4683 || ((rm
= reg_required_here (& str
, 0)) == FAIL
))
4684 inst
.error
= BAD_ARGS
;
4686 else if (rd
== REG_PC
|| rm
== REG_PC
)
4687 inst
.error
= BAD_PC
;
4693 /* ARM V5 (argument parse)
4694 LDC2{L} <coproc>, <CRd>, <addressing mode>
4695 STC2{L} <coproc>, <CRd>, <addressing mode>
4696 Instruction is not conditional, and has 0xf in the condition field.
4697 Otherwise, it's the same as LDC/STC. */
4703 skip_whitespace (str
);
4705 if (co_proc_number (& str
) == FAIL
)
4708 inst
.error
= BAD_ARGS
;
4710 else if (skip_past_comma (& str
) == FAIL
4711 || cp_reg_required_here (& str
, 12) == FAIL
)
4714 inst
.error
= BAD_ARGS
;
4716 else if (skip_past_comma (& str
) == FAIL
4717 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
4720 inst
.error
= BAD_ARGS
;
4726 /* ARM V5 (argument parse)
4727 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
4728 Instruction is not conditional, and has 0xf in the condition field.
4729 Otherwise, it's the same as CDP. */
4735 skip_whitespace (str
);
4737 if (co_proc_number (& str
) == FAIL
)
4740 inst
.error
= BAD_ARGS
;
4744 if (skip_past_comma (& str
) == FAIL
4745 || cp_opc_expr (& str
, 20,4) == FAIL
)
4748 inst
.error
= BAD_ARGS
;
4752 if (skip_past_comma (& str
) == FAIL
4753 || cp_reg_required_here (& str
, 12) == FAIL
)
4756 inst
.error
= BAD_ARGS
;
4760 if (skip_past_comma (& str
) == FAIL
4761 || cp_reg_required_here (& str
, 16) == FAIL
)
4764 inst
.error
= BAD_ARGS
;
4768 if (skip_past_comma (& str
) == FAIL
4769 || cp_reg_required_here (& str
, 0) == FAIL
)
4772 inst
.error
= BAD_ARGS
;
4776 if (skip_past_comma (& str
) == SUCCESS
)
4778 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
4781 inst
.error
= BAD_ARGS
;
4789 /* ARM V5 (argument parse)
4790 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4791 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
4792 Instruction is not conditional, and has 0xf in the condition field.
4793 Otherwise, it's the same as MCR/MRC. */
4799 skip_whitespace (str
);
4801 if (co_proc_number (& str
) == FAIL
)
4804 inst
.error
= BAD_ARGS
;
4808 if (skip_past_comma (& str
) == FAIL
4809 || cp_opc_expr (& str
, 21, 3) == FAIL
)
4812 inst
.error
= BAD_ARGS
;
4816 if (skip_past_comma (& str
) == FAIL
4817 || reg_required_here (& str
, 12) == FAIL
)
4820 inst
.error
= BAD_ARGS
;
4824 if (skip_past_comma (& str
) == FAIL
4825 || cp_reg_required_here (& str
, 16) == FAIL
)
4828 inst
.error
= BAD_ARGS
;
4832 if (skip_past_comma (& str
) == FAIL
4833 || cp_reg_required_here (& str
, 0) == FAIL
)
4836 inst
.error
= BAD_ARGS
;
4840 if (skip_past_comma (& str
) == SUCCESS
)
4842 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
4845 inst
.error
= BAD_ARGS
;
4853 /* ARM v5TEJ. Jump to Jazelle code. */
4860 skip_whitespace (str
);
4862 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
4864 inst
.error
= BAD_ARGS
;
4868 /* Note - it is not illegal to do a "bxj pc". Useless, but not illegal. */
4870 as_tsktsk (_("use of r15 in bxj is not really useful"));
4875 /* ARM V6 umaal (argument parse). */
4882 int rdlo
, rdhi
, rm
, rs
;
4884 skip_whitespace (str
);
4885 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
4886 || skip_past_comma (& str
) == FAIL
4887 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
4888 || skip_past_comma (& str
) == FAIL
4889 || (rm
= reg_required_here (& str
, 0)) == FAIL
4890 || skip_past_comma (& str
) == FAIL
4891 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
4893 inst
.error
= BAD_ARGS
;
4897 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
4899 inst
.error
= BAD_PC
;
4906 /* ARM V6 strex (argument parse). */
4914 /* Parse Rd, Rm,. */
4915 skip_whitespace (str
);
4916 if ((rd
= reg_required_here (& str
, 12)) == FAIL
4917 || skip_past_comma (& str
) == FAIL
4918 || (rm
= reg_required_here (& str
, 0)) == FAIL
4919 || skip_past_comma (& str
) == FAIL
)
4921 inst
.error
= BAD_ARGS
;
4924 if (rd
== REG_PC
|| rm
== REG_PC
)
4926 inst
.error
= BAD_PC
;
4931 inst
.error
= _("Rd equal to Rm or Rn yields unpredictable results");
4935 /* Skip past '['. */
4936 if ((strlen (str
) >= 1)
4937 && strncmp (str
, "[", 1) == 0)
4939 skip_whitespace (str
);
4942 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
4944 inst
.error
= BAD_ARGS
;
4947 else if (rn
== REG_PC
)
4949 inst
.error
= BAD_PC
;
4954 inst
.error
= _("Rd equal to Rm or Rn yields unpredictable results");
4957 skip_whitespace (str
);
4959 /* Skip past ']'. */
4960 if ((strlen (str
) >= 1)
4961 && strncmp (str
, "]", 1) == 0)
4967 /* ARM V6 ssat (argument parse). */
4973 do_sat (&str
, /*bias=*/-1);
4977 /* ARM V6 usat (argument parse). */
4983 do_sat (&str
, /*bias=*/0);
4995 skip_whitespace (*str
);
4997 /* Parse <Rd>, field. */
4998 if ((rd
= reg_required_here (str
, 12)) == FAIL
4999 || skip_past_comma (str
) == FAIL
)
5001 inst
.error
= BAD_ARGS
;
5006 inst
.error
= BAD_PC
;
5010 /* Parse #<immed>, field. */
5011 if (is_immediate_prefix (**str
))
5015 inst
.error
= _("immediate expression expected");
5018 if (my_get_expression (&expr
, str
))
5020 inst
.error
= _("bad expression");
5023 if (expr
.X_op
!= O_constant
)
5025 inst
.error
= _("constant expression expected");
5028 if (expr
.X_add_number
+ bias
< 0
5029 || expr
.X_add_number
+ bias
> 31)
5031 inst
.error
= _("immediate value out of range");
5034 inst
.instruction
|= (expr
.X_add_number
+ bias
) << 16;
5035 if (skip_past_comma (str
) == FAIL
)
5037 inst
.error
= BAD_ARGS
;
5041 /* Parse <Rm> field. */
5042 if ((rm
= reg_required_here (str
, 0)) == FAIL
)
5044 inst
.error
= BAD_ARGS
;
5049 inst
.error
= BAD_PC
;
5053 if (skip_past_comma (str
) == SUCCESS
)
5054 decode_shift (str
, SHIFT_LSL_OR_ASR_IMMEDIATE
);
5057 /* ARM V6 ssat16 (argument parse). */
5063 do_sat16 (&str
, /*bias=*/-1);
5071 do_sat16 (&str
, /*bias=*/0);
5076 do_sat16 (str
, bias
)
5083 skip_whitespace (*str
);
5085 /* Parse the <Rd> field. */
5086 if ((rd
= reg_required_here (str
, 12)) == FAIL
5087 || skip_past_comma (str
) == FAIL
)
5089 inst
.error
= BAD_ARGS
;
5094 inst
.error
= BAD_PC
;
5098 /* Parse #<immed>, field. */
5099 if (is_immediate_prefix (**str
))
5103 inst
.error
= _("immediate expression expected");
5106 if (my_get_expression (&expr
, str
))
5108 inst
.error
= _("bad expression");
5111 if (expr
.X_op
!= O_constant
)
5113 inst
.error
= _("constant expression expected");
5116 if (expr
.X_add_number
+ bias
< 0
5117 || expr
.X_add_number
+ bias
> 15)
5119 inst
.error
= _("immediate value out of range");
5122 inst
.instruction
|= (expr
.X_add_number
+ bias
) << 16;
5123 if (skip_past_comma (str
) == FAIL
)
5125 inst
.error
= BAD_ARGS
;
5129 /* Parse <Rm> field. */
5130 if ((rm
= reg_required_here (str
, 0)) == FAIL
)
5132 inst
.error
= BAD_ARGS
;
5137 inst
.error
= BAD_PC
;
5142 /* ARM V6 srs (argument parse). */
5149 skip_whitespace (str
);
5150 exclam
= strchr (str
, '!');
5158 inst
.instruction
|= WRITE_BACK
;
5164 /* ARM V6 SMMUL (argument parse). */
5172 skip_whitespace (str
);
5173 if ((rd
= reg_required_here (&str
, 16)) == FAIL
5174 || skip_past_comma (&str
) == FAIL
5175 || (rm
= reg_required_here (&str
, 0)) == FAIL
5176 || skip_past_comma (&str
) == FAIL
5177 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
5179 inst
.error
= BAD_ARGS
;
5187 inst
.error
= BAD_PC
;
5195 /* ARM V6 SMLALD (argument parse). */
5201 int rdlo
, rdhi
, rm
, rs
;
5202 skip_whitespace (str
);
5203 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
5204 || skip_past_comma (&str
) == FAIL
5205 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
5206 || skip_past_comma (&str
) == FAIL
5207 || (rm
= reg_required_here (&str
, 0)) == FAIL
5208 || skip_past_comma (&str
) == FAIL
5209 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
5211 inst
.error
= BAD_ARGS
;
5220 inst
.error
= BAD_PC
;
5227 /* ARM V6 SMLAD (argument parse). Signed multiply accumulate dual.
5228 smlad{x}{<cond>} Rd, Rm, Rs, Rn */
5236 skip_whitespace (str
);
5237 if ((rd
= reg_required_here (&str
, 16)) == FAIL
5238 || skip_past_comma (&str
) == FAIL
5239 || (rm
= reg_required_here (&str
, 0)) == FAIL
5240 || skip_past_comma (&str
) == FAIL
5241 || (rs
= reg_required_here (&str
, 8)) == FAIL
5242 || skip_past_comma (&str
) == FAIL
5243 || (rn
= reg_required_here (&str
, 12)) == FAIL
)
5245 inst
.error
= BAD_ARGS
;
5254 inst
.error
= BAD_PC
;
5261 /* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
5262 preserving the other bits.
5264 setend <endian_specifier>, where <endian_specifier> is either
5271 if (do_endian_specifier (str
))
5272 inst
.instruction
|= 0x200;
5275 /* Returns true if the endian-specifier indicates big-endianness. */
5278 do_endian_specifier (str
)
5283 skip_whitespace (str
);
5284 if (strlen (str
) < 2)
5285 inst
.error
= _("missing endian specifier");
5286 else if (strncasecmp (str
, "BE", 2) == 0)
5291 else if (strncasecmp (str
, "LE", 2) == 0)
5294 inst
.error
= _("valid endian specifiers are be or le");
5303 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
5304 Condition defaults to COND_ALWAYS.
5305 Error if any register uses R15. */
5313 int rotation_clear_mask
= 0xfffff3ff;
5314 int rotation_eight_mask
= 0x00000400;
5315 int rotation_sixteen_mask
= 0x00000800;
5316 int rotation_twenty_four_mask
= 0x00000c00;
5318 skip_whitespace (str
);
5319 if ((rd
= reg_required_here (&str
, 12)) == FAIL
5320 || skip_past_comma (&str
) == FAIL
5321 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
5323 inst
.error
= BAD_ARGS
;
5327 else if (rd
== REG_PC
|| rm
== REG_PC
)
5329 inst
.error
= BAD_PC
;
5333 /* Zero out the rotation field. */
5334 inst
.instruction
&= rotation_clear_mask
;
5336 /* Check for lack of optional rotation field. */
5337 if (skip_past_comma (&str
) == FAIL
)
5343 /* Move past 'ROR'. */
5344 skip_whitespace (str
);
5345 if (strncasecmp (str
, "ROR", 3) == 0)
5349 inst
.error
= _("missing rotation field after comma");
5353 /* Get the immediate constant. */
5354 skip_whitespace (str
);
5355 if (is_immediate_prefix (* str
))
5359 inst
.error
= _("immediate expression expected");
5363 if (my_get_expression (&expr
, &str
))
5365 inst
.error
= _("bad expression");
5369 if (expr
.X_op
!= O_constant
)
5371 inst
.error
= _("constant expression expected");
5375 switch (expr
.X_add_number
)
5378 /* Rotation field has already been zeroed. */
5381 inst
.instruction
|= rotation_eight_mask
;
5385 inst
.instruction
|= rotation_sixteen_mask
;
5389 inst
.instruction
|= rotation_twenty_four_mask
;
5393 inst
.error
= _("rotation can be 8, 16, 24 or 0 when field is ommited");
5401 /* ARM V6 SXTAH extracts a 16-bit value from a register, sign
5402 extends it to 32-bits, and adds the result to a value in another
5403 register. You can specify a rotation by 0, 8, 16, or 24 bits
5404 before extracting the 16-bit value.
5405 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
5406 Condition defaults to COND_ALWAYS.
5407 Error if any register uses R15. */
5415 int rotation_clear_mask
= 0xfffff3ff;
5416 int rotation_eight_mask
= 0x00000400;
5417 int rotation_sixteen_mask
= 0x00000800;
5418 int rotation_twenty_four_mask
= 0x00000c00;
5420 skip_whitespace (str
);
5421 if ((rd
= reg_required_here (&str
, 12)) == FAIL
5422 || skip_past_comma (&str
) == FAIL
5423 || (rn
= reg_required_here (&str
, 16)) == FAIL
5424 || skip_past_comma (&str
) == FAIL
5425 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
5427 inst
.error
= BAD_ARGS
;
5431 else if (rd
== REG_PC
|| rn
== REG_PC
|| rm
== REG_PC
)
5433 inst
.error
= BAD_PC
;
5437 /* Zero out the rotation field. */
5438 inst
.instruction
&= rotation_clear_mask
;
5440 /* Check for lack of optional rotation field. */
5441 if (skip_past_comma (&str
) == FAIL
)
5447 /* Move past 'ROR'. */
5448 skip_whitespace (str
);
5449 if (strncasecmp (str
, "ROR", 3) == 0)
5453 inst
.error
= _("missing rotation field after comma");
5457 /* Get the immediate constant. */
5458 skip_whitespace (str
);
5459 if (is_immediate_prefix (* str
))
5463 inst
.error
= _("immediate expression expected");
5467 if (my_get_expression (&expr
, &str
))
5469 inst
.error
= _("bad expression");
5473 if (expr
.X_op
!= O_constant
)
5475 inst
.error
= _("constant expression expected");
5479 switch (expr
.X_add_number
)
5482 /* Rotation field has already been zeroed. */
5486 inst
.instruction
|= rotation_eight_mask
;
5490 inst
.instruction
|= rotation_sixteen_mask
;
5494 inst
.instruction
|= rotation_twenty_four_mask
;
5498 inst
.error
= _("rotation can be 8, 16, 24 or 0 when field is ommited");
5507 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
5508 word at the specified address and the following word
5510 Unconditionally executed.
5520 skip_whitespace (str
);
5522 if ((rn
= reg_required_here (&str
, 16)) == FAIL
)
5527 inst
.error
= BAD_PC
;
5531 skip_whitespace (str
);
5535 inst
.instruction
|= WRITE_BACK
;
5541 /* ARM V6 REV (Byte Reverse Word) reverses the byte order in a 32-bit
5542 register (argument parse).
5544 Condition defaults to COND_ALWAYS.
5545 Error if Rd or Rm are R15. */
5553 skip_whitespace (str
);
5555 if ((rd
= reg_required_here (&str
, 12)) == FAIL
5556 || skip_past_comma (&str
) == FAIL
5557 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
5558 inst
.error
= BAD_ARGS
;
5560 else if (rd
== REG_PC
|| rm
== REG_PC
)
5561 inst
.error
= BAD_PC
;
5567 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
5568 QADD16{<cond>} <Rd>, <Rn>, <Rm>
5569 Condition defaults to COND_ALWAYS.
5570 Error if Rd, Rn or Rm are R15. */
5578 skip_whitespace (str
);
5580 if ((rd
= reg_required_here (&str
, 12)) == FAIL
5581 || skip_past_comma (&str
) == FAIL
5582 || (rn
= reg_required_here (&str
, 16)) == FAIL
5583 || skip_past_comma (&str
) == FAIL
5584 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
5585 inst
.error
= BAD_ARGS
;
5587 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
5588 inst
.error
= BAD_PC
;
5594 /* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
5595 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
5596 Condition defaults to COND_ALWAYS.
5597 Error if Rd, Rn or Rm are R15. */
5603 do_pkh_core (str
, SHIFT_LSL_IMMEDIATE
);
5606 /* ARM V6 PKHTB (Argument Parse). */
5612 do_pkh_core (str
, SHIFT_ASR_IMMEDIATE
);
5616 do_pkh_core (str
, shift
)
5622 skip_whitespace (str
);
5623 if (((rd
= reg_required_here (&str
, 12)) == FAIL
)
5624 || (skip_past_comma (&str
) == FAIL
)
5625 || ((rn
= reg_required_here (&str
, 16)) == FAIL
)
5626 || (skip_past_comma (&str
) == FAIL
)
5627 || ((rm
= reg_required_here (&str
, 0)) == FAIL
))
5629 inst
.error
= BAD_ARGS
;
5633 else if (rd
== REG_PC
|| rn
== REG_PC
|| rm
== REG_PC
)
5635 inst
.error
= BAD_PC
;
5639 /* Check for optional shift immediate constant. */
5640 if (skip_past_comma (&str
) == FAIL
)
5642 if (shift
== SHIFT_ASR_IMMEDIATE
)
5644 /* If the shift specifier is ommited, turn the instruction
5645 into pkhbt rd, rm, rn. First, switch the instruction
5646 code, and clear the rn and rm fields. */
5647 inst
.instruction
&= 0xfff0f010;
5648 /* Now, re-encode the registers. */
5649 inst
.instruction
|= (rm
<< 16) | rn
;
5654 decode_shift (&str
, shift
);
5657 /* ARM V6 Load Register Exclusive instruction (argument parse).
5658 LDREX{<cond>} <Rd, [<Rn>]
5659 Condition defaults to COND_ALWAYS.
5660 Error if Rd or Rn are R15.
5661 See ARMARMv6 A4.1.27: LDREX. */
5670 skip_whitespace (str
);
5673 if (((rd
= reg_required_here (&str
, 12)) == FAIL
)
5674 || (skip_past_comma (&str
) == FAIL
))
5676 inst
.error
= BAD_ARGS
;
5679 else if (rd
== REG_PC
)
5681 inst
.error
= BAD_PC
;
5684 skip_whitespace (str
);
5686 /* Skip past '['. */
5687 if ((strlen (str
) >= 1)
5688 &&strncmp (str
, "[", 1) == 0)
5690 skip_whitespace (str
);
5693 if ((rn
= reg_required_here (&str
, 16)) == FAIL
)
5695 inst
.error
= BAD_ARGS
;
5698 else if (rn
== REG_PC
)
5700 inst
.error
= BAD_PC
;
5703 skip_whitespace (str
);
5705 /* Skip past ']'. */
5706 if ((strlen (str
) >= 1)
5707 && strncmp (str
, "]", 1) == 0)
5713 /* ARM V6 change processor state instruction (argument parse)
5714 CPS, CPSIE, CSPID . */
5728 do_cps_flags (&str
, /*thumb_p=*/0);
5730 if (skip_past_comma (&str
) == SUCCESS
)
5732 skip_whitespace (str
);
5744 skip_whitespace (*str
);
5746 if (! is_immediate_prefix (**str
))
5748 inst
.error
= _("immediate expression expected");
5752 (*str
)++; /* Strip off the immediate signifier. */
5753 if (my_get_expression (&expr
, str
))
5755 inst
.error
= _("bad expression");
5759 if (expr
.X_op
!= O_constant
)
5761 inst
.error
= _("constant expression expected");
5765 /* The mode is a 5 bit field. Valid values are 0-31. */
5766 if (((unsigned) expr
.X_add_number
) > 31
5767 || (inst
.reloc
.exp
.X_add_number
) < 0)
5769 inst
.error
= _("invalid constant");
5773 inst
.instruction
|= expr
.X_add_number
;
5777 do_cps_flags (str
, thumb_p
)
5783 unsigned long arm_value
;
5784 unsigned long thumb_value
;
5786 static struct cps_flag flag_table
[] = {
5794 skip_whitespace (*str
);
5796 /* Get the a, f and i flags. */
5797 while (**str
&& **str
!= ',')
5800 struct cps_flag
*q
= flag_table
+ sizeof (flag_table
)/sizeof (*p
);
5801 for (p
= flag_table
; p
< q
; ++p
)
5802 if (strncasecmp (*str
, &p
->character
, 1) == 0)
5804 inst
.instruction
|= (thumb_p
? p
->thumb_value
: p
->arm_value
);
5810 inst
.error
= _("unrecognized flag");
5816 inst
.error
= _("no 'a', 'i', or 'f' flags for 'cps'");
5819 /* THUMB V5 breakpoint instruction (argument parse)
5827 unsigned long number
;
5829 skip_whitespace (str
);
5831 /* Allow optional leading '#'. */
5832 if (is_immediate_prefix (*str
))
5835 memset (& expr
, '\0', sizeof (expr
));
5836 if (my_get_expression (& expr
, & str
)
5837 || (expr
.X_op
!= O_constant
5838 /* As a convenience we allow 'bkpt' without an operand. */
5839 && expr
.X_op
!= O_absent
))
5841 inst
.error
= _("bad expression");
5845 number
= expr
.X_add_number
;
5847 /* Check it fits an 8 bit unsigned. */
5848 if (number
!= (number
& 0xff))
5850 inst
.error
= _("immediate value out of range");
5854 inst
.instruction
|= number
;
5859 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
5860 Expects inst.instruction is set for BLX(1).
5861 Note: this is cloned from do_branch, and the reloc changed to be a
5862 new one that can cope with setting one extra bit (the H bit). */
5868 if (my_get_expression (& inst
.reloc
.exp
, & str
))
5875 /* ScottB: February 5, 1998 */
5876 /* Check to see of PLT32 reloc required for the instruction. */
5878 /* arm_parse_reloc() works on input_line_pointer.
5879 We actually want to parse the operands to the branch instruction
5880 passed in 'str'. Save the input pointer and restore it later. */
5881 save_in
= input_line_pointer
;
5882 input_line_pointer
= str
;
5884 if (inst
.reloc
.exp
.X_op
== O_symbol
5886 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
5888 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
5889 inst
.reloc
.pc_rel
= 0;
5890 /* Modify str to point to after parsed operands, otherwise
5891 end_of_line() will complain about the (PLT) left in str. */
5892 str
= input_line_pointer
;
5896 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
5897 inst
.reloc
.pc_rel
= 1;
5900 input_line_pointer
= save_in
;
5903 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
5904 inst
.reloc
.pc_rel
= 1;
5905 #endif /* OBJ_ELF */
5910 /* ARM V5 branch-link-exchange instruction (argument parse)
5911 BLX <target_addr> ie BLX(1)
5912 BLX{<condition>} <Rm> ie BLX(2)
5913 Unfortunately, there are two different opcodes for this mnemonic.
5914 So, the insns[].value is not used, and the code here zaps values
5915 into inst.instruction.
5916 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
5925 skip_whitespace (mystr
);
5926 rm
= reg_required_here (& mystr
, 0);
5928 /* The above may set inst.error. Ignore his opinion. */
5933 /* Arg is a register.
5934 Use the condition code our caller put in inst.instruction.
5935 Pass ourselves off as a BX with a funny opcode. */
5936 inst
.instruction
|= 0x012fff30;
5941 /* This must be is BLX <target address>, no condition allowed. */
5942 if (inst
.instruction
!= COND_ALWAYS
)
5944 inst
.error
= BAD_COND
;
5948 inst
.instruction
= 0xfafffffe;
5950 /* Process like a B/BL, but with a different reloc.
5951 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
5956 /* ARM V5 Thumb BLX (argument parse)
5957 BLX <target_addr> which is BLX(1)
5958 BLX <Rm> which is BLX(2)
5959 Unfortunately, there are two different opcodes for this mnemonic.
5960 So, the tinsns[].value is not used, and the code here zaps values
5961 into inst.instruction. */
5970 skip_whitespace (mystr
);
5971 inst
.instruction
= 0x4780;
5973 /* Note that this call is to the ARM register recognizer. BLX(2)
5974 uses the ARM register space, not the Thumb one, so a call to
5975 thumb_reg() would be wrong. */
5976 rm
= reg_required_here (& mystr
, 3);
5981 /* It's BLX(2). The .instruction was zapped with rm & is final. */
5986 /* No ARM register. This must be BLX(1). Change the .instruction. */
5987 inst
.instruction
= 0xf7ffeffe;
5990 if (my_get_expression (& inst
.reloc
.exp
, & mystr
))
5993 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BLX
;
5994 inst
.reloc
.pc_rel
= 1;
5997 end_of_line (mystr
);
6000 /* ARM V5 breakpoint instruction (argument parse)
6001 BKPT <16 bit unsigned immediate>
6002 Instruction is not conditional.
6003 The bit pattern given in insns[] has the COND_ALWAYS condition,
6004 and it is an error if the caller tried to override that. */
6011 unsigned long number
;
6013 skip_whitespace (str
);
6015 /* Allow optional leading '#'. */
6016 if (is_immediate_prefix (* str
))
6019 memset (& expr
, '\0', sizeof (expr
));
6021 if (my_get_expression (& expr
, & str
)
6022 || (expr
.X_op
!= O_constant
6023 /* As a convenience we allow 'bkpt' without an operand. */
6024 && expr
.X_op
!= O_absent
))
6026 inst
.error
= _("bad expression");
6030 number
= expr
.X_add_number
;
6032 /* Check it fits a 16 bit unsigned. */
6033 if (number
!= (number
& 0xffff))
6035 inst
.error
= _("immediate value out of range");
6039 /* Top 12 of 16 bits to bits 19:8. */
6040 inst
.instruction
|= (number
& 0xfff0) << 4;
6042 /* Bottom 4 of 16 bits to bits 3:0. */
6043 inst
.instruction
|= number
& 0xf;
6048 /* THUMB CPS instruction (argument parse). */
6054 do_cps_flags (&str
, /*thumb_p=*/1);
6058 /* THUMB CPY instruction (argument parse). */
6064 thumb_mov_compare (str
, THUMB_CPY
);
6067 /* THUMB SETEND instruction (argument parse). */
6073 if (do_endian_specifier (str
))
6074 inst
.instruction
|= 0x8;
6077 static unsigned long check_iwmmxt_insn
PARAMS ((char *, enum iwmmxt_insn_type
, int));
6079 /* Parse INSN_TYPE insn STR having a possible IMMEDIATE_SIZE immediate. */
6081 static unsigned long
6082 check_iwmmxt_insn (str
, insn_type
, immediate_size
)
6084 enum iwmmxt_insn_type insn_type
;
6088 const char * inst_error
;
6090 unsigned long number
;
6092 inst_error
= inst
.error
;
6094 inst
.error
= BAD_ARGS
;
6095 skip_whitespace (str
);
6100 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
6105 if ((wreg_required_here (&str
, 0, IWMMXT_REG_WR
)) == FAIL
)
6110 if ((wreg_required_here (&str
, 12, IWMMXT_REG_WR
) == FAIL
6111 || skip_past_comma (&str
) == FAIL
6112 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
))
6117 if ((wreg_required_here (&str
, 12, IWMMXT_REG_WR
) == FAIL
6118 || skip_past_comma (&str
) == FAIL
6119 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6120 || skip_past_comma (&str
) == FAIL
6121 || wreg_required_here (&str
, 0, IWMMXT_REG_WR
) == FAIL
))
6126 if ((wreg_required_here (&str
, 12, IWMMXT_REG_WR
) == FAIL
6127 || skip_past_comma (&str
) == FAIL
6128 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6129 || skip_past_comma (&str
) == FAIL
6130 || wreg_required_here (&str
, 0, IWMMXT_REG_WCG
) == FAIL
))
6135 if ((wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6136 || skip_past_comma (&str
) == FAIL
6137 || reg_required_here (&str
, 12) == FAIL
))
6142 if ((reg_required_here (&str
, 12) == FAIL
6143 || skip_past_comma (&str
) == FAIL
6144 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
))
6149 if ((wreg_required_here (&str
, 5, IWMMXT_REG_WR
) == FAIL
6150 || skip_past_comma (&str
) == FAIL
6151 || reg_required_here (&str
, 0) == FAIL
6152 || skip_past_comma (&str
) == FAIL
6153 || reg_required_here (&str
, 12) == FAIL
))
6158 if ((wreg_required_here (&str
, 0, IWMMXT_REG_WR
) == FAIL
6159 || skip_past_comma (&str
) == FAIL
6160 || reg_required_here (&str
, 12) == FAIL
6161 || skip_past_comma (&str
) == FAIL
6162 || reg_required_here (&str
, 16) == FAIL
))
6167 if ((reg_required_here (&str
, 12) == FAIL
6168 || skip_past_comma (&str
) == FAIL
6169 || reg_required_here (&str
, 16) == FAIL
6170 || skip_past_comma (&str
) == FAIL
6171 || wreg_required_here (&str
, 0, IWMMXT_REG_WR
) == FAIL
))
6176 if ((wreg_required_here (&str
, 16, IWMMXT_REG_WC
) == FAIL
6177 || skip_past_comma (&str
) == FAIL
6178 || reg_required_here (&str
, 12) == FAIL
))
6183 if ((reg_required_here (&str
, 12) == FAIL
6184 || skip_past_comma (&str
) == FAIL
6185 || wreg_required_here (&str
, 16, IWMMXT_REG_WC
) == FAIL
))
6190 if ((wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6191 || skip_past_comma (&str
) == FAIL
6192 || reg_required_here (&str
, 12) == FAIL
6193 || skip_past_comma (&str
) == FAIL
))
6198 if ((reg_required_here (&str
, 12) == FAIL
6199 || skip_past_comma (&str
) == FAIL
))
6204 if ((wreg_required_here (&str
, 12, IWMMXT_REG_WR
) == FAIL
6205 || skip_past_comma (&str
) == FAIL
6206 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6207 || skip_past_comma (&str
) == FAIL
6208 || wreg_required_here (&str
, 0, IWMMXT_REG_WR
) == FAIL
6209 || skip_past_comma (&str
) == FAIL
))
6214 if ((reg_required_here (&str
, 12) == FAIL
6215 || skip_past_comma (&str
) == FAIL
6216 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6217 || skip_past_comma (&str
) == FAIL
))
6222 if ((wreg_required_here (&str
, 12, IWMMXT_REG_WR
) == FAIL
6223 || skip_past_comma (&str
) == FAIL
6224 || wreg_required_here (&str
, 16, IWMMXT_REG_WR
) == FAIL
6225 || skip_past_comma (&str
) == FAIL
))
6230 if (immediate_size
== 0)
6233 inst
.error
= inst_error
;
6238 skip_whitespace (str
);
6240 /* Allow optional leading '#'. */
6241 if (is_immediate_prefix (* str
))
6244 memset (& expr
, '\0', sizeof (expr
));
6246 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
6248 inst
.error
= _("bad or missing expression");
6252 number
= expr
.X_add_number
;
6254 if (number
!= (number
& immediate_size
))
6256 inst
.error
= _("immediate value out of range");
6260 inst
.error
= inst_error
;
6266 do_iwmmxt_byte_addr (str
)
6269 int op
= (inst
.instruction
& 0x300) >> 8;
6272 inst
.instruction
&= ~0x300;
6273 inst
.instruction
|= (op
& 1) << 22 | (op
& 2) << 7;
6275 skip_whitespace (str
);
6277 if ((reg
= wreg_required_here (&str
, 12, IWMMXT_REG_WR_OR_WC
)) == FAIL
6278 || skip_past_comma (& str
) == FAIL
6279 || cp_byte_address_required_here (&str
) == FAIL
)
6282 inst
.error
= BAD_ARGS
;
6287 if (wc_register (reg
))
6289 as_bad (_("non-word size not supported with control register"));
6290 inst
.instruction
|= 0xf0000100;
6291 inst
.instruction
&= ~0x00400000;
6296 do_iwmmxt_tandc (str
)
6301 reg
= check_iwmmxt_insn (str
, check_rd
, 0);
6303 if (reg
!= REG_PC
&& !inst
.error
)
6304 inst
.error
= _("only r15 allowed here");
6308 do_iwmmxt_tbcst (str
)
6311 check_iwmmxt_insn (str
, check_tbcst
, 0);
6315 do_iwmmxt_textrc (str
)
6318 unsigned long number
;
6320 if ((number
= check_iwmmxt_insn (str
, check_textrc
, 7)) == (unsigned long) FAIL
)
6323 inst
.instruction
|= number
& 0x7;
6327 do_iwmmxt_textrm (str
)
6330 unsigned long number
;
6332 if ((number
= check_iwmmxt_insn (str
, check_textrm
, 7)) == (unsigned long) FAIL
)
6335 inst
.instruction
|= number
& 0x7;
6339 do_iwmmxt_tinsr (str
)
6342 unsigned long number
;
6344 if ((number
= check_iwmmxt_insn (str
, check_tinsr
, 7)) == (unsigned long) FAIL
)
6347 inst
.instruction
|= number
& 0x7;
6351 do_iwmmxt_tmcr (str
)
6354 check_iwmmxt_insn (str
, check_tmcr
, 0);
6358 do_iwmmxt_tmcrr (str
)
6361 check_iwmmxt_insn (str
, check_tmcrr
, 0);
6365 do_iwmmxt_tmia (str
)
6368 check_iwmmxt_insn (str
, check_tmia
, 0);
6372 do_iwmmxt_tmovmsk (str
)
6375 check_iwmmxt_insn (str
, check_tmovmsk
, 0);
6379 do_iwmmxt_tmrc (str
)
6382 check_iwmmxt_insn (str
, check_tmrc
, 0);
6386 do_iwmmxt_tmrrc (str
)
6389 check_iwmmxt_insn (str
, check_tmrrc
, 0);
6393 do_iwmmxt_torc (str
)
6396 check_iwmmxt_insn (str
, check_rd
, 0);
6400 do_iwmmxt_waligni (str
)
6403 unsigned long number
;
6405 if ((number
= check_iwmmxt_insn (str
, check_waligni
, 7)) == (unsigned long) FAIL
)
6408 inst
.instruction
|= ((number
& 0x7) << 20);
6412 do_iwmmxt_wmov (str
)
6415 if (check_iwmmxt_insn (str
, check_wrwr
, 0) == (unsigned long) FAIL
)
6418 inst
.instruction
|= ((inst
.instruction
>> 16) & 0xf);
6422 do_iwmmxt_word_addr (str
)
6425 int op
= (inst
.instruction
& 0x300) >> 8;
6428 inst
.instruction
&= ~0x300;
6429 inst
.instruction
|= (op
& 1) << 22 | (op
& 2) << 7;
6431 skip_whitespace (str
);
6433 if ((reg
= wreg_required_here (&str
, 12, IWMMXT_REG_WR_OR_WC
)) == FAIL
6434 || skip_past_comma (& str
) == FAIL
6435 || cp_address_required_here (& str
, CP_WB_OK
) == FAIL
)
6438 inst
.error
= BAD_ARGS
;
6443 if (wc_register (reg
))
6445 if ((inst
.instruction
& COND_MASK
) != COND_ALWAYS
)
6446 as_bad (_("conditional execution not supported with control register"));
6448 as_bad (_("non-word size not supported with control register"));
6449 inst
.instruction
|= 0xf0000100;
6450 inst
.instruction
&= ~0x00400000;
6455 do_iwmmxt_wrwr (str
)
6458 check_iwmmxt_insn (str
, check_wrwr
, 0);
6462 do_iwmmxt_wrwrwcg (str
)
6465 check_iwmmxt_insn (str
, check_wrwrwcg
, 0);
6469 do_iwmmxt_wrwrwr (str
)
6472 check_iwmmxt_insn (str
, check_wrwrwr
, 0);
6476 do_iwmmxt_wshufh (str
)
6479 unsigned long number
;
6481 if ((number
= check_iwmmxt_insn (str
, check_wshufh
, 0xff)) == (unsigned long) FAIL
)
6484 inst
.instruction
|= ((number
& 0xf0) << 16) | (number
& 0xf);
6488 do_iwmmxt_wzero (str
)
6491 if (check_iwmmxt_insn (str
, check_wr
, 0) == (unsigned long) FAIL
)
6494 inst
.instruction
|= ((inst
.instruction
& 0xf) << 12) | ((inst
.instruction
& 0xf) << 16);
6497 /* Xscale multiply-accumulate (argument parse)
6500 MIAxycc acc0,Rm,Rs. */
6509 if (accum0_required_here (& str
) == FAIL
)
6510 inst
.error
= ERR_NO_ACCUM
;
6512 else if (skip_past_comma (& str
) == FAIL
6513 || (rm
= reg_required_here (& str
, 0)) == FAIL
)
6514 inst
.error
= BAD_ARGS
;
6516 else if (skip_past_comma (& str
) == FAIL
6517 || (rs
= reg_required_here (& str
, 12)) == FAIL
)
6518 inst
.error
= BAD_ARGS
;
6520 /* inst.instruction has now been zapped with both rm and rs. */
6521 else if (rm
== REG_PC
|| rs
== REG_PC
)
6522 inst
.error
= BAD_PC
; /* Undefined result if rm or rs is R15. */
6528 /* Xscale move-accumulator-register (argument parse)
6530 MARcc acc0,RdLo,RdHi. */
6538 if (accum0_required_here (& str
) == FAIL
)
6539 inst
.error
= ERR_NO_ACCUM
;
6541 else if (skip_past_comma (& str
) == FAIL
6542 || (rdlo
= reg_required_here (& str
, 12)) == FAIL
)
6543 inst
.error
= BAD_ARGS
;
6545 else if (skip_past_comma (& str
) == FAIL
6546 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
6547 inst
.error
= BAD_ARGS
;
6549 /* inst.instruction has now been zapped with both rdlo and rdhi. */
6550 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
6551 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
6557 /* Xscale move-register-accumulator (argument parse)
6559 MRAcc RdLo,RdHi,acc0. */
6568 skip_whitespace (str
);
6570 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
)
6571 inst
.error
= BAD_ARGS
;
6573 else if (skip_past_comma (& str
) == FAIL
6574 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
6575 inst
.error
= BAD_ARGS
;
6577 else if (skip_past_comma (& str
) == FAIL
6578 || accum0_required_here (& str
) == FAIL
)
6579 inst
.error
= ERR_NO_ACCUM
;
6581 /* inst.instruction has now been zapped with both rdlo and rdhi. */
6582 else if (rdlo
== rdhi
)
6583 inst
.error
= BAD_ARGS
; /* Undefined result if 2 writes to same reg. */
6585 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
6586 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
6591 /* ARMv5TE: Preload-Cache
6595 Syntactically, like LDR with B=1, W=0, L=1. */
6603 skip_whitespace (str
);
6607 inst
.error
= _("'[' expected after PLD mnemonic");
6612 skip_whitespace (str
);
6614 if ((rd
= reg_required_here (& str
, 16)) == FAIL
)
6617 skip_whitespace (str
);
6623 skip_whitespace (str
);
6625 /* Post-indexed addressing is not allowed with PLD. */
6626 if (skip_past_comma (&str
) == SUCCESS
)
6629 = _("post-indexed expression used in preload instruction");
6632 else if (*str
== '!') /* [Rn]! */
6634 inst
.error
= _("writeback used in preload instruction");
6638 inst
.instruction
|= INDEX_UP
| PRE_INDEX
;
6640 else /* [Rn, ...] */
6642 if (skip_past_comma (& str
) == FAIL
)
6644 inst
.error
= _("pre-indexed expression expected");
6648 if (ldst_extend (&str
) == FAIL
)
6651 skip_whitespace (str
);
6655 inst
.error
= _("missing ]");
6660 skip_whitespace (str
);
6662 if (* str
== '!') /* [Rn]! */
6664 inst
.error
= _("writeback used in preload instruction");
6668 inst
.instruction
|= PRE_INDEX
;
6674 /* ARMv5TE load-consecutive (argument parse)
6687 skip_whitespace (str
);
6689 if ((rd
= reg_required_here (& str
, 12)) == FAIL
)
6691 inst
.error
= BAD_ARGS
;
6695 if (skip_past_comma (& str
) == FAIL
6696 || (rn
= ld_mode_required_here (& str
)) == FAIL
)
6699 inst
.error
= BAD_ARGS
;
6703 /* inst.instruction has now been zapped with Rd and the addressing mode. */
6704 if (rd
& 1) /* Unpredictable result if Rd is odd. */
6706 inst
.error
= _("destination register must be even");
6712 inst
.error
= _("r14 not allowed here");
6716 if (((rd
== rn
) || (rd
+ 1 == rn
))
6717 && ((inst
.instruction
& WRITE_BACK
)
6718 || (!(inst
.instruction
& PRE_INDEX
))))
6719 as_warn (_("pre/post-indexing used when modified address register is destination"));
6721 /* For an index-register load, the index register must not overlap the
6722 destination (even if not write-back). */
6723 if ((inst
.instruction
& V4_STR_BIT
) == 0
6724 && (inst
.instruction
& HWOFFSET_IMM
) == 0)
6726 int rm
= inst
.instruction
& 0x0000000f;
6728 if (rm
== rd
|| (rm
== rd
+ 1))
6729 as_warn (_("ldrd destination registers must not overlap index register"));
6735 /* Returns the index into fp_values of a floating point number,
6736 or -1 if not in the table. */
6739 my_get_float_expression (str
)
6742 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6748 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
6750 /* Look for a raw floating point number. */
6751 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
6752 && is_end_of_line
[(unsigned char) *save_in
])
6754 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
6756 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
6758 if (words
[j
] != fp_values
[i
][j
])
6762 if (j
== MAX_LITTLENUMS
)
6770 /* Try and parse a more complex expression, this will probably fail
6771 unless the code uses a floating point prefix (eg "0f"). */
6772 save_in
= input_line_pointer
;
6773 input_line_pointer
= *str
;
6774 if (expression (&exp
) == absolute_section
6775 && exp
.X_op
== O_big
6776 && exp
.X_add_number
< 0)
6778 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
6780 if (gen_to_words (words
, 5, (long) 15) == 0)
6782 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
6784 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
6786 if (words
[j
] != fp_values
[i
][j
])
6790 if (j
== MAX_LITTLENUMS
)
6792 *str
= input_line_pointer
;
6793 input_line_pointer
= save_in
;
6800 *str
= input_line_pointer
;
6801 input_line_pointer
= save_in
;
6805 /* Return TRUE if anything in the expression is a bignum. */
6808 walk_no_bignums (sp
)
6811 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
6814 if (symbol_get_value_expression (sp
)->X_add_symbol
)
6816 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
6817 || (symbol_get_value_expression (sp
)->X_op_symbol
6818 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
6824 static int in_my_get_expression
= 0;
6827 my_get_expression (ep
, str
)
6834 save_in
= input_line_pointer
;
6835 input_line_pointer
= *str
;
6836 in_my_get_expression
= 1;
6837 seg
= expression (ep
);
6838 in_my_get_expression
= 0;
6840 if (ep
->X_op
== O_illegal
)
6842 /* We found a bad expression in md_operand(). */
6843 *str
= input_line_pointer
;
6844 input_line_pointer
= save_in
;
6849 if (seg
!= absolute_section
6850 && seg
!= text_section
6851 && seg
!= data_section
6852 && seg
!= bss_section
6853 && seg
!= undefined_section
)
6855 inst
.error
= _("bad_segment");
6856 *str
= input_line_pointer
;
6857 input_line_pointer
= save_in
;
6862 /* Get rid of any bignums now, so that we don't generate an error for which
6863 we can't establish a line number later on. Big numbers are never valid
6864 in instructions, which is where this routine is always called. */
6865 if (ep
->X_op
== O_big
6866 || (ep
->X_add_symbol
6867 && (walk_no_bignums (ep
->X_add_symbol
)
6869 && walk_no_bignums (ep
->X_op_symbol
)))))
6871 inst
.error
= _("invalid constant");
6872 *str
= input_line_pointer
;
6873 input_line_pointer
= save_in
;
6877 *str
= input_line_pointer
;
6878 input_line_pointer
= save_in
;
6882 /* We handle all bad expressions here, so that we can report the faulty
6883 instruction in the error message. */
6888 if (in_my_get_expression
)
6890 expr
->X_op
= O_illegal
;
6891 if (inst
.error
== NULL
)
6892 inst
.error
= _("bad expression");
6896 /* KIND indicates what kind of shifts are accepted. */
6899 decode_shift (str
, kind
)
6903 const struct asm_shift_name
* shift
;
6907 skip_whitespace (* str
);
6909 for (p
= * str
; ISALPHA (* p
); p
++)
6914 inst
.error
= _("shift expression expected");
6920 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
6925 inst
.error
= _("shift expression expected");
6929 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
6931 if (kind
== SHIFT_LSL_OR_ASR_IMMEDIATE
6932 && shift
->properties
->index
!= SHIFT_LSL
6933 && shift
->properties
->index
!= SHIFT_ASR
)
6935 inst
.error
= _("'LSL' or 'ASR' required");
6938 else if (kind
== SHIFT_LSL_IMMEDIATE
6939 && shift
->properties
->index
!= SHIFT_LSL
)
6941 inst
.error
= _("'LSL' required");
6944 else if (kind
== SHIFT_ASR_IMMEDIATE
6945 && shift
->properties
->index
!= SHIFT_ASR
)
6947 inst
.error
= _("'ASR' required");
6951 if (shift
->properties
->index
== SHIFT_RRX
)
6954 inst
.instruction
|= shift
->properties
->bit_field
;
6958 skip_whitespace (p
);
6960 if (kind
== NO_SHIFT_RESTRICT
&& reg_required_here (& p
, 8) != FAIL
)
6962 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
6966 else if (! is_immediate_prefix (* p
))
6968 inst
.error
= (NO_SHIFT_RESTRICT
6969 ? _("shift requires register or #expression")
6970 : _("shift requires #expression"));
6978 if (my_get_expression (& inst
.reloc
.exp
, & p
))
6981 /* Validate some simple #expressions. */
6982 if (inst
.reloc
.exp
.X_op
== O_constant
)
6984 unsigned num
= inst
.reloc
.exp
.X_add_number
;
6986 /* Reject operations greater than 32. */
6988 /* Reject a shift of 0 unless the mode allows it. */
6989 || (num
== 0 && shift
->properties
->allows_0
== 0)
6990 /* Reject a shift of 32 unless the mode allows it. */
6991 || (num
== 32 && shift
->properties
->allows_32
== 0)
6994 /* As a special case we allow a shift of zero for
6995 modes that do not support it to be recoded as an
6996 logical shift left of zero (ie nothing). We warn
6997 about this though. */
7000 as_warn (_("shift of 0 ignored."));
7001 shift
= & shift_names
[0];
7002 assert (shift
->properties
->index
== SHIFT_LSL
);
7006 inst
.error
= _("invalid immediate shift");
7011 /* Shifts of 32 are encoded as 0, for those shifts that
7016 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
7020 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
7021 inst
.reloc
.pc_rel
= 0;
7022 inst
.instruction
|= shift
->properties
->bit_field
;
7029 /* Do those data_ops which can take a negative immediate constant
7030 by altering the instruction. A bit of a hack really.
7034 by inverting the second operand, and
7037 by negating the second operand. */
7040 negate_data_op (instruction
, value
)
7041 unsigned long * instruction
;
7042 unsigned long value
;
7045 unsigned long negated
, inverted
;
7047 negated
= validate_immediate (-value
);
7048 inverted
= validate_immediate (~value
);
7050 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
7053 /* First negates. */
7054 case OPCODE_SUB
: /* ADD <-> SUB */
7055 new_inst
= OPCODE_ADD
;
7060 new_inst
= OPCODE_SUB
;
7064 case OPCODE_CMP
: /* CMP <-> CMN */
7065 new_inst
= OPCODE_CMN
;
7070 new_inst
= OPCODE_CMP
;
7074 /* Now Inverted ops. */
7075 case OPCODE_MOV
: /* MOV <-> MVN */
7076 new_inst
= OPCODE_MVN
;
7081 new_inst
= OPCODE_MOV
;
7085 case OPCODE_AND
: /* AND <-> BIC */
7086 new_inst
= OPCODE_BIC
;
7091 new_inst
= OPCODE_AND
;
7095 case OPCODE_ADC
: /* ADC <-> SBC */
7096 new_inst
= OPCODE_SBC
;
7101 new_inst
= OPCODE_ADC
;
7105 /* We cannot do anything. */
7110 if (value
== (unsigned) FAIL
)
7113 *instruction
&= OPCODE_MASK
;
7114 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
7125 skip_whitespace (* str
);
7127 if (reg_required_here (str
, 0) != FAIL
)
7129 if (skip_past_comma (str
) == SUCCESS
)
7130 /* Shift operation on register. */
7131 return decode_shift (str
, NO_SHIFT_RESTRICT
);
7137 /* Immediate expression. */
7138 if (is_immediate_prefix (**str
))
7143 if (my_get_expression (&inst
.reloc
.exp
, str
))
7146 if (inst
.reloc
.exp
.X_add_symbol
)
7148 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
7149 inst
.reloc
.pc_rel
= 0;
7153 if (skip_past_comma (str
) == SUCCESS
)
7155 /* #x, y -- ie explicit rotation by Y. */
7156 if (my_get_expression (&expr
, str
))
7159 if (expr
.X_op
!= O_constant
)
7161 inst
.error
= _("constant expression expected");
7165 /* Rotate must be a multiple of 2. */
7166 if (((unsigned) expr
.X_add_number
) > 30
7167 || (expr
.X_add_number
& 1) != 0
7168 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
7170 inst
.error
= _("invalid constant");
7173 inst
.instruction
|= INST_IMMEDIATE
;
7174 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
7175 inst
.instruction
|= expr
.X_add_number
<< 7;
7179 /* Implicit rotation, select a suitable one. */
7180 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
7184 /* Can't be done. Perhaps the code reads something like
7185 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
7186 if ((value
= negate_data_op (&inst
.instruction
,
7187 inst
.reloc
.exp
.X_add_number
))
7190 inst
.error
= _("invalid constant");
7195 inst
.instruction
|= value
;
7198 inst
.instruction
|= INST_IMMEDIATE
;
7203 inst
.error
= _("register or shift expression expected");
7212 skip_whitespace (* str
);
7214 if (fp_reg_required_here (str
, 0) != FAIL
)
7218 /* Immediate expression. */
7219 if (*((*str
)++) == '#')
7225 skip_whitespace (* str
);
7227 /* First try and match exact strings, this is to guarantee
7228 that some formats will work even for cross assembly. */
7230 for (i
= 0; fp_const
[i
]; i
++)
7232 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
7236 *str
+= strlen (fp_const
[i
]);
7237 if (is_end_of_line
[(unsigned char) **str
])
7239 inst
.instruction
|= i
+ 8;
7246 /* Just because we didn't get a match doesn't mean that the
7247 constant isn't valid, just that it is in a format that we
7248 don't automatically recognize. Try parsing it with
7249 the standard expression routines. */
7250 if ((i
= my_get_float_expression (str
)) >= 0)
7252 inst
.instruction
|= i
+ 8;
7256 inst
.error
= _("invalid floating point immediate expression");
7260 _("floating point register or immediate expression expected");
7269 skip_whitespace (str
);
7271 if (reg_required_here (&str
, 12) == FAIL
7272 || skip_past_comma (&str
) == FAIL
7273 || reg_required_here (&str
, 16) == FAIL
7274 || skip_past_comma (&str
) == FAIL
7275 || data_op2 (&str
) == FAIL
)
7278 inst
.error
= BAD_ARGS
;
7289 /* This is a pseudo-op of the form "adr rd, label" to be converted
7290 into a relative address of the form "add rd, pc, #label-.-8". */
7291 skip_whitespace (str
);
7293 if (reg_required_here (&str
, 12) == FAIL
7294 || skip_past_comma (&str
) == FAIL
7295 || my_get_expression (&inst
.reloc
.exp
, &str
))
7298 inst
.error
= BAD_ARGS
;
7302 /* Frag hacking will turn this into a sub instruction if the offset turns
7303 out to be negative. */
7304 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
7306 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
7308 inst
.reloc
.pc_rel
= 1;
7317 /* This is a pseudo-op of the form "adrl rd, label" to be converted
7318 into a relative address of the form:
7319 add rd, pc, #low(label-.-8)"
7320 add rd, rd, #high(label-.-8)" */
7322 skip_whitespace (str
);
7324 if (reg_required_here (&str
, 12) == FAIL
7325 || skip_past_comma (&str
) == FAIL
7326 || my_get_expression (&inst
.reloc
.exp
, &str
))
7329 inst
.error
= BAD_ARGS
;
7335 /* Frag hacking will turn this into a sub instruction if the offset turns
7336 out to be negative. */
7337 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
7339 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
7341 inst
.reloc
.pc_rel
= 1;
7342 inst
.size
= INSN_SIZE
* 2;
7349 skip_whitespace (str
);
7351 if (reg_required_here (&str
, 16) == FAIL
)
7354 inst
.error
= BAD_ARGS
;
7358 if (skip_past_comma (&str
) == FAIL
7359 || data_op2 (&str
) == FAIL
)
7362 inst
.error
= BAD_ARGS
;
7373 skip_whitespace (str
);
7375 if (reg_required_here (&str
, 12) == FAIL
)
7378 inst
.error
= BAD_ARGS
;
7382 if (skip_past_comma (&str
) == FAIL
7383 || data_op2 (&str
) == FAIL
)
7386 inst
.error
= BAD_ARGS
;
7404 if (my_get_expression (& inst
.reloc
.exp
, str
))
7407 if (inst
.reloc
.exp
.X_op
== O_constant
)
7409 int value
= inst
.reloc
.exp
.X_add_number
;
7411 if (value
< -4095 || value
> 4095)
7413 inst
.error
= _("address offset too large");
7423 inst
.instruction
|= add
| value
;
7427 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
7428 inst
.reloc
.pc_rel
= 0;
7441 if (reg_required_here (str
, 0) == FAIL
)
7444 inst
.instruction
|= add
| OFFSET_REG
;
7445 if (skip_past_comma (str
) == SUCCESS
)
7446 return decode_shift (str
, SHIFT_IMMEDIATE
);
7460 skip_whitespace (str
);
7462 if ((conflict_reg
= reg_required_here (&str
, 12)) == FAIL
)
7465 inst
.error
= BAD_ARGS
;
7469 if (skip_past_comma (&str
) == FAIL
)
7471 inst
.error
= _("address expected");
7481 skip_whitespace (str
);
7483 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
7486 /* Conflicts can occur on stores as well as loads. */
7487 conflict_reg
= (conflict_reg
== reg
);
7489 skip_whitespace (str
);
7495 if (skip_past_comma (&str
) == SUCCESS
)
7497 /* [Rn],... (post inc) */
7498 if (ldst_extend (&str
) == FAIL
)
7501 as_warn (_("%s register same as write-back base"),
7502 ((inst
.instruction
& LOAD_BIT
)
7503 ? _("destination") : _("source")));
7508 skip_whitespace (str
);
7513 as_warn (_("%s register same as write-back base"),
7514 ((inst
.instruction
& LOAD_BIT
)
7515 ? _("destination") : _("source")));
7517 inst
.instruction
|= WRITE_BACK
;
7520 inst
.instruction
|= INDEX_UP
;
7527 if (skip_past_comma (&str
) == FAIL
)
7529 inst
.error
= _("pre-indexed expression expected");
7534 if (ldst_extend (&str
) == FAIL
)
7537 skip_whitespace (str
);
7541 inst
.error
= _("missing ]");
7545 skip_whitespace (str
);
7550 as_warn (_("%s register same as write-back base"),
7551 ((inst
.instruction
& LOAD_BIT
)
7552 ? _("destination") : _("source")));
7554 inst
.instruction
|= WRITE_BACK
;
7558 else if (*str
== '=')
7560 if ((inst
.instruction
& LOAD_BIT
) == 0)
7562 inst
.error
= _("invalid pseudo operation");
7566 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
7569 skip_whitespace (str
);
7571 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7574 if (inst
.reloc
.exp
.X_op
!= O_constant
7575 && inst
.reloc
.exp
.X_op
!= O_symbol
)
7577 inst
.error
= _("constant expression expected");
7581 if (inst
.reloc
.exp
.X_op
== O_constant
)
7583 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
7587 /* This can be done with a mov instruction. */
7588 inst
.instruction
&= LITERAL_MASK
;
7589 inst
.instruction
|= (INST_IMMEDIATE
7590 | (OPCODE_MOV
<< DATA_OP_SHIFT
));
7591 inst
.instruction
|= value
& 0xfff;
7596 value
= validate_immediate (~inst
.reloc
.exp
.X_add_number
);
7600 /* This can be done with a mvn instruction. */
7601 inst
.instruction
&= LITERAL_MASK
;
7602 inst
.instruction
|= (INST_IMMEDIATE
7603 | (OPCODE_MVN
<< DATA_OP_SHIFT
));
7604 inst
.instruction
|= value
& 0xfff;
7610 /* Insert into literal pool. */
7611 if (add_to_lit_pool () == FAIL
)
7614 inst
.error
= _("literal pool insertion failed");
7618 /* Change the instruction exp to point to the pool. */
7619 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
7620 inst
.reloc
.pc_rel
= 1;
7621 inst
.instruction
|= (REG_PC
<< 16);
7626 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7629 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
7631 /* PC rel adjust. */
7632 inst
.reloc
.exp
.X_add_number
-= 8;
7634 inst
.reloc
.pc_rel
= 1;
7635 inst
.instruction
|= (REG_PC
<< 16);
7639 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
7649 skip_whitespace (str
);
7651 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
7654 inst
.error
= BAD_ARGS
;
7658 if (skip_past_comma (& str
) == FAIL
)
7660 inst
.error
= _("address expected");
7670 skip_whitespace (str
);
7672 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
7675 /* ldrt/strt always use post-indexed addressing, so if the base is
7676 the same as Rd, we warn. */
7677 if (conflict_reg
== reg
)
7678 as_warn (_("%s register same as write-back base"),
7679 ((inst
.instruction
& LOAD_BIT
)
7680 ? _("destination") : _("source")));
7682 skip_whitespace (str
);
7688 if (skip_past_comma (&str
) == SUCCESS
)
7690 /* [Rn],... (post inc) */
7691 if (ldst_extend (&str
) == FAIL
)
7697 skip_whitespace (str
);
7699 /* Skip a write-back '!'. */
7703 inst
.instruction
|= INDEX_UP
;
7708 inst
.error
= _("post-indexed expression expected");
7714 inst
.error
= _("post-indexed expression expected");
7722 ldst_extend_v4 (str
)
7732 if (my_get_expression (& inst
.reloc
.exp
, str
))
7735 if (inst
.reloc
.exp
.X_op
== O_constant
)
7737 int value
= inst
.reloc
.exp
.X_add_number
;
7739 if (value
< -255 || value
> 255)
7741 inst
.error
= _("address offset too large");
7751 /* Halfword and signextension instructions have the
7752 immediate value split across bits 11..8 and bits 3..0. */
7753 inst
.instruction
|= (add
| HWOFFSET_IMM
7754 | ((value
>> 4) << 8) | (value
& 0xF));
7758 inst
.instruction
|= HWOFFSET_IMM
;
7759 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
7760 inst
.reloc
.pc_rel
= 0;
7773 if (reg_required_here (str
, 0) == FAIL
)
7776 inst
.instruction
|= add
;
7781 /* Halfword and signed-byte load/store operations. */
7790 skip_whitespace (str
);
7792 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
7795 inst
.error
= BAD_ARGS
;
7799 if (skip_past_comma (& str
) == FAIL
)
7801 inst
.error
= _("address expected");
7811 skip_whitespace (str
);
7813 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
7816 /* Conflicts can occur on stores as well as loads. */
7817 conflict_reg
= (conflict_reg
== reg
);
7819 skip_whitespace (str
);
7825 if (skip_past_comma (&str
) == SUCCESS
)
7827 /* [Rn],... (post inc) */
7828 if (ldst_extend_v4 (&str
) == FAIL
)
7831 as_warn (_("%s register same as write-back base"),
7832 ((inst
.instruction
& LOAD_BIT
)
7833 ? _("destination") : _("source")));
7838 inst
.instruction
|= HWOFFSET_IMM
;
7840 skip_whitespace (str
);
7845 as_warn (_("%s register same as write-back base"),
7846 ((inst
.instruction
& LOAD_BIT
)
7847 ? _("destination") : _("source")));
7849 inst
.instruction
|= WRITE_BACK
;
7852 inst
.instruction
|= INDEX_UP
;
7859 if (skip_past_comma (&str
) == FAIL
)
7861 inst
.error
= _("pre-indexed expression expected");
7866 if (ldst_extend_v4 (&str
) == FAIL
)
7869 skip_whitespace (str
);
7873 inst
.error
= _("missing ]");
7877 skip_whitespace (str
);
7882 as_warn (_("%s register same as write-back base"),
7883 ((inst
.instruction
& LOAD_BIT
)
7884 ? _("destination") : _("source")));
7886 inst
.instruction
|= WRITE_BACK
;
7890 else if (*str
== '=')
7892 if ((inst
.instruction
& LOAD_BIT
) == 0)
7894 inst
.error
= _("invalid pseudo operation");
7898 /* XXX Does this work correctly for half-word/byte ops? */
7899 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
7902 skip_whitespace (str
);
7904 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7907 if (inst
.reloc
.exp
.X_op
!= O_constant
7908 && inst
.reloc
.exp
.X_op
!= O_symbol
)
7910 inst
.error
= _("constant expression expected");
7914 if (inst
.reloc
.exp
.X_op
== O_constant
)
7916 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
7920 /* This can be done with a mov instruction. */
7921 inst
.instruction
&= LITERAL_MASK
;
7922 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
7923 inst
.instruction
|= value
& 0xfff;
7928 value
= validate_immediate (~ inst
.reloc
.exp
.X_add_number
);
7932 /* This can be done with a mvn instruction. */
7933 inst
.instruction
&= LITERAL_MASK
;
7934 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MVN
<< DATA_OP_SHIFT
);
7935 inst
.instruction
|= value
& 0xfff;
7941 /* Insert into literal pool. */
7942 if (add_to_lit_pool () == FAIL
)
7945 inst
.error
= _("literal pool insertion failed");
7949 /* Change the instruction exp to point to the pool. */
7950 inst
.instruction
|= HWOFFSET_IMM
;
7951 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
7952 inst
.reloc
.pc_rel
= 1;
7953 inst
.instruction
|= (REG_PC
<< 16);
7958 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7961 inst
.instruction
|= HWOFFSET_IMM
;
7962 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
7964 /* PC rel adjust. */
7965 inst
.reloc
.exp
.X_add_number
-= 8;
7967 inst
.reloc
.pc_rel
= 1;
7968 inst
.instruction
|= (REG_PC
<< 16);
7972 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
7980 char * str
= * strp
;
7984 /* We come back here if we get ranges concatenated by '+' or '|'. */
7999 skip_whitespace (str
);
8001 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
8010 inst
.error
= _("bad range in register list");
8014 for (i
= cur_reg
+ 1; i
< reg
; i
++)
8016 if (range
& (1 << i
))
8018 (_("Warning: duplicated register (r%d) in register list"),
8026 if (range
& (1 << reg
))
8027 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
8029 else if (reg
<= cur_reg
)
8030 as_tsktsk (_("Warning: register range not in ascending order"));
8035 while (skip_past_comma (&str
) != FAIL
8036 || (in_range
= 1, *str
++ == '-'));
8038 skip_whitespace (str
);
8042 inst
.error
= _("missing `}'");
8050 if (my_get_expression (&expr
, &str
))
8053 if (expr
.X_op
== O_constant
)
8055 if (expr
.X_add_number
8056 != (expr
.X_add_number
& 0x0000ffff))
8058 inst
.error
= _("invalid register mask");
8062 if ((range
& expr
.X_add_number
) != 0)
8064 int regno
= range
& expr
.X_add_number
;
8067 regno
= (1 << regno
) - 1;
8069 (_("Warning: duplicated register (r%d) in register list"),
8073 range
|= expr
.X_add_number
;
8077 if (inst
.reloc
.type
!= 0)
8079 inst
.error
= _("expression too complex");
8083 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
8084 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
8085 inst
.reloc
.pc_rel
= 0;
8089 skip_whitespace (str
);
8091 if (*str
== '|' || *str
== '+')
8097 while (another_range
);
8110 skip_whitespace (str
);
8112 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
8115 if (base_reg
== REG_PC
)
8117 inst
.error
= _("r15 not allowed as base register");
8121 skip_whitespace (str
);
8125 inst
.instruction
|= WRITE_BACK
;
8129 if (skip_past_comma (&str
) == FAIL
8130 || (range
= reg_list (&str
)) == FAIL
)
8133 inst
.error
= BAD_ARGS
;
8140 inst
.instruction
|= LDM_TYPE_2_OR_3
;
8143 if (inst
.instruction
& WRITE_BACK
)
8145 /* Check for unpredictable uses of writeback. */
8146 if (inst
.instruction
& LOAD_BIT
)
8148 /* Not allowed in LDM type 2. */
8149 if ((inst
.instruction
& LDM_TYPE_2_OR_3
)
8150 && ((range
& (1 << REG_PC
)) == 0))
8151 as_warn (_("writeback of base register is UNPREDICTABLE"));
8152 /* Only allowed if base reg not in list for other types. */
8153 else if (range
& (1 << base_reg
))
8154 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
8158 /* Not allowed for type 2. */
8159 if (inst
.instruction
& LDM_TYPE_2_OR_3
)
8160 as_warn (_("writeback of base register is UNPREDICTABLE"));
8161 /* Only allowed if base reg not in list, or first in list. */
8162 else if ((range
& (1 << base_reg
))
8163 && (range
& ((1 << base_reg
) - 1)))
8164 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
8168 inst
.instruction
|= range
;
8176 skip_whitespace (str
);
8178 /* Allow optional leading '#'. */
8179 if (is_immediate_prefix (*str
))
8182 if (my_get_expression (& inst
.reloc
.exp
, & str
))
8185 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
8186 inst
.reloc
.pc_rel
= 0;
8196 skip_whitespace (str
);
8198 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
8203 inst
.error
= _("r15 not allowed in swap");
8207 if (skip_past_comma (&str
) == FAIL
8208 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
8211 inst
.error
= BAD_ARGS
;
8217 inst
.error
= _("r15 not allowed in swap");
8221 if (skip_past_comma (&str
) == FAIL
8224 inst
.error
= BAD_ARGS
;
8228 skip_whitespace (str
);
8230 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
8235 inst
.error
= BAD_PC
;
8239 skip_whitespace (str
);
8243 inst
.error
= _("missing ]");
8254 if (my_get_expression (&inst
.reloc
.exp
, &str
))
8261 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
8262 required for the instruction. */
8264 /* arm_parse_reloc () works on input_line_pointer.
8265 We actually want to parse the operands to the branch instruction
8266 passed in 'str'. Save the input pointer and restore it later. */
8267 save_in
= input_line_pointer
;
8268 input_line_pointer
= str
;
8269 if (inst
.reloc
.exp
.X_op
== O_symbol
8271 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
8273 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
8274 inst
.reloc
.pc_rel
= 0;
8275 /* Modify str to point to after parsed operands, otherwise
8276 end_of_line() will complain about the (PLT) left in str. */
8277 str
= input_line_pointer
;
8281 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
8282 inst
.reloc
.pc_rel
= 1;
8284 input_line_pointer
= save_in
;
8287 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
8288 inst
.reloc
.pc_rel
= 1;
8289 #endif /* OBJ_ELF */
8300 skip_whitespace (str
);
8302 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
8304 inst
.error
= BAD_ARGS
;
8308 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
8310 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
8319 /* Co-processor data operation.
8320 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
8321 skip_whitespace (str
);
8323 if (co_proc_number (&str
) == FAIL
)
8326 inst
.error
= BAD_ARGS
;
8330 if (skip_past_comma (&str
) == FAIL
8331 || cp_opc_expr (&str
, 20,4) == FAIL
)
8334 inst
.error
= BAD_ARGS
;
8338 if (skip_past_comma (&str
) == FAIL
8339 || cp_reg_required_here (&str
, 12) == FAIL
)
8342 inst
.error
= BAD_ARGS
;
8346 if (skip_past_comma (&str
) == FAIL
8347 || cp_reg_required_here (&str
, 16) == FAIL
)
8350 inst
.error
= BAD_ARGS
;
8354 if (skip_past_comma (&str
) == FAIL
8355 || cp_reg_required_here (&str
, 0) == FAIL
)
8358 inst
.error
= BAD_ARGS
;
8362 if (skip_past_comma (&str
) == SUCCESS
)
8364 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
8367 inst
.error
= BAD_ARGS
;
8379 /* Co-processor register load/store.
8380 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
8382 skip_whitespace (str
);
8384 if (co_proc_number (&str
) == FAIL
)
8387 inst
.error
= BAD_ARGS
;
8391 if (skip_past_comma (&str
) == FAIL
8392 || cp_reg_required_here (&str
, 12) == FAIL
)
8395 inst
.error
= BAD_ARGS
;
8399 if (skip_past_comma (&str
) == FAIL
8400 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
8403 inst
.error
= BAD_ARGS
;
8414 /* Co-processor register transfer.
8415 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
8417 skip_whitespace (str
);
8419 if (co_proc_number (&str
) == FAIL
)
8422 inst
.error
= BAD_ARGS
;
8426 if (skip_past_comma (&str
) == FAIL
8427 || cp_opc_expr (&str
, 21, 3) == FAIL
)
8430 inst
.error
= BAD_ARGS
;
8434 if (skip_past_comma (&str
) == FAIL
8435 || reg_required_here (&str
, 12) == FAIL
)
8438 inst
.error
= BAD_ARGS
;
8442 if (skip_past_comma (&str
) == FAIL
8443 || cp_reg_required_here (&str
, 16) == FAIL
)
8446 inst
.error
= BAD_ARGS
;
8450 if (skip_past_comma (&str
) == FAIL
8451 || cp_reg_required_here (&str
, 0) == FAIL
)
8454 inst
.error
= BAD_ARGS
;
8458 if (skip_past_comma (&str
) == SUCCESS
)
8460 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
8463 inst
.error
= BAD_ARGS
;
8475 /* FP control registers.
8476 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
8478 skip_whitespace (str
);
8480 if (reg_required_here (&str
, 12) == FAIL
)
8483 inst
.error
= BAD_ARGS
;
8494 skip_whitespace (str
);
8496 if (fp_reg_required_here (&str
, 12) == FAIL
)
8499 inst
.error
= BAD_ARGS
;
8503 if (skip_past_comma (&str
) == FAIL
8504 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
8507 inst
.error
= BAD_ARGS
;
8520 skip_whitespace (str
);
8522 if (fp_reg_required_here (&str
, 12) == FAIL
)
8525 inst
.error
= BAD_ARGS
;
8529 /* Get Number of registers to transfer. */
8530 if (skip_past_comma (&str
) == FAIL
8531 || my_get_expression (&inst
.reloc
.exp
, &str
))
8534 inst
.error
= _("constant expression expected");
8538 if (inst
.reloc
.exp
.X_op
!= O_constant
)
8540 inst
.error
= _("constant value required for number of registers");
8544 num_regs
= inst
.reloc
.exp
.X_add_number
;
8546 if (num_regs
< 1 || num_regs
> 4)
8548 inst
.error
= _("number of registers must be in the range [1:4]");
8555 inst
.instruction
|= CP_T_X
;
8558 inst
.instruction
|= CP_T_Y
;
8561 inst
.instruction
|= CP_T_Y
| CP_T_X
;
8569 if (inst
.instruction
& (CP_T_Pre
| CP_T_UD
)) /* ea/fd format. */
8575 /* The instruction specified "ea" or "fd", so we can only accept
8576 [Rn]{!}. The instruction does not really support stacking or
8577 unstacking, so we have to emulate these by setting appropriate
8578 bits and offsets. */
8579 if (skip_past_comma (&str
) == FAIL
8583 inst
.error
= BAD_ARGS
;
8588 skip_whitespace (str
);
8590 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
8593 skip_whitespace (str
);
8597 inst
.error
= BAD_ARGS
;
8609 _("r15 not allowed as base register with write-back");
8616 if (inst
.instruction
& CP_T_Pre
)
8618 /* Pre-decrement. */
8619 offset
= 3 * num_regs
;
8621 inst
.instruction
|= CP_T_WB
;
8625 /* Post-increment. */
8628 inst
.instruction
|= CP_T_WB
;
8629 offset
= 3 * num_regs
;
8633 /* No write-back, so convert this into a standard pre-increment
8634 instruction -- aesthetically more pleasing. */
8635 inst
.instruction
|= CP_T_Pre
| CP_T_UD
;
8640 inst
.instruction
|= offset
;
8642 else if (skip_past_comma (&str
) == FAIL
8643 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
8646 inst
.error
= BAD_ARGS
;
8657 skip_whitespace (str
);
8659 if (fp_reg_required_here (&str
, 12) == FAIL
)
8662 inst
.error
= BAD_ARGS
;
8666 if (skip_past_comma (&str
) == FAIL
8667 || fp_reg_required_here (&str
, 16) == FAIL
)
8670 inst
.error
= BAD_ARGS
;
8674 if (skip_past_comma (&str
) == FAIL
8675 || fp_op2 (&str
) == FAIL
)
8678 inst
.error
= BAD_ARGS
;
8686 do_fpa_monadic (str
)
8689 skip_whitespace (str
);
8691 if (fp_reg_required_here (&str
, 12) == FAIL
)
8694 inst
.error
= BAD_ARGS
;
8698 if (skip_past_comma (&str
) == FAIL
8699 || fp_op2 (&str
) == FAIL
)
8702 inst
.error
= BAD_ARGS
;
8713 skip_whitespace (str
);
8715 if (fp_reg_required_here (&str
, 16) == FAIL
)
8718 inst
.error
= BAD_ARGS
;
8722 if (skip_past_comma (&str
) == FAIL
8723 || fp_op2 (&str
) == FAIL
)
8726 inst
.error
= BAD_ARGS
;
8734 do_fpa_from_reg (str
)
8737 skip_whitespace (str
);
8739 if (fp_reg_required_here (&str
, 16) == FAIL
)
8742 inst
.error
= BAD_ARGS
;
8746 if (skip_past_comma (&str
) == FAIL
8747 || reg_required_here (&str
, 12) == FAIL
)
8750 inst
.error
= BAD_ARGS
;
8761 skip_whitespace (str
);
8763 if (reg_required_here (&str
, 12) == FAIL
)
8766 if (skip_past_comma (&str
) == FAIL
8767 || fp_reg_required_here (&str
, 0) == FAIL
)
8770 inst
.error
= BAD_ARGS
;
8778 vfp_sp_reg_required_here (str
, pos
)
8780 enum vfp_sp_reg_pos pos
;
8785 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_SN
].htab
)) != FAIL
)
8790 inst
.instruction
|= ((reg
>> 1) << 12) | ((reg
& 1) << 22);
8794 inst
.instruction
|= ((reg
>> 1) << 16) | ((reg
& 1) << 7);
8798 inst
.instruction
|= ((reg
>> 1) << 0) | ((reg
& 1) << 5);
8807 /* In the few cases where we might be able to accept something else
8808 this error can be overridden. */
8809 inst
.error
= _(all_reg_maps
[REG_TYPE_SN
].expected
);
8811 /* Restore the start point. */
8817 vfp_dp_reg_required_here (str
, pos
)
8819 enum vfp_dp_reg_pos pos
;
8824 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_DN
].htab
)) != FAIL
)
8829 inst
.instruction
|= reg
<< 12;
8833 inst
.instruction
|= reg
<< 16;
8837 inst
.instruction
|= reg
<< 0;
8846 /* In the few cases where we might be able to accept something else
8847 this error can be overridden. */
8848 inst
.error
= _(all_reg_maps
[REG_TYPE_DN
].expected
);
8850 /* Restore the start point. */
8856 do_vfp_sp_monadic (str
)
8859 skip_whitespace (str
);
8861 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
8864 if (skip_past_comma (&str
) == FAIL
8865 || vfp_sp_reg_required_here (&str
, VFP_REG_Sm
) == FAIL
)
8868 inst
.error
= BAD_ARGS
;
8876 do_vfp_dp_monadic (str
)
8879 skip_whitespace (str
);
8881 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
8884 if (skip_past_comma (&str
) == FAIL
8885 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
8888 inst
.error
= BAD_ARGS
;
8896 do_vfp_sp_dyadic (str
)
8899 skip_whitespace (str
);
8901 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
8904 if (skip_past_comma (&str
) == FAIL
8905 || vfp_sp_reg_required_here (&str
, VFP_REG_Sn
) == FAIL
8906 || skip_past_comma (&str
) == FAIL
8907 || vfp_sp_reg_required_here (&str
, VFP_REG_Sm
) == FAIL
)
8910 inst
.error
= BAD_ARGS
;
8918 do_vfp_dp_dyadic (str
)
8921 skip_whitespace (str
);
8923 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
8926 if (skip_past_comma (&str
) == FAIL
8927 || vfp_dp_reg_required_here (&str
, VFP_REG_Dn
) == FAIL
8928 || skip_past_comma (&str
) == FAIL
8929 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
8932 inst
.error
= BAD_ARGS
;
8940 do_vfp_reg_from_sp (str
)
8943 skip_whitespace (str
);
8945 if (reg_required_here (&str
, 12) == FAIL
)
8948 if (skip_past_comma (&str
) == FAIL
8949 || vfp_sp_reg_required_here (&str
, VFP_REG_Sn
) == FAIL
)
8952 inst
.error
= BAD_ARGS
;
8960 do_vfp_reg2_from_sp2 (str
)
8963 skip_whitespace (str
);
8965 if (reg_required_here (&str
, 12) == FAIL
8966 || skip_past_comma (&str
) == FAIL
8967 || reg_required_here (&str
, 16) == FAIL
8968 || skip_past_comma (&str
) == FAIL
)
8971 inst
.error
= BAD_ARGS
;
8975 /* We require exactly two consecutive SP registers. */
8976 if (vfp_sp_reg_list (&str
, VFP_REG_Sm
) != 2)
8979 inst
.error
= _("only two consecutive VFP SP registers allowed here");
8986 do_vfp_sp_from_reg (str
)
8989 skip_whitespace (str
);
8991 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sn
) == FAIL
)
8994 if (skip_past_comma (&str
) == FAIL
8995 || reg_required_here (&str
, 12) == FAIL
)
8998 inst
.error
= BAD_ARGS
;
9006 do_vfp_sp2_from_reg2 (str
)
9009 skip_whitespace (str
);
9011 /* We require exactly two consecutive SP registers. */
9012 if (vfp_sp_reg_list (&str
, VFP_REG_Sm
) != 2)
9015 inst
.error
= _("only two consecutive VFP SP registers allowed here");
9018 if (skip_past_comma (&str
) == FAIL
9019 || reg_required_here (&str
, 12) == FAIL
9020 || skip_past_comma (&str
) == FAIL
9021 || reg_required_here (&str
, 16) == FAIL
)
9024 inst
.error
= BAD_ARGS
;
9032 do_vfp_reg_from_dp (str
)
9035 skip_whitespace (str
);
9037 if (reg_required_here (&str
, 12) == FAIL
)
9040 if (skip_past_comma (&str
) == FAIL
9041 || vfp_dp_reg_required_here (&str
, VFP_REG_Dn
) == FAIL
)
9044 inst
.error
= BAD_ARGS
;
9052 do_vfp_reg2_from_dp (str
)
9055 skip_whitespace (str
);
9057 if (reg_required_here (&str
, 12) == FAIL
)
9060 if (skip_past_comma (&str
) == FAIL
9061 || reg_required_here (&str
, 16) == FAIL
9062 || skip_past_comma (&str
) == FAIL
9063 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
9066 inst
.error
= BAD_ARGS
;
9074 do_vfp_dp_from_reg (str
)
9077 skip_whitespace (str
);
9079 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dn
) == FAIL
)
9082 if (skip_past_comma (&str
) == FAIL
9083 || reg_required_here (&str
, 12) == FAIL
)
9086 inst
.error
= BAD_ARGS
;
9094 do_vfp_dp_from_reg2 (str
)
9097 skip_whitespace (str
);
9099 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
9102 if (skip_past_comma (&str
) == FAIL
9103 || reg_required_here (&str
, 12) == FAIL
9104 || skip_past_comma (&str
) == FAIL
9105 || reg_required_here (&str
, 16) == FAIL
)
9108 inst
.error
= BAD_ARGS
;
9115 static const struct vfp_reg
*
9122 const struct vfp_reg
*vreg
;
9126 /* Find the end of the current token. */
9131 while (ISALPHA (c
));
9136 for (vreg
= vfp_regs
+ 0;
9137 vreg
< vfp_regs
+ sizeof (vfp_regs
) / sizeof (struct vfp_reg
);
9140 if (strcmp (start
, vreg
->name
) == 0)
9153 vfp_psr_required_here (str
)
9157 const struct vfp_reg
*vreg
;
9159 vreg
= vfp_psr_parse (str
);
9163 inst
.instruction
|= vreg
->regno
;
9167 inst
.error
= _("VFP system register expected");
9174 do_vfp_reg_from_ctrl (str
)
9177 skip_whitespace (str
);
9179 if (reg_required_here (&str
, 12) == FAIL
)
9182 if (skip_past_comma (&str
) == FAIL
9183 || vfp_psr_required_here (&str
) == FAIL
)
9186 inst
.error
= BAD_ARGS
;
9194 do_vfp_ctrl_from_reg (str
)
9197 skip_whitespace (str
);
9199 if (vfp_psr_required_here (&str
) == FAIL
)
9202 if (skip_past_comma (&str
) == FAIL
9203 || reg_required_here (&str
, 12) == FAIL
)
9206 inst
.error
= BAD_ARGS
;
9214 do_vfp_sp_ldst (str
)
9217 skip_whitespace (str
);
9219 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
9222 inst
.error
= BAD_ARGS
;
9226 if (skip_past_comma (&str
) == FAIL
9227 || cp_address_required_here (&str
, CP_NO_WB
) == FAIL
)
9230 inst
.error
= BAD_ARGS
;
9238 do_vfp_dp_ldst (str
)
9241 skip_whitespace (str
);
9243 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
9246 inst
.error
= BAD_ARGS
;
9250 if (skip_past_comma (&str
) == FAIL
9251 || cp_address_required_here (&str
, CP_NO_WB
) == FAIL
)
9254 inst
.error
= BAD_ARGS
;
9261 /* Parse and encode a VFP SP register list, storing the initial
9262 register in position POS and returning the range as the result. If
9263 the string is invalid return FAIL (an invalid range). */
9265 vfp_sp_reg_list (str
, pos
)
9267 enum vfp_sp_reg_pos pos
;
9275 unsigned long mask
= 0;
9282 skip_whitespace (*str
);
9284 tempinst
= inst
.instruction
;
9288 inst
.instruction
= 0;
9290 if ((new_base
= vfp_sp_reg_required_here (str
, pos
)) == FAIL
)
9293 if (count
== 0 || base_reg
> new_base
)
9295 base_reg
= new_base
;
9296 base_bits
= inst
.instruction
;
9299 if (mask
& (1 << new_base
))
9301 inst
.error
= _("invalid register list");
9305 if ((mask
>> new_base
) != 0 && ! warned
)
9307 as_tsktsk (_("register list not in ascending order"));
9311 mask
|= 1 << new_base
;
9314 skip_whitespace (*str
);
9316 if (**str
== '-') /* We have the start of a range expression */
9323 = arm_reg_parse (str
, all_reg_maps
[REG_TYPE_SN
].htab
))
9326 inst
.error
= _(all_reg_maps
[REG_TYPE_SN
].expected
);
9330 if (high_range
<= new_base
)
9332 inst
.error
= _("register range not in ascending order");
9336 for (new_base
++; new_base
<= high_range
; new_base
++)
9338 if (mask
& (1 << new_base
))
9340 inst
.error
= _("invalid register list");
9344 mask
|= 1 << new_base
;
9349 while (skip_past_comma (str
) != FAIL
);
9353 inst
.error
= _("invalid register list");
9361 /* Sanity check -- should have raised a parse error above. */
9362 if (count
== 0 || count
> 32)
9365 /* Final test -- the registers must be consecutive. */
9368 if ((mask
& (1 << base_reg
++)) == 0)
9370 inst
.error
= _("non-contiguous register range");
9375 inst
.instruction
= tempinst
| base_bits
;
9380 vfp_dp_reg_list (str
)
9388 unsigned long mask
= 0;
9395 skip_whitespace (*str
);
9397 tempinst
= inst
.instruction
;
9401 inst
.instruction
= 0;
9403 if ((new_base
= vfp_dp_reg_required_here (str
, VFP_REG_Dd
)) == FAIL
)
9406 if (count
== 0 || base_reg
> new_base
)
9408 base_reg
= new_base
;
9409 range
= inst
.instruction
;
9412 if (mask
& (1 << new_base
))
9414 inst
.error
= _("invalid register list");
9418 if ((mask
>> new_base
) != 0 && ! warned
)
9420 as_tsktsk (_("register list not in ascending order"));
9424 mask
|= 1 << new_base
;
9427 skip_whitespace (*str
);
9429 if (**str
== '-') /* We have the start of a range expression */
9436 = arm_reg_parse (str
, all_reg_maps
[REG_TYPE_DN
].htab
))
9439 inst
.error
= _(all_reg_maps
[REG_TYPE_DN
].expected
);
9443 if (high_range
<= new_base
)
9445 inst
.error
= _("register range not in ascending order");
9449 for (new_base
++; new_base
<= high_range
; new_base
++)
9451 if (mask
& (1 << new_base
))
9453 inst
.error
= _("invalid register list");
9457 mask
|= 1 << new_base
;
9462 while (skip_past_comma (str
) != FAIL
);
9466 inst
.error
= _("invalid register list");
9474 /* Sanity check -- should have raised a parse error above. */
9475 if (count
== 0 || count
> 16)
9478 /* Final test -- the registers must be consecutive. */
9481 if ((mask
& (1 << base_reg
++)) == 0)
9483 inst
.error
= _("non-contiguous register range");
9488 inst
.instruction
= tempinst
;
9493 vfp_sp_ldstm (str
, ldstm_type
)
9495 enum vfp_ldstm_type ldstm_type
;
9499 skip_whitespace (str
);
9501 if (reg_required_here (&str
, 16) == FAIL
)
9504 skip_whitespace (str
);
9508 inst
.instruction
|= WRITE_BACK
;
9511 else if (ldstm_type
!= VFP_LDSTMIA
)
9513 inst
.error
= _("this addressing mode requires base-register writeback");
9517 if (skip_past_comma (&str
) == FAIL
9518 || (range
= vfp_sp_reg_list (&str
, VFP_REG_Sd
)) == FAIL
)
9521 inst
.error
= BAD_ARGS
;
9525 inst
.instruction
|= range
;
9530 vfp_dp_ldstm (str
, ldstm_type
)
9532 enum vfp_ldstm_type ldstm_type
;
9536 skip_whitespace (str
);
9538 if (reg_required_here (&str
, 16) == FAIL
)
9541 skip_whitespace (str
);
9545 inst
.instruction
|= WRITE_BACK
;
9548 else if (ldstm_type
!= VFP_LDSTMIA
&& ldstm_type
!= VFP_LDSTMIAX
)
9550 inst
.error
= _("this addressing mode requires base-register writeback");
9554 if (skip_past_comma (&str
) == FAIL
9555 || (range
= vfp_dp_reg_list (&str
)) == FAIL
)
9558 inst
.error
= BAD_ARGS
;
9562 if (ldstm_type
== VFP_LDSTMIAX
|| ldstm_type
== VFP_LDSTMDBX
)
9565 inst
.instruction
|= range
;
9570 do_vfp_sp_ldstmia (str
)
9573 vfp_sp_ldstm (str
, VFP_LDSTMIA
);
9577 do_vfp_sp_ldstmdb (str
)
9580 vfp_sp_ldstm (str
, VFP_LDSTMDB
);
9584 do_vfp_dp_ldstmia (str
)
9587 vfp_dp_ldstm (str
, VFP_LDSTMIA
);
9591 do_vfp_dp_ldstmdb (str
)
9594 vfp_dp_ldstm (str
, VFP_LDSTMDB
);
9598 do_vfp_xp_ldstmia (str
)
9601 vfp_dp_ldstm (str
, VFP_LDSTMIAX
);
9605 do_vfp_xp_ldstmdb (str
)
9608 vfp_dp_ldstm (str
, VFP_LDSTMDBX
);
9612 do_vfp_sp_compare_z (str
)
9615 skip_whitespace (str
);
9617 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
9620 inst
.error
= BAD_ARGS
;
9628 do_vfp_dp_compare_z (str
)
9631 skip_whitespace (str
);
9633 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
9636 inst
.error
= BAD_ARGS
;
9644 do_vfp_dp_sp_cvt (str
)
9647 skip_whitespace (str
);
9649 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
9652 if (skip_past_comma (&str
) == FAIL
9653 || vfp_sp_reg_required_here (&str
, VFP_REG_Sm
) == FAIL
)
9656 inst
.error
= BAD_ARGS
;
9664 do_vfp_sp_dp_cvt (str
)
9667 skip_whitespace (str
);
9669 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
9672 if (skip_past_comma (&str
) == FAIL
9673 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
9676 inst
.error
= BAD_ARGS
;
9683 /* Thumb specific routines. */
9685 /* Parse and validate that a register is of the right form, this saves
9686 repeated checking of this information in many similar cases.
9687 Unlike the 32-bit case we do not insert the register into the opcode
9688 here, since the position is often unknown until the full instruction
9692 thumb_reg (strp
, hi_lo
)
9698 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
9706 inst
.error
= _("lo register required");
9714 inst
.error
= _("hi register required");
9726 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
9730 thumb_add_sub (str
, subtract
)
9734 int Rd
, Rs
, Rn
= FAIL
;
9736 skip_whitespace (str
);
9738 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
9739 || skip_past_comma (&str
) == FAIL
)
9742 inst
.error
= BAD_ARGS
;
9746 if (is_immediate_prefix (*str
))
9750 if (my_get_expression (&inst
.reloc
.exp
, &str
))
9755 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
9758 if (skip_past_comma (&str
) == FAIL
)
9760 /* Two operand format, shuffle the registers
9761 and pretend there are 3. */
9765 else if (is_immediate_prefix (*str
))
9768 if (my_get_expression (&inst
.reloc
.exp
, &str
))
9771 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
9775 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9776 for the latter case, EXPR contains the immediate that was found. */
9779 /* All register format. */
9780 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
9784 inst
.error
= _("dest and source1 must be the same register");
9788 /* Can't do this for SUB. */
9791 inst
.error
= _("subtract valid only on lo regs");
9795 inst
.instruction
= (T_OPCODE_ADD_HI
9796 | (Rd
> 7 ? THUMB_H1
: 0)
9797 | (Rn
> 7 ? THUMB_H2
: 0));
9798 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
9802 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
9803 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
9808 /* Immediate expression, now things start to get nasty. */
9810 /* First deal with HI regs, only very restricted cases allowed:
9811 Adjusting SP, and using PC or SP to get an address. */
9812 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
9813 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
9815 inst
.error
= _("invalid Hi register with immediate");
9819 if (inst
.reloc
.exp
.X_op
!= O_constant
)
9821 /* Value isn't known yet, all we can do is store all the fragments
9822 we know about in the instruction and let the reloc hacking
9824 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
9825 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
9829 int offset
= inst
.reloc
.exp
.X_add_number
;
9839 /* Quick check, in case offset is MIN_INT. */
9842 inst
.error
= _("immediate value out of range");
9846 /* Note - you cannot convert a subtract of 0 into an
9847 add of 0 because the carry flag is set differently. */
9848 else if (offset
> 0)
9853 if (offset
& ~0x1fc)
9855 inst
.error
= _("invalid immediate value for stack adjust");
9858 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
9859 inst
.instruction
|= offset
>> 2;
9861 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
9864 || (offset
& ~0x3fc))
9866 inst
.error
= _("invalid immediate for address calculation");
9869 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
9871 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
9877 inst
.error
= _("immediate value out of range");
9880 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
9881 inst
.instruction
|= (Rd
<< 8) | offset
;
9887 inst
.error
= _("immediate value out of range");
9890 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
9891 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
9900 thumb_shift (str
, shift
)
9904 int Rd
, Rs
, Rn
= FAIL
;
9906 skip_whitespace (str
);
9908 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
9909 || skip_past_comma (&str
) == FAIL
)
9912 inst
.error
= BAD_ARGS
;
9916 if (is_immediate_prefix (*str
))
9918 /* Two operand immediate format, set Rs to Rd. */
9921 if (my_get_expression (&inst
.reloc
.exp
, &str
))
9926 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
9929 if (skip_past_comma (&str
) == FAIL
)
9931 /* Two operand format, shuffle the registers
9932 and pretend there are 3. */
9936 else if (is_immediate_prefix (*str
))
9939 if (my_get_expression (&inst
.reloc
.exp
, &str
))
9942 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
9946 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
9947 for the latter case, EXPR contains the immediate that was found. */
9953 inst
.error
= _("source1 and dest must be same register");
9959 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
9960 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
9961 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
9964 inst
.instruction
|= Rd
| (Rn
<< 3);
9970 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
9971 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
9972 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
9975 if (inst
.reloc
.exp
.X_op
!= O_constant
)
9977 /* Value isn't known yet, create a dummy reloc and let reloc
9978 hacking fix it up. */
9979 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
9983 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
9985 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
9987 inst
.error
= _("invalid immediate for shift");
9991 /* Shifts of zero are handled by converting to LSL. */
9992 if (shift_value
== 0)
9993 inst
.instruction
= T_OPCODE_LSL_I
;
9995 /* Shifts of 32 are encoded as a shift of zero. */
9996 if (shift_value
== 32)
9999 inst
.instruction
|= shift_value
<< 6;
10002 inst
.instruction
|= Rd
| (Rs
<< 3);
10009 thumb_mov_compare (str
, move
)
10015 skip_whitespace (str
);
10017 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
10018 || skip_past_comma (&str
) == FAIL
)
10021 inst
.error
= BAD_ARGS
;
10025 if (move
!= THUMB_CPY
&& is_immediate_prefix (*str
))
10028 if (my_get_expression (&inst
.reloc
.exp
, &str
))
10031 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
10036 if (move
!= THUMB_CPY
&& Rs
< 8 && Rd
< 8)
10038 if (move
== THUMB_MOVE
)
10039 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
10040 since a MOV instruction produces unpredictable results. */
10041 inst
.instruction
= T_OPCODE_ADD_I3
;
10043 inst
.instruction
= T_OPCODE_CMP_LR
;
10044 inst
.instruction
|= Rd
| (Rs
<< 3);
10048 if (move
== THUMB_MOVE
)
10049 inst
.instruction
= T_OPCODE_MOV_HR
;
10050 else if (move
!= THUMB_CPY
)
10051 inst
.instruction
= T_OPCODE_CMP_HR
;
10054 inst
.instruction
|= THUMB_H1
;
10057 inst
.instruction
|= THUMB_H2
;
10059 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
10066 inst
.error
= _("only lo regs allowed with immediate");
10070 if (move
== THUMB_MOVE
)
10071 inst
.instruction
= T_OPCODE_MOV_I8
;
10073 inst
.instruction
= T_OPCODE_CMP_I8
;
10075 inst
.instruction
|= Rd
<< 8;
10077 if (inst
.reloc
.exp
.X_op
!= O_constant
)
10078 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
10081 unsigned value
= inst
.reloc
.exp
.X_add_number
;
10085 inst
.error
= _("invalid immediate");
10089 inst
.instruction
|= value
;
10097 thumb_load_store (str
, load_store
, size
)
10102 int Rd
, Rb
, Ro
= FAIL
;
10104 skip_whitespace (str
);
10106 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
10107 || skip_past_comma (&str
) == FAIL
)
10110 inst
.error
= BAD_ARGS
;
10117 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
10120 if (skip_past_comma (&str
) != FAIL
)
10122 if (is_immediate_prefix (*str
))
10125 if (my_get_expression (&inst
.reloc
.exp
, &str
))
10128 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
10133 inst
.reloc
.exp
.X_op
= O_constant
;
10134 inst
.reloc
.exp
.X_add_number
= 0;
10139 inst
.error
= _("expected ']'");
10144 else if (*str
== '=')
10146 if (load_store
!= THUMB_LOAD
)
10148 inst
.error
= _("invalid pseudo operation");
10152 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
10155 skip_whitespace (str
);
10157 if (my_get_expression (& inst
.reloc
.exp
, & str
))
10162 if ( inst
.reloc
.exp
.X_op
!= O_constant
10163 && inst
.reloc
.exp
.X_op
!= O_symbol
)
10165 inst
.error
= "Constant expression expected";
10169 if (inst
.reloc
.exp
.X_op
== O_constant
10170 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
10172 /* This can be done with a mov instruction. */
10174 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
10175 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
10179 /* Insert into literal pool. */
10180 if (add_to_lit_pool () == FAIL
)
10183 inst
.error
= "literal pool insertion failed";
10187 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
10188 inst
.reloc
.pc_rel
= 1;
10189 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
10190 /* Adjust ARM pipeline offset to Thumb. */
10191 inst
.reloc
.exp
.X_add_number
+= 4;
10197 if (my_get_expression (&inst
.reloc
.exp
, &str
))
10200 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
10201 inst
.reloc
.pc_rel
= 1;
10202 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
10203 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
10208 if (Rb
== REG_PC
|| Rb
== REG_SP
)
10210 if (size
!= THUMB_WORD
)
10212 inst
.error
= _("byte or halfword not valid for base register");
10215 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
10217 inst
.error
= _("r15 based store not allowed");
10220 else if (Ro
!= FAIL
)
10222 inst
.error
= _("invalid base register for register offset");
10227 inst
.instruction
= T_OPCODE_LDR_PC
;
10228 else if (load_store
== THUMB_LOAD
)
10229 inst
.instruction
= T_OPCODE_LDR_SP
;
10231 inst
.instruction
= T_OPCODE_STR_SP
;
10233 inst
.instruction
|= Rd
<< 8;
10234 if (inst
.reloc
.exp
.X_op
== O_constant
)
10236 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
10238 if (offset
& ~0x3fc)
10240 inst
.error
= _("invalid offset");
10244 inst
.instruction
|= offset
>> 2;
10247 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
10251 inst
.error
= _("invalid base register in load/store");
10254 else if (Ro
== FAIL
)
10256 /* Immediate offset. */
10257 if (size
== THUMB_WORD
)
10258 inst
.instruction
= (load_store
== THUMB_LOAD
10259 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
10260 else if (size
== THUMB_HALFWORD
)
10261 inst
.instruction
= (load_store
== THUMB_LOAD
10262 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
10264 inst
.instruction
= (load_store
== THUMB_LOAD
10265 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
10267 inst
.instruction
|= Rd
| (Rb
<< 3);
10269 if (inst
.reloc
.exp
.X_op
== O_constant
)
10271 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
10273 if (offset
& ~(0x1f << size
))
10275 inst
.error
= _("invalid offset");
10278 inst
.instruction
|= (offset
>> size
) << 6;
10281 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
10285 /* Register offset. */
10286 if (size
== THUMB_WORD
)
10287 inst
.instruction
= (load_store
== THUMB_LOAD
10288 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
10289 else if (size
== THUMB_HALFWORD
)
10290 inst
.instruction
= (load_store
== THUMB_LOAD
10291 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
10293 inst
.instruction
= (load_store
== THUMB_LOAD
10294 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
10296 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
10302 /* A register must be given at this point.
10304 Shift is the place to put it in inst.instruction.
10306 Restores input start point on err.
10307 Returns the reg#, or FAIL. */
10310 mav_reg_required_here (str
, shift
, regtype
)
10313 enum arm_reg_type regtype
;
10316 char *start
= *str
;
10318 if ((reg
= arm_reg_parse (str
, all_reg_maps
[regtype
].htab
)) != FAIL
)
10321 inst
.instruction
|= reg
<< shift
;
10326 /* Restore the start point. */
10329 /* In the few cases where we might be able to accept something else
10330 this error can be overridden. */
10331 inst
.error
= _(all_reg_maps
[regtype
].expected
);
10336 /* Cirrus Maverick Instructions. */
10338 /* Wrapper functions. */
10341 do_mav_binops_1a (str
)
10344 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_RN
, REG_TYPE_MVF
);
10348 do_mav_binops_1b (str
)
10351 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_RN
, REG_TYPE_MVD
);
10355 do_mav_binops_1c (str
)
10358 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_RN
, REG_TYPE_MVDX
);
10362 do_mav_binops_1d (str
)
10365 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVF
);
10369 do_mav_binops_1e (str
)
10372 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVD
);
10376 do_mav_binops_1f (str
)
10379 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVF
);
10383 do_mav_binops_1g (str
)
10386 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVD
);
10390 do_mav_binops_1h (str
)
10393 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVFX
);
10397 do_mav_binops_1i (str
)
10400 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVFX
);
10404 do_mav_binops_1j (str
)
10407 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVDX
);
10411 do_mav_binops_1k (str
)
10414 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVDX
);
10418 do_mav_binops_1l (str
)
10421 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVF
);
10425 do_mav_binops_1m (str
)
10428 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVD
);
10432 do_mav_binops_1n (str
)
10435 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
10439 do_mav_binops_1o (str
)
10442 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
10446 do_mav_binops_2a (str
)
10449 do_mav_binops (str
, MAV_MODE2
, REG_TYPE_MVF
, REG_TYPE_RN
);
10453 do_mav_binops_2b (str
)
10456 do_mav_binops (str
, MAV_MODE2
, REG_TYPE_MVD
, REG_TYPE_RN
);
10460 do_mav_binops_2c (str
)
10463 do_mav_binops (str
, MAV_MODE2
, REG_TYPE_MVDX
, REG_TYPE_RN
);
10467 do_mav_binops_3a (str
)
10470 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVAX
, REG_TYPE_MVFX
);
10474 do_mav_binops_3b (str
)
10477 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVFX
, REG_TYPE_MVAX
);
10481 do_mav_binops_3c (str
)
10484 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVAX
, REG_TYPE_MVDX
);
10488 do_mav_binops_3d (str
)
10491 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVDX
, REG_TYPE_MVAX
);
10495 do_mav_triple_4a (str
)
10498 do_mav_triple (str
, MAV_MODE4
, REG_TYPE_MVFX
, REG_TYPE_MVFX
, REG_TYPE_RN
);
10502 do_mav_triple_4b (str
)
10505 do_mav_triple (str
, MAV_MODE4
, REG_TYPE_MVDX
, REG_TYPE_MVDX
, REG_TYPE_RN
);
10509 do_mav_triple_5a (str
)
10512 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVF
, REG_TYPE_MVF
);
10516 do_mav_triple_5b (str
)
10519 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVD
, REG_TYPE_MVD
);
10523 do_mav_triple_5c (str
)
10526 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
10530 do_mav_triple_5d (str
)
10533 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
10537 do_mav_triple_5e (str
)
10540 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVF
, REG_TYPE_MVF
, REG_TYPE_MVF
);
10544 do_mav_triple_5f (str
)
10547 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVD
, REG_TYPE_MVD
, REG_TYPE_MVD
);
10551 do_mav_triple_5g (str
)
10554 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVFX
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
10558 do_mav_triple_5h (str
)
10561 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVDX
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
10565 do_mav_quad_6a (str
)
10568 do_mav_quad (str
, MAV_MODE6
, REG_TYPE_MVAX
, REG_TYPE_MVFX
, REG_TYPE_MVFX
,
10573 do_mav_quad_6b (str
)
10576 do_mav_quad (str
, MAV_MODE6
, REG_TYPE_MVAX
, REG_TYPE_MVAX
, REG_TYPE_MVFX
,
10580 /* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
10582 do_mav_dspsc_1 (str
)
10585 skip_whitespace (str
);
10588 if (mav_reg_required_here (&str
, -1, REG_TYPE_DSPSC
) == FAIL
10589 || skip_past_comma (&str
) == FAIL
10590 || mav_reg_required_here (&str
, 12, REG_TYPE_MVDX
) == FAIL
)
10593 inst
.error
= BAD_ARGS
;
10601 /* cfmv32sc<cond> MVDX[15:0],DSPSC. */
10603 do_mav_dspsc_2 (str
)
10606 skip_whitespace (str
);
10609 if (mav_reg_required_here (&str
, 12, REG_TYPE_MVDX
) == FAIL
10610 || skip_past_comma (&str
) == FAIL
10611 || mav_reg_required_here (&str
, -1, REG_TYPE_DSPSC
) == FAIL
)
10614 inst
.error
= BAD_ARGS
;
10623 do_mav_shift_1 (str
)
10626 do_mav_shift (str
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
10630 do_mav_shift_2 (str
)
10633 do_mav_shift (str
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
10637 do_mav_ldst_1 (str
)
10640 do_mav_ldst (str
, REG_TYPE_MVF
);
10644 do_mav_ldst_2 (str
)
10647 do_mav_ldst (str
, REG_TYPE_MVD
);
10651 do_mav_ldst_3 (str
)
10654 do_mav_ldst (str
, REG_TYPE_MVFX
);
10658 do_mav_ldst_4 (str
)
10661 do_mav_ldst (str
, REG_TYPE_MVDX
);
10664 /* Isnsn like "foo X,Y". */
10667 do_mav_binops (str
, mode
, reg0
, reg1
)
10670 enum arm_reg_type reg0
;
10671 enum arm_reg_type reg1
;
10673 int shift0
, shift1
;
10675 shift0
= mode
& 0xff;
10676 shift1
= (mode
>> 8) & 0xff;
10678 skip_whitespace (str
);
10680 if (mav_reg_required_here (&str
, shift0
, reg0
) == FAIL
10681 || skip_past_comma (&str
) == FAIL
10682 || mav_reg_required_here (&str
, shift1
, reg1
) == FAIL
)
10685 inst
.error
= BAD_ARGS
;
10691 /* Isnsn like "foo X,Y,Z". */
10694 do_mav_triple (str
, mode
, reg0
, reg1
, reg2
)
10697 enum arm_reg_type reg0
;
10698 enum arm_reg_type reg1
;
10699 enum arm_reg_type reg2
;
10701 int shift0
, shift1
, shift2
;
10703 shift0
= mode
& 0xff;
10704 shift1
= (mode
>> 8) & 0xff;
10705 shift2
= (mode
>> 16) & 0xff;
10707 skip_whitespace (str
);
10709 if (mav_reg_required_here (&str
, shift0
, reg0
) == FAIL
10710 || skip_past_comma (&str
) == FAIL
10711 || mav_reg_required_here (&str
, shift1
, reg1
) == FAIL
10712 || skip_past_comma (&str
) == FAIL
10713 || mav_reg_required_here (&str
, shift2
, reg2
) == FAIL
)
10716 inst
.error
= BAD_ARGS
;
10722 /* Isnsn like "foo W,X,Y,Z".
10723 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
10726 do_mav_quad (str
, mode
, reg0
, reg1
, reg2
, reg3
)
10729 enum arm_reg_type reg0
;
10730 enum arm_reg_type reg1
;
10731 enum arm_reg_type reg2
;
10732 enum arm_reg_type reg3
;
10734 int shift0
, shift1
, shift2
, shift3
;
10736 shift0
= mode
& 0xff;
10737 shift1
= (mode
>> 8) & 0xff;
10738 shift2
= (mode
>> 16) & 0xff;
10739 shift3
= (mode
>> 24) & 0xff;
10741 skip_whitespace (str
);
10743 if (mav_reg_required_here (&str
, shift0
, reg0
) == FAIL
10744 || skip_past_comma (&str
) == FAIL
10745 || mav_reg_required_here (&str
, shift1
, reg1
) == FAIL
10746 || skip_past_comma (&str
) == FAIL
10747 || mav_reg_required_here (&str
, shift2
, reg2
) == FAIL
10748 || skip_past_comma (&str
) == FAIL
10749 || mav_reg_required_here (&str
, shift3
, reg3
) == FAIL
)
10752 inst
.error
= BAD_ARGS
;
10758 /* Maverick shift immediate instructions.
10759 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10760 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
10763 do_mav_shift (str
, reg0
, reg1
)
10765 enum arm_reg_type reg0
;
10766 enum arm_reg_type reg1
;
10771 skip_whitespace (str
);
10775 if (mav_reg_required_here (&str
, 12, reg0
) == FAIL
10776 || skip_past_comma (&str
) == FAIL
10777 || mav_reg_required_here (&str
, 16, reg1
) == FAIL
10778 || skip_past_comma (&str
) == FAIL
)
10781 inst
.error
= BAD_ARGS
;
10785 /* Calculate the immediate operand.
10786 The operand is a 7bit signed number. */
10787 skip_whitespace (str
);
10792 if (!ISDIGIT (*str
) && *str
!= '-')
10794 inst
.error
= _("expecting immediate, 7bit operand");
10804 for (imm
= 0; *str
&& ISDIGIT (*str
); ++str
)
10805 imm
= imm
* 10 + *str
- '0';
10809 inst
.error
= _("immediate out of range");
10813 /* Make negative imm's into 7bit signed numbers. */
10820 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10821 Bits 5-7 of the insn should have bits 4-6 of the immediate.
10822 Bit 4 should be 0. */
10823 imm
= (imm
& 0xf) | ((imm
& 0x70) << 1);
10825 inst
.instruction
|= imm
;
10830 mav_parse_offset (str
, negative
)
10839 skip_whitespace (p
);
10852 inst
.error
= _("offset expected");
10856 for (offset
= 0; *p
&& ISDIGIT (*p
); ++p
)
10857 offset
= offset
* 10 + *p
- '0';
10861 inst
.error
= _("offset out of range");
10867 return *negative
? -offset
: offset
;
10870 /* Maverick load/store instructions.
10871 <insn><cond> CRd,[Rn,<offset>]{!}.
10872 <insn><cond> CRd,[Rn],<offset>. */
10875 do_mav_ldst (str
, reg0
)
10877 enum arm_reg_type reg0
;
10879 int offset
, negative
;
10881 skip_whitespace (str
);
10883 if (mav_reg_required_here (&str
, 12, reg0
) == FAIL
10884 || skip_past_comma (&str
) == FAIL
10886 || reg_required_here (&str
, 16) == FAIL
)
10889 if (skip_past_comma (&str
) == SUCCESS
)
10891 /* You are here: "<offset>]{!}". */
10892 inst
.instruction
|= PRE_INDEX
;
10894 offset
= mav_parse_offset (&str
, &negative
);
10901 inst
.error
= _("missing ]");
10907 inst
.instruction
|= WRITE_BACK
;
10913 /* You are here: "], <offset>". */
10916 inst
.error
= _("missing ]");
10920 if (skip_past_comma (&str
) == FAIL
10921 || (offset
= mav_parse_offset (&str
, &negative
), inst
.error
))
10924 inst
.instruction
|= CP_T_WB
; /* Post indexed, set bit W. */
10930 inst
.instruction
|= CP_T_UD
; /* Positive, so set bit U. */
10932 inst
.instruction
|= offset
>> 2;
10938 inst
.error
= BAD_ARGS
;
10949 /* Handle the Format 4 instructions that do not have equivalents in other
10950 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
10959 skip_whitespace (str
);
10961 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
10962 || skip_past_comma (&str
) == FAIL
10963 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
10965 inst
.error
= BAD_ARGS
;
10969 if (skip_past_comma (&str
) != FAIL
)
10971 /* Three operand format not allowed for TST, CMN, NEG and MVN.
10972 (It isn't allowed for CMP either, but that isn't handled by this
10974 if (inst
.instruction
== T_OPCODE_TST
10975 || inst
.instruction
== T_OPCODE_CMN
10976 || inst
.instruction
== T_OPCODE_NEG
10977 || inst
.instruction
== T_OPCODE_MVN
)
10979 inst
.error
= BAD_ARGS
;
10983 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
10988 inst
.error
= _("dest and source1 must be the same register");
10994 if (inst
.instruction
== T_OPCODE_MUL
10996 as_tsktsk (_("Rs and Rd must be different in MUL"));
10998 inst
.instruction
|= Rd
| (Rs
<< 3);
11006 thumb_add_sub (str
, 0);
11013 thumb_shift (str
, THUMB_ASR
);
11020 if (my_get_expression (&inst
.reloc
.exp
, &str
))
11022 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
11023 inst
.reloc
.pc_rel
= 1;
11028 do_t_branch12 (str
)
11031 if (my_get_expression (&inst
.reloc
.exp
, &str
))
11033 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
11034 inst
.reloc
.pc_rel
= 1;
11038 /* Find the real, Thumb encoded start of a Thumb function. */
11041 find_real_start (symbolP
)
11045 const char * name
= S_GET_NAME (symbolP
);
11046 symbolS
* new_target
;
11048 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
11049 #define STUB_NAME ".real_start_of"
11054 /* Names that start with '.' are local labels, not function entry points.
11055 The compiler may generate BL instructions to these labels because it
11056 needs to perform a branch to a far away location. */
11057 if (name
[0] == '.')
11060 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
11061 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
11063 new_target
= symbol_find (real_start
);
11065 if (new_target
== NULL
)
11067 as_warn ("Failed to find real start of function: %s\n", name
);
11068 new_target
= symbolP
;
11077 do_t_branch23 (str
)
11080 if (my_get_expression (& inst
.reloc
.exp
, & str
))
11083 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
11084 inst
.reloc
.pc_rel
= 1;
11087 /* If the destination of the branch is a defined symbol which does not have
11088 the THUMB_FUNC attribute, then we must be calling a function which has
11089 the (interfacearm) attribute. We look for the Thumb entry point to that
11090 function and change the branch to refer to that function instead. */
11091 if ( inst
.reloc
.exp
.X_op
== O_symbol
11092 && inst
.reloc
.exp
.X_add_symbol
!= NULL
11093 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
11094 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
11095 inst
.reloc
.exp
.X_add_symbol
=
11096 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
11105 skip_whitespace (str
);
11107 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
11110 /* This sets THUMB_H2 from the top bit of reg. */
11111 inst
.instruction
|= reg
<< 3;
11113 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
11114 should cause the alignment to be checked once it is known. This is
11115 because BX PC only works if the instruction is word aligned. */
11124 thumb_mov_compare (str
, THUMB_COMPARE
);
11134 skip_whitespace (str
);
11136 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
11140 as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
11144 if (skip_past_comma (&str
) == FAIL
11145 || (range
= reg_list (&str
)) == FAIL
)
11148 inst
.error
= BAD_ARGS
;
11152 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
11154 /* This really doesn't seem worth it. */
11155 inst
.reloc
.type
= BFD_RELOC_NONE
;
11156 inst
.error
= _("expression too complex");
11162 inst
.error
= _("only lo-regs valid in load/store multiple");
11166 inst
.instruction
|= (Rb
<< 8) | range
;
11174 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
11181 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
11188 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
11197 skip_whitespace (str
);
11199 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
11200 || skip_past_comma (&str
) == FAIL
11202 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
11203 || skip_past_comma (&str
) == FAIL
11204 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
11208 inst
.error
= _("syntax: ldrs[b] Rd, [Rb, Ro]");
11212 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
11220 thumb_shift (str
, THUMB_LSL
);
11227 thumb_shift (str
, THUMB_LSR
);
11234 thumb_mov_compare (str
, THUMB_MOVE
);
11238 do_t_push_pop (str
)
11243 skip_whitespace (str
);
11245 if ((range
= reg_list (&str
)) == FAIL
)
11248 inst
.error
= BAD_ARGS
;
11252 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
11254 /* This really doesn't seem worth it. */
11255 inst
.reloc
.type
= BFD_RELOC_NONE
;
11256 inst
.error
= _("expression too complex");
11262 if ((inst
.instruction
== T_OPCODE_PUSH
11263 && (range
& ~0xff) == 1 << REG_LR
)
11264 || (inst
.instruction
== T_OPCODE_POP
11265 && (range
& ~0xff) == 1 << REG_PC
))
11267 inst
.instruction
|= THUMB_PP_PC_LR
;
11272 inst
.error
= _("invalid register list to push/pop instruction");
11277 inst
.instruction
|= range
;
11285 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
11292 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
11299 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
11306 thumb_add_sub (str
, 1);
11313 skip_whitespace (str
);
11315 if (my_get_expression (&inst
.reloc
.exp
, &str
))
11318 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
11328 /* This is a pseudo-op of the form "adr rd, label" to be converted
11329 into a relative address of the form "add rd, pc, #label-.-4". */
11330 skip_whitespace (str
);
11332 /* Store Rd in temporary location inside instruction. */
11333 if ((reg
= reg_required_here (&str
, 4)) == FAIL
11334 || (reg
> 7) /* For Thumb reg must be r0..r7. */
11335 || skip_past_comma (&str
) == FAIL
11336 || my_get_expression (&inst
.reloc
.exp
, &str
))
11339 inst
.error
= BAD_ARGS
;
11343 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
11344 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
11345 inst
.reloc
.pc_rel
= 1;
11346 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
11352 insert_reg (r
, htab
)
11353 const struct reg_entry
*r
;
11354 struct hash_control
*htab
;
11356 int len
= strlen (r
->name
) + 2;
11357 char * buf
= (char *) xmalloc (len
);
11358 char * buf2
= (char *) xmalloc (len
);
11361 #ifdef REGISTER_PREFIX
11362 buf
[i
++] = REGISTER_PREFIX
;
11365 strcpy (buf
+ i
, r
->name
);
11367 for (i
= 0; buf
[i
]; i
++)
11368 buf2
[i
] = TOUPPER (buf
[i
]);
11372 hash_insert (htab
, buf
, (PTR
) r
);
11373 hash_insert (htab
, buf2
, (PTR
) r
);
11377 build_reg_hsh (map
)
11378 struct reg_map
*map
;
11380 const struct reg_entry
*r
;
11382 if ((map
->htab
= hash_new ()) == NULL
)
11383 as_fatal (_("virtual memory exhausted"));
11385 for (r
= map
->names
; r
->name
!= NULL
; r
++)
11386 insert_reg (r
, map
->htab
);
11390 insert_reg_alias (str
, regnum
, htab
)
11393 struct hash_control
*htab
;
11396 struct reg_entry
*new = xmalloc (sizeof (struct reg_entry
));
11397 const char *name
= xmalloc (strlen (str
) + 1);
11399 strcpy ((char *) name
, str
);
11402 new->number
= regnum
;
11403 new->builtin
= FALSE
;
11405 error
= hash_insert (htab
, name
, (PTR
) new);
11408 as_bad (_("failed to create an alias for %s, reason: %s"),
11410 free ((char *) name
);
11415 /* Look for the .req directive. This is of the form:
11417 new_register_name .req existing_register_name
11419 If we find one, or if it looks sufficiently like one that we want to
11420 handle any error here, return non-zero. Otherwise return zero. */
11422 create_register_alias (newname
, p
)
11430 skip_whitespace (q
);
11435 if (*q
&& !strncmp (q
, ".req ", 5))
11440 #ifdef IGNORE_OPCODE_CASE
11441 newname
= original_case_string
;
11443 copy_of_str
= newname
;
11446 skip_whitespace (q
);
11448 for (r
= q
; *r
!= '\0'; r
++)
11454 enum arm_reg_type new_type
, old_type
;
11459 old_type
= arm_reg_parse_any (q
);
11462 new_type
= arm_reg_parse_any (newname
);
11464 if (new_type
== REG_TYPE_MAX
)
11466 if (old_type
!= REG_TYPE_MAX
)
11468 old_regno
= arm_reg_parse (&q
, all_reg_maps
[old_type
].htab
);
11469 insert_reg_alias (newname
, old_regno
,
11470 all_reg_maps
[old_type
].htab
);
11473 as_warn (_("register '%s' does not exist\n"), q
);
11475 else if (old_type
== REG_TYPE_MAX
)
11477 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
11482 /* Do not warn about redefinitions to the same alias. */
11483 if (new_type
!= old_type
11484 || (arm_reg_parse (&q
, all_reg_maps
[old_type
].htab
)
11485 != arm_reg_parse (&q
, all_reg_maps
[new_type
].htab
)))
11486 as_warn (_("ignoring redefinition of register alias '%s'"),
11492 as_warn (_("ignoring incomplete .req pseuso op"));
11503 set_constant_flonums ()
11507 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
11508 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
11512 /* Iterate over the base tables to create the instruction patterns. */
11514 build_arm_ops_hsh ()
11518 static struct obstack insn_obstack
;
11520 obstack_begin (&insn_obstack
, 4000);
11522 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
11524 const struct asm_opcode
*insn
= insns
+ i
;
11526 if (insn
->cond_offset
!= 0)
11528 /* Insn supports conditional execution. Build the varaints
11529 and insert them in the hash table. */
11530 for (j
= 0; j
< sizeof (conds
) / sizeof (struct asm_cond
); j
++)
11532 unsigned len
= strlen (insn
->template);
11533 struct asm_opcode
*new;
11536 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
11537 /* All condition codes are two characters. */
11538 template = obstack_alloc (&insn_obstack
, len
+ 3);
11540 strncpy (template, insn
->template, insn
->cond_offset
);
11541 strcpy (template + insn
->cond_offset
, conds
[j
].template);
11542 if (len
> insn
->cond_offset
)
11543 strcpy (template + insn
->cond_offset
+ 2,
11544 insn
->template + insn
->cond_offset
);
11545 new->template = template;
11546 new->cond_offset
= 0;
11547 new->variant
= insn
->variant
;
11548 new->parms
= insn
->parms
;
11549 new->value
= (insn
->value
& ~COND_MASK
) | conds
[j
].value
;
11551 hash_insert (arm_ops_hsh
, new->template, (PTR
) new);
11554 /* Finally, insert the unconditional insn in the table directly;
11555 no need to build a copy. */
11556 hash_insert (arm_ops_hsh
, insn
->template, (PTR
) insn
);
11560 #if 0 /* Suppressed - for now. */
11561 #if defined OBJ_ELF || defined OBJ_COFF
11564 #define arm_Note Elf_External_Note
11568 unsigned char namesz
[4]; /* Size of entry's owner string. */
11569 unsigned char descsz
[4]; /* Size of the note descriptor. */
11570 unsigned char type
[4]; /* Interpretation of the descriptor. */
11571 char name
[1]; /* Start of the name+desc data. */
11575 /* The description is kept to a fix sized in order to make updating
11576 it and merging it easier. */
11577 #define ARM_NOTE_DESCRIPTION_LENGTH 8
11580 arm_add_note (name
, description
, type
)
11582 const char * description
;
11585 arm_Note note ATTRIBUTE_UNUSED
;
11587 unsigned int name_len
;
11589 name_len
= (strlen (name
) + 1 + 3) & ~3;
11591 p
= frag_more (sizeof (note
.namesz
));
11592 md_number_to_chars (p
, (valueT
) name_len
, sizeof (note
.namesz
));
11594 p
= frag_more (sizeof (note
.descsz
));
11595 md_number_to_chars (p
, (valueT
) ARM_NOTE_DESCRIPTION_LENGTH
, sizeof (note
.descsz
));
11597 p
= frag_more (sizeof (note
.type
));
11598 md_number_to_chars (p
, (valueT
) type
, sizeof (note
.type
));
11600 p
= frag_more (name_len
);
11603 p
= frag_more (ARM_NOTE_DESCRIPTION_LENGTH
);
11604 strncpy (p
, description
, ARM_NOTE_DESCRIPTION_LENGTH
);
11605 frag_align (2, 0, 0);
11616 if ( (arm_ops_hsh
= hash_new ()) == NULL
11617 || (arm_tops_hsh
= hash_new ()) == NULL
11618 || (arm_cond_hsh
= hash_new ()) == NULL
11619 || (arm_shift_hsh
= hash_new ()) == NULL
11620 || (arm_psr_hsh
= hash_new ()) == NULL
)
11621 as_fatal (_("virtual memory exhausted"));
11623 build_arm_ops_hsh ();
11624 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
11625 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
11626 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
11627 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
11628 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
11629 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
11630 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
11631 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
11633 for (i
= (int) REG_TYPE_FIRST
; i
< (int) REG_TYPE_MAX
; i
++)
11634 build_reg_hsh (all_reg_maps
+ i
);
11636 set_constant_flonums ();
11638 /* Set the cpu variant based on the command-line options. We prefer
11639 -mcpu= over -march= if both are set (as for GCC); and we prefer
11640 -mfpu= over any other way of setting the floating point unit.
11641 Use of legacy options with new options are faulted. */
11642 if (legacy_cpu
!= -1)
11644 if (mcpu_cpu_opt
!= -1 || march_cpu_opt
!= -1)
11645 as_bad (_("use of old and new-style options to set CPU type"));
11647 mcpu_cpu_opt
= legacy_cpu
;
11649 else if (mcpu_cpu_opt
== -1)
11650 mcpu_cpu_opt
= march_cpu_opt
;
11652 if (legacy_fpu
!= -1)
11654 if (mfpu_opt
!= -1)
11655 as_bad (_("use of old and new-style options to set FPU type"));
11657 mfpu_opt
= legacy_fpu
;
11659 else if (mfpu_opt
== -1)
11661 #if !(defined (TE_LINUX) || defined (TE_NetBSD))
11662 /* Some environments specify a default FPU. If they don't, infer it
11663 from the processor. */
11664 if (mcpu_fpu_opt
!= -1)
11665 mfpu_opt
= mcpu_fpu_opt
;
11667 mfpu_opt
= march_fpu_opt
;
11669 mfpu_opt
= FPU_DEFAULT
;
11673 if (mfpu_opt
== -1)
11675 if (mcpu_cpu_opt
== -1)
11676 mfpu_opt
= FPU_DEFAULT
;
11677 else if (mcpu_cpu_opt
& ARM_EXT_V5
)
11678 mfpu_opt
= FPU_ARCH_VFP_V2
;
11680 mfpu_opt
= FPU_ARCH_FPA
;
11683 if (mcpu_cpu_opt
== -1)
11684 mcpu_cpu_opt
= CPU_DEFAULT
;
11686 cpu_variant
= mcpu_cpu_opt
| mfpu_opt
;
11688 #if defined OBJ_COFF || defined OBJ_ELF
11690 unsigned int flags
= 0;
11692 /* Set the flags in the private structure. */
11693 if (uses_apcs_26
) flags
|= F_APCS26
;
11694 if (support_interwork
) flags
|= F_INTERWORK
;
11695 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
11696 if (pic_code
) flags
|= F_PIC
;
11697 if ((cpu_variant
& FPU_ANY
) == FPU_NONE
11698 || (cpu_variant
& FPU_ANY
) == FPU_ARCH_VFP
) /* VFP layout only. */
11700 flags
|= F_SOFT_FLOAT
;
11702 switch (mfloat_abi_opt
)
11704 case ARM_FLOAT_ABI_SOFT
:
11705 case ARM_FLOAT_ABI_SOFTFP
:
11706 flags
|= F_SOFT_FLOAT
;
11709 case ARM_FLOAT_ABI_HARD
:
11710 if (flags
& F_SOFT_FLOAT
)
11711 as_bad (_("hard-float conflicts with specified fpu"));
11714 /* Using VFP conventions (even if soft-float). */
11715 if (cpu_variant
& FPU_VFP_EXT_NONE
) flags
|= F_VFP_FLOAT
;
11717 #if defined OBJ_ELF
11718 if (cpu_variant
& FPU_ARCH_MAVERICK
)
11719 flags
|= EF_ARM_MAVERICK_FLOAT
;
11722 bfd_set_private_flags (stdoutput
, flags
);
11724 /* We have run out flags in the COFF header to encode the
11725 status of ATPCS support, so instead we create a dummy,
11726 empty, debug section called .arm.atpcs. */
11731 sec
= bfd_make_section (stdoutput
, ".arm.atpcs");
11735 bfd_set_section_flags
11736 (stdoutput
, sec
, SEC_READONLY
| SEC_DEBUGGING
/* | SEC_HAS_CONTENTS */);
11737 bfd_set_section_size (stdoutput
, sec
, 0);
11738 bfd_set_section_contents (stdoutput
, sec
, NULL
, 0, 0);
11744 /* Record the CPU type as well. */
11745 switch (cpu_variant
& ARM_CPU_MASK
)
11748 mach
= bfd_mach_arm_2
;
11751 case ARM_3
: /* Also ARM_250. */
11752 mach
= bfd_mach_arm_2a
;
11755 case ARM_6
: /* Also ARM_7. */
11756 mach
= bfd_mach_arm_3
;
11760 mach
= bfd_mach_arm_unknown
;
11764 /* Catch special cases. */
11765 if (cpu_variant
& ARM_CEXT_IWMMXT
)
11766 mach
= bfd_mach_arm_iWMMXt
;
11767 else if (cpu_variant
& ARM_CEXT_XSCALE
)
11768 mach
= bfd_mach_arm_XScale
;
11769 else if (cpu_variant
& ARM_CEXT_MAVERICK
)
11770 mach
= bfd_mach_arm_ep9312
;
11771 else if (cpu_variant
& ARM_EXT_V5E
)
11772 mach
= bfd_mach_arm_5TE
;
11773 else if (cpu_variant
& ARM_EXT_V5
)
11775 if (cpu_variant
& ARM_EXT_V4T
)
11776 mach
= bfd_mach_arm_5T
;
11778 mach
= bfd_mach_arm_5
;
11780 else if (cpu_variant
& ARM_EXT_V4
)
11782 if (cpu_variant
& ARM_EXT_V4T
)
11783 mach
= bfd_mach_arm_4T
;
11785 mach
= bfd_mach_arm_4
;
11787 else if (cpu_variant
& ARM_EXT_V3M
)
11788 mach
= bfd_mach_arm_3M
;
11790 #if 0 /* Suppressed - for now. */
11791 #if defined (OBJ_ELF) || defined (OBJ_COFF)
11793 /* Create a .note section to fully identify this arm binary. */
11795 #define NOTE_ARCH_STRING "arch: "
11797 #if defined OBJ_COFF && ! defined NT_VERSION
11798 #define NT_VERSION 1
11803 segT current_seg
= now_seg
;
11804 subsegT current_subseg
= now_subseg
;
11805 asection
* arm_arch
;
11806 const char * arch_string
;
11808 arm_arch
= bfd_make_section_old_way (stdoutput
, ARM_NOTE_SECTION
);
11811 bfd_set_section_flags (stdoutput
, arm_arch
,
11812 SEC_DATA
| SEC_ALLOC
| SEC_LOAD
| SEC_LINK_ONCE \
11813 | SEC_HAS_CONTENTS
);
11815 bfd_set_section_flags (stdoutput
, arm_arch
,
11816 SEC_READONLY
| SEC_HAS_CONTENTS
);
11818 arm_arch
->output_section
= arm_arch
;
11819 subseg_set (arm_arch
, 0);
11824 case bfd_mach_arm_unknown
: arch_string
= "unknown"; break;
11825 case bfd_mach_arm_2
: arch_string
= "armv2"; break;
11826 case bfd_mach_arm_2a
: arch_string
= "armv2a"; break;
11827 case bfd_mach_arm_3
: arch_string
= "armv3"; break;
11828 case bfd_mach_arm_3M
: arch_string
= "armv3M"; break;
11829 case bfd_mach_arm_4
: arch_string
= "armv4"; break;
11830 case bfd_mach_arm_4T
: arch_string
= "armv4t"; break;
11831 case bfd_mach_arm_5
: arch_string
= "armv5"; break;
11832 case bfd_mach_arm_5T
: arch_string
= "armv5t"; break;
11833 case bfd_mach_arm_5TE
: arch_string
= "armv5te"; break;
11834 case bfd_mach_arm_XScale
: arch_string
= "XScale"; break;
11835 case bfd_mach_arm_ep9312
: arch_string
= "ep9312"; break;
11836 case bfd_mach_arm_iWMMXt
: arch_string
= "iWMMXt"; break;
11839 arm_add_note (NOTE_ARCH_STRING
, arch_string
, NT_ARCH
);
11841 subseg_set (current_seg
, current_subseg
);
11844 #endif /* Suppressed code. */
11846 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
11849 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
11850 for use in the a.out file, and stores them in the array pointed to by buf.
11851 This knows about the endian-ness of the target machine and does
11852 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
11853 2 (short) and 4 (long) Floating numbers are put out as a series of
11854 LITTLENUMS (shorts, here at least). */
11857 md_number_to_chars (buf
, val
, n
)
11862 if (target_big_endian
)
11863 number_to_chars_bigendian (buf
, val
, n
);
11865 number_to_chars_littleendian (buf
, val
, n
);
11869 md_chars_to_number (buf
, n
)
11874 unsigned char * where
= (unsigned char *) buf
;
11876 if (target_big_endian
)
11881 result
|= (*where
++ & 255);
11889 result
|= (where
[n
] & 255);
11896 /* Turn a string in input_line_pointer into a floating point constant
11897 of type TYPE, and store the appropriate bytes in *LITP. The number
11898 of LITTLENUMS emitted is stored in *SIZEP. An error message is
11899 returned, or NULL on OK.
11901 Note that fp constants aren't represent in the normal way on the ARM.
11902 In big endian mode, things are as expected. However, in little endian
11903 mode fp constants are big-endian word-wise, and little-endian byte-wise
11904 within the words. For example, (double) 1.1 in big endian mode is
11905 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
11906 the byte sequence 99 99 f1 3f 9a 99 99 99.
11908 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
11911 md_atof (type
, litP
, sizeP
)
11917 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
11949 return _("bad call to MD_ATOF()");
11952 t
= atof_ieee (input_line_pointer
, type
, words
);
11954 input_line_pointer
= t
;
11957 if (target_big_endian
)
11959 for (i
= 0; i
< prec
; i
++)
11961 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
11967 if (cpu_variant
& FPU_ARCH_VFP
)
11968 for (i
= prec
- 1; i
>= 0; i
--)
11970 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
11974 /* For a 4 byte float the order of elements in `words' is 1 0.
11975 For an 8 byte float the order is 1 0 3 2. */
11976 for (i
= 0; i
< prec
; i
+= 2)
11978 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
11979 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
11987 /* The knowledge of the PC's pipeline offset is built into the insns
11991 md_pcrel_from (fixP
)
11995 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
11996 && fixP
->fx_subsy
== NULL
)
11999 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
12001 /* PC relative addressing on the Thumb is slightly odd
12002 as the bottom two bits of the PC are forced to zero
12003 for the calculation. */
12004 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
12008 /* The pattern was adjusted to accommodate CE's off-by-one fixups,
12009 so we un-adjust here to compensate for the accommodation. */
12010 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
12012 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
12016 /* Round up a section size to the appropriate boundary. */
12019 md_section_align (segment
, size
)
12020 segT segment ATTRIBUTE_UNUSED
;
12026 /* Round all sects to multiple of 4. */
12027 return (size
+ 3) & ~3;
12031 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
12032 Otherwise we have no need to default values of symbols. */
12035 md_undefined_symbol (name
)
12036 char * name ATTRIBUTE_UNUSED
;
12039 if (name
[0] == '_' && name
[1] == 'G'
12040 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
12044 if (symbol_find (name
))
12045 as_bad ("GOT already in the symbol table");
12047 GOT_symbol
= symbol_new (name
, undefined_section
,
12048 (valueT
) 0, & zero_address_frag
);
12058 /* arm_reg_parse () := if it looks like a register, return its token and
12059 advance the pointer. */
12062 arm_reg_parse (ccp
, htab
)
12063 register char ** ccp
;
12064 struct hash_control
*htab
;
12066 char * start
= * ccp
;
12069 struct reg_entry
* reg
;
12071 #ifdef REGISTER_PREFIX
12072 if (*start
!= REGISTER_PREFIX
)
12077 #ifdef OPTIONAL_REGISTER_PREFIX
12078 if (*p
== OPTIONAL_REGISTER_PREFIX
)
12082 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
12086 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
12090 reg
= (struct reg_entry
*) hash_find (htab
, start
);
12096 return reg
->number
;
12102 /* Search for the following register name in each of the possible reg name
12103 tables. Return the classification if found, or REG_TYPE_MAX if not
12105 static enum arm_reg_type
12106 arm_reg_parse_any (cp
)
12111 for (i
= (int) REG_TYPE_FIRST
; i
< (int) REG_TYPE_MAX
; i
++)
12112 if (arm_reg_parse (&cp
, all_reg_maps
[i
].htab
) != FAIL
)
12113 return (enum arm_reg_type
) i
;
12115 return REG_TYPE_MAX
;
12119 md_apply_fix3 (fixP
, valP
, seg
)
12124 offsetT value
= * valP
;
12126 unsigned int newimm
;
12127 unsigned long temp
;
12129 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
12130 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
12132 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
12134 /* Note whether this will delete the relocation. */
12136 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
12137 doesn't work fully.) */
12138 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
12139 && !fixP
->fx_pcrel
)
12141 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
12145 /* If this symbol is in a different section then we need to leave it for
12146 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
12147 so we have to undo it's effects here. */
12148 if (fixP
->fx_pcrel
)
12150 if (fixP
->fx_addsy
!= NULL
12151 && S_IS_DEFINED (fixP
->fx_addsy
)
12152 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
12155 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
12156 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
12160 value
+= md_pcrel_from (fixP
);
12164 /* Remember value for emit_reloc. */
12165 fixP
->fx_addnumber
= value
;
12167 switch (fixP
->fx_r_type
)
12169 case BFD_RELOC_ARM_IMMEDIATE
:
12170 newimm
= validate_immediate (value
);
12171 temp
= md_chars_to_number (buf
, INSN_SIZE
);
12173 /* If the instruction will fail, see if we can fix things up by
12174 changing the opcode. */
12175 if (newimm
== (unsigned int) FAIL
12176 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
12178 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12179 _("invalid constant (%lx) after fixup"),
12180 (unsigned long) value
);
12184 newimm
|= (temp
& 0xfffff000);
12185 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
12189 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
12191 unsigned int highpart
= 0;
12192 unsigned int newinsn
= 0xe1a00000; /* nop. */
12194 newimm
= validate_immediate (value
);
12195 temp
= md_chars_to_number (buf
, INSN_SIZE
);
12197 /* If the instruction will fail, see if we can fix things up by
12198 changing the opcode. */
12199 if (newimm
== (unsigned int) FAIL
12200 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
12202 /* No ? OK - try using two ADD instructions to generate
12204 newimm
= validate_immediate_twopart (value
, & highpart
);
12206 /* Yes - then make sure that the second instruction is
12208 if (newimm
!= (unsigned int) FAIL
)
12210 /* Still No ? Try using a negated value. */
12211 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
12212 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
12213 /* Otherwise - give up. */
12216 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12217 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
12222 /* Replace the first operand in the 2nd instruction (which
12223 is the PC) with the destination register. We have
12224 already added in the PC in the first instruction and we
12225 do not want to do it again. */
12226 newinsn
&= ~ 0xf0000;
12227 newinsn
|= ((newinsn
& 0x0f000) << 4);
12230 newimm
|= (temp
& 0xfffff000);
12231 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
12233 highpart
|= (newinsn
& 0xfffff000);
12234 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
12238 case BFD_RELOC_ARM_OFFSET_IMM
:
12244 if (validate_offset_imm (value
, 0) == FAIL
)
12246 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12247 _("bad immediate value for offset (%ld)"),
12252 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12253 newval
&= 0xff7ff000;
12254 newval
|= value
| (sign
? INDEX_UP
: 0);
12255 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12258 case BFD_RELOC_ARM_OFFSET_IMM8
:
12259 case BFD_RELOC_ARM_HWLITERAL
:
12265 if (validate_offset_imm (value
, 1) == FAIL
)
12267 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
12268 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12269 _("invalid literal constant: pool needs to be closer"));
12271 as_bad (_("bad immediate value for half-word offset (%ld)"),
12276 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12277 newval
&= 0xff7ff0f0;
12278 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
12279 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12282 case BFD_RELOC_ARM_LITERAL
:
12288 if (validate_offset_imm (value
, 0) == FAIL
)
12290 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12291 _("invalid literal constant: pool needs to be closer"));
12295 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12296 newval
&= 0xff7ff000;
12297 newval
|= value
| (sign
? INDEX_UP
: 0);
12298 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12301 case BFD_RELOC_ARM_SHIFT_IMM
:
12302 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12303 if (((unsigned long) value
) > 32
12305 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
12307 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12308 _("shift expression is too large"));
12313 /* Shifts of zero must be done as lsl. */
12315 else if (value
== 32)
12317 newval
&= 0xfffff07f;
12318 newval
|= (value
& 0x1f) << 7;
12319 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12322 case BFD_RELOC_ARM_SWI
:
12323 if (arm_data
->thumb_mode
)
12325 if (((unsigned long) value
) > 0xff)
12326 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12327 _("invalid swi expression"));
12328 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
12330 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12334 if (((unsigned long) value
) > 0x00ffffff)
12335 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12336 _("invalid swi expression"));
12337 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
12339 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12343 case BFD_RELOC_ARM_MULTI
:
12344 if (((unsigned long) value
) > 0xffff)
12345 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12346 _("invalid expression in load/store multiple"));
12347 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
12348 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12351 case BFD_RELOC_ARM_PCREL_BRANCH
:
12352 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12354 /* Sign-extend a 24-bit number. */
12355 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
12359 value
= fixP
->fx_offset
;
12362 /* We are going to store value (shifted right by two) in the
12363 instruction, in a 24 bit, signed field. Thus we need to check
12364 that none of the top 8 bits of the shifted value (top 7 bits of
12365 the unshifted, unsigned value) are set, or that they are all set. */
12366 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
12367 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
12370 /* Normally we would be stuck at this point, since we cannot store
12371 the absolute address that is the destination of the branch in the
12372 24 bits of the branch instruction. If however, we happen to know
12373 that the destination of the branch is in the same section as the
12374 branch instruction itself, then we can compute the relocation for
12375 ourselves and not have to bother the linker with it.
12377 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
12378 because I have not worked out how to do this for OBJ_COFF or
12381 && fixP
->fx_addsy
!= NULL
12382 && S_IS_DEFINED (fixP
->fx_addsy
)
12383 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
12385 /* Get pc relative value to go into the branch. */
12388 /* Permit a backward branch provided that enough bits
12389 are set. Allow a forwards branch, provided that
12390 enough bits are clear. */
12391 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
12392 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
12396 if (! fixP
->fx_done
)
12398 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12399 _("GAS can't handle same-section branch dest >= 0x04000000"));
12403 value
+= SEXT24 (newval
);
12405 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
12406 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
12407 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12408 _("out of range branch"));
12410 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
12411 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12414 case BFD_RELOC_ARM_PCREL_BLX
:
12417 newval
= md_chars_to_number (buf
, INSN_SIZE
);
12421 value
= fixP
->fx_offset
;
12423 hbit
= (value
>> 1) & 1;
12424 value
= (value
>> 2) & 0x00ffffff;
12425 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
12426 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
12427 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12431 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
12432 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12434 addressT diff
= (newval
& 0xff) << 1;
12439 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
12440 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12441 _("branch out of range"));
12442 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
12444 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12447 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
12448 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12450 addressT diff
= (newval
& 0x7ff) << 1;
12455 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
12456 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12457 _("branch out of range"));
12458 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
12460 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12463 case BFD_RELOC_THUMB_PCREL_BLX
:
12464 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
12469 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12470 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
12471 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
12472 if (diff
& 0x400000)
12475 value
= fixP
->fx_offset
;
12479 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
12480 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12481 _("branch with link out of range"));
12483 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
12484 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
12485 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
)
12486 /* For a BLX instruction, make sure that the relocation is rounded up
12487 to a word boundary. This follows the semantics of the instruction
12488 which specifies that bit 1 of the target address will come from bit
12489 1 of the base address. */
12490 newval2
= (newval2
+ 1) & ~ 1;
12491 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12492 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
12497 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
12498 md_number_to_chars (buf
, value
, 1);
12500 else if (!target_oabi
)
12502 value
= fixP
->fx_offset
;
12503 md_number_to_chars (buf
, value
, 1);
12509 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
12510 md_number_to_chars (buf
, value
, 2);
12512 else if (!target_oabi
)
12514 value
= fixP
->fx_offset
;
12515 md_number_to_chars (buf
, value
, 2);
12521 case BFD_RELOC_ARM_GOT32
:
12522 case BFD_RELOC_ARM_GOTOFF
:
12523 md_number_to_chars (buf
, 0, 4);
12527 case BFD_RELOC_RVA
:
12529 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
12530 md_number_to_chars (buf
, value
, 4);
12532 else if (!target_oabi
)
12534 value
= fixP
->fx_offset
;
12535 md_number_to_chars (buf
, value
, 4);
12541 case BFD_RELOC_ARM_PLT32
:
12542 /* It appears the instruction is fully prepared at this point. */
12546 case BFD_RELOC_ARM_CP_OFF_IMM
:
12548 if (value
< -1023 || value
> 1023 || (value
& 3))
12549 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12550 _("illegal value for co-processor offset"));
12553 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
12554 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
12555 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12558 case BFD_RELOC_ARM_CP_OFF_IMM_S2
:
12560 if (value
< -255 || value
> 255)
12561 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12562 _("Illegal value for co-processor offset"));
12565 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
12566 newval
|= value
| (sign
? INDEX_UP
: 0);
12567 md_number_to_chars (buf
, newval
, INSN_SIZE
);
12570 case BFD_RELOC_ARM_THUMB_OFFSET
:
12571 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12572 /* Exactly what ranges, and where the offset is inserted depends
12573 on the type of instruction, we can establish this from the
12575 switch (newval
>> 12)
12577 case 4: /* PC load. */
12578 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
12579 forced to zero for these loads, so we will need to round
12580 up the offset if the instruction address is not word
12581 aligned (since the final address produced must be, and
12582 we can only describe word-aligned immediate offsets). */
12584 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
12585 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12586 _("invalid offset, target not word aligned (0x%08X)"),
12587 (unsigned int) (fixP
->fx_frag
->fr_address
12588 + fixP
->fx_where
+ value
));
12590 if ((value
+ 2) & ~0x3fe)
12591 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12592 _("invalid offset, value too big (0x%08lX)"),
12595 /* Round up, since pc will be rounded down. */
12596 newval
|= (value
+ 2) >> 2;
12599 case 9: /* SP load/store. */
12600 if (value
& ~0x3fc)
12601 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12602 _("invalid offset, value too big (0x%08lX)"),
12604 newval
|= value
>> 2;
12607 case 6: /* Word load/store. */
12609 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12610 _("invalid offset, value too big (0x%08lX)"),
12612 newval
|= value
<< 4; /* 6 - 2. */
12615 case 7: /* Byte load/store. */
12617 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12618 _("invalid offset, value too big (0x%08lX)"),
12620 newval
|= value
<< 6;
12623 case 8: /* Halfword load/store. */
12625 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12626 _("invalid offset, value too big (0x%08lX)"),
12628 newval
|= value
<< 5; /* 6 - 1. */
12632 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12633 "Unable to process relocation for thumb opcode: %lx",
12634 (unsigned long) newval
);
12637 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12640 case BFD_RELOC_ARM_THUMB_ADD
:
12641 /* This is a complicated relocation, since we use it for all of
12642 the following immediate relocations:
12646 9bit ADD/SUB SP word-aligned
12647 10bit ADD PC/SP word-aligned
12649 The type of instruction being processed is encoded in the
12656 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12658 int rd
= (newval
>> 4) & 0xf;
12659 int rs
= newval
& 0xf;
12660 int subtract
= newval
& 0x8000;
12664 if (value
& ~0x1fc)
12665 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12666 _("invalid immediate for stack address calculation"));
12667 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
12668 newval
|= value
>> 2;
12670 else if (rs
== REG_PC
|| rs
== REG_SP
)
12674 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12675 _("invalid immediate for address calculation (value = 0x%08lX)"),
12676 (unsigned long) value
);
12677 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
12679 newval
|= value
>> 2;
12684 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12685 _("invalid 8bit immediate"));
12686 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
12687 newval
|= (rd
<< 8) | value
;
12692 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12693 _("invalid 3bit immediate"));
12694 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
12695 newval
|= rd
| (rs
<< 3) | (value
<< 6);
12698 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12701 case BFD_RELOC_ARM_THUMB_IMM
:
12702 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
12703 switch (newval
>> 11)
12705 case 0x04: /* 8bit immediate MOV. */
12706 case 0x05: /* 8bit immediate CMP. */
12707 if (value
< 0 || value
> 255)
12708 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12709 _("invalid immediate: %ld is too large"),
12717 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12720 case BFD_RELOC_ARM_THUMB_SHIFT
:
12721 /* 5bit shift value (0..31). */
12722 if (value
< 0 || value
> 31)
12723 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12724 _("illegal Thumb shift value: %ld"), (long) value
);
12725 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
12726 newval
|= value
<< 6;
12727 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
12730 case BFD_RELOC_VTABLE_INHERIT
:
12731 case BFD_RELOC_VTABLE_ENTRY
:
12735 case BFD_RELOC_NONE
:
12737 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
12738 _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
12742 /* Translate internal representation of relocation info to BFD target
12746 tc_gen_reloc (section
, fixp
)
12747 asection
* section ATTRIBUTE_UNUSED
;
12751 bfd_reloc_code_real_type code
;
12753 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
12755 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
12756 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
12757 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
12759 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
12761 if (fixp
->fx_pcrel
== 0)
12762 reloc
->addend
= fixp
->fx_offset
;
12764 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
12765 #else /* OBJ_ELF */
12766 reloc
->addend
= fixp
->fx_offset
;
12769 switch (fixp
->fx_r_type
)
12772 if (fixp
->fx_pcrel
)
12774 code
= BFD_RELOC_8_PCREL
;
12779 if (fixp
->fx_pcrel
)
12781 code
= BFD_RELOC_16_PCREL
;
12786 if (fixp
->fx_pcrel
)
12788 code
= BFD_RELOC_32_PCREL
;
12792 case BFD_RELOC_ARM_PCREL_BRANCH
:
12793 case BFD_RELOC_ARM_PCREL_BLX
:
12794 case BFD_RELOC_RVA
:
12795 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
12796 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
12797 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
12798 case BFD_RELOC_THUMB_PCREL_BLX
:
12799 case BFD_RELOC_VTABLE_ENTRY
:
12800 case BFD_RELOC_VTABLE_INHERIT
:
12801 code
= fixp
->fx_r_type
;
12804 case BFD_RELOC_ARM_LITERAL
:
12805 case BFD_RELOC_ARM_HWLITERAL
:
12806 /* If this is called then the a literal has
12807 been referenced across a section boundary. */
12808 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12809 _("literal referenced across section boundary"));
12813 case BFD_RELOC_ARM_GOT32
:
12814 case BFD_RELOC_ARM_GOTOFF
:
12815 case BFD_RELOC_ARM_PLT32
:
12816 code
= fixp
->fx_r_type
;
12820 case BFD_RELOC_ARM_IMMEDIATE
:
12821 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12822 _("internal relocation (type: IMMEDIATE) not fixed up"));
12825 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
12826 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12827 _("ADRL used for a symbol not defined in the same file"));
12830 case BFD_RELOC_ARM_OFFSET_IMM
:
12831 if (fixp
->fx_addsy
!= NULL
12832 && !S_IS_DEFINED (fixp
->fx_addsy
)
12833 && S_IS_LOCAL (fixp
->fx_addsy
))
12835 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12836 _("undefined local label `%s'"),
12837 S_GET_NAME (fixp
->fx_addsy
));
12841 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12842 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12849 switch (fixp
->fx_r_type
)
12851 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
12852 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
12853 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
12854 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
12855 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
12856 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
12857 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
12858 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
12859 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
12860 default: type
= _("<unknown>"); break;
12862 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12863 _("cannot represent %s relocation in this object file format"),
12870 if ((code
== BFD_RELOC_32_PCREL
|| code
== BFD_RELOC_32
)
12872 && fixp
->fx_addsy
== GOT_symbol
)
12874 code
= BFD_RELOC_ARM_GOTPC
;
12875 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
12879 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
12881 if (reloc
->howto
== NULL
)
12883 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
12884 _("cannot represent %s relocation in this object file format"),
12885 bfd_get_reloc_code_name (code
));
12889 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12890 vtable entry to be used in the relocation's section offset. */
12891 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
12892 reloc
->address
= fixp
->fx_offset
;
12898 md_estimate_size_before_relax (fragP
, segtype
)
12899 fragS
* fragP ATTRIBUTE_UNUSED
;
12900 segT segtype ATTRIBUTE_UNUSED
;
12902 as_fatal (_("md_estimate_size_before_relax\n"));
12914 as_bad ("%s -- `%s'", inst
.error
, str
);
12918 to
= frag_more (inst
.size
);
12920 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
12922 assert (inst
.size
== (2 * THUMB_SIZE
));
12923 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
12924 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
12926 else if (inst
.size
> INSN_SIZE
)
12928 assert (inst
.size
== (2 * INSN_SIZE
));
12929 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
12930 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
12933 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
12935 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
12936 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
12937 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
12941 dwarf2_emit_insn (inst
.size
);
12953 /* Align the instruction.
12954 This may not be the right thing to do but ... */
12959 /* Align the previous label if needed. */
12960 if (last_label_seen
!= NULL
)
12962 symbol_set_frag (last_label_seen
, frag_now
);
12963 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
12964 S_SET_SEGMENT (last_label_seen
, now_seg
);
12967 memset (&inst
, '\0', sizeof (inst
));
12968 inst
.reloc
.type
= BFD_RELOC_NONE
;
12970 skip_whitespace (str
);
12972 /* Scan up to the end of the op-code, which must end in white space or
12974 for (start
= p
= str
; *p
!= '\0'; p
++)
12980 as_bad (_("no operator -- statement `%s'\n"), str
);
12986 const struct thumb_opcode
* opcode
;
12990 opcode
= (const struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
12995 /* Check that this instruction is supported for this CPU. */
12996 if (thumb_mode
== 1 && (opcode
->variant
& cpu_variant
) == 0)
12998 as_bad (_("selected processor does not support `%s'"), str
);
13002 mapping_state (MAP_THUMB
);
13003 inst
.instruction
= opcode
->value
;
13004 inst
.size
= opcode
->size
;
13005 (*opcode
->parms
) (p
);
13012 const struct asm_opcode
* opcode
;
13016 opcode
= (const struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
13021 /* Check that this instruction is supported for this CPU. */
13022 if ((opcode
->variant
& cpu_variant
) == 0)
13024 as_bad (_("selected processor does not support `%s'"), str
);
13028 mapping_state (MAP_ARM
);
13029 inst
.instruction
= opcode
->value
;
13030 inst
.size
= INSN_SIZE
;
13031 (*opcode
->parms
) (p
);
13037 /* It wasn't an instruction, but it might be a register alias of the form
13039 if (create_register_alias (str
, p
))
13042 as_bad (_("bad instruction `%s'"), start
);
13046 Invocation line includes a switch not recognized by the base assembler.
13047 See if it's a processor-specific option.
13049 This routine is somewhat complicated by the need for backwards
13050 compatibility (since older releases of gcc can't be changed).
13051 The new options try to make the interface as compatible as
13054 New options (supported) are:
13056 -mcpu=<cpu name> Assemble for selected processor
13057 -march=<architecture name> Assemble for selected architecture
13058 -mfpu=<fpu architecture> Assemble for selected FPU.
13059 -EB/-mbig-endian Big-endian
13060 -EL/-mlittle-endian Little-endian
13061 -k Generate PIC code
13062 -mthumb Start in Thumb mode
13063 -mthumb-interwork Code supports ARM/Thumb interworking
13065 For now we will also provide support for:
13067 -mapcs-32 32-bit Program counter
13068 -mapcs-26 26-bit Program counter
13069 -macps-float Floats passed in FP registers
13070 -mapcs-reentrant Reentrant code
13072 (sometime these will probably be replaced with -mapcs=<list of options>
13073 and -matpcs=<list of options>)
13075 The remaining options are only supported for back-wards compatibility.
13076 Cpu variants, the arm part is optional:
13077 -m[arm]1 Currently not supported.
13078 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
13079 -m[arm]3 Arm 3 processor
13080 -m[arm]6[xx], Arm 6 processors
13081 -m[arm]7[xx][t][[d]m] Arm 7 processors
13082 -m[arm]8[10] Arm 8 processors
13083 -m[arm]9[20][tdmi] Arm 9 processors
13084 -mstrongarm[110[0]] StrongARM processors
13085 -mxscale XScale processors
13086 -m[arm]v[2345[t[e]]] Arm architectures
13087 -mall All (except the ARM1)
13089 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
13090 -mfpe-old (No float load/store multiples)
13091 -mvfpxd VFP Single precision
13093 -mno-fpu Disable all floating point instructions
13095 The following CPU names are recognized:
13096 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
13097 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
13098 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
13099 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
13100 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
13101 arm10t arm10e, arm1020t, arm1020e, arm10200e,
13102 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
13106 const char * md_shortopts
= "m:k";
13108 #ifdef ARM_BI_ENDIAN
13109 #define OPTION_EB (OPTION_MD_BASE + 0)
13110 #define OPTION_EL (OPTION_MD_BASE + 1)
13112 #if TARGET_BYTES_BIG_ENDIAN
13113 #define OPTION_EB (OPTION_MD_BASE + 0)
13115 #define OPTION_EL (OPTION_MD_BASE + 1)
13119 struct option md_longopts
[] =
13122 {"EB", no_argument
, NULL
, OPTION_EB
},
13125 {"EL", no_argument
, NULL
, OPTION_EL
},
13127 {NULL
, no_argument
, NULL
, 0}
13130 size_t md_longopts_size
= sizeof (md_longopts
);
13132 struct arm_option_table
13134 char *option
; /* Option name to match. */
13135 char *help
; /* Help information. */
13136 int *var
; /* Variable to change. */
13137 int value
; /* What to change it to. */
13138 char *deprecated
; /* If non-null, print this message. */
13141 struct arm_option_table arm_opts
[] =
13143 {"k", N_("generate PIC code"), &pic_code
, 1, NULL
},
13144 {"mthumb", N_("assemble Thumb code"), &thumb_mode
, 1, NULL
},
13145 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
13146 &support_interwork
, 1, NULL
},
13147 {"moabi", N_("use old ABI (ELF only)"), &target_oabi
, 1, NULL
},
13148 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26
, 0, NULL
},
13149 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26
, 1, NULL
},
13150 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float
,
13152 {"mapcs-reentrant", N_("re-entrant code"), &pic_code
, 1, NULL
},
13153 {"matpcs", N_("code is ATPCS conformant"), &atpcs
, 1, NULL
},
13154 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian
, 1, NULL
},
13155 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian
, 1,
13158 /* These are recognized by the assembler, but have no affect on code. */
13159 {"mapcs-frame", N_("use frame pointer"), NULL
, 0, NULL
},
13160 {"mapcs-stack-check", N_("use stack size checking"), NULL
, 0, NULL
},
13162 /* DON'T add any new processors to this list -- we want the whole list
13163 to go away... Add them to the processors table instead. */
13164 {"marm1", NULL
, &legacy_cpu
, ARM_ARCH_V1
, N_("use -mcpu=arm1")},
13165 {"m1", NULL
, &legacy_cpu
, ARM_ARCH_V1
, N_("use -mcpu=arm1")},
13166 {"marm2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -mcpu=arm2")},
13167 {"m2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -mcpu=arm2")},
13168 {"marm250", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm250")},
13169 {"m250", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm250")},
13170 {"marm3", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm3")},
13171 {"m3", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm3")},
13172 {"marm6", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm6")},
13173 {"m6", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm6")},
13174 {"marm600", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm600")},
13175 {"m600", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm600")},
13176 {"marm610", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm610")},
13177 {"m610", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm610")},
13178 {"marm620", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm620")},
13179 {"m620", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm620")},
13180 {"marm7", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7")},
13181 {"m7", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7")},
13182 {"marm70", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm70")},
13183 {"m70", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm70")},
13184 {"marm700", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700")},
13185 {"m700", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700")},
13186 {"marm700i", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700i")},
13187 {"m700i", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700i")},
13188 {"marm710", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710")},
13189 {"m710", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710")},
13190 {"marm710c", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710c")},
13191 {"m710c", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710c")},
13192 {"marm720", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm720")},
13193 {"m720", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm720")},
13194 {"marm7d", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7d")},
13195 {"m7d", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7d")},
13196 {"marm7di", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7di")},
13197 {"m7di", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7di")},
13198 {"marm7m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7m")},
13199 {"m7m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7m")},
13200 {"marm7dm", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dm")},
13201 {"m7dm", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dm")},
13202 {"marm7dmi", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dmi")},
13203 {"m7dmi", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dmi")},
13204 {"marm7100", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7100")},
13205 {"m7100", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7100")},
13206 {"marm7500", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500")},
13207 {"m7500", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500")},
13208 {"marm7500fe", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500fe")},
13209 {"m7500fe", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500fe")},
13210 {"marm7t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
13211 {"m7t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
13212 {"marm7tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
13213 {"m7tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
13214 {"marm710t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm710t")},
13215 {"m710t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm710t")},
13216 {"marm720t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm720t")},
13217 {"m720t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm720t")},
13218 {"marm740t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm740t")},
13219 {"m740t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm740t")},
13220 {"marm8", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm8")},
13221 {"m8", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm8")},
13222 {"marm810", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm810")},
13223 {"m810", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm810")},
13224 {"marm9", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9")},
13225 {"m9", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9")},
13226 {"marm9tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9tdmi")},
13227 {"m9tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9tdmi")},
13228 {"marm920", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm920")},
13229 {"m920", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm920")},
13230 {"marm940", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm940")},
13231 {"m940", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm940")},
13232 {"mstrongarm", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=strongarm")},
13233 {"mstrongarm110", NULL
, &legacy_cpu
, ARM_ARCH_V4
,
13234 N_("use -mcpu=strongarm110")},
13235 {"mstrongarm1100", NULL
, &legacy_cpu
, ARM_ARCH_V4
,
13236 N_("use -mcpu=strongarm1100")},
13237 {"mstrongarm1110", NULL
, &legacy_cpu
, ARM_ARCH_V4
,
13238 N_("use -mcpu=strongarm1110")},
13239 {"mxscale", NULL
, &legacy_cpu
, ARM_ARCH_XSCALE
, N_("use -mcpu=xscale")},
13240 {"miwmmxt", NULL
, &legacy_cpu
, ARM_ARCH_IWMMXT
, N_("use -mcpu=iwmmxt")},
13241 {"mall", NULL
, &legacy_cpu
, ARM_ANY
, N_("use -mcpu=all")},
13243 /* Architecture variants -- don't add any more to this list either. */
13244 {"mv2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -march=armv2")},
13245 {"marmv2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -march=armv2")},
13246 {"mv2a", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -march=armv2a")},
13247 {"marmv2a", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -march=armv2a")},
13248 {"mv3", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -march=armv3")},
13249 {"marmv3", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -march=armv3")},
13250 {"mv3m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -march=armv3m")},
13251 {"marmv3m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -march=armv3m")},
13252 {"mv4", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -march=armv4")},
13253 {"marmv4", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -march=armv4")},
13254 {"mv4t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -march=armv4t")},
13255 {"marmv4t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -march=armv4t")},
13256 {"mv5", NULL
, &legacy_cpu
, ARM_ARCH_V5
, N_("use -march=armv5")},
13257 {"marmv5", NULL
, &legacy_cpu
, ARM_ARCH_V5
, N_("use -march=armv5")},
13258 {"mv5t", NULL
, &legacy_cpu
, ARM_ARCH_V5T
, N_("use -march=armv5t")},
13259 {"marmv5t", NULL
, &legacy_cpu
, ARM_ARCH_V5T
, N_("use -march=armv5t")},
13260 {"mv5e", NULL
, &legacy_cpu
, ARM_ARCH_V5TE
, N_("use -march=armv5te")},
13261 {"marmv5e", NULL
, &legacy_cpu
, ARM_ARCH_V5TE
, N_("use -march=armv5te")},
13263 /* Floating point variants -- don't add any more to this list either. */
13264 {"mfpe-old", NULL
, &legacy_fpu
, FPU_ARCH_FPE
, N_("use -mfpu=fpe")},
13265 {"mfpa10", NULL
, &legacy_fpu
, FPU_ARCH_FPA
, N_("use -mfpu=fpa10")},
13266 {"mfpa11", NULL
, &legacy_fpu
, FPU_ARCH_FPA
, N_("use -mfpu=fpa11")},
13267 {"mno-fpu", NULL
, &legacy_fpu
, 0,
13268 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
13270 {NULL
, NULL
, NULL
, 0, NULL
}
13273 struct arm_cpu_option_table
13277 /* For some CPUs we assume an FPU unless the user explicitly sets
13282 /* This list should, at a minimum, contain all the cpu names
13283 recognized by GCC. */
13284 static struct arm_cpu_option_table arm_cpus
[] =
13286 {"all", ARM_ANY
, FPU_ARCH_FPA
},
13287 {"arm1", ARM_ARCH_V1
, FPU_ARCH_FPA
},
13288 {"arm2", ARM_ARCH_V2
, FPU_ARCH_FPA
},
13289 {"arm250", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
13290 {"arm3", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
13291 {"arm6", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13292 {"arm60", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13293 {"arm600", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13294 {"arm610", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13295 {"arm620", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13296 {"arm7", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13297 {"arm7m", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
13298 {"arm7d", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13299 {"arm7dm", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
13300 {"arm7di", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13301 {"arm7dmi", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
13302 {"arm70", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13303 {"arm700", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13304 {"arm700i", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13305 {"arm710", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13306 {"arm710t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13307 {"arm720", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13308 {"arm720t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13309 {"arm740t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13310 {"arm710c", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13311 {"arm7100", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13312 {"arm7500", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13313 {"arm7500fe", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13314 {"arm7t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13315 {"arm7tdmi", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13316 {"arm8", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13317 {"arm810", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13318 {"strongarm", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13319 {"strongarm1", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13320 {"strongarm110", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13321 {"strongarm1100", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13322 {"strongarm1110", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13323 {"arm9", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13324 {"arm920", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13325 {"arm920t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13326 {"arm922t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13327 {"arm940t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13328 {"arm9tdmi", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13329 /* For V5 or later processors we default to using VFP; but the user
13330 should really set the FPU type explicitly. */
13331 {"arm9e-r0", ARM_ARCH_V5TExP
, FPU_ARCH_VFP_V2
},
13332 {"arm9e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13333 {"arm926ej", ARM_ARCH_V5TEJ
, FPU_ARCH_VFP_V2
},
13334 {"arm926ejs", ARM_ARCH_V5TEJ
, FPU_ARCH_VFP_V2
},
13335 {"arm946e-r0", ARM_ARCH_V5TExP
, FPU_ARCH_VFP_V2
},
13336 {"arm946e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13337 {"arm966e-r0", ARM_ARCH_V5TExP
, FPU_ARCH_VFP_V2
},
13338 {"arm966e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13339 {"arm10t", ARM_ARCH_V5T
, FPU_ARCH_VFP_V1
},
13340 {"arm10e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13341 {"arm1020", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13342 {"arm1020t", ARM_ARCH_V5T
, FPU_ARCH_VFP_V1
},
13343 {"arm1020e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13344 {"arm1026ejs", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
13345 {"arm1136js", ARM_ARCH_V6
, FPU_NONE
},
13346 {"arm1136jfs", ARM_ARCH_V6
, FPU_ARCH_VFP_V2
},
13347 /* ??? XSCALE is really an architecture. */
13348 {"xscale", ARM_ARCH_XSCALE
, FPU_ARCH_VFP_V2
},
13349 /* ??? iwmmxt is not a processor. */
13350 {"iwmmxt", ARM_ARCH_IWMMXT
, FPU_ARCH_VFP_V2
},
13351 {"i80200", ARM_ARCH_XSCALE
, FPU_ARCH_VFP_V2
},
13353 {"ep9312", ARM_ARCH_V4T
| ARM_CEXT_MAVERICK
, FPU_ARCH_MAVERICK
},
13357 struct arm_arch_option_table
13364 /* This list should, at a minimum, contain all the architecture names
13365 recognized by GCC. */
13366 static struct arm_arch_option_table arm_archs
[] =
13368 {"all", ARM_ANY
, FPU_ARCH_FPA
},
13369 {"armv1", ARM_ARCH_V1
, FPU_ARCH_FPA
},
13370 {"armv2", ARM_ARCH_V2
, FPU_ARCH_FPA
},
13371 {"armv2a", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
13372 {"armv2s", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
13373 {"armv3", ARM_ARCH_V3
, FPU_ARCH_FPA
},
13374 {"armv3m", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
13375 {"armv4", ARM_ARCH_V4
, FPU_ARCH_FPA
},
13376 {"armv4xm", ARM_ARCH_V4xM
, FPU_ARCH_FPA
},
13377 {"armv4t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
13378 {"armv4txm", ARM_ARCH_V4TxM
, FPU_ARCH_FPA
},
13379 {"armv5", ARM_ARCH_V5
, FPU_ARCH_VFP
},
13380 {"armv5t", ARM_ARCH_V5T
, FPU_ARCH_VFP
},
13381 {"armv5txm", ARM_ARCH_V5TxM
, FPU_ARCH_VFP
},
13382 {"armv5te", ARM_ARCH_V5TE
, FPU_ARCH_VFP
},
13383 {"armv5texp", ARM_ARCH_V5TExP
, FPU_ARCH_VFP
},
13384 {"armv5tej", ARM_ARCH_V5TEJ
, FPU_ARCH_VFP
},
13385 {"armv6", ARM_ARCH_V6
, FPU_ARCH_VFP
},
13386 {"armv6j", ARM_ARCH_V6
, FPU_ARCH_VFP
},
13387 {"xscale", ARM_ARCH_XSCALE
, FPU_ARCH_VFP
},
13388 {"iwmmxt", ARM_ARCH_IWMMXT
, FPU_ARCH_VFP
},
13392 /* ISA extensions in the co-processor space. */
13393 struct arm_arch_extension_table
13399 static struct arm_arch_extension_table arm_extensions
[] =
13401 {"maverick", ARM_CEXT_MAVERICK
},
13402 {"xscale", ARM_CEXT_XSCALE
},
13403 {"iwmmxt", ARM_CEXT_IWMMXT
},
13407 struct arm_fpu_option_table
13413 /* This list should, at a minimum, contain all the fpu names
13414 recognized by GCC. */
13415 static struct arm_fpu_option_table arm_fpus
[] =
13417 {"softfpa", FPU_NONE
},
13418 {"fpe", FPU_ARCH_FPE
},
13419 {"fpe2", FPU_ARCH_FPE
},
13420 {"fpe3", FPU_ARCH_FPA
}, /* Third release supports LFM/SFM. */
13421 {"fpa", FPU_ARCH_FPA
},
13422 {"fpa10", FPU_ARCH_FPA
},
13423 {"fpa11", FPU_ARCH_FPA
},
13424 {"arm7500fe", FPU_ARCH_FPA
},
13425 {"softvfp", FPU_ARCH_VFP
},
13426 {"softvfp+vfp", FPU_ARCH_VFP_V2
},
13427 {"vfp", FPU_ARCH_VFP_V2
},
13428 {"vfp9", FPU_ARCH_VFP_V2
},
13429 {"vfp10", FPU_ARCH_VFP_V2
},
13430 {"vfp10-r0", FPU_ARCH_VFP_V1
},
13431 {"vfpxd", FPU_ARCH_VFP_V1xD
},
13432 {"arm1020t", FPU_ARCH_VFP_V1
},
13433 {"arm1020e", FPU_ARCH_VFP_V2
},
13434 {"arm1136jfs", FPU_ARCH_VFP_V2
},
13435 {"maverick", FPU_ARCH_MAVERICK
},
13439 struct arm_float_abi_option_table
13445 static struct arm_float_abi_option_table arm_float_abis
[] =
13447 {"hard", ARM_FLOAT_ABI_HARD
},
13448 {"softfp", ARM_FLOAT_ABI_SOFTFP
},
13449 {"soft", ARM_FLOAT_ABI_SOFT
},
13453 struct arm_long_option_table
13455 char *option
; /* Substring to match. */
13456 char *help
; /* Help information. */
13457 int (*func
) PARAMS ((char *subopt
)); /* Function to decode sub-option. */
13458 char *deprecated
; /* If non-null, print this message. */
13462 arm_parse_extension (str
, opt_p
)
13466 while (str
!= NULL
&& *str
!= 0)
13468 struct arm_arch_extension_table
*opt
;
13474 as_bad (_("invalid architectural extension"));
13479 ext
= strchr (str
, '+');
13482 optlen
= ext
- str
;
13484 optlen
= strlen (str
);
13488 as_bad (_("missing architectural extension"));
13492 for (opt
= arm_extensions
; opt
->name
!= NULL
; opt
++)
13493 if (strncmp (opt
->name
, str
, optlen
) == 0)
13495 *opt_p
|= opt
->value
;
13499 if (opt
->name
== NULL
)
13501 as_bad (_("unknown architectural extnsion `%s'"), str
);
13512 arm_parse_cpu (str
)
13515 struct arm_cpu_option_table
*opt
;
13516 char *ext
= strchr (str
, '+');
13520 optlen
= ext
- str
;
13522 optlen
= strlen (str
);
13526 as_bad (_("missing cpu name `%s'"), str
);
13530 for (opt
= arm_cpus
; opt
->name
!= NULL
; opt
++)
13531 if (strncmp (opt
->name
, str
, optlen
) == 0)
13533 mcpu_cpu_opt
= opt
->value
;
13534 mcpu_fpu_opt
= opt
->default_fpu
;
13537 return arm_parse_extension (ext
, &mcpu_cpu_opt
);
13542 as_bad (_("unknown cpu `%s'"), str
);
13547 arm_parse_arch (str
)
13550 struct arm_arch_option_table
*opt
;
13551 char *ext
= strchr (str
, '+');
13555 optlen
= ext
- str
;
13557 optlen
= strlen (str
);
13561 as_bad (_("missing architecture name `%s'"), str
);
13566 for (opt
= arm_archs
; opt
->name
!= NULL
; opt
++)
13567 if (strcmp (opt
->name
, str
) == 0)
13569 march_cpu_opt
= opt
->value
;
13570 march_fpu_opt
= opt
->default_fpu
;
13573 return arm_parse_extension (ext
, &march_cpu_opt
);
13578 as_bad (_("unknown architecture `%s'\n"), str
);
13583 arm_parse_fpu (str
)
13586 struct arm_fpu_option_table
*opt
;
13588 for (opt
= arm_fpus
; opt
->name
!= NULL
; opt
++)
13589 if (strcmp (opt
->name
, str
) == 0)
13591 mfpu_opt
= opt
->value
;
13595 as_bad (_("unknown floating point format `%s'\n"), str
);
13600 arm_parse_float_abi (str
)
13603 struct arm_float_abi_option_table
*opt
;
13605 for (opt
= arm_float_abis
; opt
->name
!= NULL
; opt
++)
13606 if (strcmp (opt
->name
, str
) == 0)
13608 mfloat_abi_opt
= opt
->value
;
13612 as_bad (_("unknown floating point abi `%s'\n"), str
);
13616 struct arm_long_option_table arm_long_opts
[] =
13618 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
13619 arm_parse_cpu
, NULL
},
13620 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
13621 arm_parse_arch
, NULL
},
13622 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
13623 arm_parse_fpu
, NULL
},
13624 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
13625 arm_parse_float_abi
, NULL
},
13626 {NULL
, NULL
, 0, NULL
}
13630 md_parse_option (c
, arg
)
13634 struct arm_option_table
*opt
;
13635 struct arm_long_option_table
*lopt
;
13641 target_big_endian
= 1;
13647 target_big_endian
= 0;
13652 /* Listing option. Just ignore these, we don't support additional
13657 for (opt
= arm_opts
; opt
->option
!= NULL
; opt
++)
13659 if (c
== opt
->option
[0]
13660 && ((arg
== NULL
&& opt
->option
[1] == 0)
13661 || strcmp (arg
, opt
->option
+ 1) == 0))
13663 #if WARN_DEPRECATED
13664 /* If the option is deprecated, tell the user. */
13665 if (opt
->deprecated
!= NULL
)
13666 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c
,
13667 arg
? arg
: "", _(opt
->deprecated
));
13670 if (opt
->var
!= NULL
)
13671 *opt
->var
= opt
->value
;
13677 for (lopt
= arm_long_opts
; lopt
->option
!= NULL
; lopt
++)
13679 /* These options are expected to have an argument. */
13680 if (c
== lopt
->option
[0]
13682 && strncmp (arg
, lopt
->option
+ 1,
13683 strlen (lopt
->option
+ 1)) == 0)
13685 #if WARN_DEPRECATED
13686 /* If the option is deprecated, tell the user. */
13687 if (lopt
->deprecated
!= NULL
)
13688 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c
, arg
,
13689 _(lopt
->deprecated
));
13692 /* Call the sup-option parser. */
13693 return (*lopt
->func
)(arg
+ strlen (lopt
->option
) - 1);
13697 as_bad (_("unrecognized option `-%c%s'"), c
, arg
? arg
: "");
13708 struct arm_option_table
*opt
;
13709 struct arm_long_option_table
*lopt
;
13711 fprintf (fp
, _(" ARM-specific assembler options:\n"));
13713 for (opt
= arm_opts
; opt
->option
!= NULL
; opt
++)
13714 if (opt
->help
!= NULL
)
13715 fprintf (fp
, " -%-23s%s\n", opt
->option
, _(opt
->help
));
13717 for (lopt
= arm_long_opts
; lopt
->option
!= NULL
; lopt
++)
13718 if (lopt
->help
!= NULL
)
13719 fprintf (fp
, " -%s%s\n", lopt
->option
, _(lopt
->help
));
13723 -EB assemble code for a big-endian cpu\n"));
13728 -EL assemble code for a little-endian cpu\n"));
13732 /* We need to be able to fix up arbitrary expressions in some statements.
13733 This is so that we can handle symbols that are an arbitrary distance from
13734 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
13735 which returns part of an address in a form which will be valid for
13736 a data instruction. We do this by pushing the expression into a symbol
13737 in the expr_section, and creating a fix for that. */
13740 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
13749 arm_fix_data
* arm_data
;
13757 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
13761 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
13766 /* Mark whether the fix is to a THUMB instruction, or an ARM
13768 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
13769 new_fix
->tc_fix_data
= (PTR
) arm_data
;
13770 arm_data
->thumb_mode
= thumb_mode
;
13773 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
13776 cons_fix_new_arm (frag
, where
, size
, exp
)
13782 bfd_reloc_code_real_type type
;
13786 FIXME: @@ Should look at CPU word size. */
13790 type
= BFD_RELOC_8
;
13793 type
= BFD_RELOC_16
;
13797 type
= BFD_RELOC_32
;
13800 type
= BFD_RELOC_64
;
13804 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
13807 /* A good place to do this, although this was probably not intended
13808 for this kind of use. We need to dump the literal pool before
13809 references are made to a null symbol pointer. */
13814 literal_pool
* pool
;
13816 for (pool
= list_of_pools
; pool
; pool
= pool
->next
)
13818 /* Put it at the end of the relevent section. */
13819 subseg_set (pool
->section
, pool
->sub_section
);
13825 arm_start_line_hook ()
13827 last_label_seen
= NULL
;
13831 arm_frob_label (sym
)
13834 last_label_seen
= sym
;
13836 ARM_SET_THUMB (sym
, thumb_mode
);
13838 #if defined OBJ_COFF || defined OBJ_ELF
13839 ARM_SET_INTERWORK (sym
, support_interwork
);
13842 /* Note - do not allow local symbols (.Lxxx) to be labeled
13843 as Thumb functions. This is because these labels, whilst
13844 they exist inside Thumb code, are not the entry points for
13845 possible ARM->Thumb calls. Also, these labels can be used
13846 as part of a computed goto or switch statement. eg gcc
13847 can generate code that looks like this:
13849 ldr r2, [pc, .Laaa]
13859 The first instruction loads the address of the jump table.
13860 The second instruction converts a table index into a byte offset.
13861 The third instruction gets the jump address out of the table.
13862 The fourth instruction performs the jump.
13864 If the address stored at .Laaa is that of a symbol which has the
13865 Thumb_Func bit set, then the linker will arrange for this address
13866 to have the bottom bit set, which in turn would mean that the
13867 address computation performed by the third instruction would end
13868 up with the bottom bit set. Since the ARM is capable of unaligned
13869 word loads, the instruction would then load the incorrect address
13870 out of the jump table, and chaos would ensue. */
13871 if (label_is_thumb_function_name
13872 && (S_GET_NAME (sym
)[0] != '.' || S_GET_NAME (sym
)[1] != 'L')
13873 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
13875 /* When the address of a Thumb function is taken the bottom
13876 bit of that address should be set. This will allow
13877 interworking between Arm and Thumb functions to work
13880 THUMB_SET_FUNC (sym
, 1);
13882 label_is_thumb_function_name
= FALSE
;
13886 /* Adjust the symbol table. This marks Thumb symbols as distinct from
13890 arm_adjust_symtab ()
13895 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
13897 if (ARM_IS_THUMB (sym
))
13899 if (THUMB_IS_FUNC (sym
))
13901 /* Mark the symbol as a Thumb function. */
13902 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
13903 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
13904 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
13906 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
13907 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
13909 as_bad (_("%s: unexpected function type: %d"),
13910 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
13912 else switch (S_GET_STORAGE_CLASS (sym
))
13915 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
13918 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
13921 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
13929 if (ARM_IS_INTERWORK (sym
))
13930 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
13937 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
13939 if (ARM_IS_THUMB (sym
))
13941 elf_symbol_type
* elf_sym
;
13943 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
13944 bind
= ELF_ST_BIND (elf_sym
);
13946 /* If it's a .thumb_func, declare it as so,
13947 otherwise tag label as .code 16. */
13948 if (THUMB_IS_FUNC (sym
))
13949 elf_sym
->internal_elf_sym
.st_info
=
13950 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
13952 elf_sym
->internal_elf_sym
.st_info
=
13953 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
13960 arm_data_in_code ()
13962 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
13964 *input_line_pointer
= '/';
13965 input_line_pointer
+= 5;
13966 *input_line_pointer
= 0;
13974 arm_canonicalize_symbol_name (name
)
13979 if (thumb_mode
&& (len
= strlen (name
)) > 5
13980 && streq (name
+ len
- 5, "/data"))
13981 *(name
+ len
- 5) = 0;
13986 #if defined OBJ_COFF || defined OBJ_ELF
13988 arm_validate_fix (fixP
)
13991 /* If the destination of the branch is a defined symbol which does not have
13992 the THUMB_FUNC attribute, then we must be calling a function which has
13993 the (interfacearm) attribute. We look for the Thumb entry point to that
13994 function and change the branch to refer to that function instead. */
13995 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
13996 && fixP
->fx_addsy
!= NULL
13997 && S_IS_DEFINED (fixP
->fx_addsy
)
13998 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
14000 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
14006 arm_force_relocation (fixp
)
14009 #if defined (OBJ_COFF) && defined (TE_PE)
14010 if (fixp
->fx_r_type
== BFD_RELOC_RVA
)
14014 if (fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
14015 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
14016 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
14017 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
14021 /* Resolve these relocations even if the symbol is extern or weak. */
14022 if (fixp
->fx_r_type
== BFD_RELOC_ARM_IMMEDIATE
14023 || fixp
->fx_r_type
== BFD_RELOC_ARM_OFFSET_IMM
14024 || fixp
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
14027 return generic_force_reloc (fixp
);
14031 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
14032 local labels from being added to the output symbol table when they
14033 are used with the ADRL pseudo op. The ADRL relocation should always
14034 be resolved before the binbary is emitted, so it is safe to say that
14035 it is adjustable. */
14038 arm_fix_adjustable (fixP
)
14041 if (fixP
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
14048 /* Relocations against Thumb function names must be left unadjusted,
14049 so that the linker can use this information to correctly set the
14050 bottom bit of their addresses. The MIPS version of this function
14051 also prevents relocations that are mips-16 specific, but I do not
14052 know why it does this.
14055 There is one other problem that ought to be addressed here, but
14056 which currently is not: Taking the address of a label (rather
14057 than a function) and then later jumping to that address. Such
14058 addresses also ought to have their bottom bit set (assuming that
14059 they reside in Thumb code), but at the moment they will not. */
14062 arm_fix_adjustable (fixP
)
14065 if (fixP
->fx_addsy
== NULL
)
14068 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
14069 && fixP
->fx_subsy
== NULL
)
14072 /* We need the symbol name for the VTABLE entries. */
14073 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
14074 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
14077 /* Don't allow symbols to be discarded on GOT related relocs. */
14078 if (fixP
->fx_r_type
== BFD_RELOC_ARM_PLT32
14079 || fixP
->fx_r_type
== BFD_RELOC_ARM_GOT32
14080 || fixP
->fx_r_type
== BFD_RELOC_ARM_GOTOFF
)
14087 elf32_arm_target_format ()
14089 if (target_big_endian
)
14092 return "elf32-bigarm-oabi";
14094 return "elf32-bigarm";
14099 return "elf32-littlearm-oabi";
14101 return "elf32-littlearm";
14106 armelf_frob_symbol (symp
, puntp
)
14110 elf_frob_symbol (symp
, puntp
);
14113 static bfd_reloc_code_real_type
14123 bfd_reloc_code_real_type reloc
;
14127 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
14128 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
14129 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
14130 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
14131 branch instructions generated by GCC for PLT relocs. */
14132 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
14133 { NULL
, 0, BFD_RELOC_UNUSED
}
14137 for (i
= 0, ip
= input_line_pointer
;
14138 i
< sizeof (id
) && (ISALNUM (*ip
) || ISPUNCT (*ip
));
14140 id
[i
] = TOLOWER (*ip
);
14142 for (i
= 0; reloc_map
[i
].str
; i
++)
14143 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
14146 input_line_pointer
+= reloc_map
[i
].len
;
14148 return reloc_map
[i
].reloc
;
14152 s_arm_elf_cons (nbytes
)
14157 #ifdef md_flush_pending_output
14158 md_flush_pending_output ();
14161 if (is_it_end_of_statement ())
14163 demand_empty_rest_of_line ();
14167 #ifdef md_cons_align
14168 md_cons_align (nbytes
);
14171 mapping_state (MAP_DATA
);
14174 bfd_reloc_code_real_type reloc
;
14176 expression (& exp
);
14178 if (exp
.X_op
== O_symbol
14179 && * input_line_pointer
== '('
14180 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
14182 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
14183 int size
= bfd_get_reloc_size (howto
);
14186 as_bad ("%s relocations do not fit in %d bytes",
14187 howto
->name
, nbytes
);
14190 register char *p
= frag_more ((int) nbytes
);
14191 int offset
= nbytes
- size
;
14193 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
14198 emit_expr (&exp
, (unsigned int) nbytes
);
14200 while (*input_line_pointer
++ == ',');
14202 /* Put terminator back into stream. */
14203 input_line_pointer
--;
14204 demand_empty_rest_of_line ();
14207 #endif /* OBJ_ELF */
14209 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
14210 of an rs_align_code fragment. */
14213 arm_handle_align (fragP
)
14216 static char const arm_noop
[4] = { 0x00, 0x00, 0xa0, 0xe1 };
14217 static char const thumb_noop
[2] = { 0xc0, 0x46 };
14218 static char const arm_bigend_noop
[4] = { 0xe1, 0xa0, 0x00, 0x00 };
14219 static char const thumb_bigend_noop
[2] = { 0x46, 0xc0 };
14221 int bytes
, fix
, noop_size
;
14225 if (fragP
->fr_type
!= rs_align_code
)
14228 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
14229 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
14232 if (bytes
> MAX_MEM_FOR_RS_ALIGN_CODE
)
14233 bytes
&= MAX_MEM_FOR_RS_ALIGN_CODE
;
14235 if (fragP
->tc_frag_data
)
14237 if (target_big_endian
)
14238 noop
= thumb_bigend_noop
;
14241 noop_size
= sizeof (thumb_noop
);
14245 if (target_big_endian
)
14246 noop
= arm_bigend_noop
;
14249 noop_size
= sizeof (arm_noop
);
14252 if (bytes
& (noop_size
- 1))
14254 fix
= bytes
& (noop_size
- 1);
14255 memset (p
, 0, fix
);
14260 while (bytes
>= noop_size
)
14262 memcpy (p
, noop
, noop_size
);
14264 bytes
-= noop_size
;
14268 fragP
->fr_fix
+= fix
;
14269 fragP
->fr_var
= noop_size
;
14272 /* Called from md_do_align. Used to create an alignment
14273 frag in a code section. */
14276 arm_frag_align_code (n
, max
)
14282 /* We assume that there will never be a requirement
14283 to support alignments greater than 32 bytes. */
14284 if (max
> MAX_MEM_FOR_RS_ALIGN_CODE
)
14285 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
14287 p
= frag_var (rs_align_code
,
14288 MAX_MEM_FOR_RS_ALIGN_CODE
,
14290 (relax_substateT
) max
,
14298 /* Perform target specific initialisation of a frag. */
14301 arm_init_frag (fragP
)
14304 /* Record whether this frag is in an ARM or a THUMB area. */
14305 fragP
->tc_frag_data
= thumb_mode
;