1 /* tc-arm.c -- Assemble for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modified by David Taylor (dtaylor@armltd.co.uk)
6 Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 #include "safe-ctype.h"
30 /* Need TARGET_CPU. */
39 #include "dwarf2dbg.h"
42 /* XXX Set this to 1 after the next binutils release */
43 #define WARN_DEPRECATED 0
45 /* The following bitmasks control CPU extensions: */
46 #define ARM_EXT_V1 0x00000001 /* All processors (core set). */
47 #define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
48 #define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
49 #define ARM_EXT_V3 0x00000008 /* MSR MRS. */
50 #define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
51 #define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
52 #define ARM_EXT_V4T 0x00000040 /* Thumb v1. */
53 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
54 #define ARM_EXT_V5T 0x00000100 /* Thumb v2. */
55 #define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
56 #define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
57 #define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */
59 /* Co-processor space extensions. */
60 #define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */
61 #define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. */
63 /* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
64 defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
65 ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
66 three more to cover cores prior to ARM6. Finally, there are cores which
67 implement further extensions in the co-processor space. */
68 #define ARM_ARCH_V1 ARM_EXT_V1
69 #define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)
70 #define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)
71 #define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)
72 #define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)
73 #define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)
74 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)
75 #define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)
76 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)
77 #define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)
78 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
79 #define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
80 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
81 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)
82 #define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)
83 #define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE | ARM_EXT_V5J)
85 /* Processors with specific extensions in the co-processor space. */
86 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)
88 /* Some useful combinations: */
89 #define ARM_ANY 0x0000ffff /* Any basic core. */
90 #define ARM_ALL 0x00ffffff /* Any core + co-processor */
91 #define CPROC_ANY 0x00ff0000 /* Any co-processor */
92 #define FPU_ANY 0xff000000 /* Note this is ~ARM_ALL. */
95 #define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */
96 #define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */
97 #define FPU_VFP_EXT_NONE 0x20000000 /* Use VFP word-ordering. */
98 #define FPU_VFP_EXT_V1xD 0x10000000 /* Base VFP instruction set. */
99 #define FPU_VFP_EXT_V1 0x08000000 /* Double-precision insns. */
100 #define FPU_VFP_EXT_V2 0x04000000 /* ARM10E VFPr1. */
103 #define FPU_ARCH_FPE FPU_FPA_EXT_V1
104 #define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
106 #define FPU_ARCH_VFP FPU_VFP_EXT_NONE
107 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
108 #define FPU_ARCH_VFP_V1 (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
109 #define FPU_ARCH_VFP_V2 (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
111 /* Types of processor to assemble for. */
112 #define ARM_1 ARM_ARCH_V1
113 #define ARM_2 ARM_ARCH_V2
114 #define ARM_3 ARM_ARCH_V2S
115 #define ARM_250 ARM_ARCH_V2S
116 #define ARM_6 ARM_ARCH_V3
117 #define ARM_7 ARM_ARCH_V3
118 #define ARM_8 ARM_ARCH_V4
119 #define ARM_9 ARM_ARCH_V4T
120 #define ARM_STRONG ARM_ARCH_V4
121 #define ARM_CPU_MASK 0x0000000f /* XXX? */
124 #if defined __XSCALE__
125 #define CPU_DEFAULT (ARM_ARCH_XSCALE)
127 #if defined __thumb__
128 #define CPU_DEFAULT (ARM_ARCH_V5T)
130 #define CPU_DEFAULT ARM_ANY
135 /* For backwards compatibility we default to the FPA. */
137 #define FPU_DEFAULT FPU_ARCH_FPA
140 #define streq(a, b) (strcmp (a, b) == 0)
141 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
143 static unsigned long cpu_variant
;
144 static int target_oabi
= 0;
146 /* Flags stored in private area of BFD structure. */
147 static int uses_apcs_26
= false;
148 static int atpcs
= false;
149 static int support_interwork
= false;
150 static int uses_apcs_float
= false;
151 static int pic_code
= false;
153 /* Variables that we set while parsing command-line options. Once all
154 options have been read we re-process these values to set the real
156 static int legacy_cpu
= -1;
157 static int legacy_fpu
= -1;
159 static int mcpu_cpu_opt
= -1;
160 static int mcpu_fpu_opt
= -1;
161 static int march_cpu_opt
= -1;
162 static int march_fpu_opt
= -1;
163 static int mfpu_opt
= -1;
165 /* This array holds the chars that always start a comment. If the
166 pre-processor is disabled, these aren't very useful. */
167 const char comment_chars
[] = "@";
169 /* This array holds the chars that only start a comment at the beginning of
170 a line. If the line seems to have the form '# 123 filename'
171 .line and .file directives will appear in the pre-processed output. */
172 /* Note that input_file.c hand checks for '#' at the beginning of the
173 first line of the input file. This is because the compiler outputs
174 #NO_APP at the beginning of its output. */
175 /* Also note that comments like this one will always work. */
176 const char line_comment_chars
[] = "#";
178 const char line_separator_chars
[] = ";";
180 /* Chars that can be used to separate mant
181 from exp in floating point numbers. */
182 const char EXP_CHARS
[] = "eE";
184 /* Chars that mean this number is a floating point constant. */
188 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
190 /* Prefix characters that indicate the start of an immediate
192 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
195 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
196 symbolS
* GOT_symbol
;
199 /* Size of relocation record. */
200 const int md_reloc_size
= 8;
202 /* 0: assemble for ARM,
203 1: assemble for Thumb,
204 2: assemble for Thumb even though target CPU does not support thumb
206 static int thumb_mode
= 0;
208 typedef struct arm_fix
216 unsigned long instruction
;
220 bfd_reloc_code_real_type type
;
237 struct asm_shift_properties
239 enum asm_shift_index index
;
240 unsigned long bit_field
;
241 unsigned int allows_0
: 1;
242 unsigned int allows_32
: 1;
245 static const struct asm_shift_properties shift_properties
[] =
247 { SHIFT_LSL
, 0, 1, 0},
248 { SHIFT_LSR
, 0x20, 0, 1},
249 { SHIFT_ASR
, 0x40, 0, 1},
250 { SHIFT_ROR
, 0x60, 0, 0},
251 { SHIFT_RRX
, 0x60, 0, 0}
254 struct asm_shift_name
257 const struct asm_shift_properties
* properties
;
260 static const struct asm_shift_name shift_names
[] =
262 { "asl", shift_properties
+ SHIFT_LSL
},
263 { "lsl", shift_properties
+ SHIFT_LSL
},
264 { "lsr", shift_properties
+ SHIFT_LSR
},
265 { "asr", shift_properties
+ SHIFT_ASR
},
266 { "ror", shift_properties
+ SHIFT_ROR
},
267 { "rrx", shift_properties
+ SHIFT_RRX
},
268 { "ASL", shift_properties
+ SHIFT_LSL
},
269 { "LSL", shift_properties
+ SHIFT_LSL
},
270 { "LSR", shift_properties
+ SHIFT_LSR
},
271 { "ASR", shift_properties
+ SHIFT_ASR
},
272 { "ROR", shift_properties
+ SHIFT_ROR
},
273 { "RRX", shift_properties
+ SHIFT_RRX
}
276 #define NO_SHIFT_RESTRICT 1
277 #define SHIFT_RESTRICT 0
279 #define NUM_FLOAT_VALS 8
281 const char * fp_const
[] =
283 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
286 /* Number of littlenums required to hold an extended precision number. */
287 #define MAX_LITTLENUMS 6
289 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
294 /* Whether a Co-processor load/store operation accepts write-back forms. */
303 #define CP_T_X 0x00008000
304 #define CP_T_Y 0x00400000
305 #define CP_T_Pre 0x01000000
306 #define CP_T_UD 0x00800000
307 #define CP_T_WB 0x00200000
309 #define CONDS_BIT 0x00100000
310 #define LOAD_BIT 0x00100000
312 #define DOUBLE_LOAD_FLAG 0x00000001
316 const char * template;
320 #define COND_ALWAYS 0xe0000000
321 #define COND_MASK 0xf0000000
323 static const struct asm_cond conds
[] =
327 {"cs", 0x20000000}, {"hs", 0x20000000},
328 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
345 const char * template;
350 /* The bit that distnguishes CPSR and SPSR. */
351 #define SPSR_BIT (1 << 22)
353 /* How many bits to shift the PSR_xxx bits up by. */
356 #define PSR_c (1 << 0)
357 #define PSR_x (1 << 1)
358 #define PSR_s (1 << 2)
359 #define PSR_f (1 << 3)
361 static const struct asm_psr psrs
[] =
363 {"CPSR", true, PSR_c
| PSR_f
},
364 {"CPSR_all", true, PSR_c
| PSR_f
},
365 {"SPSR", false, PSR_c
| PSR_f
},
366 {"SPSR_all", false, PSR_c
| PSR_f
},
367 {"CPSR_flg", true, PSR_f
},
368 {"CPSR_f", true, PSR_f
},
369 {"SPSR_flg", false, PSR_f
},
370 {"SPSR_f", false, PSR_f
},
371 {"CPSR_c", true, PSR_c
},
372 {"CPSR_ctl", true, PSR_c
},
373 {"SPSR_c", false, PSR_c
},
374 {"SPSR_ctl", false, PSR_c
},
375 {"CPSR_x", true, PSR_x
},
376 {"CPSR_s", true, PSR_s
},
377 {"SPSR_x", false, PSR_x
},
378 {"SPSR_s", false, PSR_s
},
379 /* Combinations of flags. */
380 {"CPSR_fs", true, PSR_f
| PSR_s
},
381 {"CPSR_fx", true, PSR_f
| PSR_x
},
382 {"CPSR_fc", true, PSR_f
| PSR_c
},
383 {"CPSR_sf", true, PSR_s
| PSR_f
},
384 {"CPSR_sx", true, PSR_s
| PSR_x
},
385 {"CPSR_sc", true, PSR_s
| PSR_c
},
386 {"CPSR_xf", true, PSR_x
| PSR_f
},
387 {"CPSR_xs", true, PSR_x
| PSR_s
},
388 {"CPSR_xc", true, PSR_x
| PSR_c
},
389 {"CPSR_cf", true, PSR_c
| PSR_f
},
390 {"CPSR_cs", true, PSR_c
| PSR_s
},
391 {"CPSR_cx", true, PSR_c
| PSR_x
},
392 {"CPSR_fsx", true, PSR_f
| PSR_s
| PSR_x
},
393 {"CPSR_fsc", true, PSR_f
| PSR_s
| PSR_c
},
394 {"CPSR_fxs", true, PSR_f
| PSR_x
| PSR_s
},
395 {"CPSR_fxc", true, PSR_f
| PSR_x
| PSR_c
},
396 {"CPSR_fcs", true, PSR_f
| PSR_c
| PSR_s
},
397 {"CPSR_fcx", true, PSR_f
| PSR_c
| PSR_x
},
398 {"CPSR_sfx", true, PSR_s
| PSR_f
| PSR_x
},
399 {"CPSR_sfc", true, PSR_s
| PSR_f
| PSR_c
},
400 {"CPSR_sxf", true, PSR_s
| PSR_x
| PSR_f
},
401 {"CPSR_sxc", true, PSR_s
| PSR_x
| PSR_c
},
402 {"CPSR_scf", true, PSR_s
| PSR_c
| PSR_f
},
403 {"CPSR_scx", true, PSR_s
| PSR_c
| PSR_x
},
404 {"CPSR_xfs", true, PSR_x
| PSR_f
| PSR_s
},
405 {"CPSR_xfc", true, PSR_x
| PSR_f
| PSR_c
},
406 {"CPSR_xsf", true, PSR_x
| PSR_s
| PSR_f
},
407 {"CPSR_xsc", true, PSR_x
| PSR_s
| PSR_c
},
408 {"CPSR_xcf", true, PSR_x
| PSR_c
| PSR_f
},
409 {"CPSR_xcs", true, PSR_x
| PSR_c
| PSR_s
},
410 {"CPSR_cfs", true, PSR_c
| PSR_f
| PSR_s
},
411 {"CPSR_cfx", true, PSR_c
| PSR_f
| PSR_x
},
412 {"CPSR_csf", true, PSR_c
| PSR_s
| PSR_f
},
413 {"CPSR_csx", true, PSR_c
| PSR_s
| PSR_x
},
414 {"CPSR_cxf", true, PSR_c
| PSR_x
| PSR_f
},
415 {"CPSR_cxs", true, PSR_c
| PSR_x
| PSR_s
},
416 {"CPSR_fsxc", true, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
417 {"CPSR_fscx", true, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
418 {"CPSR_fxsc", true, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
419 {"CPSR_fxcs", true, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
420 {"CPSR_fcsx", true, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
421 {"CPSR_fcxs", true, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
422 {"CPSR_sfxc", true, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
423 {"CPSR_sfcx", true, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
424 {"CPSR_sxfc", true, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
425 {"CPSR_sxcf", true, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
426 {"CPSR_scfx", true, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
427 {"CPSR_scxf", true, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
428 {"CPSR_xfsc", true, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
429 {"CPSR_xfcs", true, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
430 {"CPSR_xsfc", true, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
431 {"CPSR_xscf", true, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
432 {"CPSR_xcfs", true, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
433 {"CPSR_xcsf", true, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
434 {"CPSR_cfsx", true, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
435 {"CPSR_cfxs", true, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
436 {"CPSR_csfx", true, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
437 {"CPSR_csxf", true, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
438 {"CPSR_cxfs", true, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
439 {"CPSR_cxsf", true, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
440 {"SPSR_fs", false, PSR_f
| PSR_s
},
441 {"SPSR_fx", false, PSR_f
| PSR_x
},
442 {"SPSR_fc", false, PSR_f
| PSR_c
},
443 {"SPSR_sf", false, PSR_s
| PSR_f
},
444 {"SPSR_sx", false, PSR_s
| PSR_x
},
445 {"SPSR_sc", false, PSR_s
| PSR_c
},
446 {"SPSR_xf", false, PSR_x
| PSR_f
},
447 {"SPSR_xs", false, PSR_x
| PSR_s
},
448 {"SPSR_xc", false, PSR_x
| PSR_c
},
449 {"SPSR_cf", false, PSR_c
| PSR_f
},
450 {"SPSR_cs", false, PSR_c
| PSR_s
},
451 {"SPSR_cx", false, PSR_c
| PSR_x
},
452 {"SPSR_fsx", false, PSR_f
| PSR_s
| PSR_x
},
453 {"SPSR_fsc", false, PSR_f
| PSR_s
| PSR_c
},
454 {"SPSR_fxs", false, PSR_f
| PSR_x
| PSR_s
},
455 {"SPSR_fxc", false, PSR_f
| PSR_x
| PSR_c
},
456 {"SPSR_fcs", false, PSR_f
| PSR_c
| PSR_s
},
457 {"SPSR_fcx", false, PSR_f
| PSR_c
| PSR_x
},
458 {"SPSR_sfx", false, PSR_s
| PSR_f
| PSR_x
},
459 {"SPSR_sfc", false, PSR_s
| PSR_f
| PSR_c
},
460 {"SPSR_sxf", false, PSR_s
| PSR_x
| PSR_f
},
461 {"SPSR_sxc", false, PSR_s
| PSR_x
| PSR_c
},
462 {"SPSR_scf", false, PSR_s
| PSR_c
| PSR_f
},
463 {"SPSR_scx", false, PSR_s
| PSR_c
| PSR_x
},
464 {"SPSR_xfs", false, PSR_x
| PSR_f
| PSR_s
},
465 {"SPSR_xfc", false, PSR_x
| PSR_f
| PSR_c
},
466 {"SPSR_xsf", false, PSR_x
| PSR_s
| PSR_f
},
467 {"SPSR_xsc", false, PSR_x
| PSR_s
| PSR_c
},
468 {"SPSR_xcf", false, PSR_x
| PSR_c
| PSR_f
},
469 {"SPSR_xcs", false, PSR_x
| PSR_c
| PSR_s
},
470 {"SPSR_cfs", false, PSR_c
| PSR_f
| PSR_s
},
471 {"SPSR_cfx", false, PSR_c
| PSR_f
| PSR_x
},
472 {"SPSR_csf", false, PSR_c
| PSR_s
| PSR_f
},
473 {"SPSR_csx", false, PSR_c
| PSR_s
| PSR_x
},
474 {"SPSR_cxf", false, PSR_c
| PSR_x
| PSR_f
},
475 {"SPSR_cxs", false, PSR_c
| PSR_x
| PSR_s
},
476 {"SPSR_fsxc", false, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
477 {"SPSR_fscx", false, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
478 {"SPSR_fxsc", false, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
479 {"SPSR_fxcs", false, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
480 {"SPSR_fcsx", false, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
481 {"SPSR_fcxs", false, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
482 {"SPSR_sfxc", false, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
483 {"SPSR_sfcx", false, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
484 {"SPSR_sxfc", false, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
485 {"SPSR_sxcf", false, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
486 {"SPSR_scfx", false, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
487 {"SPSR_scxf", false, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
488 {"SPSR_xfsc", false, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
489 {"SPSR_xfcs", false, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
490 {"SPSR_xsfc", false, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
491 {"SPSR_xscf", false, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
492 {"SPSR_xcfs", false, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
493 {"SPSR_xcsf", false, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
494 {"SPSR_cfsx", false, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
495 {"SPSR_cfxs", false, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
496 {"SPSR_csfx", false, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
497 {"SPSR_csxf", false, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
498 {"SPSR_cxfs", false, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
499 {"SPSR_cxsf", false, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
504 VFP_REG_Dd
, VFP_REG_Dm
, VFP_REG_Dn
509 VFP_REG_Sd
, VFP_REG_Sm
, VFP_REG_Sn
514 VFP_LDSTMIA
, VFP_LDSTMDB
, VFP_LDSTMIAX
, VFP_LDSTMDBX
517 /* VFP system registers. */
524 static const struct vfp_reg vfp_regs
[] =
526 {"fpsid", 0x00000000},
527 {"FPSID", 0x00000000},
528 {"fpscr", 0x00010000},
529 {"FPSCR", 0x00010000},
530 {"fpexc", 0x00080000},
531 {"FPEXC", 0x00080000}
534 /* Structure for a hash table entry for a register. */
541 /* Some well known registers that we refer to directly elsewhere. */
546 /* These are the standard names. Users can add aliases with .req. */
547 /* Integer Register Numbers. */
548 static const struct reg_entry rn_table
[] =
550 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
551 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
552 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
553 {"r12", 12}, {"r13", REG_SP
}, {"r14", REG_LR
}, {"r15", REG_PC
},
554 /* ATPCS Synonyms. */
555 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
556 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7},
557 {"v5", 8}, {"v6", 9}, {"v7", 10}, {"v8", 11},
558 /* Well-known aliases. */
560 {"sb", 9}, {"sl", 10}, {"fp", 11},
561 {"ip", 12}, {"sp", REG_SP
}, {"lr", REG_LR
}, {"pc", REG_PC
},
565 /* Co-processor Numbers. */
566 static const struct reg_entry cp_table
[] =
568 {"p0", 0}, {"p1", 1}, {"p2", 2}, {"p3", 3},
569 {"p4", 4}, {"p5", 5}, {"p6", 6}, {"p7", 7},
570 {"p8", 8}, {"p9", 9}, {"p10", 10}, {"p11", 11},
571 {"p12", 12}, {"p13", 13}, {"p14", 14}, {"p15", 15},
575 /* Co-processor Register Numbers. */
576 static const struct reg_entry cn_table
[] =
578 {"c0", 0}, {"c1", 1}, {"c2", 2}, {"c3", 3},
579 {"c4", 4}, {"c5", 5}, {"c6", 6}, {"c7", 7},
580 {"c8", 8}, {"c9", 9}, {"c10", 10}, {"c11", 11},
581 {"c12", 12}, {"c13", 13}, {"c14", 14}, {"c15", 15},
582 /* Not really valid, but kept for back-wards compatibility. */
583 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
584 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
585 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
586 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
591 static const struct reg_entry fn_table
[] =
593 {"f0", 0}, {"f1", 1}, {"f2", 2}, {"f3", 3},
594 {"f4", 4}, {"f5", 5}, {"f6", 6}, {"f7", 7},
598 /* VFP SP Registers. */
599 static const struct reg_entry sn_table
[] =
601 {"s0", 0}, {"s1", 1}, {"s2", 2}, {"s3", 3},
602 {"s4", 4}, {"s5", 5}, {"s6", 6}, {"s7", 7},
603 {"s8", 8}, {"s9", 9}, {"s10", 10}, {"s11", 11},
604 {"s12", 12}, {"s13", 13}, {"s14", 14}, {"s15", 15},
605 {"s16", 16}, {"s17", 17}, {"s18", 18}, {"s19", 19},
606 {"s20", 20}, {"s21", 21}, {"s22", 22}, {"s23", 23},
607 {"s24", 24}, {"s25", 25}, {"s26", 26}, {"s27", 27},
608 {"s28", 28}, {"s29", 29}, {"s30", 30}, {"s31", 31},
612 /* VFP DP Registers. */
613 static const struct reg_entry dn_table
[] =
615 {"d0", 0}, {"d1", 1}, {"d2", 2}, {"d3", 3},
616 {"d4", 4}, {"d5", 5}, {"d6", 6}, {"d7", 7},
617 {"d8", 8}, {"d9", 9}, {"d10", 10}, {"d11", 11},
618 {"d12", 12}, {"d13", 13}, {"d14", 14}, {"d15", 15},
622 /* Maverick DSP coprocessor registers. */
623 static const struct reg_entry mav_mvf_table
[] =
625 {"mvf0", 0}, {"mvf1", 1}, {"mvf2", 2}, {"mvf3", 3},
626 {"mvf4", 4}, {"mvf5", 5}, {"mvf6", 6}, {"mvf7", 7},
627 {"mvf8", 8}, {"mvf9", 9}, {"mvf10", 10}, {"mvf11", 11},
628 {"mvf12", 12}, {"mvf13", 13}, {"mvf14", 14}, {"mvf15", 15},
632 static const struct reg_entry mav_mvd_table
[] =
634 {"mvd0", 0}, {"mvd1", 1}, {"mvd2", 2}, {"mvd3", 3},
635 {"mvd4", 4}, {"mvd5", 5}, {"mvd6", 6}, {"mvd7", 7},
636 {"mvd8", 8}, {"mvd9", 9}, {"mvd10", 10}, {"mvd11", 11},
637 {"mvd12", 12}, {"mvd13", 13}, {"mvd14", 14}, {"mvd15", 15},
641 static const struct reg_entry mav_mvfx_table
[] =
643 {"mvfx0", 0}, {"mvfx1", 1}, {"mvfx2", 2}, {"mvfx3", 3},
644 {"mvfx4", 4}, {"mvfx5", 5}, {"mvfx6", 6}, {"mvfx7", 7},
645 {"mvfx8", 8}, {"mvfx9", 9}, {"mvfx10", 10}, {"mvfx11", 11},
646 {"mvfx12", 12}, {"mvfx13", 13}, {"mvfx14", 14}, {"mvfx15", 15},
650 static const struct reg_entry mav_mvdx_table
[] =
652 {"mvdx0", 0}, {"mvdx1", 1}, {"mvdx2", 2}, {"mvdx3", 3},
653 {"mvdx4", 4}, {"mvdx5", 5}, {"mvdx6", 6}, {"mvdx7", 7},
654 {"mvdx8", 8}, {"mvdx9", 9}, {"mvdx10", 10}, {"mvdx11", 11},
655 {"mvdx12", 12}, {"mvdx13", 13}, {"mvdx14", 14}, {"mvdx15", 15},
659 static const struct reg_entry mav_mvax_table
[] =
661 {"mvax0", 0}, {"mvax1", 1}, {"mvax2", 2}, {"mvax3", 3},
665 static const struct reg_entry mav_dspsc_table
[] =
673 const struct reg_entry
*names
;
675 struct hash_control
*htab
;
676 const char *expected
;
679 struct reg_map all_reg_maps
[] =
681 {rn_table
, 15, NULL
, N_("ARM register expected")},
682 {cp_table
, 15, NULL
, N_("bad or missing co-processor number")},
683 {cn_table
, 15, NULL
, N_("co-processor register expected")},
684 {fn_table
, 7, NULL
, N_("FPA register expected")},
685 {sn_table
, 31, NULL
, N_("VFP single precision register expected")},
686 {dn_table
, 15, NULL
, N_("VFP double precision register expected")},
687 {mav_mvf_table
, 15, NULL
, N_("Maverick MVF register expected")},
688 {mav_mvd_table
, 15, NULL
, N_("Maverick MVD register expected")},
689 {mav_mvfx_table
, 15, NULL
, N_("Maverick MVFX register expected")},
690 {mav_mvdx_table
, 15, NULL
, N_("Maverick MVFX register expected")},
691 {mav_mvax_table
, 3, NULL
, N_("Maverick MVAX register expected")},
692 {mav_dspsc_table
, 0, NULL
, N_("Maverick DSPSC register expected")},
695 /* Enumeration matching entries in table above. */
699 #define REG_TYPE_FIRST REG_TYPE_RN
715 /* Functions called by parser. */
716 /* ARM instructions. */
717 static void do_arit
PARAMS ((char *));
718 static void do_cmp
PARAMS ((char *));
719 static void do_mov
PARAMS ((char *));
720 static void do_ldst
PARAMS ((char *));
721 static void do_ldstt
PARAMS ((char *));
722 static void do_ldmstm
PARAMS ((char *));
723 static void do_branch
PARAMS ((char *));
724 static void do_swi
PARAMS ((char *));
726 /* Pseudo Op codes. */
727 static void do_adr
PARAMS ((char *));
728 static void do_adrl
PARAMS ((char *));
729 static void do_empty
PARAMS ((char *));
732 static void do_mul
PARAMS ((char *));
733 static void do_mla
PARAMS ((char *));
736 static void do_swap
PARAMS ((char *));
739 static void do_msr
PARAMS ((char *));
740 static void do_mrs
PARAMS ((char *));
743 static void do_mull
PARAMS ((char *));
746 static void do_ldstv4
PARAMS ((char *));
749 static void do_bx
PARAMS ((char *));
752 static void do_blx
PARAMS ((char *));
753 static void do_bkpt
PARAMS ((char *));
754 static void do_clz
PARAMS ((char *));
755 static void do_lstc2
PARAMS ((char *));
756 static void do_cdp2
PARAMS ((char *));
757 static void do_co_reg2
PARAMS ((char *));
760 static void do_smla
PARAMS ((char *));
761 static void do_smlal
PARAMS ((char *));
762 static void do_smul
PARAMS ((char *));
763 static void do_qadd
PARAMS ((char *));
766 static void do_pld
PARAMS ((char *));
767 static void do_ldrd
PARAMS ((char *));
768 static void do_co_reg2c
PARAMS ((char *));
771 static void do_bxj
PARAMS ((char *));
773 /* Coprocessor Instructions. */
774 static void do_cdp
PARAMS ((char *));
775 static void do_lstc
PARAMS ((char *));
776 static void do_co_reg
PARAMS ((char *));
778 /* FPA instructions. */
779 static void do_fpa_ctrl
PARAMS ((char *));
780 static void do_fpa_ldst
PARAMS ((char *));
781 static void do_fpa_ldmstm
PARAMS ((char *));
782 static void do_fpa_dyadic
PARAMS ((char *));
783 static void do_fpa_monadic
PARAMS ((char *));
784 static void do_fpa_cmp
PARAMS ((char *));
785 static void do_fpa_from_reg
PARAMS ((char *));
786 static void do_fpa_to_reg
PARAMS ((char *));
788 /* VFP instructions. */
789 static void do_vfp_sp_monadic
PARAMS ((char *));
790 static void do_vfp_dp_monadic
PARAMS ((char *));
791 static void do_vfp_sp_dyadic
PARAMS ((char *));
792 static void do_vfp_dp_dyadic
PARAMS ((char *));
793 static void do_vfp_reg_from_sp
PARAMS ((char *));
794 static void do_vfp_sp_from_reg
PARAMS ((char *));
795 static void do_vfp_sp_reg2
PARAMS ((char *));
796 static void do_vfp_reg_from_dp
PARAMS ((char *));
797 static void do_vfp_reg2_from_dp
PARAMS ((char *));
798 static void do_vfp_dp_from_reg
PARAMS ((char *));
799 static void do_vfp_dp_from_reg2
PARAMS ((char *));
800 static void do_vfp_reg_from_ctrl
PARAMS ((char *));
801 static void do_vfp_ctrl_from_reg
PARAMS ((char *));
802 static void do_vfp_sp_ldst
PARAMS ((char *));
803 static void do_vfp_dp_ldst
PARAMS ((char *));
804 static void do_vfp_sp_ldstmia
PARAMS ((char *));
805 static void do_vfp_sp_ldstmdb
PARAMS ((char *));
806 static void do_vfp_dp_ldstmia
PARAMS ((char *));
807 static void do_vfp_dp_ldstmdb
PARAMS ((char *));
808 static void do_vfp_xp_ldstmia
PARAMS ((char *));
809 static void do_vfp_xp_ldstmdb
PARAMS ((char *));
810 static void do_vfp_sp_compare_z
PARAMS ((char *));
811 static void do_vfp_dp_compare_z
PARAMS ((char *));
812 static void do_vfp_dp_sp_cvt
PARAMS ((char *));
813 static void do_vfp_sp_dp_cvt
PARAMS ((char *));
816 static void do_xsc_mia
PARAMS ((char *));
817 static void do_xsc_mar
PARAMS ((char *));
818 static void do_xsc_mra
PARAMS ((char *));
821 static void do_mav_binops
PARAMS ((char *, int, enum arm_reg_type
,
823 static void do_mav_binops_1a
PARAMS ((char *));
824 static void do_mav_binops_1b
PARAMS ((char *));
825 static void do_mav_binops_1c
PARAMS ((char *));
826 static void do_mav_binops_1d
PARAMS ((char *));
827 static void do_mav_binops_1e
PARAMS ((char *));
828 static void do_mav_binops_1f
PARAMS ((char *));
829 static void do_mav_binops_1g
PARAMS ((char *));
830 static void do_mav_binops_1h
PARAMS ((char *));
831 static void do_mav_binops_1i
PARAMS ((char *));
832 static void do_mav_binops_1j
PARAMS ((char *));
833 static void do_mav_binops_1k
PARAMS ((char *));
834 static void do_mav_binops_1l
PARAMS ((char *));
835 static void do_mav_binops_1m
PARAMS ((char *));
836 static void do_mav_binops_1n
PARAMS ((char *));
837 static void do_mav_binops_1o
PARAMS ((char *));
838 static void do_mav_binops_2a
PARAMS ((char *));
839 static void do_mav_binops_2b
PARAMS ((char *));
840 static void do_mav_binops_2c
PARAMS ((char *));
841 static void do_mav_binops_3a
PARAMS ((char *));
842 static void do_mav_binops_3b
PARAMS ((char *));
843 static void do_mav_binops_3c
PARAMS ((char *));
844 static void do_mav_binops_3d
PARAMS ((char *));
845 static void do_mav_triple
PARAMS ((char *, int, enum arm_reg_type
,
848 static void do_mav_triple_4a
PARAMS ((char *));
849 static void do_mav_triple_4b
PARAMS ((char *));
850 static void do_mav_triple_5a
PARAMS ((char *));
851 static void do_mav_triple_5b
PARAMS ((char *));
852 static void do_mav_triple_5c
PARAMS ((char *));
853 static void do_mav_triple_5d
PARAMS ((char *));
854 static void do_mav_triple_5e
PARAMS ((char *));
855 static void do_mav_triple_5f
PARAMS ((char *));
856 static void do_mav_triple_5g
PARAMS ((char *));
857 static void do_mav_triple_5h
PARAMS ((char *));
858 static void do_mav_quad
PARAMS ((char *, int, enum arm_reg_type
,
862 static void do_mav_quad_6a
PARAMS ((char *));
863 static void do_mav_quad_6b
PARAMS ((char *));
864 static void do_mav_dspsc_1
PARAMS ((char *));
865 static void do_mav_dspsc_2
PARAMS ((char *));
866 static void do_mav_shift
PARAMS ((char *, enum arm_reg_type
,
868 static void do_mav_shift_1
PARAMS ((char *));
869 static void do_mav_shift_2
PARAMS ((char *));
870 static void do_mav_ldst
PARAMS ((char *, enum arm_reg_type
));
871 static void do_mav_ldst_1
PARAMS ((char *));
872 static void do_mav_ldst_2
PARAMS ((char *));
873 static void do_mav_ldst_3
PARAMS ((char *));
874 static void do_mav_ldst_4
PARAMS ((char *));
876 static int mav_reg_required_here
PARAMS ((char **, int,
878 static int mav_parse_offset
PARAMS ((char **, int *));
880 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*,
882 static int arm_reg_parse
PARAMS ((char **, struct hash_control
*));
883 static enum arm_reg_type arm_reg_parse_any
PARAMS ((char *));
884 static const struct asm_psr
* arm_psr_parse
PARAMS ((char **));
885 static void symbol_locate
PARAMS ((symbolS
*, const char *, segT
, valueT
,
887 static int add_to_lit_pool
PARAMS ((void));
888 static unsigned validate_immediate
PARAMS ((unsigned));
889 static unsigned validate_immediate_twopart
PARAMS ((unsigned int,
891 static int validate_offset_imm
PARAMS ((unsigned int, int));
892 static void opcode_select
PARAMS ((int));
893 static void end_of_line
PARAMS ((char *));
894 static int reg_required_here
PARAMS ((char **, int));
895 static int psr_required_here
PARAMS ((char **));
896 static int co_proc_number
PARAMS ((char **));
897 static int cp_opc_expr
PARAMS ((char **, int, int));
898 static int cp_reg_required_here
PARAMS ((char **, int));
899 static int fp_reg_required_here
PARAMS ((char **, int));
900 static int vfp_sp_reg_required_here
PARAMS ((char **, enum vfp_sp_reg_pos
));
901 static int vfp_dp_reg_required_here
PARAMS ((char **, enum vfp_dp_reg_pos
));
902 static void vfp_sp_ldstm
PARAMS ((char *, enum vfp_ldstm_type
));
903 static void vfp_dp_ldstm
PARAMS ((char *, enum vfp_ldstm_type
));
904 static long vfp_sp_reg_list
PARAMS ((char **, enum vfp_sp_reg_pos
));
905 static long vfp_dp_reg_list
PARAMS ((char **));
906 static int vfp_psr_required_here
PARAMS ((char **str
));
907 static const struct vfp_reg
*vfp_psr_parse
PARAMS ((char **str
));
908 static int cp_address_offset
PARAMS ((char **));
909 static int cp_address_required_here
PARAMS ((char **, int));
910 static int my_get_float_expression
PARAMS ((char **));
911 static int skip_past_comma
PARAMS ((char **));
912 static int walk_no_bignums
PARAMS ((symbolS
*));
913 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
914 static int data_op2
PARAMS ((char **));
915 static int fp_op2
PARAMS ((char **));
916 static long reg_list
PARAMS ((char **));
917 static void thumb_load_store
PARAMS ((char *, int, int));
918 static int decode_shift
PARAMS ((char **, int));
919 static int ldst_extend
PARAMS ((char **));
920 static int ldst_extend_v4
PARAMS ((char **));
921 static void thumb_add_sub
PARAMS ((char *, int));
922 static void insert_reg
PARAMS ((const struct reg_entry
*,
923 struct hash_control
*));
924 static void thumb_shift
PARAMS ((char *, int));
925 static void thumb_mov_compare
PARAMS ((char *, int));
926 static void build_arm_ops_hsh
PARAMS ((void));
927 static void set_constant_flonums
PARAMS ((void));
928 static valueT md_chars_to_number
PARAMS ((char *, int));
929 static void build_reg_hsh
PARAMS ((struct reg_map
*));
930 static void insert_reg_alias
PARAMS ((char *, int, struct hash_control
*));
931 static int create_register_alias
PARAMS ((char *, char *));
932 static void output_inst
PARAMS ((const char *));
933 static int accum0_required_here
PARAMS ((char **));
934 static int ld_mode_required_here
PARAMS ((char **));
935 static void do_branch25
PARAMS ((char *));
936 static symbolS
* find_real_start
PARAMS ((symbolS
*));
938 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
941 /* ARM instructions take 4bytes in the object file, Thumb instructions
945 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
946 #define MAV_MODE1 0x100c
948 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
949 #define MAV_MODE2 0x0c10
951 /* "INSN<cond> X,Y" where X:0, Y:bit16. */
952 #define MAV_MODE3 0x1000
954 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
955 #define MAV_MODE4 0x0c0010
957 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
958 #define MAV_MODE5 0x00100c
960 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
961 #define MAV_MODE6 0x00100c05
965 /* Basic string to match. */
966 const char * template;
968 /* Basic instruction code. */
971 /* Offset into the template where the condition code (if any) will be.
972 If zero, then the instruction is never conditional. */
973 unsigned cond_offset
;
975 /* Which architecture variant provides this instruction. */
976 unsigned long variant
;
978 /* Function to call to parse args. */
979 void (* parms
) PARAMS ((char *));
982 static const struct asm_opcode insns
[] =
984 /* Core ARM Instructions. */
985 {"and", 0xe0000000, 3, ARM_EXT_V1
, do_arit
},
986 {"ands", 0xe0100000, 3, ARM_EXT_V1
, do_arit
},
987 {"eor", 0xe0200000, 3, ARM_EXT_V1
, do_arit
},
988 {"eors", 0xe0300000, 3, ARM_EXT_V1
, do_arit
},
989 {"sub", 0xe0400000, 3, ARM_EXT_V1
, do_arit
},
990 {"subs", 0xe0500000, 3, ARM_EXT_V1
, do_arit
},
991 {"rsb", 0xe0600000, 3, ARM_EXT_V1
, do_arit
},
992 {"rsbs", 0xe0700000, 3, ARM_EXT_V1
, do_arit
},
993 {"add", 0xe0800000, 3, ARM_EXT_V1
, do_arit
},
994 {"adds", 0xe0900000, 3, ARM_EXT_V1
, do_arit
},
995 {"adc", 0xe0a00000, 3, ARM_EXT_V1
, do_arit
},
996 {"adcs", 0xe0b00000, 3, ARM_EXT_V1
, do_arit
},
997 {"sbc", 0xe0c00000, 3, ARM_EXT_V1
, do_arit
},
998 {"sbcs", 0xe0d00000, 3, ARM_EXT_V1
, do_arit
},
999 {"rsc", 0xe0e00000, 3, ARM_EXT_V1
, do_arit
},
1000 {"rscs", 0xe0f00000, 3, ARM_EXT_V1
, do_arit
},
1001 {"orr", 0xe1800000, 3, ARM_EXT_V1
, do_arit
},
1002 {"orrs", 0xe1900000, 3, ARM_EXT_V1
, do_arit
},
1003 {"bic", 0xe1c00000, 3, ARM_EXT_V1
, do_arit
},
1004 {"bics", 0xe1d00000, 3, ARM_EXT_V1
, do_arit
},
1006 {"tst", 0xe1100000, 3, ARM_EXT_V1
, do_cmp
},
1007 {"tsts", 0xe1100000, 3, ARM_EXT_V1
, do_cmp
},
1008 {"tstp", 0xe110f000, 3, ARM_EXT_V1
, do_cmp
},
1009 {"teq", 0xe1300000, 3, ARM_EXT_V1
, do_cmp
},
1010 {"teqs", 0xe1300000, 3, ARM_EXT_V1
, do_cmp
},
1011 {"teqp", 0xe130f000, 3, ARM_EXT_V1
, do_cmp
},
1012 {"cmp", 0xe1500000, 3, ARM_EXT_V1
, do_cmp
},
1013 {"cmps", 0xe1500000, 3, ARM_EXT_V1
, do_cmp
},
1014 {"cmpp", 0xe150f000, 3, ARM_EXT_V1
, do_cmp
},
1015 {"cmn", 0xe1700000, 3, ARM_EXT_V1
, do_cmp
},
1016 {"cmns", 0xe1700000, 3, ARM_EXT_V1
, do_cmp
},
1017 {"cmnp", 0xe170f000, 3, ARM_EXT_V1
, do_cmp
},
1019 {"mov", 0xe1a00000, 3, ARM_EXT_V1
, do_mov
},
1020 {"movs", 0xe1b00000, 3, ARM_EXT_V1
, do_mov
},
1021 {"mvn", 0xe1e00000, 3, ARM_EXT_V1
, do_mov
},
1022 {"mvns", 0xe1f00000, 3, ARM_EXT_V1
, do_mov
},
1024 {"ldr", 0xe4100000, 3, ARM_EXT_V1
, do_ldst
},
1025 {"ldrb", 0xe4500000, 3, ARM_EXT_V1
, do_ldst
},
1026 {"ldrt", 0xe4300000, 3, ARM_EXT_V1
, do_ldstt
},
1027 {"ldrbt", 0xe4700000, 3, ARM_EXT_V1
, do_ldstt
},
1028 {"str", 0xe4000000, 3, ARM_EXT_V1
, do_ldst
},
1029 {"strb", 0xe4400000, 3, ARM_EXT_V1
, do_ldst
},
1030 {"strt", 0xe4200000, 3, ARM_EXT_V1
, do_ldstt
},
1031 {"strbt", 0xe4600000, 3, ARM_EXT_V1
, do_ldstt
},
1033 {"stmia", 0xe8800000, 3, ARM_EXT_V1
, do_ldmstm
},
1034 {"stmib", 0xe9800000, 3, ARM_EXT_V1
, do_ldmstm
},
1035 {"stmda", 0xe8000000, 3, ARM_EXT_V1
, do_ldmstm
},
1036 {"stmdb", 0xe9000000, 3, ARM_EXT_V1
, do_ldmstm
},
1037 {"stmfd", 0xe9000000, 3, ARM_EXT_V1
, do_ldmstm
},
1038 {"stmfa", 0xe9800000, 3, ARM_EXT_V1
, do_ldmstm
},
1039 {"stmea", 0xe8800000, 3, ARM_EXT_V1
, do_ldmstm
},
1040 {"stmed", 0xe8000000, 3, ARM_EXT_V1
, do_ldmstm
},
1042 {"ldmia", 0xe8900000, 3, ARM_EXT_V1
, do_ldmstm
},
1043 {"ldmib", 0xe9900000, 3, ARM_EXT_V1
, do_ldmstm
},
1044 {"ldmda", 0xe8100000, 3, ARM_EXT_V1
, do_ldmstm
},
1045 {"ldmdb", 0xe9100000, 3, ARM_EXT_V1
, do_ldmstm
},
1046 {"ldmfd", 0xe8900000, 3, ARM_EXT_V1
, do_ldmstm
},
1047 {"ldmfa", 0xe8100000, 3, ARM_EXT_V1
, do_ldmstm
},
1048 {"ldmea", 0xe9100000, 3, ARM_EXT_V1
, do_ldmstm
},
1049 {"ldmed", 0xe9900000, 3, ARM_EXT_V1
, do_ldmstm
},
1051 {"swi", 0xef000000, 3, ARM_EXT_V1
, do_swi
},
1053 /* XXX This is the wrong place to do this. Think multi-arch. */
1054 {"bl", 0xeb000000, 2, ARM_EXT_V1
, do_branch
},
1055 {"b", 0xea000000, 1, ARM_EXT_V1
, do_branch
},
1057 {"bl", 0xebfffffe, 2, ARM_EXT_V1
, do_branch
},
1058 {"b", 0xeafffffe, 1, ARM_EXT_V1
, do_branch
},
1062 {"adr", 0xe28f0000, 3, ARM_EXT_V1
, do_adr
},
1063 {"adrl", 0xe28f0000, 3, ARM_EXT_V1
, do_adrl
},
1064 {"nop", 0xe1a00000, 3, ARM_EXT_V1
, do_empty
},
1066 /* ARM 2 multiplies. */
1067 {"mul", 0xe0000090, 3, ARM_EXT_V2
, do_mul
},
1068 {"muls", 0xe0100090, 3, ARM_EXT_V2
, do_mul
},
1069 {"mla", 0xe0200090, 3, ARM_EXT_V2
, do_mla
},
1070 {"mlas", 0xe0300090, 3, ARM_EXT_V2
, do_mla
},
1072 /* Generic copressor instructions. */
1073 {"cdp", 0xee000000, 3, ARM_EXT_V2
, do_cdp
},
1074 {"ldc", 0xec100000, 3, ARM_EXT_V2
, do_lstc
},
1075 {"ldcl", 0xec500000, 3, ARM_EXT_V2
, do_lstc
},
1076 {"stc", 0xec000000, 3, ARM_EXT_V2
, do_lstc
},
1077 {"stcl", 0xec400000, 3, ARM_EXT_V2
, do_lstc
},
1078 {"mcr", 0xee000010, 3, ARM_EXT_V2
, do_co_reg
},
1079 {"mrc", 0xee100010, 3, ARM_EXT_V2
, do_co_reg
},
1081 /* ARM 3 - swp instructions. */
1082 {"swp", 0xe1000090, 3, ARM_EXT_V2S
, do_swap
},
1083 {"swpb", 0xe1400090, 3, ARM_EXT_V2S
, do_swap
},
1085 /* ARM 6 Status register instructions. */
1086 {"mrs", 0xe10f0000, 3, ARM_EXT_V3
, do_mrs
},
1087 {"msr", 0xe120f000, 3, ARM_EXT_V3
, do_msr
},
1088 /* ScottB: our code uses 0xe128f000 for msr.
1089 NickC: but this is wrong because the bits 16 through 19 are
1090 handled by the PSR_xxx defines above. */
1092 /* ARM 7M long multiplies. */
1093 {"smull", 0xe0c00090, 5, ARM_EXT_V3M
, do_mull
},
1094 {"smulls", 0xe0d00090, 5, ARM_EXT_V3M
, do_mull
},
1095 {"umull", 0xe0800090, 5, ARM_EXT_V3M
, do_mull
},
1096 {"umulls", 0xe0900090, 5, ARM_EXT_V3M
, do_mull
},
1097 {"smlal", 0xe0e00090, 5, ARM_EXT_V3M
, do_mull
},
1098 {"smlals", 0xe0f00090, 5, ARM_EXT_V3M
, do_mull
},
1099 {"umlal", 0xe0a00090, 5, ARM_EXT_V3M
, do_mull
},
1100 {"umlals", 0xe0b00090, 5, ARM_EXT_V3M
, do_mull
},
1102 /* ARM Architecture 4. */
1103 {"ldrh", 0xe01000b0, 3, ARM_EXT_V4
, do_ldstv4
},
1104 {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4
, do_ldstv4
},
1105 {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4
, do_ldstv4
},
1106 {"strh", 0xe00000b0, 3, ARM_EXT_V4
, do_ldstv4
},
1108 /* ARM Architecture 4T. */
1109 /* Note: bx (and blx) are required on V5, even if the processor does
1110 not support Thumb. */
1111 {"bx", 0xe12fff10, 2, ARM_EXT_V4T
| ARM_EXT_V5
, do_bx
},
1113 /* ARM Architecture 5T. */
1114 /* Note: blx has 2 variants, so the .value is set dynamically.
1115 Only one of the variants has conditional execution. */
1116 {"blx", 0xe0000000, 3, ARM_EXT_V5
, do_blx
},
1117 {"clz", 0xe16f0f10, 3, ARM_EXT_V5
, do_clz
},
1118 {"bkpt", 0xe1200070, 0, ARM_EXT_V5
, do_bkpt
},
1119 {"ldc2", 0xfc100000, 0, ARM_EXT_V5
, do_lstc2
},
1120 {"ldc2l", 0xfc500000, 0, ARM_EXT_V5
, do_lstc2
},
1121 {"stc2", 0xfc000000, 0, ARM_EXT_V5
, do_lstc2
},
1122 {"stc2l", 0xfc400000, 0, ARM_EXT_V5
, do_lstc2
},
1123 {"cdp2", 0xfe000000, 0, ARM_EXT_V5
, do_cdp2
},
1124 {"mcr2", 0xfe000010, 0, ARM_EXT_V5
, do_co_reg2
},
1125 {"mrc2", 0xfe100010, 0, ARM_EXT_V5
, do_co_reg2
},
1127 /* ARM Architecture 5TExP. */
1128 {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP
, do_smla
},
1129 {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP
, do_smla
},
1130 {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP
, do_smla
},
1131 {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP
, do_smla
},
1133 {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP
, do_smla
},
1134 {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP
, do_smla
},
1136 {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP
, do_smlal
},
1137 {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP
, do_smlal
},
1138 {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP
, do_smlal
},
1139 {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP
, do_smlal
},
1141 {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP
, do_smul
},
1142 {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP
, do_smul
},
1143 {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP
, do_smul
},
1144 {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP
, do_smul
},
1146 {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP
, do_smul
},
1147 {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP
, do_smul
},
1149 {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP
, do_qadd
},
1150 {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP
, do_qadd
},
1151 {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP
, do_qadd
},
1152 {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP
, do_qadd
},
1154 /* ARM Architecture 5TE. */
1155 {"pld", 0xf450f000, 0, ARM_EXT_V5E
, do_pld
},
1156 {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E
, do_ldrd
},
1157 {"strd", 0xe00000f0, 3, ARM_EXT_V5E
, do_ldrd
},
1159 {"mcrr", 0xec400000, 4, ARM_EXT_V5E
, do_co_reg2c
},
1160 {"mrrc", 0xec500000, 4, ARM_EXT_V5E
, do_co_reg2c
},
1162 /* ARM Architecture 5TEJ. */
1163 {"bxj", 0xe12fff20, 3, ARM_EXT_V5J
, do_bxj
},
1165 /* Core FPA instruction set (V1). */
1166 {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1167 {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1168 {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1169 {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1171 {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1172 {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1173 {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1174 {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1176 {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1177 {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1178 {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1179 {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1181 {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1182 {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1183 {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1184 {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1185 {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1186 {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1187 {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1188 {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1189 {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1190 {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1191 {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1192 {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1194 {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1195 {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1196 {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1197 {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1198 {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1199 {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1200 {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1201 {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1202 {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1203 {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1204 {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1205 {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1207 {"abss", 0xee208100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1208 {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1209 {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1210 {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1211 {"absd", 0xee208180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1212 {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1213 {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1214 {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1215 {"abse", 0xee288100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1216 {"absep", 0xee288120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1217 {"absem", 0xee288140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1218 {"absez", 0xee288160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1220 {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1221 {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1222 {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1223 {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1224 {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1225 {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1226 {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1227 {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1228 {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1229 {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1230 {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1231 {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1233 {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1234 {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1235 {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1236 {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1237 {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1238 {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1239 {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1240 {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1241 {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1242 {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1243 {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1244 {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1246 {"logs", 0xee508100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1247 {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1248 {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1249 {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1250 {"logd", 0xee508180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1251 {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1252 {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1253 {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1254 {"loge", 0xee588100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1255 {"logep", 0xee588120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1256 {"logem", 0xee588140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1257 {"logez", 0xee588160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1259 {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1260 {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1261 {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1262 {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1263 {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1264 {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1265 {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1266 {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1267 {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1268 {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1269 {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1270 {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1272 {"exps", 0xee708100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1273 {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1274 {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1275 {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1276 {"expd", 0xee708180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1277 {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1278 {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1279 {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1280 {"expe", 0xee788100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1281 {"expep", 0xee788120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1282 {"expem", 0xee788140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1283 {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1285 {"sins", 0xee808100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1286 {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1287 {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1288 {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1289 {"sind", 0xee808180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1290 {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1291 {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1292 {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1293 {"sine", 0xee888100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1294 {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1295 {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1296 {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1298 {"coss", 0xee908100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1299 {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1300 {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1301 {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1302 {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1303 {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1304 {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1305 {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1306 {"cose", 0xee988100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1307 {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1308 {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1309 {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1311 {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1312 {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1313 {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1314 {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1315 {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1316 {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1317 {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1318 {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1319 {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1320 {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1321 {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1322 {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1324 {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1325 {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1326 {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1327 {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1328 {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1329 {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1330 {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1331 {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1332 {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1333 {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1334 {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1335 {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1337 {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1338 {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1339 {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1340 {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1341 {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1342 {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1343 {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1344 {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1345 {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1346 {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1347 {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1348 {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1350 {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1351 {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1352 {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1353 {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1354 {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1355 {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1356 {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1357 {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1358 {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1359 {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1360 {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1361 {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1363 {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1364 {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1365 {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1366 {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1367 {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1368 {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1369 {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1370 {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1371 {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1372 {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1373 {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1374 {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1376 {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1377 {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1378 {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1379 {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1380 {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1381 {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1382 {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1383 {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1384 {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1385 {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1386 {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1387 {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1389 {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1390 {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1391 {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1392 {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1393 {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1394 {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1395 {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1396 {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1397 {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1398 {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1399 {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1400 {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1402 {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1403 {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1404 {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1405 {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1406 {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1407 {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1408 {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1409 {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1410 {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1411 {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1412 {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1413 {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1415 {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1416 {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1417 {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1418 {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1419 {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1420 {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1421 {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1422 {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1423 {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1424 {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1425 {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1426 {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1428 {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1429 {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1430 {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1431 {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1432 {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1433 {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1434 {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1435 {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1436 {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1437 {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1438 {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1439 {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1441 {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1442 {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1443 {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1444 {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1445 {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1446 {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1447 {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1448 {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1449 {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1450 {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1451 {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1452 {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1454 {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1455 {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1456 {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1457 {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1458 {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1459 {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1460 {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1461 {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1462 {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1463 {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1464 {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1465 {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1467 {"pows", 0xee600100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1468 {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1469 {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1470 {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1471 {"powd", 0xee600180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1472 {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1473 {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1474 {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1475 {"powe", 0xee680100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1476 {"powep", 0xee680120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1477 {"powem", 0xee680140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1478 {"powez", 0xee680160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1480 {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1481 {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1482 {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1483 {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1484 {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1485 {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1486 {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1487 {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1488 {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1489 {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1490 {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1491 {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1493 {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1494 {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1495 {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1496 {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1497 {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1498 {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1499 {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1500 {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1501 {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1502 {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1503 {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1504 {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1506 {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1507 {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1508 {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1509 {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1510 {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1511 {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1512 {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1513 {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1514 {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1515 {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1516 {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1517 {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1519 {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1520 {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1521 {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1522 {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1523 {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1524 {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1525 {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1526 {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1527 {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1528 {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1529 {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1530 {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1532 {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1533 {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1534 {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1535 {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1536 {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1537 {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1538 {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1539 {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1540 {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1541 {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1542 {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1543 {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1545 {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1546 {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1547 {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1548 {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1549 {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1550 {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1551 {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1552 {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1553 {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1554 {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1555 {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1556 {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1558 {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1559 {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1560 {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1561 {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1562 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1563 not be an optional suffix, but part of the instruction. To be
1564 compatible, we accept either. */
1565 {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1566 {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1568 {"flts", 0xee000110, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1569 {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1570 {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1571 {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1572 {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1573 {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1574 {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1575 {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1576 {"flte", 0xee080110, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1577 {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1578 {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1579 {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1581 /* The implementation of the FIX instruction is broken on some
1582 assemblers, in that it accepts a precision specifier as well as a
1583 rounding specifier, despite the fact that this is meaningless.
1584 To be more compatible, we accept it as well, though of course it
1585 does not set any bits. */
1586 {"fix", 0xee100110, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1587 {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1588 {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1589 {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1590 {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1591 {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1592 {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1593 {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1594 {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1595 {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1596 {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1597 {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1598 {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1600 /* Instructions that were new with the real FPA, call them V2. */
1601 {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1602 {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1603 {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1604 {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1605 {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1606 {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1608 /* VFP V1xD (single precision). */
1609 /* Moves and type conversions. */
1610 {"fcpys", 0xeeb00a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1611 {"fmrs", 0xee100a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_reg_from_sp
},
1612 {"fmsr", 0xee000a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_sp_from_reg
},
1613 {"fmstat", 0xeef1fa10, 6, FPU_VFP_EXT_V1xD
, do_empty
},
1614 {"fsitos", 0xeeb80ac0, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1615 {"fuitos", 0xeeb80a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1616 {"ftosis", 0xeebd0a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1617 {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1618 {"ftouis", 0xeebc0a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1619 {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1620 {"fmrx", 0xeef00a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_reg_from_ctrl
},
1621 {"fmxr", 0xeee00a10, 4, FPU_VFP_EXT_V1xD
, do_vfp_ctrl_from_reg
},
1623 /* Memory operations. */
1624 {"flds", 0xed100a00, 4, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldst
},
1625 {"fsts", 0xed000a00, 4, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldst
},
1626 {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1627 {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1628 {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1629 {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1630 {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1631 {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1632 {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1633 {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1634 {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1635 {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmia
},
1636 {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1637 {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_ldstmdb
},
1638 {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1639 {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmia
},
1640 {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1641 {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD
, do_vfp_xp_ldstmdb
},
1643 /* Monadic operations. */
1644 {"fabss", 0xeeb00ac0, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1645 {"fnegs", 0xeeb10a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1646 {"fsqrts", 0xeeb10ac0, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1648 /* Dyadic operations. */
1649 {"fadds", 0xee300a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1650 {"fsubs", 0xee300a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1651 {"fmuls", 0xee200a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1652 {"fdivs", 0xee800a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1653 {"fmacs", 0xee000a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1654 {"fmscs", 0xee100a00, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1655 {"fnmuls", 0xee200a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1656 {"fnmacs", 0xee000a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1657 {"fnmscs", 0xee100a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_dyadic
},
1660 {"fcmps", 0xeeb40a40, 5, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1661 {"fcmpzs", 0xeeb50a40, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_compare_z
},
1662 {"fcmpes", 0xeeb40ac0, 6, FPU_VFP_EXT_V1xD
, do_vfp_sp_monadic
},
1663 {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD
, do_vfp_sp_compare_z
},
1665 /* VFP V1 (Double precision). */
1666 /* Moves and type conversions. */
1667 {"fcpyd", 0xeeb00b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1668 {"fcvtds", 0xeeb70ac0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_sp_cvt
},
1669 {"fcvtsd", 0xeeb70bc0, 6, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1670 {"fmdhr", 0xee200b10, 5, FPU_VFP_EXT_V1
, do_vfp_dp_from_reg
},
1671 {"fmdlr", 0xee000b10, 5, FPU_VFP_EXT_V1
, do_vfp_dp_from_reg
},
1672 {"fmrdh", 0xee300b10, 5, FPU_VFP_EXT_V1
, do_vfp_reg_from_dp
},
1673 {"fmrdl", 0xee100b10, 5, FPU_VFP_EXT_V1
, do_vfp_reg_from_dp
},
1674 {"fsitod", 0xeeb80bc0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_sp_cvt
},
1675 {"fuitod", 0xeeb80b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_sp_cvt
},
1676 {"ftosid", 0xeebd0b40, 6, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1677 {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1678 {"ftouid", 0xeebc0b40, 6, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1679 {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1
, do_vfp_sp_dp_cvt
},
1681 /* Memory operations. */
1682 {"fldd", 0xed100b00, 4, FPU_VFP_EXT_V1
, do_vfp_dp_ldst
},
1683 {"fstd", 0xed000b00, 4, FPU_VFP_EXT_V1
, do_vfp_dp_ldst
},
1684 {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1685 {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1686 {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1687 {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1688 {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1689 {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmia
},
1690 {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1691 {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1
, do_vfp_dp_ldstmdb
},
1693 /* Monadic operations. */
1694 {"fabsd", 0xeeb00bc0, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1695 {"fnegd", 0xeeb10b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1696 {"fsqrtd", 0xeeb10bc0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1698 /* Dyadic operations. */
1699 {"faddd", 0xee300b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1700 {"fsubd", 0xee300b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1701 {"fmuld", 0xee200b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1702 {"fdivd", 0xee800b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1703 {"fmacd", 0xee000b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1704 {"fmscd", 0xee100b00, 5, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1705 {"fnmuld", 0xee200b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1706 {"fnmacd", 0xee000b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1707 {"fnmscd", 0xee100b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_dyadic
},
1710 {"fcmpd", 0xeeb40b40, 5, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1711 {"fcmpzd", 0xeeb50b40, 6, FPU_VFP_EXT_V1
, do_vfp_dp_compare_z
},
1712 {"fcmped", 0xeeb40bc0, 6, FPU_VFP_EXT_V1
, do_vfp_dp_monadic
},
1713 {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1
, do_vfp_dp_compare_z
},
1716 {"fmsrr", 0xec400a10, 5, FPU_VFP_EXT_V2
, do_vfp_sp_reg2
},
1717 {"fmrrs", 0xec500a10, 5, FPU_VFP_EXT_V2
, do_vfp_sp_reg2
},
1718 {"fmdrr", 0xec400b10, 5, FPU_VFP_EXT_V2
, do_vfp_dp_from_reg2
},
1719 {"fmrrd", 0xec500b10, 5, FPU_VFP_EXT_V2
, do_vfp_reg2_from_dp
},
1721 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
1722 {"mia", 0xee200010, 3, ARM_CEXT_XSCALE
, do_xsc_mia
},
1723 {"miaph", 0xee280010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1724 {"miabb", 0xee2c0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1725 {"miabt", 0xee2d0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1726 {"miatb", 0xee2e0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1727 {"miatt", 0xee2f0010, 5, ARM_CEXT_XSCALE
, do_xsc_mia
},
1728 {"mar", 0xec400000, 3, ARM_CEXT_XSCALE
, do_xsc_mar
},
1729 {"mra", 0xec500000, 3, ARM_CEXT_XSCALE
, do_xsc_mra
},
1731 /* Cirrus Maverick instructions. */
1732 {"cfldrs", 0xec100400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_1
},
1733 {"cfldrd", 0xec500400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_2
},
1734 {"cfldr32", 0xec100500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_3
},
1735 {"cfldr64", 0xec500500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_4
},
1736 {"cfstrs", 0xec000400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_1
},
1737 {"cfstrd", 0xec400400, 6, ARM_CEXT_MAVERICK
, do_mav_ldst_2
},
1738 {"cfstr32", 0xec000500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_3
},
1739 {"cfstr64", 0xec400500, 7, ARM_CEXT_MAVERICK
, do_mav_ldst_4
},
1740 {"cfmvsr", 0xee000450, 6, ARM_CEXT_MAVERICK
, do_mav_binops_2a
},
1741 {"cfmvrs", 0xee100450, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1a
},
1742 {"cfmvdlr", 0xee000410, 7, ARM_CEXT_MAVERICK
, do_mav_binops_2b
},
1743 {"cfmvrdl", 0xee100410, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1b
},
1744 {"cfmvdhr", 0xee000430, 7, ARM_CEXT_MAVERICK
, do_mav_binops_2b
},
1745 {"cfmvrdh", 0xee100430, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1b
},
1746 {"cfmv64lr", 0xee000510, 8, ARM_CEXT_MAVERICK
, do_mav_binops_2c
},
1747 {"cfmvr64l", 0xee100510, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1c
},
1748 {"cfmv64hr", 0xee000530, 8, ARM_CEXT_MAVERICK
, do_mav_binops_2c
},
1749 {"cfmvr64h", 0xee100530, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1c
},
1750 {"cfmval32", 0xee100610, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
1751 {"cfmv32al", 0xee000610, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
1752 {"cfmvam32", 0xee100630, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
1753 {"cfmv32am", 0xee000630, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
1754 {"cfmvah32", 0xee100650, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
1755 {"cfmv32ah", 0xee000650, 8, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
1756 {"cfmva32", 0xee100670, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3a
},
1757 {"cfmv32a", 0xee000670, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3b
},
1758 {"cfmva64", 0xee100690, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3c
},
1759 {"cfmv64a", 0xee000690, 7, ARM_CEXT_MAVERICK
, do_mav_binops_3d
},
1760 {"cfmvsc32", 0xee1006b0, 8, ARM_CEXT_MAVERICK
, do_mav_dspsc_1
},
1761 {"cfmv32sc", 0xee0006b0, 8, ARM_CEXT_MAVERICK
, do_mav_dspsc_2
},
1762 {"cfcpys", 0xee000400, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1d
},
1763 {"cfcpyd", 0xee000420, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1e
},
1764 {"cfcvtsd", 0xee000460, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1f
},
1765 {"cfcvtds", 0xee000440, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1g
},
1766 {"cfcvt32s", 0xee000480, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1h
},
1767 {"cfcvt32d", 0xee0004a0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1i
},
1768 {"cfcvt64s", 0xee0004c0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1j
},
1769 {"cfcvt64d", 0xee0004e0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1k
},
1770 {"cfcvts32", 0xee100580, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1l
},
1771 {"cfcvtd32", 0xee1005a0, 8, ARM_CEXT_MAVERICK
, do_mav_binops_1m
},
1772 {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK
, do_mav_binops_1l
},
1773 {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK
, do_mav_binops_1m
},
1774 {"cfrshl32", 0xee000550, 8, ARM_CEXT_MAVERICK
, do_mav_triple_4a
},
1775 {"cfrshl64", 0xee000570, 8, ARM_CEXT_MAVERICK
, do_mav_triple_4b
},
1776 {"cfsh32", 0xee000500, 6, ARM_CEXT_MAVERICK
, do_mav_shift_1
},
1777 {"cfsh64", 0xee200500, 6, ARM_CEXT_MAVERICK
, do_mav_shift_2
},
1778 {"cfcmps", 0xee100490, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5a
},
1779 {"cfcmpd", 0xee1004b0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5b
},
1780 {"cfcmp32", 0xee100590, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5c
},
1781 {"cfcmp64", 0xee1005b0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5d
},
1782 {"cfabss", 0xee300400, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1d
},
1783 {"cfabsd", 0xee300420, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1e
},
1784 {"cfnegs", 0xee300440, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1d
},
1785 {"cfnegd", 0xee300460, 6, ARM_CEXT_MAVERICK
, do_mav_binops_1e
},
1786 {"cfadds", 0xee300480, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5e
},
1787 {"cfaddd", 0xee3004a0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5f
},
1788 {"cfsubs", 0xee3004c0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5e
},
1789 {"cfsubd", 0xee3004e0, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5f
},
1790 {"cfmuls", 0xee100400, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5e
},
1791 {"cfmuld", 0xee100420, 6, ARM_CEXT_MAVERICK
, do_mav_triple_5f
},
1792 {"cfabs32", 0xee300500, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1n
},
1793 {"cfabs64", 0xee300520, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1o
},
1794 {"cfneg32", 0xee300540, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1n
},
1795 {"cfneg64", 0xee300560, 7, ARM_CEXT_MAVERICK
, do_mav_binops_1o
},
1796 {"cfadd32", 0xee300580, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
1797 {"cfadd64", 0xee3005a0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5h
},
1798 {"cfsub32", 0xee3005c0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
1799 {"cfsub64", 0xee3005e0, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5h
},
1800 {"cfmul32", 0xee100500, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
1801 {"cfmul64", 0xee100520, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5h
},
1802 {"cfmac32", 0xee100540, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
1803 {"cfmsc32", 0xee100560, 7, ARM_CEXT_MAVERICK
, do_mav_triple_5g
},
1804 {"cfmadd32", 0xee000600, 8, ARM_CEXT_MAVERICK
, do_mav_quad_6a
},
1805 {"cfmsub32", 0xee100600, 8, ARM_CEXT_MAVERICK
, do_mav_quad_6a
},
1806 {"cfmadda32", 0xee200600, 9, ARM_CEXT_MAVERICK
, do_mav_quad_6b
},
1807 {"cfmsuba32", 0xee300600, 9, ARM_CEXT_MAVERICK
, do_mav_quad_6b
},
1810 /* Defines for various bits that we will want to toggle. */
1811 #define INST_IMMEDIATE 0x02000000
1812 #define OFFSET_REG 0x02000000
1813 #define HWOFFSET_IMM 0x00400000
1814 #define SHIFT_BY_REG 0x00000010
1815 #define PRE_INDEX 0x01000000
1816 #define INDEX_UP 0x00800000
1817 #define WRITE_BACK 0x00200000
1818 #define LDM_TYPE_2_OR_3 0x00400000
1820 #define LITERAL_MASK 0xf000f000
1821 #define OPCODE_MASK 0xfe1fffff
1822 #define V4_STR_BIT 0x00000020
1824 #define DATA_OP_SHIFT 21
1826 /* Codes to distinguish the arithmetic instructions. */
1827 #define OPCODE_AND 0
1828 #define OPCODE_EOR 1
1829 #define OPCODE_SUB 2
1830 #define OPCODE_RSB 3
1831 #define OPCODE_ADD 4
1832 #define OPCODE_ADC 5
1833 #define OPCODE_SBC 6
1834 #define OPCODE_RSC 7
1835 #define OPCODE_TST 8
1836 #define OPCODE_TEQ 9
1837 #define OPCODE_CMP 10
1838 #define OPCODE_CMN 11
1839 #define OPCODE_ORR 12
1840 #define OPCODE_MOV 13
1841 #define OPCODE_BIC 14
1842 #define OPCODE_MVN 15
1844 /* Thumb v1 (ARMv4T). */
1845 static void do_t_nop
PARAMS ((char *));
1846 static void do_t_arit
PARAMS ((char *));
1847 static void do_t_add
PARAMS ((char *));
1848 static void do_t_asr
PARAMS ((char *));
1849 static void do_t_branch9
PARAMS ((char *));
1850 static void do_t_branch12
PARAMS ((char *));
1851 static void do_t_branch23
PARAMS ((char *));
1852 static void do_t_bx
PARAMS ((char *));
1853 static void do_t_compare
PARAMS ((char *));
1854 static void do_t_ldmstm
PARAMS ((char *));
1855 static void do_t_ldr
PARAMS ((char *));
1856 static void do_t_ldrb
PARAMS ((char *));
1857 static void do_t_ldrh
PARAMS ((char *));
1858 static void do_t_lds
PARAMS ((char *));
1859 static void do_t_lsl
PARAMS ((char *));
1860 static void do_t_lsr
PARAMS ((char *));
1861 static void do_t_mov
PARAMS ((char *));
1862 static void do_t_push_pop
PARAMS ((char *));
1863 static void do_t_str
PARAMS ((char *));
1864 static void do_t_strb
PARAMS ((char *));
1865 static void do_t_strh
PARAMS ((char *));
1866 static void do_t_sub
PARAMS ((char *));
1867 static void do_t_swi
PARAMS ((char *));
1868 static void do_t_adr
PARAMS ((char *));
1870 /* Thumb v2 (ARMv5T). */
1871 static void do_t_blx
PARAMS ((char *));
1872 static void do_t_bkpt
PARAMS ((char *));
1874 #define T_OPCODE_MUL 0x4340
1875 #define T_OPCODE_TST 0x4200
1876 #define T_OPCODE_CMN 0x42c0
1877 #define T_OPCODE_NEG 0x4240
1878 #define T_OPCODE_MVN 0x43c0
1880 #define T_OPCODE_ADD_R3 0x1800
1881 #define T_OPCODE_SUB_R3 0x1a00
1882 #define T_OPCODE_ADD_HI 0x4400
1883 #define T_OPCODE_ADD_ST 0xb000
1884 #define T_OPCODE_SUB_ST 0xb080
1885 #define T_OPCODE_ADD_SP 0xa800
1886 #define T_OPCODE_ADD_PC 0xa000
1887 #define T_OPCODE_ADD_I8 0x3000
1888 #define T_OPCODE_SUB_I8 0x3800
1889 #define T_OPCODE_ADD_I3 0x1c00
1890 #define T_OPCODE_SUB_I3 0x1e00
1892 #define T_OPCODE_ASR_R 0x4100
1893 #define T_OPCODE_LSL_R 0x4080
1894 #define T_OPCODE_LSR_R 0x40c0
1895 #define T_OPCODE_ASR_I 0x1000
1896 #define T_OPCODE_LSL_I 0x0000
1897 #define T_OPCODE_LSR_I 0x0800
1899 #define T_OPCODE_MOV_I8 0x2000
1900 #define T_OPCODE_CMP_I8 0x2800
1901 #define T_OPCODE_CMP_LR 0x4280
1902 #define T_OPCODE_MOV_HR 0x4600
1903 #define T_OPCODE_CMP_HR 0x4500
1905 #define T_OPCODE_LDR_PC 0x4800
1906 #define T_OPCODE_LDR_SP 0x9800
1907 #define T_OPCODE_STR_SP 0x9000
1908 #define T_OPCODE_LDR_IW 0x6800
1909 #define T_OPCODE_STR_IW 0x6000
1910 #define T_OPCODE_LDR_IH 0x8800
1911 #define T_OPCODE_STR_IH 0x8000
1912 #define T_OPCODE_LDR_IB 0x7800
1913 #define T_OPCODE_STR_IB 0x7000
1914 #define T_OPCODE_LDR_RW 0x5800
1915 #define T_OPCODE_STR_RW 0x5000
1916 #define T_OPCODE_LDR_RH 0x5a00
1917 #define T_OPCODE_STR_RH 0x5200
1918 #define T_OPCODE_LDR_RB 0x5c00
1919 #define T_OPCODE_STR_RB 0x5400
1921 #define T_OPCODE_PUSH 0xb400
1922 #define T_OPCODE_POP 0xbc00
1924 #define T_OPCODE_BRANCH 0xe7fe
1926 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
1928 #define THUMB_SIZE 2 /* Size of thumb instruction. */
1929 #define THUMB_REG_LO 0x1
1930 #define THUMB_REG_HI 0x2
1931 #define THUMB_REG_ANY 0x3
1933 #define THUMB_H1 0x0080
1934 #define THUMB_H2 0x0040
1940 #define THUMB_MOVE 0
1941 #define THUMB_COMPARE 1
1943 #define THUMB_LOAD 0
1944 #define THUMB_STORE 1
1946 #define THUMB_PP_PC_LR 0x0100
1948 /* These three are used for immediate shifts, do not alter. */
1949 #define THUMB_WORD 2
1950 #define THUMB_HALFWORD 1
1951 #define THUMB_BYTE 0
1955 /* Basic string to match. */
1956 const char * template;
1958 /* Basic instruction code. */
1959 unsigned long value
;
1963 /* Which CPU variants this exists for. */
1964 unsigned long variant
;
1966 /* Function to call to parse args. */
1967 void (* parms
) PARAMS ((char *));
1970 static const struct thumb_opcode tinsns
[] =
1972 /* Thumb v1 (ARMv4T). */
1973 {"adc", 0x4140, 2, ARM_EXT_V4T
, do_t_arit
},
1974 {"add", 0x0000, 2, ARM_EXT_V4T
, do_t_add
},
1975 {"and", 0x4000, 2, ARM_EXT_V4T
, do_t_arit
},
1976 {"asr", 0x0000, 2, ARM_EXT_V4T
, do_t_asr
},
1977 {"b", T_OPCODE_BRANCH
, 2, ARM_EXT_V4T
, do_t_branch12
},
1978 {"beq", 0xd0fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1979 {"bne", 0xd1fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1980 {"bcs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1981 {"bhs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1982 {"bcc", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1983 {"bul", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1984 {"blo", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1985 {"bmi", 0xd4fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1986 {"bpl", 0xd5fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1987 {"bvs", 0xd6fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1988 {"bvc", 0xd7fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1989 {"bhi", 0xd8fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1990 {"bls", 0xd9fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1991 {"bge", 0xdafe, 2, ARM_EXT_V4T
, do_t_branch9
},
1992 {"blt", 0xdbfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1993 {"bgt", 0xdcfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1994 {"ble", 0xddfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1995 {"bal", 0xdefe, 2, ARM_EXT_V4T
, do_t_branch9
},
1996 {"bic", 0x4380, 2, ARM_EXT_V4T
, do_t_arit
},
1997 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T
, do_t_branch23
},
1998 {"bx", 0x4700, 2, ARM_EXT_V4T
, do_t_bx
},
1999 {"cmn", T_OPCODE_CMN
, 2, ARM_EXT_V4T
, do_t_arit
},
2000 {"cmp", 0x0000, 2, ARM_EXT_V4T
, do_t_compare
},
2001 {"eor", 0x4040, 2, ARM_EXT_V4T
, do_t_arit
},
2002 {"ldmia", 0xc800, 2, ARM_EXT_V4T
, do_t_ldmstm
},
2003 {"ldr", 0x0000, 2, ARM_EXT_V4T
, do_t_ldr
},
2004 {"ldrb", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrb
},
2005 {"ldrh", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrh
},
2006 {"ldrsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
2007 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
2008 {"ldsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
2009 {"ldsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
2010 {"lsl", 0x0000, 2, ARM_EXT_V4T
, do_t_lsl
},
2011 {"lsr", 0x0000, 2, ARM_EXT_V4T
, do_t_lsr
},
2012 {"mov", 0x0000, 2, ARM_EXT_V4T
, do_t_mov
},
2013 {"mul", T_OPCODE_MUL
, 2, ARM_EXT_V4T
, do_t_arit
},
2014 {"mvn", T_OPCODE_MVN
, 2, ARM_EXT_V4T
, do_t_arit
},
2015 {"neg", T_OPCODE_NEG
, 2, ARM_EXT_V4T
, do_t_arit
},
2016 {"orr", 0x4300, 2, ARM_EXT_V4T
, do_t_arit
},
2017 {"pop", 0xbc00, 2, ARM_EXT_V4T
, do_t_push_pop
},
2018 {"push", 0xb400, 2, ARM_EXT_V4T
, do_t_push_pop
},
2019 {"ror", 0x41c0, 2, ARM_EXT_V4T
, do_t_arit
},
2020 {"sbc", 0x4180, 2, ARM_EXT_V4T
, do_t_arit
},
2021 {"stmia", 0xc000, 2, ARM_EXT_V4T
, do_t_ldmstm
},
2022 {"str", 0x0000, 2, ARM_EXT_V4T
, do_t_str
},
2023 {"strb", 0x0000, 2, ARM_EXT_V4T
, do_t_strb
},
2024 {"strh", 0x0000, 2, ARM_EXT_V4T
, do_t_strh
},
2025 {"swi", 0xdf00, 2, ARM_EXT_V4T
, do_t_swi
},
2026 {"sub", 0x0000, 2, ARM_EXT_V4T
, do_t_sub
},
2027 {"tst", T_OPCODE_TST
, 2, ARM_EXT_V4T
, do_t_arit
},
2029 {"adr", 0x0000, 2, ARM_EXT_V4T
, do_t_adr
},
2030 {"nop", 0x46C0, 2, ARM_EXT_V4T
, do_t_nop
}, /* mov r8,r8 */
2031 /* Thumb v2 (ARMv5T). */
2032 {"blx", 0, 0, ARM_EXT_V5T
, do_t_blx
},
2033 {"bkpt", 0xbe00, 2, ARM_EXT_V5T
, do_t_bkpt
},
2036 #define BAD_ARGS _("bad arguments to instruction")
2037 #define BAD_PC _("r15 not allowed here")
2038 #define BAD_COND _("instruction is not conditional")
2039 #define ERR_NO_ACCUM _("acc0 expected")
2041 static struct hash_control
* arm_ops_hsh
= NULL
;
2042 static struct hash_control
* arm_tops_hsh
= NULL
;
2043 static struct hash_control
* arm_cond_hsh
= NULL
;
2044 static struct hash_control
* arm_shift_hsh
= NULL
;
2045 static struct hash_control
* arm_psr_hsh
= NULL
;
2047 /* This table describes all the machine specific pseudo-ops the assembler
2048 has to support. The fields are:
2049 pseudo-op name without dot
2050 function to call to execute this pseudo-op
2051 Integer arg to pass to the function. */
2053 static void s_req
PARAMS ((int));
2054 static void s_align
PARAMS ((int));
2055 static void s_bss
PARAMS ((int));
2056 static void s_even
PARAMS ((int));
2057 static void s_ltorg
PARAMS ((int));
2058 static void s_arm
PARAMS ((int));
2059 static void s_thumb
PARAMS ((int));
2060 static void s_code
PARAMS ((int));
2061 static void s_force_thumb
PARAMS ((int));
2062 static void s_thumb_func
PARAMS ((int));
2063 static void s_thumb_set
PARAMS ((int));
2064 static void arm_s_text
PARAMS ((int));
2065 static void arm_s_data
PARAMS ((int));
2067 static void arm_s_section
PARAMS ((int));
2068 static void s_arm_elf_cons
PARAMS ((int));
2071 static int my_get_expression
PARAMS ((expressionS
*, char **));
2073 const pseudo_typeS md_pseudo_table
[] =
2075 /* Never called becasue '.req' does not start line. */
2076 { "req", s_req
, 0 },
2077 { "bss", s_bss
, 0 },
2078 { "align", s_align
, 0 },
2079 { "arm", s_arm
, 0 },
2080 { "thumb", s_thumb
, 0 },
2081 { "code", s_code
, 0 },
2082 { "force_thumb", s_force_thumb
, 0 },
2083 { "thumb_func", s_thumb_func
, 0 },
2084 { "thumb_set", s_thumb_set
, 0 },
2085 { "even", s_even
, 0 },
2086 { "ltorg", s_ltorg
, 0 },
2087 { "pool", s_ltorg
, 0 },
2088 /* Allow for the effect of section changes. */
2089 { "text", arm_s_text
, 0 },
2090 { "data", arm_s_data
, 0 },
2092 { "section", arm_s_section
, 0 },
2093 { "section.s", arm_s_section
, 0 },
2094 { "sect", arm_s_section
, 0 },
2095 { "sect.s", arm_s_section
, 0 },
2096 { "word", s_arm_elf_cons
, 4 },
2097 { "long", s_arm_elf_cons
, 4 },
2098 { "file", dwarf2_directive_file
, 0 },
2099 { "loc", dwarf2_directive_loc
, 0 },
2103 { "extend", float_cons
, 'x' },
2104 { "ldouble", float_cons
, 'x' },
2105 { "packed", float_cons
, 'p' },
2109 /* Other internal functions. */
2110 static int arm_parse_extension
PARAMS ((char *, int *));
2111 static int arm_parse_cpu
PARAMS ((char *));
2112 static int arm_parse_arch
PARAMS ((char *));
2113 static int arm_parse_fpu
PARAMS ((char *));
2115 /* Stuff needed to resolve the label ambiguity
2125 symbolS
* last_label_seen
;
2126 static int label_is_thumb_function_name
= false;
2128 /* Literal stuff. */
2130 #define MAX_LITERAL_POOL_SIZE 1024
2132 typedef struct literalS
2134 struct expressionS exp
;
2135 struct arm_it
* inst
;
2138 literalT literals
[MAX_LITERAL_POOL_SIZE
];
2140 /* Next free entry in the pool. */
2141 int next_literal_pool_place
= 0;
2143 /* Next literal pool number. */
2144 int lit_pool_num
= 1;
2146 symbolS
* current_poolP
= NULL
;
2153 if (current_poolP
== NULL
)
2154 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
2155 (valueT
) 0, &zero_address_frag
);
2157 /* Check if this literal value is already in the pool: */
2158 while (lit_count
< next_literal_pool_place
)
2160 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
2161 && inst
.reloc
.exp
.X_op
== O_constant
2162 && (literals
[lit_count
].exp
.X_add_number
2163 == inst
.reloc
.exp
.X_add_number
)
2164 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
2167 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
2168 && inst
.reloc
.exp
.X_op
== O_symbol
2169 && (literals
[lit_count
].exp
.X_add_number
2170 == inst
.reloc
.exp
.X_add_number
)
2171 && (literals
[lit_count
].exp
.X_add_symbol
2172 == inst
.reloc
.exp
.X_add_symbol
)
2173 && (literals
[lit_count
].exp
.X_op_symbol
2174 == inst
.reloc
.exp
.X_op_symbol
))
2180 if (lit_count
== next_literal_pool_place
) /* New entry. */
2182 if (next_literal_pool_place
>= MAX_LITERAL_POOL_SIZE
)
2184 inst
.error
= _("literal pool overflow");
2188 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
2189 lit_count
= next_literal_pool_place
++;
2192 inst
.reloc
.exp
.X_op
= O_symbol
;
2193 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
2194 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
2199 /* Can't use symbol_new here, so have to create a symbol and then at
2200 a later date assign it a value. Thats what these functions do. */
2203 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
2205 const char * name
; /* It is copied, the caller can modify. */
2206 segT segment
; /* Segment identifier (SEG_<something>). */
2207 valueT valu
; /* Symbol value. */
2208 fragS
* frag
; /* Associated fragment. */
2210 unsigned int name_length
;
2211 char * preserved_copy_of_name
;
2213 name_length
= strlen (name
) + 1; /* +1 for \0. */
2214 obstack_grow (¬es
, name
, name_length
);
2215 preserved_copy_of_name
= obstack_finish (¬es
);
2216 #ifdef STRIP_UNDERSCORE
2217 if (preserved_copy_of_name
[0] == '_')
2218 preserved_copy_of_name
++;
2221 #ifdef tc_canonicalize_symbol_name
2222 preserved_copy_of_name
=
2223 tc_canonicalize_symbol_name (preserved_copy_of_name
);
2226 S_SET_NAME (symbolP
, preserved_copy_of_name
);
2228 S_SET_SEGMENT (symbolP
, segment
);
2229 S_SET_VALUE (symbolP
, valu
);
2230 symbol_clear_list_pointers(symbolP
);
2232 symbol_set_frag (symbolP
, frag
);
2234 /* Link to end of symbol chain. */
2236 extern int symbol_table_frozen
;
2237 if (symbol_table_frozen
)
2241 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
2243 obj_symbol_new_hook (symbolP
);
2245 #ifdef tc_symbol_new_hook
2246 tc_symbol_new_hook (symbolP
);
2250 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
2251 #endif /* DEBUG_SYMS */
2254 /* Check that an immediate is valid.
2255 If so, convert it to the right format. */
2258 validate_immediate (val
)
2264 #define rotate_left(v, n) (v << n | v >> (32 - n))
2266 for (i
= 0; i
< 32; i
+= 2)
2267 if ((a
= rotate_left (val
, i
)) <= 0xff)
2268 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
2273 /* Check to see if an immediate can be computed as two seperate immediate
2274 values, added together. We already know that this value cannot be
2275 computed by just one ARM instruction. */
2278 validate_immediate_twopart (val
, highpart
)
2280 unsigned int * highpart
;
2285 for (i
= 0; i
< 32; i
+= 2)
2286 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
2292 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
2294 else if (a
& 0xff0000)
2298 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
2302 assert (a
& 0xff000000);
2303 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
2306 return (a
& 0xff) | (i
<< 7);
2313 validate_offset_imm (val
, hwse
)
2317 if ((hwse
&& val
> 255) || val
> 4095)
2324 int a ATTRIBUTE_UNUSED
;
2326 as_bad (_("invalid syntax for .req directive"));
2331 int ignore ATTRIBUTE_UNUSED
;
2333 /* We don't support putting frags in the BSS segment, we fake it by
2334 marking in_bss, then looking at s_skip for clues. */
2335 subseg_set (bss_section
, 0);
2336 demand_empty_rest_of_line ();
2341 int ignore ATTRIBUTE_UNUSED
;
2343 /* Never make frag if expect extra pass. */
2345 frag_align (1, 0, 0);
2347 record_alignment (now_seg
, 1);
2349 demand_empty_rest_of_line ();
2354 int ignored ATTRIBUTE_UNUSED
;
2359 if (current_poolP
== NULL
)
2362 /* Align pool as you have word accesses.
2363 Only make a frag if we have to. */
2365 frag_align (2, 0, 0);
2367 record_alignment (now_seg
, 2);
2369 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
2371 symbol_locate (current_poolP
, sym_name
, now_seg
,
2372 (valueT
) frag_now_fix (), frag_now
);
2373 symbol_table_insert (current_poolP
);
2375 ARM_SET_THUMB (current_poolP
, thumb_mode
);
2377 #if defined OBJ_COFF || defined OBJ_ELF
2378 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
2381 while (lit_count
< next_literal_pool_place
)
2382 /* First output the expression in the instruction to the pool. */
2383 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
2385 next_literal_pool_place
= 0;
2386 current_poolP
= NULL
;
2389 /* Same as s_align_ptwo but align 0 => align 2. */
2393 int unused ATTRIBUTE_UNUSED
;
2396 register long temp_fill
;
2397 long max_alignment
= 15;
2399 temp
= get_absolute_expression ();
2400 if (temp
> max_alignment
)
2401 as_bad (_("alignment too large: %d assumed"), temp
= max_alignment
);
2404 as_bad (_("alignment negative. 0 assumed."));
2408 if (*input_line_pointer
== ',')
2410 input_line_pointer
++;
2411 temp_fill
= get_absolute_expression ();
2419 /* Only make a frag if we HAVE to. */
2420 if (temp
&& !need_pass_2
)
2421 frag_align (temp
, (int) temp_fill
, 0);
2422 demand_empty_rest_of_line ();
2424 record_alignment (now_seg
, temp
);
2428 s_force_thumb (ignore
)
2429 int ignore ATTRIBUTE_UNUSED
;
2431 /* If we are not already in thumb mode go into it, EVEN if
2432 the target processor does not support thumb instructions.
2433 This is used by gcc/config/arm/lib1funcs.asm for example
2434 to compile interworking support functions even if the
2435 target processor should not support interworking. */
2440 record_alignment (now_seg
, 1);
2443 demand_empty_rest_of_line ();
2447 s_thumb_func (ignore
)
2448 int ignore ATTRIBUTE_UNUSED
;
2453 /* The following label is the name/address of the start of a Thumb function.
2454 We need to know this for the interworking support. */
2455 label_is_thumb_function_name
= true;
2457 demand_empty_rest_of_line ();
2460 /* Perform a .set directive, but also mark the alias as
2461 being a thumb function. */
2467 /* XXX the following is a duplicate of the code for s_set() in read.c
2468 We cannot just call that code as we need to get at the symbol that
2470 register char * name
;
2471 register char delim
;
2472 register char * end_name
;
2473 register symbolS
* symbolP
;
2475 /* Especial apologies for the random logic:
2476 This just grew, and could be parsed much more simply!
2478 name
= input_line_pointer
;
2479 delim
= get_symbol_end ();
2480 end_name
= input_line_pointer
;
2485 if (*input_line_pointer
!= ',')
2488 as_bad (_("expected comma after name \"%s\""), name
);
2490 ignore_rest_of_line ();
2494 input_line_pointer
++;
2497 if (name
[0] == '.' && name
[1] == '\0')
2499 /* XXX - this should not happen to .thumb_set. */
2503 if ((symbolP
= symbol_find (name
)) == NULL
2504 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
2507 /* When doing symbol listings, play games with dummy fragments living
2508 outside the normal fragment chain to record the file and line info
2510 if (listing
& LISTING_SYMBOLS
)
2512 extern struct list_info_struct
* listing_tail
;
2513 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
2515 memset (dummy_frag
, 0, sizeof (fragS
));
2516 dummy_frag
->fr_type
= rs_fill
;
2517 dummy_frag
->line
= listing_tail
;
2518 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
2519 dummy_frag
->fr_symbol
= symbolP
;
2523 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
2526 /* "set" symbols are local unless otherwise specified. */
2527 SF_SET_LOCAL (symbolP
);
2528 #endif /* OBJ_COFF */
2529 } /* Make a new symbol. */
2531 symbol_table_insert (symbolP
);
2536 && S_IS_DEFINED (symbolP
)
2537 && S_GET_SEGMENT (symbolP
) != reg_section
)
2538 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
2540 pseudo_set (symbolP
);
2542 demand_empty_rest_of_line ();
2544 /* XXX Now we come to the Thumb specific bit of code. */
2546 THUMB_SET_FUNC (symbolP
, 1);
2547 ARM_SET_THUMB (symbolP
, 1);
2548 #if defined OBJ_ELF || defined OBJ_COFF
2549 ARM_SET_INTERWORK (symbolP
, support_interwork
);
2553 /* If we change section we must dump the literal pool first. */
2559 if (now_seg
!= text_section
)
2563 obj_elf_text (ignore
);
2573 if (flag_readonly_data_in_text
)
2575 if (now_seg
!= text_section
)
2578 else if (now_seg
!= data_section
)
2582 obj_elf_data (ignore
);
2590 arm_s_section (ignore
)
2595 obj_elf_section (ignore
);
2600 opcode_select (width
)
2608 if (! (cpu_variant
& ARM_EXT_V4T
))
2609 as_bad (_("selected processor does not support THUMB opcodes"));
2612 /* No need to force the alignment, since we will have been
2613 coming from ARM mode, which is word-aligned. */
2614 record_alignment (now_seg
, 1);
2621 if ((cpu_variant
& ARM_ALL
) == ARM_EXT_V4T
)
2622 as_bad (_("selected processor does not support ARM opcodes"));
2627 frag_align (2, 0, 0);
2629 record_alignment (now_seg
, 1);
2634 as_bad (_("invalid instruction size selected (%d)"), width
);
2640 int ignore ATTRIBUTE_UNUSED
;
2643 demand_empty_rest_of_line ();
2648 int ignore ATTRIBUTE_UNUSED
;
2651 demand_empty_rest_of_line ();
2656 int unused ATTRIBUTE_UNUSED
;
2660 temp
= get_absolute_expression ();
2665 opcode_select (temp
);
2669 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
2677 skip_whitespace (str
);
2679 if (*str
!= '\0' && !inst
.error
)
2680 inst
.error
= _("garbage following instruction");
2684 skip_past_comma (str
)
2687 char * p
= * str
, c
;
2690 while ((c
= *p
) == ' ' || c
== ',')
2693 if (c
== ',' && comma
++)
2701 return comma
? SUCCESS
: FAIL
;
2704 /* A standard register must be given at this point.
2705 SHIFT is the place to put it in inst.instruction.
2706 Restores input start point on error.
2707 Returns the reg#, or FAIL. */
2710 reg_required_here (str
, shift
)
2714 static char buff
[128]; /* XXX */
2716 char * start
= * str
;
2718 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_RN
].htab
)) != FAIL
)
2721 inst
.instruction
|= reg
<< shift
;
2725 /* Restore the start point, we may have got a reg of the wrong class. */
2728 /* In the few cases where we might be able to accept something else
2729 this error can be overridden. */
2730 sprintf (buff
, _("register expected, not '%.100s'"), start
);
2736 static const struct asm_psr
*
2738 register char ** ccp
;
2740 char * start
= * ccp
;
2743 const struct asm_psr
* psr
;
2747 /* Skip to the end of the next word in the input stream. */
2752 while (ISALPHA (c
) || c
== '_');
2754 /* Terminate the word. */
2757 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
2758 feature for ease of use and backwards compatibility. */
2759 if (!strncmp (start
, "cpsr", 4))
2760 strncpy (start
, "CPSR", 4);
2761 else if (!strncmp (start
, "spsr", 4))
2762 strncpy (start
, "SPSR", 4);
2764 /* Now locate the word in the psr hash table. */
2765 psr
= (const struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
2767 /* Restore the input stream. */
2770 /* If we found a valid match, advance the
2771 stream pointer past the end of the word. */
2777 /* Parse the input looking for a PSR flag. */
2780 psr_required_here (str
)
2783 char * start
= * str
;
2784 const struct asm_psr
* psr
;
2786 psr
= arm_psr_parse (str
);
2790 /* If this is the SPSR that is being modified, set the R bit. */
2792 inst
.instruction
|= SPSR_BIT
;
2794 /* Set the psr flags in the MSR instruction. */
2795 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
2800 /* In the few cases where we might be able to accept
2801 something else this error can be overridden. */
2802 inst
.error
= _("flag for {c}psr instruction expected");
2804 /* Restore the start point. */
2810 co_proc_number (str
)
2813 int processor
, pchar
;
2816 skip_whitespace (*str
);
2819 /* The data sheet seems to imply that just a number on its own is valid
2820 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
2822 if ((processor
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_CP
].htab
))
2828 if (pchar
>= '0' && pchar
<= '9')
2830 processor
= pchar
- '0';
2831 if (**str
>= '0' && **str
<= '9')
2833 processor
= processor
* 10 + *(*str
)++ - '0';
2836 inst
.error
= _("illegal co-processor number");
2843 inst
.error
= _("bad or missing co-processor number");
2848 inst
.instruction
|= processor
<< 8;
2853 cp_opc_expr (str
, where
, length
)
2860 skip_whitespace (* str
);
2862 memset (&expr
, '\0', sizeof (expr
));
2864 if (my_get_expression (&expr
, str
))
2866 if (expr
.X_op
!= O_constant
)
2868 inst
.error
= _("bad or missing expression");
2872 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
2874 inst
.error
= _("immediate co-processor expression too large");
2878 inst
.instruction
|= expr
.X_add_number
<< where
;
2883 cp_reg_required_here (str
, where
)
2888 char * start
= *str
;
2890 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_CN
].htab
)) != FAIL
)
2892 inst
.instruction
|= reg
<< where
;
2896 /* In the few cases where we might be able to accept something else
2897 this error can be overridden. */
2898 inst
.error
= _("co-processor register expected");
2900 /* Restore the start point. */
2906 fp_reg_required_here (str
, where
)
2911 char * start
= * str
;
2913 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_FN
].htab
)) != FAIL
)
2915 inst
.instruction
|= reg
<< where
;
2919 /* In the few cases where we might be able to accept something else
2920 this error can be overridden. */
2921 inst
.error
= _("floating point register expected");
2923 /* Restore the start point. */
2929 cp_address_offset (str
)
2934 skip_whitespace (* str
);
2936 if (! is_immediate_prefix (**str
))
2938 inst
.error
= _("immediate expression expected");
2944 if (my_get_expression (& inst
.reloc
.exp
, str
))
2947 if (inst
.reloc
.exp
.X_op
== O_constant
)
2949 offset
= inst
.reloc
.exp
.X_add_number
;
2953 inst
.error
= _("co-processor address must be word aligned");
2957 if (offset
> 1023 || offset
< -1023)
2959 inst
.error
= _("offset too large");
2964 inst
.instruction
|= INDEX_UP
;
2968 inst
.instruction
|= offset
>> 2;
2971 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2977 cp_address_required_here (str
, wb_ok
)
2990 skip_whitespace (p
);
2992 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
2995 skip_whitespace (p
);
3001 if (wb_ok
&& skip_past_comma (& p
) == SUCCESS
)
3004 write_back
= WRITE_BACK
;
3008 inst
.error
= _("pc may not be used in post-increment");
3012 if (cp_address_offset (& p
) == FAIL
)
3016 pre_inc
= PRE_INDEX
| INDEX_UP
;
3020 /* '['Rn, #expr']'[!] */
3022 if (skip_past_comma (& p
) == FAIL
)
3024 inst
.error
= _("pre-indexed expression expected");
3028 pre_inc
= PRE_INDEX
;
3030 if (cp_address_offset (& p
) == FAIL
)
3033 skip_whitespace (p
);
3037 inst
.error
= _("missing ]");
3041 skip_whitespace (p
);
3043 if (wb_ok
&& *p
== '!')
3047 inst
.error
= _("pc may not be used with write-back");
3052 write_back
= WRITE_BACK
;
3058 if (my_get_expression (&inst
.reloc
.exp
, &p
))
3061 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
3062 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
3063 inst
.reloc
.pc_rel
= 1;
3064 inst
.instruction
|= (REG_PC
<< 16);
3065 pre_inc
= PRE_INDEX
;
3068 inst
.instruction
|= write_back
| pre_inc
;
3077 /* Do nothing really. */
3088 /* Only one syntax. */
3089 skip_whitespace (str
);
3091 if (reg_required_here (&str
, 12) == FAIL
)
3093 inst
.error
= BAD_ARGS
;
3097 if (skip_past_comma (&str
) == FAIL
)
3099 inst
.error
= _("comma expected after register name");
3103 skip_whitespace (str
);
3105 if ( strcmp (str
, "CPSR") == 0
3106 || strcmp (str
, "SPSR") == 0
3107 /* Lower case versions for backwards compatability. */
3108 || strcmp (str
, "cpsr") == 0
3109 || strcmp (str
, "spsr") == 0)
3112 /* This is for backwards compatability with older toolchains. */
3113 else if ( strcmp (str
, "cpsr_all") == 0
3114 || strcmp (str
, "spsr_all") == 0)
3118 inst
.error
= _("CPSR or SPSR expected");
3122 if (* str
== 's' || * str
== 'S')
3123 inst
.instruction
|= SPSR_BIT
;
3129 /* Two possible forms:
3130 "{C|S}PSR_<field>, Rm",
3131 "{C|S}PSR_f, #expression". */
3137 skip_whitespace (str
);
3139 if (psr_required_here (& str
) == FAIL
)
3142 if (skip_past_comma (& str
) == FAIL
)
3144 inst
.error
= _("comma missing after psr flags");
3148 skip_whitespace (str
);
3150 if (reg_required_here (& str
, 0) != FAIL
)
3157 if (! is_immediate_prefix (* str
))
3160 _("only a register or immediate value can follow a psr flag");
3167 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3170 _("only a register or immediate value can follow a psr flag");
3174 #if 0 /* The first edition of the ARM architecture manual stated that
3175 writing anything other than the flags with an immediate operation
3176 had UNPREDICTABLE effects. This constraint was removed in the
3177 second edition of the specification. */
3178 if ((cpu_variant
& ARM_EXT_V5
) != ARM_EXT_V5
3179 && inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
3181 inst
.error
= _("immediate value cannot be used to set this field");
3186 inst
.instruction
|= INST_IMMEDIATE
;
3188 if (inst
.reloc
.exp
.X_add_symbol
)
3190 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
3191 inst
.reloc
.pc_rel
= 0;
3195 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
3197 if (value
== (unsigned) FAIL
)
3199 inst
.error
= _("invalid constant");
3203 inst
.instruction
|= value
;
3210 /* Long Multiply Parser
3211 UMULL RdLo, RdHi, Rm, Rs
3212 SMULL RdLo, RdHi, Rm, Rs
3213 UMLAL RdLo, RdHi, Rm, Rs
3214 SMLAL RdLo, RdHi, Rm, Rs. */
3220 int rdlo
, rdhi
, rm
, rs
;
3222 /* Only one format "rdlo, rdhi, rm, rs". */
3223 skip_whitespace (str
);
3225 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
3227 inst
.error
= BAD_ARGS
;
3231 if (skip_past_comma (&str
) == FAIL
3232 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
3234 inst
.error
= BAD_ARGS
;
3238 if (skip_past_comma (&str
) == FAIL
3239 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
3241 inst
.error
= BAD_ARGS
;
3245 /* rdhi, rdlo and rm must all be different. */
3246 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
3247 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
3249 if (skip_past_comma (&str
) == FAIL
3250 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
3252 inst
.error
= BAD_ARGS
;
3256 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
3258 inst
.error
= BAD_PC
;
3272 /* Only one format "rd, rm, rs". */
3273 skip_whitespace (str
);
3275 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
3277 inst
.error
= BAD_ARGS
;
3283 inst
.error
= BAD_PC
;
3287 if (skip_past_comma (&str
) == FAIL
3288 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
3290 inst
.error
= BAD_ARGS
;
3296 inst
.error
= BAD_PC
;
3301 as_tsktsk (_("rd and rm should be different in mul"));
3303 if (skip_past_comma (&str
) == FAIL
3304 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
3306 inst
.error
= BAD_ARGS
;
3312 inst
.error
= BAD_PC
;
3326 /* Only one format "rd, rm, rs, rn". */
3327 skip_whitespace (str
);
3329 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
3331 inst
.error
= BAD_ARGS
;
3337 inst
.error
= BAD_PC
;
3341 if (skip_past_comma (&str
) == FAIL
3342 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
3344 inst
.error
= BAD_ARGS
;
3350 inst
.error
= BAD_PC
;
3355 as_tsktsk (_("rd and rm should be different in mla"));
3357 if (skip_past_comma (&str
) == FAIL
3358 || (rd
= reg_required_here (&str
, 8)) == FAIL
3359 || skip_past_comma (&str
) == FAIL
3360 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
3362 inst
.error
= BAD_ARGS
;
3366 if (rd
== REG_PC
|| rm
== REG_PC
)
3368 inst
.error
= BAD_PC
;
3376 /* Expects *str -> the characters "acc0", possibly with leading blanks.
3377 Advances *str to the next non-alphanumeric.
3378 Returns 0, or else FAIL (in which case sets inst.error).
3380 (In a future XScale, there may be accumulators other than zero.
3381 At that time this routine and its callers can be upgraded to suit.) */
3384 accum0_required_here (str
)
3387 static char buff
[128]; /* Note the address is taken. Hence, static. */
3390 int result
= 0; /* The accum number. */
3392 skip_whitespace (p
);
3394 *str
= p
; /* Advance caller's string pointer too. */
3399 *--p
= 0; /* Aap nul into input buffer at non-alnum. */
3401 if (! ( streq (*str
, "acc0") || streq (*str
, "ACC0")))
3403 sprintf (buff
, _("acc0 expected, not '%.100s'"), *str
);
3408 *p
= c
; /* Unzap. */
3409 *str
= p
; /* Caller's string pointer to after match. */
3413 /* Expects **str -> after a comma. May be leading blanks.
3414 Advances *str, recognizing a load mode, and setting inst.instruction.
3415 Returns rn, or else FAIL (in which case may set inst.error
3416 and not advance str)
3418 Note: doesn't know Rd, so no err checks that require such knowledge. */
3421 ld_mode_required_here (string
)
3424 char * str
= * string
;
3428 skip_whitespace (str
);
3434 skip_whitespace (str
);
3436 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
3439 skip_whitespace (str
);
3445 if (skip_past_comma (& str
) == SUCCESS
)
3447 /* [Rn],... (post inc) */
3448 if (ldst_extend_v4 (&str
) == FAIL
)
3453 skip_whitespace (str
);
3458 inst
.instruction
|= WRITE_BACK
;
3461 inst
.instruction
|= INDEX_UP
| HWOFFSET_IMM
;
3467 if (skip_past_comma (& str
) == FAIL
)
3469 inst
.error
= _("pre-indexed expression expected");
3475 if (ldst_extend_v4 (&str
) == FAIL
)
3478 skip_whitespace (str
);
3480 if (* str
++ != ']')
3482 inst
.error
= _("missing ]");
3486 skip_whitespace (str
);
3491 inst
.instruction
|= WRITE_BACK
;
3495 else if (* str
== '=') /* ldr's "r,=label" syntax */
3496 /* We should never reach here, because <text> = <expression> is
3497 caught gas/read.c read_a_source_file() as a .set operation. */
3499 else /* PC +- 8 bit immediate offset. */
3501 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3504 inst
.instruction
|= HWOFFSET_IMM
; /* The I bit. */
3505 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3506 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
3507 inst
.reloc
.pc_rel
= 1;
3508 inst
.instruction
|= (REG_PC
<< 16);
3514 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
3520 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3521 SMLAxy{cond} Rd,Rm,Rs,Rn
3522 SMLAWy{cond} Rd,Rm,Rs,Rn
3523 Error if any register is R15. */
3531 skip_whitespace (str
);
3533 if ((rd
= reg_required_here (& str
, 16)) == FAIL
3534 || skip_past_comma (& str
) == FAIL
3535 || (rm
= reg_required_here (& str
, 0)) == FAIL
3536 || skip_past_comma (& str
) == FAIL
3537 || (rs
= reg_required_here (& str
, 8)) == FAIL
3538 || skip_past_comma (& str
) == FAIL
3539 || (rn
= reg_required_here (& str
, 12)) == FAIL
)
3540 inst
.error
= BAD_ARGS
;
3542 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
|| rn
== REG_PC
)
3543 inst
.error
= BAD_PC
;
3549 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3550 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3551 Error if any register is R15.
3552 Warning if Rdlo == Rdhi. */
3558 int rdlo
, rdhi
, rm
, rs
;
3560 skip_whitespace (str
);
3562 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
3563 || skip_past_comma (& str
) == FAIL
3564 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
3565 || skip_past_comma (& str
) == FAIL
3566 || (rm
= reg_required_here (& str
, 0)) == FAIL
3567 || skip_past_comma (& str
) == FAIL
3568 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
3570 inst
.error
= BAD_ARGS
;
3574 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
3576 inst
.error
= BAD_PC
;
3581 as_tsktsk (_("rdhi and rdlo must be different"));
3586 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3587 SMULxy{cond} Rd,Rm,Rs
3588 Error if any register is R15. */
3596 skip_whitespace (str
);
3598 if ((rd
= reg_required_here (& str
, 16)) == FAIL
3599 || skip_past_comma (& str
) == FAIL
3600 || (rm
= reg_required_here (& str
, 0)) == FAIL
3601 || skip_past_comma (& str
) == FAIL
3602 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
3603 inst
.error
= BAD_ARGS
;
3605 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
3606 inst
.error
= BAD_PC
;
3612 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3613 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3614 Error if any register is R15. */
3622 skip_whitespace (str
);
3624 if ((rd
= reg_required_here (& str
, 12)) == FAIL
3625 || skip_past_comma (& str
) == FAIL
3626 || (rm
= reg_required_here (& str
, 0)) == FAIL
3627 || skip_past_comma (& str
) == FAIL
3628 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
3629 inst
.error
= BAD_ARGS
;
3631 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
3632 inst
.error
= BAD_PC
;
3638 /* ARM V5E (el Segundo)
3639 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3640 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3642 These are equivalent to the XScale instructions MAR and MRA,
3643 respectively, when coproc == 0, opcode == 0, and CRm == 0.
3645 Result unpredicatable if Rd or Rn is R15. */
3653 skip_whitespace (str
);
3655 if (co_proc_number (& str
) == FAIL
)
3658 inst
.error
= BAD_ARGS
;
3662 if (skip_past_comma (& str
) == FAIL
3663 || cp_opc_expr (& str
, 4, 4) == FAIL
)
3666 inst
.error
= BAD_ARGS
;
3670 if (skip_past_comma (& str
) == FAIL
3671 || (rd
= reg_required_here (& str
, 12)) == FAIL
)
3674 inst
.error
= BAD_ARGS
;
3678 if (skip_past_comma (& str
) == FAIL
3679 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
3682 inst
.error
= BAD_ARGS
;
3686 /* Unpredictable result if rd or rn is R15. */
3687 if (rd
== REG_PC
|| rn
== REG_PC
)
3689 (_("Warning: instruction unpredictable when using r15"));
3691 if (skip_past_comma (& str
) == FAIL
3692 || cp_reg_required_here (& str
, 0) == FAIL
)
3695 inst
.error
= BAD_ARGS
;
3702 /* ARM V5 count-leading-zeroes instruction (argument parse)
3703 CLZ{<cond>} <Rd>, <Rm>
3704 Condition defaults to COND_ALWAYS.
3705 Error if Rd or Rm are R15. */
3713 skip_whitespace (str
);
3715 if (((rd
= reg_required_here (& str
, 12)) == FAIL
)
3716 || (skip_past_comma (& str
) == FAIL
)
3717 || ((rm
= reg_required_here (& str
, 0)) == FAIL
))
3718 inst
.error
= BAD_ARGS
;
3720 else if (rd
== REG_PC
|| rm
== REG_PC
)
3721 inst
.error
= BAD_PC
;
3727 /* ARM V5 (argument parse)
3728 LDC2{L} <coproc>, <CRd>, <addressing mode>
3729 STC2{L} <coproc>, <CRd>, <addressing mode>
3730 Instruction is not conditional, and has 0xf in the codition field.
3731 Otherwise, it's the same as LDC/STC. */
3737 skip_whitespace (str
);
3739 if (co_proc_number (& str
) == FAIL
)
3742 inst
.error
= BAD_ARGS
;
3744 else if (skip_past_comma (& str
) == FAIL
3745 || cp_reg_required_here (& str
, 12) == FAIL
)
3748 inst
.error
= BAD_ARGS
;
3750 else if (skip_past_comma (& str
) == FAIL
3751 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
3754 inst
.error
= BAD_ARGS
;
3760 /* ARM V5 (argument parse)
3761 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3762 Instruction is not conditional, and has 0xf in the condition field.
3763 Otherwise, it's the same as CDP. */
3769 skip_whitespace (str
);
3771 if (co_proc_number (& str
) == FAIL
)
3774 inst
.error
= BAD_ARGS
;
3778 if (skip_past_comma (& str
) == FAIL
3779 || cp_opc_expr (& str
, 20,4) == FAIL
)
3782 inst
.error
= BAD_ARGS
;
3786 if (skip_past_comma (& str
) == FAIL
3787 || cp_reg_required_here (& str
, 12) == FAIL
)
3790 inst
.error
= BAD_ARGS
;
3794 if (skip_past_comma (& str
) == FAIL
3795 || cp_reg_required_here (& str
, 16) == FAIL
)
3798 inst
.error
= BAD_ARGS
;
3802 if (skip_past_comma (& str
) == FAIL
3803 || cp_reg_required_here (& str
, 0) == FAIL
)
3806 inst
.error
= BAD_ARGS
;
3810 if (skip_past_comma (& str
) == SUCCESS
)
3812 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3815 inst
.error
= BAD_ARGS
;
3823 /* ARM V5 (argument parse)
3824 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3825 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3826 Instruction is not conditional, and has 0xf in the condition field.
3827 Otherwise, it's the same as MCR/MRC. */
3833 skip_whitespace (str
);
3835 if (co_proc_number (& str
) == FAIL
)
3838 inst
.error
= BAD_ARGS
;
3842 if (skip_past_comma (& str
) == FAIL
3843 || cp_opc_expr (& str
, 21, 3) == FAIL
)
3846 inst
.error
= BAD_ARGS
;
3850 if (skip_past_comma (& str
) == FAIL
3851 || reg_required_here (& str
, 12) == FAIL
)
3854 inst
.error
= BAD_ARGS
;
3858 if (skip_past_comma (& str
) == FAIL
3859 || cp_reg_required_here (& str
, 16) == FAIL
)
3862 inst
.error
= BAD_ARGS
;
3866 if (skip_past_comma (& str
) == FAIL
3867 || cp_reg_required_here (& str
, 0) == FAIL
)
3870 inst
.error
= BAD_ARGS
;
3874 if (skip_past_comma (& str
) == SUCCESS
)
3876 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3879 inst
.error
= BAD_ARGS
;
3887 /* ARM v5TEJ. Jump to Jazelle code. */
3894 skip_whitespace (str
);
3896 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3898 inst
.error
= BAD_ARGS
;
3902 /* Note - it is not illegal to do a "bxj pc". Useless, but not illegal. */
3904 as_tsktsk (_("use of r15 in bxj is not really useful"));
3909 /* THUMB V5 breakpoint instruction (argument parse)
3917 unsigned long number
;
3919 skip_whitespace (str
);
3921 /* Allow optional leading '#'. */
3922 if (is_immediate_prefix (*str
))
3925 memset (& expr
, '\0', sizeof (expr
));
3926 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3928 inst
.error
= _("bad or missing expression");
3932 number
= expr
.X_add_number
;
3934 /* Check it fits an 8 bit unsigned. */
3935 if (number
!= (number
& 0xff))
3937 inst
.error
= _("immediate value out of range");
3941 inst
.instruction
|= number
;
3946 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3947 Expects inst.instruction is set for BLX(1).
3948 Note: this is cloned from do_branch, and the reloc changed to be a
3949 new one that can cope with setting one extra bit (the H bit). */
3955 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3962 /* ScottB: February 5, 1998 */
3963 /* Check to see of PLT32 reloc required for the instruction. */
3965 /* arm_parse_reloc() works on input_line_pointer.
3966 We actually want to parse the operands to the branch instruction
3967 passed in 'str'. Save the input pointer and restore it later. */
3968 save_in
= input_line_pointer
;
3969 input_line_pointer
= str
;
3971 if (inst
.reloc
.exp
.X_op
== O_symbol
3973 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3975 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3976 inst
.reloc
.pc_rel
= 0;
3977 /* Modify str to point to after parsed operands, otherwise
3978 end_of_line() will complain about the (PLT) left in str. */
3979 str
= input_line_pointer
;
3983 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3984 inst
.reloc
.pc_rel
= 1;
3987 input_line_pointer
= save_in
;
3990 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3991 inst
.reloc
.pc_rel
= 1;
3992 #endif /* OBJ_ELF */
3997 /* ARM V5 branch-link-exchange instruction (argument parse)
3998 BLX <target_addr> ie BLX(1)
3999 BLX{<condition>} <Rm> ie BLX(2)
4000 Unfortunately, there are two different opcodes for this mnemonic.
4001 So, the insns[].value is not used, and the code here zaps values
4002 into inst.instruction.
4003 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
4012 skip_whitespace (mystr
);
4013 rm
= reg_required_here (& mystr
, 0);
4015 /* The above may set inst.error. Ignore his opinion. */
4020 /* Arg is a register.
4021 Use the condition code our caller put in inst.instruction.
4022 Pass ourselves off as a BX with a funny opcode. */
4023 inst
.instruction
|= 0x012fff30;
4028 /* This must be is BLX <target address>, no condition allowed. */
4029 if (inst
.instruction
!= COND_ALWAYS
)
4031 inst
.error
= BAD_COND
;
4035 inst
.instruction
= 0xfafffffe;
4037 /* Process like a B/BL, but with a different reloc.
4038 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
4043 /* ARM V5 Thumb BLX (argument parse)
4044 BLX <target_addr> which is BLX(1)
4045 BLX <Rm> which is BLX(2)
4046 Unfortunately, there are two different opcodes for this mnemonic.
4047 So, the tinsns[].value is not used, and the code here zaps values
4048 into inst.instruction. */
4057 skip_whitespace (mystr
);
4058 inst
.instruction
= 0x4780;
4060 /* Note that this call is to the ARM register recognizer. BLX(2)
4061 uses the ARM register space, not the Thumb one, so a call to
4062 thumb_reg() would be wrong. */
4063 rm
= reg_required_here (& mystr
, 3);
4068 /* It's BLX(2). The .instruction was zapped with rm & is final. */
4073 /* No ARM register. This must be BLX(1). Change the .instruction. */
4074 inst
.instruction
= 0xf7ffeffe;
4077 if (my_get_expression (& inst
.reloc
.exp
, & mystr
))
4080 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BLX
;
4081 inst
.reloc
.pc_rel
= 1;
4084 end_of_line (mystr
);
4087 /* ARM V5 breakpoint instruction (argument parse)
4088 BKPT <16 bit unsigned immediate>
4089 Instruction is not conditional.
4090 The bit pattern given in insns[] has the COND_ALWAYS condition,
4091 and it is an error if the caller tried to override that. */
4098 unsigned long number
;
4100 skip_whitespace (str
);
4102 /* Allow optional leading '#'. */
4103 if (is_immediate_prefix (* str
))
4106 memset (& expr
, '\0', sizeof (expr
));
4108 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
4110 inst
.error
= _("bad or missing expression");
4114 number
= expr
.X_add_number
;
4116 /* Check it fits a 16 bit unsigned. */
4117 if (number
!= (number
& 0xffff))
4119 inst
.error
= _("immediate value out of range");
4123 /* Top 12 of 16 bits to bits 19:8. */
4124 inst
.instruction
|= (number
& 0xfff0) << 4;
4126 /* Bottom 4 of 16 bits to bits 3:0. */
4127 inst
.instruction
|= number
& 0xf;
4132 /* Xscale multiply-accumulate (argument parse)
4135 MIAxycc acc0,Rm,Rs. */
4144 if (accum0_required_here (& str
) == FAIL
)
4145 inst
.error
= ERR_NO_ACCUM
;
4147 else if (skip_past_comma (& str
) == FAIL
4148 || (rm
= reg_required_here (& str
, 0)) == FAIL
)
4149 inst
.error
= BAD_ARGS
;
4151 else if (skip_past_comma (& str
) == FAIL
4152 || (rs
= reg_required_here (& str
, 12)) == FAIL
)
4153 inst
.error
= BAD_ARGS
;
4155 /* inst.instruction has now been zapped with both rm and rs. */
4156 else if (rm
== REG_PC
|| rs
== REG_PC
)
4157 inst
.error
= BAD_PC
; /* Undefined result if rm or rs is R15. */
4163 /* Xscale move-accumulator-register (argument parse)
4165 MARcc acc0,RdLo,RdHi. */
4173 if (accum0_required_here (& str
) == FAIL
)
4174 inst
.error
= ERR_NO_ACCUM
;
4176 else if (skip_past_comma (& str
) == FAIL
4177 || (rdlo
= reg_required_here (& str
, 12)) == FAIL
)
4178 inst
.error
= BAD_ARGS
;
4180 else if (skip_past_comma (& str
) == FAIL
4181 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
4182 inst
.error
= BAD_ARGS
;
4184 /* inst.instruction has now been zapped with both rdlo and rdhi. */
4185 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
4186 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
4192 /* Xscale move-register-accumulator (argument parse)
4194 MRAcc RdLo,RdHi,acc0. */
4203 skip_whitespace (str
);
4205 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
)
4206 inst
.error
= BAD_ARGS
;
4208 else if (skip_past_comma (& str
) == FAIL
4209 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
4210 inst
.error
= BAD_ARGS
;
4212 else if (skip_past_comma (& str
) == FAIL
4213 || accum0_required_here (& str
) == FAIL
)
4214 inst
.error
= ERR_NO_ACCUM
;
4216 /* inst.instruction has now been zapped with both rdlo and rdhi. */
4217 else if (rdlo
== rdhi
)
4218 inst
.error
= BAD_ARGS
; /* Undefined result if 2 writes to same reg. */
4220 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
4221 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
4226 /* ARMv5TE: Preload-Cache
4230 Syntactically, like LDR with B=1, W=0, L=1. */
4238 skip_whitespace (str
);
4242 inst
.error
= _("'[' expected after PLD mnemonic");
4247 skip_whitespace (str
);
4249 if ((rd
= reg_required_here (& str
, 16)) == FAIL
)
4252 skip_whitespace (str
);
4258 skip_whitespace (str
);
4260 /* Post-indexed addressing is not allowed with PLD. */
4261 if (skip_past_comma (&str
) == SUCCESS
)
4264 = _("post-indexed expression used in preload instruction");
4267 else if (*str
== '!') /* [Rn]! */
4269 inst
.error
= _("writeback used in preload instruction");
4273 inst
.instruction
|= INDEX_UP
| PRE_INDEX
;
4275 else /* [Rn, ...] */
4277 if (skip_past_comma (& str
) == FAIL
)
4279 inst
.error
= _("pre-indexed expression expected");
4283 if (ldst_extend (&str
) == FAIL
)
4286 skip_whitespace (str
);
4290 inst
.error
= _("missing ]");
4295 skip_whitespace (str
);
4297 if (* str
== '!') /* [Rn]! */
4299 inst
.error
= _("writeback used in preload instruction");
4303 inst
.instruction
|= PRE_INDEX
;
4309 /* ARMv5TE load-consecutive (argument parse)
4322 skip_whitespace (str
);
4324 if ((rd
= reg_required_here (& str
, 12)) == FAIL
)
4326 inst
.error
= BAD_ARGS
;
4330 if (skip_past_comma (& str
) == FAIL
4331 || (rn
= ld_mode_required_here (& str
)) == FAIL
)
4334 inst
.error
= BAD_ARGS
;
4338 /* inst.instruction has now been zapped with Rd and the addressing mode. */
4339 if (rd
& 1) /* Unpredictable result if Rd is odd. */
4341 inst
.error
= _("destination register must be even");
4347 inst
.error
= _("r14 not allowed here");
4351 if (((rd
== rn
) || (rd
+ 1 == rn
))
4352 && ((inst
.instruction
& WRITE_BACK
)
4353 || (!(inst
.instruction
& PRE_INDEX
))))
4354 as_warn (_("pre/post-indexing used when modified address register is destination"));
4356 /* For an index-register load, the index register must not overlap the
4357 destination (even if not write-back). */
4358 if ((inst
.instruction
& V4_STR_BIT
) == 0
4359 && (inst
.instruction
& HWOFFSET_IMM
) == 0)
4361 int rm
= inst
.instruction
& 0x0000000f;
4363 if (rm
== rd
|| (rm
== rd
+ 1))
4364 as_warn (_("ldrd destination registers must not overlap index register"));
4370 /* Returns the index into fp_values of a floating point number,
4371 or -1 if not in the table. */
4374 my_get_float_expression (str
)
4377 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4383 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
4385 /* Look for a raw floating point number. */
4386 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
4387 && is_end_of_line
[(unsigned char) *save_in
])
4389 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4391 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
4393 if (words
[j
] != fp_values
[i
][j
])
4397 if (j
== MAX_LITTLENUMS
)
4405 /* Try and parse a more complex expression, this will probably fail
4406 unless the code uses a floating point prefix (eg "0f"). */
4407 save_in
= input_line_pointer
;
4408 input_line_pointer
= *str
;
4409 if (expression (&exp
) == absolute_section
4410 && exp
.X_op
== O_big
4411 && exp
.X_add_number
< 0)
4413 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
4415 if (gen_to_words (words
, 5, (long) 15) == 0)
4417 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4419 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
4421 if (words
[j
] != fp_values
[i
][j
])
4425 if (j
== MAX_LITTLENUMS
)
4427 *str
= input_line_pointer
;
4428 input_line_pointer
= save_in
;
4435 *str
= input_line_pointer
;
4436 input_line_pointer
= save_in
;
4440 /* Return true if anything in the expression is a bignum. */
4443 walk_no_bignums (sp
)
4446 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
4449 if (symbol_get_value_expression (sp
)->X_add_symbol
)
4451 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
4452 || (symbol_get_value_expression (sp
)->X_op_symbol
4453 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
4459 static int in_my_get_expression
= 0;
4462 my_get_expression (ep
, str
)
4469 save_in
= input_line_pointer
;
4470 input_line_pointer
= *str
;
4471 in_my_get_expression
= 1;
4472 seg
= expression (ep
);
4473 in_my_get_expression
= 0;
4475 if (ep
->X_op
== O_illegal
)
4477 /* We found a bad expression in md_operand(). */
4478 *str
= input_line_pointer
;
4479 input_line_pointer
= save_in
;
4484 if (seg
!= absolute_section
4485 && seg
!= text_section
4486 && seg
!= data_section
4487 && seg
!= bss_section
4488 && seg
!= undefined_section
)
4490 inst
.error
= _("bad_segment");
4491 *str
= input_line_pointer
;
4492 input_line_pointer
= save_in
;
4497 /* Get rid of any bignums now, so that we don't generate an error for which
4498 we can't establish a line number later on. Big numbers are never valid
4499 in instructions, which is where this routine is always called. */
4500 if (ep
->X_op
== O_big
4501 || (ep
->X_add_symbol
4502 && (walk_no_bignums (ep
->X_add_symbol
)
4504 && walk_no_bignums (ep
->X_op_symbol
)))))
4506 inst
.error
= _("invalid constant");
4507 *str
= input_line_pointer
;
4508 input_line_pointer
= save_in
;
4512 *str
= input_line_pointer
;
4513 input_line_pointer
= save_in
;
4517 /* We handle all bad expressions here, so that we can report the faulty
4518 instruction in the error message. */
4523 if (in_my_get_expression
)
4525 expr
->X_op
= O_illegal
;
4526 if (inst
.error
== NULL
)
4527 inst
.error
= _("bad expression");
4531 /* UNRESTRICT should be one if <shift> <register> is permitted for this
4535 decode_shift (str
, unrestrict
)
4539 const struct asm_shift_name
* shift
;
4543 skip_whitespace (* str
);
4545 for (p
= * str
; ISALPHA (* p
); p
++)
4550 inst
.error
= _("shift expression expected");
4556 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
4561 inst
.error
= _("shift expression expected");
4565 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
4567 if (shift
->properties
->index
== SHIFT_RRX
)
4570 inst
.instruction
|= shift
->properties
->bit_field
;
4574 skip_whitespace (p
);
4576 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
4578 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
4582 else if (! is_immediate_prefix (* p
))
4584 inst
.error
= (unrestrict
4585 ? _("shift requires register or #expression")
4586 : _("shift requires #expression"));
4594 if (my_get_expression (& inst
.reloc
.exp
, & p
))
4597 /* Validate some simple #expressions. */
4598 if (inst
.reloc
.exp
.X_op
== O_constant
)
4600 unsigned num
= inst
.reloc
.exp
.X_add_number
;
4602 /* Reject operations greater than 32. */
4604 /* Reject a shift of 0 unless the mode allows it. */
4605 || (num
== 0 && shift
->properties
->allows_0
== 0)
4606 /* Reject a shift of 32 unless the mode allows it. */
4607 || (num
== 32 && shift
->properties
->allows_32
== 0)
4610 /* As a special case we allow a shift of zero for
4611 modes that do not support it to be recoded as an
4612 logical shift left of zero (ie nothing). We warn
4613 about this though. */
4616 as_warn (_("shift of 0 ignored."));
4617 shift
= & shift_names
[0];
4618 assert (shift
->properties
->index
== SHIFT_LSL
);
4622 inst
.error
= _("invalid immediate shift");
4627 /* Shifts of 32 are encoded as 0, for those shifts that
4632 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
4636 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
4637 inst
.reloc
.pc_rel
= 0;
4638 inst
.instruction
|= shift
->properties
->bit_field
;
4645 /* Do those data_ops which can take a negative immediate constant
4646 by altering the instuction. A bit of a hack really.
4650 by inverting the second operand, and
4653 by negating the second operand. */
4656 negate_data_op (instruction
, value
)
4657 unsigned long * instruction
;
4658 unsigned long value
;
4661 unsigned long negated
, inverted
;
4663 negated
= validate_immediate (-value
);
4664 inverted
= validate_immediate (~value
);
4666 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
4669 /* First negates. */
4670 case OPCODE_SUB
: /* ADD <-> SUB */
4671 new_inst
= OPCODE_ADD
;
4676 new_inst
= OPCODE_SUB
;
4680 case OPCODE_CMP
: /* CMP <-> CMN */
4681 new_inst
= OPCODE_CMN
;
4686 new_inst
= OPCODE_CMP
;
4690 /* Now Inverted ops. */
4691 case OPCODE_MOV
: /* MOV <-> MVN */
4692 new_inst
= OPCODE_MVN
;
4697 new_inst
= OPCODE_MOV
;
4701 case OPCODE_AND
: /* AND <-> BIC */
4702 new_inst
= OPCODE_BIC
;
4707 new_inst
= OPCODE_AND
;
4711 case OPCODE_ADC
: /* ADC <-> SBC */
4712 new_inst
= OPCODE_SBC
;
4717 new_inst
= OPCODE_ADC
;
4721 /* We cannot do anything. */
4726 if (value
== (unsigned) FAIL
)
4729 *instruction
&= OPCODE_MASK
;
4730 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
4741 skip_whitespace (* str
);
4743 if (reg_required_here (str
, 0) != FAIL
)
4745 if (skip_past_comma (str
) == SUCCESS
)
4746 /* Shift operation on register. */
4747 return decode_shift (str
, NO_SHIFT_RESTRICT
);
4753 /* Immediate expression. */
4754 if (is_immediate_prefix (**str
))
4759 if (my_get_expression (&inst
.reloc
.exp
, str
))
4762 if (inst
.reloc
.exp
.X_add_symbol
)
4764 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4765 inst
.reloc
.pc_rel
= 0;
4769 if (skip_past_comma (str
) == SUCCESS
)
4771 /* #x, y -- ie explicit rotation by Y. */
4772 if (my_get_expression (&expr
, str
))
4775 if (expr
.X_op
!= O_constant
)
4777 inst
.error
= _("constant expression expected");
4781 /* Rotate must be a multiple of 2. */
4782 if (((unsigned) expr
.X_add_number
) > 30
4783 || (expr
.X_add_number
& 1) != 0
4784 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
4786 inst
.error
= _("invalid constant");
4789 inst
.instruction
|= INST_IMMEDIATE
;
4790 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4791 inst
.instruction
|= expr
.X_add_number
<< 7;
4795 /* Implicit rotation, select a suitable one. */
4796 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4800 /* Can't be done. Perhaps the code reads something like
4801 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
4802 if ((value
= negate_data_op (&inst
.instruction
,
4803 inst
.reloc
.exp
.X_add_number
))
4806 inst
.error
= _("invalid constant");
4811 inst
.instruction
|= value
;
4814 inst
.instruction
|= INST_IMMEDIATE
;
4819 inst
.error
= _("register or shift expression expected");
4828 skip_whitespace (* str
);
4830 if (fp_reg_required_here (str
, 0) != FAIL
)
4834 /* Immediate expression. */
4835 if (*((*str
)++) == '#')
4841 skip_whitespace (* str
);
4843 /* First try and match exact strings, this is to guarantee
4844 that some formats will work even for cross assembly. */
4846 for (i
= 0; fp_const
[i
]; i
++)
4848 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
4852 *str
+= strlen (fp_const
[i
]);
4853 if (is_end_of_line
[(unsigned char) **str
])
4855 inst
.instruction
|= i
+ 8;
4862 /* Just because we didn't get a match doesn't mean that the
4863 constant isn't valid, just that it is in a format that we
4864 don't automatically recognize. Try parsing it with
4865 the standard expression routines. */
4866 if ((i
= my_get_float_expression (str
)) >= 0)
4868 inst
.instruction
|= i
+ 8;
4872 inst
.error
= _("invalid floating point immediate expression");
4876 _("floating point register or immediate expression expected");
4885 skip_whitespace (str
);
4887 if (reg_required_here (&str
, 12) == FAIL
4888 || skip_past_comma (&str
) == FAIL
4889 || reg_required_here (&str
, 16) == FAIL
4890 || skip_past_comma (&str
) == FAIL
4891 || data_op2 (&str
) == FAIL
)
4894 inst
.error
= BAD_ARGS
;
4906 /* This is a pseudo-op of the form "adr rd, label" to be converted
4907 into a relative address of the form "add rd, pc, #label-.-8". */
4908 skip_whitespace (str
);
4910 if (reg_required_here (&str
, 12) == FAIL
4911 || skip_past_comma (&str
) == FAIL
4912 || my_get_expression (&inst
.reloc
.exp
, &str
))
4915 inst
.error
= BAD_ARGS
;
4919 /* Frag hacking will turn this into a sub instruction if the offset turns
4920 out to be negative. */
4921 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4922 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
4923 inst
.reloc
.pc_rel
= 1;
4932 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4933 into a relative address of the form:
4934 add rd, pc, #low(label-.-8)"
4935 add rd, rd, #high(label-.-8)" */
4937 skip_whitespace (str
);
4939 if (reg_required_here (&str
, 12) == FAIL
4940 || skip_past_comma (&str
) == FAIL
4941 || my_get_expression (&inst
.reloc
.exp
, &str
))
4944 inst
.error
= BAD_ARGS
;
4950 /* Frag hacking will turn this into a sub instruction if the offset turns
4951 out to be negative. */
4952 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
4953 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
4954 inst
.reloc
.pc_rel
= 1;
4955 inst
.size
= INSN_SIZE
* 2;
4964 skip_whitespace (str
);
4966 if (reg_required_here (&str
, 16) == FAIL
)
4969 inst
.error
= BAD_ARGS
;
4973 if (skip_past_comma (&str
) == FAIL
4974 || data_op2 (&str
) == FAIL
)
4977 inst
.error
= BAD_ARGS
;
4989 skip_whitespace (str
);
4991 if (reg_required_here (&str
, 12) == FAIL
)
4994 inst
.error
= BAD_ARGS
;
4998 if (skip_past_comma (&str
) == FAIL
4999 || data_op2 (&str
) == FAIL
)
5002 inst
.error
= BAD_ARGS
;
5021 if (my_get_expression (& inst
.reloc
.exp
, str
))
5024 if (inst
.reloc
.exp
.X_op
== O_constant
)
5026 int value
= inst
.reloc
.exp
.X_add_number
;
5028 if (value
< -4095 || value
> 4095)
5030 inst
.error
= _("address offset too large");
5040 inst
.instruction
|= add
| value
;
5044 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
5045 inst
.reloc
.pc_rel
= 0;
5058 if (reg_required_here (str
, 0) == FAIL
)
5061 inst
.instruction
|= add
| OFFSET_REG
;
5062 if (skip_past_comma (str
) == SUCCESS
)
5063 return decode_shift (str
, SHIFT_RESTRICT
);
5077 skip_whitespace (str
);
5079 if ((conflict_reg
= reg_required_here (&str
, 12)) == FAIL
)
5082 inst
.error
= BAD_ARGS
;
5086 if (skip_past_comma (&str
) == FAIL
)
5088 inst
.error
= _("address expected");
5098 skip_whitespace (str
);
5100 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5103 /* Conflicts can occur on stores as well as loads. */
5104 conflict_reg
= (conflict_reg
== reg
);
5106 skip_whitespace (str
);
5112 if (skip_past_comma (&str
) == SUCCESS
)
5114 /* [Rn],... (post inc) */
5115 if (ldst_extend (&str
) == FAIL
)
5118 as_warn (_("%s register same as write-back base"),
5119 ((inst
.instruction
& LOAD_BIT
)
5120 ? _("destination") : _("source")));
5125 skip_whitespace (str
);
5130 as_warn (_("%s register same as write-back base"),
5131 ((inst
.instruction
& LOAD_BIT
)
5132 ? _("destination") : _("source")));
5134 inst
.instruction
|= WRITE_BACK
;
5137 inst
.instruction
|= INDEX_UP
;
5144 if (skip_past_comma (&str
) == FAIL
)
5146 inst
.error
= _("pre-indexed expression expected");
5151 if (ldst_extend (&str
) == FAIL
)
5154 skip_whitespace (str
);
5158 inst
.error
= _("missing ]");
5162 skip_whitespace (str
);
5167 as_warn (_("%s register same as write-back base"),
5168 ((inst
.instruction
& LOAD_BIT
)
5169 ? _("destination") : _("source")));
5171 inst
.instruction
|= WRITE_BACK
;
5175 else if (*str
== '=')
5177 if ((inst
.instruction
& LOAD_BIT
) == 0)
5179 inst
.error
= _("invalid pseudo operation");
5183 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5186 skip_whitespace (str
);
5188 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5191 if (inst
.reloc
.exp
.X_op
!= O_constant
5192 && inst
.reloc
.exp
.X_op
!= O_symbol
)
5194 inst
.error
= _("constant expression expected");
5198 if (inst
.reloc
.exp
.X_op
== O_constant
)
5200 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
5204 /* This can be done with a mov instruction. */
5205 inst
.instruction
&= LITERAL_MASK
;
5206 inst
.instruction
|= (INST_IMMEDIATE
5207 | (OPCODE_MOV
<< DATA_OP_SHIFT
));
5208 inst
.instruction
|= value
& 0xfff;
5213 value
= validate_immediate (~inst
.reloc
.exp
.X_add_number
);
5217 /* This can be done with a mvn instruction. */
5218 inst
.instruction
&= LITERAL_MASK
;
5219 inst
.instruction
|= (INST_IMMEDIATE
5220 | (OPCODE_MVN
<< DATA_OP_SHIFT
));
5221 inst
.instruction
|= value
& 0xfff;
5227 /* Insert into literal pool. */
5228 if (add_to_lit_pool () == FAIL
)
5231 inst
.error
= _("literal pool insertion failed");
5235 /* Change the instruction exp to point to the pool. */
5236 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
5237 inst
.reloc
.pc_rel
= 1;
5238 inst
.instruction
|= (REG_PC
<< 16);
5243 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5246 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
5248 /* PC rel adjust. */
5249 inst
.reloc
.exp
.X_add_number
-= 8;
5251 inst
.reloc
.pc_rel
= 1;
5252 inst
.instruction
|= (REG_PC
<< 16);
5256 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
5267 skip_whitespace (str
);
5269 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
5272 inst
.error
= BAD_ARGS
;
5276 if (skip_past_comma (& str
) == FAIL
)
5278 inst
.error
= _("address expected");
5288 skip_whitespace (str
);
5290 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5293 /* ldrt/strt always use post-indexed addressing, so if the base is
5294 the same as Rd, we warn. */
5295 if (conflict_reg
== reg
)
5296 as_warn (_("%s register same as write-back base"),
5297 ((inst
.instruction
& LOAD_BIT
)
5298 ? _("destination") : _("source")));
5300 skip_whitespace (str
);
5306 if (skip_past_comma (&str
) == SUCCESS
)
5308 /* [Rn],... (post inc) */
5309 if (ldst_extend (&str
) == FAIL
)
5315 skip_whitespace (str
);
5317 /* Skip a write-back '!'. */
5321 inst
.instruction
|= INDEX_UP
;
5326 inst
.error
= _("post-indexed expression expected");
5332 inst
.error
= _("post-indexed expression expected");
5341 ldst_extend_v4 (str
)
5351 if (my_get_expression (& inst
.reloc
.exp
, str
))
5354 if (inst
.reloc
.exp
.X_op
== O_constant
)
5356 int value
= inst
.reloc
.exp
.X_add_number
;
5358 if (value
< -255 || value
> 255)
5360 inst
.error
= _("address offset too large");
5370 /* Halfword and signextension instructions have the
5371 immediate value split across bits 11..8 and bits 3..0. */
5372 inst
.instruction
|= (add
| HWOFFSET_IMM
5373 | ((value
>> 4) << 8) | (value
& 0xF));
5377 inst
.instruction
|= HWOFFSET_IMM
;
5378 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
5379 inst
.reloc
.pc_rel
= 0;
5392 if (reg_required_here (str
, 0) == FAIL
)
5395 inst
.instruction
|= add
;
5400 /* Halfword and signed-byte load/store operations. */
5409 skip_whitespace (str
);
5411 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
5414 inst
.error
= BAD_ARGS
;
5418 if (skip_past_comma (& str
) == FAIL
)
5420 inst
.error
= _("address expected");
5430 skip_whitespace (str
);
5432 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5435 /* Conflicts can occur on stores as well as loads. */
5436 conflict_reg
= (conflict_reg
== reg
);
5438 skip_whitespace (str
);
5444 if (skip_past_comma (&str
) == SUCCESS
)
5446 /* [Rn],... (post inc) */
5447 if (ldst_extend_v4 (&str
) == FAIL
)
5450 as_warn (_("%s register same as write-back base"),
5451 ((inst
.instruction
& LOAD_BIT
)
5452 ? _("destination") : _("source")));
5457 inst
.instruction
|= HWOFFSET_IMM
;
5459 skip_whitespace (str
);
5464 as_warn (_("%s register same as write-back base"),
5465 ((inst
.instruction
& LOAD_BIT
)
5466 ? _("destination") : _("source")));
5468 inst
.instruction
|= WRITE_BACK
;
5471 inst
.instruction
|= INDEX_UP
;
5478 if (skip_past_comma (&str
) == FAIL
)
5480 inst
.error
= _("pre-indexed expression expected");
5485 if (ldst_extend_v4 (&str
) == FAIL
)
5488 skip_whitespace (str
);
5492 inst
.error
= _("missing ]");
5496 skip_whitespace (str
);
5501 as_warn (_("%s register same as write-back base"),
5502 ((inst
.instruction
& LOAD_BIT
)
5503 ? _("destination") : _("source")));
5505 inst
.instruction
|= WRITE_BACK
;
5509 else if (*str
== '=')
5511 if ((inst
.instruction
& LOAD_BIT
) == 0)
5513 inst
.error
= _("invalid pseudo operation");
5517 /* XXX Does this work correctly for half-word/byte ops? */
5518 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5521 skip_whitespace (str
);
5523 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5526 if (inst
.reloc
.exp
.X_op
!= O_constant
5527 && inst
.reloc
.exp
.X_op
!= O_symbol
)
5529 inst
.error
= _("constant expression expected");
5533 if (inst
.reloc
.exp
.X_op
== O_constant
)
5535 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
5539 /* This can be done with a mov instruction. */
5540 inst
.instruction
&= LITERAL_MASK
;
5541 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
5542 inst
.instruction
|= value
& 0xfff;
5547 value
= validate_immediate (~ inst
.reloc
.exp
.X_add_number
);
5551 /* This can be done with a mvn instruction. */
5552 inst
.instruction
&= LITERAL_MASK
;
5553 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MVN
<< DATA_OP_SHIFT
);
5554 inst
.instruction
|= value
& 0xfff;
5560 /* Insert into literal pool. */
5561 if (add_to_lit_pool () == FAIL
)
5564 inst
.error
= _("literal pool insertion failed");
5568 /* Change the instruction exp to point to the pool. */
5569 inst
.instruction
|= HWOFFSET_IMM
;
5570 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
5571 inst
.reloc
.pc_rel
= 1;
5572 inst
.instruction
|= (REG_PC
<< 16);
5577 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5580 inst
.instruction
|= HWOFFSET_IMM
;
5581 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
5583 /* PC rel adjust. */
5584 inst
.reloc
.exp
.X_add_number
-= 8;
5586 inst
.reloc
.pc_rel
= 1;
5587 inst
.instruction
|= (REG_PC
<< 16);
5591 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
5600 char * str
= * strp
;
5604 /* We come back here if we get ranges concatenated by '+' or '|'. */
5619 skip_whitespace (str
);
5621 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
5630 inst
.error
= _("bad range in register list");
5634 for (i
= cur_reg
+ 1; i
< reg
; i
++)
5636 if (range
& (1 << i
))
5638 (_("Warning: duplicated register (r%d) in register list"),
5646 if (range
& (1 << reg
))
5647 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
5649 else if (reg
<= cur_reg
)
5650 as_tsktsk (_("Warning: register range not in ascending order"));
5655 while (skip_past_comma (&str
) != FAIL
5656 || (in_range
= 1, *str
++ == '-'));
5658 skip_whitespace (str
);
5662 inst
.error
= _("missing `}'");
5670 if (my_get_expression (&expr
, &str
))
5673 if (expr
.X_op
== O_constant
)
5675 if (expr
.X_add_number
5676 != (expr
.X_add_number
& 0x0000ffff))
5678 inst
.error
= _("invalid register mask");
5682 if ((range
& expr
.X_add_number
) != 0)
5684 int regno
= range
& expr
.X_add_number
;
5687 regno
= (1 << regno
) - 1;
5689 (_("Warning: duplicated register (r%d) in register list"),
5693 range
|= expr
.X_add_number
;
5697 if (inst
.reloc
.type
!= 0)
5699 inst
.error
= _("expression too complex");
5703 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
5704 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
5705 inst
.reloc
.pc_rel
= 0;
5709 skip_whitespace (str
);
5711 if (*str
== '|' || *str
== '+')
5717 while (another_range
);
5730 skip_whitespace (str
);
5732 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
5735 if (base_reg
== REG_PC
)
5737 inst
.error
= _("r15 not allowed as base register");
5741 skip_whitespace (str
);
5745 inst
.instruction
|= WRITE_BACK
;
5749 if (skip_past_comma (&str
) == FAIL
5750 || (range
= reg_list (&str
)) == FAIL
)
5753 inst
.error
= BAD_ARGS
;
5760 inst
.instruction
|= LDM_TYPE_2_OR_3
;
5763 inst
.instruction
|= range
;
5772 skip_whitespace (str
);
5774 /* Allow optional leading '#'. */
5775 if (is_immediate_prefix (*str
))
5778 if (my_get_expression (& inst
.reloc
.exp
, & str
))
5781 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
5782 inst
.reloc
.pc_rel
= 0;
5794 skip_whitespace (str
);
5796 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
5801 inst
.error
= _("r15 not allowed in swap");
5805 if (skip_past_comma (&str
) == FAIL
5806 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
5809 inst
.error
= BAD_ARGS
;
5815 inst
.error
= _("r15 not allowed in swap");
5819 if (skip_past_comma (&str
) == FAIL
5822 inst
.error
= BAD_ARGS
;
5826 skip_whitespace (str
);
5828 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5833 inst
.error
= BAD_PC
;
5837 skip_whitespace (str
);
5841 inst
.error
= _("missing ]");
5853 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5860 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
5861 required for the instruction. */
5863 /* arm_parse_reloc () works on input_line_pointer.
5864 We actually want to parse the operands to the branch instruction
5865 passed in 'str'. Save the input pointer and restore it later. */
5866 save_in
= input_line_pointer
;
5867 input_line_pointer
= str
;
5868 if (inst
.reloc
.exp
.X_op
== O_symbol
5870 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
5872 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
5873 inst
.reloc
.pc_rel
= 0;
5874 /* Modify str to point to after parsed operands, otherwise
5875 end_of_line() will complain about the (PLT) left in str. */
5876 str
= input_line_pointer
;
5880 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
5881 inst
.reloc
.pc_rel
= 1;
5883 input_line_pointer
= save_in
;
5886 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
5887 inst
.reloc
.pc_rel
= 1;
5888 #endif /* OBJ_ELF */
5900 skip_whitespace (str
);
5902 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
5904 inst
.error
= BAD_ARGS
;
5908 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
5910 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
5919 /* Co-processor data operation.
5920 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
5921 skip_whitespace (str
);
5923 if (co_proc_number (&str
) == FAIL
)
5926 inst
.error
= BAD_ARGS
;
5930 if (skip_past_comma (&str
) == FAIL
5931 || cp_opc_expr (&str
, 20,4) == FAIL
)
5934 inst
.error
= BAD_ARGS
;
5938 if (skip_past_comma (&str
) == FAIL
5939 || cp_reg_required_here (&str
, 12) == FAIL
)
5942 inst
.error
= BAD_ARGS
;
5946 if (skip_past_comma (&str
) == FAIL
5947 || cp_reg_required_here (&str
, 16) == FAIL
)
5950 inst
.error
= BAD_ARGS
;
5954 if (skip_past_comma (&str
) == FAIL
5955 || cp_reg_required_here (&str
, 0) == FAIL
)
5958 inst
.error
= BAD_ARGS
;
5962 if (skip_past_comma (&str
) == SUCCESS
)
5964 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5967 inst
.error
= BAD_ARGS
;
5980 /* Co-processor register load/store.
5981 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
5983 skip_whitespace (str
);
5985 if (co_proc_number (&str
) == FAIL
)
5988 inst
.error
= BAD_ARGS
;
5992 if (skip_past_comma (&str
) == FAIL
5993 || cp_reg_required_here (&str
, 12) == FAIL
)
5996 inst
.error
= BAD_ARGS
;
6000 if (skip_past_comma (&str
) == FAIL
6001 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
6004 inst
.error
= BAD_ARGS
;
6016 /* Co-processor register transfer.
6017 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
6019 skip_whitespace (str
);
6021 if (co_proc_number (&str
) == FAIL
)
6024 inst
.error
= BAD_ARGS
;
6028 if (skip_past_comma (&str
) == FAIL
6029 || cp_opc_expr (&str
, 21, 3) == FAIL
)
6032 inst
.error
= BAD_ARGS
;
6036 if (skip_past_comma (&str
) == FAIL
6037 || reg_required_here (&str
, 12) == FAIL
)
6040 inst
.error
= BAD_ARGS
;
6044 if (skip_past_comma (&str
) == FAIL
6045 || cp_reg_required_here (&str
, 16) == FAIL
)
6048 inst
.error
= BAD_ARGS
;
6052 if (skip_past_comma (&str
) == FAIL
6053 || cp_reg_required_here (&str
, 0) == FAIL
)
6056 inst
.error
= BAD_ARGS
;
6060 if (skip_past_comma (&str
) == SUCCESS
)
6062 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
6065 inst
.error
= BAD_ARGS
;
6078 /* FP control registers.
6079 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
6081 skip_whitespace (str
);
6083 if (reg_required_here (&str
, 12) == FAIL
)
6086 inst
.error
= BAD_ARGS
;
6098 skip_whitespace (str
);
6100 if (fp_reg_required_here (&str
, 12) == FAIL
)
6103 inst
.error
= BAD_ARGS
;
6107 if (skip_past_comma (&str
) == FAIL
6108 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
6111 inst
.error
= BAD_ARGS
;
6124 skip_whitespace (str
);
6126 if (fp_reg_required_here (&str
, 12) == FAIL
)
6129 inst
.error
= BAD_ARGS
;
6133 /* Get Number of registers to transfer. */
6134 if (skip_past_comma (&str
) == FAIL
6135 || my_get_expression (&inst
.reloc
.exp
, &str
))
6138 inst
.error
= _("constant expression expected");
6142 if (inst
.reloc
.exp
.X_op
!= O_constant
)
6144 inst
.error
= _("constant value required for number of registers");
6148 num_regs
= inst
.reloc
.exp
.X_add_number
;
6150 if (num_regs
< 1 || num_regs
> 4)
6152 inst
.error
= _("number of registers must be in the range [1:4]");
6159 inst
.instruction
|= CP_T_X
;
6162 inst
.instruction
|= CP_T_Y
;
6165 inst
.instruction
|= CP_T_Y
| CP_T_X
;
6173 if (inst
.instruction
& (CP_T_Pre
| CP_T_UD
)) /* ea/fd format. */
6179 /* The instruction specified "ea" or "fd", so we can only accept
6180 [Rn]{!}. The instruction does not really support stacking or
6181 unstacking, so we have to emulate these by setting appropriate
6182 bits and offsets. */
6183 if (skip_past_comma (&str
) == FAIL
6187 inst
.error
= BAD_ARGS
;
6192 skip_whitespace (str
);
6194 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
6197 skip_whitespace (str
);
6201 inst
.error
= BAD_ARGS
;
6213 _("r15 not allowed as base register with write-back");
6220 if (inst
.instruction
& CP_T_Pre
)
6222 /* Pre-decrement. */
6223 offset
= 3 * num_regs
;
6225 inst
.instruction
|= CP_T_WB
;
6229 /* Post-increment. */
6232 inst
.instruction
|= CP_T_WB
;
6233 offset
= 3 * num_regs
;
6237 /* No write-back, so convert this into a standard pre-increment
6238 instruction -- aesthetically more pleasing. */
6239 inst
.instruction
|= CP_T_Pre
| CP_T_UD
;
6244 inst
.instruction
|= offset
;
6246 else if (skip_past_comma (&str
) == FAIL
6247 || cp_address_required_here (&str
, CP_WB_OK
) == FAIL
)
6250 inst
.error
= BAD_ARGS
;
6261 skip_whitespace (str
);
6263 if (fp_reg_required_here (&str
, 12) == FAIL
)
6266 inst
.error
= BAD_ARGS
;
6270 if (skip_past_comma (&str
) == FAIL
6271 || fp_reg_required_here (&str
, 16) == FAIL
)
6274 inst
.error
= BAD_ARGS
;
6278 if (skip_past_comma (&str
) == FAIL
6279 || fp_op2 (&str
) == FAIL
)
6282 inst
.error
= BAD_ARGS
;
6291 do_fpa_monadic (str
)
6294 skip_whitespace (str
);
6296 if (fp_reg_required_here (&str
, 12) == FAIL
)
6299 inst
.error
= BAD_ARGS
;
6303 if (skip_past_comma (&str
) == FAIL
6304 || fp_op2 (&str
) == FAIL
)
6307 inst
.error
= BAD_ARGS
;
6319 skip_whitespace (str
);
6321 if (fp_reg_required_here (&str
, 16) == FAIL
)
6324 inst
.error
= BAD_ARGS
;
6328 if (skip_past_comma (&str
) == FAIL
6329 || fp_op2 (&str
) == FAIL
)
6332 inst
.error
= BAD_ARGS
;
6341 do_fpa_from_reg (str
)
6344 skip_whitespace (str
);
6346 if (fp_reg_required_here (&str
, 16) == FAIL
)
6349 inst
.error
= BAD_ARGS
;
6353 if (skip_past_comma (&str
) == FAIL
6354 || reg_required_here (&str
, 12) == FAIL
)
6357 inst
.error
= BAD_ARGS
;
6369 skip_whitespace (str
);
6371 if (reg_required_here (&str
, 12) == FAIL
)
6374 if (skip_past_comma (&str
) == FAIL
6375 || fp_reg_required_here (&str
, 0) == FAIL
)
6378 inst
.error
= BAD_ARGS
;
6387 vfp_sp_reg_required_here (str
, pos
)
6389 enum vfp_sp_reg_pos pos
;
6394 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_SN
].htab
)) != FAIL
)
6399 inst
.instruction
|= ((reg
>> 1) << 12) | ((reg
& 1) << 22);
6403 inst
.instruction
|= ((reg
>> 1) << 16) | ((reg
& 1) << 7);
6407 inst
.instruction
|= ((reg
>> 1) << 0) | ((reg
& 1) << 5);
6416 /* In the few cases where we might be able to accept something else
6417 this error can be overridden. */
6418 inst
.error
= _(all_reg_maps
[REG_TYPE_SN
].expected
);
6420 /* Restore the start point. */
6426 vfp_dp_reg_required_here (str
, pos
)
6428 enum vfp_dp_reg_pos pos
;
6433 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_DN
].htab
)) != FAIL
)
6438 inst
.instruction
|= reg
<< 12;
6442 inst
.instruction
|= reg
<< 16;
6446 inst
.instruction
|= reg
<< 0;
6455 /* In the few cases where we might be able to accept something else
6456 this error can be overridden. */
6457 inst
.error
= _(all_reg_maps
[REG_TYPE_DN
].expected
);
6459 /* Restore the start point. */
6465 do_vfp_sp_monadic (str
)
6468 skip_whitespace (str
);
6470 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
6473 if (skip_past_comma (&str
) == FAIL
6474 || vfp_sp_reg_required_here (&str
, VFP_REG_Sm
) == FAIL
)
6477 inst
.error
= BAD_ARGS
;
6486 do_vfp_dp_monadic (str
)
6489 skip_whitespace (str
);
6491 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
6494 if (skip_past_comma (&str
) == FAIL
6495 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
6498 inst
.error
= BAD_ARGS
;
6507 do_vfp_sp_dyadic (str
)
6510 skip_whitespace (str
);
6512 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
6515 if (skip_past_comma (&str
) == FAIL
6516 || vfp_sp_reg_required_here (&str
, VFP_REG_Sn
) == FAIL
6517 || skip_past_comma (&str
) == FAIL
6518 || vfp_sp_reg_required_here (&str
, VFP_REG_Sm
) == FAIL
)
6521 inst
.error
= BAD_ARGS
;
6530 do_vfp_dp_dyadic (str
)
6533 skip_whitespace (str
);
6535 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
6538 if (skip_past_comma (&str
) == FAIL
6539 || vfp_dp_reg_required_here (&str
, VFP_REG_Dn
) == FAIL
6540 || skip_past_comma (&str
) == FAIL
6541 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
6544 inst
.error
= BAD_ARGS
;
6553 do_vfp_reg_from_sp (str
)
6556 skip_whitespace (str
);
6558 if (reg_required_here (&str
, 12) == FAIL
)
6561 if (skip_past_comma (&str
) == FAIL
6562 || vfp_sp_reg_required_here (&str
, VFP_REG_Sn
) == FAIL
)
6565 inst
.error
= BAD_ARGS
;
6574 do_vfp_sp_reg2 (str
)
6577 skip_whitespace (str
);
6579 if (reg_required_here (&str
, 12) == FAIL
)
6582 if (skip_past_comma (&str
) == FAIL
6583 || reg_required_here (&str
, 16) == FAIL
6584 || skip_past_comma (&str
) == FAIL
)
6587 inst
.error
= BAD_ARGS
;
6591 /* We require exactly two consecutive SP registers. */
6592 if (vfp_sp_reg_list (&str
, VFP_REG_Sm
) != 2)
6595 inst
.error
= _("only two consecutive VFP SP registers allowed here");
6603 do_vfp_sp_from_reg (str
)
6606 skip_whitespace (str
);
6608 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sn
) == FAIL
)
6611 if (skip_past_comma (&str
) == FAIL
6612 || reg_required_here (&str
, 12) == FAIL
)
6615 inst
.error
= BAD_ARGS
;
6624 do_vfp_reg_from_dp (str
)
6627 skip_whitespace (str
);
6629 if (reg_required_here (&str
, 12) == FAIL
)
6632 if (skip_past_comma (&str
) == FAIL
6633 || vfp_dp_reg_required_here (&str
, VFP_REG_Dn
) == FAIL
)
6636 inst
.error
= BAD_ARGS
;
6645 do_vfp_reg2_from_dp (str
)
6648 skip_whitespace (str
);
6650 if (reg_required_here (&str
, 12) == FAIL
)
6653 if (skip_past_comma (&str
) == FAIL
6654 || reg_required_here (&str
, 16) == FAIL
6655 || skip_past_comma (&str
) == FAIL
6656 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
6659 inst
.error
= BAD_ARGS
;
6668 do_vfp_dp_from_reg (str
)
6671 skip_whitespace (str
);
6673 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dn
) == FAIL
)
6676 if (skip_past_comma (&str
) == FAIL
6677 || reg_required_here (&str
, 12) == FAIL
)
6680 inst
.error
= BAD_ARGS
;
6689 do_vfp_dp_from_reg2 (str
)
6692 skip_whitespace (str
);
6694 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
6697 if (skip_past_comma (&str
) == FAIL
6698 || reg_required_here (&str
, 12) == FAIL
6699 || skip_past_comma (&str
) == FAIL
6700 || reg_required_here (&str
, 16))
6703 inst
.error
= BAD_ARGS
;
6711 static const struct vfp_reg
*
6718 const struct vfp_reg
*vreg
;
6722 /* Find the end of the current token. */
6727 while (ISALPHA (c
));
6732 for (vreg
= vfp_regs
+ 0;
6733 vreg
< vfp_regs
+ sizeof (vfp_regs
) / sizeof (struct vfp_reg
);
6736 if (strcmp (start
, vreg
->name
) == 0)
6749 vfp_psr_required_here (str
)
6753 const struct vfp_reg
*vreg
;
6755 vreg
= vfp_psr_parse (str
);
6759 inst
.instruction
|= vreg
->regno
;
6763 inst
.error
= _("VFP system register expected");
6770 do_vfp_reg_from_ctrl (str
)
6773 skip_whitespace (str
);
6775 if (reg_required_here (&str
, 12) == FAIL
)
6778 if (skip_past_comma (&str
) == FAIL
6779 || vfp_psr_required_here (&str
) == FAIL
)
6782 inst
.error
= BAD_ARGS
;
6791 do_vfp_ctrl_from_reg (str
)
6794 skip_whitespace (str
);
6796 if (vfp_psr_required_here (&str
) == FAIL
)
6799 if (skip_past_comma (&str
) == FAIL
6800 || reg_required_here (&str
, 12) == FAIL
)
6803 inst
.error
= BAD_ARGS
;
6812 do_vfp_sp_ldst (str
)
6815 skip_whitespace (str
);
6817 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
6820 inst
.error
= BAD_ARGS
;
6824 if (skip_past_comma (&str
) == FAIL
6825 || cp_address_required_here (&str
, CP_NO_WB
) == FAIL
)
6828 inst
.error
= BAD_ARGS
;
6837 do_vfp_dp_ldst (str
)
6840 skip_whitespace (str
);
6842 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
6845 inst
.error
= BAD_ARGS
;
6849 if (skip_past_comma (&str
) == FAIL
6850 || cp_address_required_here (&str
, CP_NO_WB
) == FAIL
)
6853 inst
.error
= BAD_ARGS
;
6861 /* Parse and encode a VFP SP register list, storing the initial
6862 register in position POS and returning the range as the result. If
6863 the string is invalid return FAIL (an invalid range). */
6865 vfp_sp_reg_list (str
, pos
)
6867 enum vfp_sp_reg_pos pos
;
6875 unsigned long mask
= 0;
6882 skip_whitespace (*str
);
6884 tempinst
= inst
.instruction
;
6888 inst
.instruction
= 0;
6890 if ((new_base
= vfp_sp_reg_required_here (str
, pos
)) == FAIL
)
6893 if (count
== 0 || base_reg
> new_base
)
6895 base_reg
= new_base
;
6896 base_bits
= inst
.instruction
;
6899 if (mask
& (1 << new_base
))
6901 inst
.error
= _("invalid register list");
6905 if ((mask
>> new_base
) != 0 && ! warned
)
6907 as_tsktsk (_("register list not in ascending order"));
6911 mask
|= 1 << new_base
;
6914 skip_whitespace (*str
);
6916 if (**str
== '-') /* We have the start of a range expression */
6923 = arm_reg_parse (str
, all_reg_maps
[REG_TYPE_SN
].htab
))
6926 inst
.error
= _(all_reg_maps
[REG_TYPE_SN
].expected
);
6930 if (high_range
<= new_base
)
6932 inst
.error
= _("register range not in ascending order");
6936 for (new_base
++; new_base
<= high_range
; new_base
++)
6938 if (mask
& (1 << new_base
))
6940 inst
.error
= _("invalid register list");
6944 mask
|= 1 << new_base
;
6949 while (skip_past_comma (str
) != FAIL
);
6953 inst
.error
= _("invalid register list");
6961 /* Sanity check -- should have raised a parse error above. */
6962 if (count
== 0 || count
> 32)
6965 /* Final test -- the registers must be consecutive. */
6968 if ((mask
& (1 << base_reg
++)) == 0)
6970 inst
.error
= _("non-contiguous register range");
6975 inst
.instruction
= tempinst
| base_bits
;
6980 vfp_dp_reg_list (str
)
6988 unsigned long mask
= 0;
6995 skip_whitespace (*str
);
6997 tempinst
= inst
.instruction
;
7001 inst
.instruction
= 0;
7003 if ((new_base
= vfp_dp_reg_required_here (str
, VFP_REG_Dd
)) == FAIL
)
7006 if (count
== 0 || base_reg
> new_base
)
7008 base_reg
= new_base
;
7009 range
= inst
.instruction
;
7012 if (mask
& (1 << new_base
))
7014 inst
.error
= _("invalid register list");
7018 if ((mask
>> new_base
) != 0 && ! warned
)
7020 as_tsktsk (_("register list not in ascending order"));
7024 mask
|= 1 << new_base
;
7027 skip_whitespace (*str
);
7029 if (**str
== '-') /* We have the start of a range expression */
7036 = arm_reg_parse (str
, all_reg_maps
[REG_TYPE_DN
].htab
))
7039 inst
.error
= _(all_reg_maps
[REG_TYPE_DN
].expected
);
7043 if (high_range
<= new_base
)
7045 inst
.error
= _("register range not in ascending order");
7049 for (new_base
++; new_base
<= high_range
; new_base
++)
7051 if (mask
& (1 << new_base
))
7053 inst
.error
= _("invalid register list");
7057 mask
|= 1 << new_base
;
7062 while (skip_past_comma (str
) != FAIL
);
7066 inst
.error
= _("invalid register list");
7074 /* Sanity check -- should have raised a parse error above. */
7075 if (count
== 0 || count
> 16)
7078 /* Final test -- the registers must be consecutive. */
7081 if ((mask
& (1 << base_reg
++)) == 0)
7083 inst
.error
= _("non-contiguous register range");
7088 inst
.instruction
= tempinst
;
7093 vfp_sp_ldstm(str
, ldstm_type
)
7095 enum vfp_ldstm_type ldstm_type
;
7099 skip_whitespace (str
);
7101 if (reg_required_here (&str
, 16) == FAIL
)
7104 skip_whitespace (str
);
7108 inst
.instruction
|= WRITE_BACK
;
7111 else if (ldstm_type
!= VFP_LDSTMIA
)
7113 inst
.error
= _("this addressing mode requires base-register writeback");
7117 if (skip_past_comma (&str
) == FAIL
7118 || (range
= vfp_sp_reg_list (&str
, VFP_REG_Sd
)) == FAIL
)
7121 inst
.error
= BAD_ARGS
;
7125 inst
.instruction
|= range
;
7130 vfp_dp_ldstm(str
, ldstm_type
)
7132 enum vfp_ldstm_type ldstm_type
;
7136 skip_whitespace (str
);
7138 if (reg_required_here (&str
, 16) == FAIL
)
7141 skip_whitespace (str
);
7145 inst
.instruction
|= WRITE_BACK
;
7148 else if (ldstm_type
!= VFP_LDSTMIA
&& ldstm_type
!= VFP_LDSTMIAX
)
7150 inst
.error
= _("this addressing mode requires base-register writeback");
7154 if (skip_past_comma (&str
) == FAIL
7155 || (range
= vfp_dp_reg_list (&str
)) == FAIL
)
7158 inst
.error
= BAD_ARGS
;
7162 if (ldstm_type
== VFP_LDSTMIAX
|| ldstm_type
== VFP_LDSTMDBX
)
7165 inst
.instruction
|= range
;
7170 do_vfp_sp_ldstmia (str
)
7173 vfp_sp_ldstm (str
, VFP_LDSTMIA
);
7177 do_vfp_sp_ldstmdb (str
)
7180 vfp_sp_ldstm (str
, VFP_LDSTMDB
);
7184 do_vfp_dp_ldstmia (str
)
7187 vfp_dp_ldstm (str
, VFP_LDSTMIA
);
7191 do_vfp_dp_ldstmdb (str
)
7194 vfp_dp_ldstm (str
, VFP_LDSTMDB
);
7198 do_vfp_xp_ldstmia (str
)
7201 vfp_dp_ldstm (str
, VFP_LDSTMIAX
);
7205 do_vfp_xp_ldstmdb (str
)
7208 vfp_dp_ldstm (str
, VFP_LDSTMDBX
);
7212 do_vfp_sp_compare_z (str
)
7215 skip_whitespace (str
);
7217 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
7220 inst
.error
= BAD_ARGS
;
7229 do_vfp_dp_compare_z (str
)
7232 skip_whitespace (str
);
7234 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
7237 inst
.error
= BAD_ARGS
;
7246 do_vfp_dp_sp_cvt (str
)
7249 skip_whitespace (str
);
7251 if (vfp_dp_reg_required_here (&str
, VFP_REG_Dd
) == FAIL
)
7254 if (skip_past_comma (&str
) == FAIL
7255 || vfp_sp_reg_required_here (&str
, VFP_REG_Sm
) == FAIL
)
7258 inst
.error
= BAD_ARGS
;
7267 do_vfp_sp_dp_cvt (str
)
7270 skip_whitespace (str
);
7272 if (vfp_sp_reg_required_here (&str
, VFP_REG_Sd
) == FAIL
)
7275 if (skip_past_comma (&str
) == FAIL
7276 || vfp_dp_reg_required_here (&str
, VFP_REG_Dm
) == FAIL
)
7279 inst
.error
= BAD_ARGS
;
7287 /* Thumb specific routines. */
7289 /* Parse and validate that a register is of the right form, this saves
7290 repeated checking of this information in many similar cases.
7291 Unlike the 32-bit case we do not insert the register into the opcode
7292 here, since the position is often unknown until the full instruction
7296 thumb_reg (strp
, hi_lo
)
7302 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
7310 inst
.error
= _("lo register required");
7318 inst
.error
= _("hi register required");
7330 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
7334 thumb_add_sub (str
, subtract
)
7338 int Rd
, Rs
, Rn
= FAIL
;
7340 skip_whitespace (str
);
7342 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
7343 || skip_past_comma (&str
) == FAIL
)
7346 inst
.error
= BAD_ARGS
;
7350 if (is_immediate_prefix (*str
))
7354 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7359 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
7362 if (skip_past_comma (&str
) == FAIL
)
7364 /* Two operand format, shuffle the registers
7365 and pretend there are 3. */
7369 else if (is_immediate_prefix (*str
))
7372 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7375 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
7379 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
7380 for the latter case, EXPR contains the immediate that was found. */
7383 /* All register format. */
7384 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
7388 inst
.error
= _("dest and source1 must be the same register");
7392 /* Can't do this for SUB. */
7395 inst
.error
= _("subtract valid only on lo regs");
7399 inst
.instruction
= (T_OPCODE_ADD_HI
7400 | (Rd
> 7 ? THUMB_H1
: 0)
7401 | (Rn
> 7 ? THUMB_H2
: 0));
7402 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
7406 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
7407 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
7412 /* Immediate expression, now things start to get nasty. */
7414 /* First deal with HI regs, only very restricted cases allowed:
7415 Adjusting SP, and using PC or SP to get an address. */
7416 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
7417 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
7419 inst
.error
= _("invalid Hi register with immediate");
7423 if (inst
.reloc
.exp
.X_op
!= O_constant
)
7425 /* Value isn't known yet, all we can do is store all the fragments
7426 we know about in the instruction and let the reloc hacking
7428 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
7429 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
7433 int offset
= inst
.reloc
.exp
.X_add_number
;
7443 /* Quick check, in case offset is MIN_INT. */
7446 inst
.error
= _("immediate value out of range");
7450 /* Note - you cannot convert a subtract of 0 into an
7451 add of 0 because the carry flag is set differently. */
7452 else if (offset
> 0)
7457 if (offset
& ~0x1fc)
7459 inst
.error
= _("invalid immediate value for stack adjust");
7462 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
7463 inst
.instruction
|= offset
>> 2;
7465 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
7468 || (offset
& ~0x3fc))
7470 inst
.error
= _("invalid immediate for address calculation");
7473 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
7475 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
7481 inst
.error
= _("immediate value out of range");
7484 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
7485 inst
.instruction
|= (Rd
<< 8) | offset
;
7491 inst
.error
= _("immediate value out of range");
7494 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
7495 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
7504 thumb_shift (str
, shift
)
7508 int Rd
, Rs
, Rn
= FAIL
;
7510 skip_whitespace (str
);
7512 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7513 || skip_past_comma (&str
) == FAIL
)
7516 inst
.error
= BAD_ARGS
;
7520 if (is_immediate_prefix (*str
))
7522 /* Two operand immediate format, set Rs to Rd. */
7525 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7530 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7533 if (skip_past_comma (&str
) == FAIL
)
7535 /* Two operand format, shuffle the registers
7536 and pretend there are 3. */
7540 else if (is_immediate_prefix (*str
))
7543 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7546 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7550 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
7551 for the latter case, EXPR contains the immediate that was found. */
7557 inst
.error
= _("source1 and dest must be same register");
7563 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
7564 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
7565 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
7568 inst
.instruction
|= Rd
| (Rn
<< 3);
7574 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
7575 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
7576 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
7579 if (inst
.reloc
.exp
.X_op
!= O_constant
)
7581 /* Value isn't known yet, create a dummy reloc and let reloc
7582 hacking fix it up. */
7583 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
7587 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
7589 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
7591 inst
.error
= _("invalid immediate for shift");
7595 /* Shifts of zero are handled by converting to LSL. */
7596 if (shift_value
== 0)
7597 inst
.instruction
= T_OPCODE_LSL_I
;
7599 /* Shifts of 32 are encoded as a shift of zero. */
7600 if (shift_value
== 32)
7603 inst
.instruction
|= shift_value
<< 6;
7606 inst
.instruction
|= Rd
| (Rs
<< 3);
7613 thumb_mov_compare (str
, move
)
7619 skip_whitespace (str
);
7621 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
7622 || skip_past_comma (&str
) == FAIL
)
7625 inst
.error
= BAD_ARGS
;
7629 if (is_immediate_prefix (*str
))
7632 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7635 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
7640 if (Rs
< 8 && Rd
< 8)
7642 if (move
== THUMB_MOVE
)
7643 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
7644 since a MOV instruction produces unpredictable results. */
7645 inst
.instruction
= T_OPCODE_ADD_I3
;
7647 inst
.instruction
= T_OPCODE_CMP_LR
;
7648 inst
.instruction
|= Rd
| (Rs
<< 3);
7652 if (move
== THUMB_MOVE
)
7653 inst
.instruction
= T_OPCODE_MOV_HR
;
7655 inst
.instruction
= T_OPCODE_CMP_HR
;
7658 inst
.instruction
|= THUMB_H1
;
7661 inst
.instruction
|= THUMB_H2
;
7663 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
7670 inst
.error
= _("only lo regs allowed with immediate");
7674 if (move
== THUMB_MOVE
)
7675 inst
.instruction
= T_OPCODE_MOV_I8
;
7677 inst
.instruction
= T_OPCODE_CMP_I8
;
7679 inst
.instruction
|= Rd
<< 8;
7681 if (inst
.reloc
.exp
.X_op
!= O_constant
)
7682 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
7685 unsigned value
= inst
.reloc
.exp
.X_add_number
;
7689 inst
.error
= _("invalid immediate");
7693 inst
.instruction
|= value
;
7701 thumb_load_store (str
, load_store
, size
)
7706 int Rd
, Rb
, Ro
= FAIL
;
7708 skip_whitespace (str
);
7710 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7711 || skip_past_comma (&str
) == FAIL
)
7714 inst
.error
= BAD_ARGS
;
7721 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
7724 if (skip_past_comma (&str
) != FAIL
)
7726 if (is_immediate_prefix (*str
))
7729 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7732 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7737 inst
.reloc
.exp
.X_op
= O_constant
;
7738 inst
.reloc
.exp
.X_add_number
= 0;
7743 inst
.error
= _("expected ']'");
7748 else if (*str
== '=')
7750 if (load_store
!= THUMB_LOAD
)
7752 inst
.error
= _("invalid pseudo operation");
7756 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
7759 skip_whitespace (str
);
7761 if (my_get_expression (& inst
.reloc
.exp
, & str
))
7766 if ( inst
.reloc
.exp
.X_op
!= O_constant
7767 && inst
.reloc
.exp
.X_op
!= O_symbol
)
7769 inst
.error
= "Constant expression expected";
7773 if (inst
.reloc
.exp
.X_op
== O_constant
7774 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
7776 /* This can be done with a mov instruction. */
7778 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
7779 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
7783 /* Insert into literal pool. */
7784 if (add_to_lit_pool () == FAIL
)
7787 inst
.error
= "literal pool insertion failed";
7791 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
7792 inst
.reloc
.pc_rel
= 1;
7793 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
7794 /* Adjust ARM pipeline offset to Thumb. */
7795 inst
.reloc
.exp
.X_add_number
+= 4;
7801 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7804 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
7805 inst
.reloc
.pc_rel
= 1;
7806 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
7807 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
7812 if (Rb
== REG_PC
|| Rb
== REG_SP
)
7814 if (size
!= THUMB_WORD
)
7816 inst
.error
= _("byte or halfword not valid for base register");
7819 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
7821 inst
.error
= _("r15 based store not allowed");
7824 else if (Ro
!= FAIL
)
7826 inst
.error
= _("invalid base register for register offset");
7831 inst
.instruction
= T_OPCODE_LDR_PC
;
7832 else if (load_store
== THUMB_LOAD
)
7833 inst
.instruction
= T_OPCODE_LDR_SP
;
7835 inst
.instruction
= T_OPCODE_STR_SP
;
7837 inst
.instruction
|= Rd
<< 8;
7838 if (inst
.reloc
.exp
.X_op
== O_constant
)
7840 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
7842 if (offset
& ~0x3fc)
7844 inst
.error
= _("invalid offset");
7848 inst
.instruction
|= offset
>> 2;
7851 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
7855 inst
.error
= _("invalid base register in load/store");
7858 else if (Ro
== FAIL
)
7860 /* Immediate offset. */
7861 if (size
== THUMB_WORD
)
7862 inst
.instruction
= (load_store
== THUMB_LOAD
7863 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
7864 else if (size
== THUMB_HALFWORD
)
7865 inst
.instruction
= (load_store
== THUMB_LOAD
7866 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
7868 inst
.instruction
= (load_store
== THUMB_LOAD
7869 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
7871 inst
.instruction
|= Rd
| (Rb
<< 3);
7873 if (inst
.reloc
.exp
.X_op
== O_constant
)
7875 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
7877 if (offset
& ~(0x1f << size
))
7879 inst
.error
= _("invalid offset");
7882 inst
.instruction
|= (offset
>> size
) << 6;
7885 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
7889 /* Register offset. */
7890 if (size
== THUMB_WORD
)
7891 inst
.instruction
= (load_store
== THUMB_LOAD
7892 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
7893 else if (size
== THUMB_HALFWORD
)
7894 inst
.instruction
= (load_store
== THUMB_LOAD
7895 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
7897 inst
.instruction
= (load_store
== THUMB_LOAD
7898 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
7900 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
7906 /* A register must be given at this point.
7908 Shift is the place to put it in inst.instruction.
7910 Restores input start point on err.
7911 Returns the reg#, or FAIL. */
7914 mav_reg_required_here (str
, shift
, regtype
)
7917 enum arm_reg_type regtype
;
7922 if ((reg
= arm_reg_parse (str
, all_reg_maps
[regtype
].htab
)) != FAIL
)
7925 inst
.instruction
|= reg
<< shift
;
7930 /* Restore the start point. */
7933 /* In the few cases where we might be able to accept something else
7934 this error can be overridden. */
7935 inst
.error
= _(all_reg_maps
[regtype
].expected
);
7940 /* Cirrus Maverick Instructions. */
7942 /* Wrapper functions. */
7945 do_mav_binops_1a (str
)
7948 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_RN
, REG_TYPE_MVF
);
7952 do_mav_binops_1b (str
)
7955 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_RN
, REG_TYPE_MVD
);
7959 do_mav_binops_1c (str
)
7962 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_RN
, REG_TYPE_MVDX
);
7966 do_mav_binops_1d (str
)
7969 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVF
);
7973 do_mav_binops_1e (str
)
7976 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVD
);
7980 do_mav_binops_1f (str
)
7983 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVF
);
7987 do_mav_binops_1g (str
)
7990 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVD
);
7994 do_mav_binops_1h (str
)
7997 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVFX
);
8001 do_mav_binops_1i (str
)
8004 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVFX
);
8008 do_mav_binops_1j (str
)
8011 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVDX
);
8015 do_mav_binops_1k (str
)
8018 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVDX
);
8022 do_mav_binops_1l (str
)
8025 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVF
);
8029 do_mav_binops_1m (str
)
8032 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVD
);
8036 do_mav_binops_1n (str
)
8039 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
8043 do_mav_binops_1o (str
)
8046 do_mav_binops (str
, MAV_MODE1
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
8050 do_mav_binops_2a (str
)
8053 do_mav_binops (str
, MAV_MODE2
, REG_TYPE_MVF
, REG_TYPE_RN
);
8057 do_mav_binops_2b (str
)
8060 do_mav_binops (str
, MAV_MODE2
, REG_TYPE_MVD
, REG_TYPE_RN
);
8064 do_mav_binops_2c (str
)
8067 do_mav_binops (str
, MAV_MODE2
, REG_TYPE_MVDX
, REG_TYPE_RN
);
8071 do_mav_binops_3a (str
)
8074 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVAX
, REG_TYPE_MVFX
);
8078 do_mav_binops_3b (str
)
8081 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVFX
, REG_TYPE_MVAX
);
8085 do_mav_binops_3c (str
)
8088 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVAX
, REG_TYPE_MVDX
);
8092 do_mav_binops_3d (str
)
8095 do_mav_binops (str
, MAV_MODE3
, REG_TYPE_MVDX
, REG_TYPE_MVAX
);
8099 do_mav_triple_4a (str
)
8102 do_mav_triple (str
, MAV_MODE4
, REG_TYPE_MVFX
, REG_TYPE_MVFX
, REG_TYPE_RN
);
8106 do_mav_triple_4b (str
)
8109 do_mav_triple (str
, MAV_MODE4
, REG_TYPE_MVDX
, REG_TYPE_MVDX
, REG_TYPE_RN
);
8113 do_mav_triple_5a (str
)
8116 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVF
, REG_TYPE_MVF
);
8120 do_mav_triple_5b (str
)
8123 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVD
, REG_TYPE_MVD
);
8127 do_mav_triple_5c (str
)
8130 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
8134 do_mav_triple_5d (str
)
8137 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_RN
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
8141 do_mav_triple_5e (str
)
8144 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVF
, REG_TYPE_MVF
, REG_TYPE_MVF
);
8148 do_mav_triple_5f (str
)
8151 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVD
, REG_TYPE_MVD
, REG_TYPE_MVD
);
8155 do_mav_triple_5g (str
)
8158 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVFX
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
8162 do_mav_triple_5h (str
)
8165 do_mav_triple (str
, MAV_MODE5
, REG_TYPE_MVDX
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
8169 do_mav_quad_6a (str
)
8172 do_mav_quad (str
, MAV_MODE6
, REG_TYPE_MVAX
, REG_TYPE_MVFX
, REG_TYPE_MVFX
,
8177 do_mav_quad_6b (str
)
8180 do_mav_quad (str
, MAV_MODE6
, REG_TYPE_MVAX
, REG_TYPE_MVAX
, REG_TYPE_MVFX
,
8184 /* cfmvsc32<cond> DSPSC,MVFX[15:0]. */
8186 do_mav_dspsc_1 (str
)
8189 skip_whitespace (str
);
8192 if (mav_reg_required_here (&str
, -1, REG_TYPE_DSPSC
) == FAIL
8193 || skip_past_comma (&str
) == FAIL
8194 || mav_reg_required_here (&str
, 16, REG_TYPE_MVFX
) == FAIL
)
8197 inst
.error
= BAD_ARGS
;
8205 /* cfmv32sc<cond> MVFX[15:0],DSPSC. */
8207 do_mav_dspsc_2 (str
)
8210 skip_whitespace (str
);
8213 if (mav_reg_required_here (&str
, 0, REG_TYPE_MVFX
) == FAIL
8214 || skip_past_comma (&str
) == FAIL
8215 || mav_reg_required_here (&str
, -1, REG_TYPE_DSPSC
) == FAIL
)
8218 inst
.error
= BAD_ARGS
;
8227 do_mav_shift_1 (str
)
8230 do_mav_shift (str
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
8234 do_mav_shift_2 (str
)
8237 do_mav_shift (str
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
8244 do_mav_ldst (str
, REG_TYPE_MVF
);
8251 do_mav_ldst (str
, REG_TYPE_MVD
);
8258 do_mav_ldst (str
, REG_TYPE_MVFX
);
8265 do_mav_ldst (str
, REG_TYPE_MVDX
);
8268 /* Isnsn like "foo X,Y". */
8271 do_mav_binops (str
, mode
, reg0
, reg1
)
8274 enum arm_reg_type reg0
;
8275 enum arm_reg_type reg1
;
8279 shift0
= mode
& 0xff;
8280 shift1
= (mode
>> 8) & 0xff;
8282 skip_whitespace (str
);
8284 if (mav_reg_required_here (&str
, shift0
, reg0
) == FAIL
8285 || skip_past_comma (&str
) == FAIL
8286 || mav_reg_required_here (&str
, shift1
, reg1
) == FAIL
)
8289 inst
.error
= BAD_ARGS
;
8295 /* Isnsn like "foo X,Y,Z". */
8298 do_mav_triple (str
, mode
, reg0
, reg1
, reg2
)
8301 enum arm_reg_type reg0
;
8302 enum arm_reg_type reg1
;
8303 enum arm_reg_type reg2
;
8305 int shift0
, shift1
, shift2
;
8307 shift0
= mode
& 0xff;
8308 shift1
= (mode
>> 8) & 0xff;
8309 shift2
= (mode
>> 16) & 0xff;
8311 skip_whitespace (str
);
8313 if (mav_reg_required_here (&str
, shift0
, reg0
) == FAIL
8314 || skip_past_comma (&str
) == FAIL
8315 || mav_reg_required_here (&str
, shift1
, reg1
) == FAIL
8316 || skip_past_comma (&str
) == FAIL
8317 || mav_reg_required_here (&str
, shift2
, reg2
) == FAIL
)
8320 inst
.error
= BAD_ARGS
;
8326 /* Isnsn like "foo W,X,Y,Z".
8327 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
8330 do_mav_quad (str
, mode
, reg0
, reg1
, reg2
, reg3
)
8333 enum arm_reg_type reg0
;
8334 enum arm_reg_type reg1
;
8335 enum arm_reg_type reg2
;
8336 enum arm_reg_type reg3
;
8338 int shift0
, shift1
, shift2
, shift3
;
8340 shift0
= mode
& 0xff;
8341 shift1
= (mode
>> 8) & 0xff;
8342 shift2
= (mode
>> 16) & 0xff;
8343 shift3
= (mode
>> 24) & 0xff;
8345 skip_whitespace (str
);
8347 if (mav_reg_required_here (&str
, shift0
, reg0
) == FAIL
8348 || skip_past_comma (&str
) == FAIL
8349 || mav_reg_required_here (&str
, shift1
, reg1
) == FAIL
8350 || skip_past_comma (&str
) == FAIL
8351 || mav_reg_required_here (&str
, shift2
, reg2
) == FAIL
8352 || skip_past_comma (&str
) == FAIL
8353 || mav_reg_required_here (&str
, shift3
, reg3
) == FAIL
)
8356 inst
.error
= BAD_ARGS
;
8362 /* Maverick shift immediate instructions.
8363 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
8364 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
8367 do_mav_shift (str
, reg0
, reg1
)
8369 enum arm_reg_type reg0
;
8370 enum arm_reg_type reg1
;
8375 skip_whitespace (str
);
8379 if (mav_reg_required_here (&str
, 12, reg0
) == FAIL
8380 || skip_past_comma (&str
) == FAIL
8381 || mav_reg_required_here (&str
, 16, reg1
) == FAIL
8382 || skip_past_comma (&str
) == FAIL
)
8385 inst
.error
= BAD_ARGS
;
8389 /* Calculate the immediate operand.
8390 The operand is a 7bit signed number. */
8391 skip_whitespace (str
);
8396 if (!ISDIGIT (*str
) && *str
!= '-')
8398 inst
.error
= _("expecting immediate, 7bit operand");
8408 for (imm
= 0; *str
&& ISDIGIT (*str
); ++str
)
8409 imm
= imm
* 10 + *str
- '0';
8413 inst
.error
= _("immediate out of range");
8417 /* Make negative imm's into 7bit signed numbers. */
8424 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
8425 Bits 5-7 of the insn should have bits 4-6 of the immediate.
8426 Bit 4 should be 0. */
8427 imm
= (imm
& 0xf) | ((imm
& 0x70) << 1);
8429 inst
.instruction
|= imm
;
8434 mav_parse_offset (str
, negative
)
8443 skip_whitespace (p
);
8456 inst
.error
= _("offset expected");
8460 for (offset
= 0; *p
&& ISDIGIT (*p
); ++p
)
8461 offset
= offset
* 10 + *p
- '0';
8465 inst
.error
= _("offset out of range");
8471 return *negative
? -offset
: offset
;
8474 /* Maverick load/store instructions.
8475 <insn><cond> CRd,[Rn,<offset>]{!}.
8476 <insn><cond> CRd,[Rn],<offset>. */
8479 do_mav_ldst (str
, reg0
)
8481 enum arm_reg_type reg0
;
8483 int offset
, negative
;
8485 skip_whitespace (str
);
8487 if (mav_reg_required_here (&str
, 12, reg0
) == FAIL
8488 || skip_past_comma (&str
) == FAIL
8490 || reg_required_here (&str
, 16) == FAIL
)
8493 if (skip_past_comma (&str
) == SUCCESS
)
8495 /* You are here: "<offset>]{!}". */
8496 inst
.instruction
|= PRE_INDEX
;
8498 offset
= mav_parse_offset (&str
, &negative
);
8505 inst
.error
= _("missing ]");
8511 inst
.instruction
|= WRITE_BACK
;
8517 /* You are here: "], <offset>". */
8520 inst
.error
= _("missing ]");
8524 if (skip_past_comma (&str
) == FAIL
8525 || (offset
= mav_parse_offset (&str
, &negative
), inst
.error
))
8528 inst
.instruction
|= CP_T_WB
; /* Post indexed, set bit W. */
8534 inst
.instruction
|= CP_T_UD
; /* Postive, so set bit U. */
8536 inst
.instruction
|= offset
>> 2;
8542 inst
.error
= BAD_ARGS
;
8555 /* Handle the Format 4 instructions that do not have equivalents in other
8556 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
8565 skip_whitespace (str
);
8567 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
8568 || skip_past_comma (&str
) == FAIL
8569 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
8571 inst
.error
= BAD_ARGS
;
8575 if (skip_past_comma (&str
) != FAIL
)
8577 /* Three operand format not allowed for TST, CMN, NEG and MVN.
8578 (It isn't allowed for CMP either, but that isn't handled by this
8580 if (inst
.instruction
== T_OPCODE_TST
8581 || inst
.instruction
== T_OPCODE_CMN
8582 || inst
.instruction
== T_OPCODE_NEG
8583 || inst
.instruction
== T_OPCODE_MVN
)
8585 inst
.error
= BAD_ARGS
;
8589 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
8594 inst
.error
= _("dest and source1 must be the same register");
8600 if (inst
.instruction
== T_OPCODE_MUL
8602 as_tsktsk (_("Rs and Rd must be different in MUL"));
8604 inst
.instruction
|= Rd
| (Rs
<< 3);
8612 thumb_add_sub (str
, 0);
8619 thumb_shift (str
, THUMB_ASR
);
8626 if (my_get_expression (&inst
.reloc
.exp
, &str
))
8628 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
8629 inst
.reloc
.pc_rel
= 1;
8637 if (my_get_expression (&inst
.reloc
.exp
, &str
))
8639 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
8640 inst
.reloc
.pc_rel
= 1;
8644 /* Find the real, Thumb encoded start of a Thumb function. */
8647 find_real_start (symbolP
)
8651 const char * name
= S_GET_NAME (symbolP
);
8652 symbolS
* new_target
;
8654 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
8655 #define STUB_NAME ".real_start_of"
8660 /* Names that start with '.' are local labels, not function entry points.
8661 The compiler may generate BL instructions to these labels because it
8662 needs to perform a branch to a far away location. */
8666 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
8667 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
8669 new_target
= symbol_find (real_start
);
8671 if (new_target
== NULL
)
8673 as_warn ("Failed to find real start of function: %s\n", name
);
8674 new_target
= symbolP
;
8686 if (my_get_expression (& inst
.reloc
.exp
, & str
))
8689 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
8690 inst
.reloc
.pc_rel
= 1;
8693 /* If the destination of the branch is a defined symbol which does not have
8694 the THUMB_FUNC attribute, then we must be calling a function which has
8695 the (interfacearm) attribute. We look for the Thumb entry point to that
8696 function and change the branch to refer to that function instead. */
8697 if ( inst
.reloc
.exp
.X_op
== O_symbol
8698 && inst
.reloc
.exp
.X_add_symbol
!= NULL
8699 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
8700 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
8701 inst
.reloc
.exp
.X_add_symbol
=
8702 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
8711 skip_whitespace (str
);
8713 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
8716 /* This sets THUMB_H2 from the top bit of reg. */
8717 inst
.instruction
|= reg
<< 3;
8719 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
8720 should cause the alignment to be checked once it is known. This is
8721 because BX PC only works if the instruction is word aligned. */
8730 thumb_mov_compare (str
, THUMB_COMPARE
);
8740 skip_whitespace (str
);
8742 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
8746 as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
8750 if (skip_past_comma (&str
) == FAIL
8751 || (range
= reg_list (&str
)) == FAIL
)
8754 inst
.error
= BAD_ARGS
;
8758 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
8760 /* This really doesn't seem worth it. */
8761 inst
.reloc
.type
= BFD_RELOC_NONE
;
8762 inst
.error
= _("expression too complex");
8768 inst
.error
= _("only lo-regs valid in load/store multiple");
8772 inst
.instruction
|= (Rb
<< 8) | range
;
8780 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
8787 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
8794 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
8803 skip_whitespace (str
);
8805 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
8806 || skip_past_comma (&str
) == FAIL
8808 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
8809 || skip_past_comma (&str
) == FAIL
8810 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
8814 inst
.error
= _("syntax: ldrs[b] Rd, [Rb, Ro]");
8818 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
8826 thumb_shift (str
, THUMB_LSL
);
8833 thumb_shift (str
, THUMB_LSR
);
8840 thumb_mov_compare (str
, THUMB_MOVE
);
8849 skip_whitespace (str
);
8851 if ((range
= reg_list (&str
)) == FAIL
)
8854 inst
.error
= BAD_ARGS
;
8858 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
8860 /* This really doesn't seem worth it. */
8861 inst
.reloc
.type
= BFD_RELOC_NONE
;
8862 inst
.error
= _("expression too complex");
8868 if ((inst
.instruction
== T_OPCODE_PUSH
8869 && (range
& ~0xff) == 1 << REG_LR
)
8870 || (inst
.instruction
== T_OPCODE_POP
8871 && (range
& ~0xff) == 1 << REG_PC
))
8873 inst
.instruction
|= THUMB_PP_PC_LR
;
8878 inst
.error
= _("invalid register list to push/pop instruction");
8883 inst
.instruction
|= range
;
8891 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
8898 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
8905 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
8912 thumb_add_sub (str
, 1);
8919 skip_whitespace (str
);
8921 if (my_get_expression (&inst
.reloc
.exp
, &str
))
8924 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
8935 /* This is a pseudo-op of the form "adr rd, label" to be converted
8936 into a relative address of the form "add rd, pc, #label-.-4". */
8937 skip_whitespace (str
);
8939 /* Store Rd in temporary location inside instruction. */
8940 if ((reg
= reg_required_here (&str
, 4)) == FAIL
8941 || (reg
> 7) /* For Thumb reg must be r0..r7. */
8942 || skip_past_comma (&str
) == FAIL
8943 || my_get_expression (&inst
.reloc
.exp
, &str
))
8946 inst
.error
= BAD_ARGS
;
8950 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
8951 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
8952 inst
.reloc
.pc_rel
= 1;
8953 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
8959 insert_reg (r
, htab
)
8960 const struct reg_entry
*r
;
8961 struct hash_control
*htab
;
8963 int len
= strlen (r
->name
) + 2;
8964 char * buf
= (char *) xmalloc (len
);
8965 char * buf2
= (char *) xmalloc (len
);
8968 #ifdef REGISTER_PREFIX
8969 buf
[i
++] = REGISTER_PREFIX
;
8972 strcpy (buf
+ i
, r
->name
);
8974 for (i
= 0; buf
[i
]; i
++)
8975 buf2
[i
] = TOUPPER (buf
[i
]);
8979 hash_insert (htab
, buf
, (PTR
) r
);
8980 hash_insert (htab
, buf2
, (PTR
) r
);
8985 struct reg_map
*map
;
8987 const struct reg_entry
*r
;
8989 if ((map
->htab
= hash_new ()) == NULL
)
8990 as_fatal (_("virtual memory exhausted"));
8992 for (r
= map
->names
; r
->name
!= NULL
; r
++)
8993 insert_reg (r
, map
->htab
);
8997 insert_reg_alias (str
, regnum
, htab
)
9000 struct hash_control
*htab
;
9002 struct reg_entry
*new =
9003 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
9004 char *name
= xmalloc (strlen (str
) + 1);
9008 new->number
= regnum
;
9010 hash_insert (htab
, name
, (PTR
) new);
9013 /* Look for the .req directive. This is of the form:
9015 newname .req existing_name
9017 If we find one, or if it looks sufficiently like one that we want to
9018 handle any error here, return non-zero. Otherwise return zero. */
9020 create_register_alias (newname
, p
)
9028 skip_whitespace (q
);
9033 if (*q
&& !strncmp (q
, ".req ", 5))
9038 #ifdef IGNORE_OPCODE_CASE
9039 newname
= original_case_string
;
9041 copy_of_str
= newname
;
9044 skip_whitespace (q
);
9046 for (r
= q
; *r
!= '\0'; r
++)
9052 enum arm_reg_type new_type
, old_type
;
9057 old_type
= arm_reg_parse_any (q
);
9060 new_type
= arm_reg_parse_any (newname
);
9062 if (new_type
== REG_TYPE_MAX
)
9064 if (old_type
!= REG_TYPE_MAX
)
9066 old_regno
= arm_reg_parse (&q
, all_reg_maps
[old_type
].htab
);
9067 insert_reg_alias (newname
, old_regno
,
9068 all_reg_maps
[old_type
].htab
);
9071 as_warn (_("register '%s' does not exist\n"), q
);
9073 else if (old_type
== REG_TYPE_MAX
)
9075 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
9080 /* Do not warn about redefinitions to the same alias. */
9081 if (new_type
!= old_type
9082 || (arm_reg_parse (&q
, all_reg_maps
[old_type
].htab
)
9083 != arm_reg_parse (&q
, all_reg_maps
[new_type
].htab
)))
9084 as_warn (_("ignoring redefinition of register alias '%s'"),
9090 as_warn (_("ignoring incomplete .req pseuso op"));
9100 set_constant_flonums ()
9104 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
9105 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
9109 /* Iterate over the base tables to create the instruction patterns. */
9111 build_arm_ops_hsh ()
9115 static struct obstack insn_obstack
;
9117 obstack_begin (&insn_obstack
, 4000);
9119 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
9121 const struct asm_opcode
*insn
= insns
+ i
;
9123 if (insn
->cond_offset
!= 0)
9125 /* Insn supports conditional execution. Build the varaints
9126 and insert them in the hash table. */
9127 for (j
= 0; j
< sizeof (conds
) / sizeof (struct asm_cond
); j
++)
9129 unsigned len
= strlen (insn
->template);
9130 struct asm_opcode
*new;
9133 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
9134 /* All condition codes are two characters. */
9135 template = obstack_alloc (&insn_obstack
, len
+ 3);
9137 strncpy (template, insn
->template, insn
->cond_offset
);
9138 strcpy (template + insn
->cond_offset
, conds
[j
].template);
9139 if (len
> insn
->cond_offset
)
9140 strcpy (template + insn
->cond_offset
+ 2,
9141 insn
->template + insn
->cond_offset
);
9142 new->template = template;
9143 new->cond_offset
= 0;
9144 new->variant
= insn
->variant
;
9145 new->parms
= insn
->parms
;
9146 new->value
= (insn
->value
& ~COND_MASK
) | conds
[j
].value
;
9148 hash_insert (arm_ops_hsh
, new->template, (PTR
) new);
9151 /* Finally, insert the unconditional insn in the table directly;
9152 no need to build a copy. */
9153 hash_insert (arm_ops_hsh
, insn
->template, (PTR
) insn
);
9163 if ( (arm_ops_hsh
= hash_new ()) == NULL
9164 || (arm_tops_hsh
= hash_new ()) == NULL
9165 || (arm_cond_hsh
= hash_new ()) == NULL
9166 || (arm_shift_hsh
= hash_new ()) == NULL
9167 || (arm_psr_hsh
= hash_new ()) == NULL
)
9168 as_fatal (_("virtual memory exhausted"));
9170 build_arm_ops_hsh ();
9171 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
9172 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
9173 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
9174 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
9175 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
9176 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
9177 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
9178 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
9180 for (i
= (int) REG_TYPE_FIRST
; i
< (int) REG_TYPE_MAX
; i
++)
9181 build_reg_hsh (all_reg_maps
+ i
);
9183 set_constant_flonums ();
9185 /* Set the cpu variant based on the command-line options. We prefer
9186 -mcpu= over -march= if both are set (as for GCC); and we prefer
9187 -mfpu= over any other way of setting the floating point unit.
9188 Use of legacy options with new options are faulted. */
9189 if (legacy_cpu
!= -1)
9191 if (mcpu_cpu_opt
!= -1 || march_cpu_opt
!= -1)
9192 as_bad (_("use of old and new-style options to set CPU type"));
9194 mcpu_cpu_opt
= legacy_cpu
;
9196 else if (mcpu_cpu_opt
== -1)
9197 mcpu_cpu_opt
= march_cpu_opt
;
9199 if (legacy_fpu
!= -1)
9202 as_bad (_("use of old and new-style options to set FPU type"));
9204 mfpu_opt
= legacy_fpu
;
9206 else if (mfpu_opt
== -1)
9208 if (mcpu_fpu_opt
!= -1)
9209 mfpu_opt
= mcpu_fpu_opt
;
9211 mfpu_opt
= march_fpu_opt
;
9216 if (mcpu_cpu_opt
== -1)
9217 mfpu_opt
= FPU_DEFAULT
;
9218 else if (mcpu_cpu_opt
& ARM_EXT_V5
)
9219 mfpu_opt
= FPU_ARCH_VFP_V2
;
9221 mfpu_opt
= FPU_ARCH_FPA
;
9224 if (mcpu_cpu_opt
== -1)
9225 mcpu_cpu_opt
= CPU_DEFAULT
;
9227 cpu_variant
= mcpu_cpu_opt
| mfpu_opt
;
9229 #if defined OBJ_COFF || defined OBJ_ELF
9231 unsigned int flags
= 0;
9233 /* Set the flags in the private structure. */
9234 if (uses_apcs_26
) flags
|= F_APCS26
;
9235 if (support_interwork
) flags
|= F_INTERWORK
;
9236 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
9237 if (pic_code
) flags
|= F_PIC
;
9238 if ((cpu_variant
& FPU_ANY
) == FPU_NONE
9239 || (cpu_variant
& FPU_ANY
) == FPU_ARCH_VFP
) /* VFP layout only. */
9240 flags
|= F_SOFT_FLOAT
;
9241 /* Using VFP conventions (even if soft-float). */
9242 if (cpu_variant
& FPU_VFP_EXT_NONE
) flags
|= F_VFP_FLOAT
;
9245 bfd_set_private_flags (stdoutput
, flags
);
9247 /* We have run out flags in the COFF header to encode the
9248 status of ATPCS support, so instead we create a dummy,
9249 empty, debug section called .arm.atpcs. */
9254 sec
= bfd_make_section (stdoutput
, ".arm.atpcs");
9258 bfd_set_section_flags
9259 (stdoutput
, sec
, SEC_READONLY
| SEC_DEBUGGING
/* | SEC_HAS_CONTENTS */);
9260 bfd_set_section_size (stdoutput
, sec
, 0);
9261 bfd_set_section_contents (stdoutput
, sec
, NULL
, 0, 0);
9267 /* Record the CPU type as well. */
9268 switch (cpu_variant
& ARM_CPU_MASK
)
9271 mach
= bfd_mach_arm_2
;
9274 case ARM_3
: /* Also ARM_250. */
9275 mach
= bfd_mach_arm_2a
;
9278 case ARM_6
: /* Also ARM_7. */
9279 mach
= bfd_mach_arm_3
;
9283 mach
= bfd_mach_arm_4
;
9287 /* Catch special cases. */
9288 if (cpu_variant
& ARM_CEXT_XSCALE
)
9289 mach
= bfd_mach_arm_XScale
;
9290 else if (cpu_variant
& ARM_EXT_V5E
)
9291 mach
= bfd_mach_arm_5TE
;
9292 else if (cpu_variant
& ARM_EXT_V5
)
9294 if (cpu_variant
& ARM_EXT_V4T
)
9295 mach
= bfd_mach_arm_5T
;
9297 mach
= bfd_mach_arm_5
;
9299 else if (cpu_variant
& ARM_EXT_V4
)
9301 if (cpu_variant
& ARM_EXT_V4T
)
9302 mach
= bfd_mach_arm_4T
;
9304 mach
= bfd_mach_arm_4
;
9306 else if (cpu_variant
& ARM_EXT_V3M
)
9307 mach
= bfd_mach_arm_3M
;
9309 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
9312 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
9313 for use in the a.out file, and stores them in the array pointed to by buf.
9314 This knows about the endian-ness of the target machine and does
9315 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
9316 2 (short) and 4 (long) Floating numbers are put out as a series of
9317 LITTLENUMS (shorts, here at least). */
9320 md_number_to_chars (buf
, val
, n
)
9325 if (target_big_endian
)
9326 number_to_chars_bigendian (buf
, val
, n
);
9328 number_to_chars_littleendian (buf
, val
, n
);
9332 md_chars_to_number (buf
, n
)
9337 unsigned char * where
= (unsigned char *) buf
;
9339 if (target_big_endian
)
9344 result
|= (*where
++ & 255);
9352 result
|= (where
[n
] & 255);
9359 /* Turn a string in input_line_pointer into a floating point constant
9360 of type TYPE, and store the appropriate bytes in *LITP. The number
9361 of LITTLENUMS emitted is stored in *SIZEP. An error message is
9362 returned, or NULL on OK.
9364 Note that fp constants aren't represent in the normal way on the ARM.
9365 In big endian mode, things are as expected. However, in little endian
9366 mode fp constants are big-endian word-wise, and little-endian byte-wise
9367 within the words. For example, (double) 1.1 in big endian mode is
9368 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
9369 the byte sequence 99 99 f1 3f 9a 99 99 99.
9371 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
9374 md_atof (type
, litP
, sizeP
)
9380 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
9412 return _("bad call to MD_ATOF()");
9415 t
= atof_ieee (input_line_pointer
, type
, words
);
9417 input_line_pointer
= t
;
9420 if (target_big_endian
)
9422 for (i
= 0; i
< prec
; i
++)
9424 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
9430 if (cpu_variant
& FPU_ARCH_VFP
)
9431 for (i
= prec
- 1; i
>= 0; i
--)
9433 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
9437 /* For a 4 byte float the order of elements in `words' is 1 0.
9438 For an 8 byte float the order is 1 0 3 2. */
9439 for (i
= 0; i
< prec
; i
+= 2)
9441 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
9442 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
9450 /* The knowledge of the PC's pipeline offset is built into the insns
9454 md_pcrel_from (fixP
)
9458 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
9459 && fixP
->fx_subsy
== NULL
)
9462 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
9464 /* PC relative addressing on the Thumb is slightly odd
9465 as the bottom two bits of the PC are forced to zero
9466 for the calculation. */
9467 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
9471 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
9472 so we un-adjust here to compensate for the accomodation. */
9473 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
9475 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
9479 /* Round up a section size to the appropriate boundary. */
9482 md_section_align (segment
, size
)
9483 segT segment ATTRIBUTE_UNUSED
;
9489 /* Round all sects to multiple of 4. */
9490 return (size
+ 3) & ~3;
9494 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
9495 Otherwise we have no need to default values of symbols. */
9498 md_undefined_symbol (name
)
9499 char * name ATTRIBUTE_UNUSED
;
9502 if (name
[0] == '_' && name
[1] == 'G'
9503 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
9507 if (symbol_find (name
))
9508 as_bad ("GOT already in the symbol table");
9510 GOT_symbol
= symbol_new (name
, undefined_section
,
9511 (valueT
) 0, & zero_address_frag
);
9521 /* arm_reg_parse () := if it looks like a register, return its token and
9522 advance the pointer. */
9525 arm_reg_parse (ccp
, htab
)
9526 register char ** ccp
;
9527 struct hash_control
*htab
;
9529 char * start
= * ccp
;
9532 struct reg_entry
* reg
;
9534 #ifdef REGISTER_PREFIX
9535 if (*start
!= REGISTER_PREFIX
)
9540 #ifdef OPTIONAL_REGISTER_PREFIX
9541 if (*p
== OPTIONAL_REGISTER_PREFIX
)
9545 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
9549 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
9553 reg
= (struct reg_entry
*) hash_find (htab
, start
);
9565 /* Search for the following register name in each of the possible reg name
9566 tables. Return the classification if found, or REG_TYPE_MAX if not
9568 static enum arm_reg_type
9569 arm_reg_parse_any (cp
)
9574 for (i
= (int) REG_TYPE_FIRST
; i
< (int) REG_TYPE_MAX
; i
++)
9575 if (arm_reg_parse (&cp
, all_reg_maps
[i
].htab
) != FAIL
)
9576 return (enum arm_reg_type
) i
;
9578 return REG_TYPE_MAX
;
9582 md_apply_fix3 (fixP
, valP
, seg
)
9587 offsetT value
= * valP
;
9589 unsigned int newimm
;
9592 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
9593 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
9595 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
9597 /* Note whether this will delete the relocation. */
9599 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
9600 doesn't work fully.) */
9601 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
9604 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
9608 /* If this symbol is in a different section then we need to leave it for
9609 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
9610 so we have to undo it's effects here. */
9613 if (fixP
->fx_addsy
!= NULL
9614 && S_IS_DEFINED (fixP
->fx_addsy
)
9615 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
9618 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
9619 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
9623 value
+= md_pcrel_from (fixP
);
9627 /* Remember value for emit_reloc. */
9628 fixP
->fx_addnumber
= value
;
9630 switch (fixP
->fx_r_type
)
9632 case BFD_RELOC_ARM_IMMEDIATE
:
9633 newimm
= validate_immediate (value
);
9634 temp
= md_chars_to_number (buf
, INSN_SIZE
);
9636 /* If the instruction will fail, see if we can fix things up by
9637 changing the opcode. */
9638 if (newimm
== (unsigned int) FAIL
9639 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
9641 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9642 _("invalid constant (%lx) after fixup"),
9643 (unsigned long) value
);
9647 newimm
|= (temp
& 0xfffff000);
9648 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
9651 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
9653 unsigned int highpart
= 0;
9654 unsigned int newinsn
= 0xe1a00000; /* nop. */
9655 newimm
= validate_immediate (value
);
9656 temp
= md_chars_to_number (buf
, INSN_SIZE
);
9658 /* If the instruction will fail, see if we can fix things up by
9659 changing the opcode. */
9660 if (newimm
== (unsigned int) FAIL
9661 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
9663 /* No ? OK - try using two ADD instructions to generate
9665 newimm
= validate_immediate_twopart (value
, & highpart
);
9667 /* Yes - then make sure that the second instruction is
9669 if (newimm
!= (unsigned int) FAIL
)
9671 /* Still No ? Try using a negated value. */
9672 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
9673 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
9674 /* Otherwise - give up. */
9677 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9678 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
9683 /* Replace the first operand in the 2nd instruction (which
9684 is the PC) with the destination register. We have
9685 already added in the PC in the first instruction and we
9686 do not want to do it again. */
9687 newinsn
&= ~ 0xf0000;
9688 newinsn
|= ((newinsn
& 0x0f000) << 4);
9691 newimm
|= (temp
& 0xfffff000);
9692 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
9694 highpart
|= (newinsn
& 0xfffff000);
9695 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
9699 case BFD_RELOC_ARM_OFFSET_IMM
:
9705 if (validate_offset_imm (value
, 0) == FAIL
)
9707 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9708 _("bad immediate value for offset (%ld)"),
9713 newval
= md_chars_to_number (buf
, INSN_SIZE
);
9714 newval
&= 0xff7ff000;
9715 newval
|= value
| (sign
? INDEX_UP
: 0);
9716 md_number_to_chars (buf
, newval
, INSN_SIZE
);
9719 case BFD_RELOC_ARM_OFFSET_IMM8
:
9720 case BFD_RELOC_ARM_HWLITERAL
:
9726 if (validate_offset_imm (value
, 1) == FAIL
)
9728 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
9729 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9730 _("invalid literal constant: pool needs to be closer"));
9732 as_bad (_("bad immediate value for half-word offset (%ld)"),
9737 newval
= md_chars_to_number (buf
, INSN_SIZE
);
9738 newval
&= 0xff7ff0f0;
9739 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
9740 md_number_to_chars (buf
, newval
, INSN_SIZE
);
9743 case BFD_RELOC_ARM_LITERAL
:
9749 if (validate_offset_imm (value
, 0) == FAIL
)
9751 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9752 _("invalid literal constant: pool needs to be closer"));
9756 newval
= md_chars_to_number (buf
, INSN_SIZE
);
9757 newval
&= 0xff7ff000;
9758 newval
|= value
| (sign
? INDEX_UP
: 0);
9759 md_number_to_chars (buf
, newval
, INSN_SIZE
);
9762 case BFD_RELOC_ARM_SHIFT_IMM
:
9763 newval
= md_chars_to_number (buf
, INSN_SIZE
);
9764 if (((unsigned long) value
) > 32
9766 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
9768 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9769 _("shift expression is too large"));
9774 /* Shifts of zero must be done as lsl. */
9776 else if (value
== 32)
9778 newval
&= 0xfffff07f;
9779 newval
|= (value
& 0x1f) << 7;
9780 md_number_to_chars (buf
, newval
, INSN_SIZE
);
9783 case BFD_RELOC_ARM_SWI
:
9784 if (arm_data
->thumb_mode
)
9786 if (((unsigned long) value
) > 0xff)
9787 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9788 _("invalid swi expression"));
9789 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
9791 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
9795 if (((unsigned long) value
) > 0x00ffffff)
9796 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9797 _("invalid swi expression"));
9798 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
9800 md_number_to_chars (buf
, newval
, INSN_SIZE
);
9804 case BFD_RELOC_ARM_MULTI
:
9805 if (((unsigned long) value
) > 0xffff)
9806 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9807 _("invalid expression in load/store multiple"));
9808 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
9809 md_number_to_chars (buf
, newval
, INSN_SIZE
);
9812 case BFD_RELOC_ARM_PCREL_BRANCH
:
9813 newval
= md_chars_to_number (buf
, INSN_SIZE
);
9815 /* Sign-extend a 24-bit number. */
9816 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
9820 value
= fixP
->fx_offset
;
9823 /* We are going to store value (shifted right by two) in the
9824 instruction, in a 24 bit, signed field. Thus we need to check
9825 that none of the top 8 bits of the shifted value (top 7 bits of
9826 the unshifted, unsigned value) are set, or that they are all set. */
9827 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
9828 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
9831 /* Normally we would be stuck at this point, since we cannot store
9832 the absolute address that is the destination of the branch in the
9833 24 bits of the branch instruction. If however, we happen to know
9834 that the destination of the branch is in the same section as the
9835 branch instruciton itself, then we can compute the relocation for
9836 ourselves and not have to bother the linker with it.
9838 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
9839 because I have not worked out how to do this for OBJ_COFF or
9842 && fixP
->fx_addsy
!= NULL
9843 && S_IS_DEFINED (fixP
->fx_addsy
)
9844 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
9846 /* Get pc relative value to go into the branch. */
9849 /* Permit a backward branch provided that enough bits
9850 are set. Allow a forwards branch, provided that
9851 enough bits are clear. */
9852 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
9853 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
9857 if (! fixP
->fx_done
)
9859 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9860 _("GAS can't handle same-section branch dest >= 0x04000000"));
9864 value
+= SEXT24 (newval
);
9866 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
9867 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
9868 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9869 _("out of range branch"));
9871 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
9872 md_number_to_chars (buf
, newval
, INSN_SIZE
);
9875 case BFD_RELOC_ARM_PCREL_BLX
:
9878 newval
= md_chars_to_number (buf
, INSN_SIZE
);
9882 value
= fixP
->fx_offset
;
9884 hbit
= (value
>> 1) & 1;
9885 value
= (value
>> 2) & 0x00ffffff;
9886 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
9887 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
9888 md_number_to_chars (buf
, newval
, INSN_SIZE
);
9892 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
9893 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
9895 addressT diff
= (newval
& 0xff) << 1;
9900 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
9901 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9902 _("branch out of range"));
9903 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
9905 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
9908 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
9909 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
9911 addressT diff
= (newval
& 0x7ff) << 1;
9916 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
9917 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9918 _("branch out of range"));
9919 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
9921 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
9924 case BFD_RELOC_THUMB_PCREL_BLX
:
9925 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
9930 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
9931 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
9932 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
9933 if (diff
& 0x400000)
9936 value
= fixP
->fx_offset
;
9939 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
9940 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
9941 _("branch with link out of range"));
9943 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
9944 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
9945 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
)
9946 /* Remove bit zero of the adjusted offset. Bit zero can only be
9947 set if the upper insn is at a half-word boundary, since the
9948 destination address, an ARM instruction, must always be on a
9949 word boundary. The semantics of the BLX (1) instruction, however,
9950 are that bit zero in the offset must always be zero, and the
9951 corresponding bit one in the target address will be set from bit
9952 one of the source address. */
9954 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
9955 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
9960 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
9961 md_number_to_chars (buf
, value
, 1);
9963 else if (!target_oabi
)
9965 value
= fixP
->fx_offset
;
9966 md_number_to_chars (buf
, value
, 1);
9972 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
9973 md_number_to_chars (buf
, value
, 2);
9975 else if (!target_oabi
)
9977 value
= fixP
->fx_offset
;
9978 md_number_to_chars (buf
, value
, 2);
9984 case BFD_RELOC_ARM_GOT32
:
9985 case BFD_RELOC_ARM_GOTOFF
:
9986 md_number_to_chars (buf
, 0, 4);
9992 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
9993 md_number_to_chars (buf
, value
, 4);
9995 else if (!target_oabi
)
9997 value
= fixP
->fx_offset
;
9998 md_number_to_chars (buf
, value
, 4);
10004 case BFD_RELOC_ARM_PLT32
:
10005 /* It appears the instruction is fully prepared at this point. */
10009 case BFD_RELOC_ARM_GOTPC
:
10010 md_number_to_chars (buf
, value
, 4);
10013 case BFD_RELOC_ARM_CP_OFF_IMM
:
10015 if (value
< -1023 || value
> 1023 || (value
& 3))
10016 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10017 _("illegal value for co-processor offset"));
10020 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
10021 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
10022 md_number_to_chars (buf
, newval
, INSN_SIZE
);
10025 case BFD_RELOC_ARM_THUMB_OFFSET
:
10026 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
10027 /* Exactly what ranges, and where the offset is inserted depends
10028 on the type of instruction, we can establish this from the
10030 switch (newval
>> 12)
10032 case 4: /* PC load. */
10033 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
10034 forced to zero for these loads, so we will need to round
10035 up the offset if the instruction address is not word
10036 aligned (since the final address produced must be, and
10037 we can only describe word-aligned immediate offsets). */
10039 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
10040 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10041 _("invalid offset, target not word aligned (0x%08X)"),
10042 (unsigned int) (fixP
->fx_frag
->fr_address
10043 + fixP
->fx_where
+ value
));
10045 if ((value
+ 2) & ~0x3fe)
10046 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10047 _("invalid offset, value too big (0x%08lX)"), value
);
10049 /* Round up, since pc will be rounded down. */
10050 newval
|= (value
+ 2) >> 2;
10053 case 9: /* SP load/store. */
10054 if (value
& ~0x3fc)
10055 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10056 _("invalid offset, value too big (0x%08lX)"), value
);
10057 newval
|= value
>> 2;
10060 case 6: /* Word load/store. */
10062 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10063 _("invalid offset, value too big (0x%08lX)"), value
);
10064 newval
|= value
<< 4; /* 6 - 2. */
10067 case 7: /* Byte load/store. */
10069 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10070 _("invalid offset, value too big (0x%08lX)"), value
);
10071 newval
|= value
<< 6;
10074 case 8: /* Halfword load/store. */
10076 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10077 _("invalid offset, value too big (0x%08lX)"), value
);
10078 newval
|= value
<< 5; /* 6 - 1. */
10082 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10083 "Unable to process relocation for thumb opcode: %lx",
10084 (unsigned long) newval
);
10087 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
10090 case BFD_RELOC_ARM_THUMB_ADD
:
10091 /* This is a complicated relocation, since we use it for all of
10092 the following immediate relocations:
10096 9bit ADD/SUB SP word-aligned
10097 10bit ADD PC/SP word-aligned
10099 The type of instruction being processed is encoded in the
10106 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
10108 int rd
= (newval
>> 4) & 0xf;
10109 int rs
= newval
& 0xf;
10110 int subtract
= newval
& 0x8000;
10114 if (value
& ~0x1fc)
10115 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10116 _("invalid immediate for stack address calculation"));
10117 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
10118 newval
|= value
>> 2;
10120 else if (rs
== REG_PC
|| rs
== REG_SP
)
10124 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10125 _("invalid immediate for address calculation (value = 0x%08lX)"),
10126 (unsigned long) value
);
10127 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
10129 newval
|= value
>> 2;
10134 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10135 _("invalid 8bit immediate"));
10136 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
10137 newval
|= (rd
<< 8) | value
;
10142 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10143 _("invalid 3bit immediate"));
10144 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
10145 newval
|= rd
| (rs
<< 3) | (value
<< 6);
10148 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
10151 case BFD_RELOC_ARM_THUMB_IMM
:
10152 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
10153 switch (newval
>> 11)
10155 case 0x04: /* 8bit immediate MOV. */
10156 case 0x05: /* 8bit immediate CMP. */
10157 if (value
< 0 || value
> 255)
10158 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10159 _("invalid immediate: %ld is too large"),
10167 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
10170 case BFD_RELOC_ARM_THUMB_SHIFT
:
10171 /* 5bit shift value (0..31). */
10172 if (value
< 0 || value
> 31)
10173 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10174 _("illegal Thumb shift value: %ld"), (long) value
);
10175 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
10176 newval
|= value
<< 6;
10177 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
10180 case BFD_RELOC_VTABLE_INHERIT
:
10181 case BFD_RELOC_VTABLE_ENTRY
:
10185 case BFD_RELOC_NONE
:
10187 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
10188 _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
10192 /* Translate internal representation of relocation info to BFD target
10196 tc_gen_reloc (section
, fixp
)
10197 asection
* section ATTRIBUTE_UNUSED
;
10201 bfd_reloc_code_real_type code
;
10203 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
10205 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
10206 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
10207 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
10209 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
10211 if (fixp
->fx_pcrel
== 0)
10212 reloc
->addend
= fixp
->fx_offset
;
10214 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
10215 #else /* OBJ_ELF */
10216 reloc
->addend
= fixp
->fx_offset
;
10219 switch (fixp
->fx_r_type
)
10222 if (fixp
->fx_pcrel
)
10224 code
= BFD_RELOC_8_PCREL
;
10229 if (fixp
->fx_pcrel
)
10231 code
= BFD_RELOC_16_PCREL
;
10236 if (fixp
->fx_pcrel
)
10238 code
= BFD_RELOC_32_PCREL
;
10242 case BFD_RELOC_ARM_PCREL_BRANCH
:
10243 case BFD_RELOC_ARM_PCREL_BLX
:
10244 case BFD_RELOC_RVA
:
10245 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
10246 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
10247 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
10248 case BFD_RELOC_THUMB_PCREL_BLX
:
10249 case BFD_RELOC_VTABLE_ENTRY
:
10250 case BFD_RELOC_VTABLE_INHERIT
:
10251 code
= fixp
->fx_r_type
;
10254 case BFD_RELOC_ARM_LITERAL
:
10255 case BFD_RELOC_ARM_HWLITERAL
:
10256 /* If this is called then the a literal has been referenced across
10257 a section boundary - possibly due to an implicit dump. */
10258 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
10259 _("literal referenced across section boundary (Implicit dump?)"));
10263 case BFD_RELOC_ARM_GOT32
:
10264 case BFD_RELOC_ARM_GOTOFF
:
10265 case BFD_RELOC_ARM_PLT32
:
10266 code
= fixp
->fx_r_type
;
10270 case BFD_RELOC_ARM_IMMEDIATE
:
10271 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
10272 _("internal relocation (type %d) not fixed up (IMMEDIATE)"),
10276 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
10277 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
10278 _("ADRL used for a symbol not defined in the same file"));
10281 case BFD_RELOC_ARM_OFFSET_IMM
:
10282 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
10283 _("internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
10291 switch (fixp
->fx_r_type
)
10293 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
10294 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
10295 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
10296 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
10297 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
10298 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
10299 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
10300 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
10301 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
10302 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
10303 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
10304 default: type
= _("<unknown>"); break;
10306 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
10307 _("cannot represent %s relocation in this object file format"),
10314 if (code
== BFD_RELOC_32_PCREL
10316 && fixp
->fx_addsy
== GOT_symbol
)
10318 code
= BFD_RELOC_ARM_GOTPC
;
10319 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
10323 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
10325 if (reloc
->howto
== NULL
)
10327 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
10328 _("cannot represent %s relocation in this object file format"),
10329 bfd_get_reloc_code_name (code
));
10333 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
10334 vtable entry to be used in the relocation's section offset. */
10335 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
10336 reloc
->address
= fixp
->fx_offset
;
10342 md_estimate_size_before_relax (fragP
, segtype
)
10343 fragS
* fragP ATTRIBUTE_UNUSED
;
10344 segT segtype ATTRIBUTE_UNUSED
;
10346 as_fatal (_("md_estimate_size_before_relax\n"));
10358 as_bad ("%s -- `%s'", inst
.error
, str
);
10362 to
= frag_more (inst
.size
);
10364 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
10366 assert (inst
.size
== (2 * THUMB_SIZE
));
10367 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
10368 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
10370 else if (inst
.size
> INSN_SIZE
)
10372 assert (inst
.size
== (2 * INSN_SIZE
));
10373 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
10374 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
10377 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
10379 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
10380 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
10381 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
10385 dwarf2_emit_insn (inst
.size
);
10397 /* Align the instruction.
10398 This may not be the right thing to do but ... */
10402 listing_prev_line (); /* Defined in listing.h. */
10404 /* Align the previous label if needed. */
10405 if (last_label_seen
!= NULL
)
10407 symbol_set_frag (last_label_seen
, frag_now
);
10408 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
10409 S_SET_SEGMENT (last_label_seen
, now_seg
);
10412 memset (&inst
, '\0', sizeof (inst
));
10413 inst
.reloc
.type
= BFD_RELOC_NONE
;
10415 skip_whitespace (str
);
10417 /* Scan up to the end of the op-code, which must end in white space or
10419 for (start
= p
= str
; *p
!= '\0'; p
++)
10425 as_bad (_("no operator -- statement `%s'\n"), str
);
10431 const struct thumb_opcode
* opcode
;
10435 opcode
= (const struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
10440 /* Check that this instruction is supported for this CPU. */
10441 if (thumb_mode
== 1 && (opcode
->variant
& cpu_variant
) == 0)
10443 as_bad (_("selected processor does not support `%s'"), str
);
10447 inst
.instruction
= opcode
->value
;
10448 inst
.size
= opcode
->size
;
10449 (*opcode
->parms
) (p
);
10456 const struct asm_opcode
* opcode
;
10460 opcode
= (const struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
10465 /* Check that this instruction is supported for this CPU. */
10466 if ((opcode
->variant
& cpu_variant
) == 0)
10468 as_bad (_("selected processor does not support `%s'"), str
);
10472 inst
.instruction
= opcode
->value
;
10473 inst
.size
= INSN_SIZE
;
10474 (*opcode
->parms
) (p
);
10480 /* It wasn't an instruction, but it might be a register alias of the form
10482 if (create_register_alias (str
, p
))
10485 as_bad (_("bad instruction `%s'"), start
);
10489 Invocation line includes a switch not recognized by the base assembler.
10490 See if it's a processor-specific option.
10492 This routine is somewhat complicated by the need for backwards
10493 compatibility (since older releases of gcc can't be changed).
10494 The new options try to make the interface as compatible as
10497 New options (supported) are:
10499 -mcpu=<cpu name> Assemble for selected processor
10500 -march=<architecture name> Assemble for selected architecture
10501 -mfpu=<fpu architecture> Assemble for selected FPU.
10502 -EB/-mbig-endian Big-endian
10503 -EL/-mlittle-endian Little-endian
10504 -k Generate PIC code
10505 -mthumb Start in Thumb mode
10506 -mthumb-interwork Code supports ARM/Thumb interworking
10508 For now we will also provide support for
10510 -mapcs-32 32-bit Program counter
10511 -mapcs-26 26-bit Program counter
10512 -macps-float Floats passed in FP registers
10513 -mapcs-reentrant Reentrant code
10515 (sometime these will probably be replaced with -mapcs=<list of options>
10516 and -matpcs=<list of options>)
10518 The remaining options are only supported for back-wards compatibility.
10519 Cpu variants, the arm part is optional:
10520 -m[arm]1 Currently not supported.
10521 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
10522 -m[arm]3 Arm 3 processor
10523 -m[arm]6[xx], Arm 6 processors
10524 -m[arm]7[xx][t][[d]m] Arm 7 processors
10525 -m[arm]8[10] Arm 8 processors
10526 -m[arm]9[20][tdmi] Arm 9 processors
10527 -mstrongarm[110[0]] StrongARM processors
10528 -mxscale XScale processors
10529 -m[arm]v[2345[t[e]]] Arm architectures
10530 -mall All (except the ARM1)
10532 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
10533 -mfpe-old (No float load/store multiples)
10534 -mvfpxd VFP Single precision
10536 -mno-fpu Disable all floating point instructions
10538 The following CPU names are recognized:
10539 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
10540 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
10541 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
10542 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
10543 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
10544 arm10t arm10e, arm1020t, arm1020e, arm10200e,
10545 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
10549 CONST
char * md_shortopts
= "m:k";
10551 #ifdef ARM_BI_ENDIAN
10552 #define OPTION_EB (OPTION_MD_BASE + 0)
10553 #define OPTION_EL (OPTION_MD_BASE + 1)
10555 #if TARGET_BYTES_BIG_ENDIAN
10556 #define OPTION_EB (OPTION_MD_BASE + 0)
10558 #define OPTION_EL (OPTION_MD_BASE + 1)
10562 struct option md_longopts
[] =
10565 {"EB", no_argument
, NULL
, OPTION_EB
},
10568 {"EL", no_argument
, NULL
, OPTION_EL
},
10570 {NULL
, no_argument
, NULL
, 0}
10573 size_t md_longopts_size
= sizeof (md_longopts
);
10575 struct arm_option_table
10577 char *option
; /* Option name to match. */
10578 char *help
; /* Help information. */
10579 int *var
; /* Variable to change. */
10580 int value
; /* What to change it to. */
10581 char *deprecated
; /* If non-null, print this message. */
10584 struct arm_option_table arm_opts
[] =
10586 {"k", N_("generate PIC code"), &pic_code
, 1, NULL
},
10587 {"mthumb", N_("assemble Thumb code"), &thumb_mode
, 1, NULL
},
10588 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
10589 &support_interwork
, 1, NULL
},
10590 {"moabi", N_("use old ABI (ELF only)"), &target_oabi
, 1, NULL
},
10591 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26
, 0, NULL
},
10592 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26
, 1, NULL
},
10593 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float
,
10595 {"mapcs-reentrant", N_("re-entrant code"), &pic_code
, 1, NULL
},
10596 {"matpcs", N_("code is ATPCS conformant"), &atpcs
, 1, NULL
},
10597 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian
, 1, NULL
},
10598 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian
, 1,
10601 /* These are recognized by the assembler, but have no affect on code. */
10602 {"mapcs-frame", N_("use frame pointer"), NULL
, 0, NULL
},
10603 {"mapcs-stack-check", N_("use stack size checking"), NULL
, 0, NULL
},
10605 /* DON'T add any new processors to this list -- we want the whole list
10606 to go away... Add them to the processors table instead. */
10607 {"marm1", NULL
, &legacy_cpu
, ARM_ARCH_V1
, N_("use -mcpu=arm1")},
10608 {"m1", NULL
, &legacy_cpu
, ARM_ARCH_V1
, N_("use -mcpu=arm1")},
10609 {"marm2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -mcpu=arm2")},
10610 {"m2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -mcpu=arm2")},
10611 {"marm250", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm250")},
10612 {"m250", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm250")},
10613 {"marm3", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm3")},
10614 {"m3", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -mcpu=arm3")},
10615 {"marm6", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm6")},
10616 {"m6", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm6")},
10617 {"marm600", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm600")},
10618 {"m600", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm600")},
10619 {"marm610", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm610")},
10620 {"m610", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm610")},
10621 {"marm620", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm620")},
10622 {"m620", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm620")},
10623 {"marm7", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7")},
10624 {"m7", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7")},
10625 {"marm70", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm70")},
10626 {"m70", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm70")},
10627 {"marm700", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700")},
10628 {"m700", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700")},
10629 {"marm700i", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700i")},
10630 {"m700i", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm700i")},
10631 {"marm710", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710")},
10632 {"m710", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710")},
10633 {"marm710c", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710c")},
10634 {"m710c", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm710c")},
10635 {"marm720", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm720")},
10636 {"m720", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm720")},
10637 {"marm7d", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7d")},
10638 {"m7d", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7d")},
10639 {"marm7di", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7di")},
10640 {"m7di", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7di")},
10641 {"marm7m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7m")},
10642 {"m7m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7m")},
10643 {"marm7dm", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dm")},
10644 {"m7dm", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dm")},
10645 {"marm7dmi", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dmi")},
10646 {"m7dmi", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -mcpu=arm7dmi")},
10647 {"marm7100", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7100")},
10648 {"m7100", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7100")},
10649 {"marm7500", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500")},
10650 {"m7500", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500")},
10651 {"marm7500fe", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500fe")},
10652 {"m7500fe", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -mcpu=arm7500fe")},
10653 {"marm7t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
10654 {"m7t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
10655 {"marm7tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
10656 {"m7tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm7tdmi")},
10657 {"marm710t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm710t")},
10658 {"m710t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm710t")},
10659 {"marm720t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm720t")},
10660 {"m720t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm720t")},
10661 {"marm740t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm740t")},
10662 {"m740t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm740t")},
10663 {"marm8", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm8")},
10664 {"m8", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm8")},
10665 {"marm810", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm810")},
10666 {"m810", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=arm810")},
10667 {"marm9", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9")},
10668 {"m9", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9")},
10669 {"marm9tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9tdmi")},
10670 {"m9tdmi", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm9tdmi")},
10671 {"marm920", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm920")},
10672 {"m920", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm920")},
10673 {"marm940", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm940")},
10674 {"m940", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -mcpu=arm940")},
10675 {"mstrongarm", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -mcpu=strongarm")},
10676 {"mstrongarm110", NULL
, &legacy_cpu
, ARM_ARCH_V4
,
10677 N_("use -mcpu=strongarm110")},
10678 {"mstrongarm1100", NULL
, &legacy_cpu
, ARM_ARCH_V4
,
10679 N_("use -mcpu=strongarm1100")},
10680 {"mstrongarm1110", NULL
, &legacy_cpu
, ARM_ARCH_V4
,
10681 N_("use -mcpu=strongarm1110")},
10682 {"mxscale", NULL
, &legacy_cpu
, ARM_ARCH_XSCALE
, N_("use -mcpu=xscale")},
10683 {"mall", NULL
, &legacy_cpu
, ARM_ANY
, N_("use -mcpu=all")},
10685 /* Architecture variants -- don't add any more to this list either. */
10686 {"mv2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -march=armv2")},
10687 {"marmv2", NULL
, &legacy_cpu
, ARM_ARCH_V2
, N_("use -march=armv2")},
10688 {"mv2a", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -march=armv2a")},
10689 {"marmv2a", NULL
, &legacy_cpu
, ARM_ARCH_V2S
, N_("use -march=armv2a")},
10690 {"mv3", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -march=armv3")},
10691 {"marmv3", NULL
, &legacy_cpu
, ARM_ARCH_V3
, N_("use -march=armv3")},
10692 {"mv3m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -march=armv3m")},
10693 {"marmv3m", NULL
, &legacy_cpu
, ARM_ARCH_V3M
, N_("use -march=armv3m")},
10694 {"mv4", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -march=armv4")},
10695 {"marmv4", NULL
, &legacy_cpu
, ARM_ARCH_V4
, N_("use -march=armv4")},
10696 {"mv4t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -march=armv4t")},
10697 {"marmv4t", NULL
, &legacy_cpu
, ARM_ARCH_V4T
, N_("use -march=armv4t")},
10698 {"mv5", NULL
, &legacy_cpu
, ARM_ARCH_V5
, N_("use -march=armv5")},
10699 {"marmv5", NULL
, &legacy_cpu
, ARM_ARCH_V5
, N_("use -march=armv5")},
10700 {"mv5t", NULL
, &legacy_cpu
, ARM_ARCH_V5T
, N_("use -march=armv5t")},
10701 {"marmv5t", NULL
, &legacy_cpu
, ARM_ARCH_V5T
, N_("use -march=armv5t")},
10702 {"mv5e", NULL
, &legacy_cpu
, ARM_ARCH_V5TE
, N_("use -march=armv5te")},
10703 {"marmv5e", NULL
, &legacy_cpu
, ARM_ARCH_V5TE
, N_("use -march=armv5te")},
10705 /* Floating point variants -- don't add any more to this list either. */
10706 {"mfpe-old", NULL
, &legacy_fpu
, FPU_ARCH_FPE
, N_("use -mfpu=fpe")},
10707 {"mfpa10", NULL
, &legacy_fpu
, FPU_ARCH_FPA
, N_("use -mfpu=fpa10")},
10708 {"mfpa11", NULL
, &legacy_fpu
, FPU_ARCH_FPA
, N_("use -mfpu=fpa11")},
10709 {"mno-fpu", NULL
, &legacy_fpu
, 0,
10710 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
10712 {NULL
, NULL
, NULL
, 0, NULL
}
10715 struct arm_cpu_option_table
10719 /* For some CPUs we assume an FPU unless the user explicitly sets
10724 /* This list should, at a minimum, contain all the cpu names
10725 recognized by GCC. */
10726 static struct arm_cpu_option_table arm_cpus
[] =
10728 {"all", ARM_ANY
, FPU_ARCH_FPA
},
10729 {"arm1", ARM_ARCH_V1
, FPU_ARCH_FPA
},
10730 {"arm2", ARM_ARCH_V2
, FPU_ARCH_FPA
},
10731 {"arm250", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
10732 {"arm3", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
10733 {"arm6", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10734 {"arm60", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10735 {"arm600", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10736 {"arm610", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10737 {"arm620", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10738 {"arm7", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10739 {"arm7m", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
10740 {"arm7d", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10741 {"arm7dm", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
10742 {"arm7di", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10743 {"arm7dmi", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
10744 {"arm70", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10745 {"arm700", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10746 {"arm700i", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10747 {"arm710", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10748 {"arm710t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10749 {"arm720", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10750 {"arm720t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10751 {"arm740t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10752 {"arm710c", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10753 {"arm7100", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10754 {"arm7500", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10755 {"arm7500fe", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10756 {"arm7t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10757 {"arm7tdmi", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10758 {"arm8", ARM_ARCH_V4
, FPU_ARCH_FPA
},
10759 {"arm810", ARM_ARCH_V4
, FPU_ARCH_FPA
},
10760 {"strongarm", ARM_ARCH_V4
, FPU_ARCH_FPA
},
10761 {"strongarm1", ARM_ARCH_V4
, FPU_ARCH_FPA
},
10762 {"strongarm110", ARM_ARCH_V4
, FPU_ARCH_FPA
},
10763 {"strongarm1100", ARM_ARCH_V4
, FPU_ARCH_FPA
},
10764 {"strongarm1110", ARM_ARCH_V4
, FPU_ARCH_FPA
},
10765 {"arm9", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10766 {"arm920", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10767 {"arm920t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10768 {"arm922t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10769 {"arm940t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10770 {"arm9tdmi", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10771 /* For V5 or later processors we default to using VFP; but the user
10772 should really set the FPU type explicitly. */
10773 {"arm9e-r0", ARM_ARCH_V5TExP
, FPU_ARCH_VFP_V2
},
10774 {"arm9e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
10775 {"arm926ej", ARM_ARCH_V5TEJ
, FPU_ARCH_VFP_V2
},
10776 {"arm946e-r0", ARM_ARCH_V5TExP
, FPU_ARCH_VFP_V2
},
10777 {"arm946e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
10778 {"arm966e-r0", ARM_ARCH_V5TExP
, FPU_ARCH_VFP_V2
},
10779 {"arm966e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
10780 {"arm10t", ARM_ARCH_V5T
, FPU_ARCH_VFP_V1
},
10781 {"arm10e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
10782 {"arm1020", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
10783 {"arm1020t", ARM_ARCH_V5T
, FPU_ARCH_VFP_V1
},
10784 {"arm1020e", ARM_ARCH_V5TE
, FPU_ARCH_VFP_V2
},
10785 /* ??? XSCALE is really an architecture. */
10786 {"xscale", ARM_ARCH_XSCALE
, FPU_ARCH_VFP_V2
},
10787 {"i80200", ARM_ARCH_XSCALE
, FPU_ARCH_VFP_V2
},
10789 {"ep9312", ARM_ARCH_V4T
| ARM_CEXT_MAVERICK
, FPU_NONE
},
10793 struct arm_arch_option_table
10800 /* This list should, at a minimum, contain all the architecture names
10801 recognized by GCC. */
10802 static struct arm_arch_option_table arm_archs
[] =
10804 {"all", ARM_ANY
, FPU_ARCH_FPA
},
10805 {"armv1", ARM_ARCH_V1
, FPU_ARCH_FPA
},
10806 {"armv2", ARM_ARCH_V2
, FPU_ARCH_FPA
},
10807 {"armv2a", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
10808 {"armv2s", ARM_ARCH_V2S
, FPU_ARCH_FPA
},
10809 {"armv3", ARM_ARCH_V3
, FPU_ARCH_FPA
},
10810 {"armv3m", ARM_ARCH_V3M
, FPU_ARCH_FPA
},
10811 {"armv4", ARM_ARCH_V4
, FPU_ARCH_FPA
},
10812 {"armv4xm", ARM_ARCH_V4xM
, FPU_ARCH_FPA
},
10813 {"armv4t", ARM_ARCH_V4T
, FPU_ARCH_FPA
},
10814 {"armv4txm", ARM_ARCH_V4TxM
, FPU_ARCH_FPA
},
10815 {"armv5", ARM_ARCH_V5
, FPU_ARCH_VFP
},
10816 {"armv5t", ARM_ARCH_V5T
, FPU_ARCH_VFP
},
10817 {"armv5txm", ARM_ARCH_V5TxM
, FPU_ARCH_VFP
},
10818 {"armv5te", ARM_ARCH_V5TE
, FPU_ARCH_VFP
},
10819 {"armv5texp", ARM_ARCH_V5TExP
, FPU_ARCH_VFP
},
10820 {"armv5tej", ARM_ARCH_V5TEJ
, FPU_ARCH_VFP
},
10821 {"xscale", ARM_ARCH_XSCALE
, FPU_ARCH_VFP
},
10825 /* ISA extensions in the co-processor space. */
10826 struct arm_arch_extension_table
10832 static struct arm_arch_extension_table arm_extensions
[] =
10834 {"maverick", ARM_CEXT_MAVERICK
},
10835 {"xscale", ARM_CEXT_XSCALE
},
10839 struct arm_fpu_option_table
10845 /* This list should, at a minimum, contain all the fpu names
10846 recognized by GCC. */
10847 static struct arm_fpu_option_table arm_fpus
[] =
10849 {"softfpa", FPU_NONE
},
10850 {"fpe", FPU_ARCH_FPE
},
10851 {"fpe2", FPU_ARCH_FPE
},
10852 {"fpe3", FPU_ARCH_FPA
}, /* Third release supports LFM/SFM. */
10853 {"fpa", FPU_ARCH_FPA
},
10854 {"fpa10", FPU_ARCH_FPA
},
10855 {"fpa11", FPU_ARCH_FPA
},
10856 {"arm7500fe", FPU_ARCH_FPA
},
10857 {"softvfp", FPU_ARCH_VFP
},
10858 {"softvfp+vfp", FPU_ARCH_VFP_V2
},
10859 {"vfp", FPU_ARCH_VFP_V2
},
10860 {"vfp9", FPU_ARCH_VFP_V2
},
10861 {"vfp10", FPU_ARCH_VFP_V2
},
10862 {"vfp10-r0", FPU_ARCH_VFP_V1
},
10863 {"vfpxd", FPU_ARCH_VFP_V1xD
},
10864 {"arm1020t", FPU_ARCH_VFP_V1
},
10865 {"arm1020e", FPU_ARCH_VFP_V2
},
10869 struct arm_long_option_table
10871 char *option
; /* Substring to match. */
10872 char *help
; /* Help information. */
10873 int (*func
) PARAMS ((char *subopt
)); /* Function to decode sub-option. */
10874 char *deprecated
; /* If non-null, print this message. */
10878 arm_parse_extension (str
, opt_p
)
10882 while (str
!= NULL
&& *str
!= 0)
10884 struct arm_arch_extension_table
*opt
;
10890 as_bad (_("invalid architectural extension"));
10895 ext
= strchr (str
, '+');
10898 optlen
= ext
- str
;
10900 optlen
= strlen (str
);
10904 as_bad (_("missing architectural extension"));
10908 for (opt
= arm_extensions
; opt
->name
!= NULL
; opt
++)
10909 if (strncmp (opt
->name
, str
, optlen
) == 0)
10911 *opt_p
|= opt
->value
;
10915 if (opt
->name
== NULL
)
10917 as_bad (_("unknown architectural extnsion `%s'"), str
);
10928 arm_parse_cpu (str
)
10931 struct arm_cpu_option_table
*opt
;
10932 char *ext
= strchr (str
, '+');
10936 optlen
= ext
- str
;
10938 optlen
= strlen (str
);
10942 as_bad (_("missing cpu name `%s'"), str
);
10946 for (opt
= arm_cpus
; opt
->name
!= NULL
; opt
++)
10947 if (strncmp (opt
->name
, str
, optlen
) == 0)
10949 mcpu_cpu_opt
= opt
->value
;
10950 mcpu_fpu_opt
= opt
->default_fpu
;
10953 return arm_parse_extension (ext
, &mcpu_cpu_opt
);
10958 as_bad (_("unknown cpu `%s'"), str
);
10963 arm_parse_arch (str
)
10966 struct arm_arch_option_table
*opt
;
10967 char *ext
= strchr (str
, '+');
10971 optlen
= ext
- str
;
10973 optlen
= strlen (str
);
10977 as_bad (_("missing architecture name `%s'"), str
);
10982 for (opt
= arm_archs
; opt
->name
!= NULL
; opt
++)
10983 if (strcmp (opt
->name
, str
) == 0)
10985 march_cpu_opt
= opt
->value
;
10986 march_fpu_opt
= opt
->default_fpu
;
10989 return arm_parse_extension (ext
, &march_cpu_opt
);
10994 as_bad (_("unknown architecture `%s'\n"), str
);
10999 arm_parse_fpu (str
)
11002 struct arm_fpu_option_table
*opt
;
11004 for (opt
= arm_fpus
; opt
->name
!= NULL
; opt
++)
11005 if (strcmp (opt
->name
, str
) == 0)
11007 mfpu_opt
= opt
->value
;
11011 as_bad (_("unknown floating point format `%s'\n"), str
);
11015 struct arm_long_option_table arm_long_opts
[] =
11017 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
11018 arm_parse_cpu
, NULL
},
11019 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
11020 arm_parse_arch
, NULL
},
11021 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
11022 arm_parse_fpu
, NULL
},
11023 {NULL
, NULL
, 0, NULL
}
11027 md_parse_option (c
, arg
)
11031 struct arm_option_table
*opt
;
11032 struct arm_long_option_table
*lopt
;
11038 target_big_endian
= 1;
11044 target_big_endian
= 0;
11049 /* Listing option. Just ignore these, we don't support additional
11054 for (opt
= arm_opts
; opt
->option
!= NULL
; opt
++)
11056 if (c
== opt
->option
[0]
11057 && ((arg
== NULL
&& opt
->option
[1] == 0)
11058 || strcmp (arg
, opt
->option
+ 1) == 0))
11060 #if WARN_DEPRECATED
11061 /* If the option is deprecated, tell the user. */
11062 if (opt
->deprecated
!= NULL
)
11063 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c
,
11064 arg
? arg
: "", _(opt
->deprecated
));
11067 if (opt
->var
!= NULL
)
11068 *opt
->var
= opt
->value
;
11074 for (lopt
= arm_long_opts
; lopt
->option
!= NULL
; lopt
++)
11076 /* These options are expected to have an argument. */
11077 if (c
== lopt
->option
[0]
11079 && strncmp (arg
, lopt
->option
+ 1,
11080 strlen (lopt
->option
+ 1)) == 0)
11082 #if WARN_DEPRECATED
11083 /* If the option is deprecated, tell the user. */
11084 if (lopt
->deprecated
!= NULL
)
11085 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c
, arg
,
11086 _(lopt
->deprecated
));
11089 /* Call the sup-option parser. */
11090 return (*lopt
->func
)(arg
+ strlen (lopt
->option
) - 1);
11094 as_bad (_("unrecognized option `-%c%s'"), c
, arg
? arg
: "");
11105 struct arm_option_table
*opt
;
11106 struct arm_long_option_table
*lopt
;
11108 fprintf (fp
, _(" ARM-specific assembler options:\n"));
11110 for (opt
= arm_opts
; opt
->option
!= NULL
; opt
++)
11111 if (opt
->help
!= NULL
)
11112 fprintf (fp
, " -%-23s%s\n", opt
->option
, _(opt
->help
));
11114 for (lopt
= arm_long_opts
; lopt
->option
!= NULL
; lopt
++)
11115 if (lopt
->help
!= NULL
)
11116 fprintf (fp
, " -%s%s\n", lopt
->option
, _(lopt
->help
));
11120 -EB assemble code for a big-endian cpu\n"));
11125 -EL assemble code for a little-endian cpu\n"));
11129 /* We need to be able to fix up arbitrary expressions in some statements.
11130 This is so that we can handle symbols that are an arbitrary distance from
11131 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
11132 which returns part of an address in a form which will be valid for
11133 a data instruction. We do this by pushing the expression into a symbol
11134 in the expr_section, and creating a fix for that. */
11137 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
11146 arm_fix_data
* arm_data
;
11154 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
11158 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
11163 /* Mark whether the fix is to a THUMB instruction, or an ARM
11165 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
11166 new_fix
->tc_fix_data
= (PTR
) arm_data
;
11167 arm_data
->thumb_mode
= thumb_mode
;
11172 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
11175 cons_fix_new_arm (frag
, where
, size
, exp
)
11181 bfd_reloc_code_real_type type
;
11185 FIXME: @@ Should look at CPU word size. */
11189 type
= BFD_RELOC_8
;
11192 type
= BFD_RELOC_16
;
11196 type
= BFD_RELOC_32
;
11199 type
= BFD_RELOC_64
;
11203 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
11206 /* A good place to do this, although this was probably not intended
11207 for this kind of use. We need to dump the literal pool before
11208 references are made to a null symbol pointer. */
11213 if (current_poolP
== NULL
)
11216 /* Put it at the end of text section. */
11217 subseg_set (text_section
, 0);
11219 listing_prev_line ();
11223 arm_start_line_hook ()
11225 last_label_seen
= NULL
;
11229 arm_frob_label (sym
)
11232 last_label_seen
= sym
;
11234 ARM_SET_THUMB (sym
, thumb_mode
);
11236 #if defined OBJ_COFF || defined OBJ_ELF
11237 ARM_SET_INTERWORK (sym
, support_interwork
);
11240 /* Note - do not allow local symbols (.Lxxx) to be labeled
11241 as Thumb functions. This is because these labels, whilst
11242 they exist inside Thumb code, are not the entry points for
11243 possible ARM->Thumb calls. Also, these labels can be used
11244 as part of a computed goto or switch statement. eg gcc
11245 can generate code that looks like this:
11247 ldr r2, [pc, .Laaa]
11257 The first instruction loads the address of the jump table.
11258 The second instruction converts a table index into a byte offset.
11259 The third instruction gets the jump address out of the table.
11260 The fourth instruction performs the jump.
11262 If the address stored at .Laaa is that of a symbol which has the
11263 Thumb_Func bit set, then the linker will arrange for this address
11264 to have the bottom bit set, which in turn would mean that the
11265 address computation performed by the third instruction would end
11266 up with the bottom bit set. Since the ARM is capable of unaligned
11267 word loads, the instruction would then load the incorrect address
11268 out of the jump table, and chaos would ensue. */
11269 if (label_is_thumb_function_name
11270 && (S_GET_NAME (sym
)[0] != '.' || S_GET_NAME (sym
)[1] != 'L')
11271 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
11273 /* When the address of a Thumb function is taken the bottom
11274 bit of that address should be set. This will allow
11275 interworking between Arm and Thumb functions to work
11278 THUMB_SET_FUNC (sym
, 1);
11280 label_is_thumb_function_name
= false;
11284 /* Adjust the symbol table. This marks Thumb symbols as distinct from
11288 arm_adjust_symtab ()
11293 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
11295 if (ARM_IS_THUMB (sym
))
11297 if (THUMB_IS_FUNC (sym
))
11299 /* Mark the symbol as a Thumb function. */
11300 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
11301 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
11302 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
11304 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
11305 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
11307 as_bad (_("%s: unexpected function type: %d"),
11308 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
11310 else switch (S_GET_STORAGE_CLASS (sym
))
11313 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
11316 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
11319 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
11327 if (ARM_IS_INTERWORK (sym
))
11328 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
11335 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
11337 if (ARM_IS_THUMB (sym
))
11339 elf_symbol_type
* elf_sym
;
11341 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
11342 bind
= ELF_ST_BIND (elf_sym
);
11344 /* If it's a .thumb_func, declare it as so,
11345 otherwise tag label as .code 16. */
11346 if (THUMB_IS_FUNC (sym
))
11347 elf_sym
->internal_elf_sym
.st_info
=
11348 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
11350 elf_sym
->internal_elf_sym
.st_info
=
11351 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
11358 arm_data_in_code ()
11360 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
11362 *input_line_pointer
= '/';
11363 input_line_pointer
+= 5;
11364 *input_line_pointer
= 0;
11372 arm_canonicalize_symbol_name (name
)
11377 if (thumb_mode
&& (len
= strlen (name
)) > 5
11378 && streq (name
+ len
- 5, "/data"))
11379 *(name
+ len
- 5) = 0;
11385 arm_validate_fix (fixP
)
11388 /* If the destination of the branch is a defined symbol which does not have
11389 the THUMB_FUNC attribute, then we must be calling a function which has
11390 the (interfacearm) attribute. We look for the Thumb entry point to that
11391 function and change the branch to refer to that function instead. */
11392 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
11393 && fixP
->fx_addsy
!= NULL
11394 && S_IS_DEFINED (fixP
->fx_addsy
)
11395 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
11397 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
11405 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
11406 local labels from being added to the output symbol table when they
11407 are used with the ADRL pseudo op. The ADRL relocation should always
11408 be resolved before the binbary is emitted, so it is safe to say that
11409 it is adjustable. */
11412 arm_fix_adjustable (fixP
)
11415 if (fixP
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
11421 /* Relocations against Thumb function names must be left unadjusted,
11422 so that the linker can use this information to correctly set the
11423 bottom bit of their addresses. The MIPS version of this function
11424 also prevents relocations that are mips-16 specific, but I do not
11425 know why it does this.
11428 There is one other problem that ought to be addressed here, but
11429 which currently is not: Taking the address of a label (rather
11430 than a function) and then later jumping to that address. Such
11431 addresses also ought to have their bottom bit set (assuming that
11432 they reside in Thumb code), but at the moment they will not. */
11435 arm_fix_adjustable (fixP
)
11438 if (fixP
->fx_addsy
== NULL
)
11441 /* Prevent all adjustments to global symbols. */
11442 if (S_IS_EXTERN (fixP
->fx_addsy
))
11445 if (S_IS_WEAK (fixP
->fx_addsy
))
11448 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
11449 && fixP
->fx_subsy
== NULL
)
11452 /* We need the symbol name for the VTABLE entries. */
11453 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
11454 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
11461 elf32_arm_target_format ()
11463 if (target_big_endian
)
11466 return "elf32-bigarm-oabi";
11468 return "elf32-bigarm";
11473 return "elf32-littlearm-oabi";
11475 return "elf32-littlearm";
11480 armelf_frob_symbol (symp
, puntp
)
11484 elf_frob_symbol (symp
, puntp
);
11488 arm_force_relocation (fixp
)
11491 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
11492 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
11493 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
11494 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
11495 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
11496 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
11502 static bfd_reloc_code_real_type
11512 bfd_reloc_code_real_type reloc
;
11516 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
11517 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
11518 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
11519 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
11520 branch instructions generated by GCC for PLT relocs. */
11521 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
11522 { NULL
, 0, BFD_RELOC_UNUSED
}
11526 for (i
= 0, ip
= input_line_pointer
;
11527 i
< sizeof (id
) && (ISALNUM (*ip
) || ISPUNCT (*ip
));
11529 id
[i
] = TOLOWER (*ip
);
11531 for (i
= 0; reloc_map
[i
].str
; i
++)
11532 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
11535 input_line_pointer
+= reloc_map
[i
].len
;
11537 return reloc_map
[i
].reloc
;
11541 s_arm_elf_cons (nbytes
)
11546 #ifdef md_flush_pending_output
11547 md_flush_pending_output ();
11550 if (is_it_end_of_statement ())
11552 demand_empty_rest_of_line ();
11556 #ifdef md_cons_align
11557 md_cons_align (nbytes
);
11562 bfd_reloc_code_real_type reloc
;
11564 expression (& exp
);
11566 if (exp
.X_op
== O_symbol
11567 && * input_line_pointer
== '('
11568 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
11570 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
11571 int size
= bfd_get_reloc_size (howto
);
11574 as_bad ("%s relocations do not fit in %d bytes",
11575 howto
->name
, nbytes
);
11578 register char *p
= frag_more ((int) nbytes
);
11579 int offset
= nbytes
- size
;
11581 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
11586 emit_expr (&exp
, (unsigned int) nbytes
);
11588 while (*input_line_pointer
++ == ',');
11590 /* Put terminator back into stream. */
11591 input_line_pointer
--;
11592 demand_empty_rest_of_line ();
11595 #endif /* OBJ_ELF */
11597 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
11598 of an rs_align_code fragment. */
11601 arm_handle_align (fragP
)
11604 static char const arm_noop
[4] = { 0x00, 0x00, 0xa0, 0xe1 };
11605 static char const thumb_noop
[2] = { 0xc0, 0x46 };
11606 static char const arm_bigend_noop
[4] = { 0xe1, 0xa0, 0x00, 0x00 };
11607 static char const thumb_bigend_noop
[2] = { 0x46, 0xc0 };
11609 int bytes
, fix
, noop_size
;
11613 if (fragP
->fr_type
!= rs_align_code
)
11616 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
11617 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
11620 if (bytes
> MAX_MEM_FOR_RS_ALIGN_CODE
)
11621 bytes
&= MAX_MEM_FOR_RS_ALIGN_CODE
;
11623 if (fragP
->tc_frag_data
)
11625 if (target_big_endian
)
11626 noop
= thumb_bigend_noop
;
11629 noop_size
= sizeof (thumb_noop
);
11633 if (target_big_endian
)
11634 noop
= arm_bigend_noop
;
11637 noop_size
= sizeof (arm_noop
);
11640 if (bytes
& (noop_size
- 1))
11642 fix
= bytes
& (noop_size
- 1);
11643 memset (p
, 0, fix
);
11648 while (bytes
>= noop_size
)
11650 memcpy (p
, noop
, noop_size
);
11652 bytes
-= noop_size
;
11656 fragP
->fr_fix
+= fix
;
11657 fragP
->fr_var
= noop_size
;
11660 /* Called from md_do_align. Used to create an alignment
11661 frag in a code section. */
11664 arm_frag_align_code (n
, max
)
11670 /* We assume that there will never be a requirment
11671 to support alignments greater than 32 bytes. */
11672 if (max
> MAX_MEM_FOR_RS_ALIGN_CODE
)
11673 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
11675 p
= frag_var (rs_align_code
,
11676 MAX_MEM_FOR_RS_ALIGN_CODE
,
11678 (relax_substateT
) max
,
11686 /* Perform target specific initialisation of a frag. */
11689 arm_init_frag (fragP
)
11692 /* Record whether this frag is in an ARM or a THUMB area. */
11693 fragP
->tc_frag_data
= thumb_mode
;