1 /* tc-arm.c -- Assemble for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
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 /* The following bitmasks control CPU extensions: */
43 #define ARM_EXT_V1 0x00000001 /* All processors (core set). */
44 #define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
45 #define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
46 #define ARM_EXT_V3 0x00000008 /* MSR MRS. */
47 #define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
48 #define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
49 #define ARM_EXT_V4T 0x00000040 /* Thumb v1. */
50 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
51 #define ARM_EXT_V5T 0x00000100 /* Thumb v2. */
52 #define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
53 #define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
54 /* Processor specific extensions. */
55 #define ARM_EXT_XSCALE 0x00000800 /* Allow MIA etc. */
56 #define ARM_EXT_MAVERICK 0x00001000 /* Use Cirrus/DSP coprocessor. */
58 /* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
59 defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
60 ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
61 three more to cover cores prior to ARM6. Finally, there are cores which
62 implement further extensions in the co-processor space. */
63 #define ARM_ARCH_V1 ARM_EXT_V1
64 #define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)
65 #define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)
66 #define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)
67 #define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)
68 #define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)
69 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)
70 #define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)
71 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)
72 #define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)
73 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
74 #define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
75 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
76 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)
77 #define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)
78 /* Processors with specific extensions in the co-processor space. */
79 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_EXT_XSCALE)
81 /* Some useful combinations: */
82 #define ARM_ANY 0x00ffffff
83 #define ARM_ALL ARM_ANY
85 #define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */
86 #define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */
89 #define FPU_ARCH_FPE FPU_FPA_EXT_V1
90 #define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
92 /* Some useful combinations. */
93 #define FPU_ANY 0xff000000 /* Note this is ~ARM_ANY. */
95 /* Types of processor to assemble for. */
96 #define ARM_1 ARM_ARCH_V1
97 #define ARM_2 ARM_ARCH_V2
98 #define ARM_3 ARM_ARCH_V2S
99 #define ARM_250 ARM_ARCH_V2S
100 #define ARM_6 ARM_ARCH_V3
101 #define ARM_7 ARM_ARCH_V3
102 #define ARM_8 ARM_ARCH_V4
103 #define ARM_9 ARM_ARCH_V4T
104 #define ARM_STRONG ARM_ARCH_V4
105 #define ARM_CPU_MASK 0x0000000f /* XXX? */
108 #if defined __XSCALE__
109 #define CPU_DEFAULT (ARM_ARCH_XSCALE)
111 #if defined __thumb__
112 #define CPU_DEFAULT (ARM_ARCH_V5T)
114 #define CPU_DEFAULT ARM_ALL
120 #define FPU_DEFAULT FPU_ARCH_FPA
123 #define streq(a, b) (strcmp (a, b) == 0)
124 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
126 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
127 static int target_oabi
= 0;
129 #if defined OBJ_COFF || defined OBJ_ELF
130 /* Flags stored in private area of BFD structure. */
131 static boolean uses_apcs_26
= false;
132 static boolean atpcs
= false;
133 static boolean support_interwork
= false;
134 static boolean uses_apcs_float
= false;
135 static boolean pic_code
= false;
138 /* This array holds the chars that always start a comment. If the
139 pre-processor is disabled, these aren't very useful. */
140 const char comment_chars
[] = "@";
142 /* This array holds the chars that only start a comment at the beginning of
143 a line. If the line seems to have the form '# 123 filename'
144 .line and .file directives will appear in the pre-processed output. */
145 /* Note that input_file.c hand checks for '#' at the beginning of the
146 first line of the input file. This is because the compiler outputs
147 #NO_APP at the beginning of its output. */
148 /* Also note that comments like this one will always work. */
149 const char line_comment_chars
[] = "#";
151 const char line_separator_chars
[] = ";";
153 /* Chars that can be used to separate mant
154 from exp in floating point numbers. */
155 const char EXP_CHARS
[] = "eE";
157 /* Chars that mean this number is a floating point constant. */
161 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
163 /* Prefix characters that indicate the start of an immediate
165 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
168 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
169 symbolS
* GOT_symbol
;
172 /* Size of relocation record. */
173 const int md_reloc_size
= 8;
175 /* 0: assemble for ARM,
176 1: assemble for Thumb,
177 2: assemble for Thumb even though target CPU does not support thumb
179 static int thumb_mode
= 0;
181 typedef struct arm_fix
189 unsigned long instruction
;
193 bfd_reloc_code_real_type type
;
210 struct asm_shift_properties
212 enum asm_shift_index index
;
213 unsigned long bit_field
;
214 unsigned int allows_0
: 1;
215 unsigned int allows_32
: 1;
218 static const struct asm_shift_properties shift_properties
[] =
220 { SHIFT_LSL
, 0, 1, 0},
221 { SHIFT_LSR
, 0x20, 0, 1},
222 { SHIFT_ASR
, 0x40, 0, 1},
223 { SHIFT_ROR
, 0x60, 0, 0},
224 { SHIFT_RRX
, 0x60, 0, 0}
227 struct asm_shift_name
230 const struct asm_shift_properties
* properties
;
233 static const struct asm_shift_name shift_names
[] =
235 { "asl", shift_properties
+ SHIFT_LSL
},
236 { "lsl", shift_properties
+ SHIFT_LSL
},
237 { "lsr", shift_properties
+ SHIFT_LSR
},
238 { "asr", shift_properties
+ SHIFT_ASR
},
239 { "ror", shift_properties
+ SHIFT_ROR
},
240 { "rrx", shift_properties
+ SHIFT_RRX
},
241 { "ASL", shift_properties
+ SHIFT_LSL
},
242 { "LSL", shift_properties
+ SHIFT_LSL
},
243 { "LSR", shift_properties
+ SHIFT_LSR
},
244 { "ASR", shift_properties
+ SHIFT_ASR
},
245 { "ROR", shift_properties
+ SHIFT_ROR
},
246 { "RRX", shift_properties
+ SHIFT_RRX
}
249 #define NO_SHIFT_RESTRICT 1
250 #define SHIFT_RESTRICT 0
252 #define NUM_FLOAT_VALS 8
254 const char * fp_const
[] =
256 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
259 /* Number of littlenums required to hold an extended precision number. */
260 #define MAX_LITTLENUMS 6
262 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
272 #define CP_T_X 0x00008000
273 #define CP_T_Y 0x00400000
274 #define CP_T_Pre 0x01000000
275 #define CP_T_UD 0x00800000
276 #define CP_T_WB 0x00200000
278 #define CONDS_BIT 0x00100000
279 #define LOAD_BIT 0x00100000
281 #define DOUBLE_LOAD_FLAG 0x00000001
285 const char * template;
289 #define COND_ALWAYS 0xe0000000
290 #define COND_MASK 0xf0000000
292 static const struct asm_cond conds
[] =
296 {"cs", 0x20000000}, {"hs", 0x20000000},
297 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
314 const char * template;
319 /* The bit that distnguishes CPSR and SPSR. */
320 #define SPSR_BIT (1 << 22)
322 /* How many bits to shift the PSR_xxx bits up by. */
325 #define PSR_c (1 << 0)
326 #define PSR_x (1 << 1)
327 #define PSR_s (1 << 2)
328 #define PSR_f (1 << 3)
330 static const struct asm_psr psrs
[] =
332 {"CPSR", true, PSR_c
| PSR_f
},
333 {"CPSR_all", true, PSR_c
| PSR_f
},
334 {"SPSR", false, PSR_c
| PSR_f
},
335 {"SPSR_all", false, PSR_c
| PSR_f
},
336 {"CPSR_flg", true, PSR_f
},
337 {"CPSR_f", true, PSR_f
},
338 {"SPSR_flg", false, PSR_f
},
339 {"SPSR_f", false, PSR_f
},
340 {"CPSR_c", true, PSR_c
},
341 {"CPSR_ctl", true, PSR_c
},
342 {"SPSR_c", false, PSR_c
},
343 {"SPSR_ctl", false, PSR_c
},
344 {"CPSR_x", true, PSR_x
},
345 {"CPSR_s", true, PSR_s
},
346 {"SPSR_x", false, PSR_x
},
347 {"SPSR_s", false, PSR_s
},
348 /* Combinations of flags. */
349 {"CPSR_fs", true, PSR_f
| PSR_s
},
350 {"CPSR_fx", true, PSR_f
| PSR_x
},
351 {"CPSR_fc", true, PSR_f
| PSR_c
},
352 {"CPSR_sf", true, PSR_s
| PSR_f
},
353 {"CPSR_sx", true, PSR_s
| PSR_x
},
354 {"CPSR_sc", true, PSR_s
| PSR_c
},
355 {"CPSR_xf", true, PSR_x
| PSR_f
},
356 {"CPSR_xs", true, PSR_x
| PSR_s
},
357 {"CPSR_xc", true, PSR_x
| PSR_c
},
358 {"CPSR_cf", true, PSR_c
| PSR_f
},
359 {"CPSR_cs", true, PSR_c
| PSR_s
},
360 {"CPSR_cx", true, PSR_c
| PSR_x
},
361 {"CPSR_fsx", true, PSR_f
| PSR_s
| PSR_x
},
362 {"CPSR_fsc", true, PSR_f
| PSR_s
| PSR_c
},
363 {"CPSR_fxs", true, PSR_f
| PSR_x
| PSR_s
},
364 {"CPSR_fxc", true, PSR_f
| PSR_x
| PSR_c
},
365 {"CPSR_fcs", true, PSR_f
| PSR_c
| PSR_s
},
366 {"CPSR_fcx", true, PSR_f
| PSR_c
| PSR_x
},
367 {"CPSR_sfx", true, PSR_s
| PSR_f
| PSR_x
},
368 {"CPSR_sfc", true, PSR_s
| PSR_f
| PSR_c
},
369 {"CPSR_sxf", true, PSR_s
| PSR_x
| PSR_f
},
370 {"CPSR_sxc", true, PSR_s
| PSR_x
| PSR_c
},
371 {"CPSR_scf", true, PSR_s
| PSR_c
| PSR_f
},
372 {"CPSR_scx", true, PSR_s
| PSR_c
| PSR_x
},
373 {"CPSR_xfs", true, PSR_x
| PSR_f
| PSR_s
},
374 {"CPSR_xfc", true, PSR_x
| PSR_f
| PSR_c
},
375 {"CPSR_xsf", true, PSR_x
| PSR_s
| PSR_f
},
376 {"CPSR_xsc", true, PSR_x
| PSR_s
| PSR_c
},
377 {"CPSR_xcf", true, PSR_x
| PSR_c
| PSR_f
},
378 {"CPSR_xcs", true, PSR_x
| PSR_c
| PSR_s
},
379 {"CPSR_cfs", true, PSR_c
| PSR_f
| PSR_s
},
380 {"CPSR_cfx", true, PSR_c
| PSR_f
| PSR_x
},
381 {"CPSR_csf", true, PSR_c
| PSR_s
| PSR_f
},
382 {"CPSR_csx", true, PSR_c
| PSR_s
| PSR_x
},
383 {"CPSR_cxf", true, PSR_c
| PSR_x
| PSR_f
},
384 {"CPSR_cxs", true, PSR_c
| PSR_x
| PSR_s
},
385 {"CPSR_fsxc", true, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
386 {"CPSR_fscx", true, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
387 {"CPSR_fxsc", true, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
388 {"CPSR_fxcs", true, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
389 {"CPSR_fcsx", true, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
390 {"CPSR_fcxs", true, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
391 {"CPSR_sfxc", true, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
392 {"CPSR_sfcx", true, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
393 {"CPSR_sxfc", true, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
394 {"CPSR_sxcf", true, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
395 {"CPSR_scfx", true, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
396 {"CPSR_scxf", true, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
397 {"CPSR_xfsc", true, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
398 {"CPSR_xfcs", true, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
399 {"CPSR_xsfc", true, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
400 {"CPSR_xscf", true, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
401 {"CPSR_xcfs", true, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
402 {"CPSR_xcsf", true, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
403 {"CPSR_cfsx", true, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
404 {"CPSR_cfxs", true, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
405 {"CPSR_csfx", true, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
406 {"CPSR_csxf", true, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
407 {"CPSR_cxfs", true, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
408 {"CPSR_cxsf", true, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
409 {"SPSR_fs", false, PSR_f
| PSR_s
},
410 {"SPSR_fx", false, PSR_f
| PSR_x
},
411 {"SPSR_fc", false, PSR_f
| PSR_c
},
412 {"SPSR_sf", false, PSR_s
| PSR_f
},
413 {"SPSR_sx", false, PSR_s
| PSR_x
},
414 {"SPSR_sc", false, PSR_s
| PSR_c
},
415 {"SPSR_xf", false, PSR_x
| PSR_f
},
416 {"SPSR_xs", false, PSR_x
| PSR_s
},
417 {"SPSR_xc", false, PSR_x
| PSR_c
},
418 {"SPSR_cf", false, PSR_c
| PSR_f
},
419 {"SPSR_cs", false, PSR_c
| PSR_s
},
420 {"SPSR_cx", false, PSR_c
| PSR_x
},
421 {"SPSR_fsx", false, PSR_f
| PSR_s
| PSR_x
},
422 {"SPSR_fsc", false, PSR_f
| PSR_s
| PSR_c
},
423 {"SPSR_fxs", false, PSR_f
| PSR_x
| PSR_s
},
424 {"SPSR_fxc", false, PSR_f
| PSR_x
| PSR_c
},
425 {"SPSR_fcs", false, PSR_f
| PSR_c
| PSR_s
},
426 {"SPSR_fcx", false, PSR_f
| PSR_c
| PSR_x
},
427 {"SPSR_sfx", false, PSR_s
| PSR_f
| PSR_x
},
428 {"SPSR_sfc", false, PSR_s
| PSR_f
| PSR_c
},
429 {"SPSR_sxf", false, PSR_s
| PSR_x
| PSR_f
},
430 {"SPSR_sxc", false, PSR_s
| PSR_x
| PSR_c
},
431 {"SPSR_scf", false, PSR_s
| PSR_c
| PSR_f
},
432 {"SPSR_scx", false, PSR_s
| PSR_c
| PSR_x
},
433 {"SPSR_xfs", false, PSR_x
| PSR_f
| PSR_s
},
434 {"SPSR_xfc", false, PSR_x
| PSR_f
| PSR_c
},
435 {"SPSR_xsf", false, PSR_x
| PSR_s
| PSR_f
},
436 {"SPSR_xsc", false, PSR_x
| PSR_s
| PSR_c
},
437 {"SPSR_xcf", false, PSR_x
| PSR_c
| PSR_f
},
438 {"SPSR_xcs", false, PSR_x
| PSR_c
| PSR_s
},
439 {"SPSR_cfs", false, PSR_c
| PSR_f
| PSR_s
},
440 {"SPSR_cfx", false, PSR_c
| PSR_f
| PSR_x
},
441 {"SPSR_csf", false, PSR_c
| PSR_s
| PSR_f
},
442 {"SPSR_csx", false, PSR_c
| PSR_s
| PSR_x
},
443 {"SPSR_cxf", false, PSR_c
| PSR_x
| PSR_f
},
444 {"SPSR_cxs", false, PSR_c
| PSR_x
| PSR_s
},
445 {"SPSR_fsxc", false, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
446 {"SPSR_fscx", false, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
447 {"SPSR_fxsc", false, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
448 {"SPSR_fxcs", false, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
449 {"SPSR_fcsx", false, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
450 {"SPSR_fcxs", false, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
451 {"SPSR_sfxc", false, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
452 {"SPSR_sfcx", false, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
453 {"SPSR_sxfc", false, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
454 {"SPSR_sxcf", false, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
455 {"SPSR_scfx", false, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
456 {"SPSR_scxf", false, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
457 {"SPSR_xfsc", false, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
458 {"SPSR_xfcs", false, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
459 {"SPSR_xsfc", false, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
460 {"SPSR_xscf", false, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
461 {"SPSR_xcfs", false, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
462 {"SPSR_xcsf", false, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
463 {"SPSR_cfsx", false, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
464 {"SPSR_cfxs", false, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
465 {"SPSR_csfx", false, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
466 {"SPSR_csxf", false, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
467 {"SPSR_cxfs", false, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
468 {"SPSR_cxsf", false, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
473 CIRRUS_REGTYPE_MVF
= 1,
474 CIRRUS_REGTYPE_MVFX
= 2,
475 CIRRUS_REGTYPE_MVD
= 3,
476 CIRRUS_REGTYPE_MVDX
= 4,
477 CIRRUS_REGTYPE_MVAX
= 5,
478 CIRRUS_REGTYPE_DSPSC
= 6,
479 CIRRUS_REGTYPE_ANY
= 7
482 /* Functions called by parser. */
483 /* ARM instructions. */
484 static void do_arit
PARAMS ((char *));
485 static void do_cmp
PARAMS ((char *));
486 static void do_mov
PARAMS ((char *));
487 static void do_ldst
PARAMS ((char *));
488 static void do_ldstt
PARAMS ((char *));
489 static void do_ldmstm
PARAMS ((char *));
490 static void do_branch
PARAMS ((char *));
491 static void do_swi
PARAMS ((char *));
493 /* Pseudo Op codes. */
494 static void do_adr
PARAMS ((char *));
495 static void do_adrl
PARAMS ((char *));
496 static void do_empty
PARAMS ((char *));
499 static void do_mul
PARAMS ((char *));
500 static void do_mla
PARAMS ((char *));
503 static void do_swap
PARAMS ((char *));
506 static void do_msr
PARAMS ((char *));
507 static void do_mrs
PARAMS ((char *));
510 static void do_mull
PARAMS ((char *));
513 static void do_ldstv4
PARAMS ((char *));
516 static void do_bx
PARAMS ((char *));
519 static void do_blx
PARAMS ((char *));
520 static void do_bkpt
PARAMS ((char *));
521 static void do_clz
PARAMS ((char *));
522 static void do_lstc2
PARAMS ((char *));
523 static void do_cdp2
PARAMS ((char *));
524 static void do_co_reg2
PARAMS ((char *));
527 static void do_smla
PARAMS ((char *));
528 static void do_smlal
PARAMS ((char *));
529 static void do_smul
PARAMS ((char *));
530 static void do_qadd
PARAMS ((char *));
533 static void do_pld
PARAMS ((char *));
534 static void do_ldrd
PARAMS ((char *));
535 static void do_co_reg2c
PARAMS ((char *));
537 /* Coprocessor Instructions. */
538 static void do_cdp
PARAMS ((char *));
539 static void do_lstc
PARAMS ((char *));
540 static void do_co_reg
PARAMS ((char *));
542 /* FPA instructions. */
543 static void do_fpa_ctrl
PARAMS ((char *));
544 static void do_fpa_ldst
PARAMS ((char *));
545 static void do_fpa_ldmstm
PARAMS ((char *));
546 static void do_fpa_dyadic
PARAMS ((char *));
547 static void do_fpa_monadic
PARAMS ((char *));
548 static void do_fpa_cmp
PARAMS ((char *));
549 static void do_fpa_from_reg
PARAMS ((char *));
550 static void do_fpa_to_reg
PARAMS ((char *));
553 static void do_mia
PARAMS ((char *));
554 static void do_mar
PARAMS ((char *));
555 static void do_mra
PARAMS ((char *));
558 static void do_c_binops
PARAMS ((char *, int));
559 static void do_c_binops_1
PARAMS ((char *));
560 static void do_c_binops_2
PARAMS ((char *));
561 static void do_c_binops_3
PARAMS ((char *));
562 static void do_c_triple
PARAMS ((char *, int));
563 static void do_c_triple_4
PARAMS ((char *));
564 static void do_c_triple_5
PARAMS ((char *));
565 static void do_c_quad
PARAMS ((char *, int));
566 static void do_c_quad_6
PARAMS ((char *));
567 static void do_c_dspsc
PARAMS ((char *, int));
568 static void do_c_dspsc_1
PARAMS ((char *));
569 static void do_c_dspsc_2
PARAMS ((char *));
570 static void do_c_shift
PARAMS ((char *, int));
571 static void do_c_shift_1
PARAMS ((char *));
572 static void do_c_shift_2
PARAMS ((char *));
573 static void do_c_ldst
PARAMS ((char *, int));
574 static void do_c_ldst_1
PARAMS ((char *));
575 static void do_c_ldst_2
PARAMS ((char *));
576 static void do_c_ldst_3
PARAMS ((char *));
577 static void do_c_ldst_4
PARAMS ((char *));
578 static int cirrus_reg_required_here
PARAMS ((char **, int,
579 enum cirrus_regtype
));
580 static int cirrus_valid_reg
PARAMS ((int, enum cirrus_regtype
));
581 static int cirrus_parse_offset
PARAMS ((char **, int *));
583 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*,
585 static int arm_reg_parse
PARAMS ((char **));
586 static const struct asm_psr
* arm_psr_parse
PARAMS ((char **));
587 static void symbol_locate
PARAMS ((symbolS
*, const char *, segT
, valueT
,
589 static int add_to_lit_pool
PARAMS ((void));
590 static unsigned validate_immediate
PARAMS ((unsigned));
591 static unsigned validate_immediate_twopart
PARAMS ((unsigned int,
593 static int validate_offset_imm
PARAMS ((unsigned int, int));
594 static void opcode_select
PARAMS ((int));
595 static void end_of_line
PARAMS ((char *));
596 static int reg_required_here
PARAMS ((char **, int));
597 static int psr_required_here
PARAMS ((char **));
598 static int co_proc_number
PARAMS ((char **));
599 static int cp_opc_expr
PARAMS ((char **, int, int));
600 static int cp_reg_required_here
PARAMS ((char **, int));
601 static int fp_reg_required_here
PARAMS ((char **, int));
602 static int cp_address_offset
PARAMS ((char **));
603 static int cp_address_required_here
PARAMS ((char **));
604 static int my_get_float_expression
PARAMS ((char **));
605 static int skip_past_comma
PARAMS ((char **));
606 static int walk_no_bignums
PARAMS ((symbolS
*));
607 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
608 static int data_op2
PARAMS ((char **));
609 static int fp_op2
PARAMS ((char **));
610 static long reg_list
PARAMS ((char **));
611 static void thumb_load_store
PARAMS ((char *, int, int));
612 static int decode_shift
PARAMS ((char **, int));
613 static int ldst_extend
PARAMS ((char **));
614 static int ldst_extend_v4
PARAMS ((char **));
615 static void thumb_add_sub
PARAMS ((char *, int));
616 static void insert_reg
PARAMS ((int));
617 static void thumb_shift
PARAMS ((char *, int));
618 static void thumb_mov_compare
PARAMS ((char *, int));
619 static void build_arm_ops_hsh
PARAMS ((void));
620 static void set_constant_flonums
PARAMS ((void));
621 static valueT md_chars_to_number
PARAMS ((char *, int));
622 static void insert_reg_alias
PARAMS ((char *, int));
623 static void output_inst
PARAMS ((void));
624 static int accum0_required_here
PARAMS ((char **));
625 static int ld_mode_required_here
PARAMS ((char **));
626 static void do_branch25
PARAMS ((char *));
627 static symbolS
* find_real_start
PARAMS ((symbolS
*));
629 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
632 /* ARM instructions take 4bytes in the object file, Thumb instructions
636 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
637 #define CIRRUS_MODE1 0x100c
639 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
640 #define CIRRUS_MODE2 0x0c10
642 /* "INSN<cond> X,Y" where X:0, Y:bit16. */
643 #define CIRRUS_MODE3 0x1000
645 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
646 #define CIRRUS_MODE4 0x0c0010
648 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
649 #define CIRRUS_MODE5 0x00100c
651 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
652 #define CIRRUS_MODE6 0x00100c05
656 /* Basic string to match. */
657 const char * template;
659 /* Basic instruction code. */
662 /* Offset into the template where the condition code (if any) will be.
663 If zero, then the instruction is never conditional. */
664 unsigned cond_offset
;
666 /* Which architecture variant provides this instruction. */
667 unsigned long variant
;
669 /* Function to call to parse args. */
670 void (* parms
) PARAMS ((char *));
673 static const struct asm_opcode insns
[] =
675 /* Core ARM Instructions. */
676 {"and", 0xe0000000, 3, ARM_EXT_V1
, do_arit
},
677 {"ands", 0xe0100000, 3, ARM_EXT_V1
, do_arit
},
678 {"eor", 0xe0200000, 3, ARM_EXT_V1
, do_arit
},
679 {"eors", 0xe0300000, 3, ARM_EXT_V1
, do_arit
},
680 {"sub", 0xe0400000, 3, ARM_EXT_V1
, do_arit
},
681 {"subs", 0xe0500000, 3, ARM_EXT_V1
, do_arit
},
682 {"rsb", 0xe0600000, 3, ARM_EXT_V1
, do_arit
},
683 {"rsbs", 0xe0700000, 3, ARM_EXT_V1
, do_arit
},
684 {"add", 0xe0800000, 3, ARM_EXT_V1
, do_arit
},
685 {"adds", 0xe0900000, 3, ARM_EXT_V1
, do_arit
},
686 {"adc", 0xe0a00000, 3, ARM_EXT_V1
, do_arit
},
687 {"adcs", 0xe0b00000, 3, ARM_EXT_V1
, do_arit
},
688 {"sbc", 0xe0c00000, 3, ARM_EXT_V1
, do_arit
},
689 {"sbcs", 0xe0d00000, 3, ARM_EXT_V1
, do_arit
},
690 {"rsc", 0xe0e00000, 3, ARM_EXT_V1
, do_arit
},
691 {"rscs", 0xe0f00000, 3, ARM_EXT_V1
, do_arit
},
692 {"orr", 0xe1800000, 3, ARM_EXT_V1
, do_arit
},
693 {"orrs", 0xe1900000, 3, ARM_EXT_V1
, do_arit
},
694 {"bic", 0xe1c00000, 3, ARM_EXT_V1
, do_arit
},
695 {"bics", 0xe1d00000, 3, ARM_EXT_V1
, do_arit
},
697 {"tst", 0xe1100000, 3, ARM_EXT_V1
, do_cmp
},
698 {"tsts", 0xe1100000, 3, ARM_EXT_V1
, do_cmp
},
699 {"tstp", 0xe110f000, 3, ARM_EXT_V1
, do_cmp
},
700 {"teq", 0xe1300000, 3, ARM_EXT_V1
, do_cmp
},
701 {"teqs", 0xe1300000, 3, ARM_EXT_V1
, do_cmp
},
702 {"teqp", 0xe130f000, 3, ARM_EXT_V1
, do_cmp
},
703 {"cmp", 0xe1500000, 3, ARM_EXT_V1
, do_cmp
},
704 {"cmps", 0xe1500000, 3, ARM_EXT_V1
, do_cmp
},
705 {"cmpp", 0xe150f000, 3, ARM_EXT_V1
, do_cmp
},
706 {"cmn", 0xe1700000, 3, ARM_EXT_V1
, do_cmp
},
707 {"cmns", 0xe1700000, 3, ARM_EXT_V1
, do_cmp
},
708 {"cmnp", 0xe170f000, 3, ARM_EXT_V1
, do_cmp
},
710 {"mov", 0xe1a00000, 3, ARM_EXT_V1
, do_mov
},
711 {"movs", 0xe1b00000, 3, ARM_EXT_V1
, do_mov
},
712 {"mvn", 0xe1e00000, 3, ARM_EXT_V1
, do_mov
},
713 {"mvns", 0xe1f00000, 3, ARM_EXT_V1
, do_mov
},
715 {"ldr", 0xe4100000, 3, ARM_EXT_V1
, do_ldst
},
716 {"ldrb", 0xe4500000, 3, ARM_EXT_V1
, do_ldst
},
717 {"ldrt", 0xe4300000, 3, ARM_EXT_V1
, do_ldstt
},
718 {"ldrbt", 0xe4700000, 3, ARM_EXT_V1
, do_ldstt
},
719 {"str", 0xe4000000, 3, ARM_EXT_V1
, do_ldst
},
720 {"strb", 0xe4400000, 3, ARM_EXT_V1
, do_ldst
},
721 {"strt", 0xe4200000, 3, ARM_EXT_V1
, do_ldstt
},
722 {"strbt", 0xe4600000, 3, ARM_EXT_V1
, do_ldstt
},
724 {"stmia", 0xe8800000, 3, ARM_EXT_V1
, do_ldmstm
},
725 {"stmib", 0xe9800000, 3, ARM_EXT_V1
, do_ldmstm
},
726 {"stmda", 0xe8000000, 3, ARM_EXT_V1
, do_ldmstm
},
727 {"stmdb", 0xe9000000, 3, ARM_EXT_V1
, do_ldmstm
},
728 {"stmfd", 0xe9000000, 3, ARM_EXT_V1
, do_ldmstm
},
729 {"stmfa", 0xe9800000, 3, ARM_EXT_V1
, do_ldmstm
},
730 {"stmea", 0xe8800000, 3, ARM_EXT_V1
, do_ldmstm
},
731 {"stmed", 0xe8000000, 3, ARM_EXT_V1
, do_ldmstm
},
733 {"ldmia", 0xe8900000, 3, ARM_EXT_V1
, do_ldmstm
},
734 {"ldmib", 0xe9900000, 3, ARM_EXT_V1
, do_ldmstm
},
735 {"ldmda", 0xe8100000, 3, ARM_EXT_V1
, do_ldmstm
},
736 {"ldmdb", 0xe9100000, 3, ARM_EXT_V1
, do_ldmstm
},
737 {"ldmfd", 0xe8900000, 3, ARM_EXT_V1
, do_ldmstm
},
738 {"ldmfa", 0xe8100000, 3, ARM_EXT_V1
, do_ldmstm
},
739 {"ldmea", 0xe9100000, 3, ARM_EXT_V1
, do_ldmstm
},
740 {"ldmed", 0xe9900000, 3, ARM_EXT_V1
, do_ldmstm
},
742 {"swi", 0xef000000, 3, ARM_EXT_V1
, do_swi
},
744 /* XXX This is the wrong place to do this. Think multi-arch. */
745 {"bl", 0xeb000000, 2, ARM_EXT_V1
, do_branch
},
746 {"b", 0xea000000, 1, ARM_EXT_V1
, do_branch
},
748 {"bl", 0xebfffffe, 2, ARM_EXT_V1
, do_branch
},
749 {"b", 0xeafffffe, 1, ARM_EXT_V1
, do_branch
},
753 {"adr", 0xe28f0000, 3, ARM_EXT_V1
, do_adr
},
754 {"adrl", 0xe28f0000, 3, ARM_EXT_V1
, do_adrl
},
755 {"nop", 0xe1a00000, 3, ARM_EXT_V1
, do_empty
},
757 /* ARM 2 multiplies. */
758 {"mul", 0xe0000090, 3, ARM_EXT_V2
, do_mul
},
759 {"muls", 0xe0100090, 3, ARM_EXT_V2
, do_mul
},
760 {"mla", 0xe0200090, 3, ARM_EXT_V2
, do_mla
},
761 {"mlas", 0xe0300090, 3, ARM_EXT_V2
, do_mla
},
763 /* Generic copressor instructions. */
764 {"cdp", 0xee000000, 3, ARM_EXT_V2
, do_cdp
},
765 {"ldc", 0xec100000, 3, ARM_EXT_V2
, do_lstc
},
766 {"ldcl", 0xec500000, 3, ARM_EXT_V2
, do_lstc
},
767 {"stc", 0xec000000, 3, ARM_EXT_V2
, do_lstc
},
768 {"stcl", 0xec400000, 3, ARM_EXT_V2
, do_lstc
},
769 {"mcr", 0xee000010, 3, ARM_EXT_V2
, do_co_reg
},
770 {"mrc", 0xee100010, 3, ARM_EXT_V2
, do_co_reg
},
772 /* ARM 3 - swp instructions. */
773 {"swp", 0xe1000090, 3, ARM_EXT_V2S
, do_swap
},
774 {"swpb", 0xe1400090, 3, ARM_EXT_V2S
, do_swap
},
776 /* ARM 6 Status register instructions. */
777 {"mrs", 0xe10f0000, 3, ARM_EXT_V3
, do_mrs
},
778 {"msr", 0xe120f000, 3, ARM_EXT_V3
, do_msr
},
779 /* ScottB: our code uses 0xe128f000 for msr.
780 NickC: but this is wrong because the bits 16 through 19 are
781 handled by the PSR_xxx defines above. */
783 /* ARM 7M long multiplies. */
784 {"smull", 0xe0c00090, 5, ARM_EXT_V3M
, do_mull
},
785 {"smulls", 0xe0d00090, 5, ARM_EXT_V3M
, do_mull
},
786 {"umull", 0xe0800090, 5, ARM_EXT_V3M
, do_mull
},
787 {"umulls", 0xe0900090, 5, ARM_EXT_V3M
, do_mull
},
788 {"smlal", 0xe0e00090, 5, ARM_EXT_V3M
, do_mull
},
789 {"smlals", 0xe0f00090, 5, ARM_EXT_V3M
, do_mull
},
790 {"umlal", 0xe0a00090, 5, ARM_EXT_V3M
, do_mull
},
791 {"umlals", 0xe0b00090, 5, ARM_EXT_V3M
, do_mull
},
793 /* ARM Architecture 4. */
794 {"ldrh", 0xe01000b0, 3, ARM_EXT_V4
, do_ldstv4
},
795 {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4
, do_ldstv4
},
796 {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4
, do_ldstv4
},
797 {"strh", 0xe00000b0, 3, ARM_EXT_V4
, do_ldstv4
},
799 /* ARM Architecture 4T. */
800 /* Note: bx (and blx) are required on V5, even if the processor does
801 not support Thumb. */
802 {"bx", 0xe12fff10, 2, ARM_EXT_V4T
| ARM_EXT_V5
, do_bx
},
804 /* ARM Architecture 5. */
805 /* Note: blx has 2 variants, so the .value is set dynamically.
806 Only one of the variants has conditional execution. */
807 {"blx", 0xe0000000, 3, ARM_EXT_V5
, do_blx
},
808 {"clz", 0xe16f0f10, 3, ARM_EXT_V5
, do_clz
},
809 {"bkpt", 0xe1200070, 0, ARM_EXT_V5
, do_bkpt
},
810 {"ldc2", 0xfc100000, 0, ARM_EXT_V5
, do_lstc2
},
811 {"ldc2l", 0xfc500000, 0, ARM_EXT_V5
, do_lstc2
},
812 {"stc2", 0xfc000000, 0, ARM_EXT_V5
, do_lstc2
},
813 {"stc2l", 0xfc400000, 0, ARM_EXT_V5
, do_lstc2
},
814 {"cdp2", 0xfe000000, 0, ARM_EXT_V5
, do_cdp2
},
815 {"mcr2", 0xfe000010, 0, ARM_EXT_V5
, do_co_reg2
},
816 {"mrc2", 0xfe100010, 0, ARM_EXT_V5
, do_co_reg2
},
818 /* ARM Architecture 5ExP. */
819 {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP
, do_smla
},
820 {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP
, do_smla
},
821 {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP
, do_smla
},
822 {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP
, do_smla
},
824 {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP
, do_smla
},
825 {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP
, do_smla
},
827 {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP
, do_smlal
},
828 {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP
, do_smlal
},
829 {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP
, do_smlal
},
830 {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP
, do_smlal
},
832 {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP
, do_smul
},
833 {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP
, do_smul
},
834 {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP
, do_smul
},
835 {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP
, do_smul
},
837 {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP
, do_smul
},
838 {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP
, do_smul
},
840 {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP
, do_qadd
},
841 {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP
, do_qadd
},
842 {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP
, do_qadd
},
843 {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP
, do_qadd
},
845 /* ARM Architecture 5E. */
846 {"pld", 0xf450f000, 0, ARM_EXT_V5E
, do_pld
},
847 {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E
, do_ldrd
},
848 {"strd", 0xe00000f0, 3, ARM_EXT_V5E
, do_ldrd
},
850 {"mcrr", 0xec400000, 4, ARM_EXT_V5E
, do_co_reg2c
},
851 {"mrrc", 0xec500000, 4, ARM_EXT_V5E
, do_co_reg2c
},
853 /* Core FPA instruction set (V1). */
854 {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
855 {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
856 {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
857 {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
859 {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
860 {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
861 {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
862 {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
864 {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
865 {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
866 {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
867 {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
869 {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
870 {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
871 {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
872 {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
873 {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
874 {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
875 {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
876 {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
877 {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
878 {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
879 {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
880 {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
882 {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
883 {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
884 {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
885 {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
886 {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
887 {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
888 {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
889 {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
890 {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
891 {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
892 {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
893 {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
895 {"abss", 0xee208100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
896 {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
897 {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
898 {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
899 {"absd", 0xee208180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
900 {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
901 {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
902 {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
903 {"abse", 0xee288100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
904 {"absep", 0xee288120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
905 {"absem", 0xee288140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
906 {"absez", 0xee288160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
908 {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
909 {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
910 {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
911 {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
912 {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
913 {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
914 {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
915 {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
916 {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
917 {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
918 {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
919 {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
921 {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
922 {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
923 {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
924 {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
925 {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
926 {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
927 {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
928 {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
929 {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
930 {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
931 {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
932 {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
934 {"logs", 0xee508100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
935 {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
936 {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
937 {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
938 {"logd", 0xee508180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
939 {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
940 {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
941 {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
942 {"loge", 0xee588100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
943 {"logep", 0xee588120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
944 {"logem", 0xee588140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
945 {"logez", 0xee588160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
947 {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
948 {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
949 {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
950 {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
951 {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
952 {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
953 {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
954 {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
955 {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
956 {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
957 {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
958 {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
960 {"exps", 0xee708100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
961 {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
962 {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
963 {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
964 {"expd", 0xee708180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
965 {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
966 {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
967 {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
968 {"expe", 0xee788100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
969 {"expep", 0xee788120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
970 {"expem", 0xee788140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
971 {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
973 {"sins", 0xee808100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
974 {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
975 {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
976 {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
977 {"sind", 0xee808180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
978 {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
979 {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
980 {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
981 {"sine", 0xee888100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
982 {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
983 {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
984 {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
986 {"coss", 0xee908100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
987 {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
988 {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
989 {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
990 {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
991 {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
992 {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
993 {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
994 {"cose", 0xee988100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
995 {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
996 {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
997 {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
999 {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1000 {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1001 {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1002 {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1003 {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1004 {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1005 {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1006 {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1007 {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1008 {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1009 {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1010 {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1012 {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1013 {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1014 {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1015 {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1016 {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1017 {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1018 {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1019 {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1020 {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1021 {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1022 {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1023 {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1025 {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1026 {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1027 {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1028 {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1029 {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1030 {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1031 {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1032 {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1033 {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1034 {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1035 {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1036 {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1038 {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1039 {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1040 {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1041 {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1042 {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1043 {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1044 {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1045 {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1046 {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1047 {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1048 {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1049 {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1051 {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1052 {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1053 {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1054 {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1055 {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1056 {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1057 {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1058 {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1059 {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1060 {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1061 {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1062 {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1064 {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1065 {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1066 {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1067 {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1068 {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1069 {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1070 {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1071 {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1072 {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1073 {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1074 {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1075 {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1077 {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1078 {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1079 {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1080 {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1081 {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1082 {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1083 {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1084 {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1085 {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1086 {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1087 {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1088 {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1090 {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1091 {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1092 {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1093 {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1094 {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1095 {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1096 {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1097 {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1098 {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1099 {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1100 {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1101 {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1103 {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1104 {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1105 {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1106 {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1107 {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1108 {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1109 {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1110 {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1111 {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1112 {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1113 {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1114 {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1116 {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1117 {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1118 {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1119 {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1120 {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1121 {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1122 {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1123 {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1124 {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1125 {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1126 {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1127 {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1129 {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1130 {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1131 {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1132 {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1133 {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1134 {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1135 {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1136 {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1137 {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1138 {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1139 {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1140 {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1142 {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1143 {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1144 {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1145 {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1146 {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1147 {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1148 {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1149 {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1150 {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1151 {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1152 {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1153 {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1155 {"pows", 0xee600100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1156 {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1157 {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1158 {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1159 {"powd", 0xee600180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1160 {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1161 {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1162 {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1163 {"powe", 0xee680100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1164 {"powep", 0xee680120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1165 {"powem", 0xee680140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1166 {"powez", 0xee680160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1168 {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1169 {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1170 {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1171 {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1172 {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1173 {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1174 {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1175 {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1176 {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1177 {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1178 {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1179 {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1181 {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1182 {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1183 {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1184 {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1185 {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1186 {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1187 {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1188 {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1189 {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1190 {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1191 {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1192 {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1194 {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1195 {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1196 {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1197 {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1198 {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1199 {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1200 {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1201 {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1202 {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1203 {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1204 {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1205 {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1207 {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1208 {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1209 {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1210 {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1211 {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1212 {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1213 {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1214 {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1215 {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1216 {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1217 {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1218 {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1220 {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1221 {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1222 {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1223 {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1224 {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1225 {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1226 {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1227 {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1228 {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1229 {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1230 {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1231 {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1233 {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1234 {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1235 {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1236 {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1237 {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1238 {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1239 {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1240 {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1241 {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1242 {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1243 {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1244 {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1246 {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1247 {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1248 {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1249 {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1250 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1251 not be an optional suffix, but part of the instruction. To be
1252 compatible, we accept either. */
1253 {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1254 {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1256 {"flts", 0xee000110, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1257 {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1258 {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1259 {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1260 {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1261 {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1262 {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1263 {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1264 {"flte", 0xee080110, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1265 {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1266 {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1267 {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1269 /* The implementation of the FIX instruction is broken on some
1270 assemblers, in that it accepts a precision specifier as well as a
1271 rounding specifier, despite the fact that this is meaningless.
1272 To be more compatible, we accept it as well, though of course it
1273 does not set any bits. */
1274 {"fix", 0xee100110, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1275 {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1276 {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1277 {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1278 {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1279 {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1280 {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1281 {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1282 {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1283 {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1284 {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1285 {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1286 {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1288 /* Instructions that were new with the real FPA, call them V2. */
1289 {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1290 {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1291 {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1292 {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1293 {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1294 {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1296 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
1297 {"mia", 0xee200010, 3, ARM_EXT_XSCALE
, do_mia
},
1298 {"miaph", 0xee280010, 5, ARM_EXT_XSCALE
, do_mia
},
1299 {"miabb", 0xee2c0010, 5, ARM_EXT_XSCALE
, do_mia
},
1300 {"miabt", 0xee2d0010, 5, ARM_EXT_XSCALE
, do_mia
},
1301 {"miatb", 0xee2e0010, 5, ARM_EXT_XSCALE
, do_mia
},
1302 {"miatt", 0xee2f0010, 5, ARM_EXT_XSCALE
, do_mia
},
1303 {"mar", 0xec400000, 3, ARM_EXT_XSCALE
, do_mar
},
1304 {"mra", 0xec500000, 3, ARM_EXT_XSCALE
, do_mra
},
1306 /* Cirrus DSP instructions. */
1307 {"cfldrs", 0xec100400, 6, ARM_EXT_MAVERICK
, do_c_ldst_1
},
1308 {"cfldrd", 0xec500400, 6, ARM_EXT_MAVERICK
, do_c_ldst_2
},
1309 {"cfldr32", 0xec100500, 7, ARM_EXT_MAVERICK
, do_c_ldst_3
},
1310 {"cfldr64", 0xec500500, 7, ARM_EXT_MAVERICK
, do_c_ldst_4
},
1311 {"cfstrs", 0xec000400, 6, ARM_EXT_MAVERICK
, do_c_ldst_1
},
1312 {"cfstrd", 0xec400400, 6, ARM_EXT_MAVERICK
, do_c_ldst_2
},
1313 {"cfstr32", 0xec000500, 7, ARM_EXT_MAVERICK
, do_c_ldst_3
},
1314 {"cfstr64", 0xec400500, 7, ARM_EXT_MAVERICK
, do_c_ldst_4
},
1315 {"cfmvsr", 0xee000450, 6, ARM_EXT_MAVERICK
, do_c_binops_2
},
1316 {"cfmvrs", 0xee100450, 6, ARM_EXT_MAVERICK
, do_c_binops_1
},
1317 {"cfmvdlr", 0xee000410, 7, ARM_EXT_MAVERICK
, do_c_binops_2
},
1318 {"cfmvrdl", 0xee100410, 7, ARM_EXT_MAVERICK
, do_c_binops_1
},
1319 {"cfmvdhr", 0xee000430, 7, ARM_EXT_MAVERICK
, do_c_binops_2
},
1320 {"cfmvrdh", 0xee100430, 7, ARM_EXT_MAVERICK
, do_c_binops_1
},
1321 {"cfmv64lr", 0xee000510, 8, ARM_EXT_MAVERICK
, do_c_binops_2
},
1322 {"cfmvr64l", 0xee100510, 8, ARM_EXT_MAVERICK
, do_c_binops_1
},
1323 {"cfmv64hr", 0xee000530, 8, ARM_EXT_MAVERICK
, do_c_binops_2
},
1324 {"cfmvr64h", 0xee100530, 8, ARM_EXT_MAVERICK
, do_c_binops_1
},
1325 {"cfmval32", 0xee100610, 8, ARM_EXT_MAVERICK
, do_c_binops_3
},
1326 {"cfmv32al", 0xee000610, 8, ARM_EXT_MAVERICK
, do_c_binops_3
},
1327 {"cfmvam32", 0xee100630, 8, ARM_EXT_MAVERICK
, do_c_binops_3
},
1328 {"cfmv32am", 0xee000630, 8, ARM_EXT_MAVERICK
, do_c_binops_3
},
1329 {"cfmvah32", 0xee100650, 8, ARM_EXT_MAVERICK
, do_c_binops_3
},
1330 {"cfmv32ah", 0xee000650, 8, ARM_EXT_MAVERICK
, do_c_binops_3
},
1331 {"cfmv32a", 0xee000670, 7, ARM_EXT_MAVERICK
, do_c_binops_3
},
1332 {"cfmva32", 0xee100670, 7, ARM_EXT_MAVERICK
, do_c_binops_3
},
1333 {"cfmv64a", 0xee000690, 7, ARM_EXT_MAVERICK
, do_c_binops_3
},
1334 {"cfmva64", 0xee100690, 7, ARM_EXT_MAVERICK
, do_c_binops_3
},
1335 {"cfmvsc32", 0xee1006b0, 8, ARM_EXT_MAVERICK
, do_c_dspsc_1
},
1336 {"cfmv32sc", 0xee0006b0, 8, ARM_EXT_MAVERICK
, do_c_dspsc_2
},
1337 {"cfcpys", 0xee000400, 6, ARM_EXT_MAVERICK
, do_c_binops_1
},
1338 {"cfcpyd", 0xee000420, 6, ARM_EXT_MAVERICK
, do_c_binops_1
},
1339 {"cfcvtsd", 0xee000460, 7, ARM_EXT_MAVERICK
, do_c_binops_1
},
1340 {"cfcvtds", 0xee000440, 7, ARM_EXT_MAVERICK
, do_c_binops_1
},
1341 {"cfcvt32s", 0xee000480, 8, ARM_EXT_MAVERICK
, do_c_binops_1
},
1342 {"cfcvt32d", 0xee0004a0, 8, ARM_EXT_MAVERICK
, do_c_binops_1
},
1343 {"cfcvt64s", 0xee0004c0, 8, ARM_EXT_MAVERICK
, do_c_binops_1
},
1344 {"cfcvt64d", 0xee0004e0, 8, ARM_EXT_MAVERICK
, do_c_binops_1
},
1345 {"cfcvts32", 0xee100580, 8, ARM_EXT_MAVERICK
, do_c_binops_1
},
1346 {"cfcvtd32", 0xee1005a0, 8, ARM_EXT_MAVERICK
, do_c_binops_1
},
1347 {"cftruncs32", 0xee1005c0, 10, ARM_EXT_MAVERICK
, do_c_binops_1
},
1348 {"cftruncd32", 0xee1005e0, 10, ARM_EXT_MAVERICK
, do_c_binops_1
},
1349 {"cfrshl32", 0xee000550, 8, ARM_EXT_MAVERICK
, do_c_triple_4
},
1350 {"cfrshl64", 0xee000570, 8, ARM_EXT_MAVERICK
, do_c_triple_4
},
1351 {"cfsh32", 0xee000500, 6, ARM_EXT_MAVERICK
, do_c_shift_1
},
1352 {"cfsh64", 0xee200500, 6, ARM_EXT_MAVERICK
, do_c_shift_2
},
1353 {"cfcmps", 0xee100490, 6, ARM_EXT_MAVERICK
, do_c_triple_5
},
1354 {"cfcmpd", 0xee1004b0, 6, ARM_EXT_MAVERICK
, do_c_triple_5
},
1355 {"cfcmp32", 0xee100590, 7, ARM_EXT_MAVERICK
, do_c_triple_5
},
1356 {"cfcmp64", 0xee1005b0, 7, ARM_EXT_MAVERICK
, do_c_triple_5
},
1357 {"cfabss", 0xee300400, 6, ARM_EXT_MAVERICK
, do_c_binops_1
},
1358 {"cfabsd", 0xee300420, 6, ARM_EXT_MAVERICK
, do_c_binops_1
},
1359 {"cfnegs", 0xee300440, 6, ARM_EXT_MAVERICK
, do_c_binops_1
},
1360 {"cfnegd", 0xee300460, 6, ARM_EXT_MAVERICK
, do_c_binops_1
},
1361 {"cfadds", 0xee300480, 6, ARM_EXT_MAVERICK
, do_c_triple_5
},
1362 {"cfaddd", 0xee3004a0, 6, ARM_EXT_MAVERICK
, do_c_triple_5
},
1363 {"cfsubs", 0xee3004c0, 6, ARM_EXT_MAVERICK
, do_c_triple_5
},
1364 {"cfsubd", 0xee3004e0, 6, ARM_EXT_MAVERICK
, do_c_triple_5
},
1365 {"cfmuls", 0xee100400, 6, ARM_EXT_MAVERICK
, do_c_triple_5
},
1366 {"cfmuld", 0xee100420, 6, ARM_EXT_MAVERICK
, do_c_triple_5
},
1367 {"cfabs32", 0xee300500, 7, ARM_EXT_MAVERICK
, do_c_binops_1
},
1368 {"cfabs64", 0xee300520, 7, ARM_EXT_MAVERICK
, do_c_binops_1
},
1369 {"cfneg32", 0xee300540, 7, ARM_EXT_MAVERICK
, do_c_binops_1
},
1370 {"cfneg64", 0xee300560, 7, ARM_EXT_MAVERICK
, do_c_binops_1
},
1371 {"cfadd32", 0xee300580, 7, ARM_EXT_MAVERICK
, do_c_triple_5
},
1372 {"cfadd64", 0xee3005a0, 7, ARM_EXT_MAVERICK
, do_c_triple_5
},
1373 {"cfsub32", 0xee3005c0, 7, ARM_EXT_MAVERICK
, do_c_triple_5
},
1374 {"cfsub64", 0xee3005e0, 7, ARM_EXT_MAVERICK
, do_c_triple_5
},
1375 {"cfmul32", 0xee100500, 7, ARM_EXT_MAVERICK
, do_c_triple_5
},
1376 {"cfmul64", 0xee100520, 7, ARM_EXT_MAVERICK
, do_c_triple_5
},
1377 {"cfmac32", 0xee100540, 7, ARM_EXT_MAVERICK
, do_c_triple_5
},
1378 {"cfmsc32", 0xee100560, 7, ARM_EXT_MAVERICK
, do_c_triple_5
},
1379 {"cfmadd32", 0xee000600, 8, ARM_EXT_MAVERICK
, do_c_quad_6
},
1380 {"cfmsub32", 0xee100600, 8, ARM_EXT_MAVERICK
, do_c_quad_6
},
1381 {"cfmadda32", 0xee200600, 9, ARM_EXT_MAVERICK
, do_c_quad_6
},
1382 {"cfmsuba32", 0xee300600, 9, ARM_EXT_MAVERICK
, do_c_quad_6
},
1385 /* Defines for various bits that we will want to toggle. */
1386 #define INST_IMMEDIATE 0x02000000
1387 #define OFFSET_REG 0x02000000
1388 #define HWOFFSET_IMM 0x00400000
1389 #define SHIFT_BY_REG 0x00000010
1390 #define PRE_INDEX 0x01000000
1391 #define INDEX_UP 0x00800000
1392 #define WRITE_BACK 0x00200000
1393 #define LDM_TYPE_2_OR_3 0x00400000
1395 #define LITERAL_MASK 0xf000f000
1396 #define OPCODE_MASK 0xfe1fffff
1397 #define V4_STR_BIT 0x00000020
1399 #define DATA_OP_SHIFT 21
1401 /* Codes to distinguish the arithmetic instructions. */
1402 #define OPCODE_AND 0
1403 #define OPCODE_EOR 1
1404 #define OPCODE_SUB 2
1405 #define OPCODE_RSB 3
1406 #define OPCODE_ADD 4
1407 #define OPCODE_ADC 5
1408 #define OPCODE_SBC 6
1409 #define OPCODE_RSC 7
1410 #define OPCODE_TST 8
1411 #define OPCODE_TEQ 9
1412 #define OPCODE_CMP 10
1413 #define OPCODE_CMN 11
1414 #define OPCODE_ORR 12
1415 #define OPCODE_MOV 13
1416 #define OPCODE_BIC 14
1417 #define OPCODE_MVN 15
1419 /* Thumb v1 (ARMv4T). */
1420 static void do_t_nop
PARAMS ((char *));
1421 static void do_t_arit
PARAMS ((char *));
1422 static void do_t_add
PARAMS ((char *));
1423 static void do_t_asr
PARAMS ((char *));
1424 static void do_t_branch9
PARAMS ((char *));
1425 static void do_t_branch12
PARAMS ((char *));
1426 static void do_t_branch23
PARAMS ((char *));
1427 static void do_t_bx
PARAMS ((char *));
1428 static void do_t_compare
PARAMS ((char *));
1429 static void do_t_ldmstm
PARAMS ((char *));
1430 static void do_t_ldr
PARAMS ((char *));
1431 static void do_t_ldrb
PARAMS ((char *));
1432 static void do_t_ldrh
PARAMS ((char *));
1433 static void do_t_lds
PARAMS ((char *));
1434 static void do_t_lsl
PARAMS ((char *));
1435 static void do_t_lsr
PARAMS ((char *));
1436 static void do_t_mov
PARAMS ((char *));
1437 static void do_t_push_pop
PARAMS ((char *));
1438 static void do_t_str
PARAMS ((char *));
1439 static void do_t_strb
PARAMS ((char *));
1440 static void do_t_strh
PARAMS ((char *));
1441 static void do_t_sub
PARAMS ((char *));
1442 static void do_t_swi
PARAMS ((char *));
1443 static void do_t_adr
PARAMS ((char *));
1445 /* Thumb v2 (ARMv5T). */
1446 static void do_t_blx
PARAMS ((char *));
1447 static void do_t_bkpt
PARAMS ((char *));
1449 #define T_OPCODE_MUL 0x4340
1450 #define T_OPCODE_TST 0x4200
1451 #define T_OPCODE_CMN 0x42c0
1452 #define T_OPCODE_NEG 0x4240
1453 #define T_OPCODE_MVN 0x43c0
1455 #define T_OPCODE_ADD_R3 0x1800
1456 #define T_OPCODE_SUB_R3 0x1a00
1457 #define T_OPCODE_ADD_HI 0x4400
1458 #define T_OPCODE_ADD_ST 0xb000
1459 #define T_OPCODE_SUB_ST 0xb080
1460 #define T_OPCODE_ADD_SP 0xa800
1461 #define T_OPCODE_ADD_PC 0xa000
1462 #define T_OPCODE_ADD_I8 0x3000
1463 #define T_OPCODE_SUB_I8 0x3800
1464 #define T_OPCODE_ADD_I3 0x1c00
1465 #define T_OPCODE_SUB_I3 0x1e00
1467 #define T_OPCODE_ASR_R 0x4100
1468 #define T_OPCODE_LSL_R 0x4080
1469 #define T_OPCODE_LSR_R 0x40c0
1470 #define T_OPCODE_ASR_I 0x1000
1471 #define T_OPCODE_LSL_I 0x0000
1472 #define T_OPCODE_LSR_I 0x0800
1474 #define T_OPCODE_MOV_I8 0x2000
1475 #define T_OPCODE_CMP_I8 0x2800
1476 #define T_OPCODE_CMP_LR 0x4280
1477 #define T_OPCODE_MOV_HR 0x4600
1478 #define T_OPCODE_CMP_HR 0x4500
1480 #define T_OPCODE_LDR_PC 0x4800
1481 #define T_OPCODE_LDR_SP 0x9800
1482 #define T_OPCODE_STR_SP 0x9000
1483 #define T_OPCODE_LDR_IW 0x6800
1484 #define T_OPCODE_STR_IW 0x6000
1485 #define T_OPCODE_LDR_IH 0x8800
1486 #define T_OPCODE_STR_IH 0x8000
1487 #define T_OPCODE_LDR_IB 0x7800
1488 #define T_OPCODE_STR_IB 0x7000
1489 #define T_OPCODE_LDR_RW 0x5800
1490 #define T_OPCODE_STR_RW 0x5000
1491 #define T_OPCODE_LDR_RH 0x5a00
1492 #define T_OPCODE_STR_RH 0x5200
1493 #define T_OPCODE_LDR_RB 0x5c00
1494 #define T_OPCODE_STR_RB 0x5400
1496 #define T_OPCODE_PUSH 0xb400
1497 #define T_OPCODE_POP 0xbc00
1499 #define T_OPCODE_BRANCH 0xe7fe
1501 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
1503 #define THUMB_SIZE 2 /* Size of thumb instruction. */
1504 #define THUMB_REG_LO 0x1
1505 #define THUMB_REG_HI 0x2
1506 #define THUMB_REG_ANY 0x3
1508 #define THUMB_H1 0x0080
1509 #define THUMB_H2 0x0040
1515 #define THUMB_MOVE 0
1516 #define THUMB_COMPARE 1
1518 #define THUMB_LOAD 0
1519 #define THUMB_STORE 1
1521 #define THUMB_PP_PC_LR 0x0100
1523 /* These three are used for immediate shifts, do not alter. */
1524 #define THUMB_WORD 2
1525 #define THUMB_HALFWORD 1
1526 #define THUMB_BYTE 0
1530 /* Basic string to match. */
1531 const char * template;
1533 /* Basic instruction code. */
1534 unsigned long value
;
1538 /* Which CPU variants this exists for. */
1539 unsigned long variant
;
1541 /* Function to call to parse args. */
1542 void (* parms
) PARAMS ((char *));
1545 static const struct thumb_opcode tinsns
[] =
1547 /* Thumb v1 (ARMv4T). */
1548 {"adc", 0x4140, 2, ARM_EXT_V4T
, do_t_arit
},
1549 {"add", 0x0000, 2, ARM_EXT_V4T
, do_t_add
},
1550 {"and", 0x4000, 2, ARM_EXT_V4T
, do_t_arit
},
1551 {"asr", 0x0000, 2, ARM_EXT_V4T
, do_t_asr
},
1552 {"b", T_OPCODE_BRANCH
, 2, ARM_EXT_V4T
, do_t_branch12
},
1553 {"beq", 0xd0fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1554 {"bne", 0xd1fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1555 {"bcs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1556 {"bhs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1557 {"bcc", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1558 {"bul", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1559 {"blo", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1560 {"bmi", 0xd4fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1561 {"bpl", 0xd5fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1562 {"bvs", 0xd6fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1563 {"bvc", 0xd7fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1564 {"bhi", 0xd8fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1565 {"bls", 0xd9fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1566 {"bge", 0xdafe, 2, ARM_EXT_V4T
, do_t_branch9
},
1567 {"blt", 0xdbfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1568 {"bgt", 0xdcfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1569 {"ble", 0xddfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1570 {"bal", 0xdefe, 2, ARM_EXT_V4T
, do_t_branch9
},
1571 {"bic", 0x4380, 2, ARM_EXT_V4T
, do_t_arit
},
1572 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T
, do_t_branch23
},
1573 {"bx", 0x4700, 2, ARM_EXT_V4T
, do_t_bx
},
1574 {"cmn", T_OPCODE_CMN
, 2, ARM_EXT_V4T
, do_t_arit
},
1575 {"cmp", 0x0000, 2, ARM_EXT_V4T
, do_t_compare
},
1576 {"eor", 0x4040, 2, ARM_EXT_V4T
, do_t_arit
},
1577 {"ldmia", 0xc800, 2, ARM_EXT_V4T
, do_t_ldmstm
},
1578 {"ldr", 0x0000, 2, ARM_EXT_V4T
, do_t_ldr
},
1579 {"ldrb", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrb
},
1580 {"ldrh", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrh
},
1581 {"ldrsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
1582 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
1583 {"ldsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
1584 {"ldsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
1585 {"lsl", 0x0000, 2, ARM_EXT_V4T
, do_t_lsl
},
1586 {"lsr", 0x0000, 2, ARM_EXT_V4T
, do_t_lsr
},
1587 {"mov", 0x0000, 2, ARM_EXT_V4T
, do_t_mov
},
1588 {"mul", T_OPCODE_MUL
, 2, ARM_EXT_V4T
, do_t_arit
},
1589 {"mvn", T_OPCODE_MVN
, 2, ARM_EXT_V4T
, do_t_arit
},
1590 {"neg", T_OPCODE_NEG
, 2, ARM_EXT_V4T
, do_t_arit
},
1591 {"orr", 0x4300, 2, ARM_EXT_V4T
, do_t_arit
},
1592 {"pop", 0xbc00, 2, ARM_EXT_V4T
, do_t_push_pop
},
1593 {"push", 0xb400, 2, ARM_EXT_V4T
, do_t_push_pop
},
1594 {"ror", 0x41c0, 2, ARM_EXT_V4T
, do_t_arit
},
1595 {"sbc", 0x4180, 2, ARM_EXT_V4T
, do_t_arit
},
1596 {"stmia", 0xc000, 2, ARM_EXT_V4T
, do_t_ldmstm
},
1597 {"str", 0x0000, 2, ARM_EXT_V4T
, do_t_str
},
1598 {"strb", 0x0000, 2, ARM_EXT_V4T
, do_t_strb
},
1599 {"strh", 0x0000, 2, ARM_EXT_V4T
, do_t_strh
},
1600 {"swi", 0xdf00, 2, ARM_EXT_V4T
, do_t_swi
},
1601 {"sub", 0x0000, 2, ARM_EXT_V4T
, do_t_sub
},
1602 {"tst", T_OPCODE_TST
, 2, ARM_EXT_V4T
, do_t_arit
},
1604 {"adr", 0x0000, 2, ARM_EXT_V4T
, do_t_adr
},
1605 {"nop", 0x46C0, 2, ARM_EXT_V4T
, do_t_nop
}, /* mov r8,r8 */
1606 /* Thumb v2 (ARMv5T). */
1607 {"blx", 0, 0, ARM_EXT_V5T
, do_t_blx
},
1608 {"bkpt", 0xbe00, 2, ARM_EXT_V5T
, do_t_bkpt
},
1617 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
1618 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
1619 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
1621 #define ARM_EXT_MAVERICKSC_REG 134
1623 #define cirrus_register(reg) ((reg) >= 50 && (reg) <= 134)
1624 #define cirrus_mvf_register(reg) ((reg) >= 50 && (reg) <= 65)
1625 #define cirrus_mvd_register(reg) ((reg) >= 70 && (reg) <= 85)
1626 #define cirrus_mvfx_register(reg) ((reg) >= 90 && (reg) <= 105)
1627 #define cirrus_mvdx_register(reg) ((reg) >= 110 && (reg) <= 125)
1628 #define cirrus_mvax_register(reg) ((reg) >= 130 && (reg) <= 133)
1629 #define ARM_EXT_MAVERICKsc_register(reg) ((reg) == ARM_EXT_MAVERICKSC_REG)
1635 /* These are the standard names. Users can add aliases with .req. */
1636 static const struct reg_entry reg_table
[] =
1638 /* Processor Register Numbers. */
1639 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
1640 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
1641 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
1642 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
1643 /* APCS conventions. */
1644 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
1645 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
1646 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
1647 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
1648 /* ATPCS additions to APCS conventions. */
1649 {"wr", 7}, {"v8", 11},
1651 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
1652 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
1653 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
1654 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
1655 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
1656 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
1657 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
1658 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
1659 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
1660 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1661 /* ATPCS additions to float register names. */
1662 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
1663 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
1664 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
1665 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
1666 /* Cirrus DSP coprocessor registers. */
1667 {"mvf0", 50}, {"mvf1", 51}, {"mvf2", 52}, {"mvf3", 53},
1668 {"mvf4", 54}, {"mvf5", 55}, {"mvf6", 56}, {"mvf7", 57},
1669 {"mvf8", 58}, {"mvf9", 59}, {"mvf10", 60}, {"mvf11", 61},
1670 {"mvf12", 62},{"mvf13", 63}, {"mvf14", 64}, {"mvf15", 65},
1671 {"mvd0", 70}, {"mvd1", 71}, {"mvd2", 72}, {"mvd3", 73},
1672 {"mvd4", 74}, {"mvd5", 75}, {"mvd6", 76}, {"mvd7", 77},
1673 {"mvd8", 78}, {"mvd9", 79}, {"mvd10", 80}, {"mvd11", 81},
1674 {"mvd12", 82},{"mvd13", 83}, {"mvd14", 84}, {"mvd15", 85},
1675 {"mvfx0", 90},{"mvfx1", 91}, {"mvfx2", 92}, {"mvfx3", 93},
1676 {"mvfx4", 94},{"mvfx5", 95}, {"mvfx6", 96}, {"mvfx7", 97},
1677 {"mvfx8", 98},{"mvfx9", 99}, {"mvfx10", 100},{"mvfx11", 101},
1678 {"mvfx12", 102},{"mvfx13", 103},{"mvfx14", 104},{"mvfx15", 105},
1679 {"mvdx0", 110}, {"mvdx1", 111}, {"mvdx2", 112}, {"mvdx3", 113},
1680 {"mvdx4", 114}, {"mvdx5", 115}, {"mvdx6", 116}, {"mvdx7", 117},
1681 {"mvdx8", 118}, {"mvdx9", 119}, {"mvdx10", 120},{"mvdx11", 121},
1682 {"mvdx12", 122},{"mvdx13", 123},{"mvdx14", 124},{"mvdx15", 125},
1683 {"mvax0", 130}, {"mvax1", 131}, {"mvax2", 132}, {"mvax3", 133},
1684 {"dspsc", ARM_EXT_MAVERICKSC_REG
},
1685 /* FIXME: At some point we need to add VFP register names. */
1686 /* Array terminator. */
1690 #define BAD_ARGS _("Bad arguments to instruction")
1691 #define BAD_PC _("r15 not allowed here")
1692 #define BAD_COND _("Instruction is not conditional")
1693 #define ERR_NO_ACCUM _("acc0 expected")
1695 static struct hash_control
* arm_ops_hsh
= NULL
;
1696 static struct hash_control
* arm_tops_hsh
= NULL
;
1697 static struct hash_control
* arm_cond_hsh
= NULL
;
1698 static struct hash_control
* arm_shift_hsh
= NULL
;
1699 static struct hash_control
* arm_reg_hsh
= NULL
;
1700 static struct hash_control
* arm_psr_hsh
= NULL
;
1702 /* This table describes all the machine specific pseudo-ops the assembler
1703 has to support. The fields are:
1704 pseudo-op name without dot
1705 function to call to execute this pseudo-op
1706 Integer arg to pass to the function. */
1708 static void s_req
PARAMS ((int));
1709 static void s_align
PARAMS ((int));
1710 static void s_bss
PARAMS ((int));
1711 static void s_even
PARAMS ((int));
1712 static void s_ltorg
PARAMS ((int));
1713 static void s_arm
PARAMS ((int));
1714 static void s_thumb
PARAMS ((int));
1715 static void s_code
PARAMS ((int));
1716 static void s_force_thumb
PARAMS ((int));
1717 static void s_thumb_func
PARAMS ((int));
1718 static void s_thumb_set
PARAMS ((int));
1719 static void arm_s_text
PARAMS ((int));
1720 static void arm_s_data
PARAMS ((int));
1722 static void arm_s_section
PARAMS ((int));
1723 static void s_arm_elf_cons
PARAMS ((int));
1726 static int my_get_expression
PARAMS ((expressionS
*, char **));
1728 const pseudo_typeS md_pseudo_table
[] =
1730 /* Never called becasue '.req' does not start line. */
1731 { "req", s_req
, 0 },
1732 { "bss", s_bss
, 0 },
1733 { "align", s_align
, 0 },
1734 { "arm", s_arm
, 0 },
1735 { "thumb", s_thumb
, 0 },
1736 { "code", s_code
, 0 },
1737 { "force_thumb", s_force_thumb
, 0 },
1738 { "thumb_func", s_thumb_func
, 0 },
1739 { "thumb_set", s_thumb_set
, 0 },
1740 { "even", s_even
, 0 },
1741 { "ltorg", s_ltorg
, 0 },
1742 { "pool", s_ltorg
, 0 },
1743 /* Allow for the effect of section changes. */
1744 { "text", arm_s_text
, 0 },
1745 { "data", arm_s_data
, 0 },
1747 { "section", arm_s_section
, 0 },
1748 { "section.s", arm_s_section
, 0 },
1749 { "sect", arm_s_section
, 0 },
1750 { "sect.s", arm_s_section
, 0 },
1751 { "word", s_arm_elf_cons
, 4 },
1752 { "long", s_arm_elf_cons
, 4 },
1753 { "file", dwarf2_directive_file
, 0 },
1754 { "loc", dwarf2_directive_loc
, 0 },
1758 { "extend", float_cons
, 'x' },
1759 { "ldouble", float_cons
, 'x' },
1760 { "packed", float_cons
, 'p' },
1764 /* Stuff needed to resolve the label ambiguity
1774 symbolS
* last_label_seen
;
1775 static int label_is_thumb_function_name
= false;
1777 /* Literal stuff. */
1779 #define MAX_LITERAL_POOL_SIZE 1024
1781 typedef struct literalS
1783 struct expressionS exp
;
1784 struct arm_it
* inst
;
1787 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1789 /* Next free entry in the pool. */
1790 int next_literal_pool_place
= 0;
1792 /* Next literal pool number. */
1793 int lit_pool_num
= 1;
1795 symbolS
* current_poolP
= NULL
;
1802 if (current_poolP
== NULL
)
1803 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1804 (valueT
) 0, &zero_address_frag
);
1806 /* Check if this literal value is already in the pool: */
1807 while (lit_count
< next_literal_pool_place
)
1809 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1810 && inst
.reloc
.exp
.X_op
== O_constant
1811 && (literals
[lit_count
].exp
.X_add_number
1812 == inst
.reloc
.exp
.X_add_number
)
1813 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1816 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1817 && inst
.reloc
.exp
.X_op
== O_symbol
1818 && (literals
[lit_count
].exp
.X_add_number
1819 == inst
.reloc
.exp
.X_add_number
)
1820 && (literals
[lit_count
].exp
.X_add_symbol
1821 == inst
.reloc
.exp
.X_add_symbol
)
1822 && (literals
[lit_count
].exp
.X_op_symbol
1823 == inst
.reloc
.exp
.X_op_symbol
))
1829 if (lit_count
== next_literal_pool_place
) /* New entry. */
1831 if (next_literal_pool_place
>= MAX_LITERAL_POOL_SIZE
)
1833 inst
.error
= _("Literal Pool Overflow");
1837 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1838 lit_count
= next_literal_pool_place
++;
1841 inst
.reloc
.exp
.X_op
= O_symbol
;
1842 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1843 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1848 /* Can't use symbol_new here, so have to create a symbol and then at
1849 a later date assign it a value. Thats what these functions do. */
1852 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1854 const char * name
; /* It is copied, the caller can modify. */
1855 segT segment
; /* Segment identifier (SEG_<something>). */
1856 valueT valu
; /* Symbol value. */
1857 fragS
* frag
; /* Associated fragment. */
1859 unsigned int name_length
;
1860 char * preserved_copy_of_name
;
1862 name_length
= strlen (name
) + 1; /* +1 for \0. */
1863 obstack_grow (¬es
, name
, name_length
);
1864 preserved_copy_of_name
= obstack_finish (¬es
);
1865 #ifdef STRIP_UNDERSCORE
1866 if (preserved_copy_of_name
[0] == '_')
1867 preserved_copy_of_name
++;
1870 #ifdef tc_canonicalize_symbol_name
1871 preserved_copy_of_name
=
1872 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1875 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1877 S_SET_SEGMENT (symbolP
, segment
);
1878 S_SET_VALUE (symbolP
, valu
);
1879 symbol_clear_list_pointers(symbolP
);
1881 symbol_set_frag (symbolP
, frag
);
1883 /* Link to end of symbol chain. */
1885 extern int symbol_table_frozen
;
1886 if (symbol_table_frozen
)
1890 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1892 obj_symbol_new_hook (symbolP
);
1894 #ifdef tc_symbol_new_hook
1895 tc_symbol_new_hook (symbolP
);
1899 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1900 #endif /* DEBUG_SYMS */
1903 /* Check that an immediate is valid.
1904 If so, convert it to the right format. */
1907 validate_immediate (val
)
1913 #define rotate_left(v, n) (v << n | v >> (32 - n))
1915 for (i
= 0; i
< 32; i
+= 2)
1916 if ((a
= rotate_left (val
, i
)) <= 0xff)
1917 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
1922 /* Check to see if an immediate can be computed as two seperate immediate
1923 values, added together. We already know that this value cannot be
1924 computed by just one ARM instruction. */
1927 validate_immediate_twopart (val
, highpart
)
1929 unsigned int * highpart
;
1934 for (i
= 0; i
< 32; i
+= 2)
1935 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1941 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1943 else if (a
& 0xff0000)
1947 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1951 assert (a
& 0xff000000);
1952 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1955 return (a
& 0xff) | (i
<< 7);
1962 validate_offset_imm (val
, hwse
)
1966 if ((hwse
&& val
> 255) || val
> 4095)
1973 int a ATTRIBUTE_UNUSED
;
1975 as_bad (_("Invalid syntax for .req directive."));
1980 int ignore ATTRIBUTE_UNUSED
;
1982 /* We don't support putting frags in the BSS segment, we fake it by
1983 marking in_bss, then looking at s_skip for clues. */
1984 subseg_set (bss_section
, 0);
1985 demand_empty_rest_of_line ();
1990 int ignore ATTRIBUTE_UNUSED
;
1992 /* Never make frag if expect extra pass. */
1994 frag_align (1, 0, 0);
1996 record_alignment (now_seg
, 1);
1998 demand_empty_rest_of_line ();
2003 int ignored ATTRIBUTE_UNUSED
;
2008 if (current_poolP
== NULL
)
2011 /* Align pool as you have word accesses.
2012 Only make a frag if we have to. */
2014 frag_align (2, 0, 0);
2016 record_alignment (now_seg
, 2);
2018 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
2020 symbol_locate (current_poolP
, sym_name
, now_seg
,
2021 (valueT
) frag_now_fix (), frag_now
);
2022 symbol_table_insert (current_poolP
);
2024 ARM_SET_THUMB (current_poolP
, thumb_mode
);
2026 #if defined OBJ_COFF || defined OBJ_ELF
2027 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
2030 while (lit_count
< next_literal_pool_place
)
2031 /* First output the expression in the instruction to the pool. */
2032 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
2034 next_literal_pool_place
= 0;
2035 current_poolP
= NULL
;
2038 /* Same as s_align_ptwo but align 0 => align 2. */
2042 int unused ATTRIBUTE_UNUSED
;
2045 register long temp_fill
;
2046 long max_alignment
= 15;
2048 temp
= get_absolute_expression ();
2049 if (temp
> max_alignment
)
2050 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
2053 as_bad (_("Alignment negative. 0 assumed."));
2057 if (*input_line_pointer
== ',')
2059 input_line_pointer
++;
2060 temp_fill
= get_absolute_expression ();
2068 /* Only make a frag if we HAVE to. */
2069 if (temp
&& !need_pass_2
)
2070 frag_align (temp
, (int) temp_fill
, 0);
2071 demand_empty_rest_of_line ();
2073 record_alignment (now_seg
, temp
);
2077 s_force_thumb (ignore
)
2078 int ignore ATTRIBUTE_UNUSED
;
2080 /* If we are not already in thumb mode go into it, EVEN if
2081 the target processor does not support thumb instructions.
2082 This is used by gcc/config/arm/lib1funcs.asm for example
2083 to compile interworking support functions even if the
2084 target processor should not support interworking. */
2089 record_alignment (now_seg
, 1);
2092 demand_empty_rest_of_line ();
2096 s_thumb_func (ignore
)
2097 int ignore ATTRIBUTE_UNUSED
;
2102 /* The following label is the name/address of the start of a Thumb function.
2103 We need to know this for the interworking support. */
2104 label_is_thumb_function_name
= true;
2106 demand_empty_rest_of_line ();
2109 /* Perform a .set directive, but also mark the alias as
2110 being a thumb function. */
2116 /* XXX the following is a duplicate of the code for s_set() in read.c
2117 We cannot just call that code as we need to get at the symbol that
2119 register char * name
;
2120 register char delim
;
2121 register char * end_name
;
2122 register symbolS
* symbolP
;
2124 /* Especial apologies for the random logic:
2125 This just grew, and could be parsed much more simply!
2127 name
= input_line_pointer
;
2128 delim
= get_symbol_end ();
2129 end_name
= input_line_pointer
;
2134 if (*input_line_pointer
!= ',')
2137 as_bad (_("Expected comma after name \"%s\""), name
);
2139 ignore_rest_of_line ();
2143 input_line_pointer
++;
2146 if (name
[0] == '.' && name
[1] == '\0')
2148 /* XXX - this should not happen to .thumb_set. */
2152 if ((symbolP
= symbol_find (name
)) == NULL
2153 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
2156 /* When doing symbol listings, play games with dummy fragments living
2157 outside the normal fragment chain to record the file and line info
2159 if (listing
& LISTING_SYMBOLS
)
2161 extern struct list_info_struct
* listing_tail
;
2162 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
2164 memset (dummy_frag
, 0, sizeof (fragS
));
2165 dummy_frag
->fr_type
= rs_fill
;
2166 dummy_frag
->line
= listing_tail
;
2167 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
2168 dummy_frag
->fr_symbol
= symbolP
;
2172 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
2175 /* "set" symbols are local unless otherwise specified. */
2176 SF_SET_LOCAL (symbolP
);
2177 #endif /* OBJ_COFF */
2178 } /* Make a new symbol. */
2180 symbol_table_insert (symbolP
);
2185 && S_IS_DEFINED (symbolP
)
2186 && S_GET_SEGMENT (symbolP
) != reg_section
)
2187 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
2189 pseudo_set (symbolP
);
2191 demand_empty_rest_of_line ();
2193 /* XXX Now we come to the Thumb specific bit of code. */
2195 THUMB_SET_FUNC (symbolP
, 1);
2196 ARM_SET_THUMB (symbolP
, 1);
2197 #if defined OBJ_ELF || defined OBJ_COFF
2198 ARM_SET_INTERWORK (symbolP
, support_interwork
);
2202 /* If we change section we must dump the literal pool first. */
2208 if (now_seg
!= text_section
)
2212 obj_elf_text (ignore
);
2222 if (flag_readonly_data_in_text
)
2224 if (now_seg
!= text_section
)
2227 else if (now_seg
!= data_section
)
2231 obj_elf_data (ignore
);
2239 arm_s_section (ignore
)
2244 obj_elf_section (ignore
);
2249 opcode_select (width
)
2257 if (! (cpu_variant
& ARM_EXT_V4T
))
2258 as_bad (_("selected processor does not support THUMB opcodes"));
2261 /* No need to force the alignment, since we will have been
2262 coming from ARM mode, which is word-aligned. */
2263 record_alignment (now_seg
, 1);
2270 if ((cpu_variant
& ARM_ANY
) == ARM_EXT_V4T
)
2271 as_bad (_("selected processor does not support ARM opcodes"));
2276 frag_align (2, 0, 0);
2278 record_alignment (now_seg
, 1);
2283 as_bad (_("invalid instruction size selected (%d)"), width
);
2289 int ignore ATTRIBUTE_UNUSED
;
2292 demand_empty_rest_of_line ();
2297 int ignore ATTRIBUTE_UNUSED
;
2300 demand_empty_rest_of_line ();
2305 int unused ATTRIBUTE_UNUSED
;
2309 temp
= get_absolute_expression ();
2314 opcode_select (temp
);
2318 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
2326 skip_whitespace (str
);
2329 inst
.error
= _("Garbage following instruction");
2333 skip_past_comma (str
)
2336 char * p
= * str
, c
;
2339 while ((c
= *p
) == ' ' || c
== ',')
2342 if (c
== ',' && comma
++)
2350 return comma
? SUCCESS
: FAIL
;
2353 /* A standard register must be given at this point.
2354 SHIFT is the place to put it in inst.instruction.
2355 Restores input start point on error.
2356 Returns the reg#, or FAIL. */
2359 reg_required_here (str
, shift
)
2363 static char buff
[128]; /* XXX */
2365 char * start
= * str
;
2367 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
2370 inst
.instruction
|= reg
<< shift
;
2374 /* Restore the start point, we may have got a reg of the wrong class. */
2377 /* In the few cases where we might be able to accept something else
2378 this error can be overridden. */
2379 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
2385 static const struct asm_psr
*
2387 register char ** ccp
;
2389 char * start
= * ccp
;
2392 const struct asm_psr
* psr
;
2396 /* Skip to the end of the next word in the input stream. */
2401 while (ISALPHA (c
) || c
== '_');
2403 /* Terminate the word. */
2406 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
2407 feature for ease of use and backwards compatibility. */
2408 if (!strncmp (start
, "cpsr", 4))
2409 strncpy (start
, "CPSR", 4);
2410 else if (!strncmp (start
, "spsr", 4))
2411 strncpy (start
, "SPSR", 4);
2413 /* Now locate the word in the psr hash table. */
2414 psr
= (const struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
2416 /* Restore the input stream. */
2419 /* If we found a valid match, advance the
2420 stream pointer past the end of the word. */
2426 /* Parse the input looking for a PSR flag. */
2429 psr_required_here (str
)
2432 char * start
= * str
;
2433 const struct asm_psr
* psr
;
2435 psr
= arm_psr_parse (str
);
2439 /* If this is the SPSR that is being modified, set the R bit. */
2441 inst
.instruction
|= SPSR_BIT
;
2443 /* Set the psr flags in the MSR instruction. */
2444 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
2449 /* In the few cases where we might be able to accept
2450 something else this error can be overridden. */
2451 inst
.error
= _("flag for {c}psr instruction expected");
2453 /* Restore the start point. */
2459 co_proc_number (str
)
2462 int processor
, pchar
;
2464 skip_whitespace (* str
);
2466 /* The data sheet seems to imply that just a number on its own is valid
2467 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
2469 if (**str
== 'p' || **str
== 'P')
2473 if (pchar
>= '0' && pchar
<= '9')
2475 processor
= pchar
- '0';
2476 if (**str
>= '0' && **str
<= '9')
2478 processor
= processor
* 10 + *(*str
)++ - '0';
2481 inst
.error
= _("Illegal co-processor number");
2488 inst
.error
= _("Bad or missing co-processor number");
2492 inst
.instruction
|= processor
<< 8;
2497 cp_opc_expr (str
, where
, length
)
2504 skip_whitespace (* str
);
2506 memset (&expr
, '\0', sizeof (expr
));
2508 if (my_get_expression (&expr
, str
))
2510 if (expr
.X_op
!= O_constant
)
2512 inst
.error
= _("bad or missing expression");
2516 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
2518 inst
.error
= _("immediate co-processor expression too large");
2522 inst
.instruction
|= expr
.X_add_number
<< where
;
2527 cp_reg_required_here (str
, where
)
2532 char * start
= *str
;
2534 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
2537 inst
.instruction
|= reg
<< where
;
2541 /* In the few cases where we might be able to accept something else
2542 this error can be overridden. */
2543 inst
.error
= _("Co-processor register expected");
2545 /* Restore the start point. */
2551 fp_reg_required_here (str
, where
)
2556 char * start
= * str
;
2558 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
2561 inst
.instruction
|= reg
<< where
;
2565 /* In the few cases where we might be able to accept something else
2566 this error can be overridden. */
2567 inst
.error
= _("Floating point register expected");
2569 /* Restore the start point. */
2575 cp_address_offset (str
)
2580 skip_whitespace (* str
);
2582 if (! is_immediate_prefix (**str
))
2584 inst
.error
= _("immediate expression expected");
2590 if (my_get_expression (& inst
.reloc
.exp
, str
))
2593 if (inst
.reloc
.exp
.X_op
== O_constant
)
2595 offset
= inst
.reloc
.exp
.X_add_number
;
2599 inst
.error
= _("co-processor address must be word aligned");
2603 if (offset
> 1023 || offset
< -1023)
2605 inst
.error
= _("offset too large");
2610 inst
.instruction
|= INDEX_UP
;
2614 inst
.instruction
|= offset
>> 2;
2617 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2623 cp_address_required_here (str
)
2635 skip_whitespace (p
);
2637 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
2640 skip_whitespace (p
);
2646 if (skip_past_comma (& p
) == SUCCESS
)
2649 write_back
= WRITE_BACK
;
2653 inst
.error
= _("pc may not be used in post-increment");
2657 if (cp_address_offset (& p
) == FAIL
)
2661 pre_inc
= PRE_INDEX
| INDEX_UP
;
2665 /* '['Rn, #expr']'[!] */
2667 if (skip_past_comma (& p
) == FAIL
)
2669 inst
.error
= _("pre-indexed expression expected");
2673 pre_inc
= PRE_INDEX
;
2675 if (cp_address_offset (& p
) == FAIL
)
2678 skip_whitespace (p
);
2682 inst
.error
= _("missing ]");
2686 skip_whitespace (p
);
2692 inst
.error
= _("pc may not be used with write-back");
2697 write_back
= WRITE_BACK
;
2703 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2706 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2707 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2708 inst
.reloc
.pc_rel
= 1;
2709 inst
.instruction
|= (REG_PC
<< 16);
2710 pre_inc
= PRE_INDEX
;
2713 inst
.instruction
|= write_back
| pre_inc
;
2722 /* Do nothing really. */
2733 /* Only one syntax. */
2734 skip_whitespace (str
);
2736 if (reg_required_here (&str
, 12) == FAIL
)
2738 inst
.error
= BAD_ARGS
;
2742 if (skip_past_comma (&str
) == FAIL
)
2744 inst
.error
= _("comma expected after register name");
2748 skip_whitespace (str
);
2750 if ( strcmp (str
, "CPSR") == 0
2751 || strcmp (str
, "SPSR") == 0
2752 /* Lower case versions for backwards compatability. */
2753 || strcmp (str
, "cpsr") == 0
2754 || strcmp (str
, "spsr") == 0)
2757 /* This is for backwards compatability with older toolchains. */
2758 else if ( strcmp (str
, "cpsr_all") == 0
2759 || strcmp (str
, "spsr_all") == 0)
2763 inst
.error
= _("{C|S}PSR expected");
2767 if (* str
== 's' || * str
== 'S')
2768 inst
.instruction
|= SPSR_BIT
;
2774 /* Two possible forms:
2775 "{C|S}PSR_<field>, Rm",
2776 "{C|S}PSR_f, #expression". */
2782 skip_whitespace (str
);
2784 if (psr_required_here (& str
) == FAIL
)
2787 if (skip_past_comma (& str
) == FAIL
)
2789 inst
.error
= _("comma missing after psr flags");
2793 skip_whitespace (str
);
2795 if (reg_required_here (& str
, 0) != FAIL
)
2802 if (! is_immediate_prefix (* str
))
2805 _("only a register or immediate value can follow a psr flag");
2812 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2815 _("only a register or immediate value can follow a psr flag");
2819 #if 0 /* The first edition of the ARM architecture manual stated that
2820 writing anything other than the flags with an immediate operation
2821 had UNPREDICTABLE effects. This constraint was removed in the
2822 second edition of the specification. */
2823 if ((cpu_variant
& ARM_EXT_V5
) != ARM_EXT_V5
2824 && inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2826 inst
.error
= _("immediate value cannot be used to set this field");
2831 inst
.instruction
|= INST_IMMEDIATE
;
2833 if (inst
.reloc
.exp
.X_add_symbol
)
2835 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2836 inst
.reloc
.pc_rel
= 0;
2840 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2842 if (value
== (unsigned) FAIL
)
2844 inst
.error
= _("Invalid constant");
2848 inst
.instruction
|= value
;
2855 /* Long Multiply Parser
2856 UMULL RdLo, RdHi, Rm, Rs
2857 SMULL RdLo, RdHi, Rm, Rs
2858 UMLAL RdLo, RdHi, Rm, Rs
2859 SMLAL RdLo, RdHi, Rm, Rs. */
2865 int rdlo
, rdhi
, rm
, rs
;
2867 /* Only one format "rdlo, rdhi, rm, rs". */
2868 skip_whitespace (str
);
2870 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2872 inst
.error
= BAD_ARGS
;
2876 if (skip_past_comma (&str
) == FAIL
2877 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2879 inst
.error
= BAD_ARGS
;
2883 if (skip_past_comma (&str
) == FAIL
2884 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2886 inst
.error
= BAD_ARGS
;
2890 /* rdhi, rdlo and rm must all be different. */
2891 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2892 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2894 if (skip_past_comma (&str
) == FAIL
2895 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2897 inst
.error
= BAD_ARGS
;
2901 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2903 inst
.error
= BAD_PC
;
2917 /* Only one format "rd, rm, rs". */
2918 skip_whitespace (str
);
2920 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2922 inst
.error
= BAD_ARGS
;
2928 inst
.error
= BAD_PC
;
2932 if (skip_past_comma (&str
) == FAIL
2933 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2935 inst
.error
= BAD_ARGS
;
2941 inst
.error
= BAD_PC
;
2946 as_tsktsk (_("rd and rm should be different in mul"));
2948 if (skip_past_comma (&str
) == FAIL
2949 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2951 inst
.error
= BAD_ARGS
;
2957 inst
.error
= BAD_PC
;
2971 /* Only one format "rd, rm, rs, rn". */
2972 skip_whitespace (str
);
2974 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2976 inst
.error
= BAD_ARGS
;
2982 inst
.error
= BAD_PC
;
2986 if (skip_past_comma (&str
) == FAIL
2987 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2989 inst
.error
= BAD_ARGS
;
2995 inst
.error
= BAD_PC
;
3000 as_tsktsk (_("rd and rm should be different in mla"));
3002 if (skip_past_comma (&str
) == FAIL
3003 || (rd
= reg_required_here (&str
, 8)) == FAIL
3004 || skip_past_comma (&str
) == FAIL
3005 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
3007 inst
.error
= BAD_ARGS
;
3011 if (rd
== REG_PC
|| rm
== REG_PC
)
3013 inst
.error
= BAD_PC
;
3021 /* Expects *str -> the characters "acc0", possibly with leading blanks.
3022 Advances *str to the next non-alphanumeric.
3023 Returns 0, or else FAIL (in which case sets inst.error).
3025 (In a future XScale, there may be accumulators other than zero.
3026 At that time this routine and its callers can be upgraded to suit.) */
3029 accum0_required_here (str
)
3032 static char buff
[128]; /* Note the address is taken. Hence, static. */
3035 int result
= 0; /* The accum number. */
3037 skip_whitespace (p
);
3039 *str
= p
; /* Advance caller's string pointer too. */
3044 *--p
= 0; /* Aap nul into input buffer at non-alnum. */
3046 if (! ( streq (*str
, "acc0") || streq (*str
, "ACC0")))
3048 sprintf (buff
, _("acc0 expected, not '%.100s'"), *str
);
3053 *p
= c
; /* Unzap. */
3054 *str
= p
; /* Caller's string pointer to after match. */
3058 /* Expects **str -> after a comma. May be leading blanks.
3059 Advances *str, recognizing a load mode, and setting inst.instruction.
3060 Returns rn, or else FAIL (in which case may set inst.error
3061 and not advance str)
3063 Note: doesn't know Rd, so no err checks that require such knowledge. */
3066 ld_mode_required_here (string
)
3069 char * str
= * string
;
3073 skip_whitespace (str
);
3079 skip_whitespace (str
);
3081 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
3084 skip_whitespace (str
);
3090 if (skip_past_comma (& str
) == SUCCESS
)
3092 /* [Rn],... (post inc) */
3093 if (ldst_extend_v4 (&str
) == FAIL
)
3098 skip_whitespace (str
);
3103 inst
.instruction
|= WRITE_BACK
;
3106 inst
.instruction
|= INDEX_UP
| HWOFFSET_IMM
;
3112 if (skip_past_comma (& str
) == FAIL
)
3114 inst
.error
= _("pre-indexed expression expected");
3120 if (ldst_extend_v4 (&str
) == FAIL
)
3123 skip_whitespace (str
);
3125 if (* str
++ != ']')
3127 inst
.error
= _("missing ]");
3131 skip_whitespace (str
);
3136 inst
.instruction
|= WRITE_BACK
;
3140 else if (* str
== '=') /* ldr's "r,=label" syntax */
3141 /* We should never reach here, because <text> = <expression> is
3142 caught gas/read.c read_a_source_file() as a .set operation. */
3144 else /* PC +- 8 bit immediate offset. */
3146 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3149 inst
.instruction
|= HWOFFSET_IMM
; /* The I bit. */
3150 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3151 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
3152 inst
.reloc
.pc_rel
= 1;
3153 inst
.instruction
|= (REG_PC
<< 16);
3159 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
3165 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3166 SMLAxy{cond} Rd,Rm,Rs,Rn
3167 SMLAWy{cond} Rd,Rm,Rs,Rn
3168 Error if any register is R15. */
3176 skip_whitespace (str
);
3178 if ((rd
= reg_required_here (& str
, 16)) == FAIL
3179 || skip_past_comma (& str
) == FAIL
3180 || (rm
= reg_required_here (& str
, 0)) == FAIL
3181 || skip_past_comma (& str
) == FAIL
3182 || (rs
= reg_required_here (& str
, 8)) == FAIL
3183 || skip_past_comma (& str
) == FAIL
3184 || (rn
= reg_required_here (& str
, 12)) == FAIL
)
3185 inst
.error
= BAD_ARGS
;
3187 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
|| rn
== REG_PC
)
3188 inst
.error
= BAD_PC
;
3194 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3195 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3196 Error if any register is R15.
3197 Warning if Rdlo == Rdhi. */
3203 int rdlo
, rdhi
, rm
, rs
;
3205 skip_whitespace (str
);
3207 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
3208 || skip_past_comma (& str
) == FAIL
3209 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
3210 || skip_past_comma (& str
) == FAIL
3211 || (rm
= reg_required_here (& str
, 0)) == FAIL
3212 || skip_past_comma (& str
) == FAIL
3213 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
3215 inst
.error
= BAD_ARGS
;
3219 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
3221 inst
.error
= BAD_PC
;
3226 as_tsktsk (_("rdhi and rdlo must be different"));
3231 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3232 SMULxy{cond} Rd,Rm,Rs
3233 Error if any register is R15. */
3241 skip_whitespace (str
);
3243 if ((rd
= reg_required_here (& str
, 16)) == FAIL
3244 || skip_past_comma (& str
) == FAIL
3245 || (rm
= reg_required_here (& str
, 0)) == FAIL
3246 || skip_past_comma (& str
) == FAIL
3247 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
3248 inst
.error
= BAD_ARGS
;
3250 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
3251 inst
.error
= BAD_PC
;
3257 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3258 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3259 Error if any register is R15. */
3267 skip_whitespace (str
);
3269 if ((rd
= reg_required_here (& str
, 12)) == FAIL
3270 || skip_past_comma (& str
) == FAIL
3271 || (rm
= reg_required_here (& str
, 0)) == FAIL
3272 || skip_past_comma (& str
) == FAIL
3273 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
3274 inst
.error
= BAD_ARGS
;
3276 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
3277 inst
.error
= BAD_PC
;
3283 /* ARM V5E (el Segundo)
3284 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3285 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3287 These are equivalent to the XScale instructions MAR and MRA,
3288 respectively, when coproc == 0, opcode == 0, and CRm == 0.
3290 Result unpredicatable if Rd or Rn is R15. */
3298 skip_whitespace (str
);
3300 if (co_proc_number (& str
) == FAIL
)
3303 inst
.error
= BAD_ARGS
;
3307 if (skip_past_comma (& str
) == FAIL
3308 || cp_opc_expr (& str
, 4, 4) == FAIL
)
3311 inst
.error
= BAD_ARGS
;
3315 if (skip_past_comma (& str
) == FAIL
3316 || (rd
= reg_required_here (& str
, 12)) == FAIL
)
3319 inst
.error
= BAD_ARGS
;
3323 if (skip_past_comma (& str
) == FAIL
3324 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
3327 inst
.error
= BAD_ARGS
;
3331 /* Unpredictable result if rd or rn is R15. */
3332 if (rd
== REG_PC
|| rn
== REG_PC
)
3334 (_("Warning: Instruction unpredictable when using r15"));
3336 if (skip_past_comma (& str
) == FAIL
3337 || cp_reg_required_here (& str
, 0) == FAIL
)
3340 inst
.error
= BAD_ARGS
;
3347 /* ARM V5 count-leading-zeroes instruction (argument parse)
3348 CLZ{<cond>} <Rd>, <Rm>
3349 Condition defaults to COND_ALWAYS.
3350 Error if Rd or Rm are R15. */
3358 skip_whitespace (str
);
3360 if (((rd
= reg_required_here (& str
, 12)) == FAIL
)
3361 || (skip_past_comma (& str
) == FAIL
)
3362 || ((rm
= reg_required_here (& str
, 0)) == FAIL
))
3363 inst
.error
= BAD_ARGS
;
3365 else if (rd
== REG_PC
|| rm
== REG_PC
)
3366 inst
.error
= BAD_PC
;
3372 /* ARM V5 (argument parse)
3373 LDC2{L} <coproc>, <CRd>, <addressing mode>
3374 STC2{L} <coproc>, <CRd>, <addressing mode>
3375 Instruction is not conditional, and has 0xf in the codition field.
3376 Otherwise, it's the same as LDC/STC. */
3382 skip_whitespace (str
);
3384 if (co_proc_number (& str
) == FAIL
)
3387 inst
.error
= BAD_ARGS
;
3389 else if (skip_past_comma (& str
) == FAIL
3390 || cp_reg_required_here (& str
, 12) == FAIL
)
3393 inst
.error
= BAD_ARGS
;
3395 else if (skip_past_comma (& str
) == FAIL
3396 || cp_address_required_here (& str
) == FAIL
)
3399 inst
.error
= BAD_ARGS
;
3405 /* ARM V5 (argument parse)
3406 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3407 Instruction is not conditional, and has 0xf in the condition field.
3408 Otherwise, it's the same as CDP. */
3414 skip_whitespace (str
);
3416 if (co_proc_number (& str
) == FAIL
)
3419 inst
.error
= BAD_ARGS
;
3423 if (skip_past_comma (& str
) == FAIL
3424 || cp_opc_expr (& str
, 20,4) == FAIL
)
3427 inst
.error
= BAD_ARGS
;
3431 if (skip_past_comma (& str
) == FAIL
3432 || cp_reg_required_here (& str
, 12) == FAIL
)
3435 inst
.error
= BAD_ARGS
;
3439 if (skip_past_comma (& str
) == FAIL
3440 || cp_reg_required_here (& str
, 16) == FAIL
)
3443 inst
.error
= BAD_ARGS
;
3447 if (skip_past_comma (& str
) == FAIL
3448 || cp_reg_required_here (& str
, 0) == FAIL
)
3451 inst
.error
= BAD_ARGS
;
3455 if (skip_past_comma (& str
) == SUCCESS
)
3457 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3460 inst
.error
= BAD_ARGS
;
3468 /* ARM V5 (argument parse)
3469 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3470 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3471 Instruction is not conditional, and has 0xf in the condition field.
3472 Otherwise, it's the same as MCR/MRC. */
3478 skip_whitespace (str
);
3480 if (co_proc_number (& str
) == FAIL
)
3483 inst
.error
= BAD_ARGS
;
3487 if (skip_past_comma (& str
) == FAIL
3488 || cp_opc_expr (& str
, 21, 3) == FAIL
)
3491 inst
.error
= BAD_ARGS
;
3495 if (skip_past_comma (& str
) == FAIL
3496 || reg_required_here (& str
, 12) == FAIL
)
3499 inst
.error
= BAD_ARGS
;
3503 if (skip_past_comma (& str
) == FAIL
3504 || cp_reg_required_here (& str
, 16) == FAIL
)
3507 inst
.error
= BAD_ARGS
;
3511 if (skip_past_comma (& str
) == FAIL
3512 || cp_reg_required_here (& str
, 0) == FAIL
)
3515 inst
.error
= BAD_ARGS
;
3519 if (skip_past_comma (& str
) == SUCCESS
)
3521 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3524 inst
.error
= BAD_ARGS
;
3532 /* THUMB V5 breakpoint instruction (argument parse)
3540 unsigned long number
;
3542 skip_whitespace (str
);
3544 /* Allow optional leading '#'. */
3545 if (is_immediate_prefix (*str
))
3548 memset (& expr
, '\0', sizeof (expr
));
3549 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3551 inst
.error
= _("bad or missing expression");
3555 number
= expr
.X_add_number
;
3557 /* Check it fits an 8 bit unsigned. */
3558 if (number
!= (number
& 0xff))
3560 inst
.error
= _("immediate value out of range");
3564 inst
.instruction
|= number
;
3569 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3570 Expects inst.instruction is set for BLX(1).
3571 Note: this is cloned from do_branch, and the reloc changed to be a
3572 new one that can cope with setting one extra bit (the H bit). */
3578 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3585 /* ScottB: February 5, 1998 */
3586 /* Check to see of PLT32 reloc required for the instruction. */
3588 /* arm_parse_reloc() works on input_line_pointer.
3589 We actually want to parse the operands to the branch instruction
3590 passed in 'str'. Save the input pointer and restore it later. */
3591 save_in
= input_line_pointer
;
3592 input_line_pointer
= str
;
3594 if (inst
.reloc
.exp
.X_op
== O_symbol
3596 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3598 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3599 inst
.reloc
.pc_rel
= 0;
3600 /* Modify str to point to after parsed operands, otherwise
3601 end_of_line() will complain about the (PLT) left in str. */
3602 str
= input_line_pointer
;
3606 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3607 inst
.reloc
.pc_rel
= 1;
3610 input_line_pointer
= save_in
;
3613 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3614 inst
.reloc
.pc_rel
= 1;
3615 #endif /* OBJ_ELF */
3620 /* ARM V5 branch-link-exchange instruction (argument parse)
3621 BLX <target_addr> ie BLX(1)
3622 BLX{<condition>} <Rm> ie BLX(2)
3623 Unfortunately, there are two different opcodes for this mnemonic.
3624 So, the insns[].value is not used, and the code here zaps values
3625 into inst.instruction.
3626 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
3635 skip_whitespace (mystr
);
3636 rm
= reg_required_here (& mystr
, 0);
3638 /* The above may set inst.error. Ignore his opinion. */
3643 /* Arg is a register.
3644 Use the condition code our caller put in inst.instruction.
3645 Pass ourselves off as a BX with a funny opcode. */
3646 inst
.instruction
|= 0x012fff30;
3651 /* This must be is BLX <target address>, no condition allowed. */
3652 if (inst
.instruction
!= COND_ALWAYS
)
3654 inst
.error
= BAD_COND
;
3658 inst
.instruction
= 0xfafffffe;
3660 /* Process like a B/BL, but with a different reloc.
3661 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
3666 /* ARM V5 Thumb BLX (argument parse)
3667 BLX <target_addr> which is BLX(1)
3668 BLX <Rm> which is BLX(2)
3669 Unfortunately, there are two different opcodes for this mnemonic.
3670 So, the tinsns[].value is not used, and the code here zaps values
3671 into inst.instruction. */
3680 skip_whitespace (mystr
);
3681 inst
.instruction
= 0x4780;
3683 /* Note that this call is to the ARM register recognizer. BLX(2)
3684 uses the ARM register space, not the Thumb one, so a call to
3685 thumb_reg() would be wrong. */
3686 rm
= reg_required_here (& mystr
, 3);
3691 /* It's BLX(2). The .instruction was zapped with rm & is final. */
3696 /* No ARM register. This must be BLX(1). Change the .instruction. */
3697 inst
.instruction
= 0xf7ffeffe;
3700 if (my_get_expression (& inst
.reloc
.exp
, & mystr
))
3703 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BLX
;
3704 inst
.reloc
.pc_rel
= 1;
3707 end_of_line (mystr
);
3710 /* ARM V5 breakpoint instruction (argument parse)
3711 BKPT <16 bit unsigned immediate>
3712 Instruction is not conditional.
3713 The bit pattern given in insns[] has the COND_ALWAYS condition,
3714 and it is an error if the caller tried to override that. */
3721 unsigned long number
;
3723 skip_whitespace (str
);
3725 /* Allow optional leading '#'. */
3726 if (is_immediate_prefix (* str
))
3729 memset (& expr
, '\0', sizeof (expr
));
3731 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3733 inst
.error
= _("bad or missing expression");
3737 number
= expr
.X_add_number
;
3739 /* Check it fits a 16 bit unsigned. */
3740 if (number
!= (number
& 0xffff))
3742 inst
.error
= _("immediate value out of range");
3746 /* Top 12 of 16 bits to bits 19:8. */
3747 inst
.instruction
|= (number
& 0xfff0) << 4;
3749 /* Bottom 4 of 16 bits to bits 3:0. */
3750 inst
.instruction
|= number
& 0xf;
3755 /* Xscale multiply-accumulate (argument parse)
3758 MIAxycc acc0,Rm,Rs. */
3767 if (accum0_required_here (& str
) == FAIL
)
3768 inst
.error
= ERR_NO_ACCUM
;
3770 else if (skip_past_comma (& str
) == FAIL
3771 || (rm
= reg_required_here (& str
, 0)) == FAIL
)
3772 inst
.error
= BAD_ARGS
;
3774 else if (skip_past_comma (& str
) == FAIL
3775 || (rs
= reg_required_here (& str
, 12)) == FAIL
)
3776 inst
.error
= BAD_ARGS
;
3778 /* inst.instruction has now been zapped with both rm and rs. */
3779 else if (rm
== REG_PC
|| rs
== REG_PC
)
3780 inst
.error
= BAD_PC
; /* Undefined result if rm or rs is R15. */
3786 /* Xscale move-accumulator-register (argument parse)
3788 MARcc acc0,RdLo,RdHi. */
3796 if (accum0_required_here (& str
) == FAIL
)
3797 inst
.error
= ERR_NO_ACCUM
;
3799 else if (skip_past_comma (& str
) == FAIL
3800 || (rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3801 inst
.error
= BAD_ARGS
;
3803 else if (skip_past_comma (& str
) == FAIL
3804 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3805 inst
.error
= BAD_ARGS
;
3807 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3808 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3809 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3815 /* Xscale move-register-accumulator (argument parse)
3817 MRAcc RdLo,RdHi,acc0. */
3826 skip_whitespace (str
);
3828 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3829 inst
.error
= BAD_ARGS
;
3831 else if (skip_past_comma (& str
) == FAIL
3832 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3833 inst
.error
= BAD_ARGS
;
3835 else if (skip_past_comma (& str
) == FAIL
3836 || accum0_required_here (& str
) == FAIL
)
3837 inst
.error
= ERR_NO_ACCUM
;
3839 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3840 else if (rdlo
== rdhi
)
3841 inst
.error
= BAD_ARGS
; /* Undefined result if 2 writes to same reg. */
3843 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3844 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3849 /* ARMv5TE: Preload-Cache
3853 Syntactically, like LDR with B=1, W=0, L=1. */
3861 skip_whitespace (str
);
3865 inst
.error
= _("'[' expected after PLD mnemonic");
3870 skip_whitespace (str
);
3872 if ((rd
= reg_required_here (& str
, 16)) == FAIL
)
3875 skip_whitespace (str
);
3881 skip_whitespace (str
);
3883 /* Post-indexed addressing is not allowed with PLD. */
3884 if (skip_past_comma (&str
) == SUCCESS
)
3887 = _("post-indexed expression used in preload instruction");
3890 else if (*str
== '!') /* [Rn]! */
3892 inst
.error
= _("writeback used in preload instruction");
3896 inst
.instruction
|= INDEX_UP
| PRE_INDEX
;
3898 else /* [Rn, ...] */
3900 if (skip_past_comma (& str
) == FAIL
)
3902 inst
.error
= _("pre-indexed expression expected");
3906 if (ldst_extend (&str
) == FAIL
)
3909 skip_whitespace (str
);
3913 inst
.error
= _("missing ]");
3918 skip_whitespace (str
);
3920 if (* str
== '!') /* [Rn]! */
3922 inst
.error
= _("writeback used in preload instruction");
3926 inst
.instruction
|= PRE_INDEX
;
3932 /* ARMv5TE load-consecutive (argument parse)
3945 skip_whitespace (str
);
3947 if ((rd
= reg_required_here (& str
, 12)) == FAIL
)
3949 inst
.error
= BAD_ARGS
;
3953 if (skip_past_comma (& str
) == FAIL
3954 || (rn
= ld_mode_required_here (& str
)) == FAIL
)
3957 inst
.error
= BAD_ARGS
;
3961 /* inst.instruction has now been zapped with Rd and the addressing mode. */
3962 if (rd
& 1) /* Unpredictable result if Rd is odd. */
3964 inst
.error
= _("Destination register must be even");
3970 inst
.error
= _("r14 not allowed here");
3974 if (((rd
== rn
) || (rd
+ 1 == rn
))
3975 && ((inst
.instruction
& WRITE_BACK
)
3976 || (!(inst
.instruction
& PRE_INDEX
))))
3977 as_warn (_("pre/post-indexing used when modified address register is destination"));
3979 /* For an index-register load, the index register must not overlap the
3980 destination (even if not write-back). */
3981 if ((inst
.instruction
& V4_STR_BIT
) == 0
3982 && (inst
.instruction
& HWOFFSET_IMM
) == 0)
3984 int rm
= inst
.instruction
& 0x0000000f;
3986 if (rm
== rd
|| (rm
== rd
+ 1))
3987 as_warn (_("ldrd destination registers must not overlap index register"));
3993 /* Returns the index into fp_values of a floating point number,
3994 or -1 if not in the table. */
3997 my_get_float_expression (str
)
4000 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4006 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
4008 /* Look for a raw floating point number. */
4009 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
4010 && is_end_of_line
[(unsigned char) *save_in
])
4012 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4014 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
4016 if (words
[j
] != fp_values
[i
][j
])
4020 if (j
== MAX_LITTLENUMS
)
4028 /* Try and parse a more complex expression, this will probably fail
4029 unless the code uses a floating point prefix (eg "0f"). */
4030 save_in
= input_line_pointer
;
4031 input_line_pointer
= *str
;
4032 if (expression (&exp
) == absolute_section
4033 && exp
.X_op
== O_big
4034 && exp
.X_add_number
< 0)
4036 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
4038 if (gen_to_words (words
, 5, (long) 15) == 0)
4040 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4042 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
4044 if (words
[j
] != fp_values
[i
][j
])
4048 if (j
== MAX_LITTLENUMS
)
4050 *str
= input_line_pointer
;
4051 input_line_pointer
= save_in
;
4058 *str
= input_line_pointer
;
4059 input_line_pointer
= save_in
;
4063 /* Return true if anything in the expression is a bignum. */
4066 walk_no_bignums (sp
)
4069 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
4072 if (symbol_get_value_expression (sp
)->X_add_symbol
)
4074 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
4075 || (symbol_get_value_expression (sp
)->X_op_symbol
4076 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
4083 my_get_expression (ep
, str
)
4090 save_in
= input_line_pointer
;
4091 input_line_pointer
= *str
;
4092 seg
= expression (ep
);
4095 if (seg
!= absolute_section
4096 && seg
!= text_section
4097 && seg
!= data_section
4098 && seg
!= bss_section
4099 && seg
!= undefined_section
)
4101 inst
.error
= _("bad_segment");
4102 *str
= input_line_pointer
;
4103 input_line_pointer
= save_in
;
4108 /* Get rid of any bignums now, so that we don't generate an error for which
4109 we can't establish a line number later on. Big numbers are never valid
4110 in instructions, which is where this routine is always called. */
4111 if (ep
->X_op
== O_big
4112 || (ep
->X_add_symbol
4113 && (walk_no_bignums (ep
->X_add_symbol
)
4115 && walk_no_bignums (ep
->X_op_symbol
)))))
4117 inst
.error
= _("Invalid constant");
4118 *str
= input_line_pointer
;
4119 input_line_pointer
= save_in
;
4123 *str
= input_line_pointer
;
4124 input_line_pointer
= save_in
;
4128 /* UNRESTRICT should be one if <shift> <register> is permitted for this
4132 decode_shift (str
, unrestrict
)
4136 const struct asm_shift_name
* shift
;
4140 skip_whitespace (* str
);
4142 for (p
= * str
; ISALPHA (* p
); p
++)
4147 inst
.error
= _("Shift expression expected");
4153 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
4158 inst
.error
= _("Shift expression expected");
4162 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
4164 if (shift
->properties
->index
== SHIFT_RRX
)
4167 inst
.instruction
|= shift
->properties
->bit_field
;
4171 skip_whitespace (p
);
4173 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
4175 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
4179 else if (! is_immediate_prefix (* p
))
4181 inst
.error
= (unrestrict
4182 ? _("shift requires register or #expression")
4183 : _("shift requires #expression"));
4191 if (my_get_expression (& inst
.reloc
.exp
, & p
))
4194 /* Validate some simple #expressions. */
4195 if (inst
.reloc
.exp
.X_op
== O_constant
)
4197 unsigned num
= inst
.reloc
.exp
.X_add_number
;
4199 /* Reject operations greater than 32. */
4201 /* Reject a shift of 0 unless the mode allows it. */
4202 || (num
== 0 && shift
->properties
->allows_0
== 0)
4203 /* Reject a shift of 32 unless the mode allows it. */
4204 || (num
== 32 && shift
->properties
->allows_32
== 0)
4207 /* As a special case we allow a shift of zero for
4208 modes that do not support it to be recoded as an
4209 logical shift left of zero (ie nothing). We warn
4210 about this though. */
4213 as_warn (_("Shift of 0 ignored."));
4214 shift
= & shift_names
[0];
4215 assert (shift
->properties
->index
== SHIFT_LSL
);
4219 inst
.error
= _("Invalid immediate shift");
4224 /* Shifts of 32 are encoded as 0, for those shifts that
4229 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
4233 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
4234 inst
.reloc
.pc_rel
= 0;
4235 inst
.instruction
|= shift
->properties
->bit_field
;
4242 /* Do those data_ops which can take a negative immediate constant
4243 by altering the instuction. A bit of a hack really.
4247 by inverting the second operand, and
4250 by negating the second operand. */
4253 negate_data_op (instruction
, value
)
4254 unsigned long * instruction
;
4255 unsigned long value
;
4258 unsigned long negated
, inverted
;
4260 negated
= validate_immediate (-value
);
4261 inverted
= validate_immediate (~value
);
4263 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
4266 /* First negates. */
4267 case OPCODE_SUB
: /* ADD <-> SUB */
4268 new_inst
= OPCODE_ADD
;
4273 new_inst
= OPCODE_SUB
;
4277 case OPCODE_CMP
: /* CMP <-> CMN */
4278 new_inst
= OPCODE_CMN
;
4283 new_inst
= OPCODE_CMP
;
4287 /* Now Inverted ops. */
4288 case OPCODE_MOV
: /* MOV <-> MVN */
4289 new_inst
= OPCODE_MVN
;
4294 new_inst
= OPCODE_MOV
;
4298 case OPCODE_AND
: /* AND <-> BIC */
4299 new_inst
= OPCODE_BIC
;
4304 new_inst
= OPCODE_AND
;
4308 case OPCODE_ADC
: /* ADC <-> SBC */
4309 new_inst
= OPCODE_SBC
;
4314 new_inst
= OPCODE_ADC
;
4318 /* We cannot do anything. */
4323 if (value
== (unsigned) FAIL
)
4326 *instruction
&= OPCODE_MASK
;
4327 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
4338 skip_whitespace (* str
);
4340 if (reg_required_here (str
, 0) != FAIL
)
4342 if (skip_past_comma (str
) == SUCCESS
)
4343 /* Shift operation on register. */
4344 return decode_shift (str
, NO_SHIFT_RESTRICT
);
4350 /* Immediate expression. */
4351 if (is_immediate_prefix (**str
))
4356 if (my_get_expression (&inst
.reloc
.exp
, str
))
4359 if (inst
.reloc
.exp
.X_add_symbol
)
4361 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4362 inst
.reloc
.pc_rel
= 0;
4366 if (skip_past_comma (str
) == SUCCESS
)
4368 /* #x, y -- ie explicit rotation by Y. */
4369 if (my_get_expression (&expr
, str
))
4372 if (expr
.X_op
!= O_constant
)
4374 inst
.error
= _("Constant expression expected");
4378 /* Rotate must be a multiple of 2. */
4379 if (((unsigned) expr
.X_add_number
) > 30
4380 || (expr
.X_add_number
& 1) != 0
4381 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
4383 inst
.error
= _("Invalid constant");
4386 inst
.instruction
|= INST_IMMEDIATE
;
4387 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4388 inst
.instruction
|= expr
.X_add_number
<< 7;
4392 /* Implicit rotation, select a suitable one. */
4393 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4397 /* Can't be done. Perhaps the code reads something like
4398 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
4399 if ((value
= negate_data_op (&inst
.instruction
,
4400 inst
.reloc
.exp
.X_add_number
))
4403 inst
.error
= _("Invalid constant");
4408 inst
.instruction
|= value
;
4411 inst
.instruction
|= INST_IMMEDIATE
;
4416 inst
.error
= _("Register or shift expression expected");
4425 skip_whitespace (* str
);
4427 if (fp_reg_required_here (str
, 0) != FAIL
)
4431 /* Immediate expression. */
4432 if (*((*str
)++) == '#')
4438 skip_whitespace (* str
);
4440 /* First try and match exact strings, this is to guarantee
4441 that some formats will work even for cross assembly. */
4443 for (i
= 0; fp_const
[i
]; i
++)
4445 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
4449 *str
+= strlen (fp_const
[i
]);
4450 if (is_end_of_line
[(unsigned char) **str
])
4452 inst
.instruction
|= i
+ 8;
4459 /* Just because we didn't get a match doesn't mean that the
4460 constant isn't valid, just that it is in a format that we
4461 don't automatically recognize. Try parsing it with
4462 the standard expression routines. */
4463 if ((i
= my_get_float_expression (str
)) >= 0)
4465 inst
.instruction
|= i
+ 8;
4469 inst
.error
= _("Invalid floating point immediate expression");
4473 _("Floating point register or immediate expression expected");
4482 skip_whitespace (str
);
4484 if (reg_required_here (&str
, 12) == FAIL
4485 || skip_past_comma (&str
) == FAIL
4486 || reg_required_here (&str
, 16) == FAIL
4487 || skip_past_comma (&str
) == FAIL
4488 || data_op2 (&str
) == FAIL
)
4491 inst
.error
= BAD_ARGS
;
4503 /* This is a pseudo-op of the form "adr rd, label" to be converted
4504 into a relative address of the form "add rd, pc, #label-.-8". */
4505 skip_whitespace (str
);
4507 if (reg_required_here (&str
, 12) == FAIL
4508 || skip_past_comma (&str
) == FAIL
4509 || my_get_expression (&inst
.reloc
.exp
, &str
))
4512 inst
.error
= BAD_ARGS
;
4516 /* Frag hacking will turn this into a sub instruction if the offset turns
4517 out to be negative. */
4518 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4519 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
4520 inst
.reloc
.pc_rel
= 1;
4529 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4530 into a relative address of the form:
4531 add rd, pc, #low(label-.-8)"
4532 add rd, rd, #high(label-.-8)" */
4534 skip_whitespace (str
);
4536 if (reg_required_here (&str
, 12) == FAIL
4537 || skip_past_comma (&str
) == FAIL
4538 || my_get_expression (&inst
.reloc
.exp
, &str
))
4541 inst
.error
= BAD_ARGS
;
4547 /* Frag hacking will turn this into a sub instruction if the offset turns
4548 out to be negative. */
4549 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
4550 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
4551 inst
.reloc
.pc_rel
= 1;
4552 inst
.size
= INSN_SIZE
* 2;
4561 skip_whitespace (str
);
4563 if (reg_required_here (&str
, 16) == FAIL
)
4566 inst
.error
= BAD_ARGS
;
4570 if (skip_past_comma (&str
) == FAIL
4571 || data_op2 (&str
) == FAIL
)
4574 inst
.error
= BAD_ARGS
;
4586 skip_whitespace (str
);
4588 if (reg_required_here (&str
, 12) == FAIL
)
4591 inst
.error
= BAD_ARGS
;
4595 if (skip_past_comma (&str
) == FAIL
4596 || data_op2 (&str
) == FAIL
)
4599 inst
.error
= BAD_ARGS
;
4618 if (my_get_expression (& inst
.reloc
.exp
, str
))
4621 if (inst
.reloc
.exp
.X_op
== O_constant
)
4623 int value
= inst
.reloc
.exp
.X_add_number
;
4625 if (value
< -4095 || value
> 4095)
4627 inst
.error
= _("address offset too large");
4637 inst
.instruction
|= add
| value
;
4641 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4642 inst
.reloc
.pc_rel
= 0;
4655 if (reg_required_here (str
, 0) == FAIL
)
4658 inst
.instruction
|= add
| OFFSET_REG
;
4659 if (skip_past_comma (str
) == SUCCESS
)
4660 return decode_shift (str
, SHIFT_RESTRICT
);
4674 skip_whitespace (str
);
4676 if ((conflict_reg
= reg_required_here (&str
, 12)) == FAIL
)
4679 inst
.error
= BAD_ARGS
;
4683 if (skip_past_comma (&str
) == FAIL
)
4685 inst
.error
= _("Address expected");
4695 skip_whitespace (str
);
4697 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4700 /* Conflicts can occur on stores as well as loads. */
4701 conflict_reg
= (conflict_reg
== reg
);
4703 skip_whitespace (str
);
4709 if (skip_past_comma (&str
) == SUCCESS
)
4711 /* [Rn],... (post inc) */
4712 if (ldst_extend (&str
) == FAIL
)
4715 as_warn (_("%s register same as write-back base"),
4716 ((inst
.instruction
& LOAD_BIT
)
4717 ? _("destination") : _("source")));
4722 skip_whitespace (str
);
4727 as_warn (_("%s register same as write-back base"),
4728 ((inst
.instruction
& LOAD_BIT
)
4729 ? _("destination") : _("source")));
4731 inst
.instruction
|= WRITE_BACK
;
4734 inst
.instruction
|= INDEX_UP
;
4741 if (skip_past_comma (&str
) == FAIL
)
4743 inst
.error
= _("pre-indexed expression expected");
4748 if (ldst_extend (&str
) == FAIL
)
4751 skip_whitespace (str
);
4755 inst
.error
= _("missing ]");
4759 skip_whitespace (str
);
4764 as_warn (_("%s register same as write-back base"),
4765 ((inst
.instruction
& LOAD_BIT
)
4766 ? _("destination") : _("source")));
4768 inst
.instruction
|= WRITE_BACK
;
4772 else if (*str
== '=')
4774 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4777 skip_whitespace (str
);
4779 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4782 if (inst
.reloc
.exp
.X_op
!= O_constant
4783 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4785 inst
.error
= _("Constant expression expected");
4789 if (inst
.reloc
.exp
.X_op
== O_constant
4790 && (value
= validate_immediate (inst
.reloc
.exp
.X_add_number
)) != FAIL
)
4792 /* This can be done with a mov instruction. */
4793 inst
.instruction
&= LITERAL_MASK
;
4794 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
4795 inst
.instruction
|= (value
& 0xfff);
4801 /* Insert into literal pool. */
4802 if (add_to_lit_pool () == FAIL
)
4805 inst
.error
= _("literal pool insertion failed");
4809 /* Change the instruction exp to point to the pool. */
4810 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
4811 inst
.reloc
.pc_rel
= 1;
4812 inst
.instruction
|= (REG_PC
<< 16);
4818 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4821 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4823 /* PC rel adjust. */
4824 inst
.reloc
.exp
.X_add_number
-= 8;
4826 inst
.reloc
.pc_rel
= 1;
4827 inst
.instruction
|= (REG_PC
<< 16);
4831 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
4842 skip_whitespace (str
);
4844 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
4847 inst
.error
= BAD_ARGS
;
4851 if (skip_past_comma (& str
) == FAIL
)
4853 inst
.error
= _("Address expected");
4863 skip_whitespace (str
);
4865 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4868 /* ldrt/strt always use post-indexed addressing, so if the base is
4869 the same as Rd, we warn. */
4870 if (conflict_reg
== reg
)
4871 as_warn (_("%s register same as write-back base"),
4872 ((inst
.instruction
& LOAD_BIT
)
4873 ? _("destination") : _("source")));
4875 skip_whitespace (str
);
4881 if (skip_past_comma (&str
) == SUCCESS
)
4883 /* [Rn],... (post inc) */
4884 if (ldst_extend (&str
) == FAIL
)
4890 skip_whitespace (str
);
4892 /* Skip a write-back '!'. */
4896 inst
.instruction
|= INDEX_UP
;
4901 inst
.error
= _("post-indexed expression expected");
4907 inst
.error
= _("post-indexed expression expected");
4916 ldst_extend_v4 (str
)
4926 if (my_get_expression (& inst
.reloc
.exp
, str
))
4929 if (inst
.reloc
.exp
.X_op
== O_constant
)
4931 int value
= inst
.reloc
.exp
.X_add_number
;
4933 if (value
< -255 || value
> 255)
4935 inst
.error
= _("address offset too large");
4945 /* Halfword and signextension instructions have the
4946 immediate value split across bits 11..8 and bits 3..0. */
4947 inst
.instruction
|= (add
| HWOFFSET_IMM
4948 | ((value
>> 4) << 8) | (value
& 0xF));
4952 inst
.instruction
|= HWOFFSET_IMM
;
4953 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
4954 inst
.reloc
.pc_rel
= 0;
4967 if (reg_required_here (str
, 0) == FAIL
)
4970 inst
.instruction
|= add
;
4975 /* Halfword and signed-byte load/store operations. */
4984 skip_whitespace (str
);
4986 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
4989 inst
.error
= BAD_ARGS
;
4993 if (skip_past_comma (& str
) == FAIL
)
4995 inst
.error
= _("Address expected");
5005 skip_whitespace (str
);
5007 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5010 /* Conflicts can occur on stores as well as loads. */
5011 conflict_reg
= (conflict_reg
== reg
);
5013 skip_whitespace (str
);
5019 if (skip_past_comma (&str
) == SUCCESS
)
5021 /* [Rn],... (post inc) */
5022 if (ldst_extend_v4 (&str
) == FAIL
)
5025 as_warn (_("%s register same as write-back base"),
5026 ((inst
.instruction
& LOAD_BIT
)
5027 ? _("destination") : _("source")));
5032 inst
.instruction
|= HWOFFSET_IMM
;
5034 skip_whitespace (str
);
5039 as_warn (_("%s register same as write-back base"),
5040 ((inst
.instruction
& LOAD_BIT
)
5041 ? _("destination") : _("source")));
5043 inst
.instruction
|= WRITE_BACK
;
5046 inst
.instruction
|= INDEX_UP
;
5053 if (skip_past_comma (&str
) == FAIL
)
5055 inst
.error
= _("pre-indexed expression expected");
5060 if (ldst_extend_v4 (&str
) == FAIL
)
5063 skip_whitespace (str
);
5067 inst
.error
= _("missing ]");
5071 skip_whitespace (str
);
5076 as_warn (_("%s register same as write-back base"),
5077 ((inst
.instruction
& LOAD_BIT
)
5078 ? _("destination") : _("source")));
5080 inst
.instruction
|= WRITE_BACK
;
5084 else if (*str
== '=')
5086 /* XXX Does this work correctly for half-word/byte ops? */
5087 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5090 skip_whitespace (str
);
5092 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5095 if (inst
.reloc
.exp
.X_op
!= O_constant
5096 && inst
.reloc
.exp
.X_op
!= O_symbol
)
5098 inst
.error
= _("Constant expression expected");
5102 if (inst
.reloc
.exp
.X_op
== O_constant
)
5104 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
5108 /* This can be done with a mov instruction. */
5109 inst
.instruction
&= LITERAL_MASK
;
5110 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
5111 inst
.instruction
|= value
& 0xfff;
5116 value
= validate_immediate (~ inst
.reloc
.exp
.X_add_number
);
5120 /* This can be done with a mvn instruction. */
5121 inst
.instruction
&= LITERAL_MASK
;
5122 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MVN
<< DATA_OP_SHIFT
);
5123 inst
.instruction
|= value
& 0xfff;
5129 /* Insert into literal pool. */
5130 if (add_to_lit_pool () == FAIL
)
5133 inst
.error
= _("literal pool insertion failed");
5137 /* Change the instruction exp to point to the pool. */
5138 inst
.instruction
|= HWOFFSET_IMM
;
5139 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
5140 inst
.reloc
.pc_rel
= 1;
5141 inst
.instruction
|= (REG_PC
<< 16);
5146 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5149 inst
.instruction
|= HWOFFSET_IMM
;
5150 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
5152 /* PC rel adjust. */
5153 inst
.reloc
.exp
.X_add_number
-= 8;
5155 inst
.reloc
.pc_rel
= 1;
5156 inst
.instruction
|= (REG_PC
<< 16);
5160 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
5169 char * str
= * strp
;
5173 /* We come back here if we get ranges concatenated by '+' or '|'. */
5188 skip_whitespace (str
);
5190 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
5199 inst
.error
= _("Bad range in register list");
5203 for (i
= cur_reg
+ 1; i
< reg
; i
++)
5205 if (range
& (1 << i
))
5207 (_("Warning: Duplicated register (r%d) in register list"),
5215 if (range
& (1 << reg
))
5216 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
5218 else if (reg
<= cur_reg
)
5219 as_tsktsk (_("Warning: Register range not in ascending order"));
5224 while (skip_past_comma (&str
) != FAIL
5225 || (in_range
= 1, *str
++ == '-'));
5227 skip_whitespace (str
);
5231 inst
.error
= _("Missing `}'");
5239 if (my_get_expression (&expr
, &str
))
5242 if (expr
.X_op
== O_constant
)
5244 if (expr
.X_add_number
5245 != (expr
.X_add_number
& 0x0000ffff))
5247 inst
.error
= _("invalid register mask");
5251 if ((range
& expr
.X_add_number
) != 0)
5253 int regno
= range
& expr
.X_add_number
;
5256 regno
= (1 << regno
) - 1;
5258 (_("Warning: Duplicated register (r%d) in register list"),
5262 range
|= expr
.X_add_number
;
5266 if (inst
.reloc
.type
!= 0)
5268 inst
.error
= _("expression too complex");
5272 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
5273 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
5274 inst
.reloc
.pc_rel
= 0;
5278 skip_whitespace (str
);
5280 if (*str
== '|' || *str
== '+')
5286 while (another_range
);
5299 skip_whitespace (str
);
5301 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
5304 if (base_reg
== REG_PC
)
5306 inst
.error
= _("r15 not allowed as base register");
5310 skip_whitespace (str
);
5314 inst
.instruction
|= WRITE_BACK
;
5318 if (skip_past_comma (&str
) == FAIL
5319 || (range
= reg_list (&str
)) == FAIL
)
5322 inst
.error
= BAD_ARGS
;
5329 inst
.instruction
|= LDM_TYPE_2_OR_3
;
5332 inst
.instruction
|= range
;
5341 skip_whitespace (str
);
5343 /* Allow optional leading '#'. */
5344 if (is_immediate_prefix (*str
))
5347 if (my_get_expression (& inst
.reloc
.exp
, & str
))
5350 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
5351 inst
.reloc
.pc_rel
= 0;
5363 skip_whitespace (str
);
5365 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
5370 inst
.error
= _("r15 not allowed in swap");
5374 if (skip_past_comma (&str
) == FAIL
5375 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
5378 inst
.error
= BAD_ARGS
;
5384 inst
.error
= _("r15 not allowed in swap");
5388 if (skip_past_comma (&str
) == FAIL
5391 inst
.error
= BAD_ARGS
;
5395 skip_whitespace (str
);
5397 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5402 inst
.error
= BAD_PC
;
5406 skip_whitespace (str
);
5410 inst
.error
= _("missing ]");
5422 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5429 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
5430 required for the instruction. */
5432 /* arm_parse_reloc () works on input_line_pointer.
5433 We actually want to parse the operands to the branch instruction
5434 passed in 'str'. Save the input pointer and restore it later. */
5435 save_in
= input_line_pointer
;
5436 input_line_pointer
= str
;
5437 if (inst
.reloc
.exp
.X_op
== O_symbol
5439 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
5441 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
5442 inst
.reloc
.pc_rel
= 0;
5443 /* Modify str to point to after parsed operands, otherwise
5444 end_of_line() will complain about the (PLT) left in str. */
5445 str
= input_line_pointer
;
5449 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
5450 inst
.reloc
.pc_rel
= 1;
5452 input_line_pointer
= save_in
;
5455 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
5456 inst
.reloc
.pc_rel
= 1;
5457 #endif /* OBJ_ELF */
5469 skip_whitespace (str
);
5471 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
5473 inst
.error
= BAD_ARGS
;
5477 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
5479 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
5488 /* Co-processor data operation.
5489 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
5490 skip_whitespace (str
);
5492 if (co_proc_number (&str
) == FAIL
)
5495 inst
.error
= BAD_ARGS
;
5499 if (skip_past_comma (&str
) == FAIL
5500 || cp_opc_expr (&str
, 20,4) == FAIL
)
5503 inst
.error
= BAD_ARGS
;
5507 if (skip_past_comma (&str
) == FAIL
5508 || cp_reg_required_here (&str
, 12) == FAIL
)
5511 inst
.error
= BAD_ARGS
;
5515 if (skip_past_comma (&str
) == FAIL
5516 || cp_reg_required_here (&str
, 16) == FAIL
)
5519 inst
.error
= BAD_ARGS
;
5523 if (skip_past_comma (&str
) == FAIL
5524 || cp_reg_required_here (&str
, 0) == FAIL
)
5527 inst
.error
= BAD_ARGS
;
5531 if (skip_past_comma (&str
) == SUCCESS
)
5533 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5536 inst
.error
= BAD_ARGS
;
5549 /* Co-processor register load/store.
5550 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
5552 skip_whitespace (str
);
5554 if (co_proc_number (&str
) == FAIL
)
5557 inst
.error
= BAD_ARGS
;
5561 if (skip_past_comma (&str
) == FAIL
5562 || cp_reg_required_here (&str
, 12) == FAIL
)
5565 inst
.error
= BAD_ARGS
;
5569 if (skip_past_comma (&str
) == FAIL
5570 || cp_address_required_here (&str
) == FAIL
)
5573 inst
.error
= BAD_ARGS
;
5585 /* Co-processor register transfer.
5586 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
5588 skip_whitespace (str
);
5590 if (co_proc_number (&str
) == FAIL
)
5593 inst
.error
= BAD_ARGS
;
5597 if (skip_past_comma (&str
) == FAIL
5598 || cp_opc_expr (&str
, 21, 3) == FAIL
)
5601 inst
.error
= BAD_ARGS
;
5605 if (skip_past_comma (&str
) == FAIL
5606 || reg_required_here (&str
, 12) == FAIL
)
5609 inst
.error
= BAD_ARGS
;
5613 if (skip_past_comma (&str
) == FAIL
5614 || cp_reg_required_here (&str
, 16) == FAIL
)
5617 inst
.error
= BAD_ARGS
;
5621 if (skip_past_comma (&str
) == FAIL
5622 || cp_reg_required_here (&str
, 0) == FAIL
)
5625 inst
.error
= BAD_ARGS
;
5629 if (skip_past_comma (&str
) == SUCCESS
)
5631 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5634 inst
.error
= BAD_ARGS
;
5647 /* FP control registers.
5648 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
5650 skip_whitespace (str
);
5652 if (reg_required_here (&str
, 12) == FAIL
)
5655 inst
.error
= BAD_ARGS
;
5667 skip_whitespace (str
);
5669 if (fp_reg_required_here (&str
, 12) == FAIL
)
5672 inst
.error
= BAD_ARGS
;
5676 if (skip_past_comma (&str
) == FAIL
5677 || cp_address_required_here (&str
) == FAIL
)
5680 inst
.error
= BAD_ARGS
;
5693 skip_whitespace (str
);
5695 if (fp_reg_required_here (&str
, 12) == FAIL
)
5698 inst
.error
= BAD_ARGS
;
5702 /* Get Number of registers to transfer. */
5703 if (skip_past_comma (&str
) == FAIL
5704 || my_get_expression (&inst
.reloc
.exp
, &str
))
5707 inst
.error
= _("constant expression expected");
5711 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5713 inst
.error
= _("Constant value required for number of registers");
5717 num_regs
= inst
.reloc
.exp
.X_add_number
;
5719 if (num_regs
< 1 || num_regs
> 4)
5721 inst
.error
= _("number of registers must be in the range [1:4]");
5728 inst
.instruction
|= CP_T_X
;
5731 inst
.instruction
|= CP_T_Y
;
5734 inst
.instruction
|= CP_T_Y
| CP_T_X
;
5742 if (inst
.instruction
& (CP_T_Pre
| CP_T_UD
)) /* ed/fd format. */
5748 /* The instruction specified "ea" or "fd", so we can only accept
5749 [Rn]{!}. The instruction does not really support stacking or
5750 unstacking, so we have to emulate these by setting appropriate
5751 bits and offsets. */
5752 if (skip_past_comma (&str
) == FAIL
5756 inst
.error
= BAD_ARGS
;
5761 skip_whitespace (str
);
5763 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5766 skip_whitespace (str
);
5770 inst
.error
= BAD_ARGS
;
5782 _("R15 not allowed as base register with write-back");
5789 if (inst
.instruction
& CP_T_Pre
)
5791 /* Pre-decrement. */
5792 offset
= 3 * num_regs
;
5794 inst
.instruction
|= CP_T_WB
;
5798 /* Post-increment. */
5801 inst
.instruction
|= CP_T_WB
;
5802 offset
= 3 * num_regs
;
5806 /* No write-back, so convert this into a standard pre-increment
5807 instruction -- aesthetically more pleasing. */
5808 inst
.instruction
|= CP_T_Pre
| CP_T_UD
;
5813 inst
.instruction
|= offset
;
5815 else if (skip_past_comma (&str
) == FAIL
5816 || cp_address_required_here (&str
) == FAIL
)
5819 inst
.error
= BAD_ARGS
;
5830 skip_whitespace (str
);
5832 if (fp_reg_required_here (&str
, 12) == FAIL
)
5835 inst
.error
= BAD_ARGS
;
5839 if (skip_past_comma (&str
) == FAIL
5840 || fp_reg_required_here (&str
, 16) == FAIL
)
5843 inst
.error
= BAD_ARGS
;
5847 if (skip_past_comma (&str
) == FAIL
5848 || fp_op2 (&str
) == FAIL
)
5851 inst
.error
= BAD_ARGS
;
5860 do_fpa_monadic (str
)
5863 skip_whitespace (str
);
5865 if (fp_reg_required_here (&str
, 12) == FAIL
)
5868 inst
.error
= BAD_ARGS
;
5872 if (skip_past_comma (&str
) == FAIL
5873 || fp_op2 (&str
) == FAIL
)
5876 inst
.error
= BAD_ARGS
;
5888 skip_whitespace (str
);
5890 if (fp_reg_required_here (&str
, 16) == FAIL
)
5893 inst
.error
= BAD_ARGS
;
5897 if (skip_past_comma (&str
) == FAIL
5898 || fp_op2 (&str
) == FAIL
)
5901 inst
.error
= BAD_ARGS
;
5910 do_fpa_from_reg (str
)
5913 skip_whitespace (str
);
5915 if (fp_reg_required_here (&str
, 16) == FAIL
)
5918 inst
.error
= BAD_ARGS
;
5922 if (skip_past_comma (&str
) == FAIL
5923 || reg_required_here (&str
, 12) == FAIL
)
5926 inst
.error
= BAD_ARGS
;
5938 skip_whitespace (str
);
5940 if (reg_required_here (&str
, 12) == FAIL
)
5943 if (skip_past_comma (&str
) == FAIL
5944 || fp_reg_required_here (&str
, 0) == FAIL
)
5947 inst
.error
= BAD_ARGS
;
5955 /* Thumb specific routines. */
5957 /* Parse and validate that a register is of the right form, this saves
5958 repeated checking of this information in many similar cases.
5959 Unlike the 32-bit case we do not insert the register into the opcode
5960 here, since the position is often unknown until the full instruction
5964 thumb_reg (strp
, hi_lo
)
5970 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
5978 inst
.error
= _("lo register required");
5986 inst
.error
= _("hi register required");
5998 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
6002 thumb_add_sub (str
, subtract
)
6006 int Rd
, Rs
, Rn
= FAIL
;
6008 skip_whitespace (str
);
6010 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
6011 || skip_past_comma (&str
) == FAIL
)
6014 inst
.error
= BAD_ARGS
;
6018 if (is_immediate_prefix (*str
))
6022 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6027 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6030 if (skip_past_comma (&str
) == FAIL
)
6032 /* Two operand format, shuffle the registers
6033 and pretend there are 3. */
6037 else if (is_immediate_prefix (*str
))
6040 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6043 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6047 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
6048 for the latter case, EXPR contains the immediate that was found. */
6051 /* All register format. */
6052 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
6056 inst
.error
= _("dest and source1 must be the same register");
6060 /* Can't do this for SUB. */
6063 inst
.error
= _("subtract valid only on lo regs");
6067 inst
.instruction
= (T_OPCODE_ADD_HI
6068 | (Rd
> 7 ? THUMB_H1
: 0)
6069 | (Rn
> 7 ? THUMB_H2
: 0));
6070 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
6074 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
6075 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
6080 /* Immediate expression, now things start to get nasty. */
6082 /* First deal with HI regs, only very restricted cases allowed:
6083 Adjusting SP, and using PC or SP to get an address. */
6084 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
6085 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
6087 inst
.error
= _("invalid Hi register with immediate");
6091 if (inst
.reloc
.exp
.X_op
!= O_constant
)
6093 /* Value isn't known yet, all we can do is store all the fragments
6094 we know about in the instruction and let the reloc hacking
6096 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
6097 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
6101 int offset
= inst
.reloc
.exp
.X_add_number
;
6111 /* Quick check, in case offset is MIN_INT. */
6114 inst
.error
= _("immediate value out of range");
6123 if (offset
& ~0x1fc)
6125 inst
.error
= _("invalid immediate value for stack adjust");
6128 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
6129 inst
.instruction
|= offset
>> 2;
6131 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
6134 || (offset
& ~0x3fc))
6136 inst
.error
= _("invalid immediate for address calculation");
6139 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
6141 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
6147 inst
.error
= _("immediate value out of range");
6150 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
6151 inst
.instruction
|= (Rd
<< 8) | offset
;
6157 inst
.error
= _("immediate value out of range");
6160 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
6161 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
6170 thumb_shift (str
, shift
)
6174 int Rd
, Rs
, Rn
= FAIL
;
6176 skip_whitespace (str
);
6178 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6179 || skip_past_comma (&str
) == FAIL
)
6182 inst
.error
= BAD_ARGS
;
6186 if (is_immediate_prefix (*str
))
6188 /* Two operand immediate format, set Rs to Rd. */
6191 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6196 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6199 if (skip_past_comma (&str
) == FAIL
)
6201 /* Two operand format, shuffle the registers
6202 and pretend there are 3. */
6206 else if (is_immediate_prefix (*str
))
6209 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6212 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6216 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
6217 for the latter case, EXPR contains the immediate that was found. */
6223 inst
.error
= _("source1 and dest must be same register");
6229 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
6230 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
6231 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
6234 inst
.instruction
|= Rd
| (Rn
<< 3);
6240 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
6241 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
6242 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
6245 if (inst
.reloc
.exp
.X_op
!= O_constant
)
6247 /* Value isn't known yet, create a dummy reloc and let reloc
6248 hacking fix it up. */
6249 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
6253 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
6255 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
6257 inst
.error
= _("Invalid immediate for shift");
6261 /* Shifts of zero are handled by converting to LSL. */
6262 if (shift_value
== 0)
6263 inst
.instruction
= T_OPCODE_LSL_I
;
6265 /* Shifts of 32 are encoded as a shift of zero. */
6266 if (shift_value
== 32)
6269 inst
.instruction
|= shift_value
<< 6;
6272 inst
.instruction
|= Rd
| (Rs
<< 3);
6279 thumb_mov_compare (str
, move
)
6285 skip_whitespace (str
);
6287 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
6288 || skip_past_comma (&str
) == FAIL
)
6291 inst
.error
= BAD_ARGS
;
6295 if (is_immediate_prefix (*str
))
6298 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6301 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6306 if (Rs
< 8 && Rd
< 8)
6308 if (move
== THUMB_MOVE
)
6309 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
6310 since a MOV instruction produces unpredictable results. */
6311 inst
.instruction
= T_OPCODE_ADD_I3
;
6313 inst
.instruction
= T_OPCODE_CMP_LR
;
6314 inst
.instruction
|= Rd
| (Rs
<< 3);
6318 if (move
== THUMB_MOVE
)
6319 inst
.instruction
= T_OPCODE_MOV_HR
;
6321 inst
.instruction
= T_OPCODE_CMP_HR
;
6324 inst
.instruction
|= THUMB_H1
;
6327 inst
.instruction
|= THUMB_H2
;
6329 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
6336 inst
.error
= _("only lo regs allowed with immediate");
6340 if (move
== THUMB_MOVE
)
6341 inst
.instruction
= T_OPCODE_MOV_I8
;
6343 inst
.instruction
= T_OPCODE_CMP_I8
;
6345 inst
.instruction
|= Rd
<< 8;
6347 if (inst
.reloc
.exp
.X_op
!= O_constant
)
6348 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
6351 unsigned value
= inst
.reloc
.exp
.X_add_number
;
6355 inst
.error
= _("invalid immediate");
6359 inst
.instruction
|= value
;
6367 thumb_load_store (str
, load_store
, size
)
6372 int Rd
, Rb
, Ro
= FAIL
;
6374 skip_whitespace (str
);
6376 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6377 || skip_past_comma (&str
) == FAIL
)
6380 inst
.error
= BAD_ARGS
;
6387 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6390 if (skip_past_comma (&str
) != FAIL
)
6392 if (is_immediate_prefix (*str
))
6395 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6398 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6403 inst
.reloc
.exp
.X_op
= O_constant
;
6404 inst
.reloc
.exp
.X_add_number
= 0;
6409 inst
.error
= _("expected ']'");
6414 else if (*str
== '=')
6416 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6419 skip_whitespace (str
);
6421 if (my_get_expression (& inst
.reloc
.exp
, & str
))
6426 if ( inst
.reloc
.exp
.X_op
!= O_constant
6427 && inst
.reloc
.exp
.X_op
!= O_symbol
)
6429 inst
.error
= "Constant expression expected";
6433 if (inst
.reloc
.exp
.X_op
== O_constant
6434 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
6436 /* This can be done with a mov instruction. */
6438 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
6439 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
6443 /* Insert into literal pool. */
6444 if (add_to_lit_pool () == FAIL
)
6447 inst
.error
= "literal pool insertion failed";
6451 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6452 inst
.reloc
.pc_rel
= 1;
6453 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
6454 /* Adjust ARM pipeline offset to Thumb. */
6455 inst
.reloc
.exp
.X_add_number
+= 4;
6461 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6464 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
6465 inst
.reloc
.pc_rel
= 1;
6466 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
6467 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6472 if (Rb
== REG_PC
|| Rb
== REG_SP
)
6474 if (size
!= THUMB_WORD
)
6476 inst
.error
= _("byte or halfword not valid for base register");
6479 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
6481 inst
.error
= _("R15 based store not allowed");
6484 else if (Ro
!= FAIL
)
6486 inst
.error
= _("Invalid base register for register offset");
6491 inst
.instruction
= T_OPCODE_LDR_PC
;
6492 else if (load_store
== THUMB_LOAD
)
6493 inst
.instruction
= T_OPCODE_LDR_SP
;
6495 inst
.instruction
= T_OPCODE_STR_SP
;
6497 inst
.instruction
|= Rd
<< 8;
6498 if (inst
.reloc
.exp
.X_op
== O_constant
)
6500 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
6502 if (offset
& ~0x3fc)
6504 inst
.error
= _("invalid offset");
6508 inst
.instruction
|= offset
>> 2;
6511 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6515 inst
.error
= _("invalid base register in load/store");
6518 else if (Ro
== FAIL
)
6520 /* Immediate offset. */
6521 if (size
== THUMB_WORD
)
6522 inst
.instruction
= (load_store
== THUMB_LOAD
6523 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
6524 else if (size
== THUMB_HALFWORD
)
6525 inst
.instruction
= (load_store
== THUMB_LOAD
6526 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
6528 inst
.instruction
= (load_store
== THUMB_LOAD
6529 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
6531 inst
.instruction
|= Rd
| (Rb
<< 3);
6533 if (inst
.reloc
.exp
.X_op
== O_constant
)
6535 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
6537 if (offset
& ~(0x1f << size
))
6539 inst
.error
= _("Invalid offset");
6542 inst
.instruction
|= (offset
>> size
) << 6;
6545 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6549 /* Register offset. */
6550 if (size
== THUMB_WORD
)
6551 inst
.instruction
= (load_store
== THUMB_LOAD
6552 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
6553 else if (size
== THUMB_HALFWORD
)
6554 inst
.instruction
= (load_store
== THUMB_LOAD
6555 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
6557 inst
.instruction
= (load_store
== THUMB_LOAD
6558 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
6560 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
6566 /* Given a register and a register type, return 1 if
6567 the register is of the given type, else return 0. */
6570 cirrus_valid_reg (reg
, regtype
)
6572 enum cirrus_regtype regtype
;
6576 case CIRRUS_REGTYPE_ANY
:
6579 case CIRRUS_REGTYPE_MVF
:
6580 return cirrus_mvf_register (reg
);
6582 case CIRRUS_REGTYPE_MVFX
:
6583 return cirrus_mvfx_register (reg
);
6585 case CIRRUS_REGTYPE_MVD
:
6586 return cirrus_mvd_register (reg
);
6588 case CIRRUS_REGTYPE_MVDX
:
6589 return cirrus_mvdx_register (reg
);
6591 case CIRRUS_REGTYPE_MVAX
:
6592 return cirrus_mvax_register (reg
);
6594 case CIRRUS_REGTYPE_DSPSC
:
6595 return ARM_EXT_MAVERICKsc_register (reg
);
6601 /* A register must be given at this point.
6603 If the register is a Cirrus register, convert it's reg# appropriately.
6605 Shift is the place to put it in inst.instruction.
6607 regtype is type register type expected, and is:
6613 CIRRUS_REGTYPE_DSPSC
6615 Restores input start point on err.
6616 Returns the reg#, or FAIL. */
6619 cirrus_reg_required_here (str
, shift
, regtype
)
6622 enum cirrus_regtype regtype
;
6624 static char buff
[135]; /* XXX */
6626 char * start
= * str
;
6628 if ((reg
= arm_reg_parse (str
)) != FAIL
6629 && (int_register (reg
)
6630 || cirrus_register (reg
)))
6634 /* Calculate actual register # for opcode. */
6635 if (cirrus_register (reg
)
6636 && !ARM_EXT_MAVERICKsc_register (reg
)) /* Leave this one as is. */
6640 else if (reg
>= 110)
6650 if (!cirrus_valid_reg (orig_reg
, regtype
))
6652 sprintf (buff
, _("invalid register type at '%.100s'"), start
);
6658 inst
.instruction
|= reg
<< shift
;
6663 /* Restore the start point, we may have got a reg of the wrong class. */
6666 /* In the few cases where we might be able to accept something else
6667 this error can be overridden. */
6668 sprintf (buff
, _("Cirrus register expected, not '%.100s'"), start
);
6674 /* Cirrus Instructions. */
6676 /* Wrapper functions. */
6682 do_c_binops (str
, CIRRUS_MODE1
);
6689 do_c_binops (str
, CIRRUS_MODE2
);
6696 do_c_binops (str
, CIRRUS_MODE3
);
6703 do_c_triple (str
, CIRRUS_MODE4
);
6710 do_c_triple (str
, CIRRUS_MODE5
);
6717 do_c_quad (str
, CIRRUS_MODE6
);
6724 do_c_dspsc (str
, CIRRUS_MODE1
);
6731 do_c_dspsc (str
, CIRRUS_MODE2
);
6738 do_c_shift (str
, CIRRUS_MODE1
);
6745 do_c_shift (str
, CIRRUS_MODE2
);
6752 do_c_ldst (str
, CIRRUS_MODE1
);
6759 do_c_ldst (str
, CIRRUS_MODE2
);
6766 do_c_ldst (str
, CIRRUS_MODE3
);
6773 do_c_ldst (str
, CIRRUS_MODE4
);
6776 /* Isnsn like "foo X,Y". */
6779 do_c_binops (str
, mode
)
6785 shift1
= mode
& 0xff;
6786 shift2
= (mode
>> 8) & 0xff;
6788 skip_whitespace (str
);
6790 if (cirrus_reg_required_here (&str
, shift1
, CIRRUS_REGTYPE_ANY
) == FAIL
6791 || skip_past_comma (&str
) == FAIL
6792 || cirrus_reg_required_here (&str
, shift2
, CIRRUS_REGTYPE_ANY
) == FAIL
)
6795 inst
.error
= BAD_ARGS
;
6801 /* Isnsn like "foo X,Y,Z". */
6804 do_c_triple (str
, mode
)
6808 int shift1
, shift2
, shift3
;
6810 shift1
= mode
& 0xff;
6811 shift2
= (mode
>> 8) & 0xff;
6812 shift3
= (mode
>> 16) & 0xff;
6814 skip_whitespace (str
);
6816 if (cirrus_reg_required_here (&str
, shift1
, CIRRUS_REGTYPE_ANY
) == FAIL
6817 || skip_past_comma (&str
) == FAIL
6818 || cirrus_reg_required_here (&str
, shift2
, CIRRUS_REGTYPE_ANY
) == FAIL
6819 || skip_past_comma (&str
) == FAIL
6820 || cirrus_reg_required_here (&str
, shift3
, CIRRUS_REGTYPE_ANY
) == FAIL
)
6823 inst
.error
= BAD_ARGS
;
6829 /* Isnsn like "foo W,X,Y,Z".
6830 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
6833 do_c_quad (str
, mode
)
6837 int shift1
, shift2
, shift3
, shift4
;
6838 enum cirrus_regtype rt
;
6840 rt
= (inst
.instruction
<< 4 == 0xe2006000
6841 || inst
.instruction
<< 4 == 0xe3006000) ? CIRRUS_REGTYPE_MVAX
6842 : CIRRUS_REGTYPE_MVFX
;
6844 shift1
= mode
& 0xff;
6845 shift2
= (mode
>> 8) & 0xff;
6846 shift3
= (mode
>> 16) & 0xff;
6847 shift4
= (mode
>> 24) & 0xff;
6849 skip_whitespace (str
);
6851 if (cirrus_reg_required_here (&str
, shift1
, CIRRUS_REGTYPE_MVAX
) == FAIL
6852 || skip_past_comma (&str
) == FAIL
6853 || cirrus_reg_required_here (&str
, shift2
, rt
) == FAIL
6854 || skip_past_comma (&str
) == FAIL
6855 || cirrus_reg_required_here (&str
, shift3
, CIRRUS_REGTYPE_MVFX
) == FAIL
6856 || skip_past_comma (&str
) == FAIL
6857 || cirrus_reg_required_here (&str
, shift4
, CIRRUS_REGTYPE_MVFX
) == FAIL
)
6860 inst
.error
= BAD_ARGS
;
6866 /* cfmvsc32<cond> DSPSC,MVFX[15:0].
6867 cfmv32sc<cond> MVFX[15:0],DSPSC. */
6870 do_c_dspsc (str
, mode
)
6876 skip_whitespace (str
);
6880 if (mode
== CIRRUS_MODE1
)
6883 if (cirrus_reg_required_here (&str
, -1, CIRRUS_REGTYPE_DSPSC
) == FAIL
6884 || skip_past_comma (&str
) == FAIL
6885 || cirrus_reg_required_here (&str
, 16, CIRRUS_REGTYPE_MVFX
) == FAIL
)
6891 if (cirrus_reg_required_here (&str
, 0, CIRRUS_REGTYPE_MVFX
) == FAIL
6892 || skip_past_comma (&str
) == FAIL
6893 || cirrus_reg_required_here (&str
, -1, CIRRUS_REGTYPE_DSPSC
) == FAIL
)
6900 inst
.error
= BAD_ARGS
;
6908 /* Cirrus shift immediate instructions.
6909 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
6910 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
6913 do_c_shift (str
, mode
)
6920 skip_whitespace (str
);
6924 if (cirrus_reg_required_here (&str
, 12,
6925 (mode
== CIRRUS_MODE1
)
6926 ? CIRRUS_REGTYPE_MVFX
6927 : CIRRUS_REGTYPE_MVDX
) == FAIL
6928 || skip_past_comma (&str
) == FAIL
6929 || cirrus_reg_required_here (&str
, 16,
6930 (mode
== CIRRUS_MODE1
)
6931 ? CIRRUS_REGTYPE_MVFX
6932 : CIRRUS_REGTYPE_MVDX
) == FAIL
6933 || skip_past_comma (&str
) == FAIL
)
6936 inst
.error
= BAD_ARGS
;
6940 /* Calculate the immediate operand.
6941 The operand is a 7bit signed number. */
6942 skip_whitespace (str
);
6947 if (!ISDIGIT (*str
) && *str
!= '-')
6949 inst
.error
= _("expecting immediate, 7bit operand");
6959 for (imm
= 0; *str
&& ISDIGIT (*str
); ++str
)
6960 imm
= imm
* 10 + *str
- '0';
6964 inst
.error
= _("immediate out of range");
6968 /* Make negative imm's into 7bit signed numbers. */
6975 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
6976 Bits 5-7 of the insn should have bits 4-6 of the immediate.
6977 Bit 4 should be 0. */
6978 imm
= (imm
& 0xf) | ((imm
& 0x70) << 1);
6980 inst
.instruction
|= imm
;
6985 cirrus_parse_offset (str
, negative
)
6994 skip_whitespace (p
);
7007 inst
.error
= _("offset expected");
7011 for (offset
= 0; *p
&& ISDIGIT (*p
); ++p
)
7012 offset
= offset
* 10 + *p
- '0';
7016 inst
.error
= _("offset out of range");
7022 return *negative
? -offset
: offset
;
7025 /* Cirrus load/store instructions.
7026 <insn><cond> CRd,[Rn,<offset>]{!}.
7027 <insn><cond> CRd,[Rn],<offset>. */
7030 do_c_ldst (str
, mode
)
7034 int offset
, negative
;
7035 enum cirrus_regtype rt
;
7037 rt
= mode
== CIRRUS_MODE1
? CIRRUS_REGTYPE_MVF
7038 : mode
== CIRRUS_MODE2
? CIRRUS_REGTYPE_MVD
7039 : mode
== CIRRUS_MODE3
? CIRRUS_REGTYPE_MVFX
7040 : mode
== CIRRUS_MODE4
? CIRRUS_REGTYPE_MVDX
: CIRRUS_REGTYPE_MVF
;
7042 skip_whitespace (str
);
7044 if (cirrus_reg_required_here (& str
, 12, rt
) == FAIL
7045 || skip_past_comma (& str
) == FAIL
7047 || reg_required_here (& str
, 16) == FAIL
)
7050 if (skip_past_comma (& str
) == SUCCESS
)
7052 /* You are here: "<offset>]{!}". */
7053 inst
.instruction
|= PRE_INDEX
;
7055 offset
= cirrus_parse_offset (&str
, &negative
);
7062 inst
.error
= _("missing ]");
7068 inst
.instruction
|= WRITE_BACK
;
7074 /* You are here: "], <offset>". */
7077 inst
.error
= _("missing ]");
7081 if (skip_past_comma (&str
) == FAIL
7082 || (offset
= cirrus_parse_offset (&str
, &negative
), inst
.error
))
7085 inst
.instruction
|= CP_T_WB
; /* Post indexed, set bit W. */
7091 inst
.instruction
|= CP_T_UD
; /* Postive, so set bit U. */
7093 inst
.instruction
|= offset
>> 2;
7099 inst
.error
= BAD_ARGS
;
7112 /* Handle the Format 4 instructions that do not have equivalents in other
7113 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
7122 skip_whitespace (str
);
7124 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7125 || skip_past_comma (&str
) == FAIL
7126 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7128 inst
.error
= BAD_ARGS
;
7132 if (skip_past_comma (&str
) != FAIL
)
7134 /* Three operand format not allowed for TST, CMN, NEG and MVN.
7135 (It isn't allowed for CMP either, but that isn't handled by this
7137 if (inst
.instruction
== T_OPCODE_TST
7138 || inst
.instruction
== T_OPCODE_CMN
7139 || inst
.instruction
== T_OPCODE_NEG
7140 || inst
.instruction
== T_OPCODE_MVN
)
7142 inst
.error
= BAD_ARGS
;
7146 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7151 inst
.error
= _("dest and source1 must be the same register");
7157 if (inst
.instruction
== T_OPCODE_MUL
7159 as_tsktsk (_("Rs and Rd must be different in MUL"));
7161 inst
.instruction
|= Rd
| (Rs
<< 3);
7169 thumb_add_sub (str
, 0);
7176 thumb_shift (str
, THUMB_ASR
);
7183 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7185 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
7186 inst
.reloc
.pc_rel
= 1;
7194 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7196 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
7197 inst
.reloc
.pc_rel
= 1;
7201 /* Find the real, Thumb encoded start of a Thumb function. */
7204 find_real_start (symbolP
)
7208 const char * name
= S_GET_NAME (symbolP
);
7209 symbolS
* new_target
;
7211 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
7212 #define STUB_NAME ".real_start_of"
7217 /* Names that start with '.' are local labels, not function entry points.
7218 The compiler may generate BL instructions to these labels because it
7219 needs to perform a branch to a far away location. */
7223 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
7224 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
7226 new_target
= symbol_find (real_start
);
7228 if (new_target
== NULL
)
7230 as_warn ("Failed to find real start of function: %s\n", name
);
7231 new_target
= symbolP
;
7243 if (my_get_expression (& inst
.reloc
.exp
, & str
))
7246 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
7247 inst
.reloc
.pc_rel
= 1;
7250 /* If the destination of the branch is a defined symbol which does not have
7251 the THUMB_FUNC attribute, then we must be calling a function which has
7252 the (interfacearm) attribute. We look for the Thumb entry point to that
7253 function and change the branch to refer to that function instead. */
7254 if ( inst
.reloc
.exp
.X_op
== O_symbol
7255 && inst
.reloc
.exp
.X_add_symbol
!= NULL
7256 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
7257 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
7258 inst
.reloc
.exp
.X_add_symbol
=
7259 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
7268 skip_whitespace (str
);
7270 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
7273 /* This sets THUMB_H2 from the top bit of reg. */
7274 inst
.instruction
|= reg
<< 3;
7276 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
7277 should cause the alignment to be checked once it is known. This is
7278 because BX PC only works if the instruction is word aligned. */
7287 thumb_mov_compare (str
, THUMB_COMPARE
);
7297 skip_whitespace (str
);
7299 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7303 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
7307 if (skip_past_comma (&str
) == FAIL
7308 || (range
= reg_list (&str
)) == FAIL
)
7311 inst
.error
= BAD_ARGS
;
7315 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
7317 /* This really doesn't seem worth it. */
7318 inst
.reloc
.type
= BFD_RELOC_NONE
;
7319 inst
.error
= _("Expression too complex");
7325 inst
.error
= _("only lo-regs valid in load/store multiple");
7329 inst
.instruction
|= (Rb
<< 8) | range
;
7337 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
7344 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
7351 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
7360 skip_whitespace (str
);
7362 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7363 || skip_past_comma (&str
) == FAIL
7365 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7366 || skip_past_comma (&str
) == FAIL
7367 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7371 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
7375 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
7383 thumb_shift (str
, THUMB_LSL
);
7390 thumb_shift (str
, THUMB_LSR
);
7397 thumb_mov_compare (str
, THUMB_MOVE
);
7406 skip_whitespace (str
);
7408 if ((range
= reg_list (&str
)) == FAIL
)
7411 inst
.error
= BAD_ARGS
;
7415 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
7417 /* This really doesn't seem worth it. */
7418 inst
.reloc
.type
= BFD_RELOC_NONE
;
7419 inst
.error
= _("Expression too complex");
7425 if ((inst
.instruction
== T_OPCODE_PUSH
7426 && (range
& ~0xff) == 1 << REG_LR
)
7427 || (inst
.instruction
== T_OPCODE_POP
7428 && (range
& ~0xff) == 1 << REG_PC
))
7430 inst
.instruction
|= THUMB_PP_PC_LR
;
7435 inst
.error
= _("invalid register list to push/pop instruction");
7440 inst
.instruction
|= range
;
7448 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
7455 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
7462 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
7469 thumb_add_sub (str
, 1);
7476 skip_whitespace (str
);
7478 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7481 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
7492 /* This is a pseudo-op of the form "adr rd, label" to be converted
7493 into a relative address of the form "add rd, pc, #label-.-4". */
7494 skip_whitespace (str
);
7496 /* Store Rd in temporary location inside instruction. */
7497 if ((reg
= reg_required_here (&str
, 4)) == FAIL
7498 || (reg
> 7) /* For Thumb reg must be r0..r7. */
7499 || skip_past_comma (&str
) == FAIL
7500 || my_get_expression (&inst
.reloc
.exp
, &str
))
7503 inst
.error
= BAD_ARGS
;
7507 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
7508 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
7509 inst
.reloc
.pc_rel
= 1;
7510 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
7519 int len
= strlen (reg_table
[entry
].name
) + 2;
7520 char * buf
= (char *) xmalloc (len
);
7521 char * buf2
= (char *) xmalloc (len
);
7524 #ifdef REGISTER_PREFIX
7525 buf
[i
++] = REGISTER_PREFIX
;
7528 strcpy (buf
+ i
, reg_table
[entry
].name
);
7530 for (i
= 0; buf
[i
]; i
++)
7531 buf2
[i
] = TOUPPER (buf
[i
]);
7535 hash_insert (arm_reg_hsh
, buf
, (PTR
) & reg_table
[entry
]);
7536 hash_insert (arm_reg_hsh
, buf2
, (PTR
) & reg_table
[entry
]);
7540 insert_reg_alias (str
, regnum
)
7544 struct reg_entry
*new =
7545 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
7546 char *name
= xmalloc (strlen (str
) + 1);
7550 new->number
= regnum
;
7552 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
7556 set_constant_flonums ()
7560 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
7561 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
7565 /* Iterate over the base tables to create the instruction patterns. */
7567 build_arm_ops_hsh ()
7571 static struct obstack insn_obstack
;
7573 obstack_begin (&insn_obstack
, 4000);
7575 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
7577 CONST
struct asm_opcode
*insn
= insns
+ i
;
7579 if (insn
->cond_offset
!= 0)
7581 /* Insn supports conditional execution. Build the varaints
7582 and insert them in the hash table. */
7583 for (j
= 0; j
< sizeof (conds
) / sizeof (struct asm_cond
); j
++)
7585 unsigned len
= strlen (insn
->template);
7586 struct asm_opcode
*new;
7589 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
7590 /* All condition codes are two characters. */
7591 template = obstack_alloc (&insn_obstack
, len
+ 3);
7593 strncpy (template, insn
->template, insn
->cond_offset
);
7594 strcpy (template + insn
->cond_offset
, conds
[j
].template);
7595 if (len
> insn
->cond_offset
)
7596 strcpy (template + insn
->cond_offset
+ 2,
7597 insn
->template + insn
->cond_offset
);
7598 new->template = template;
7599 new->cond_offset
= 0;
7600 new->variant
= insn
->variant
;
7601 new->parms
= insn
->parms
;
7602 new->value
= (insn
->value
& ~COND_MASK
) | conds
[j
].value
;
7604 hash_insert (arm_ops_hsh
, new->template, (PTR
) new);
7607 /* Finally, insert the unconditional insn in the table directly;
7608 no need to build a copy. */
7609 hash_insert (arm_ops_hsh
, insn
->template, (PTR
) insn
);
7619 if ( (arm_ops_hsh
= hash_new ()) == NULL
7620 || (arm_tops_hsh
= hash_new ()) == NULL
7621 || (arm_cond_hsh
= hash_new ()) == NULL
7622 || (arm_shift_hsh
= hash_new ()) == NULL
7623 || (arm_reg_hsh
= hash_new ()) == NULL
7624 || (arm_psr_hsh
= hash_new ()) == NULL
)
7625 as_fatal (_("Virtual memory exhausted"));
7627 build_arm_ops_hsh ();
7628 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
7629 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
7630 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
7631 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
7632 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
7633 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
7634 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
7635 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
7637 for (i
= 0; reg_table
[i
].name
; i
++)
7640 set_constant_flonums ();
7642 #if defined OBJ_COFF || defined OBJ_ELF
7644 unsigned int flags
= 0;
7646 /* Set the flags in the private structure. */
7647 if (uses_apcs_26
) flags
|= F_APCS26
;
7648 if (support_interwork
) flags
|= F_INTERWORK
;
7649 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
7650 if (pic_code
) flags
|= F_PIC
;
7651 if ((cpu_variant
& FPU_ANY
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
7653 bfd_set_private_flags (stdoutput
, flags
);
7655 /* We have run out flags in the COFF header to encode the
7656 status of ATPCS support, so instead we create a dummy,
7657 empty, debug section called .arm.atpcs. */
7662 sec
= bfd_make_section (stdoutput
, ".arm.atpcs");
7666 bfd_set_section_flags
7667 (stdoutput
, sec
, SEC_READONLY
| SEC_DEBUGGING
/* | SEC_HAS_CONTENTS */);
7668 bfd_set_section_size (stdoutput
, sec
, 0);
7669 bfd_set_section_contents (stdoutput
, sec
, NULL
, 0, 0);
7675 /* Record the CPU type as well. */
7676 switch (cpu_variant
& ARM_CPU_MASK
)
7679 mach
= bfd_mach_arm_2
;
7682 case ARM_3
: /* Also ARM_250. */
7683 mach
= bfd_mach_arm_2a
;
7686 case ARM_6
: /* Also ARM_7. */
7687 mach
= bfd_mach_arm_3
;
7691 mach
= bfd_mach_arm_4
;
7696 /* Catch special cases. */
7697 if (cpu_variant
& ARM_EXT_XSCALE
)
7698 mach
= bfd_mach_arm_XScale
;
7699 else if (cpu_variant
& ARM_EXT_V5E
)
7700 mach
= bfd_mach_arm_5TE
;
7701 else if (cpu_variant
& ARM_EXT_V5
)
7703 if (cpu_variant
& ARM_EXT_V4T
)
7704 mach
= bfd_mach_arm_5T
;
7706 mach
= bfd_mach_arm_5
;
7708 else if (cpu_variant
& ARM_EXT_V4
)
7710 if (cpu_variant
& ARM_EXT_V4T
)
7711 mach
= bfd_mach_arm_4T
;
7713 mach
= bfd_mach_arm_4
;
7715 else if (cpu_variant
& ARM_EXT_V3M
)
7716 mach
= bfd_mach_arm_3M
;
7718 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
7721 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
7722 for use in the a.out file, and stores them in the array pointed to by buf.
7723 This knows about the endian-ness of the target machine and does
7724 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
7725 2 (short) and 4 (long) Floating numbers are put out as a series of
7726 LITTLENUMS (shorts, here at least). */
7729 md_number_to_chars (buf
, val
, n
)
7734 if (target_big_endian
)
7735 number_to_chars_bigendian (buf
, val
, n
);
7737 number_to_chars_littleendian (buf
, val
, n
);
7741 md_chars_to_number (buf
, n
)
7746 unsigned char * where
= (unsigned char *) buf
;
7748 if (target_big_endian
)
7753 result
|= (*where
++ & 255);
7761 result
|= (where
[n
] & 255);
7768 /* Turn a string in input_line_pointer into a floating point constant
7769 of type TYPE, and store the appropriate bytes in *LITP. The number
7770 of LITTLENUMS emitted is stored in *SIZEP. An error message is
7771 returned, or NULL on OK.
7773 Note that fp constants aren't represent in the normal way on the ARM.
7774 In big endian mode, things are as expected. However, in little endian
7775 mode fp constants are big-endian word-wise, and little-endian byte-wise
7776 within the words. For example, (double) 1.1 in big endian mode is
7777 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
7778 the byte sequence 99 99 f1 3f 9a 99 99 99.
7780 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
7783 md_atof (type
, litP
, sizeP
)
7789 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
7821 return _("Bad call to MD_ATOF()");
7824 t
= atof_ieee (input_line_pointer
, type
, words
);
7826 input_line_pointer
= t
;
7829 if (target_big_endian
)
7831 for (i
= 0; i
< prec
; i
++)
7833 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
7839 /* For a 4 byte float the order of elements in `words' is 1 0. For an
7840 8 byte float the order is 1 0 3 2. */
7841 for (i
= 0; i
< prec
; i
+= 2)
7843 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
7844 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
7852 /* The knowledge of the PC's pipeline offset is built into the insns
7856 md_pcrel_from (fixP
)
7860 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
7861 && fixP
->fx_subsy
== NULL
)
7864 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
7866 /* PC relative addressing on the Thumb is slightly odd
7867 as the bottom two bits of the PC are forced to zero
7868 for the calculation. */
7869 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
7873 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
7874 so we un-adjust here to compensate for the accomodation. */
7875 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
7877 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
7881 /* Round up a section size to the appropriate boundary. */
7884 md_section_align (segment
, size
)
7885 segT segment ATTRIBUTE_UNUSED
;
7891 /* Round all sects to multiple of 4. */
7892 return (size
+ 3) & ~3;
7896 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
7897 Otherwise we have no need to default values of symbols. */
7900 md_undefined_symbol (name
)
7901 char * name ATTRIBUTE_UNUSED
;
7904 if (name
[0] == '_' && name
[1] == 'G'
7905 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
7909 if (symbol_find (name
))
7910 as_bad ("GOT already in the symbol table");
7912 GOT_symbol
= symbol_new (name
, undefined_section
,
7913 (valueT
) 0, & zero_address_frag
);
7923 /* arm_reg_parse () := if it looks like a register, return its token and
7924 advance the pointer. */
7928 register char ** ccp
;
7930 char * start
= * ccp
;
7933 struct reg_entry
* reg
;
7935 #ifdef REGISTER_PREFIX
7936 if (*start
!= REGISTER_PREFIX
)
7941 #ifdef OPTIONAL_REGISTER_PREFIX
7942 if (*p
== OPTIONAL_REGISTER_PREFIX
)
7946 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
7950 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
7954 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
7967 md_apply_fix3 (fixP
, valP
, seg
)
7972 offsetT value
= * valP
;
7974 unsigned int newimm
;
7977 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
7978 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
7980 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
7982 /* Note whether this will delete the relocation. */
7984 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
7985 doesn't work fully.) */
7986 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
7989 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
7993 /* If this symbol is in a different section then we need to leave it for
7994 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
7995 so we have to undo it's effects here. */
7998 if (fixP
->fx_addsy
!= NULL
7999 && S_IS_DEFINED (fixP
->fx_addsy
)
8000 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
8003 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
8004 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
8008 value
+= md_pcrel_from (fixP
);
8012 /* Remember value for emit_reloc. */
8013 fixP
->fx_addnumber
= value
;
8015 switch (fixP
->fx_r_type
)
8017 case BFD_RELOC_ARM_IMMEDIATE
:
8018 newimm
= validate_immediate (value
);
8019 temp
= md_chars_to_number (buf
, INSN_SIZE
);
8021 /* If the instruction will fail, see if we can fix things up by
8022 changing the opcode. */
8023 if (newimm
== (unsigned int) FAIL
8024 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
8026 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8027 _("invalid constant (%lx) after fixup"),
8028 (unsigned long) value
);
8032 newimm
|= (temp
& 0xfffff000);
8033 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
8036 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
8038 unsigned int highpart
= 0;
8039 unsigned int newinsn
= 0xe1a00000; /* nop. */
8040 newimm
= validate_immediate (value
);
8041 temp
= md_chars_to_number (buf
, INSN_SIZE
);
8043 /* If the instruction will fail, see if we can fix things up by
8044 changing the opcode. */
8045 if (newimm
== (unsigned int) FAIL
8046 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
8048 /* No ? OK - try using two ADD instructions to generate
8050 newimm
= validate_immediate_twopart (value
, & highpart
);
8052 /* Yes - then make sure that the second instruction is
8054 if (newimm
!= (unsigned int) FAIL
)
8056 /* Still No ? Try using a negated value. */
8057 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
8058 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
8059 /* Otherwise - give up. */
8062 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8063 _("Unable to compute ADRL instructions for PC offset of 0x%lx"),
8068 /* Replace the first operand in the 2nd instruction (which
8069 is the PC) with the destination register. We have
8070 already added in the PC in the first instruction and we
8071 do not want to do it again. */
8072 newinsn
&= ~ 0xf0000;
8073 newinsn
|= ((newinsn
& 0x0f000) << 4);
8076 newimm
|= (temp
& 0xfffff000);
8077 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
8079 highpart
|= (newinsn
& 0xfffff000);
8080 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
8084 case BFD_RELOC_ARM_OFFSET_IMM
:
8090 if (validate_offset_imm (value
, 0) == FAIL
)
8092 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8093 _("bad immediate value for offset (%ld)"),
8098 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8099 newval
&= 0xff7ff000;
8100 newval
|= value
| (sign
? INDEX_UP
: 0);
8101 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8104 case BFD_RELOC_ARM_OFFSET_IMM8
:
8105 case BFD_RELOC_ARM_HWLITERAL
:
8111 if (validate_offset_imm (value
, 1) == FAIL
)
8113 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
8114 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8115 _("invalid literal constant: pool needs to be closer"));
8117 as_bad (_("bad immediate value for half-word offset (%ld)"),
8122 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8123 newval
&= 0xff7ff0f0;
8124 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
8125 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8128 case BFD_RELOC_ARM_LITERAL
:
8134 if (validate_offset_imm (value
, 0) == FAIL
)
8136 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8137 _("invalid literal constant: pool needs to be closer"));
8141 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8142 newval
&= 0xff7ff000;
8143 newval
|= value
| (sign
? INDEX_UP
: 0);
8144 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8147 case BFD_RELOC_ARM_SHIFT_IMM
:
8148 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8149 if (((unsigned long) value
) > 32
8151 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
8153 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8154 _("shift expression is too large"));
8159 /* Shifts of zero must be done as lsl. */
8161 else if (value
== 32)
8163 newval
&= 0xfffff07f;
8164 newval
|= (value
& 0x1f) << 7;
8165 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8168 case BFD_RELOC_ARM_SWI
:
8169 if (arm_data
->thumb_mode
)
8171 if (((unsigned long) value
) > 0xff)
8172 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8173 _("Invalid swi expression"));
8174 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
8176 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8180 if (((unsigned long) value
) > 0x00ffffff)
8181 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8182 _("Invalid swi expression"));
8183 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
8185 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8189 case BFD_RELOC_ARM_MULTI
:
8190 if (((unsigned long) value
) > 0xffff)
8191 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8192 _("Invalid expression in load/store multiple"));
8193 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
8194 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8197 case BFD_RELOC_ARM_PCREL_BRANCH
:
8198 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8200 /* Sign-extend a 24-bit number. */
8201 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
8205 value
= fixP
->fx_offset
;
8208 /* We are going to store value (shifted right by two) in the
8209 instruction, in a 24 bit, signed field. Thus we need to check
8210 that none of the top 8 bits of the shifted value (top 7 bits of
8211 the unshifted, unsigned value) are set, or that they are all set. */
8212 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
8213 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
8216 /* Normally we would be stuck at this point, since we cannot store
8217 the absolute address that is the destination of the branch in the
8218 24 bits of the branch instruction. If however, we happen to know
8219 that the destination of the branch is in the same section as the
8220 branch instruciton itself, then we can compute the relocation for
8221 ourselves and not have to bother the linker with it.
8223 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
8224 because I have not worked out how to do this for OBJ_COFF or
8227 && fixP
->fx_addsy
!= NULL
8228 && S_IS_DEFINED (fixP
->fx_addsy
)
8229 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
8231 /* Get pc relative value to go into the branch. */
8234 /* Permit a backward branch provided that enough bits
8235 are set. Allow a forwards branch, provided that
8236 enough bits are clear. */
8237 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
8238 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
8242 if (! fixP
->fx_done
)
8244 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8245 _("gas can't handle same-section branch dest >= 0x04000000"));
8249 value
+= SEXT24 (newval
);
8251 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
8252 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
8253 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8254 _("out of range branch"));
8256 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
8257 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8260 case BFD_RELOC_ARM_PCREL_BLX
:
8263 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8267 value
= fixP
->fx_offset
;
8269 hbit
= (value
>> 1) & 1;
8270 value
= (value
>> 2) & 0x00ffffff;
8271 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
8272 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
8273 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8277 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
8278 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8280 addressT diff
= (newval
& 0xff) << 1;
8285 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
8286 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8287 _("Branch out of range"));
8288 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
8290 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8293 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
8294 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8296 addressT diff
= (newval
& 0x7ff) << 1;
8301 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
8302 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8303 _("Branch out of range"));
8304 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
8306 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8309 case BFD_RELOC_THUMB_PCREL_BLX
:
8310 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
8315 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8316 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
8317 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
8318 if (diff
& 0x400000)
8321 value
= fixP
->fx_offset
;
8324 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
8325 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8326 _("Branch with link out of range"));
8328 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
8329 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
8330 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
)
8331 /* Remove bit zero of the adjusted offset. Bit zero can only be
8332 set if the upper insn is at a half-word boundary, since the
8333 destination address, an ARM instruction, must always be on a
8334 word boundary. The semantics of the BLX (1) instruction, however,
8335 are that bit zero in the offset must always be zero, and the
8336 corresponding bit one in the target address will be set from bit
8337 one of the source address. */
8339 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8340 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
8345 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
8346 md_number_to_chars (buf
, value
, 1);
8348 else if (!target_oabi
)
8350 value
= fixP
->fx_offset
;
8351 md_number_to_chars (buf
, value
, 1);
8357 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
8358 md_number_to_chars (buf
, value
, 2);
8360 else if (!target_oabi
)
8362 value
= fixP
->fx_offset
;
8363 md_number_to_chars (buf
, value
, 2);
8369 case BFD_RELOC_ARM_GOT32
:
8370 case BFD_RELOC_ARM_GOTOFF
:
8371 md_number_to_chars (buf
, 0, 4);
8377 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
8378 md_number_to_chars (buf
, value
, 4);
8380 else if (!target_oabi
)
8382 value
= fixP
->fx_offset
;
8383 md_number_to_chars (buf
, value
, 4);
8389 case BFD_RELOC_ARM_PLT32
:
8390 /* It appears the instruction is fully prepared at this point. */
8394 case BFD_RELOC_ARM_GOTPC
:
8395 md_number_to_chars (buf
, value
, 4);
8398 case BFD_RELOC_ARM_CP_OFF_IMM
:
8400 if (value
< -1023 || value
> 1023 || (value
& 3))
8401 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8402 _("Illegal value for co-processor offset"));
8405 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
8406 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
8407 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8410 case BFD_RELOC_ARM_THUMB_OFFSET
:
8411 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8412 /* Exactly what ranges, and where the offset is inserted depends
8413 on the type of instruction, we can establish this from the
8415 switch (newval
>> 12)
8417 case 4: /* PC load. */
8418 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
8419 forced to zero for these loads, so we will need to round
8420 up the offset if the instruction address is not word
8421 aligned (since the final address produced must be, and
8422 we can only describe word-aligned immediate offsets). */
8424 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
8425 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8426 _("Invalid offset, target not word aligned (0x%08X)"),
8427 (unsigned int) (fixP
->fx_frag
->fr_address
8428 + fixP
->fx_where
+ value
));
8430 if ((value
+ 2) & ~0x3fe)
8431 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8432 _("Invalid offset, value too big (0x%08lX)"), value
);
8434 /* Round up, since pc will be rounded down. */
8435 newval
|= (value
+ 2) >> 2;
8438 case 9: /* SP load/store. */
8440 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8441 _("Invalid offset, value too big (0x%08lX)"), value
);
8442 newval
|= value
>> 2;
8445 case 6: /* Word load/store. */
8447 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8448 _("Invalid offset, value too big (0x%08lX)"), value
);
8449 newval
|= value
<< 4; /* 6 - 2. */
8452 case 7: /* Byte load/store. */
8454 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8455 _("Invalid offset, value too big (0x%08lX)"), value
);
8456 newval
|= value
<< 6;
8459 case 8: /* Halfword load/store. */
8461 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8462 _("Invalid offset, value too big (0x%08lX)"), value
);
8463 newval
|= value
<< 5; /* 6 - 1. */
8467 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8468 "Unable to process relocation for thumb opcode: %lx",
8469 (unsigned long) newval
);
8472 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8475 case BFD_RELOC_ARM_THUMB_ADD
:
8476 /* This is a complicated relocation, since we use it for all of
8477 the following immediate relocations:
8481 9bit ADD/SUB SP word-aligned
8482 10bit ADD PC/SP word-aligned
8484 The type of instruction being processed is encoded in the
8491 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8493 int rd
= (newval
>> 4) & 0xf;
8494 int rs
= newval
& 0xf;
8495 int subtract
= newval
& 0x8000;
8500 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8501 _("Invalid immediate for stack address calculation"));
8502 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
8503 newval
|= value
>> 2;
8505 else if (rs
== REG_PC
|| rs
== REG_SP
)
8509 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8510 _("Invalid immediate for address calculation (value = 0x%08lX)"),
8511 (unsigned long) value
);
8512 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
8514 newval
|= value
>> 2;
8519 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8520 _("Invalid 8bit immediate"));
8521 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
8522 newval
|= (rd
<< 8) | value
;
8527 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8528 _("Invalid 3bit immediate"));
8529 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
8530 newval
|= rd
| (rs
<< 3) | (value
<< 6);
8533 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8536 case BFD_RELOC_ARM_THUMB_IMM
:
8537 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8538 switch (newval
>> 11)
8540 case 0x04: /* 8bit immediate MOV. */
8541 case 0x05: /* 8bit immediate CMP. */
8542 if (value
< 0 || value
> 255)
8543 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8544 _("Invalid immediate: %ld is too large"),
8552 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8555 case BFD_RELOC_ARM_THUMB_SHIFT
:
8556 /* 5bit shift value (0..31). */
8557 if (value
< 0 || value
> 31)
8558 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8559 _("Illegal Thumb shift value: %ld"), (long) value
);
8560 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
8561 newval
|= value
<< 6;
8562 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8565 case BFD_RELOC_VTABLE_INHERIT
:
8566 case BFD_RELOC_VTABLE_ENTRY
:
8570 case BFD_RELOC_NONE
:
8572 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8573 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
8577 /* Translate internal representation of relocation info to BFD target
8581 tc_gen_reloc (section
, fixp
)
8582 asection
* section ATTRIBUTE_UNUSED
;
8586 bfd_reloc_code_real_type code
;
8588 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
8590 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
8591 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
8592 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
8594 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
8596 if (fixp
->fx_pcrel
== 0)
8597 reloc
->addend
= fixp
->fx_offset
;
8599 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
8601 reloc
->addend
= fixp
->fx_offset
;
8604 switch (fixp
->fx_r_type
)
8609 code
= BFD_RELOC_8_PCREL
;
8616 code
= BFD_RELOC_16_PCREL
;
8623 code
= BFD_RELOC_32_PCREL
;
8627 case BFD_RELOC_ARM_PCREL_BRANCH
:
8628 case BFD_RELOC_ARM_PCREL_BLX
:
8630 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
8631 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
8632 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
8633 case BFD_RELOC_THUMB_PCREL_BLX
:
8634 case BFD_RELOC_VTABLE_ENTRY
:
8635 case BFD_RELOC_VTABLE_INHERIT
:
8636 code
= fixp
->fx_r_type
;
8639 case BFD_RELOC_ARM_LITERAL
:
8640 case BFD_RELOC_ARM_HWLITERAL
:
8641 /* If this is called then the a literal has been referenced across
8642 a section boundary - possibly due to an implicit dump. */
8643 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8644 _("Literal referenced across section boundary (Implicit dump?)"));
8648 case BFD_RELOC_ARM_GOT32
:
8649 case BFD_RELOC_ARM_GOTOFF
:
8650 case BFD_RELOC_ARM_PLT32
:
8651 code
= fixp
->fx_r_type
;
8655 case BFD_RELOC_ARM_IMMEDIATE
:
8656 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8657 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
8661 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
8662 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8663 _("ADRL used for a symbol not defined in the same file"));
8666 case BFD_RELOC_ARM_OFFSET_IMM
:
8667 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8668 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
8676 switch (fixp
->fx_r_type
)
8678 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
8679 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
8680 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
8681 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
8682 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
8683 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
8684 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
8685 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
8686 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
8687 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
8688 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
8689 default: type
= _("<unknown>"); break;
8691 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8692 _("Cannot represent %s relocation in this object file format"),
8699 if (code
== BFD_RELOC_32_PCREL
8701 && fixp
->fx_addsy
== GOT_symbol
)
8703 code
= BFD_RELOC_ARM_GOTPC
;
8704 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
8708 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
8710 if (reloc
->howto
== NULL
)
8712 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8713 _("Can not represent %s relocation in this object file format"),
8714 bfd_get_reloc_code_name (code
));
8718 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
8719 vtable entry to be used in the relocation's section offset. */
8720 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
8721 reloc
->address
= fixp
->fx_offset
;
8727 md_estimate_size_before_relax (fragP
, segtype
)
8728 fragS
* fragP ATTRIBUTE_UNUSED
;
8729 segT segtype ATTRIBUTE_UNUSED
;
8731 as_fatal (_("md_estimate_size_before_relax\n"));
8736 output_inst
PARAMS ((void))
8742 as_bad (inst
.error
);
8746 to
= frag_more (inst
.size
);
8748 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
8750 assert (inst
.size
== (2 * THUMB_SIZE
));
8751 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
8752 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
8754 else if (inst
.size
> INSN_SIZE
)
8756 assert (inst
.size
== (2 * INSN_SIZE
));
8757 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
8758 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
8761 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
8763 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
8764 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
8765 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
8769 dwarf2_emit_insn (inst
.size
);
8782 /* Align the instruction.
8783 This may not be the right thing to do but ... */
8787 listing_prev_line (); /* Defined in listing.h. */
8789 /* Align the previous label if needed. */
8790 if (last_label_seen
!= NULL
)
8792 symbol_set_frag (last_label_seen
, frag_now
);
8793 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
8794 S_SET_SEGMENT (last_label_seen
, now_seg
);
8797 memset (&inst
, '\0', sizeof (inst
));
8798 inst
.reloc
.type
= BFD_RELOC_NONE
;
8800 skip_whitespace (str
);
8802 /* Scan up to the end of the op-code, which must end in white space or
8804 for (start
= p
= str
; *p
!= '\0'; p
++)
8810 as_bad (_("No operator -- statement `%s'\n"), str
);
8816 const struct thumb_opcode
* opcode
;
8820 opcode
= (const struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
8825 /* Check that this instruction is supported for this CPU. */
8826 if (thumb_mode
== 1 && (opcode
->variant
& cpu_variant
) == 0)
8828 as_bad (_("selected processor does not support this opcode"));
8832 inst
.instruction
= opcode
->value
;
8833 inst
.size
= opcode
->size
;
8834 (*opcode
->parms
) (p
);
8841 const struct asm_opcode
* opcode
;
8845 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
8850 /* Check that this instruction is supported for this CPU. */
8851 if ((opcode
->variant
& cpu_variant
) == 0)
8853 as_bad (_("selected processor does not support this opcode"));
8857 inst
.instruction
= opcode
->value
;
8858 inst
.size
= INSN_SIZE
;
8859 (*opcode
->parms
) (p
);
8865 /* It wasn't an instruction, but it might be a register alias of the form
8868 skip_whitespace (q
);
8873 if (*q
&& !strncmp (q
, ".req ", 4))
8879 #ifdef IGNORE_OPCODE_CASE
8880 str
= original_case_string
;
8885 skip_whitespace (q
);
8887 for (r
= q
; *r
!= '\0'; r
++)
8897 regnum
= arm_reg_parse (& q
);
8900 reg
= arm_reg_parse (& str
);
8905 insert_reg_alias (str
, regnum
);
8907 as_warn (_("register '%s' does not exist\n"), q
);
8909 else if (regnum
!= FAIL
)
8912 as_warn (_("ignoring redefinition of register alias '%s'"),
8915 /* Do not warn about redefinitions to the same alias. */
8918 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
8922 as_warn (_("ignoring incomplete .req pseuso op"));
8929 as_bad (_("bad instruction `%s'"), start
);
8933 Invocation line includes a switch not recognized by the base assembler.
8934 See if it's a processor-specific option. These are:
8935 Cpu variants, the arm part is optional:
8936 -m[arm]1 Currently not supported.
8937 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
8938 -m[arm]3 Arm 3 processor
8939 -m[arm]6[xx], Arm 6 processors
8940 -m[arm]7[xx][t][[d]m] Arm 7 processors
8941 -m[arm]8[10] Arm 8 processors
8942 -m[arm]9[20][tdmi] Arm 9 processors
8943 -marm9e Allow Cirrus/DSP instructions
8944 -mstrongarm[110[0]] StrongARM processors
8945 -mxscale XScale processors
8946 -m[arm]v[2345[t[e]]] Arm architectures
8947 -mall All (except the ARM1)
8949 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
8950 -mfpe-old (No float load/store multiples)
8951 -mno-fpu Disable all floating point instructions
8952 Run-time endian selection:
8954 -EL little endian cpu
8955 ARM Procedure Calling Standard:
8956 -mapcs-32 32 bit APCS
8957 -mapcs-26 26 bit APCS
8958 -mapcs-float Pass floats in float regs
8959 -mapcs-reentrant Position independent code
8960 -mthumb-interwork Code supports Arm/Thumb interworking
8961 -matpcs ARM/Thumb Procedure Call Standard
8962 -moabi Old ELF ABI */
8964 const char * md_shortopts
= "m:k";
8966 struct option md_longopts
[] =
8968 #ifdef ARM_BI_ENDIAN
8969 #define OPTION_EB (OPTION_MD_BASE + 0)
8970 {"EB", no_argument
, NULL
, OPTION_EB
},
8971 #define OPTION_EL (OPTION_MD_BASE + 1)
8972 {"EL", no_argument
, NULL
, OPTION_EL
},
8974 #define OPTION_OABI (OPTION_MD_BASE +2)
8975 {"oabi", no_argument
, NULL
, OPTION_OABI
},
8978 {NULL
, no_argument
, NULL
, 0}
8981 size_t md_longopts_size
= sizeof (md_longopts
);
8984 md_parse_option (c
, arg
)
8992 #ifdef ARM_BI_ENDIAN
8994 target_big_endian
= 1;
8997 target_big_endian
= 0;
9005 if (streq (str
, "fpa10") || streq (str
, "fpa11"))
9006 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_ARCH_FPA
;
9007 else if (streq (str
, "fpe-old"))
9008 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_ARCH_FPE
;
9014 if (streq (str
, "no-fpu"))
9015 cpu_variant
&= ~FPU_ANY
;
9020 if (streq (str
, "oabi"))
9026 /* Limit assembler to generating only Thumb instructions: */
9027 if (streq (str
, "thumb"))
9029 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_EXT_V4T
;
9030 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_NONE
;
9033 else if (streq (str
, "thumb-interwork"))
9035 if ((cpu_variant
& ARM_EXT_V4T
) == 0)
9036 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
9037 #if defined OBJ_COFF || defined OBJ_ELF
9038 support_interwork
= true;
9046 if (streq (str
, "all"))
9048 cpu_variant
= ARM_ALL
| FPU_DEFAULT
;
9051 #if defined OBJ_COFF || defined OBJ_ELF
9052 if (! strncmp (str
, "apcs-", 5))
9054 /* GCC passes on all command line options starting "-mapcs-..."
9055 to us, so we must parse them here. */
9059 if (streq (str
, "32"))
9061 uses_apcs_26
= false;
9064 else if (streq (str
, "26"))
9066 uses_apcs_26
= true;
9069 else if (streq (str
, "frame"))
9071 /* Stack frames are being generated - does not affect
9075 else if (streq (str
, "stack-check"))
9077 /* Stack checking is being performed - does not affect
9078 linkage, but does require that the functions
9079 __rt_stkovf_split_small and __rt_stkovf_split_big be
9080 present in the final link. */
9084 else if (streq (str
, "float"))
9086 /* Floating point arguments are being passed in the floating
9087 point registers. This does affect linking, since this
9088 version of the APCS is incompatible with the version that
9089 passes floating points in the integer registers. */
9091 uses_apcs_float
= true;
9094 else if (streq (str
, "reentrant"))
9096 /* Reentrant code has been generated. This does affect
9097 linking, since there is no point in linking reentrant/
9098 position independent code with absolute position code. */
9103 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
9107 if (! strcmp (str
, "atpcs"))
9113 /* Strip off optional "arm". */
9114 if (! strncmp (str
, "arm", 3))
9120 if (streq (str
, "1"))
9121 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
9127 if (streq (str
, "2"))
9128 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
9129 else if (streq (str
, "250"))
9130 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
9136 if (streq (str
, "3"))
9137 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
9143 switch (strtol (str
, NULL
, 10))
9150 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
9158 /* Eat the processor name. */
9159 switch (strtol (str
, & str
, 10))
9172 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
9178 cpu_variant
|= ARM_ARCH_V4T
;
9182 cpu_variant
|= ARM_EXT_V3M
;
9185 case 'f': /* fe => fp enabled cpu. */
9191 case 'c': /* Left over from 710c processor name. */
9192 case 'd': /* Debug. */
9193 case 'i': /* Embedded ICE. */
9194 /* Included for completeness in ARM processor naming. */
9204 if (streq (str
, "8") || streq (str
, "810"))
9205 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9206 | ARM_8
| ARM_ARCH_V4
;
9212 if (streq (str
, "9"))
9213 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9214 | ARM_9
| ARM_ARCH_V4T
;
9215 else if (streq (str
, "920"))
9216 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9217 | ARM_9
| ARM_ARCH_V4
;
9218 else if (streq (str
, "920t"))
9219 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9220 | ARM_9
| ARM_ARCH_V4T
;
9221 else if (streq (str
, "9tdmi"))
9222 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9223 | ARM_9
| ARM_ARCH_V4T
;
9224 else if (streq (str
, "9e"))
9225 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9226 | ARM_9
| ARM_ARCH_V4T
| ARM_EXT_MAVERICK
;
9232 if (streq (str
, "strongarm")
9233 || streq (str
, "strongarm110")
9234 || streq (str
, "strongarm1100"))
9235 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9236 | ARM_8
| ARM_ARCH_V4
;
9242 if (streq (str
, "xscale"))
9243 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9244 | ARM_9
| ARM_ARCH_XSCALE
;
9250 /* Select variant based on architecture rather than
9258 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
9261 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
9264 as_bad (_("Invalid architecture variant -m%s"), arg
);
9270 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
9274 case 'm': cpu_variant
|= ARM_EXT_V3M
; break;
9277 as_bad (_("Invalid architecture variant -m%s"), arg
);
9283 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCH_V4
;
9287 case 't': cpu_variant
|= ARM_EXT_V4T
; break;
9290 as_bad (_("Invalid architecture variant -m%s"), arg
);
9296 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V5
;
9299 case 't': cpu_variant
|= ARM_EXT_V4T
; break;
9300 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
9303 as_bad (_("Invalid architecture variant -m%s"), arg
);
9309 as_bad (_("Invalid architecture variant -m%s"), arg
);
9316 as_bad (_("Invalid processor variant -m%s"), arg
);
9322 #if defined OBJ_ELF || defined OBJ_COFF
9340 ARM Specific Assembler Options:\n\
9341 -m[arm][<processor name>] select processor variant\n\
9342 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
9343 -marm9e allow Cirrus/DSP instructions\n\
9344 -mthumb only allow Thumb instructions\n\
9345 -mthumb-interwork mark the assembled code as supporting interworking\n\
9346 -mall allow any instruction\n\
9347 -mfpa10, -mfpa11 select floating point architecture\n\
9348 -mfpe-old don't allow floating-point multiple instructions\n\
9349 -mno-fpu don't allow any floating-point instructions.\n\
9350 -k generate PIC code.\n"));
9351 #if defined OBJ_COFF || defined OBJ_ELF
9353 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
9354 -matpcs use ARM/Thumb Procedure Calling Standard\n\
9355 -mapcs-float floating point args are passed in FP regs\n\
9356 -mapcs-reentrant the code is position independent/reentrant\n"));
9360 -moabi support the old ELF ABI\n"));
9362 #ifdef ARM_BI_ENDIAN
9364 -EB assemble code for a big endian cpu\n\
9365 -EL assemble code for a little endian cpu\n"));
9369 /* We need to be able to fix up arbitrary expressions in some statements.
9370 This is so that we can handle symbols that are an arbitrary distance from
9371 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
9372 which returns part of an address in a form which will be valid for
9373 a data instruction. We do this by pushing the expression into a symbol
9374 in the expr_section, and creating a fix for that. */
9377 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
9386 arm_fix_data
* arm_data
;
9394 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
9398 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
9403 /* Mark whether the fix is to a THUMB instruction, or an ARM
9405 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
9406 new_fix
->tc_fix_data
= (PTR
) arm_data
;
9407 arm_data
->thumb_mode
= thumb_mode
;
9412 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
9415 cons_fix_new_arm (frag
, where
, size
, exp
)
9421 bfd_reloc_code_real_type type
;
9425 FIXME: @@ Should look at CPU word size. */
9432 type
= BFD_RELOC_16
;
9436 type
= BFD_RELOC_32
;
9439 type
= BFD_RELOC_64
;
9443 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
9446 /* A good place to do this, although this was probably not intended
9447 for this kind of use. We need to dump the literal pool before
9448 references are made to a null symbol pointer. */
9453 if (current_poolP
== NULL
)
9456 /* Put it at the end of text section. */
9457 subseg_set (text_section
, 0);
9459 listing_prev_line ();
9463 arm_start_line_hook ()
9465 last_label_seen
= NULL
;
9469 arm_frob_label (sym
)
9472 last_label_seen
= sym
;
9474 ARM_SET_THUMB (sym
, thumb_mode
);
9476 #if defined OBJ_COFF || defined OBJ_ELF
9477 ARM_SET_INTERWORK (sym
, support_interwork
);
9480 /* Note - do not allow local symbols (.Lxxx) to be labeled
9481 as Thumb functions. This is because these labels, whilst
9482 they exist inside Thumb code, are not the entry points for
9483 possible ARM->Thumb calls. Also, these labels can be used
9484 as part of a computed goto or switch statement. eg gcc
9485 can generate code that looks like this:
9497 The first instruction loads the address of the jump table.
9498 The second instruction converts a table index into a byte offset.
9499 The third instruction gets the jump address out of the table.
9500 The fourth instruction performs the jump.
9502 If the address stored at .Laaa is that of a symbol which has the
9503 Thumb_Func bit set, then the linker will arrange for this address
9504 to have the bottom bit set, which in turn would mean that the
9505 address computation performed by the third instruction would end
9506 up with the bottom bit set. Since the ARM is capable of unaligned
9507 word loads, the instruction would then load the incorrect address
9508 out of the jump table, and chaos would ensue. */
9509 if (label_is_thumb_function_name
9510 && (S_GET_NAME (sym
)[0] != '.' || S_GET_NAME (sym
)[1] != 'L')
9511 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
9513 /* When the address of a Thumb function is taken the bottom
9514 bit of that address should be set. This will allow
9515 interworking between Arm and Thumb functions to work
9518 THUMB_SET_FUNC (sym
, 1);
9520 label_is_thumb_function_name
= false;
9524 /* Adjust the symbol table. This marks Thumb symbols as distinct from
9528 arm_adjust_symtab ()
9533 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
9535 if (ARM_IS_THUMB (sym
))
9537 if (THUMB_IS_FUNC (sym
))
9539 /* Mark the symbol as a Thumb function. */
9540 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
9541 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
9542 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
9544 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
9545 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
9547 as_bad (_("%s: unexpected function type: %d"),
9548 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
9550 else switch (S_GET_STORAGE_CLASS (sym
))
9553 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
9556 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
9559 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
9567 if (ARM_IS_INTERWORK (sym
))
9568 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
9575 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
9577 if (ARM_IS_THUMB (sym
))
9579 elf_symbol_type
* elf_sym
;
9581 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
9582 bind
= ELF_ST_BIND (elf_sym
);
9584 /* If it's a .thumb_func, declare it as so,
9585 otherwise tag label as .code 16. */
9586 if (THUMB_IS_FUNC (sym
))
9587 elf_sym
->internal_elf_sym
.st_info
=
9588 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
9590 elf_sym
->internal_elf_sym
.st_info
=
9591 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
9600 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
9602 *input_line_pointer
= '/';
9603 input_line_pointer
+= 5;
9604 *input_line_pointer
= 0;
9612 arm_canonicalize_symbol_name (name
)
9617 if (thumb_mode
&& (len
= strlen (name
)) > 5
9618 && streq (name
+ len
- 5, "/data"))
9619 *(name
+ len
- 5) = 0;
9625 arm_validate_fix (fixP
)
9628 /* If the destination of the branch is a defined symbol which does not have
9629 the THUMB_FUNC attribute, then we must be calling a function which has
9630 the (interfacearm) attribute. We look for the Thumb entry point to that
9631 function and change the branch to refer to that function instead. */
9632 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
9633 && fixP
->fx_addsy
!= NULL
9634 && S_IS_DEFINED (fixP
->fx_addsy
)
9635 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
9637 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
9645 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
9646 local labels from being added to the output symbol table when they
9647 are used with the ADRL pseudo op. The ADRL relocation should always
9648 be resolved before the binbary is emitted, so it is safe to say that
9649 it is adjustable. */
9652 arm_fix_adjustable (fixP
)
9655 if (fixP
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
9661 /* Relocations against Thumb function names must be left unadjusted,
9662 so that the linker can use this information to correctly set the
9663 bottom bit of their addresses. The MIPS version of this function
9664 also prevents relocations that are mips-16 specific, but I do not
9665 know why it does this.
9668 There is one other problem that ought to be addressed here, but
9669 which currently is not: Taking the address of a label (rather
9670 than a function) and then later jumping to that address. Such
9671 addresses also ought to have their bottom bit set (assuming that
9672 they reside in Thumb code), but at the moment they will not. */
9675 arm_fix_adjustable (fixP
)
9678 if (fixP
->fx_addsy
== NULL
)
9681 /* Prevent all adjustments to global symbols. */
9682 if (S_IS_EXTERN (fixP
->fx_addsy
))
9685 if (S_IS_WEAK (fixP
->fx_addsy
))
9688 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
9689 && fixP
->fx_subsy
== NULL
)
9692 /* We need the symbol name for the VTABLE entries. */
9693 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
9694 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
9701 elf32_arm_target_format ()
9703 if (target_big_endian
)
9706 return "elf32-bigarm-oabi";
9708 return "elf32-bigarm";
9713 return "elf32-littlearm-oabi";
9715 return "elf32-littlearm";
9720 armelf_frob_symbol (symp
, puntp
)
9724 elf_frob_symbol (symp
, puntp
);
9728 arm_force_relocation (fixp
)
9731 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
9732 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
9733 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
9734 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
9735 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
9736 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
9742 static bfd_reloc_code_real_type
9752 bfd_reloc_code_real_type reloc
;
9756 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
9757 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
9758 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
9759 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
9760 branch instructions generated by GCC for PLT relocs. */
9761 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
9762 { NULL
, 0, BFD_RELOC_UNUSED
}
9766 for (i
= 0, ip
= input_line_pointer
;
9767 i
< sizeof (id
) && (ISALNUM (*ip
) || ISPUNCT (*ip
));
9769 id
[i
] = TOLOWER (*ip
);
9771 for (i
= 0; reloc_map
[i
].str
; i
++)
9772 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
9775 input_line_pointer
+= reloc_map
[i
].len
;
9777 return reloc_map
[i
].reloc
;
9781 s_arm_elf_cons (nbytes
)
9786 #ifdef md_flush_pending_output
9787 md_flush_pending_output ();
9790 if (is_it_end_of_statement ())
9792 demand_empty_rest_of_line ();
9796 #ifdef md_cons_align
9797 md_cons_align (nbytes
);
9802 bfd_reloc_code_real_type reloc
;
9806 if (exp
.X_op
== O_symbol
9807 && * input_line_pointer
== '('
9808 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
9810 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
9811 int size
= bfd_get_reloc_size (howto
);
9814 as_bad ("%s relocations do not fit in %d bytes",
9815 howto
->name
, nbytes
);
9818 register char *p
= frag_more ((int) nbytes
);
9819 int offset
= nbytes
- size
;
9821 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
9826 emit_expr (&exp
, (unsigned int) nbytes
);
9828 while (*input_line_pointer
++ == ',');
9830 /* Put terminator back into stream. */
9831 input_line_pointer
--;
9832 demand_empty_rest_of_line ();
9835 #endif /* OBJ_ELF */
9837 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
9838 of an rs_align_code fragment. */
9841 arm_handle_align (fragP
)
9844 static char const arm_noop
[4] = { 0x00, 0x00, 0xa0, 0xe1 };
9845 static char const thumb_noop
[2] = { 0xc0, 0x46 };
9846 static char const arm_bigend_noop
[4] = { 0xe1, 0xa0, 0x00, 0x00 };
9847 static char const thumb_bigend_noop
[2] = { 0x46, 0xc0 };
9849 int bytes
, fix
, noop_size
;
9853 if (fragP
->fr_type
!= rs_align_code
)
9856 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
9857 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
9860 if (bytes
> MAX_MEM_FOR_RS_ALIGN_CODE
)
9861 bytes
&= MAX_MEM_FOR_RS_ALIGN_CODE
;
9863 if (fragP
->tc_frag_data
)
9865 if (target_big_endian
)
9866 noop
= thumb_bigend_noop
;
9869 noop_size
= sizeof (thumb_noop
);
9873 if (target_big_endian
)
9874 noop
= arm_bigend_noop
;
9877 noop_size
= sizeof (arm_noop
);
9880 if (bytes
& (noop_size
- 1))
9882 fix
= bytes
& (noop_size
- 1);
9888 while (bytes
>= noop_size
)
9890 memcpy (p
, noop
, noop_size
);
9896 fragP
->fr_fix
+= fix
;
9897 fragP
->fr_var
= noop_size
;
9900 /* Called from md_do_align. Used to create an alignment
9901 frag in a code section. */
9904 arm_frag_align_code (n
, max
)
9910 /* We assume that there will never be a requirment
9911 to support alignments greater than 32 bytes. */
9912 if (max
> MAX_MEM_FOR_RS_ALIGN_CODE
)
9913 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
9915 p
= frag_var (rs_align_code
,
9916 MAX_MEM_FOR_RS_ALIGN_CODE
,
9918 (relax_substateT
) max
,
9926 /* Perform target specific initialisation of a frag. */
9929 arm_init_frag (fragP
)
9932 /* Record whether this frag is in an ARM or a THUMB area. */
9933 fragP
->tc_frag_data
= thumb_mode
;