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
},
471 /* Structure for a hash table entry for a register. */
478 /* Some well known registers that we refer to directly elsewhere. */
483 /* These are the standard names. Users can add aliases with .req. */
484 /* Integer Register Numbers. */
485 static const struct reg_entry rn_table
[] =
487 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
488 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
489 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
490 {"r12", 12}, {"r13", REG_SP
}, {"r14", REG_LR
}, {"r15", REG_PC
},
491 /* ATPCS Synonyms. */
492 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
493 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7},
494 {"v5", 8}, {"v6", 9}, {"v7", 10}, {"v8", 11},
495 /* Well-known aliases. */
497 {"sb", 9}, {"sl", 10}, {"fp", 11},
498 {"ip", 12}, {"sp", REG_SP
}, {"lr", REG_LR
}, {"pc", REG_PC
},
502 /* Co-processor Numbers. */
503 static const struct reg_entry cp_table
[] =
505 {"p0", 0}, {"p1", 1}, {"p2", 2}, {"p3", 3},
506 {"p4", 4}, {"p5", 5}, {"p6", 6}, {"p7", 7},
507 {"p8", 8}, {"p9", 9}, {"p10", 10}, {"p11", 11},
508 {"p12", 12}, {"p13", 13}, {"p14", 14}, {"p15", 15},
512 /* Co-processor Register Numbers. */
513 static const struct reg_entry cn_table
[] =
515 {"c0", 0}, {"c1", 1}, {"c2", 2}, {"c3", 3},
516 {"c4", 4}, {"c5", 5}, {"c6", 6}, {"c7", 7},
517 {"c8", 8}, {"c9", 9}, {"c10", 10}, {"c11", 11},
518 {"c12", 12}, {"c13", 13}, {"c14", 14}, {"c15", 15},
519 /* Not really valid, but kept for back-wards compatibility. */
520 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
521 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
522 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
523 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
528 static const struct reg_entry fn_table
[] =
530 {"f0", 0}, {"f1", 1}, {"f2", 2}, {"f3", 3},
531 {"f4", 4}, {"f5", 5}, {"f6", 6}, {"f7", 7},
535 /* Cirrus DSP coprocessor registers. */
536 static const struct reg_entry mav_mvf_table
[] =
538 {"mvf0", 0}, {"mvf1", 1}, {"mvf2", 2}, {"mvf3", 3},
539 {"mvf4", 4}, {"mvf5", 5}, {"mvf6", 6}, {"mvf7", 7},
540 {"mvf8", 8}, {"mvf9", 9}, {"mvf10", 10}, {"mvf11", 11},
541 {"mvf12", 12}, {"mvf13", 13}, {"mvf14", 14}, {"mvf15", 15},
545 static const struct reg_entry mav_mvd_table
[] =
547 {"mvd0", 0}, {"mvd1", 1}, {"mvd2", 2}, {"mvd3", 3},
548 {"mvd4", 4}, {"mvd5", 5}, {"mvd6", 6}, {"mvd7", 7},
549 {"mvd8", 8}, {"mvd9", 9}, {"mvd10", 10}, {"mvd11", 11},
550 {"mvd12", 12}, {"mvd13", 13}, {"mvd14", 14}, {"mvd15", 15},
554 static const struct reg_entry mav_mvfx_table
[] =
556 {"mvfx0", 0}, {"mvfx1", 1}, {"mvfx2", 2}, {"mvfx3", 3},
557 {"mvfx4", 4}, {"mvfx5", 5}, {"mvfx6", 6}, {"mvfx7", 7},
558 {"mvfx8", 8}, {"mvfx9", 9}, {"mvfx10", 10}, {"mvfx11", 11},
559 {"mvfx12", 12}, {"mvfx13", 13}, {"mvfx14", 14}, {"mvfx15", 15},
563 static const struct reg_entry mav_mvdx_table
[] =
565 {"mvdx0", 0}, {"mvdx1", 1}, {"mvdx2", 2}, {"mvdx3", 3},
566 {"mvdx4", 4}, {"mvdx5", 5}, {"mvdx6", 6}, {"mvdx7", 7},
567 {"mvdx8", 8}, {"mvdx9", 9}, {"mvdx10", 10}, {"mvdx11", 11},
568 {"mvdx12", 12}, {"mvdx13", 13}, {"mvdx14", 14}, {"mvdx15", 15},
572 static const struct reg_entry mav_mvax_table
[] =
574 {"mvax0", 0}, {"mvax1", 1}, {"mvax2", 2}, {"mvax3", 3},
578 static const struct reg_entry mav_dspsc_table
[] =
586 const struct reg_entry
*names
;
588 struct hash_control
*htab
;
589 const char *expected
;
592 struct reg_map all_reg_maps
[] =
594 {rn_table
, 15, NULL
, N_("ARM register expected")},
595 {cp_table
, 15, NULL
, N_("Bad or missing co-processor number")},
596 {cn_table
, 15, NULL
, N_("Co-processor register expected")},
597 {fn_table
, 7, NULL
, N_("FPA register expected")},
598 {mav_mvf_table
, 15, NULL
, N_("Maverick MVF register expected")},
599 {mav_mvd_table
, 15, NULL
, N_("Maverick MVD register expected")},
600 {mav_mvfx_table
, 15, NULL
, N_("Maverick MVFX register expected")},
601 {mav_mvdx_table
, 15, NULL
, N_("Maverick MVFX register expected")},
602 {mav_mvax_table
, 3, NULL
, N_("Maverick MVAX register expected")},
603 {mav_dspsc_table
, 0, NULL
, N_("Maverick DSPSC register expected")},
606 /* Enumeration matching entries in table above. */
610 #define REG_TYPE_FIRST REG_TYPE_RN
624 /* Functions called by parser. */
625 /* ARM instructions. */
626 static void do_arit
PARAMS ((char *));
627 static void do_cmp
PARAMS ((char *));
628 static void do_mov
PARAMS ((char *));
629 static void do_ldst
PARAMS ((char *));
630 static void do_ldstt
PARAMS ((char *));
631 static void do_ldmstm
PARAMS ((char *));
632 static void do_branch
PARAMS ((char *));
633 static void do_swi
PARAMS ((char *));
635 /* Pseudo Op codes. */
636 static void do_adr
PARAMS ((char *));
637 static void do_adrl
PARAMS ((char *));
638 static void do_empty
PARAMS ((char *));
641 static void do_mul
PARAMS ((char *));
642 static void do_mla
PARAMS ((char *));
645 static void do_swap
PARAMS ((char *));
648 static void do_msr
PARAMS ((char *));
649 static void do_mrs
PARAMS ((char *));
652 static void do_mull
PARAMS ((char *));
655 static void do_ldstv4
PARAMS ((char *));
658 static void do_bx
PARAMS ((char *));
661 static void do_blx
PARAMS ((char *));
662 static void do_bkpt
PARAMS ((char *));
663 static void do_clz
PARAMS ((char *));
664 static void do_lstc2
PARAMS ((char *));
665 static void do_cdp2
PARAMS ((char *));
666 static void do_co_reg2
PARAMS ((char *));
669 static void do_smla
PARAMS ((char *));
670 static void do_smlal
PARAMS ((char *));
671 static void do_smul
PARAMS ((char *));
672 static void do_qadd
PARAMS ((char *));
675 static void do_pld
PARAMS ((char *));
676 static void do_ldrd
PARAMS ((char *));
677 static void do_co_reg2c
PARAMS ((char *));
679 /* Coprocessor Instructions. */
680 static void do_cdp
PARAMS ((char *));
681 static void do_lstc
PARAMS ((char *));
682 static void do_co_reg
PARAMS ((char *));
684 /* FPA instructions. */
685 static void do_fpa_ctrl
PARAMS ((char *));
686 static void do_fpa_ldst
PARAMS ((char *));
687 static void do_fpa_ldmstm
PARAMS ((char *));
688 static void do_fpa_dyadic
PARAMS ((char *));
689 static void do_fpa_monadic
PARAMS ((char *));
690 static void do_fpa_cmp
PARAMS ((char *));
691 static void do_fpa_from_reg
PARAMS ((char *));
692 static void do_fpa_to_reg
PARAMS ((char *));
695 static void do_mia
PARAMS ((char *));
696 static void do_mar
PARAMS ((char *));
697 static void do_mra
PARAMS ((char *));
700 static void do_c_binops
PARAMS ((char *, int, enum arm_reg_type
,
702 static void do_c_binops_1a
PARAMS ((char *));
703 static void do_c_binops_1b
PARAMS ((char *));
704 static void do_c_binops_1c
PARAMS ((char *));
705 static void do_c_binops_1d
PARAMS ((char *));
706 static void do_c_binops_1e
PARAMS ((char *));
707 static void do_c_binops_1f
PARAMS ((char *));
708 static void do_c_binops_1g
PARAMS ((char *));
709 static void do_c_binops_1h
PARAMS ((char *));
710 static void do_c_binops_1i
PARAMS ((char *));
711 static void do_c_binops_1j
PARAMS ((char *));
712 static void do_c_binops_1k
PARAMS ((char *));
713 static void do_c_binops_1l
PARAMS ((char *));
714 static void do_c_binops_1m
PARAMS ((char *));
715 static void do_c_binops_1n
PARAMS ((char *));
716 static void do_c_binops_1o
PARAMS ((char *));
717 static void do_c_binops_2a
PARAMS ((char *));
718 static void do_c_binops_2b
PARAMS ((char *));
719 static void do_c_binops_2c
PARAMS ((char *));
720 static void do_c_binops_3a
PARAMS ((char *));
721 static void do_c_binops_3b
PARAMS ((char *));
722 static void do_c_binops_3c
PARAMS ((char *));
723 static void do_c_binops_3d
PARAMS ((char *));
724 static void do_c_triple
PARAMS ((char *, int, enum arm_reg_type
,
727 static void do_c_triple_4a
PARAMS ((char *));
728 static void do_c_triple_4b
PARAMS ((char *));
729 static void do_c_triple_5a
PARAMS ((char *));
730 static void do_c_triple_5b
PARAMS ((char *));
731 static void do_c_triple_5c
PARAMS ((char *));
732 static void do_c_triple_5d
PARAMS ((char *));
733 static void do_c_triple_5e
PARAMS ((char *));
734 static void do_c_triple_5f
PARAMS ((char *));
735 static void do_c_triple_5g
PARAMS ((char *));
736 static void do_c_triple_5h
PARAMS ((char *));
737 static void do_c_quad
PARAMS ((char *, int, enum arm_reg_type
,
741 static void do_c_quad_6a
PARAMS ((char *));
742 static void do_c_quad_6b
PARAMS ((char *));
743 static void do_c_dspsc_1
PARAMS ((char *));
744 static void do_c_dspsc_2
PARAMS ((char *));
745 static void do_c_shift
PARAMS ((char *, enum arm_reg_type
,
747 static void do_c_shift_1
PARAMS ((char *));
748 static void do_c_shift_2
PARAMS ((char *));
749 static void do_c_ldst
PARAMS ((char *, enum arm_reg_type
));
750 static void do_c_ldst_1
PARAMS ((char *));
751 static void do_c_ldst_2
PARAMS ((char *));
752 static void do_c_ldst_3
PARAMS ((char *));
753 static void do_c_ldst_4
PARAMS ((char *));
755 static int cirrus_reg_required_here
PARAMS ((char **, int,
757 static int cirrus_parse_offset
PARAMS ((char **, int *));
759 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*,
761 static int arm_reg_parse
PARAMS ((char **, struct hash_control
*));
762 static enum arm_reg_type arm_reg_parse_any
PARAMS ((char *));
763 static const struct asm_psr
* arm_psr_parse
PARAMS ((char **));
764 static void symbol_locate
PARAMS ((symbolS
*, const char *, segT
, valueT
,
766 static int add_to_lit_pool
PARAMS ((void));
767 static unsigned validate_immediate
PARAMS ((unsigned));
768 static unsigned validate_immediate_twopart
PARAMS ((unsigned int,
770 static int validate_offset_imm
PARAMS ((unsigned int, int));
771 static void opcode_select
PARAMS ((int));
772 static void end_of_line
PARAMS ((char *));
773 static int reg_required_here
PARAMS ((char **, int));
774 static int psr_required_here
PARAMS ((char **));
775 static int co_proc_number
PARAMS ((char **));
776 static int cp_opc_expr
PARAMS ((char **, int, int));
777 static int cp_reg_required_here
PARAMS ((char **, int));
778 static int fp_reg_required_here
PARAMS ((char **, int));
779 static int cp_address_offset
PARAMS ((char **));
780 static int cp_address_required_here
PARAMS ((char **));
781 static int my_get_float_expression
PARAMS ((char **));
782 static int skip_past_comma
PARAMS ((char **));
783 static int walk_no_bignums
PARAMS ((symbolS
*));
784 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
785 static int data_op2
PARAMS ((char **));
786 static int fp_op2
PARAMS ((char **));
787 static long reg_list
PARAMS ((char **));
788 static void thumb_load_store
PARAMS ((char *, int, int));
789 static int decode_shift
PARAMS ((char **, int));
790 static int ldst_extend
PARAMS ((char **));
791 static int ldst_extend_v4
PARAMS ((char **));
792 static void thumb_add_sub
PARAMS ((char *, int));
793 static void insert_reg
PARAMS ((const struct reg_entry
*,
794 struct hash_control
*));
795 static void thumb_shift
PARAMS ((char *, int));
796 static void thumb_mov_compare
PARAMS ((char *, int));
797 static void build_arm_ops_hsh
PARAMS ((void));
798 static void set_constant_flonums
PARAMS ((void));
799 static valueT md_chars_to_number
PARAMS ((char *, int));
800 static void build_reg_hsh
PARAMS ((struct reg_map
*));
801 static void insert_reg_alias
PARAMS ((char *, int, struct hash_control
*));
802 static int create_register_alias
PARAMS ((char *, char *));
803 static void output_inst
PARAMS ((void));
804 static int accum0_required_here
PARAMS ((char **));
805 static int ld_mode_required_here
PARAMS ((char **));
806 static void do_branch25
PARAMS ((char *));
807 static symbolS
* find_real_start
PARAMS ((symbolS
*));
809 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
812 /* ARM instructions take 4bytes in the object file, Thumb instructions
816 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
817 #define CIRRUS_MODE1 0x100c
819 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
820 #define CIRRUS_MODE2 0x0c10
822 /* "INSN<cond> X,Y" where X:0, Y:bit16. */
823 #define CIRRUS_MODE3 0x1000
825 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
826 #define CIRRUS_MODE4 0x0c0010
828 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
829 #define CIRRUS_MODE5 0x00100c
831 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
832 #define CIRRUS_MODE6 0x00100c05
836 /* Basic string to match. */
837 const char * template;
839 /* Basic instruction code. */
842 /* Offset into the template where the condition code (if any) will be.
843 If zero, then the instruction is never conditional. */
844 unsigned cond_offset
;
846 /* Which architecture variant provides this instruction. */
847 unsigned long variant
;
849 /* Function to call to parse args. */
850 void (* parms
) PARAMS ((char *));
853 static const struct asm_opcode insns
[] =
855 /* Core ARM Instructions. */
856 {"and", 0xe0000000, 3, ARM_EXT_V1
, do_arit
},
857 {"ands", 0xe0100000, 3, ARM_EXT_V1
, do_arit
},
858 {"eor", 0xe0200000, 3, ARM_EXT_V1
, do_arit
},
859 {"eors", 0xe0300000, 3, ARM_EXT_V1
, do_arit
},
860 {"sub", 0xe0400000, 3, ARM_EXT_V1
, do_arit
},
861 {"subs", 0xe0500000, 3, ARM_EXT_V1
, do_arit
},
862 {"rsb", 0xe0600000, 3, ARM_EXT_V1
, do_arit
},
863 {"rsbs", 0xe0700000, 3, ARM_EXT_V1
, do_arit
},
864 {"add", 0xe0800000, 3, ARM_EXT_V1
, do_arit
},
865 {"adds", 0xe0900000, 3, ARM_EXT_V1
, do_arit
},
866 {"adc", 0xe0a00000, 3, ARM_EXT_V1
, do_arit
},
867 {"adcs", 0xe0b00000, 3, ARM_EXT_V1
, do_arit
},
868 {"sbc", 0xe0c00000, 3, ARM_EXT_V1
, do_arit
},
869 {"sbcs", 0xe0d00000, 3, ARM_EXT_V1
, do_arit
},
870 {"rsc", 0xe0e00000, 3, ARM_EXT_V1
, do_arit
},
871 {"rscs", 0xe0f00000, 3, ARM_EXT_V1
, do_arit
},
872 {"orr", 0xe1800000, 3, ARM_EXT_V1
, do_arit
},
873 {"orrs", 0xe1900000, 3, ARM_EXT_V1
, do_arit
},
874 {"bic", 0xe1c00000, 3, ARM_EXT_V1
, do_arit
},
875 {"bics", 0xe1d00000, 3, ARM_EXT_V1
, do_arit
},
877 {"tst", 0xe1100000, 3, ARM_EXT_V1
, do_cmp
},
878 {"tsts", 0xe1100000, 3, ARM_EXT_V1
, do_cmp
},
879 {"tstp", 0xe110f000, 3, ARM_EXT_V1
, do_cmp
},
880 {"teq", 0xe1300000, 3, ARM_EXT_V1
, do_cmp
},
881 {"teqs", 0xe1300000, 3, ARM_EXT_V1
, do_cmp
},
882 {"teqp", 0xe130f000, 3, ARM_EXT_V1
, do_cmp
},
883 {"cmp", 0xe1500000, 3, ARM_EXT_V1
, do_cmp
},
884 {"cmps", 0xe1500000, 3, ARM_EXT_V1
, do_cmp
},
885 {"cmpp", 0xe150f000, 3, ARM_EXT_V1
, do_cmp
},
886 {"cmn", 0xe1700000, 3, ARM_EXT_V1
, do_cmp
},
887 {"cmns", 0xe1700000, 3, ARM_EXT_V1
, do_cmp
},
888 {"cmnp", 0xe170f000, 3, ARM_EXT_V1
, do_cmp
},
890 {"mov", 0xe1a00000, 3, ARM_EXT_V1
, do_mov
},
891 {"movs", 0xe1b00000, 3, ARM_EXT_V1
, do_mov
},
892 {"mvn", 0xe1e00000, 3, ARM_EXT_V1
, do_mov
},
893 {"mvns", 0xe1f00000, 3, ARM_EXT_V1
, do_mov
},
895 {"ldr", 0xe4100000, 3, ARM_EXT_V1
, do_ldst
},
896 {"ldrb", 0xe4500000, 3, ARM_EXT_V1
, do_ldst
},
897 {"ldrt", 0xe4300000, 3, ARM_EXT_V1
, do_ldstt
},
898 {"ldrbt", 0xe4700000, 3, ARM_EXT_V1
, do_ldstt
},
899 {"str", 0xe4000000, 3, ARM_EXT_V1
, do_ldst
},
900 {"strb", 0xe4400000, 3, ARM_EXT_V1
, do_ldst
},
901 {"strt", 0xe4200000, 3, ARM_EXT_V1
, do_ldstt
},
902 {"strbt", 0xe4600000, 3, ARM_EXT_V1
, do_ldstt
},
904 {"stmia", 0xe8800000, 3, ARM_EXT_V1
, do_ldmstm
},
905 {"stmib", 0xe9800000, 3, ARM_EXT_V1
, do_ldmstm
},
906 {"stmda", 0xe8000000, 3, ARM_EXT_V1
, do_ldmstm
},
907 {"stmdb", 0xe9000000, 3, ARM_EXT_V1
, do_ldmstm
},
908 {"stmfd", 0xe9000000, 3, ARM_EXT_V1
, do_ldmstm
},
909 {"stmfa", 0xe9800000, 3, ARM_EXT_V1
, do_ldmstm
},
910 {"stmea", 0xe8800000, 3, ARM_EXT_V1
, do_ldmstm
},
911 {"stmed", 0xe8000000, 3, ARM_EXT_V1
, do_ldmstm
},
913 {"ldmia", 0xe8900000, 3, ARM_EXT_V1
, do_ldmstm
},
914 {"ldmib", 0xe9900000, 3, ARM_EXT_V1
, do_ldmstm
},
915 {"ldmda", 0xe8100000, 3, ARM_EXT_V1
, do_ldmstm
},
916 {"ldmdb", 0xe9100000, 3, ARM_EXT_V1
, do_ldmstm
},
917 {"ldmfd", 0xe8900000, 3, ARM_EXT_V1
, do_ldmstm
},
918 {"ldmfa", 0xe8100000, 3, ARM_EXT_V1
, do_ldmstm
},
919 {"ldmea", 0xe9100000, 3, ARM_EXT_V1
, do_ldmstm
},
920 {"ldmed", 0xe9900000, 3, ARM_EXT_V1
, do_ldmstm
},
922 {"swi", 0xef000000, 3, ARM_EXT_V1
, do_swi
},
924 /* XXX This is the wrong place to do this. Think multi-arch. */
925 {"bl", 0xeb000000, 2, ARM_EXT_V1
, do_branch
},
926 {"b", 0xea000000, 1, ARM_EXT_V1
, do_branch
},
928 {"bl", 0xebfffffe, 2, ARM_EXT_V1
, do_branch
},
929 {"b", 0xeafffffe, 1, ARM_EXT_V1
, do_branch
},
933 {"adr", 0xe28f0000, 3, ARM_EXT_V1
, do_adr
},
934 {"adrl", 0xe28f0000, 3, ARM_EXT_V1
, do_adrl
},
935 {"nop", 0xe1a00000, 3, ARM_EXT_V1
, do_empty
},
937 /* ARM 2 multiplies. */
938 {"mul", 0xe0000090, 3, ARM_EXT_V2
, do_mul
},
939 {"muls", 0xe0100090, 3, ARM_EXT_V2
, do_mul
},
940 {"mla", 0xe0200090, 3, ARM_EXT_V2
, do_mla
},
941 {"mlas", 0xe0300090, 3, ARM_EXT_V2
, do_mla
},
943 /* Generic copressor instructions. */
944 {"cdp", 0xee000000, 3, ARM_EXT_V2
, do_cdp
},
945 {"ldc", 0xec100000, 3, ARM_EXT_V2
, do_lstc
},
946 {"ldcl", 0xec500000, 3, ARM_EXT_V2
, do_lstc
},
947 {"stc", 0xec000000, 3, ARM_EXT_V2
, do_lstc
},
948 {"stcl", 0xec400000, 3, ARM_EXT_V2
, do_lstc
},
949 {"mcr", 0xee000010, 3, ARM_EXT_V2
, do_co_reg
},
950 {"mrc", 0xee100010, 3, ARM_EXT_V2
, do_co_reg
},
952 /* ARM 3 - swp instructions. */
953 {"swp", 0xe1000090, 3, ARM_EXT_V2S
, do_swap
},
954 {"swpb", 0xe1400090, 3, ARM_EXT_V2S
, do_swap
},
956 /* ARM 6 Status register instructions. */
957 {"mrs", 0xe10f0000, 3, ARM_EXT_V3
, do_mrs
},
958 {"msr", 0xe120f000, 3, ARM_EXT_V3
, do_msr
},
959 /* ScottB: our code uses 0xe128f000 for msr.
960 NickC: but this is wrong because the bits 16 through 19 are
961 handled by the PSR_xxx defines above. */
963 /* ARM 7M long multiplies. */
964 {"smull", 0xe0c00090, 5, ARM_EXT_V3M
, do_mull
},
965 {"smulls", 0xe0d00090, 5, ARM_EXT_V3M
, do_mull
},
966 {"umull", 0xe0800090, 5, ARM_EXT_V3M
, do_mull
},
967 {"umulls", 0xe0900090, 5, ARM_EXT_V3M
, do_mull
},
968 {"smlal", 0xe0e00090, 5, ARM_EXT_V3M
, do_mull
},
969 {"smlals", 0xe0f00090, 5, ARM_EXT_V3M
, do_mull
},
970 {"umlal", 0xe0a00090, 5, ARM_EXT_V3M
, do_mull
},
971 {"umlals", 0xe0b00090, 5, ARM_EXT_V3M
, do_mull
},
973 /* ARM Architecture 4. */
974 {"ldrh", 0xe01000b0, 3, ARM_EXT_V4
, do_ldstv4
},
975 {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4
, do_ldstv4
},
976 {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4
, do_ldstv4
},
977 {"strh", 0xe00000b0, 3, ARM_EXT_V4
, do_ldstv4
},
979 /* ARM Architecture 4T. */
980 /* Note: bx (and blx) are required on V5, even if the processor does
981 not support Thumb. */
982 {"bx", 0xe12fff10, 2, ARM_EXT_V4T
| ARM_EXT_V5
, do_bx
},
984 /* ARM Architecture 5. */
985 /* Note: blx has 2 variants, so the .value is set dynamically.
986 Only one of the variants has conditional execution. */
987 {"blx", 0xe0000000, 3, ARM_EXT_V5
, do_blx
},
988 {"clz", 0xe16f0f10, 3, ARM_EXT_V5
, do_clz
},
989 {"bkpt", 0xe1200070, 0, ARM_EXT_V5
, do_bkpt
},
990 {"ldc2", 0xfc100000, 0, ARM_EXT_V5
, do_lstc2
},
991 {"ldc2l", 0xfc500000, 0, ARM_EXT_V5
, do_lstc2
},
992 {"stc2", 0xfc000000, 0, ARM_EXT_V5
, do_lstc2
},
993 {"stc2l", 0xfc400000, 0, ARM_EXT_V5
, do_lstc2
},
994 {"cdp2", 0xfe000000, 0, ARM_EXT_V5
, do_cdp2
},
995 {"mcr2", 0xfe000010, 0, ARM_EXT_V5
, do_co_reg2
},
996 {"mrc2", 0xfe100010, 0, ARM_EXT_V5
, do_co_reg2
},
998 /* ARM Architecture 5ExP. */
999 {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP
, do_smla
},
1000 {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP
, do_smla
},
1001 {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP
, do_smla
},
1002 {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP
, do_smla
},
1004 {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP
, do_smla
},
1005 {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP
, do_smla
},
1007 {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP
, do_smlal
},
1008 {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP
, do_smlal
},
1009 {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP
, do_smlal
},
1010 {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP
, do_smlal
},
1012 {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP
, do_smul
},
1013 {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP
, do_smul
},
1014 {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP
, do_smul
},
1015 {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP
, do_smul
},
1017 {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP
, do_smul
},
1018 {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP
, do_smul
},
1020 {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP
, do_qadd
},
1021 {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP
, do_qadd
},
1022 {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP
, do_qadd
},
1023 {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP
, do_qadd
},
1025 /* ARM Architecture 5E. */
1026 {"pld", 0xf450f000, 0, ARM_EXT_V5E
, do_pld
},
1027 {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E
, do_ldrd
},
1028 {"strd", 0xe00000f0, 3, ARM_EXT_V5E
, do_ldrd
},
1030 {"mcrr", 0xec400000, 4, ARM_EXT_V5E
, do_co_reg2c
},
1031 {"mrrc", 0xec500000, 4, ARM_EXT_V5E
, do_co_reg2c
},
1033 /* Core FPA instruction set (V1). */
1034 {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1035 {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1036 {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1037 {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
1039 {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1040 {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1041 {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1042 {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1044 {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1045 {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1046 {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1047 {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1
, do_fpa_ldst
},
1049 {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1050 {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1051 {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1052 {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1053 {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1054 {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1055 {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1056 {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1057 {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1058 {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1059 {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1060 {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1062 {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1063 {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1064 {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1065 {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1066 {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1067 {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1068 {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1069 {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1070 {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1071 {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1072 {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1073 {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1075 {"abss", 0xee208100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1076 {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1077 {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1078 {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1079 {"absd", 0xee208180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1080 {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1081 {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1082 {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1083 {"abse", 0xee288100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1084 {"absep", 0xee288120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1085 {"absem", 0xee288140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1086 {"absez", 0xee288160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1088 {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1089 {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1090 {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1091 {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1092 {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1093 {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1094 {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1095 {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1096 {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1097 {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1098 {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1099 {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1101 {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1102 {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1103 {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1104 {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1105 {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1106 {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1107 {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1108 {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1109 {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1110 {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1111 {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1112 {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1114 {"logs", 0xee508100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1115 {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1116 {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1117 {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1118 {"logd", 0xee508180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1119 {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1120 {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1121 {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1122 {"loge", 0xee588100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1123 {"logep", 0xee588120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1124 {"logem", 0xee588140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1125 {"logez", 0xee588160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1127 {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1128 {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1129 {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1130 {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1131 {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1132 {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1133 {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1134 {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1135 {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1136 {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1137 {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1138 {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1140 {"exps", 0xee708100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1141 {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1142 {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1143 {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1144 {"expd", 0xee708180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1145 {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1146 {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1147 {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1148 {"expe", 0xee788100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1149 {"expep", 0xee788120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1150 {"expem", 0xee788140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1151 {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1153 {"sins", 0xee808100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1154 {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1155 {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1156 {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1157 {"sind", 0xee808180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1158 {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1159 {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1160 {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1161 {"sine", 0xee888100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1162 {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1163 {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1164 {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1166 {"coss", 0xee908100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1167 {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1168 {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1169 {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1170 {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1171 {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1172 {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1173 {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1174 {"cose", 0xee988100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1175 {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1176 {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1177 {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1179 {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1180 {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1181 {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1182 {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1183 {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1184 {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1185 {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1186 {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1187 {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1188 {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1189 {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1190 {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1192 {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1193 {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1194 {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1195 {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1196 {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1197 {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1198 {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1199 {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1200 {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1201 {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1202 {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1203 {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1205 {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1206 {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1207 {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1208 {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1209 {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1210 {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1211 {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1212 {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1213 {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1214 {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1215 {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1216 {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1218 {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1219 {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1220 {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1221 {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1222 {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1223 {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1224 {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1225 {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1226 {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1227 {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1228 {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1229 {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1231 {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1232 {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1233 {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1234 {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1235 {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1236 {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1237 {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1238 {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1239 {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1240 {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1241 {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1242 {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1244 {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1245 {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1246 {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1247 {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1248 {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1249 {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1250 {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1251 {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1252 {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1253 {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1254 {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1255 {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1
, do_fpa_monadic
},
1257 {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1258 {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1259 {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1260 {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1261 {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1262 {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1263 {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1264 {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1265 {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1266 {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1267 {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1268 {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1270 {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1271 {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1272 {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1273 {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1274 {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1275 {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1276 {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1277 {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1278 {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1279 {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1280 {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1281 {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1283 {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1284 {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1285 {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1286 {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1287 {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1288 {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1289 {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1290 {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1291 {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1292 {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1293 {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1294 {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1296 {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1297 {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1298 {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1299 {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1300 {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1301 {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1302 {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1303 {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1304 {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1305 {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1306 {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1307 {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1309 {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1310 {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1311 {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1312 {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1313 {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1314 {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1315 {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1316 {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1317 {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1318 {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1319 {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1320 {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1322 {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1323 {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1324 {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1325 {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1326 {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1327 {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1328 {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1329 {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1330 {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1331 {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1332 {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1333 {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1335 {"pows", 0xee600100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1336 {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1337 {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1338 {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1339 {"powd", 0xee600180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1340 {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1341 {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1342 {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1343 {"powe", 0xee680100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1344 {"powep", 0xee680120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1345 {"powem", 0xee680140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1346 {"powez", 0xee680160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1348 {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1349 {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1350 {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1351 {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1352 {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1353 {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1354 {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1355 {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1356 {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1357 {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1358 {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1359 {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1361 {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1362 {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1363 {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1364 {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1365 {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1366 {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1367 {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1368 {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1369 {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1370 {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1371 {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1372 {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1374 {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1375 {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1376 {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1377 {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1378 {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1379 {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1380 {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1381 {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1382 {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1383 {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1384 {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1385 {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1387 {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1388 {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1389 {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1390 {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1391 {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1392 {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1393 {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1394 {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1395 {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1396 {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1397 {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1398 {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1400 {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1401 {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1402 {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1403 {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1404 {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1405 {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1406 {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1407 {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1408 {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1409 {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1410 {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1411 {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1413 {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1414 {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1415 {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1416 {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1417 {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1418 {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1419 {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1420 {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1421 {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1422 {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1423 {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1424 {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
1426 {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1427 {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1428 {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1429 {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1430 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1431 not be an optional suffix, but part of the instruction. To be
1432 compatible, we accept either. */
1433 {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1434 {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1
, do_fpa_cmp
},
1436 {"flts", 0xee000110, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1437 {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1438 {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1439 {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1440 {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1441 {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1442 {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1443 {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1444 {"flte", 0xee080110, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1445 {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1446 {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1447 {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
1449 /* The implementation of the FIX instruction is broken on some
1450 assemblers, in that it accepts a precision specifier as well as a
1451 rounding specifier, despite the fact that this is meaningless.
1452 To be more compatible, we accept it as well, though of course it
1453 does not set any bits. */
1454 {"fix", 0xee100110, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1455 {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1456 {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1457 {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1458 {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1459 {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1460 {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1461 {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1462 {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1463 {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1464 {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1465 {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1466 {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
1468 /* Instructions that were new with the real FPA, call them V2. */
1469 {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1470 {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1471 {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1472 {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1473 {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1474 {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
1476 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
1477 {"mia", 0xee200010, 3, ARM_EXT_XSCALE
, do_mia
},
1478 {"miaph", 0xee280010, 5, ARM_EXT_XSCALE
, do_mia
},
1479 {"miabb", 0xee2c0010, 5, ARM_EXT_XSCALE
, do_mia
},
1480 {"miabt", 0xee2d0010, 5, ARM_EXT_XSCALE
, do_mia
},
1481 {"miatb", 0xee2e0010, 5, ARM_EXT_XSCALE
, do_mia
},
1482 {"miatt", 0xee2f0010, 5, ARM_EXT_XSCALE
, do_mia
},
1483 {"mar", 0xec400000, 3, ARM_EXT_XSCALE
, do_mar
},
1484 {"mra", 0xec500000, 3, ARM_EXT_XSCALE
, do_mra
},
1486 /* Cirrus DSP instructions. */
1487 {"cfldrs", 0xec100400, 6, ARM_EXT_MAVERICK
, do_c_ldst_1
},
1488 {"cfldrd", 0xec500400, 6, ARM_EXT_MAVERICK
, do_c_ldst_2
},
1489 {"cfldr32", 0xec100500, 7, ARM_EXT_MAVERICK
, do_c_ldst_3
},
1490 {"cfldr64", 0xec500500, 7, ARM_EXT_MAVERICK
, do_c_ldst_4
},
1491 {"cfstrs", 0xec000400, 6, ARM_EXT_MAVERICK
, do_c_ldst_1
},
1492 {"cfstrd", 0xec400400, 6, ARM_EXT_MAVERICK
, do_c_ldst_2
},
1493 {"cfstr32", 0xec000500, 7, ARM_EXT_MAVERICK
, do_c_ldst_3
},
1494 {"cfstr64", 0xec400500, 7, ARM_EXT_MAVERICK
, do_c_ldst_4
},
1495 {"cfmvsr", 0xee000450, 6, ARM_EXT_MAVERICK
, do_c_binops_2a
},
1496 {"cfmvrs", 0xee100450, 6, ARM_EXT_MAVERICK
, do_c_binops_1a
},
1497 {"cfmvdlr", 0xee000410, 7, ARM_EXT_MAVERICK
, do_c_binops_2b
},
1498 {"cfmvrdl", 0xee100410, 7, ARM_EXT_MAVERICK
, do_c_binops_1b
},
1499 {"cfmvdhr", 0xee000430, 7, ARM_EXT_MAVERICK
, do_c_binops_2b
},
1500 {"cfmvrdh", 0xee100430, 7, ARM_EXT_MAVERICK
, do_c_binops_1b
},
1501 {"cfmv64lr", 0xee000510, 8, ARM_EXT_MAVERICK
, do_c_binops_2c
},
1502 {"cfmvr64l", 0xee100510, 8, ARM_EXT_MAVERICK
, do_c_binops_1c
},
1503 {"cfmv64hr", 0xee000530, 8, ARM_EXT_MAVERICK
, do_c_binops_2c
},
1504 {"cfmvr64h", 0xee100530, 8, ARM_EXT_MAVERICK
, do_c_binops_1c
},
1505 {"cfmval32", 0xee100610, 8, ARM_EXT_MAVERICK
, do_c_binops_3a
},
1506 {"cfmv32al", 0xee000610, 8, ARM_EXT_MAVERICK
, do_c_binops_3b
},
1507 {"cfmvam32", 0xee100630, 8, ARM_EXT_MAVERICK
, do_c_binops_3a
},
1508 {"cfmv32am", 0xee000630, 8, ARM_EXT_MAVERICK
, do_c_binops_3b
},
1509 {"cfmvah32", 0xee100650, 8, ARM_EXT_MAVERICK
, do_c_binops_3a
},
1510 {"cfmv32ah", 0xee000650, 8, ARM_EXT_MAVERICK
, do_c_binops_3b
},
1511 {"cfmva32", 0xee100670, 7, ARM_EXT_MAVERICK
, do_c_binops_3a
},
1512 {"cfmv32a", 0xee000670, 7, ARM_EXT_MAVERICK
, do_c_binops_3b
},
1513 {"cfmva64", 0xee100690, 7, ARM_EXT_MAVERICK
, do_c_binops_3c
},
1514 {"cfmv64a", 0xee000690, 7, ARM_EXT_MAVERICK
, do_c_binops_3d
},
1515 {"cfmvsc32", 0xee1006b0, 8, ARM_EXT_MAVERICK
, do_c_dspsc_1
},
1516 {"cfmv32sc", 0xee0006b0, 8, ARM_EXT_MAVERICK
, do_c_dspsc_2
},
1517 {"cfcpys", 0xee000400, 6, ARM_EXT_MAVERICK
, do_c_binops_1d
},
1518 {"cfcpyd", 0xee000420, 6, ARM_EXT_MAVERICK
, do_c_binops_1e
},
1519 {"cfcvtsd", 0xee000460, 7, ARM_EXT_MAVERICK
, do_c_binops_1f
},
1520 {"cfcvtds", 0xee000440, 7, ARM_EXT_MAVERICK
, do_c_binops_1g
},
1521 {"cfcvt32s", 0xee000480, 8, ARM_EXT_MAVERICK
, do_c_binops_1h
},
1522 {"cfcvt32d", 0xee0004a0, 8, ARM_EXT_MAVERICK
, do_c_binops_1i
},
1523 {"cfcvt64s", 0xee0004c0, 8, ARM_EXT_MAVERICK
, do_c_binops_1j
},
1524 {"cfcvt64d", 0xee0004e0, 8, ARM_EXT_MAVERICK
, do_c_binops_1k
},
1525 {"cfcvts32", 0xee100580, 8, ARM_EXT_MAVERICK
, do_c_binops_1l
},
1526 {"cfcvtd32", 0xee1005a0, 8, ARM_EXT_MAVERICK
, do_c_binops_1m
},
1527 {"cftruncs32", 0xee1005c0, 10, ARM_EXT_MAVERICK
, do_c_binops_1l
},
1528 {"cftruncd32", 0xee1005e0, 10, ARM_EXT_MAVERICK
, do_c_binops_1m
},
1529 {"cfrshl32", 0xee000550, 8, ARM_EXT_MAVERICK
, do_c_triple_4a
},
1530 {"cfrshl64", 0xee000570, 8, ARM_EXT_MAVERICK
, do_c_triple_4b
},
1531 {"cfsh32", 0xee000500, 6, ARM_EXT_MAVERICK
, do_c_shift_1
},
1532 {"cfsh64", 0xee200500, 6, ARM_EXT_MAVERICK
, do_c_shift_2
},
1533 {"cfcmps", 0xee100490, 6, ARM_EXT_MAVERICK
, do_c_triple_5a
},
1534 {"cfcmpd", 0xee1004b0, 6, ARM_EXT_MAVERICK
, do_c_triple_5b
},
1535 {"cfcmp32", 0xee100590, 7, ARM_EXT_MAVERICK
, do_c_triple_5c
},
1536 {"cfcmp64", 0xee1005b0, 7, ARM_EXT_MAVERICK
, do_c_triple_5d
},
1537 {"cfabss", 0xee300400, 6, ARM_EXT_MAVERICK
, do_c_binops_1d
},
1538 {"cfabsd", 0xee300420, 6, ARM_EXT_MAVERICK
, do_c_binops_1e
},
1539 {"cfnegs", 0xee300440, 6, ARM_EXT_MAVERICK
, do_c_binops_1d
},
1540 {"cfnegd", 0xee300460, 6, ARM_EXT_MAVERICK
, do_c_binops_1e
},
1541 {"cfadds", 0xee300480, 6, ARM_EXT_MAVERICK
, do_c_triple_5e
},
1542 {"cfaddd", 0xee3004a0, 6, ARM_EXT_MAVERICK
, do_c_triple_5f
},
1543 {"cfsubs", 0xee3004c0, 6, ARM_EXT_MAVERICK
, do_c_triple_5e
},
1544 {"cfsubd", 0xee3004e0, 6, ARM_EXT_MAVERICK
, do_c_triple_5f
},
1545 {"cfmuls", 0xee100400, 6, ARM_EXT_MAVERICK
, do_c_triple_5e
},
1546 {"cfmuld", 0xee100420, 6, ARM_EXT_MAVERICK
, do_c_triple_5f
},
1547 {"cfabs32", 0xee300500, 7, ARM_EXT_MAVERICK
, do_c_binops_1n
},
1548 {"cfabs64", 0xee300520, 7, ARM_EXT_MAVERICK
, do_c_binops_1o
},
1549 {"cfneg32", 0xee300540, 7, ARM_EXT_MAVERICK
, do_c_binops_1n
},
1550 {"cfneg64", 0xee300560, 7, ARM_EXT_MAVERICK
, do_c_binops_1o
},
1551 {"cfadd32", 0xee300580, 7, ARM_EXT_MAVERICK
, do_c_triple_5g
},
1552 {"cfadd64", 0xee3005a0, 7, ARM_EXT_MAVERICK
, do_c_triple_5h
},
1553 {"cfsub32", 0xee3005c0, 7, ARM_EXT_MAVERICK
, do_c_triple_5g
},
1554 {"cfsub64", 0xee3005e0, 7, ARM_EXT_MAVERICK
, do_c_triple_5h
},
1555 {"cfmul32", 0xee100500, 7, ARM_EXT_MAVERICK
, do_c_triple_5g
},
1556 {"cfmul64", 0xee100520, 7, ARM_EXT_MAVERICK
, do_c_triple_5h
},
1557 {"cfmac32", 0xee100540, 7, ARM_EXT_MAVERICK
, do_c_triple_5g
},
1558 {"cfmsc32", 0xee100560, 7, ARM_EXT_MAVERICK
, do_c_triple_5g
},
1559 {"cfmadd32", 0xee000600, 8, ARM_EXT_MAVERICK
, do_c_quad_6a
},
1560 {"cfmsub32", 0xee100600, 8, ARM_EXT_MAVERICK
, do_c_quad_6a
},
1561 {"cfmadda32", 0xee200600, 9, ARM_EXT_MAVERICK
, do_c_quad_6b
},
1562 {"cfmsuba32", 0xee300600, 9, ARM_EXT_MAVERICK
, do_c_quad_6b
},
1565 /* Defines for various bits that we will want to toggle. */
1566 #define INST_IMMEDIATE 0x02000000
1567 #define OFFSET_REG 0x02000000
1568 #define HWOFFSET_IMM 0x00400000
1569 #define SHIFT_BY_REG 0x00000010
1570 #define PRE_INDEX 0x01000000
1571 #define INDEX_UP 0x00800000
1572 #define WRITE_BACK 0x00200000
1573 #define LDM_TYPE_2_OR_3 0x00400000
1575 #define LITERAL_MASK 0xf000f000
1576 #define OPCODE_MASK 0xfe1fffff
1577 #define V4_STR_BIT 0x00000020
1579 #define DATA_OP_SHIFT 21
1581 /* Codes to distinguish the arithmetic instructions. */
1582 #define OPCODE_AND 0
1583 #define OPCODE_EOR 1
1584 #define OPCODE_SUB 2
1585 #define OPCODE_RSB 3
1586 #define OPCODE_ADD 4
1587 #define OPCODE_ADC 5
1588 #define OPCODE_SBC 6
1589 #define OPCODE_RSC 7
1590 #define OPCODE_TST 8
1591 #define OPCODE_TEQ 9
1592 #define OPCODE_CMP 10
1593 #define OPCODE_CMN 11
1594 #define OPCODE_ORR 12
1595 #define OPCODE_MOV 13
1596 #define OPCODE_BIC 14
1597 #define OPCODE_MVN 15
1599 /* Thumb v1 (ARMv4T). */
1600 static void do_t_nop
PARAMS ((char *));
1601 static void do_t_arit
PARAMS ((char *));
1602 static void do_t_add
PARAMS ((char *));
1603 static void do_t_asr
PARAMS ((char *));
1604 static void do_t_branch9
PARAMS ((char *));
1605 static void do_t_branch12
PARAMS ((char *));
1606 static void do_t_branch23
PARAMS ((char *));
1607 static void do_t_bx
PARAMS ((char *));
1608 static void do_t_compare
PARAMS ((char *));
1609 static void do_t_ldmstm
PARAMS ((char *));
1610 static void do_t_ldr
PARAMS ((char *));
1611 static void do_t_ldrb
PARAMS ((char *));
1612 static void do_t_ldrh
PARAMS ((char *));
1613 static void do_t_lds
PARAMS ((char *));
1614 static void do_t_lsl
PARAMS ((char *));
1615 static void do_t_lsr
PARAMS ((char *));
1616 static void do_t_mov
PARAMS ((char *));
1617 static void do_t_push_pop
PARAMS ((char *));
1618 static void do_t_str
PARAMS ((char *));
1619 static void do_t_strb
PARAMS ((char *));
1620 static void do_t_strh
PARAMS ((char *));
1621 static void do_t_sub
PARAMS ((char *));
1622 static void do_t_swi
PARAMS ((char *));
1623 static void do_t_adr
PARAMS ((char *));
1625 /* Thumb v2 (ARMv5T). */
1626 static void do_t_blx
PARAMS ((char *));
1627 static void do_t_bkpt
PARAMS ((char *));
1629 #define T_OPCODE_MUL 0x4340
1630 #define T_OPCODE_TST 0x4200
1631 #define T_OPCODE_CMN 0x42c0
1632 #define T_OPCODE_NEG 0x4240
1633 #define T_OPCODE_MVN 0x43c0
1635 #define T_OPCODE_ADD_R3 0x1800
1636 #define T_OPCODE_SUB_R3 0x1a00
1637 #define T_OPCODE_ADD_HI 0x4400
1638 #define T_OPCODE_ADD_ST 0xb000
1639 #define T_OPCODE_SUB_ST 0xb080
1640 #define T_OPCODE_ADD_SP 0xa800
1641 #define T_OPCODE_ADD_PC 0xa000
1642 #define T_OPCODE_ADD_I8 0x3000
1643 #define T_OPCODE_SUB_I8 0x3800
1644 #define T_OPCODE_ADD_I3 0x1c00
1645 #define T_OPCODE_SUB_I3 0x1e00
1647 #define T_OPCODE_ASR_R 0x4100
1648 #define T_OPCODE_LSL_R 0x4080
1649 #define T_OPCODE_LSR_R 0x40c0
1650 #define T_OPCODE_ASR_I 0x1000
1651 #define T_OPCODE_LSL_I 0x0000
1652 #define T_OPCODE_LSR_I 0x0800
1654 #define T_OPCODE_MOV_I8 0x2000
1655 #define T_OPCODE_CMP_I8 0x2800
1656 #define T_OPCODE_CMP_LR 0x4280
1657 #define T_OPCODE_MOV_HR 0x4600
1658 #define T_OPCODE_CMP_HR 0x4500
1660 #define T_OPCODE_LDR_PC 0x4800
1661 #define T_OPCODE_LDR_SP 0x9800
1662 #define T_OPCODE_STR_SP 0x9000
1663 #define T_OPCODE_LDR_IW 0x6800
1664 #define T_OPCODE_STR_IW 0x6000
1665 #define T_OPCODE_LDR_IH 0x8800
1666 #define T_OPCODE_STR_IH 0x8000
1667 #define T_OPCODE_LDR_IB 0x7800
1668 #define T_OPCODE_STR_IB 0x7000
1669 #define T_OPCODE_LDR_RW 0x5800
1670 #define T_OPCODE_STR_RW 0x5000
1671 #define T_OPCODE_LDR_RH 0x5a00
1672 #define T_OPCODE_STR_RH 0x5200
1673 #define T_OPCODE_LDR_RB 0x5c00
1674 #define T_OPCODE_STR_RB 0x5400
1676 #define T_OPCODE_PUSH 0xb400
1677 #define T_OPCODE_POP 0xbc00
1679 #define T_OPCODE_BRANCH 0xe7fe
1681 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
1683 #define THUMB_SIZE 2 /* Size of thumb instruction. */
1684 #define THUMB_REG_LO 0x1
1685 #define THUMB_REG_HI 0x2
1686 #define THUMB_REG_ANY 0x3
1688 #define THUMB_H1 0x0080
1689 #define THUMB_H2 0x0040
1695 #define THUMB_MOVE 0
1696 #define THUMB_COMPARE 1
1698 #define THUMB_LOAD 0
1699 #define THUMB_STORE 1
1701 #define THUMB_PP_PC_LR 0x0100
1703 /* These three are used for immediate shifts, do not alter. */
1704 #define THUMB_WORD 2
1705 #define THUMB_HALFWORD 1
1706 #define THUMB_BYTE 0
1710 /* Basic string to match. */
1711 const char * template;
1713 /* Basic instruction code. */
1714 unsigned long value
;
1718 /* Which CPU variants this exists for. */
1719 unsigned long variant
;
1721 /* Function to call to parse args. */
1722 void (* parms
) PARAMS ((char *));
1725 static const struct thumb_opcode tinsns
[] =
1727 /* Thumb v1 (ARMv4T). */
1728 {"adc", 0x4140, 2, ARM_EXT_V4T
, do_t_arit
},
1729 {"add", 0x0000, 2, ARM_EXT_V4T
, do_t_add
},
1730 {"and", 0x4000, 2, ARM_EXT_V4T
, do_t_arit
},
1731 {"asr", 0x0000, 2, ARM_EXT_V4T
, do_t_asr
},
1732 {"b", T_OPCODE_BRANCH
, 2, ARM_EXT_V4T
, do_t_branch12
},
1733 {"beq", 0xd0fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1734 {"bne", 0xd1fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1735 {"bcs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1736 {"bhs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1737 {"bcc", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1738 {"bul", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1739 {"blo", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1740 {"bmi", 0xd4fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1741 {"bpl", 0xd5fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1742 {"bvs", 0xd6fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1743 {"bvc", 0xd7fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1744 {"bhi", 0xd8fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1745 {"bls", 0xd9fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1746 {"bge", 0xdafe, 2, ARM_EXT_V4T
, do_t_branch9
},
1747 {"blt", 0xdbfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1748 {"bgt", 0xdcfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1749 {"ble", 0xddfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1750 {"bal", 0xdefe, 2, ARM_EXT_V4T
, do_t_branch9
},
1751 {"bic", 0x4380, 2, ARM_EXT_V4T
, do_t_arit
},
1752 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T
, do_t_branch23
},
1753 {"bx", 0x4700, 2, ARM_EXT_V4T
, do_t_bx
},
1754 {"cmn", T_OPCODE_CMN
, 2, ARM_EXT_V4T
, do_t_arit
},
1755 {"cmp", 0x0000, 2, ARM_EXT_V4T
, do_t_compare
},
1756 {"eor", 0x4040, 2, ARM_EXT_V4T
, do_t_arit
},
1757 {"ldmia", 0xc800, 2, ARM_EXT_V4T
, do_t_ldmstm
},
1758 {"ldr", 0x0000, 2, ARM_EXT_V4T
, do_t_ldr
},
1759 {"ldrb", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrb
},
1760 {"ldrh", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrh
},
1761 {"ldrsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
1762 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
1763 {"ldsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
1764 {"ldsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
1765 {"lsl", 0x0000, 2, ARM_EXT_V4T
, do_t_lsl
},
1766 {"lsr", 0x0000, 2, ARM_EXT_V4T
, do_t_lsr
},
1767 {"mov", 0x0000, 2, ARM_EXT_V4T
, do_t_mov
},
1768 {"mul", T_OPCODE_MUL
, 2, ARM_EXT_V4T
, do_t_arit
},
1769 {"mvn", T_OPCODE_MVN
, 2, ARM_EXT_V4T
, do_t_arit
},
1770 {"neg", T_OPCODE_NEG
, 2, ARM_EXT_V4T
, do_t_arit
},
1771 {"orr", 0x4300, 2, ARM_EXT_V4T
, do_t_arit
},
1772 {"pop", 0xbc00, 2, ARM_EXT_V4T
, do_t_push_pop
},
1773 {"push", 0xb400, 2, ARM_EXT_V4T
, do_t_push_pop
},
1774 {"ror", 0x41c0, 2, ARM_EXT_V4T
, do_t_arit
},
1775 {"sbc", 0x4180, 2, ARM_EXT_V4T
, do_t_arit
},
1776 {"stmia", 0xc000, 2, ARM_EXT_V4T
, do_t_ldmstm
},
1777 {"str", 0x0000, 2, ARM_EXT_V4T
, do_t_str
},
1778 {"strb", 0x0000, 2, ARM_EXT_V4T
, do_t_strb
},
1779 {"strh", 0x0000, 2, ARM_EXT_V4T
, do_t_strh
},
1780 {"swi", 0xdf00, 2, ARM_EXT_V4T
, do_t_swi
},
1781 {"sub", 0x0000, 2, ARM_EXT_V4T
, do_t_sub
},
1782 {"tst", T_OPCODE_TST
, 2, ARM_EXT_V4T
, do_t_arit
},
1784 {"adr", 0x0000, 2, ARM_EXT_V4T
, do_t_adr
},
1785 {"nop", 0x46C0, 2, ARM_EXT_V4T
, do_t_nop
}, /* mov r8,r8 */
1786 /* Thumb v2 (ARMv5T). */
1787 {"blx", 0, 0, ARM_EXT_V5T
, do_t_blx
},
1788 {"bkpt", 0xbe00, 2, ARM_EXT_V5T
, do_t_bkpt
},
1791 #define BAD_ARGS _("Bad arguments to instruction")
1792 #define BAD_PC _("r15 not allowed here")
1793 #define BAD_COND _("Instruction is not conditional")
1794 #define ERR_NO_ACCUM _("acc0 expected")
1796 static struct hash_control
* arm_ops_hsh
= NULL
;
1797 static struct hash_control
* arm_tops_hsh
= NULL
;
1798 static struct hash_control
* arm_cond_hsh
= NULL
;
1799 static struct hash_control
* arm_shift_hsh
= NULL
;
1800 static struct hash_control
* arm_psr_hsh
= NULL
;
1802 /* This table describes all the machine specific pseudo-ops the assembler
1803 has to support. The fields are:
1804 pseudo-op name without dot
1805 function to call to execute this pseudo-op
1806 Integer arg to pass to the function. */
1808 static void s_req
PARAMS ((int));
1809 static void s_align
PARAMS ((int));
1810 static void s_bss
PARAMS ((int));
1811 static void s_even
PARAMS ((int));
1812 static void s_ltorg
PARAMS ((int));
1813 static void s_arm
PARAMS ((int));
1814 static void s_thumb
PARAMS ((int));
1815 static void s_code
PARAMS ((int));
1816 static void s_force_thumb
PARAMS ((int));
1817 static void s_thumb_func
PARAMS ((int));
1818 static void s_thumb_set
PARAMS ((int));
1819 static void arm_s_text
PARAMS ((int));
1820 static void arm_s_data
PARAMS ((int));
1822 static void arm_s_section
PARAMS ((int));
1823 static void s_arm_elf_cons
PARAMS ((int));
1826 static int my_get_expression
PARAMS ((expressionS
*, char **));
1828 const pseudo_typeS md_pseudo_table
[] =
1830 /* Never called becasue '.req' does not start line. */
1831 { "req", s_req
, 0 },
1832 { "bss", s_bss
, 0 },
1833 { "align", s_align
, 0 },
1834 { "arm", s_arm
, 0 },
1835 { "thumb", s_thumb
, 0 },
1836 { "code", s_code
, 0 },
1837 { "force_thumb", s_force_thumb
, 0 },
1838 { "thumb_func", s_thumb_func
, 0 },
1839 { "thumb_set", s_thumb_set
, 0 },
1840 { "even", s_even
, 0 },
1841 { "ltorg", s_ltorg
, 0 },
1842 { "pool", s_ltorg
, 0 },
1843 /* Allow for the effect of section changes. */
1844 { "text", arm_s_text
, 0 },
1845 { "data", arm_s_data
, 0 },
1847 { "section", arm_s_section
, 0 },
1848 { "section.s", arm_s_section
, 0 },
1849 { "sect", arm_s_section
, 0 },
1850 { "sect.s", arm_s_section
, 0 },
1851 { "word", s_arm_elf_cons
, 4 },
1852 { "long", s_arm_elf_cons
, 4 },
1853 { "file", dwarf2_directive_file
, 0 },
1854 { "loc", dwarf2_directive_loc
, 0 },
1858 { "extend", float_cons
, 'x' },
1859 { "ldouble", float_cons
, 'x' },
1860 { "packed", float_cons
, 'p' },
1864 /* Stuff needed to resolve the label ambiguity
1874 symbolS
* last_label_seen
;
1875 static int label_is_thumb_function_name
= false;
1877 /* Literal stuff. */
1879 #define MAX_LITERAL_POOL_SIZE 1024
1881 typedef struct literalS
1883 struct expressionS exp
;
1884 struct arm_it
* inst
;
1887 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1889 /* Next free entry in the pool. */
1890 int next_literal_pool_place
= 0;
1892 /* Next literal pool number. */
1893 int lit_pool_num
= 1;
1895 symbolS
* current_poolP
= NULL
;
1902 if (current_poolP
== NULL
)
1903 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1904 (valueT
) 0, &zero_address_frag
);
1906 /* Check if this literal value is already in the pool: */
1907 while (lit_count
< next_literal_pool_place
)
1909 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1910 && inst
.reloc
.exp
.X_op
== O_constant
1911 && (literals
[lit_count
].exp
.X_add_number
1912 == inst
.reloc
.exp
.X_add_number
)
1913 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1916 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1917 && inst
.reloc
.exp
.X_op
== O_symbol
1918 && (literals
[lit_count
].exp
.X_add_number
1919 == inst
.reloc
.exp
.X_add_number
)
1920 && (literals
[lit_count
].exp
.X_add_symbol
1921 == inst
.reloc
.exp
.X_add_symbol
)
1922 && (literals
[lit_count
].exp
.X_op_symbol
1923 == inst
.reloc
.exp
.X_op_symbol
))
1929 if (lit_count
== next_literal_pool_place
) /* New entry. */
1931 if (next_literal_pool_place
>= MAX_LITERAL_POOL_SIZE
)
1933 inst
.error
= _("Literal Pool Overflow");
1937 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1938 lit_count
= next_literal_pool_place
++;
1941 inst
.reloc
.exp
.X_op
= O_symbol
;
1942 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1943 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1948 /* Can't use symbol_new here, so have to create a symbol and then at
1949 a later date assign it a value. Thats what these functions do. */
1952 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1954 const char * name
; /* It is copied, the caller can modify. */
1955 segT segment
; /* Segment identifier (SEG_<something>). */
1956 valueT valu
; /* Symbol value. */
1957 fragS
* frag
; /* Associated fragment. */
1959 unsigned int name_length
;
1960 char * preserved_copy_of_name
;
1962 name_length
= strlen (name
) + 1; /* +1 for \0. */
1963 obstack_grow (¬es
, name
, name_length
);
1964 preserved_copy_of_name
= obstack_finish (¬es
);
1965 #ifdef STRIP_UNDERSCORE
1966 if (preserved_copy_of_name
[0] == '_')
1967 preserved_copy_of_name
++;
1970 #ifdef tc_canonicalize_symbol_name
1971 preserved_copy_of_name
=
1972 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1975 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1977 S_SET_SEGMENT (symbolP
, segment
);
1978 S_SET_VALUE (symbolP
, valu
);
1979 symbol_clear_list_pointers(symbolP
);
1981 symbol_set_frag (symbolP
, frag
);
1983 /* Link to end of symbol chain. */
1985 extern int symbol_table_frozen
;
1986 if (symbol_table_frozen
)
1990 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1992 obj_symbol_new_hook (symbolP
);
1994 #ifdef tc_symbol_new_hook
1995 tc_symbol_new_hook (symbolP
);
1999 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
2000 #endif /* DEBUG_SYMS */
2003 /* Check that an immediate is valid.
2004 If so, convert it to the right format. */
2007 validate_immediate (val
)
2013 #define rotate_left(v, n) (v << n | v >> (32 - n))
2015 for (i
= 0; i
< 32; i
+= 2)
2016 if ((a
= rotate_left (val
, i
)) <= 0xff)
2017 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
2022 /* Check to see if an immediate can be computed as two seperate immediate
2023 values, added together. We already know that this value cannot be
2024 computed by just one ARM instruction. */
2027 validate_immediate_twopart (val
, highpart
)
2029 unsigned int * highpart
;
2034 for (i
= 0; i
< 32; i
+= 2)
2035 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
2041 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
2043 else if (a
& 0xff0000)
2047 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
2051 assert (a
& 0xff000000);
2052 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
2055 return (a
& 0xff) | (i
<< 7);
2062 validate_offset_imm (val
, hwse
)
2066 if ((hwse
&& val
> 255) || val
> 4095)
2073 int a ATTRIBUTE_UNUSED
;
2075 as_bad (_("Invalid syntax for .req directive."));
2080 int ignore ATTRIBUTE_UNUSED
;
2082 /* We don't support putting frags in the BSS segment, we fake it by
2083 marking in_bss, then looking at s_skip for clues. */
2084 subseg_set (bss_section
, 0);
2085 demand_empty_rest_of_line ();
2090 int ignore ATTRIBUTE_UNUSED
;
2092 /* Never make frag if expect extra pass. */
2094 frag_align (1, 0, 0);
2096 record_alignment (now_seg
, 1);
2098 demand_empty_rest_of_line ();
2103 int ignored ATTRIBUTE_UNUSED
;
2108 if (current_poolP
== NULL
)
2111 /* Align pool as you have word accesses.
2112 Only make a frag if we have to. */
2114 frag_align (2, 0, 0);
2116 record_alignment (now_seg
, 2);
2118 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
2120 symbol_locate (current_poolP
, sym_name
, now_seg
,
2121 (valueT
) frag_now_fix (), frag_now
);
2122 symbol_table_insert (current_poolP
);
2124 ARM_SET_THUMB (current_poolP
, thumb_mode
);
2126 #if defined OBJ_COFF || defined OBJ_ELF
2127 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
2130 while (lit_count
< next_literal_pool_place
)
2131 /* First output the expression in the instruction to the pool. */
2132 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
2134 next_literal_pool_place
= 0;
2135 current_poolP
= NULL
;
2138 /* Same as s_align_ptwo but align 0 => align 2. */
2142 int unused ATTRIBUTE_UNUSED
;
2145 register long temp_fill
;
2146 long max_alignment
= 15;
2148 temp
= get_absolute_expression ();
2149 if (temp
> max_alignment
)
2150 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
2153 as_bad (_("Alignment negative. 0 assumed."));
2157 if (*input_line_pointer
== ',')
2159 input_line_pointer
++;
2160 temp_fill
= get_absolute_expression ();
2168 /* Only make a frag if we HAVE to. */
2169 if (temp
&& !need_pass_2
)
2170 frag_align (temp
, (int) temp_fill
, 0);
2171 demand_empty_rest_of_line ();
2173 record_alignment (now_seg
, temp
);
2177 s_force_thumb (ignore
)
2178 int ignore ATTRIBUTE_UNUSED
;
2180 /* If we are not already in thumb mode go into it, EVEN if
2181 the target processor does not support thumb instructions.
2182 This is used by gcc/config/arm/lib1funcs.asm for example
2183 to compile interworking support functions even if the
2184 target processor should not support interworking. */
2189 record_alignment (now_seg
, 1);
2192 demand_empty_rest_of_line ();
2196 s_thumb_func (ignore
)
2197 int ignore ATTRIBUTE_UNUSED
;
2202 /* The following label is the name/address of the start of a Thumb function.
2203 We need to know this for the interworking support. */
2204 label_is_thumb_function_name
= true;
2206 demand_empty_rest_of_line ();
2209 /* Perform a .set directive, but also mark the alias as
2210 being a thumb function. */
2216 /* XXX the following is a duplicate of the code for s_set() in read.c
2217 We cannot just call that code as we need to get at the symbol that
2219 register char * name
;
2220 register char delim
;
2221 register char * end_name
;
2222 register symbolS
* symbolP
;
2224 /* Especial apologies for the random logic:
2225 This just grew, and could be parsed much more simply!
2227 name
= input_line_pointer
;
2228 delim
= get_symbol_end ();
2229 end_name
= input_line_pointer
;
2234 if (*input_line_pointer
!= ',')
2237 as_bad (_("Expected comma after name \"%s\""), name
);
2239 ignore_rest_of_line ();
2243 input_line_pointer
++;
2246 if (name
[0] == '.' && name
[1] == '\0')
2248 /* XXX - this should not happen to .thumb_set. */
2252 if ((symbolP
= symbol_find (name
)) == NULL
2253 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
2256 /* When doing symbol listings, play games with dummy fragments living
2257 outside the normal fragment chain to record the file and line info
2259 if (listing
& LISTING_SYMBOLS
)
2261 extern struct list_info_struct
* listing_tail
;
2262 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
2264 memset (dummy_frag
, 0, sizeof (fragS
));
2265 dummy_frag
->fr_type
= rs_fill
;
2266 dummy_frag
->line
= listing_tail
;
2267 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
2268 dummy_frag
->fr_symbol
= symbolP
;
2272 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
2275 /* "set" symbols are local unless otherwise specified. */
2276 SF_SET_LOCAL (symbolP
);
2277 #endif /* OBJ_COFF */
2278 } /* Make a new symbol. */
2280 symbol_table_insert (symbolP
);
2285 && S_IS_DEFINED (symbolP
)
2286 && S_GET_SEGMENT (symbolP
) != reg_section
)
2287 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
2289 pseudo_set (symbolP
);
2291 demand_empty_rest_of_line ();
2293 /* XXX Now we come to the Thumb specific bit of code. */
2295 THUMB_SET_FUNC (symbolP
, 1);
2296 ARM_SET_THUMB (symbolP
, 1);
2297 #if defined OBJ_ELF || defined OBJ_COFF
2298 ARM_SET_INTERWORK (symbolP
, support_interwork
);
2302 /* If we change section we must dump the literal pool first. */
2308 if (now_seg
!= text_section
)
2312 obj_elf_text (ignore
);
2322 if (flag_readonly_data_in_text
)
2324 if (now_seg
!= text_section
)
2327 else if (now_seg
!= data_section
)
2331 obj_elf_data (ignore
);
2339 arm_s_section (ignore
)
2344 obj_elf_section (ignore
);
2349 opcode_select (width
)
2357 if (! (cpu_variant
& ARM_EXT_V4T
))
2358 as_bad (_("selected processor does not support THUMB opcodes"));
2361 /* No need to force the alignment, since we will have been
2362 coming from ARM mode, which is word-aligned. */
2363 record_alignment (now_seg
, 1);
2370 if ((cpu_variant
& ARM_ANY
) == ARM_EXT_V4T
)
2371 as_bad (_("selected processor does not support ARM opcodes"));
2376 frag_align (2, 0, 0);
2378 record_alignment (now_seg
, 1);
2383 as_bad (_("invalid instruction size selected (%d)"), width
);
2389 int ignore ATTRIBUTE_UNUSED
;
2392 demand_empty_rest_of_line ();
2397 int ignore ATTRIBUTE_UNUSED
;
2400 demand_empty_rest_of_line ();
2405 int unused ATTRIBUTE_UNUSED
;
2409 temp
= get_absolute_expression ();
2414 opcode_select (temp
);
2418 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
2426 skip_whitespace (str
);
2429 inst
.error
= _("Garbage following instruction");
2433 skip_past_comma (str
)
2436 char * p
= * str
, c
;
2439 while ((c
= *p
) == ' ' || c
== ',')
2442 if (c
== ',' && comma
++)
2450 return comma
? SUCCESS
: FAIL
;
2453 /* A standard register must be given at this point.
2454 SHIFT is the place to put it in inst.instruction.
2455 Restores input start point on error.
2456 Returns the reg#, or FAIL. */
2459 reg_required_here (str
, shift
)
2463 static char buff
[128]; /* XXX */
2465 char * start
= * str
;
2467 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_RN
].htab
)) != FAIL
)
2470 inst
.instruction
|= reg
<< shift
;
2474 /* Restore the start point, we may have got a reg of the wrong class. */
2477 /* In the few cases where we might be able to accept something else
2478 this error can be overridden. */
2479 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
2485 static const struct asm_psr
*
2487 register char ** ccp
;
2489 char * start
= * ccp
;
2492 const struct asm_psr
* psr
;
2496 /* Skip to the end of the next word in the input stream. */
2501 while (ISALPHA (c
) || c
== '_');
2503 /* Terminate the word. */
2506 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
2507 feature for ease of use and backwards compatibility. */
2508 if (!strncmp (start
, "cpsr", 4))
2509 strncpy (start
, "CPSR", 4);
2510 else if (!strncmp (start
, "spsr", 4))
2511 strncpy (start
, "SPSR", 4);
2513 /* Now locate the word in the psr hash table. */
2514 psr
= (const struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
2516 /* Restore the input stream. */
2519 /* If we found a valid match, advance the
2520 stream pointer past the end of the word. */
2526 /* Parse the input looking for a PSR flag. */
2529 psr_required_here (str
)
2532 char * start
= * str
;
2533 const struct asm_psr
* psr
;
2535 psr
= arm_psr_parse (str
);
2539 /* If this is the SPSR that is being modified, set the R bit. */
2541 inst
.instruction
|= SPSR_BIT
;
2543 /* Set the psr flags in the MSR instruction. */
2544 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
2549 /* In the few cases where we might be able to accept
2550 something else this error can be overridden. */
2551 inst
.error
= _("flag for {c}psr instruction expected");
2553 /* Restore the start point. */
2559 co_proc_number (str
)
2562 int processor
, pchar
;
2565 skip_whitespace (*str
);
2568 /* The data sheet seems to imply that just a number on its own is valid
2569 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
2571 if ((processor
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_CP
].htab
))
2577 if (pchar
>= '0' && pchar
<= '9')
2579 processor
= pchar
- '0';
2580 if (**str
>= '0' && **str
<= '9')
2582 processor
= processor
* 10 + *(*str
)++ - '0';
2585 inst
.error
= _("Illegal co-processor number");
2592 inst
.error
= _("Bad or missing co-processor number");
2597 inst
.instruction
|= processor
<< 8;
2602 cp_opc_expr (str
, where
, length
)
2609 skip_whitespace (* str
);
2611 memset (&expr
, '\0', sizeof (expr
));
2613 if (my_get_expression (&expr
, str
))
2615 if (expr
.X_op
!= O_constant
)
2617 inst
.error
= _("bad or missing expression");
2621 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
2623 inst
.error
= _("immediate co-processor expression too large");
2627 inst
.instruction
|= expr
.X_add_number
<< where
;
2632 cp_reg_required_here (str
, where
)
2637 char * start
= *str
;
2639 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_CN
].htab
)) != FAIL
)
2641 inst
.instruction
|= reg
<< where
;
2645 /* In the few cases where we might be able to accept something else
2646 this error can be overridden. */
2647 inst
.error
= _("Co-processor register expected");
2649 /* Restore the start point. */
2655 fp_reg_required_here (str
, where
)
2660 char * start
= * str
;
2662 if ((reg
= arm_reg_parse (str
, all_reg_maps
[REG_TYPE_FN
].htab
)) != FAIL
)
2664 inst
.instruction
|= reg
<< where
;
2668 /* In the few cases where we might be able to accept something else
2669 this error can be overridden. */
2670 inst
.error
= _("Floating point register expected");
2672 /* Restore the start point. */
2678 cp_address_offset (str
)
2683 skip_whitespace (* str
);
2685 if (! is_immediate_prefix (**str
))
2687 inst
.error
= _("immediate expression expected");
2693 if (my_get_expression (& inst
.reloc
.exp
, str
))
2696 if (inst
.reloc
.exp
.X_op
== O_constant
)
2698 offset
= inst
.reloc
.exp
.X_add_number
;
2702 inst
.error
= _("co-processor address must be word aligned");
2706 if (offset
> 1023 || offset
< -1023)
2708 inst
.error
= _("offset too large");
2713 inst
.instruction
|= INDEX_UP
;
2717 inst
.instruction
|= offset
>> 2;
2720 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2726 cp_address_required_here (str
)
2738 skip_whitespace (p
);
2740 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
2743 skip_whitespace (p
);
2749 if (skip_past_comma (& p
) == SUCCESS
)
2752 write_back
= WRITE_BACK
;
2756 inst
.error
= _("pc may not be used in post-increment");
2760 if (cp_address_offset (& p
) == FAIL
)
2764 pre_inc
= PRE_INDEX
| INDEX_UP
;
2768 /* '['Rn, #expr']'[!] */
2770 if (skip_past_comma (& p
) == FAIL
)
2772 inst
.error
= _("pre-indexed expression expected");
2776 pre_inc
= PRE_INDEX
;
2778 if (cp_address_offset (& p
) == FAIL
)
2781 skip_whitespace (p
);
2785 inst
.error
= _("missing ]");
2789 skip_whitespace (p
);
2795 inst
.error
= _("pc may not be used with write-back");
2800 write_back
= WRITE_BACK
;
2806 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2809 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2810 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2811 inst
.reloc
.pc_rel
= 1;
2812 inst
.instruction
|= (REG_PC
<< 16);
2813 pre_inc
= PRE_INDEX
;
2816 inst
.instruction
|= write_back
| pre_inc
;
2825 /* Do nothing really. */
2836 /* Only one syntax. */
2837 skip_whitespace (str
);
2839 if (reg_required_here (&str
, 12) == FAIL
)
2841 inst
.error
= BAD_ARGS
;
2845 if (skip_past_comma (&str
) == FAIL
)
2847 inst
.error
= _("comma expected after register name");
2851 skip_whitespace (str
);
2853 if ( strcmp (str
, "CPSR") == 0
2854 || strcmp (str
, "SPSR") == 0
2855 /* Lower case versions for backwards compatability. */
2856 || strcmp (str
, "cpsr") == 0
2857 || strcmp (str
, "spsr") == 0)
2860 /* This is for backwards compatability with older toolchains. */
2861 else if ( strcmp (str
, "cpsr_all") == 0
2862 || strcmp (str
, "spsr_all") == 0)
2866 inst
.error
= _("{C|S}PSR expected");
2870 if (* str
== 's' || * str
== 'S')
2871 inst
.instruction
|= SPSR_BIT
;
2877 /* Two possible forms:
2878 "{C|S}PSR_<field>, Rm",
2879 "{C|S}PSR_f, #expression". */
2885 skip_whitespace (str
);
2887 if (psr_required_here (& str
) == FAIL
)
2890 if (skip_past_comma (& str
) == FAIL
)
2892 inst
.error
= _("comma missing after psr flags");
2896 skip_whitespace (str
);
2898 if (reg_required_here (& str
, 0) != FAIL
)
2905 if (! is_immediate_prefix (* str
))
2908 _("only a register or immediate value can follow a psr flag");
2915 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2918 _("only a register or immediate value can follow a psr flag");
2922 #if 0 /* The first edition of the ARM architecture manual stated that
2923 writing anything other than the flags with an immediate operation
2924 had UNPREDICTABLE effects. This constraint was removed in the
2925 second edition of the specification. */
2926 if ((cpu_variant
& ARM_EXT_V5
) != ARM_EXT_V5
2927 && inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2929 inst
.error
= _("immediate value cannot be used to set this field");
2934 inst
.instruction
|= INST_IMMEDIATE
;
2936 if (inst
.reloc
.exp
.X_add_symbol
)
2938 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2939 inst
.reloc
.pc_rel
= 0;
2943 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2945 if (value
== (unsigned) FAIL
)
2947 inst
.error
= _("Invalid constant");
2951 inst
.instruction
|= value
;
2958 /* Long Multiply Parser
2959 UMULL RdLo, RdHi, Rm, Rs
2960 SMULL RdLo, RdHi, Rm, Rs
2961 UMLAL RdLo, RdHi, Rm, Rs
2962 SMLAL RdLo, RdHi, Rm, Rs. */
2968 int rdlo
, rdhi
, rm
, rs
;
2970 /* Only one format "rdlo, rdhi, rm, rs". */
2971 skip_whitespace (str
);
2973 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2975 inst
.error
= BAD_ARGS
;
2979 if (skip_past_comma (&str
) == FAIL
2980 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2982 inst
.error
= BAD_ARGS
;
2986 if (skip_past_comma (&str
) == FAIL
2987 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2989 inst
.error
= BAD_ARGS
;
2993 /* rdhi, rdlo and rm must all be different. */
2994 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2995 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2997 if (skip_past_comma (&str
) == FAIL
2998 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
3000 inst
.error
= BAD_ARGS
;
3004 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
3006 inst
.error
= BAD_PC
;
3020 /* Only one format "rd, rm, rs". */
3021 skip_whitespace (str
);
3023 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
3025 inst
.error
= BAD_ARGS
;
3031 inst
.error
= BAD_PC
;
3035 if (skip_past_comma (&str
) == FAIL
3036 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
3038 inst
.error
= BAD_ARGS
;
3044 inst
.error
= BAD_PC
;
3049 as_tsktsk (_("rd and rm should be different in mul"));
3051 if (skip_past_comma (&str
) == FAIL
3052 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
3054 inst
.error
= BAD_ARGS
;
3060 inst
.error
= BAD_PC
;
3074 /* Only one format "rd, rm, rs, rn". */
3075 skip_whitespace (str
);
3077 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
3079 inst
.error
= BAD_ARGS
;
3085 inst
.error
= BAD_PC
;
3089 if (skip_past_comma (&str
) == FAIL
3090 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
3092 inst
.error
= BAD_ARGS
;
3098 inst
.error
= BAD_PC
;
3103 as_tsktsk (_("rd and rm should be different in mla"));
3105 if (skip_past_comma (&str
) == FAIL
3106 || (rd
= reg_required_here (&str
, 8)) == FAIL
3107 || skip_past_comma (&str
) == FAIL
3108 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
3110 inst
.error
= BAD_ARGS
;
3114 if (rd
== REG_PC
|| rm
== REG_PC
)
3116 inst
.error
= BAD_PC
;
3124 /* Expects *str -> the characters "acc0", possibly with leading blanks.
3125 Advances *str to the next non-alphanumeric.
3126 Returns 0, or else FAIL (in which case sets inst.error).
3128 (In a future XScale, there may be accumulators other than zero.
3129 At that time this routine and its callers can be upgraded to suit.) */
3132 accum0_required_here (str
)
3135 static char buff
[128]; /* Note the address is taken. Hence, static. */
3138 int result
= 0; /* The accum number. */
3140 skip_whitespace (p
);
3142 *str
= p
; /* Advance caller's string pointer too. */
3147 *--p
= 0; /* Aap nul into input buffer at non-alnum. */
3149 if (! ( streq (*str
, "acc0") || streq (*str
, "ACC0")))
3151 sprintf (buff
, _("acc0 expected, not '%.100s'"), *str
);
3156 *p
= c
; /* Unzap. */
3157 *str
= p
; /* Caller's string pointer to after match. */
3161 /* Expects **str -> after a comma. May be leading blanks.
3162 Advances *str, recognizing a load mode, and setting inst.instruction.
3163 Returns rn, or else FAIL (in which case may set inst.error
3164 and not advance str)
3166 Note: doesn't know Rd, so no err checks that require such knowledge. */
3169 ld_mode_required_here (string
)
3172 char * str
= * string
;
3176 skip_whitespace (str
);
3182 skip_whitespace (str
);
3184 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
3187 skip_whitespace (str
);
3193 if (skip_past_comma (& str
) == SUCCESS
)
3195 /* [Rn],... (post inc) */
3196 if (ldst_extend_v4 (&str
) == FAIL
)
3201 skip_whitespace (str
);
3206 inst
.instruction
|= WRITE_BACK
;
3209 inst
.instruction
|= INDEX_UP
| HWOFFSET_IMM
;
3215 if (skip_past_comma (& str
) == FAIL
)
3217 inst
.error
= _("pre-indexed expression expected");
3223 if (ldst_extend_v4 (&str
) == FAIL
)
3226 skip_whitespace (str
);
3228 if (* str
++ != ']')
3230 inst
.error
= _("missing ]");
3234 skip_whitespace (str
);
3239 inst
.instruction
|= WRITE_BACK
;
3243 else if (* str
== '=') /* ldr's "r,=label" syntax */
3244 /* We should never reach here, because <text> = <expression> is
3245 caught gas/read.c read_a_source_file() as a .set operation. */
3247 else /* PC +- 8 bit immediate offset. */
3249 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3252 inst
.instruction
|= HWOFFSET_IMM
; /* The I bit. */
3253 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3254 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
3255 inst
.reloc
.pc_rel
= 1;
3256 inst
.instruction
|= (REG_PC
<< 16);
3262 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
3268 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3269 SMLAxy{cond} Rd,Rm,Rs,Rn
3270 SMLAWy{cond} Rd,Rm,Rs,Rn
3271 Error if any register is R15. */
3279 skip_whitespace (str
);
3281 if ((rd
= reg_required_here (& str
, 16)) == FAIL
3282 || skip_past_comma (& str
) == FAIL
3283 || (rm
= reg_required_here (& str
, 0)) == FAIL
3284 || skip_past_comma (& str
) == FAIL
3285 || (rs
= reg_required_here (& str
, 8)) == FAIL
3286 || skip_past_comma (& str
) == FAIL
3287 || (rn
= reg_required_here (& str
, 12)) == FAIL
)
3288 inst
.error
= BAD_ARGS
;
3290 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
|| rn
== REG_PC
)
3291 inst
.error
= BAD_PC
;
3297 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3298 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3299 Error if any register is R15.
3300 Warning if Rdlo == Rdhi. */
3306 int rdlo
, rdhi
, rm
, rs
;
3308 skip_whitespace (str
);
3310 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
3311 || skip_past_comma (& str
) == FAIL
3312 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
3313 || skip_past_comma (& str
) == FAIL
3314 || (rm
= reg_required_here (& str
, 0)) == FAIL
3315 || skip_past_comma (& str
) == FAIL
3316 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
3318 inst
.error
= BAD_ARGS
;
3322 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
3324 inst
.error
= BAD_PC
;
3329 as_tsktsk (_("rdhi and rdlo must be different"));
3334 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3335 SMULxy{cond} Rd,Rm,Rs
3336 Error if any register is R15. */
3344 skip_whitespace (str
);
3346 if ((rd
= reg_required_here (& str
, 16)) == FAIL
3347 || skip_past_comma (& str
) == FAIL
3348 || (rm
= reg_required_here (& str
, 0)) == FAIL
3349 || skip_past_comma (& str
) == FAIL
3350 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
3351 inst
.error
= BAD_ARGS
;
3353 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
3354 inst
.error
= BAD_PC
;
3360 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3361 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3362 Error if any register is R15. */
3370 skip_whitespace (str
);
3372 if ((rd
= reg_required_here (& str
, 12)) == FAIL
3373 || skip_past_comma (& str
) == FAIL
3374 || (rm
= reg_required_here (& str
, 0)) == FAIL
3375 || skip_past_comma (& str
) == FAIL
3376 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
3377 inst
.error
= BAD_ARGS
;
3379 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
3380 inst
.error
= BAD_PC
;
3386 /* ARM V5E (el Segundo)
3387 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3388 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3390 These are equivalent to the XScale instructions MAR and MRA,
3391 respectively, when coproc == 0, opcode == 0, and CRm == 0.
3393 Result unpredicatable if Rd or Rn is R15. */
3401 skip_whitespace (str
);
3403 if (co_proc_number (& str
) == FAIL
)
3406 inst
.error
= BAD_ARGS
;
3410 if (skip_past_comma (& str
) == FAIL
3411 || cp_opc_expr (& str
, 4, 4) == FAIL
)
3414 inst
.error
= BAD_ARGS
;
3418 if (skip_past_comma (& str
) == FAIL
3419 || (rd
= reg_required_here (& str
, 12)) == FAIL
)
3422 inst
.error
= BAD_ARGS
;
3426 if (skip_past_comma (& str
) == FAIL
3427 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
3430 inst
.error
= BAD_ARGS
;
3434 /* Unpredictable result if rd or rn is R15. */
3435 if (rd
== REG_PC
|| rn
== REG_PC
)
3437 (_("Warning: Instruction unpredictable when using r15"));
3439 if (skip_past_comma (& str
) == FAIL
3440 || cp_reg_required_here (& str
, 0) == FAIL
)
3443 inst
.error
= BAD_ARGS
;
3450 /* ARM V5 count-leading-zeroes instruction (argument parse)
3451 CLZ{<cond>} <Rd>, <Rm>
3452 Condition defaults to COND_ALWAYS.
3453 Error if Rd or Rm are R15. */
3461 skip_whitespace (str
);
3463 if (((rd
= reg_required_here (& str
, 12)) == FAIL
)
3464 || (skip_past_comma (& str
) == FAIL
)
3465 || ((rm
= reg_required_here (& str
, 0)) == FAIL
))
3466 inst
.error
= BAD_ARGS
;
3468 else if (rd
== REG_PC
|| rm
== REG_PC
)
3469 inst
.error
= BAD_PC
;
3475 /* ARM V5 (argument parse)
3476 LDC2{L} <coproc>, <CRd>, <addressing mode>
3477 STC2{L} <coproc>, <CRd>, <addressing mode>
3478 Instruction is not conditional, and has 0xf in the codition field.
3479 Otherwise, it's the same as LDC/STC. */
3485 skip_whitespace (str
);
3487 if (co_proc_number (& str
) == FAIL
)
3490 inst
.error
= BAD_ARGS
;
3492 else if (skip_past_comma (& str
) == FAIL
3493 || cp_reg_required_here (& str
, 12) == FAIL
)
3496 inst
.error
= BAD_ARGS
;
3498 else if (skip_past_comma (& str
) == FAIL
3499 || cp_address_required_here (& str
) == FAIL
)
3502 inst
.error
= BAD_ARGS
;
3508 /* ARM V5 (argument parse)
3509 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3510 Instruction is not conditional, and has 0xf in the condition field.
3511 Otherwise, it's the same as CDP. */
3517 skip_whitespace (str
);
3519 if (co_proc_number (& str
) == FAIL
)
3522 inst
.error
= BAD_ARGS
;
3526 if (skip_past_comma (& str
) == FAIL
3527 || cp_opc_expr (& str
, 20,4) == FAIL
)
3530 inst
.error
= BAD_ARGS
;
3534 if (skip_past_comma (& str
) == FAIL
3535 || cp_reg_required_here (& str
, 12) == FAIL
)
3538 inst
.error
= BAD_ARGS
;
3542 if (skip_past_comma (& str
) == FAIL
3543 || cp_reg_required_here (& str
, 16) == FAIL
)
3546 inst
.error
= BAD_ARGS
;
3550 if (skip_past_comma (& str
) == FAIL
3551 || cp_reg_required_here (& str
, 0) == FAIL
)
3554 inst
.error
= BAD_ARGS
;
3558 if (skip_past_comma (& str
) == SUCCESS
)
3560 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3563 inst
.error
= BAD_ARGS
;
3571 /* ARM V5 (argument parse)
3572 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3573 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3574 Instruction is not conditional, and has 0xf in the condition field.
3575 Otherwise, it's the same as MCR/MRC. */
3581 skip_whitespace (str
);
3583 if (co_proc_number (& str
) == FAIL
)
3586 inst
.error
= BAD_ARGS
;
3590 if (skip_past_comma (& str
) == FAIL
3591 || cp_opc_expr (& str
, 21, 3) == FAIL
)
3594 inst
.error
= BAD_ARGS
;
3598 if (skip_past_comma (& str
) == FAIL
3599 || reg_required_here (& str
, 12) == FAIL
)
3602 inst
.error
= BAD_ARGS
;
3606 if (skip_past_comma (& str
) == FAIL
3607 || cp_reg_required_here (& str
, 16) == FAIL
)
3610 inst
.error
= BAD_ARGS
;
3614 if (skip_past_comma (& str
) == FAIL
3615 || cp_reg_required_here (& str
, 0) == FAIL
)
3618 inst
.error
= BAD_ARGS
;
3622 if (skip_past_comma (& str
) == SUCCESS
)
3624 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3627 inst
.error
= BAD_ARGS
;
3635 /* THUMB V5 breakpoint instruction (argument parse)
3643 unsigned long number
;
3645 skip_whitespace (str
);
3647 /* Allow optional leading '#'. */
3648 if (is_immediate_prefix (*str
))
3651 memset (& expr
, '\0', sizeof (expr
));
3652 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3654 inst
.error
= _("bad or missing expression");
3658 number
= expr
.X_add_number
;
3660 /* Check it fits an 8 bit unsigned. */
3661 if (number
!= (number
& 0xff))
3663 inst
.error
= _("immediate value out of range");
3667 inst
.instruction
|= number
;
3672 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3673 Expects inst.instruction is set for BLX(1).
3674 Note: this is cloned from do_branch, and the reloc changed to be a
3675 new one that can cope with setting one extra bit (the H bit). */
3681 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3688 /* ScottB: February 5, 1998 */
3689 /* Check to see of PLT32 reloc required for the instruction. */
3691 /* arm_parse_reloc() works on input_line_pointer.
3692 We actually want to parse the operands to the branch instruction
3693 passed in 'str'. Save the input pointer and restore it later. */
3694 save_in
= input_line_pointer
;
3695 input_line_pointer
= str
;
3697 if (inst
.reloc
.exp
.X_op
== O_symbol
3699 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3701 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3702 inst
.reloc
.pc_rel
= 0;
3703 /* Modify str to point to after parsed operands, otherwise
3704 end_of_line() will complain about the (PLT) left in str. */
3705 str
= input_line_pointer
;
3709 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3710 inst
.reloc
.pc_rel
= 1;
3713 input_line_pointer
= save_in
;
3716 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3717 inst
.reloc
.pc_rel
= 1;
3718 #endif /* OBJ_ELF */
3723 /* ARM V5 branch-link-exchange instruction (argument parse)
3724 BLX <target_addr> ie BLX(1)
3725 BLX{<condition>} <Rm> ie BLX(2)
3726 Unfortunately, there are two different opcodes for this mnemonic.
3727 So, the insns[].value is not used, and the code here zaps values
3728 into inst.instruction.
3729 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
3738 skip_whitespace (mystr
);
3739 rm
= reg_required_here (& mystr
, 0);
3741 /* The above may set inst.error. Ignore his opinion. */
3746 /* Arg is a register.
3747 Use the condition code our caller put in inst.instruction.
3748 Pass ourselves off as a BX with a funny opcode. */
3749 inst
.instruction
|= 0x012fff30;
3754 /* This must be is BLX <target address>, no condition allowed. */
3755 if (inst
.instruction
!= COND_ALWAYS
)
3757 inst
.error
= BAD_COND
;
3761 inst
.instruction
= 0xfafffffe;
3763 /* Process like a B/BL, but with a different reloc.
3764 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
3769 /* ARM V5 Thumb BLX (argument parse)
3770 BLX <target_addr> which is BLX(1)
3771 BLX <Rm> which is BLX(2)
3772 Unfortunately, there are two different opcodes for this mnemonic.
3773 So, the tinsns[].value is not used, and the code here zaps values
3774 into inst.instruction. */
3783 skip_whitespace (mystr
);
3784 inst
.instruction
= 0x4780;
3786 /* Note that this call is to the ARM register recognizer. BLX(2)
3787 uses the ARM register space, not the Thumb one, so a call to
3788 thumb_reg() would be wrong. */
3789 rm
= reg_required_here (& mystr
, 3);
3794 /* It's BLX(2). The .instruction was zapped with rm & is final. */
3799 /* No ARM register. This must be BLX(1). Change the .instruction. */
3800 inst
.instruction
= 0xf7ffeffe;
3803 if (my_get_expression (& inst
.reloc
.exp
, & mystr
))
3806 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BLX
;
3807 inst
.reloc
.pc_rel
= 1;
3810 end_of_line (mystr
);
3813 /* ARM V5 breakpoint instruction (argument parse)
3814 BKPT <16 bit unsigned immediate>
3815 Instruction is not conditional.
3816 The bit pattern given in insns[] has the COND_ALWAYS condition,
3817 and it is an error if the caller tried to override that. */
3824 unsigned long number
;
3826 skip_whitespace (str
);
3828 /* Allow optional leading '#'. */
3829 if (is_immediate_prefix (* str
))
3832 memset (& expr
, '\0', sizeof (expr
));
3834 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3836 inst
.error
= _("bad or missing expression");
3840 number
= expr
.X_add_number
;
3842 /* Check it fits a 16 bit unsigned. */
3843 if (number
!= (number
& 0xffff))
3845 inst
.error
= _("immediate value out of range");
3849 /* Top 12 of 16 bits to bits 19:8. */
3850 inst
.instruction
|= (number
& 0xfff0) << 4;
3852 /* Bottom 4 of 16 bits to bits 3:0. */
3853 inst
.instruction
|= number
& 0xf;
3858 /* Xscale multiply-accumulate (argument parse)
3861 MIAxycc acc0,Rm,Rs. */
3870 if (accum0_required_here (& str
) == FAIL
)
3871 inst
.error
= ERR_NO_ACCUM
;
3873 else if (skip_past_comma (& str
) == FAIL
3874 || (rm
= reg_required_here (& str
, 0)) == FAIL
)
3875 inst
.error
= BAD_ARGS
;
3877 else if (skip_past_comma (& str
) == FAIL
3878 || (rs
= reg_required_here (& str
, 12)) == FAIL
)
3879 inst
.error
= BAD_ARGS
;
3881 /* inst.instruction has now been zapped with both rm and rs. */
3882 else if (rm
== REG_PC
|| rs
== REG_PC
)
3883 inst
.error
= BAD_PC
; /* Undefined result if rm or rs is R15. */
3889 /* Xscale move-accumulator-register (argument parse)
3891 MARcc acc0,RdLo,RdHi. */
3899 if (accum0_required_here (& str
) == FAIL
)
3900 inst
.error
= ERR_NO_ACCUM
;
3902 else if (skip_past_comma (& str
) == FAIL
3903 || (rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3904 inst
.error
= BAD_ARGS
;
3906 else if (skip_past_comma (& str
) == FAIL
3907 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3908 inst
.error
= BAD_ARGS
;
3910 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3911 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3912 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3918 /* Xscale move-register-accumulator (argument parse)
3920 MRAcc RdLo,RdHi,acc0. */
3929 skip_whitespace (str
);
3931 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3932 inst
.error
= BAD_ARGS
;
3934 else if (skip_past_comma (& str
) == FAIL
3935 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3936 inst
.error
= BAD_ARGS
;
3938 else if (skip_past_comma (& str
) == FAIL
3939 || accum0_required_here (& str
) == FAIL
)
3940 inst
.error
= ERR_NO_ACCUM
;
3942 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3943 else if (rdlo
== rdhi
)
3944 inst
.error
= BAD_ARGS
; /* Undefined result if 2 writes to same reg. */
3946 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3947 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3952 /* ARMv5TE: Preload-Cache
3956 Syntactically, like LDR with B=1, W=0, L=1. */
3964 skip_whitespace (str
);
3968 inst
.error
= _("'[' expected after PLD mnemonic");
3973 skip_whitespace (str
);
3975 if ((rd
= reg_required_here (& str
, 16)) == FAIL
)
3978 skip_whitespace (str
);
3984 skip_whitespace (str
);
3986 /* Post-indexed addressing is not allowed with PLD. */
3987 if (skip_past_comma (&str
) == SUCCESS
)
3990 = _("post-indexed expression used in preload instruction");
3993 else if (*str
== '!') /* [Rn]! */
3995 inst
.error
= _("writeback used in preload instruction");
3999 inst
.instruction
|= INDEX_UP
| PRE_INDEX
;
4001 else /* [Rn, ...] */
4003 if (skip_past_comma (& str
) == FAIL
)
4005 inst
.error
= _("pre-indexed expression expected");
4009 if (ldst_extend (&str
) == FAIL
)
4012 skip_whitespace (str
);
4016 inst
.error
= _("missing ]");
4021 skip_whitespace (str
);
4023 if (* str
== '!') /* [Rn]! */
4025 inst
.error
= _("writeback used in preload instruction");
4029 inst
.instruction
|= PRE_INDEX
;
4035 /* ARMv5TE load-consecutive (argument parse)
4048 skip_whitespace (str
);
4050 if ((rd
= reg_required_here (& str
, 12)) == FAIL
)
4052 inst
.error
= BAD_ARGS
;
4056 if (skip_past_comma (& str
) == FAIL
4057 || (rn
= ld_mode_required_here (& str
)) == FAIL
)
4060 inst
.error
= BAD_ARGS
;
4064 /* inst.instruction has now been zapped with Rd and the addressing mode. */
4065 if (rd
& 1) /* Unpredictable result if Rd is odd. */
4067 inst
.error
= _("Destination register must be even");
4073 inst
.error
= _("r14 not allowed here");
4077 if (((rd
== rn
) || (rd
+ 1 == rn
))
4078 && ((inst
.instruction
& WRITE_BACK
)
4079 || (!(inst
.instruction
& PRE_INDEX
))))
4080 as_warn (_("pre/post-indexing used when modified address register is destination"));
4082 /* For an index-register load, the index register must not overlap the
4083 destination (even if not write-back). */
4084 if ((inst
.instruction
& V4_STR_BIT
) == 0
4085 && (inst
.instruction
& HWOFFSET_IMM
) == 0)
4087 int rm
= inst
.instruction
& 0x0000000f;
4089 if (rm
== rd
|| (rm
== rd
+ 1))
4090 as_warn (_("ldrd destination registers must not overlap index register"));
4096 /* Returns the index into fp_values of a floating point number,
4097 or -1 if not in the table. */
4100 my_get_float_expression (str
)
4103 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4109 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
4111 /* Look for a raw floating point number. */
4112 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
4113 && is_end_of_line
[(unsigned char) *save_in
])
4115 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4117 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
4119 if (words
[j
] != fp_values
[i
][j
])
4123 if (j
== MAX_LITTLENUMS
)
4131 /* Try and parse a more complex expression, this will probably fail
4132 unless the code uses a floating point prefix (eg "0f"). */
4133 save_in
= input_line_pointer
;
4134 input_line_pointer
= *str
;
4135 if (expression (&exp
) == absolute_section
4136 && exp
.X_op
== O_big
4137 && exp
.X_add_number
< 0)
4139 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
4141 if (gen_to_words (words
, 5, (long) 15) == 0)
4143 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4145 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
4147 if (words
[j
] != fp_values
[i
][j
])
4151 if (j
== MAX_LITTLENUMS
)
4153 *str
= input_line_pointer
;
4154 input_line_pointer
= save_in
;
4161 *str
= input_line_pointer
;
4162 input_line_pointer
= save_in
;
4166 /* Return true if anything in the expression is a bignum. */
4169 walk_no_bignums (sp
)
4172 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
4175 if (symbol_get_value_expression (sp
)->X_add_symbol
)
4177 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
4178 || (symbol_get_value_expression (sp
)->X_op_symbol
4179 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
4186 my_get_expression (ep
, str
)
4193 save_in
= input_line_pointer
;
4194 input_line_pointer
= *str
;
4195 seg
= expression (ep
);
4198 if (seg
!= absolute_section
4199 && seg
!= text_section
4200 && seg
!= data_section
4201 && seg
!= bss_section
4202 && seg
!= undefined_section
)
4204 inst
.error
= _("bad_segment");
4205 *str
= input_line_pointer
;
4206 input_line_pointer
= save_in
;
4211 /* Get rid of any bignums now, so that we don't generate an error for which
4212 we can't establish a line number later on. Big numbers are never valid
4213 in instructions, which is where this routine is always called. */
4214 if (ep
->X_op
== O_big
4215 || (ep
->X_add_symbol
4216 && (walk_no_bignums (ep
->X_add_symbol
)
4218 && walk_no_bignums (ep
->X_op_symbol
)))))
4220 inst
.error
= _("Invalid constant");
4221 *str
= input_line_pointer
;
4222 input_line_pointer
= save_in
;
4226 *str
= input_line_pointer
;
4227 input_line_pointer
= save_in
;
4231 /* UNRESTRICT should be one if <shift> <register> is permitted for this
4235 decode_shift (str
, unrestrict
)
4239 const struct asm_shift_name
* shift
;
4243 skip_whitespace (* str
);
4245 for (p
= * str
; ISALPHA (* p
); p
++)
4250 inst
.error
= _("Shift expression expected");
4256 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
4261 inst
.error
= _("Shift expression expected");
4265 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
4267 if (shift
->properties
->index
== SHIFT_RRX
)
4270 inst
.instruction
|= shift
->properties
->bit_field
;
4274 skip_whitespace (p
);
4276 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
4278 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
4282 else if (! is_immediate_prefix (* p
))
4284 inst
.error
= (unrestrict
4285 ? _("shift requires register or #expression")
4286 : _("shift requires #expression"));
4294 if (my_get_expression (& inst
.reloc
.exp
, & p
))
4297 /* Validate some simple #expressions. */
4298 if (inst
.reloc
.exp
.X_op
== O_constant
)
4300 unsigned num
= inst
.reloc
.exp
.X_add_number
;
4302 /* Reject operations greater than 32. */
4304 /* Reject a shift of 0 unless the mode allows it. */
4305 || (num
== 0 && shift
->properties
->allows_0
== 0)
4306 /* Reject a shift of 32 unless the mode allows it. */
4307 || (num
== 32 && shift
->properties
->allows_32
== 0)
4310 /* As a special case we allow a shift of zero for
4311 modes that do not support it to be recoded as an
4312 logical shift left of zero (ie nothing). We warn
4313 about this though. */
4316 as_warn (_("Shift of 0 ignored."));
4317 shift
= & shift_names
[0];
4318 assert (shift
->properties
->index
== SHIFT_LSL
);
4322 inst
.error
= _("Invalid immediate shift");
4327 /* Shifts of 32 are encoded as 0, for those shifts that
4332 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
4336 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
4337 inst
.reloc
.pc_rel
= 0;
4338 inst
.instruction
|= shift
->properties
->bit_field
;
4345 /* Do those data_ops which can take a negative immediate constant
4346 by altering the instuction. A bit of a hack really.
4350 by inverting the second operand, and
4353 by negating the second operand. */
4356 negate_data_op (instruction
, value
)
4357 unsigned long * instruction
;
4358 unsigned long value
;
4361 unsigned long negated
, inverted
;
4363 negated
= validate_immediate (-value
);
4364 inverted
= validate_immediate (~value
);
4366 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
4369 /* First negates. */
4370 case OPCODE_SUB
: /* ADD <-> SUB */
4371 new_inst
= OPCODE_ADD
;
4376 new_inst
= OPCODE_SUB
;
4380 case OPCODE_CMP
: /* CMP <-> CMN */
4381 new_inst
= OPCODE_CMN
;
4386 new_inst
= OPCODE_CMP
;
4390 /* Now Inverted ops. */
4391 case OPCODE_MOV
: /* MOV <-> MVN */
4392 new_inst
= OPCODE_MVN
;
4397 new_inst
= OPCODE_MOV
;
4401 case OPCODE_AND
: /* AND <-> BIC */
4402 new_inst
= OPCODE_BIC
;
4407 new_inst
= OPCODE_AND
;
4411 case OPCODE_ADC
: /* ADC <-> SBC */
4412 new_inst
= OPCODE_SBC
;
4417 new_inst
= OPCODE_ADC
;
4421 /* We cannot do anything. */
4426 if (value
== (unsigned) FAIL
)
4429 *instruction
&= OPCODE_MASK
;
4430 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
4441 skip_whitespace (* str
);
4443 if (reg_required_here (str
, 0) != FAIL
)
4445 if (skip_past_comma (str
) == SUCCESS
)
4446 /* Shift operation on register. */
4447 return decode_shift (str
, NO_SHIFT_RESTRICT
);
4453 /* Immediate expression. */
4454 if (is_immediate_prefix (**str
))
4459 if (my_get_expression (&inst
.reloc
.exp
, str
))
4462 if (inst
.reloc
.exp
.X_add_symbol
)
4464 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4465 inst
.reloc
.pc_rel
= 0;
4469 if (skip_past_comma (str
) == SUCCESS
)
4471 /* #x, y -- ie explicit rotation by Y. */
4472 if (my_get_expression (&expr
, str
))
4475 if (expr
.X_op
!= O_constant
)
4477 inst
.error
= _("Constant expression expected");
4481 /* Rotate must be a multiple of 2. */
4482 if (((unsigned) expr
.X_add_number
) > 30
4483 || (expr
.X_add_number
& 1) != 0
4484 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
4486 inst
.error
= _("Invalid constant");
4489 inst
.instruction
|= INST_IMMEDIATE
;
4490 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4491 inst
.instruction
|= expr
.X_add_number
<< 7;
4495 /* Implicit rotation, select a suitable one. */
4496 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4500 /* Can't be done. Perhaps the code reads something like
4501 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
4502 if ((value
= negate_data_op (&inst
.instruction
,
4503 inst
.reloc
.exp
.X_add_number
))
4506 inst
.error
= _("Invalid constant");
4511 inst
.instruction
|= value
;
4514 inst
.instruction
|= INST_IMMEDIATE
;
4519 inst
.error
= _("Register or shift expression expected");
4528 skip_whitespace (* str
);
4530 if (fp_reg_required_here (str
, 0) != FAIL
)
4534 /* Immediate expression. */
4535 if (*((*str
)++) == '#')
4541 skip_whitespace (* str
);
4543 /* First try and match exact strings, this is to guarantee
4544 that some formats will work even for cross assembly. */
4546 for (i
= 0; fp_const
[i
]; i
++)
4548 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
4552 *str
+= strlen (fp_const
[i
]);
4553 if (is_end_of_line
[(unsigned char) **str
])
4555 inst
.instruction
|= i
+ 8;
4562 /* Just because we didn't get a match doesn't mean that the
4563 constant isn't valid, just that it is in a format that we
4564 don't automatically recognize. Try parsing it with
4565 the standard expression routines. */
4566 if ((i
= my_get_float_expression (str
)) >= 0)
4568 inst
.instruction
|= i
+ 8;
4572 inst
.error
= _("Invalid floating point immediate expression");
4576 _("Floating point register or immediate expression expected");
4585 skip_whitespace (str
);
4587 if (reg_required_here (&str
, 12) == FAIL
4588 || skip_past_comma (&str
) == FAIL
4589 || reg_required_here (&str
, 16) == FAIL
4590 || skip_past_comma (&str
) == FAIL
4591 || data_op2 (&str
) == FAIL
)
4594 inst
.error
= BAD_ARGS
;
4606 /* This is a pseudo-op of the form "adr rd, label" to be converted
4607 into a relative address of the form "add rd, pc, #label-.-8". */
4608 skip_whitespace (str
);
4610 if (reg_required_here (&str
, 12) == FAIL
4611 || skip_past_comma (&str
) == FAIL
4612 || my_get_expression (&inst
.reloc
.exp
, &str
))
4615 inst
.error
= BAD_ARGS
;
4619 /* Frag hacking will turn this into a sub instruction if the offset turns
4620 out to be negative. */
4621 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4622 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
4623 inst
.reloc
.pc_rel
= 1;
4632 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4633 into a relative address of the form:
4634 add rd, pc, #low(label-.-8)"
4635 add rd, rd, #high(label-.-8)" */
4637 skip_whitespace (str
);
4639 if (reg_required_here (&str
, 12) == FAIL
4640 || skip_past_comma (&str
) == FAIL
4641 || my_get_expression (&inst
.reloc
.exp
, &str
))
4644 inst
.error
= BAD_ARGS
;
4650 /* Frag hacking will turn this into a sub instruction if the offset turns
4651 out to be negative. */
4652 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
4653 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
4654 inst
.reloc
.pc_rel
= 1;
4655 inst
.size
= INSN_SIZE
* 2;
4664 skip_whitespace (str
);
4666 if (reg_required_here (&str
, 16) == FAIL
)
4669 inst
.error
= BAD_ARGS
;
4673 if (skip_past_comma (&str
) == FAIL
4674 || data_op2 (&str
) == FAIL
)
4677 inst
.error
= BAD_ARGS
;
4689 skip_whitespace (str
);
4691 if (reg_required_here (&str
, 12) == FAIL
)
4694 inst
.error
= BAD_ARGS
;
4698 if (skip_past_comma (&str
) == FAIL
4699 || data_op2 (&str
) == FAIL
)
4702 inst
.error
= BAD_ARGS
;
4721 if (my_get_expression (& inst
.reloc
.exp
, str
))
4724 if (inst
.reloc
.exp
.X_op
== O_constant
)
4726 int value
= inst
.reloc
.exp
.X_add_number
;
4728 if (value
< -4095 || value
> 4095)
4730 inst
.error
= _("address offset too large");
4740 inst
.instruction
|= add
| value
;
4744 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4745 inst
.reloc
.pc_rel
= 0;
4758 if (reg_required_here (str
, 0) == FAIL
)
4761 inst
.instruction
|= add
| OFFSET_REG
;
4762 if (skip_past_comma (str
) == SUCCESS
)
4763 return decode_shift (str
, SHIFT_RESTRICT
);
4777 skip_whitespace (str
);
4779 if ((conflict_reg
= reg_required_here (&str
, 12)) == FAIL
)
4782 inst
.error
= BAD_ARGS
;
4786 if (skip_past_comma (&str
) == FAIL
)
4788 inst
.error
= _("Address expected");
4798 skip_whitespace (str
);
4800 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4803 /* Conflicts can occur on stores as well as loads. */
4804 conflict_reg
= (conflict_reg
== reg
);
4806 skip_whitespace (str
);
4812 if (skip_past_comma (&str
) == SUCCESS
)
4814 /* [Rn],... (post inc) */
4815 if (ldst_extend (&str
) == FAIL
)
4818 as_warn (_("%s register same as write-back base"),
4819 ((inst
.instruction
& LOAD_BIT
)
4820 ? _("destination") : _("source")));
4825 skip_whitespace (str
);
4830 as_warn (_("%s register same as write-back base"),
4831 ((inst
.instruction
& LOAD_BIT
)
4832 ? _("destination") : _("source")));
4834 inst
.instruction
|= WRITE_BACK
;
4837 inst
.instruction
|= INDEX_UP
;
4844 if (skip_past_comma (&str
) == FAIL
)
4846 inst
.error
= _("pre-indexed expression expected");
4851 if (ldst_extend (&str
) == FAIL
)
4854 skip_whitespace (str
);
4858 inst
.error
= _("missing ]");
4862 skip_whitespace (str
);
4867 as_warn (_("%s register same as write-back base"),
4868 ((inst
.instruction
& LOAD_BIT
)
4869 ? _("destination") : _("source")));
4871 inst
.instruction
|= WRITE_BACK
;
4875 else if (*str
== '=')
4877 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4880 skip_whitespace (str
);
4882 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4885 if (inst
.reloc
.exp
.X_op
!= O_constant
4886 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4888 inst
.error
= _("Constant expression expected");
4892 if (inst
.reloc
.exp
.X_op
== O_constant
)
4894 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4898 /* This can be done with a mov instruction. */
4899 inst
.instruction
&= LITERAL_MASK
;
4900 inst
.instruction
|= (INST_IMMEDIATE
4901 | (OPCODE_MOV
<< DATA_OP_SHIFT
));
4902 inst
.instruction
|= value
& 0xfff;
4907 value
= validate_immediate (~inst
.reloc
.exp
.X_add_number
);
4911 /* This can be done with a mvn instruction. */
4912 inst
.instruction
&= LITERAL_MASK
;
4913 inst
.instruction
|= (INST_IMMEDIATE
4914 | (OPCODE_MVN
<< DATA_OP_SHIFT
));
4915 inst
.instruction
|= value
& 0xfff;
4921 /* Insert into literal pool. */
4922 if (add_to_lit_pool () == FAIL
)
4925 inst
.error
= _("literal pool insertion failed");
4929 /* Change the instruction exp to point to the pool. */
4930 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
4931 inst
.reloc
.pc_rel
= 1;
4932 inst
.instruction
|= (REG_PC
<< 16);
4937 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4940 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4942 /* PC rel adjust. */
4943 inst
.reloc
.exp
.X_add_number
-= 8;
4945 inst
.reloc
.pc_rel
= 1;
4946 inst
.instruction
|= (REG_PC
<< 16);
4950 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
4961 skip_whitespace (str
);
4963 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
4966 inst
.error
= BAD_ARGS
;
4970 if (skip_past_comma (& str
) == FAIL
)
4972 inst
.error
= _("Address expected");
4982 skip_whitespace (str
);
4984 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4987 /* ldrt/strt always use post-indexed addressing, so if the base is
4988 the same as Rd, we warn. */
4989 if (conflict_reg
== reg
)
4990 as_warn (_("%s register same as write-back base"),
4991 ((inst
.instruction
& LOAD_BIT
)
4992 ? _("destination") : _("source")));
4994 skip_whitespace (str
);
5000 if (skip_past_comma (&str
) == SUCCESS
)
5002 /* [Rn],... (post inc) */
5003 if (ldst_extend (&str
) == FAIL
)
5009 skip_whitespace (str
);
5011 /* Skip a write-back '!'. */
5015 inst
.instruction
|= INDEX_UP
;
5020 inst
.error
= _("post-indexed expression expected");
5026 inst
.error
= _("post-indexed expression expected");
5035 ldst_extend_v4 (str
)
5045 if (my_get_expression (& inst
.reloc
.exp
, str
))
5048 if (inst
.reloc
.exp
.X_op
== O_constant
)
5050 int value
= inst
.reloc
.exp
.X_add_number
;
5052 if (value
< -255 || value
> 255)
5054 inst
.error
= _("address offset too large");
5064 /* Halfword and signextension instructions have the
5065 immediate value split across bits 11..8 and bits 3..0. */
5066 inst
.instruction
|= (add
| HWOFFSET_IMM
5067 | ((value
>> 4) << 8) | (value
& 0xF));
5071 inst
.instruction
|= HWOFFSET_IMM
;
5072 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
5073 inst
.reloc
.pc_rel
= 0;
5086 if (reg_required_here (str
, 0) == FAIL
)
5089 inst
.instruction
|= add
;
5094 /* Halfword and signed-byte load/store operations. */
5103 skip_whitespace (str
);
5105 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
5108 inst
.error
= BAD_ARGS
;
5112 if (skip_past_comma (& str
) == FAIL
)
5114 inst
.error
= _("Address expected");
5124 skip_whitespace (str
);
5126 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5129 /* Conflicts can occur on stores as well as loads. */
5130 conflict_reg
= (conflict_reg
== reg
);
5132 skip_whitespace (str
);
5138 if (skip_past_comma (&str
) == SUCCESS
)
5140 /* [Rn],... (post inc) */
5141 if (ldst_extend_v4 (&str
) == FAIL
)
5144 as_warn (_("%s register same as write-back base"),
5145 ((inst
.instruction
& LOAD_BIT
)
5146 ? _("destination") : _("source")));
5151 inst
.instruction
|= HWOFFSET_IMM
;
5153 skip_whitespace (str
);
5158 as_warn (_("%s register same as write-back base"),
5159 ((inst
.instruction
& LOAD_BIT
)
5160 ? _("destination") : _("source")));
5162 inst
.instruction
|= WRITE_BACK
;
5165 inst
.instruction
|= INDEX_UP
;
5172 if (skip_past_comma (&str
) == FAIL
)
5174 inst
.error
= _("pre-indexed expression expected");
5179 if (ldst_extend_v4 (&str
) == FAIL
)
5182 skip_whitespace (str
);
5186 inst
.error
= _("missing ]");
5190 skip_whitespace (str
);
5195 as_warn (_("%s register same as write-back base"),
5196 ((inst
.instruction
& LOAD_BIT
)
5197 ? _("destination") : _("source")));
5199 inst
.instruction
|= WRITE_BACK
;
5203 else if (*str
== '=')
5205 /* XXX Does this work correctly for half-word/byte ops? */
5206 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5209 skip_whitespace (str
);
5211 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5214 if (inst
.reloc
.exp
.X_op
!= O_constant
5215 && inst
.reloc
.exp
.X_op
!= O_symbol
)
5217 inst
.error
= _("Constant expression expected");
5221 if (inst
.reloc
.exp
.X_op
== O_constant
)
5223 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
5227 /* This can be done with a mov instruction. */
5228 inst
.instruction
&= LITERAL_MASK
;
5229 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
5230 inst
.instruction
|= value
& 0xfff;
5235 value
= validate_immediate (~ inst
.reloc
.exp
.X_add_number
);
5239 /* This can be done with a mvn instruction. */
5240 inst
.instruction
&= LITERAL_MASK
;
5241 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MVN
<< DATA_OP_SHIFT
);
5242 inst
.instruction
|= value
& 0xfff;
5248 /* Insert into literal pool. */
5249 if (add_to_lit_pool () == FAIL
)
5252 inst
.error
= _("literal pool insertion failed");
5256 /* Change the instruction exp to point to the pool. */
5257 inst
.instruction
|= HWOFFSET_IMM
;
5258 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
5259 inst
.reloc
.pc_rel
= 1;
5260 inst
.instruction
|= (REG_PC
<< 16);
5265 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5268 inst
.instruction
|= HWOFFSET_IMM
;
5269 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
5271 /* PC rel adjust. */
5272 inst
.reloc
.exp
.X_add_number
-= 8;
5274 inst
.reloc
.pc_rel
= 1;
5275 inst
.instruction
|= (REG_PC
<< 16);
5279 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
5288 char * str
= * strp
;
5292 /* We come back here if we get ranges concatenated by '+' or '|'. */
5307 skip_whitespace (str
);
5309 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
5318 inst
.error
= _("Bad range in register list");
5322 for (i
= cur_reg
+ 1; i
< reg
; i
++)
5324 if (range
& (1 << i
))
5326 (_("Warning: Duplicated register (r%d) in register list"),
5334 if (range
& (1 << reg
))
5335 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
5337 else if (reg
<= cur_reg
)
5338 as_tsktsk (_("Warning: Register range not in ascending order"));
5343 while (skip_past_comma (&str
) != FAIL
5344 || (in_range
= 1, *str
++ == '-'));
5346 skip_whitespace (str
);
5350 inst
.error
= _("Missing `}'");
5358 if (my_get_expression (&expr
, &str
))
5361 if (expr
.X_op
== O_constant
)
5363 if (expr
.X_add_number
5364 != (expr
.X_add_number
& 0x0000ffff))
5366 inst
.error
= _("invalid register mask");
5370 if ((range
& expr
.X_add_number
) != 0)
5372 int regno
= range
& expr
.X_add_number
;
5375 regno
= (1 << regno
) - 1;
5377 (_("Warning: Duplicated register (r%d) in register list"),
5381 range
|= expr
.X_add_number
;
5385 if (inst
.reloc
.type
!= 0)
5387 inst
.error
= _("expression too complex");
5391 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
5392 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
5393 inst
.reloc
.pc_rel
= 0;
5397 skip_whitespace (str
);
5399 if (*str
== '|' || *str
== '+')
5405 while (another_range
);
5418 skip_whitespace (str
);
5420 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
5423 if (base_reg
== REG_PC
)
5425 inst
.error
= _("r15 not allowed as base register");
5429 skip_whitespace (str
);
5433 inst
.instruction
|= WRITE_BACK
;
5437 if (skip_past_comma (&str
) == FAIL
5438 || (range
= reg_list (&str
)) == FAIL
)
5441 inst
.error
= BAD_ARGS
;
5448 inst
.instruction
|= LDM_TYPE_2_OR_3
;
5451 inst
.instruction
|= range
;
5460 skip_whitespace (str
);
5462 /* Allow optional leading '#'. */
5463 if (is_immediate_prefix (*str
))
5466 if (my_get_expression (& inst
.reloc
.exp
, & str
))
5469 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
5470 inst
.reloc
.pc_rel
= 0;
5482 skip_whitespace (str
);
5484 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
5489 inst
.error
= _("r15 not allowed in swap");
5493 if (skip_past_comma (&str
) == FAIL
5494 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
5497 inst
.error
= BAD_ARGS
;
5503 inst
.error
= _("r15 not allowed in swap");
5507 if (skip_past_comma (&str
) == FAIL
5510 inst
.error
= BAD_ARGS
;
5514 skip_whitespace (str
);
5516 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5521 inst
.error
= BAD_PC
;
5525 skip_whitespace (str
);
5529 inst
.error
= _("missing ]");
5541 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5548 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
5549 required for the instruction. */
5551 /* arm_parse_reloc () works on input_line_pointer.
5552 We actually want to parse the operands to the branch instruction
5553 passed in 'str'. Save the input pointer and restore it later. */
5554 save_in
= input_line_pointer
;
5555 input_line_pointer
= str
;
5556 if (inst
.reloc
.exp
.X_op
== O_symbol
5558 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
5560 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
5561 inst
.reloc
.pc_rel
= 0;
5562 /* Modify str to point to after parsed operands, otherwise
5563 end_of_line() will complain about the (PLT) left in str. */
5564 str
= input_line_pointer
;
5568 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
5569 inst
.reloc
.pc_rel
= 1;
5571 input_line_pointer
= save_in
;
5574 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
5575 inst
.reloc
.pc_rel
= 1;
5576 #endif /* OBJ_ELF */
5588 skip_whitespace (str
);
5590 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
5592 inst
.error
= BAD_ARGS
;
5596 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
5598 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
5607 /* Co-processor data operation.
5608 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
5609 skip_whitespace (str
);
5611 if (co_proc_number (&str
) == FAIL
)
5614 inst
.error
= BAD_ARGS
;
5618 if (skip_past_comma (&str
) == FAIL
5619 || cp_opc_expr (&str
, 20,4) == FAIL
)
5622 inst
.error
= BAD_ARGS
;
5626 if (skip_past_comma (&str
) == FAIL
5627 || cp_reg_required_here (&str
, 12) == FAIL
)
5630 inst
.error
= BAD_ARGS
;
5634 if (skip_past_comma (&str
) == FAIL
5635 || cp_reg_required_here (&str
, 16) == FAIL
)
5638 inst
.error
= BAD_ARGS
;
5642 if (skip_past_comma (&str
) == FAIL
5643 || cp_reg_required_here (&str
, 0) == FAIL
)
5646 inst
.error
= BAD_ARGS
;
5650 if (skip_past_comma (&str
) == SUCCESS
)
5652 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5655 inst
.error
= BAD_ARGS
;
5668 /* Co-processor register load/store.
5669 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
5671 skip_whitespace (str
);
5673 if (co_proc_number (&str
) == FAIL
)
5676 inst
.error
= BAD_ARGS
;
5680 if (skip_past_comma (&str
) == FAIL
5681 || cp_reg_required_here (&str
, 12) == FAIL
)
5684 inst
.error
= BAD_ARGS
;
5688 if (skip_past_comma (&str
) == FAIL
5689 || cp_address_required_here (&str
) == FAIL
)
5692 inst
.error
= BAD_ARGS
;
5704 /* Co-processor register transfer.
5705 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
5707 skip_whitespace (str
);
5709 if (co_proc_number (&str
) == FAIL
)
5712 inst
.error
= BAD_ARGS
;
5716 if (skip_past_comma (&str
) == FAIL
5717 || cp_opc_expr (&str
, 21, 3) == FAIL
)
5720 inst
.error
= BAD_ARGS
;
5724 if (skip_past_comma (&str
) == FAIL
5725 || reg_required_here (&str
, 12) == FAIL
)
5728 inst
.error
= BAD_ARGS
;
5732 if (skip_past_comma (&str
) == FAIL
5733 || cp_reg_required_here (&str
, 16) == FAIL
)
5736 inst
.error
= BAD_ARGS
;
5740 if (skip_past_comma (&str
) == FAIL
5741 || cp_reg_required_here (&str
, 0) == FAIL
)
5744 inst
.error
= BAD_ARGS
;
5748 if (skip_past_comma (&str
) == SUCCESS
)
5750 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5753 inst
.error
= BAD_ARGS
;
5766 /* FP control registers.
5767 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
5769 skip_whitespace (str
);
5771 if (reg_required_here (&str
, 12) == FAIL
)
5774 inst
.error
= BAD_ARGS
;
5786 skip_whitespace (str
);
5788 if (fp_reg_required_here (&str
, 12) == FAIL
)
5791 inst
.error
= BAD_ARGS
;
5795 if (skip_past_comma (&str
) == FAIL
5796 || cp_address_required_here (&str
) == FAIL
)
5799 inst
.error
= BAD_ARGS
;
5812 skip_whitespace (str
);
5814 if (fp_reg_required_here (&str
, 12) == FAIL
)
5817 inst
.error
= BAD_ARGS
;
5821 /* Get Number of registers to transfer. */
5822 if (skip_past_comma (&str
) == FAIL
5823 || my_get_expression (&inst
.reloc
.exp
, &str
))
5826 inst
.error
= _("constant expression expected");
5830 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5832 inst
.error
= _("Constant value required for number of registers");
5836 num_regs
= inst
.reloc
.exp
.X_add_number
;
5838 if (num_regs
< 1 || num_regs
> 4)
5840 inst
.error
= _("number of registers must be in the range [1:4]");
5847 inst
.instruction
|= CP_T_X
;
5850 inst
.instruction
|= CP_T_Y
;
5853 inst
.instruction
|= CP_T_Y
| CP_T_X
;
5861 if (inst
.instruction
& (CP_T_Pre
| CP_T_UD
)) /* ea/fd format. */
5867 /* The instruction specified "ea" or "fd", so we can only accept
5868 [Rn]{!}. The instruction does not really support stacking or
5869 unstacking, so we have to emulate these by setting appropriate
5870 bits and offsets. */
5871 if (skip_past_comma (&str
) == FAIL
5875 inst
.error
= BAD_ARGS
;
5880 skip_whitespace (str
);
5882 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5885 skip_whitespace (str
);
5889 inst
.error
= BAD_ARGS
;
5901 _("R15 not allowed as base register with write-back");
5908 if (inst
.instruction
& CP_T_Pre
)
5910 /* Pre-decrement. */
5911 offset
= 3 * num_regs
;
5913 inst
.instruction
|= CP_T_WB
;
5917 /* Post-increment. */
5920 inst
.instruction
|= CP_T_WB
;
5921 offset
= 3 * num_regs
;
5925 /* No write-back, so convert this into a standard pre-increment
5926 instruction -- aesthetically more pleasing. */
5927 inst
.instruction
|= CP_T_Pre
| CP_T_UD
;
5932 inst
.instruction
|= offset
;
5934 else if (skip_past_comma (&str
) == FAIL
5935 || cp_address_required_here (&str
) == FAIL
)
5938 inst
.error
= BAD_ARGS
;
5949 skip_whitespace (str
);
5951 if (fp_reg_required_here (&str
, 12) == FAIL
)
5954 inst
.error
= BAD_ARGS
;
5958 if (skip_past_comma (&str
) == FAIL
5959 || fp_reg_required_here (&str
, 16) == FAIL
)
5962 inst
.error
= BAD_ARGS
;
5966 if (skip_past_comma (&str
) == FAIL
5967 || fp_op2 (&str
) == FAIL
)
5970 inst
.error
= BAD_ARGS
;
5979 do_fpa_monadic (str
)
5982 skip_whitespace (str
);
5984 if (fp_reg_required_here (&str
, 12) == FAIL
)
5987 inst
.error
= BAD_ARGS
;
5991 if (skip_past_comma (&str
) == FAIL
5992 || fp_op2 (&str
) == FAIL
)
5995 inst
.error
= BAD_ARGS
;
6007 skip_whitespace (str
);
6009 if (fp_reg_required_here (&str
, 16) == FAIL
)
6012 inst
.error
= BAD_ARGS
;
6016 if (skip_past_comma (&str
) == FAIL
6017 || fp_op2 (&str
) == FAIL
)
6020 inst
.error
= BAD_ARGS
;
6029 do_fpa_from_reg (str
)
6032 skip_whitespace (str
);
6034 if (fp_reg_required_here (&str
, 16) == FAIL
)
6037 inst
.error
= BAD_ARGS
;
6041 if (skip_past_comma (&str
) == FAIL
6042 || reg_required_here (&str
, 12) == FAIL
)
6045 inst
.error
= BAD_ARGS
;
6057 skip_whitespace (str
);
6059 if (reg_required_here (&str
, 12) == FAIL
)
6062 if (skip_past_comma (&str
) == FAIL
6063 || fp_reg_required_here (&str
, 0) == FAIL
)
6066 inst
.error
= BAD_ARGS
;
6074 /* Thumb specific routines. */
6076 /* Parse and validate that a register is of the right form, this saves
6077 repeated checking of this information in many similar cases.
6078 Unlike the 32-bit case we do not insert the register into the opcode
6079 here, since the position is often unknown until the full instruction
6083 thumb_reg (strp
, hi_lo
)
6089 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
6097 inst
.error
= _("lo register required");
6105 inst
.error
= _("hi register required");
6117 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
6121 thumb_add_sub (str
, subtract
)
6125 int Rd
, Rs
, Rn
= FAIL
;
6127 skip_whitespace (str
);
6129 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
6130 || skip_past_comma (&str
) == FAIL
)
6133 inst
.error
= BAD_ARGS
;
6137 if (is_immediate_prefix (*str
))
6141 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6146 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6149 if (skip_past_comma (&str
) == FAIL
)
6151 /* Two operand format, shuffle the registers
6152 and pretend there are 3. */
6156 else if (is_immediate_prefix (*str
))
6159 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6162 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6166 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
6167 for the latter case, EXPR contains the immediate that was found. */
6170 /* All register format. */
6171 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
6175 inst
.error
= _("dest and source1 must be the same register");
6179 /* Can't do this for SUB. */
6182 inst
.error
= _("subtract valid only on lo regs");
6186 inst
.instruction
= (T_OPCODE_ADD_HI
6187 | (Rd
> 7 ? THUMB_H1
: 0)
6188 | (Rn
> 7 ? THUMB_H2
: 0));
6189 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
6193 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
6194 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
6199 /* Immediate expression, now things start to get nasty. */
6201 /* First deal with HI regs, only very restricted cases allowed:
6202 Adjusting SP, and using PC or SP to get an address. */
6203 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
6204 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
6206 inst
.error
= _("invalid Hi register with immediate");
6210 if (inst
.reloc
.exp
.X_op
!= O_constant
)
6212 /* Value isn't known yet, all we can do is store all the fragments
6213 we know about in the instruction and let the reloc hacking
6215 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
6216 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
6220 int offset
= inst
.reloc
.exp
.X_add_number
;
6230 /* Quick check, in case offset is MIN_INT. */
6233 inst
.error
= _("immediate value out of range");
6242 if (offset
& ~0x1fc)
6244 inst
.error
= _("invalid immediate value for stack adjust");
6247 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
6248 inst
.instruction
|= offset
>> 2;
6250 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
6253 || (offset
& ~0x3fc))
6255 inst
.error
= _("invalid immediate for address calculation");
6258 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
6260 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
6266 inst
.error
= _("immediate value out of range");
6269 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
6270 inst
.instruction
|= (Rd
<< 8) | offset
;
6276 inst
.error
= _("immediate value out of range");
6279 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
6280 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
6289 thumb_shift (str
, shift
)
6293 int Rd
, Rs
, Rn
= FAIL
;
6295 skip_whitespace (str
);
6297 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6298 || skip_past_comma (&str
) == FAIL
)
6301 inst
.error
= BAD_ARGS
;
6305 if (is_immediate_prefix (*str
))
6307 /* Two operand immediate format, set Rs to Rd. */
6310 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6315 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6318 if (skip_past_comma (&str
) == FAIL
)
6320 /* Two operand format, shuffle the registers
6321 and pretend there are 3. */
6325 else if (is_immediate_prefix (*str
))
6328 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6331 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6335 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
6336 for the latter case, EXPR contains the immediate that was found. */
6342 inst
.error
= _("source1 and dest must be same register");
6348 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
6349 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
6350 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
6353 inst
.instruction
|= Rd
| (Rn
<< 3);
6359 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
6360 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
6361 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
6364 if (inst
.reloc
.exp
.X_op
!= O_constant
)
6366 /* Value isn't known yet, create a dummy reloc and let reloc
6367 hacking fix it up. */
6368 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
6372 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
6374 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
6376 inst
.error
= _("Invalid immediate for shift");
6380 /* Shifts of zero are handled by converting to LSL. */
6381 if (shift_value
== 0)
6382 inst
.instruction
= T_OPCODE_LSL_I
;
6384 /* Shifts of 32 are encoded as a shift of zero. */
6385 if (shift_value
== 32)
6388 inst
.instruction
|= shift_value
<< 6;
6391 inst
.instruction
|= Rd
| (Rs
<< 3);
6398 thumb_mov_compare (str
, move
)
6404 skip_whitespace (str
);
6406 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
6407 || skip_past_comma (&str
) == FAIL
)
6410 inst
.error
= BAD_ARGS
;
6414 if (is_immediate_prefix (*str
))
6417 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6420 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6425 if (Rs
< 8 && Rd
< 8)
6427 if (move
== THUMB_MOVE
)
6428 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
6429 since a MOV instruction produces unpredictable results. */
6430 inst
.instruction
= T_OPCODE_ADD_I3
;
6432 inst
.instruction
= T_OPCODE_CMP_LR
;
6433 inst
.instruction
|= Rd
| (Rs
<< 3);
6437 if (move
== THUMB_MOVE
)
6438 inst
.instruction
= T_OPCODE_MOV_HR
;
6440 inst
.instruction
= T_OPCODE_CMP_HR
;
6443 inst
.instruction
|= THUMB_H1
;
6446 inst
.instruction
|= THUMB_H2
;
6448 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
6455 inst
.error
= _("only lo regs allowed with immediate");
6459 if (move
== THUMB_MOVE
)
6460 inst
.instruction
= T_OPCODE_MOV_I8
;
6462 inst
.instruction
= T_OPCODE_CMP_I8
;
6464 inst
.instruction
|= Rd
<< 8;
6466 if (inst
.reloc
.exp
.X_op
!= O_constant
)
6467 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
6470 unsigned value
= inst
.reloc
.exp
.X_add_number
;
6474 inst
.error
= _("invalid immediate");
6478 inst
.instruction
|= value
;
6486 thumb_load_store (str
, load_store
, size
)
6491 int Rd
, Rb
, Ro
= FAIL
;
6493 skip_whitespace (str
);
6495 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6496 || skip_past_comma (&str
) == FAIL
)
6499 inst
.error
= BAD_ARGS
;
6506 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6509 if (skip_past_comma (&str
) != FAIL
)
6511 if (is_immediate_prefix (*str
))
6514 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6517 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6522 inst
.reloc
.exp
.X_op
= O_constant
;
6523 inst
.reloc
.exp
.X_add_number
= 0;
6528 inst
.error
= _("expected ']'");
6533 else if (*str
== '=')
6535 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6538 skip_whitespace (str
);
6540 if (my_get_expression (& inst
.reloc
.exp
, & str
))
6545 if ( inst
.reloc
.exp
.X_op
!= O_constant
6546 && inst
.reloc
.exp
.X_op
!= O_symbol
)
6548 inst
.error
= "Constant expression expected";
6552 if (inst
.reloc
.exp
.X_op
== O_constant
6553 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
6555 /* This can be done with a mov instruction. */
6557 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
6558 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
6562 /* Insert into literal pool. */
6563 if (add_to_lit_pool () == FAIL
)
6566 inst
.error
= "literal pool insertion failed";
6570 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6571 inst
.reloc
.pc_rel
= 1;
6572 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
6573 /* Adjust ARM pipeline offset to Thumb. */
6574 inst
.reloc
.exp
.X_add_number
+= 4;
6580 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6583 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
6584 inst
.reloc
.pc_rel
= 1;
6585 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
6586 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6591 if (Rb
== REG_PC
|| Rb
== REG_SP
)
6593 if (size
!= THUMB_WORD
)
6595 inst
.error
= _("byte or halfword not valid for base register");
6598 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
6600 inst
.error
= _("R15 based store not allowed");
6603 else if (Ro
!= FAIL
)
6605 inst
.error
= _("Invalid base register for register offset");
6610 inst
.instruction
= T_OPCODE_LDR_PC
;
6611 else if (load_store
== THUMB_LOAD
)
6612 inst
.instruction
= T_OPCODE_LDR_SP
;
6614 inst
.instruction
= T_OPCODE_STR_SP
;
6616 inst
.instruction
|= Rd
<< 8;
6617 if (inst
.reloc
.exp
.X_op
== O_constant
)
6619 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
6621 if (offset
& ~0x3fc)
6623 inst
.error
= _("invalid offset");
6627 inst
.instruction
|= offset
>> 2;
6630 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6634 inst
.error
= _("invalid base register in load/store");
6637 else if (Ro
== FAIL
)
6639 /* Immediate offset. */
6640 if (size
== THUMB_WORD
)
6641 inst
.instruction
= (load_store
== THUMB_LOAD
6642 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
6643 else if (size
== THUMB_HALFWORD
)
6644 inst
.instruction
= (load_store
== THUMB_LOAD
6645 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
6647 inst
.instruction
= (load_store
== THUMB_LOAD
6648 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
6650 inst
.instruction
|= Rd
| (Rb
<< 3);
6652 if (inst
.reloc
.exp
.X_op
== O_constant
)
6654 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
6656 if (offset
& ~(0x1f << size
))
6658 inst
.error
= _("Invalid offset");
6661 inst
.instruction
|= (offset
>> size
) << 6;
6664 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6668 /* Register offset. */
6669 if (size
== THUMB_WORD
)
6670 inst
.instruction
= (load_store
== THUMB_LOAD
6671 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
6672 else if (size
== THUMB_HALFWORD
)
6673 inst
.instruction
= (load_store
== THUMB_LOAD
6674 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
6676 inst
.instruction
= (load_store
== THUMB_LOAD
6677 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
6679 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
6685 /* A register must be given at this point.
6687 Shift is the place to put it in inst.instruction.
6689 Restores input start point on err.
6690 Returns the reg#, or FAIL. */
6693 cirrus_reg_required_here (str
, shift
, regtype
)
6696 enum arm_reg_type regtype
;
6701 if ((reg
= arm_reg_parse (str
, all_reg_maps
[regtype
].htab
)) != FAIL
)
6704 inst
.instruction
|= reg
<< shift
;
6709 /* Restore the start point. */
6712 /* In the few cases where we might be able to accept something else
6713 this error can be overridden. */
6714 inst
.error
= _(all_reg_maps
[regtype
].expected
);
6719 /* Cirrus Instructions. */
6721 /* Wrapper functions. */
6724 do_c_binops_1a (str
)
6727 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_RN
, REG_TYPE_MVF
);
6731 do_c_binops_1b (str
)
6734 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_RN
, REG_TYPE_MVD
);
6738 do_c_binops_1c (str
)
6741 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_RN
, REG_TYPE_MVDX
);
6745 do_c_binops_1d (str
)
6748 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVF
);
6752 do_c_binops_1e (str
)
6755 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVD
);
6759 do_c_binops_1f (str
)
6762 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVF
);
6766 do_c_binops_1g (str
)
6769 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVD
);
6773 do_c_binops_1h (str
)
6776 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVFX
);
6780 do_c_binops_1i (str
)
6783 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVFX
);
6787 do_c_binops_1j (str
)
6790 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVDX
);
6794 do_c_binops_1k (str
)
6797 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVDX
);
6801 do_c_binops_1l (str
)
6804 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVF
);
6808 do_c_binops_1m (str
)
6811 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVD
);
6815 do_c_binops_1n (str
)
6818 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
6822 do_c_binops_1o (str
)
6825 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
6829 do_c_binops_2a (str
)
6832 do_c_binops (str
, CIRRUS_MODE2
, REG_TYPE_MVF
, REG_TYPE_RN
);
6836 do_c_binops_2b (str
)
6839 do_c_binops (str
, CIRRUS_MODE2
, REG_TYPE_MVD
, REG_TYPE_RN
);
6843 do_c_binops_2c (str
)
6846 do_c_binops (str
, CIRRUS_MODE2
, REG_TYPE_MVDX
, REG_TYPE_RN
);
6850 do_c_binops_3a (str
)
6853 do_c_binops (str
, CIRRUS_MODE3
, REG_TYPE_MVAX
, REG_TYPE_MVFX
);
6857 do_c_binops_3b (str
)
6860 do_c_binops (str
, CIRRUS_MODE3
, REG_TYPE_MVFX
, REG_TYPE_MVAX
);
6864 do_c_binops_3c (str
)
6867 do_c_binops (str
, CIRRUS_MODE3
, REG_TYPE_MVAX
, REG_TYPE_MVDX
);
6871 do_c_binops_3d (str
)
6874 do_c_binops (str
, CIRRUS_MODE3
, REG_TYPE_MVDX
, REG_TYPE_MVAX
);
6878 do_c_triple_4a (str
)
6881 do_c_triple (str
, CIRRUS_MODE4
, REG_TYPE_MVFX
, REG_TYPE_MVFX
, REG_TYPE_RN
);
6885 do_c_triple_4b (str
)
6888 do_c_triple (str
, CIRRUS_MODE4
, REG_TYPE_MVDX
, REG_TYPE_MVDX
, REG_TYPE_RN
);
6892 do_c_triple_5a (str
)
6895 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_RN
, REG_TYPE_MVF
, REG_TYPE_MVF
);
6899 do_c_triple_5b (str
)
6902 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_RN
, REG_TYPE_MVD
, REG_TYPE_MVD
);
6906 do_c_triple_5c (str
)
6909 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_RN
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
6913 do_c_triple_5d (str
)
6916 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_RN
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
6920 do_c_triple_5e (str
)
6923 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_MVF
, REG_TYPE_MVF
, REG_TYPE_MVF
);
6927 do_c_triple_5f (str
)
6930 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_MVD
, REG_TYPE_MVD
, REG_TYPE_MVD
);
6934 do_c_triple_5g (str
)
6937 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_MVFX
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
6941 do_c_triple_5h (str
)
6944 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_MVDX
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
6951 do_c_quad (str
, CIRRUS_MODE6
, REG_TYPE_MVAX
, REG_TYPE_MVFX
, REG_TYPE_MVFX
,
6959 do_c_quad (str
, CIRRUS_MODE6
, REG_TYPE_MVAX
, REG_TYPE_MVAX
, REG_TYPE_MVFX
,
6963 /* cfmvsc32<cond> DSPSC,MVFX[15:0]. */
6968 skip_whitespace (str
);
6971 if (cirrus_reg_required_here (&str
, -1, REG_TYPE_DSPSC
) == FAIL
6972 || skip_past_comma (&str
) == FAIL
6973 || cirrus_reg_required_here (&str
, 16, REG_TYPE_MVFX
) == FAIL
)
6976 inst
.error
= BAD_ARGS
;
6984 /* cfmv32sc<cond> MVFX[15:0],DSPSC. */
6989 skip_whitespace (str
);
6992 if (cirrus_reg_required_here (&str
, 0, REG_TYPE_MVFX
) == FAIL
6993 || skip_past_comma (&str
) == FAIL
6994 || cirrus_reg_required_here (&str
, -1, REG_TYPE_DSPSC
) == FAIL
)
6997 inst
.error
= BAD_ARGS
;
7009 do_c_shift (str
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
7016 do_c_shift (str
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
7023 do_c_ldst (str
, REG_TYPE_MVF
);
7030 do_c_ldst (str
, REG_TYPE_MVD
);
7037 do_c_ldst (str
, REG_TYPE_MVFX
);
7044 do_c_ldst (str
, REG_TYPE_MVDX
);
7047 /* Isnsn like "foo X,Y". */
7050 do_c_binops (str
, mode
, reg0
, reg1
)
7053 enum arm_reg_type reg0
;
7054 enum arm_reg_type reg1
;
7058 shift0
= mode
& 0xff;
7059 shift1
= (mode
>> 8) & 0xff;
7061 skip_whitespace (str
);
7063 if (cirrus_reg_required_here (&str
, shift0
, reg0
) == FAIL
7064 || skip_past_comma (&str
) == FAIL
7065 || cirrus_reg_required_here (&str
, shift1
, reg1
) == FAIL
)
7068 inst
.error
= BAD_ARGS
;
7074 /* Isnsn like "foo X,Y,Z". */
7077 do_c_triple (str
, mode
, reg0
, reg1
, reg2
)
7080 enum arm_reg_type reg0
;
7081 enum arm_reg_type reg1
;
7082 enum arm_reg_type reg2
;
7084 int shift0
, shift1
, shift2
;
7086 shift0
= mode
& 0xff;
7087 shift1
= (mode
>> 8) & 0xff;
7088 shift2
= (mode
>> 16) & 0xff;
7090 skip_whitespace (str
);
7092 if (cirrus_reg_required_here (&str
, shift0
, reg0
) == FAIL
7093 || skip_past_comma (&str
) == FAIL
7094 || cirrus_reg_required_here (&str
, shift1
, reg1
) == FAIL
7095 || skip_past_comma (&str
) == FAIL
7096 || cirrus_reg_required_here (&str
, shift2
, reg2
) == FAIL
)
7099 inst
.error
= BAD_ARGS
;
7105 /* Isnsn like "foo W,X,Y,Z".
7106 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
7109 do_c_quad (str
, mode
, reg0
, reg1
, reg2
, reg3
)
7112 enum arm_reg_type reg0
;
7113 enum arm_reg_type reg1
;
7114 enum arm_reg_type reg2
;
7115 enum arm_reg_type reg3
;
7117 int shift0
, shift1
, shift2
, shift3
;
7119 shift0
= mode
& 0xff;
7120 shift1
= (mode
>> 8) & 0xff;
7121 shift2
= (mode
>> 16) & 0xff;
7122 shift3
= (mode
>> 24) & 0xff;
7124 skip_whitespace (str
);
7126 if (cirrus_reg_required_here (&str
, shift0
, reg0
) == FAIL
7127 || skip_past_comma (&str
) == FAIL
7128 || cirrus_reg_required_here (&str
, shift1
, reg1
) == FAIL
7129 || skip_past_comma (&str
) == FAIL
7130 || cirrus_reg_required_here (&str
, shift2
, reg2
) == FAIL
7131 || skip_past_comma (&str
) == FAIL
7132 || cirrus_reg_required_here (&str
, shift3
, reg3
) == FAIL
)
7135 inst
.error
= BAD_ARGS
;
7141 /* Cirrus shift immediate instructions.
7142 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
7143 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
7146 do_c_shift (str
, reg0
, reg1
)
7148 enum arm_reg_type reg0
;
7149 enum arm_reg_type reg1
;
7154 skip_whitespace (str
);
7158 if (cirrus_reg_required_here (&str
, 12, reg0
) == FAIL
7159 || skip_past_comma (&str
) == FAIL
7160 || cirrus_reg_required_here (&str
, 16, reg1
) == FAIL
7161 || skip_past_comma (&str
) == FAIL
)
7164 inst
.error
= BAD_ARGS
;
7168 /* Calculate the immediate operand.
7169 The operand is a 7bit signed number. */
7170 skip_whitespace (str
);
7175 if (!ISDIGIT (*str
) && *str
!= '-')
7177 inst
.error
= _("expecting immediate, 7bit operand");
7187 for (imm
= 0; *str
&& ISDIGIT (*str
); ++str
)
7188 imm
= imm
* 10 + *str
- '0';
7192 inst
.error
= _("immediate out of range");
7196 /* Make negative imm's into 7bit signed numbers. */
7203 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
7204 Bits 5-7 of the insn should have bits 4-6 of the immediate.
7205 Bit 4 should be 0. */
7206 imm
= (imm
& 0xf) | ((imm
& 0x70) << 1);
7208 inst
.instruction
|= imm
;
7213 cirrus_parse_offset (str
, negative
)
7222 skip_whitespace (p
);
7235 inst
.error
= _("offset expected");
7239 for (offset
= 0; *p
&& ISDIGIT (*p
); ++p
)
7240 offset
= offset
* 10 + *p
- '0';
7244 inst
.error
= _("offset out of range");
7250 return *negative
? -offset
: offset
;
7253 /* Cirrus load/store instructions.
7254 <insn><cond> CRd,[Rn,<offset>]{!}.
7255 <insn><cond> CRd,[Rn],<offset>. */
7258 do_c_ldst (str
, reg0
)
7260 enum arm_reg_type reg0
;
7262 int offset
, negative
;
7264 skip_whitespace (str
);
7266 if (cirrus_reg_required_here (&str
, 12, reg0
) == FAIL
7267 || skip_past_comma (&str
) == FAIL
7269 || reg_required_here (&str
, 16) == FAIL
)
7272 if (skip_past_comma (&str
) == SUCCESS
)
7274 /* You are here: "<offset>]{!}". */
7275 inst
.instruction
|= PRE_INDEX
;
7277 offset
= cirrus_parse_offset (&str
, &negative
);
7284 inst
.error
= _("missing ]");
7290 inst
.instruction
|= WRITE_BACK
;
7296 /* You are here: "], <offset>". */
7299 inst
.error
= _("missing ]");
7303 if (skip_past_comma (&str
) == FAIL
7304 || (offset
= cirrus_parse_offset (&str
, &negative
), inst
.error
))
7307 inst
.instruction
|= CP_T_WB
; /* Post indexed, set bit W. */
7313 inst
.instruction
|= CP_T_UD
; /* Postive, so set bit U. */
7315 inst
.instruction
|= offset
>> 2;
7321 inst
.error
= BAD_ARGS
;
7334 /* Handle the Format 4 instructions that do not have equivalents in other
7335 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
7344 skip_whitespace (str
);
7346 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7347 || skip_past_comma (&str
) == FAIL
7348 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7350 inst
.error
= BAD_ARGS
;
7354 if (skip_past_comma (&str
) != FAIL
)
7356 /* Three operand format not allowed for TST, CMN, NEG and MVN.
7357 (It isn't allowed for CMP either, but that isn't handled by this
7359 if (inst
.instruction
== T_OPCODE_TST
7360 || inst
.instruction
== T_OPCODE_CMN
7361 || inst
.instruction
== T_OPCODE_NEG
7362 || inst
.instruction
== T_OPCODE_MVN
)
7364 inst
.error
= BAD_ARGS
;
7368 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7373 inst
.error
= _("dest and source1 must be the same register");
7379 if (inst
.instruction
== T_OPCODE_MUL
7381 as_tsktsk (_("Rs and Rd must be different in MUL"));
7383 inst
.instruction
|= Rd
| (Rs
<< 3);
7391 thumb_add_sub (str
, 0);
7398 thumb_shift (str
, THUMB_ASR
);
7405 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7407 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
7408 inst
.reloc
.pc_rel
= 1;
7416 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7418 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
7419 inst
.reloc
.pc_rel
= 1;
7423 /* Find the real, Thumb encoded start of a Thumb function. */
7426 find_real_start (symbolP
)
7430 const char * name
= S_GET_NAME (symbolP
);
7431 symbolS
* new_target
;
7433 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
7434 #define STUB_NAME ".real_start_of"
7439 /* Names that start with '.' are local labels, not function entry points.
7440 The compiler may generate BL instructions to these labels because it
7441 needs to perform a branch to a far away location. */
7445 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
7446 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
7448 new_target
= symbol_find (real_start
);
7450 if (new_target
== NULL
)
7452 as_warn ("Failed to find real start of function: %s\n", name
);
7453 new_target
= symbolP
;
7465 if (my_get_expression (& inst
.reloc
.exp
, & str
))
7468 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
7469 inst
.reloc
.pc_rel
= 1;
7472 /* If the destination of the branch is a defined symbol which does not have
7473 the THUMB_FUNC attribute, then we must be calling a function which has
7474 the (interfacearm) attribute. We look for the Thumb entry point to that
7475 function and change the branch to refer to that function instead. */
7476 if ( inst
.reloc
.exp
.X_op
== O_symbol
7477 && inst
.reloc
.exp
.X_add_symbol
!= NULL
7478 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
7479 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
7480 inst
.reloc
.exp
.X_add_symbol
=
7481 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
7490 skip_whitespace (str
);
7492 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
7495 /* This sets THUMB_H2 from the top bit of reg. */
7496 inst
.instruction
|= reg
<< 3;
7498 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
7499 should cause the alignment to be checked once it is known. This is
7500 because BX PC only works if the instruction is word aligned. */
7509 thumb_mov_compare (str
, THUMB_COMPARE
);
7519 skip_whitespace (str
);
7521 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7525 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
7529 if (skip_past_comma (&str
) == FAIL
7530 || (range
= reg_list (&str
)) == FAIL
)
7533 inst
.error
= BAD_ARGS
;
7537 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
7539 /* This really doesn't seem worth it. */
7540 inst
.reloc
.type
= BFD_RELOC_NONE
;
7541 inst
.error
= _("Expression too complex");
7547 inst
.error
= _("only lo-regs valid in load/store multiple");
7551 inst
.instruction
|= (Rb
<< 8) | range
;
7559 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
7566 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
7573 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
7582 skip_whitespace (str
);
7584 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7585 || skip_past_comma (&str
) == FAIL
7587 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7588 || skip_past_comma (&str
) == FAIL
7589 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7593 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
7597 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
7605 thumb_shift (str
, THUMB_LSL
);
7612 thumb_shift (str
, THUMB_LSR
);
7619 thumb_mov_compare (str
, THUMB_MOVE
);
7628 skip_whitespace (str
);
7630 if ((range
= reg_list (&str
)) == FAIL
)
7633 inst
.error
= BAD_ARGS
;
7637 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
7639 /* This really doesn't seem worth it. */
7640 inst
.reloc
.type
= BFD_RELOC_NONE
;
7641 inst
.error
= _("Expression too complex");
7647 if ((inst
.instruction
== T_OPCODE_PUSH
7648 && (range
& ~0xff) == 1 << REG_LR
)
7649 || (inst
.instruction
== T_OPCODE_POP
7650 && (range
& ~0xff) == 1 << REG_PC
))
7652 inst
.instruction
|= THUMB_PP_PC_LR
;
7657 inst
.error
= _("invalid register list to push/pop instruction");
7662 inst
.instruction
|= range
;
7670 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
7677 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
7684 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
7691 thumb_add_sub (str
, 1);
7698 skip_whitespace (str
);
7700 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7703 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
7714 /* This is a pseudo-op of the form "adr rd, label" to be converted
7715 into a relative address of the form "add rd, pc, #label-.-4". */
7716 skip_whitespace (str
);
7718 /* Store Rd in temporary location inside instruction. */
7719 if ((reg
= reg_required_here (&str
, 4)) == FAIL
7720 || (reg
> 7) /* For Thumb reg must be r0..r7. */
7721 || skip_past_comma (&str
) == FAIL
7722 || my_get_expression (&inst
.reloc
.exp
, &str
))
7725 inst
.error
= BAD_ARGS
;
7729 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
7730 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
7731 inst
.reloc
.pc_rel
= 1;
7732 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
7738 insert_reg (r
, htab
)
7739 const struct reg_entry
*r
;
7740 struct hash_control
*htab
;
7742 int len
= strlen (r
->name
) + 2;
7743 char * buf
= (char *) xmalloc (len
);
7744 char * buf2
= (char *) xmalloc (len
);
7747 #ifdef REGISTER_PREFIX
7748 buf
[i
++] = REGISTER_PREFIX
;
7751 strcpy (buf
+ i
, r
->name
);
7753 for (i
= 0; buf
[i
]; i
++)
7754 buf2
[i
] = TOUPPER (buf
[i
]);
7758 hash_insert (htab
, buf
, (PTR
) r
);
7759 hash_insert (htab
, buf2
, (PTR
) r
);
7764 struct reg_map
*map
;
7766 const struct reg_entry
*r
;
7768 if ((map
->htab
= hash_new ()) == NULL
)
7769 as_fatal (_("Virtual memory exhausted"));
7771 for (r
= map
->names
; r
->name
!= NULL
; r
++)
7772 insert_reg (r
, map
->htab
);
7776 insert_reg_alias (str
, regnum
, htab
)
7779 struct hash_control
*htab
;
7781 struct reg_entry
*new =
7782 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
7783 char *name
= xmalloc (strlen (str
) + 1);
7787 new->number
= regnum
;
7789 hash_insert (htab
, name
, (PTR
) new);
7792 /* Look for the .req directive. This is of the form:
7794 newname .req existing_name
7796 If we find one, or if it looks sufficiently like one that we want to
7797 handle any error here, return non-zero. Otherwise return zero. */
7799 create_register_alias (newname
, p
)
7807 skip_whitespace (q
);
7812 if (*q
&& !strncmp (q
, ".req ", 5))
7817 #ifdef IGNORE_OPCODE_CASE
7818 newname
= original_case_string
;
7820 copy_of_str
= newname
;
7823 skip_whitespace (q
);
7825 for (r
= q
; *r
!= '\0'; r
++)
7831 enum arm_reg_type new_type
, old_type
;
7836 old_type
= arm_reg_parse_any (q
);
7839 new_type
= arm_reg_parse_any (newname
);
7841 if (new_type
== REG_TYPE_MAX
)
7843 if (old_type
!= REG_TYPE_MAX
)
7845 old_regno
= arm_reg_parse (&q
, all_reg_maps
[old_type
].htab
);
7846 insert_reg_alias (newname
, old_regno
,
7847 all_reg_maps
[old_type
].htab
);
7850 as_warn (_("register '%s' does not exist\n"), q
);
7852 else if (old_type
== REG_TYPE_MAX
)
7854 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
7859 /* Do not warn about redefinitions to the same alias. */
7860 if (new_type
!= old_type
7861 || (arm_reg_parse (&q
, all_reg_maps
[old_type
].htab
)
7862 != arm_reg_parse (&q
, all_reg_maps
[new_type
].htab
)))
7863 as_warn (_("ignoring redefinition of register alias '%s'"),
7869 as_warn (_("ignoring incomplete .req pseuso op"));
7879 set_constant_flonums ()
7883 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
7884 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
7888 /* Iterate over the base tables to create the instruction patterns. */
7890 build_arm_ops_hsh ()
7894 static struct obstack insn_obstack
;
7896 obstack_begin (&insn_obstack
, 4000);
7898 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
7900 const struct asm_opcode
*insn
= insns
+ i
;
7902 if (insn
->cond_offset
!= 0)
7904 /* Insn supports conditional execution. Build the varaints
7905 and insert them in the hash table. */
7906 for (j
= 0; j
< sizeof (conds
) / sizeof (struct asm_cond
); j
++)
7908 unsigned len
= strlen (insn
->template);
7909 struct asm_opcode
*new;
7912 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
7913 /* All condition codes are two characters. */
7914 template = obstack_alloc (&insn_obstack
, len
+ 3);
7916 strncpy (template, insn
->template, insn
->cond_offset
);
7917 strcpy (template + insn
->cond_offset
, conds
[j
].template);
7918 if (len
> insn
->cond_offset
)
7919 strcpy (template + insn
->cond_offset
+ 2,
7920 insn
->template + insn
->cond_offset
);
7921 new->template = template;
7922 new->cond_offset
= 0;
7923 new->variant
= insn
->variant
;
7924 new->parms
= insn
->parms
;
7925 new->value
= (insn
->value
& ~COND_MASK
) | conds
[j
].value
;
7927 hash_insert (arm_ops_hsh
, new->template, (PTR
) new);
7930 /* Finally, insert the unconditional insn in the table directly;
7931 no need to build a copy. */
7932 hash_insert (arm_ops_hsh
, insn
->template, (PTR
) insn
);
7942 if ( (arm_ops_hsh
= hash_new ()) == NULL
7943 || (arm_tops_hsh
= hash_new ()) == NULL
7944 || (arm_cond_hsh
= hash_new ()) == NULL
7945 || (arm_shift_hsh
= hash_new ()) == NULL
7946 || (arm_psr_hsh
= hash_new ()) == NULL
)
7947 as_fatal (_("Virtual memory exhausted"));
7949 build_arm_ops_hsh ();
7950 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
7951 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
7952 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
7953 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
7954 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
7955 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
7956 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
7957 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
7959 for (i
= (int) REG_TYPE_FIRST
; i
< (int) REG_TYPE_MAX
; i
++)
7960 build_reg_hsh (all_reg_maps
+ i
);
7962 set_constant_flonums ();
7964 #if defined OBJ_COFF || defined OBJ_ELF
7966 unsigned int flags
= 0;
7968 /* Set the flags in the private structure. */
7969 if (uses_apcs_26
) flags
|= F_APCS26
;
7970 if (support_interwork
) flags
|= F_INTERWORK
;
7971 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
7972 if (pic_code
) flags
|= F_PIC
;
7973 if ((cpu_variant
& FPU_ANY
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
7975 bfd_set_private_flags (stdoutput
, flags
);
7977 /* We have run out flags in the COFF header to encode the
7978 status of ATPCS support, so instead we create a dummy,
7979 empty, debug section called .arm.atpcs. */
7984 sec
= bfd_make_section (stdoutput
, ".arm.atpcs");
7988 bfd_set_section_flags
7989 (stdoutput
, sec
, SEC_READONLY
| SEC_DEBUGGING
/* | SEC_HAS_CONTENTS */);
7990 bfd_set_section_size (stdoutput
, sec
, 0);
7991 bfd_set_section_contents (stdoutput
, sec
, NULL
, 0, 0);
7997 /* Record the CPU type as well. */
7998 switch (cpu_variant
& ARM_CPU_MASK
)
8001 mach
= bfd_mach_arm_2
;
8004 case ARM_3
: /* Also ARM_250. */
8005 mach
= bfd_mach_arm_2a
;
8008 case ARM_6
: /* Also ARM_7. */
8009 mach
= bfd_mach_arm_3
;
8013 mach
= bfd_mach_arm_4
;
8017 /* Catch special cases. */
8018 if (cpu_variant
& ARM_EXT_XSCALE
)
8019 mach
= bfd_mach_arm_XScale
;
8020 else if (cpu_variant
& ARM_EXT_V5E
)
8021 mach
= bfd_mach_arm_5TE
;
8022 else if (cpu_variant
& ARM_EXT_V5
)
8024 if (cpu_variant
& ARM_EXT_V4T
)
8025 mach
= bfd_mach_arm_5T
;
8027 mach
= bfd_mach_arm_5
;
8029 else if (cpu_variant
& ARM_EXT_V4
)
8031 if (cpu_variant
& ARM_EXT_V4T
)
8032 mach
= bfd_mach_arm_4T
;
8034 mach
= bfd_mach_arm_4
;
8036 else if (cpu_variant
& ARM_EXT_V3M
)
8037 mach
= bfd_mach_arm_3M
;
8039 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
8042 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
8043 for use in the a.out file, and stores them in the array pointed to by buf.
8044 This knows about the endian-ness of the target machine and does
8045 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
8046 2 (short) and 4 (long) Floating numbers are put out as a series of
8047 LITTLENUMS (shorts, here at least). */
8050 md_number_to_chars (buf
, val
, n
)
8055 if (target_big_endian
)
8056 number_to_chars_bigendian (buf
, val
, n
);
8058 number_to_chars_littleendian (buf
, val
, n
);
8062 md_chars_to_number (buf
, n
)
8067 unsigned char * where
= (unsigned char *) buf
;
8069 if (target_big_endian
)
8074 result
|= (*where
++ & 255);
8082 result
|= (where
[n
] & 255);
8089 /* Turn a string in input_line_pointer into a floating point constant
8090 of type TYPE, and store the appropriate bytes in *LITP. The number
8091 of LITTLENUMS emitted is stored in *SIZEP. An error message is
8092 returned, or NULL on OK.
8094 Note that fp constants aren't represent in the normal way on the ARM.
8095 In big endian mode, things are as expected. However, in little endian
8096 mode fp constants are big-endian word-wise, and little-endian byte-wise
8097 within the words. For example, (double) 1.1 in big endian mode is
8098 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
8099 the byte sequence 99 99 f1 3f 9a 99 99 99.
8101 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
8104 md_atof (type
, litP
, sizeP
)
8110 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
8142 return _("Bad call to MD_ATOF()");
8145 t
= atof_ieee (input_line_pointer
, type
, words
);
8147 input_line_pointer
= t
;
8150 if (target_big_endian
)
8152 for (i
= 0; i
< prec
; i
++)
8154 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
8160 /* For a 4 byte float the order of elements in `words' is 1 0. For an
8161 8 byte float the order is 1 0 3 2. */
8162 for (i
= 0; i
< prec
; i
+= 2)
8164 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
8165 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
8173 /* The knowledge of the PC's pipeline offset is built into the insns
8177 md_pcrel_from (fixP
)
8181 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
8182 && fixP
->fx_subsy
== NULL
)
8185 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
8187 /* PC relative addressing on the Thumb is slightly odd
8188 as the bottom two bits of the PC are forced to zero
8189 for the calculation. */
8190 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
8194 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
8195 so we un-adjust here to compensate for the accomodation. */
8196 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
8198 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
8202 /* Round up a section size to the appropriate boundary. */
8205 md_section_align (segment
, size
)
8206 segT segment ATTRIBUTE_UNUSED
;
8212 /* Round all sects to multiple of 4. */
8213 return (size
+ 3) & ~3;
8217 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
8218 Otherwise we have no need to default values of symbols. */
8221 md_undefined_symbol (name
)
8222 char * name ATTRIBUTE_UNUSED
;
8225 if (name
[0] == '_' && name
[1] == 'G'
8226 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
8230 if (symbol_find (name
))
8231 as_bad ("GOT already in the symbol table");
8233 GOT_symbol
= symbol_new (name
, undefined_section
,
8234 (valueT
) 0, & zero_address_frag
);
8244 /* arm_reg_parse () := if it looks like a register, return its token and
8245 advance the pointer. */
8248 arm_reg_parse (ccp
, htab
)
8249 register char ** ccp
;
8250 struct hash_control
*htab
;
8252 char * start
= * ccp
;
8255 struct reg_entry
* reg
;
8257 #ifdef REGISTER_PREFIX
8258 if (*start
!= REGISTER_PREFIX
)
8263 #ifdef OPTIONAL_REGISTER_PREFIX
8264 if (*p
== OPTIONAL_REGISTER_PREFIX
)
8268 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
8272 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
8276 reg
= (struct reg_entry
*) hash_find (htab
, start
);
8288 /* Search for the following register name in each of the possible reg name
8289 tables. Return the classification if found, or REG_TYPE_MAX if not
8291 static enum arm_reg_type
8292 arm_reg_parse_any (cp
)
8297 for (i
= (int) REG_TYPE_FIRST
; i
< (int) REG_TYPE_MAX
; i
++)
8298 if (arm_reg_parse (&cp
, all_reg_maps
[i
].htab
) != FAIL
)
8299 return (enum arm_reg_type
) i
;
8301 return REG_TYPE_MAX
;
8305 md_apply_fix3 (fixP
, valP
, seg
)
8310 offsetT value
= * valP
;
8312 unsigned int newimm
;
8315 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
8316 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
8318 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
8320 /* Note whether this will delete the relocation. */
8322 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
8323 doesn't work fully.) */
8324 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
8327 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
8331 /* If this symbol is in a different section then we need to leave it for
8332 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
8333 so we have to undo it's effects here. */
8336 if (fixP
->fx_addsy
!= NULL
8337 && S_IS_DEFINED (fixP
->fx_addsy
)
8338 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
8341 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
8342 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
8346 value
+= md_pcrel_from (fixP
);
8350 /* Remember value for emit_reloc. */
8351 fixP
->fx_addnumber
= value
;
8353 switch (fixP
->fx_r_type
)
8355 case BFD_RELOC_ARM_IMMEDIATE
:
8356 newimm
= validate_immediate (value
);
8357 temp
= md_chars_to_number (buf
, INSN_SIZE
);
8359 /* If the instruction will fail, see if we can fix things up by
8360 changing the opcode. */
8361 if (newimm
== (unsigned int) FAIL
8362 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
8364 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8365 _("invalid constant (%lx) after fixup"),
8366 (unsigned long) value
);
8370 newimm
|= (temp
& 0xfffff000);
8371 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
8374 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
8376 unsigned int highpart
= 0;
8377 unsigned int newinsn
= 0xe1a00000; /* nop. */
8378 newimm
= validate_immediate (value
);
8379 temp
= md_chars_to_number (buf
, INSN_SIZE
);
8381 /* If the instruction will fail, see if we can fix things up by
8382 changing the opcode. */
8383 if (newimm
== (unsigned int) FAIL
8384 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
8386 /* No ? OK - try using two ADD instructions to generate
8388 newimm
= validate_immediate_twopart (value
, & highpart
);
8390 /* Yes - then make sure that the second instruction is
8392 if (newimm
!= (unsigned int) FAIL
)
8394 /* Still No ? Try using a negated value. */
8395 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
8396 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
8397 /* Otherwise - give up. */
8400 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8401 _("Unable to compute ADRL instructions for PC offset of 0x%lx"),
8406 /* Replace the first operand in the 2nd instruction (which
8407 is the PC) with the destination register. We have
8408 already added in the PC in the first instruction and we
8409 do not want to do it again. */
8410 newinsn
&= ~ 0xf0000;
8411 newinsn
|= ((newinsn
& 0x0f000) << 4);
8414 newimm
|= (temp
& 0xfffff000);
8415 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
8417 highpart
|= (newinsn
& 0xfffff000);
8418 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
8422 case BFD_RELOC_ARM_OFFSET_IMM
:
8428 if (validate_offset_imm (value
, 0) == FAIL
)
8430 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8431 _("bad immediate value for offset (%ld)"),
8436 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8437 newval
&= 0xff7ff000;
8438 newval
|= value
| (sign
? INDEX_UP
: 0);
8439 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8442 case BFD_RELOC_ARM_OFFSET_IMM8
:
8443 case BFD_RELOC_ARM_HWLITERAL
:
8449 if (validate_offset_imm (value
, 1) == FAIL
)
8451 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
8452 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8453 _("invalid literal constant: pool needs to be closer"));
8455 as_bad (_("bad immediate value for half-word offset (%ld)"),
8460 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8461 newval
&= 0xff7ff0f0;
8462 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
8463 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8466 case BFD_RELOC_ARM_LITERAL
:
8472 if (validate_offset_imm (value
, 0) == FAIL
)
8474 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8475 _("invalid literal constant: pool needs to be closer"));
8479 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8480 newval
&= 0xff7ff000;
8481 newval
|= value
| (sign
? INDEX_UP
: 0);
8482 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8485 case BFD_RELOC_ARM_SHIFT_IMM
:
8486 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8487 if (((unsigned long) value
) > 32
8489 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
8491 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8492 _("shift expression is too large"));
8497 /* Shifts of zero must be done as lsl. */
8499 else if (value
== 32)
8501 newval
&= 0xfffff07f;
8502 newval
|= (value
& 0x1f) << 7;
8503 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8506 case BFD_RELOC_ARM_SWI
:
8507 if (arm_data
->thumb_mode
)
8509 if (((unsigned long) value
) > 0xff)
8510 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8511 _("Invalid swi expression"));
8512 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
8514 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8518 if (((unsigned long) value
) > 0x00ffffff)
8519 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8520 _("Invalid swi expression"));
8521 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
8523 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8527 case BFD_RELOC_ARM_MULTI
:
8528 if (((unsigned long) value
) > 0xffff)
8529 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8530 _("Invalid expression in load/store multiple"));
8531 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
8532 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8535 case BFD_RELOC_ARM_PCREL_BRANCH
:
8536 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8538 /* Sign-extend a 24-bit number. */
8539 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
8543 value
= fixP
->fx_offset
;
8546 /* We are going to store value (shifted right by two) in the
8547 instruction, in a 24 bit, signed field. Thus we need to check
8548 that none of the top 8 bits of the shifted value (top 7 bits of
8549 the unshifted, unsigned value) are set, or that they are all set. */
8550 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
8551 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
8554 /* Normally we would be stuck at this point, since we cannot store
8555 the absolute address that is the destination of the branch in the
8556 24 bits of the branch instruction. If however, we happen to know
8557 that the destination of the branch is in the same section as the
8558 branch instruciton itself, then we can compute the relocation for
8559 ourselves and not have to bother the linker with it.
8561 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
8562 because I have not worked out how to do this for OBJ_COFF or
8565 && fixP
->fx_addsy
!= NULL
8566 && S_IS_DEFINED (fixP
->fx_addsy
)
8567 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
8569 /* Get pc relative value to go into the branch. */
8572 /* Permit a backward branch provided that enough bits
8573 are set. Allow a forwards branch, provided that
8574 enough bits are clear. */
8575 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
8576 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
8580 if (! fixP
->fx_done
)
8582 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8583 _("gas can't handle same-section branch dest >= 0x04000000"));
8587 value
+= SEXT24 (newval
);
8589 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
8590 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
8591 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8592 _("out of range branch"));
8594 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
8595 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8598 case BFD_RELOC_ARM_PCREL_BLX
:
8601 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8605 value
= fixP
->fx_offset
;
8607 hbit
= (value
>> 1) & 1;
8608 value
= (value
>> 2) & 0x00ffffff;
8609 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
8610 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
8611 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8615 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
8616 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8618 addressT diff
= (newval
& 0xff) << 1;
8623 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
8624 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8625 _("Branch out of range"));
8626 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
8628 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8631 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
8632 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8634 addressT diff
= (newval
& 0x7ff) << 1;
8639 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
8640 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8641 _("Branch out of range"));
8642 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
8644 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8647 case BFD_RELOC_THUMB_PCREL_BLX
:
8648 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
8653 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8654 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
8655 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
8656 if (diff
& 0x400000)
8659 value
= fixP
->fx_offset
;
8662 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
8663 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8664 _("Branch with link out of range"));
8666 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
8667 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
8668 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
)
8669 /* Remove bit zero of the adjusted offset. Bit zero can only be
8670 set if the upper insn is at a half-word boundary, since the
8671 destination address, an ARM instruction, must always be on a
8672 word boundary. The semantics of the BLX (1) instruction, however,
8673 are that bit zero in the offset must always be zero, and the
8674 corresponding bit one in the target address will be set from bit
8675 one of the source address. */
8677 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8678 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
8683 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
8684 md_number_to_chars (buf
, value
, 1);
8686 else if (!target_oabi
)
8688 value
= fixP
->fx_offset
;
8689 md_number_to_chars (buf
, value
, 1);
8695 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
8696 md_number_to_chars (buf
, value
, 2);
8698 else if (!target_oabi
)
8700 value
= fixP
->fx_offset
;
8701 md_number_to_chars (buf
, value
, 2);
8707 case BFD_RELOC_ARM_GOT32
:
8708 case BFD_RELOC_ARM_GOTOFF
:
8709 md_number_to_chars (buf
, 0, 4);
8715 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
8716 md_number_to_chars (buf
, value
, 4);
8718 else if (!target_oabi
)
8720 value
= fixP
->fx_offset
;
8721 md_number_to_chars (buf
, value
, 4);
8727 case BFD_RELOC_ARM_PLT32
:
8728 /* It appears the instruction is fully prepared at this point. */
8732 case BFD_RELOC_ARM_GOTPC
:
8733 md_number_to_chars (buf
, value
, 4);
8736 case BFD_RELOC_ARM_CP_OFF_IMM
:
8738 if (value
< -1023 || value
> 1023 || (value
& 3))
8739 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8740 _("Illegal value for co-processor offset"));
8743 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
8744 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
8745 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8748 case BFD_RELOC_ARM_THUMB_OFFSET
:
8749 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8750 /* Exactly what ranges, and where the offset is inserted depends
8751 on the type of instruction, we can establish this from the
8753 switch (newval
>> 12)
8755 case 4: /* PC load. */
8756 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
8757 forced to zero for these loads, so we will need to round
8758 up the offset if the instruction address is not word
8759 aligned (since the final address produced must be, and
8760 we can only describe word-aligned immediate offsets). */
8762 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
8763 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8764 _("Invalid offset, target not word aligned (0x%08X)"),
8765 (unsigned int) (fixP
->fx_frag
->fr_address
8766 + fixP
->fx_where
+ value
));
8768 if ((value
+ 2) & ~0x3fe)
8769 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8770 _("Invalid offset, value too big (0x%08lX)"), value
);
8772 /* Round up, since pc will be rounded down. */
8773 newval
|= (value
+ 2) >> 2;
8776 case 9: /* SP load/store. */
8778 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8779 _("Invalid offset, value too big (0x%08lX)"), value
);
8780 newval
|= value
>> 2;
8783 case 6: /* Word load/store. */
8785 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8786 _("Invalid offset, value too big (0x%08lX)"), value
);
8787 newval
|= value
<< 4; /* 6 - 2. */
8790 case 7: /* Byte load/store. */
8792 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8793 _("Invalid offset, value too big (0x%08lX)"), value
);
8794 newval
|= value
<< 6;
8797 case 8: /* Halfword load/store. */
8799 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8800 _("Invalid offset, value too big (0x%08lX)"), value
);
8801 newval
|= value
<< 5; /* 6 - 1. */
8805 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8806 "Unable to process relocation for thumb opcode: %lx",
8807 (unsigned long) newval
);
8810 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8813 case BFD_RELOC_ARM_THUMB_ADD
:
8814 /* This is a complicated relocation, since we use it for all of
8815 the following immediate relocations:
8819 9bit ADD/SUB SP word-aligned
8820 10bit ADD PC/SP word-aligned
8822 The type of instruction being processed is encoded in the
8829 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8831 int rd
= (newval
>> 4) & 0xf;
8832 int rs
= newval
& 0xf;
8833 int subtract
= newval
& 0x8000;
8838 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8839 _("Invalid immediate for stack address calculation"));
8840 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
8841 newval
|= value
>> 2;
8843 else if (rs
== REG_PC
|| rs
== REG_SP
)
8847 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8848 _("Invalid immediate for address calculation (value = 0x%08lX)"),
8849 (unsigned long) value
);
8850 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
8852 newval
|= value
>> 2;
8857 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8858 _("Invalid 8bit immediate"));
8859 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
8860 newval
|= (rd
<< 8) | value
;
8865 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8866 _("Invalid 3bit immediate"));
8867 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
8868 newval
|= rd
| (rs
<< 3) | (value
<< 6);
8871 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8874 case BFD_RELOC_ARM_THUMB_IMM
:
8875 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8876 switch (newval
>> 11)
8878 case 0x04: /* 8bit immediate MOV. */
8879 case 0x05: /* 8bit immediate CMP. */
8880 if (value
< 0 || value
> 255)
8881 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8882 _("Invalid immediate: %ld is too large"),
8890 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8893 case BFD_RELOC_ARM_THUMB_SHIFT
:
8894 /* 5bit shift value (0..31). */
8895 if (value
< 0 || value
> 31)
8896 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8897 _("Illegal Thumb shift value: %ld"), (long) value
);
8898 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
8899 newval
|= value
<< 6;
8900 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8903 case BFD_RELOC_VTABLE_INHERIT
:
8904 case BFD_RELOC_VTABLE_ENTRY
:
8908 case BFD_RELOC_NONE
:
8910 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8911 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
8915 /* Translate internal representation of relocation info to BFD target
8919 tc_gen_reloc (section
, fixp
)
8920 asection
* section ATTRIBUTE_UNUSED
;
8924 bfd_reloc_code_real_type code
;
8926 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
8928 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
8929 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
8930 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
8932 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
8934 if (fixp
->fx_pcrel
== 0)
8935 reloc
->addend
= fixp
->fx_offset
;
8937 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
8939 reloc
->addend
= fixp
->fx_offset
;
8942 switch (fixp
->fx_r_type
)
8947 code
= BFD_RELOC_8_PCREL
;
8954 code
= BFD_RELOC_16_PCREL
;
8961 code
= BFD_RELOC_32_PCREL
;
8965 case BFD_RELOC_ARM_PCREL_BRANCH
:
8966 case BFD_RELOC_ARM_PCREL_BLX
:
8968 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
8969 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
8970 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
8971 case BFD_RELOC_THUMB_PCREL_BLX
:
8972 case BFD_RELOC_VTABLE_ENTRY
:
8973 case BFD_RELOC_VTABLE_INHERIT
:
8974 code
= fixp
->fx_r_type
;
8977 case BFD_RELOC_ARM_LITERAL
:
8978 case BFD_RELOC_ARM_HWLITERAL
:
8979 /* If this is called then the a literal has been referenced across
8980 a section boundary - possibly due to an implicit dump. */
8981 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8982 _("Literal referenced across section boundary (Implicit dump?)"));
8986 case BFD_RELOC_ARM_GOT32
:
8987 case BFD_RELOC_ARM_GOTOFF
:
8988 case BFD_RELOC_ARM_PLT32
:
8989 code
= fixp
->fx_r_type
;
8993 case BFD_RELOC_ARM_IMMEDIATE
:
8994 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8995 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
8999 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
9000 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9001 _("ADRL used for a symbol not defined in the same file"));
9004 case BFD_RELOC_ARM_OFFSET_IMM
:
9005 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9006 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
9014 switch (fixp
->fx_r_type
)
9016 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
9017 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
9018 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
9019 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
9020 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
9021 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
9022 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
9023 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
9024 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
9025 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
9026 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
9027 default: type
= _("<unknown>"); break;
9029 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9030 _("Cannot represent %s relocation in this object file format"),
9037 if (code
== BFD_RELOC_32_PCREL
9039 && fixp
->fx_addsy
== GOT_symbol
)
9041 code
= BFD_RELOC_ARM_GOTPC
;
9042 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
9046 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
9048 if (reloc
->howto
== NULL
)
9050 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9051 _("Can not represent %s relocation in this object file format"),
9052 bfd_get_reloc_code_name (code
));
9056 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
9057 vtable entry to be used in the relocation's section offset. */
9058 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
9059 reloc
->address
= fixp
->fx_offset
;
9065 md_estimate_size_before_relax (fragP
, segtype
)
9066 fragS
* fragP ATTRIBUTE_UNUSED
;
9067 segT segtype ATTRIBUTE_UNUSED
;
9069 as_fatal (_("md_estimate_size_before_relax\n"));
9074 output_inst
PARAMS ((void))
9080 as_bad (inst
.error
);
9084 to
= frag_more (inst
.size
);
9086 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
9088 assert (inst
.size
== (2 * THUMB_SIZE
));
9089 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
9090 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
9092 else if (inst
.size
> INSN_SIZE
)
9094 assert (inst
.size
== (2 * INSN_SIZE
));
9095 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
9096 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
9099 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
9101 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
9102 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
9103 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
9107 dwarf2_emit_insn (inst
.size
);
9119 /* Align the instruction.
9120 This may not be the right thing to do but ... */
9124 listing_prev_line (); /* Defined in listing.h. */
9126 /* Align the previous label if needed. */
9127 if (last_label_seen
!= NULL
)
9129 symbol_set_frag (last_label_seen
, frag_now
);
9130 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
9131 S_SET_SEGMENT (last_label_seen
, now_seg
);
9134 memset (&inst
, '\0', sizeof (inst
));
9135 inst
.reloc
.type
= BFD_RELOC_NONE
;
9137 skip_whitespace (str
);
9139 /* Scan up to the end of the op-code, which must end in white space or
9141 for (start
= p
= str
; *p
!= '\0'; p
++)
9147 as_bad (_("No operator -- statement `%s'\n"), str
);
9153 const struct thumb_opcode
* opcode
;
9157 opcode
= (const struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
9162 /* Check that this instruction is supported for this CPU. */
9163 if (thumb_mode
== 1 && (opcode
->variant
& cpu_variant
) == 0)
9165 as_bad (_("selected processor does not support this opcode"));
9169 inst
.instruction
= opcode
->value
;
9170 inst
.size
= opcode
->size
;
9171 (*opcode
->parms
) (p
);
9178 const struct asm_opcode
* opcode
;
9182 opcode
= (const struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
9187 /* Check that this instruction is supported for this CPU. */
9188 if ((opcode
->variant
& cpu_variant
) == 0)
9190 as_bad (_("selected processor does not support this opcode"));
9194 inst
.instruction
= opcode
->value
;
9195 inst
.size
= INSN_SIZE
;
9196 (*opcode
->parms
) (p
);
9202 /* It wasn't an instruction, but it might be a register alias of the form
9204 if (create_register_alias (str
, p
))
9207 as_bad (_("bad instruction `%s'"), start
);
9211 Invocation line includes a switch not recognized by the base assembler.
9212 See if it's a processor-specific option. These are:
9213 Cpu variants, the arm part is optional:
9214 -m[arm]1 Currently not supported.
9215 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
9216 -m[arm]3 Arm 3 processor
9217 -m[arm]6[xx], Arm 6 processors
9218 -m[arm]7[xx][t][[d]m] Arm 7 processors
9219 -m[arm]8[10] Arm 8 processors
9220 -m[arm]9[20][tdmi] Arm 9 processors
9221 -marm9e Allow Cirrus/DSP instructions
9222 -mstrongarm[110[0]] StrongARM processors
9223 -mxscale XScale processors
9224 -m[arm]v[2345[t[e]]] Arm architectures
9225 -mall All (except the ARM1)
9227 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
9228 -mfpe-old (No float load/store multiples)
9229 -mno-fpu Disable all floating point instructions
9230 Run-time endian selection:
9232 -EL little endian cpu
9233 ARM Procedure Calling Standard:
9234 -mapcs-32 32 bit APCS
9235 -mapcs-26 26 bit APCS
9236 -mapcs-float Pass floats in float regs
9237 -mapcs-reentrant Position independent code
9238 -mthumb-interwork Code supports Arm/Thumb interworking
9239 -matpcs ARM/Thumb Procedure Call Standard
9240 -moabi Old ELF ABI */
9242 const char * md_shortopts
= "m:k";
9244 struct option md_longopts
[] =
9246 #ifdef ARM_BI_ENDIAN
9247 #define OPTION_EB (OPTION_MD_BASE + 0)
9248 {"EB", no_argument
, NULL
, OPTION_EB
},
9249 #define OPTION_EL (OPTION_MD_BASE + 1)
9250 {"EL", no_argument
, NULL
, OPTION_EL
},
9252 #define OPTION_OABI (OPTION_MD_BASE +2)
9253 {"oabi", no_argument
, NULL
, OPTION_OABI
},
9256 {NULL
, no_argument
, NULL
, 0}
9259 size_t md_longopts_size
= sizeof (md_longopts
);
9262 md_parse_option (c
, arg
)
9270 #ifdef ARM_BI_ENDIAN
9272 target_big_endian
= 1;
9275 target_big_endian
= 0;
9283 if (streq (str
, "fpa10") || streq (str
, "fpa11"))
9284 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_ARCH_FPA
;
9285 else if (streq (str
, "fpe-old"))
9286 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_ARCH_FPE
;
9292 if (streq (str
, "no-fpu"))
9293 cpu_variant
&= ~FPU_ANY
;
9298 if (streq (str
, "oabi"))
9304 /* Limit assembler to generating only Thumb instructions: */
9305 if (streq (str
, "thumb"))
9307 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_EXT_V4T
;
9308 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_NONE
;
9311 else if (streq (str
, "thumb-interwork"))
9313 if ((cpu_variant
& ARM_EXT_V4T
) == 0)
9314 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
9315 #if defined OBJ_COFF || defined OBJ_ELF
9316 support_interwork
= true;
9324 if (streq (str
, "all"))
9326 cpu_variant
= ARM_ALL
| FPU_DEFAULT
;
9329 #if defined OBJ_COFF || defined OBJ_ELF
9330 if (! strncmp (str
, "apcs-", 5))
9332 /* GCC passes on all command line options starting "-mapcs-..."
9333 to us, so we must parse them here. */
9337 if (streq (str
, "32"))
9339 uses_apcs_26
= false;
9342 else if (streq (str
, "26"))
9344 uses_apcs_26
= true;
9347 else if (streq (str
, "frame"))
9349 /* Stack frames are being generated - does not affect
9353 else if (streq (str
, "stack-check"))
9355 /* Stack checking is being performed - does not affect
9356 linkage, but does require that the functions
9357 __rt_stkovf_split_small and __rt_stkovf_split_big be
9358 present in the final link. */
9362 else if (streq (str
, "float"))
9364 /* Floating point arguments are being passed in the floating
9365 point registers. This does affect linking, since this
9366 version of the APCS is incompatible with the version that
9367 passes floating points in the integer registers. */
9369 uses_apcs_float
= true;
9372 else if (streq (str
, "reentrant"))
9374 /* Reentrant code has been generated. This does affect
9375 linking, since there is no point in linking reentrant/
9376 position independent code with absolute position code. */
9381 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
9385 if (! strcmp (str
, "atpcs"))
9391 /* Strip off optional "arm". */
9392 if (! strncmp (str
, "arm", 3))
9398 if (streq (str
, "1"))
9399 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
9405 if (streq (str
, "2"))
9406 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
9407 else if (streq (str
, "250"))
9408 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
9414 if (streq (str
, "3"))
9415 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
9421 switch (strtol (str
, NULL
, 10))
9428 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
9436 /* Eat the processor name. */
9437 switch (strtol (str
, & str
, 10))
9450 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
9456 cpu_variant
|= ARM_ARCH_V4T
;
9460 cpu_variant
|= ARM_EXT_V3M
;
9463 case 'f': /* fe => fp enabled cpu. */
9469 case 'c': /* Left over from 710c processor name. */
9470 case 'd': /* Debug. */
9471 case 'i': /* Embedded ICE. */
9472 /* Included for completeness in ARM processor naming. */
9482 if (streq (str
, "8") || streq (str
, "810"))
9483 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9484 | ARM_8
| ARM_ARCH_V4
;
9490 if (streq (str
, "9"))
9491 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9492 | ARM_9
| ARM_ARCH_V4T
;
9493 else if (streq (str
, "920"))
9494 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9495 | ARM_9
| ARM_ARCH_V4
;
9496 else if (streq (str
, "920t"))
9497 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9498 | ARM_9
| ARM_ARCH_V4T
;
9499 else if (streq (str
, "9tdmi"))
9500 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9501 | ARM_9
| ARM_ARCH_V4T
;
9502 else if (streq (str
, "9e"))
9503 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9504 | ARM_9
| ARM_ARCH_V4T
| ARM_EXT_MAVERICK
;
9510 if (streq (str
, "strongarm")
9511 || streq (str
, "strongarm110")
9512 || streq (str
, "strongarm1100"))
9513 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9514 | ARM_8
| ARM_ARCH_V4
;
9520 if (streq (str
, "xscale"))
9521 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9522 | ARM_9
| ARM_ARCH_XSCALE
;
9528 /* Select variant based on architecture rather than
9536 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
9539 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
9542 as_bad (_("Invalid architecture variant -m%s"), arg
);
9548 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
9552 case 'm': cpu_variant
|= ARM_EXT_V3M
; break;
9555 as_bad (_("Invalid architecture variant -m%s"), arg
);
9561 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCH_V4
;
9565 case 't': cpu_variant
|= ARM_EXT_V4T
; break;
9568 as_bad (_("Invalid architecture variant -m%s"), arg
);
9574 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V5
;
9577 case 't': cpu_variant
|= ARM_EXT_V4T
; break;
9578 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
9581 as_bad (_("Invalid architecture variant -m%s"), arg
);
9587 as_bad (_("Invalid architecture variant -m%s"), arg
);
9594 as_bad (_("Invalid processor variant -m%s"), arg
);
9600 #if defined OBJ_ELF || defined OBJ_COFF
9618 ARM Specific Assembler Options:\n\
9619 -m[arm][<processor name>] select processor variant\n\
9620 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
9621 -marm9e allow Cirrus/DSP instructions\n\
9622 -mthumb only allow Thumb instructions\n\
9623 -mthumb-interwork mark the assembled code as supporting interworking\n\
9624 -mall allow any instruction\n\
9625 -mfpa10, -mfpa11 select floating point architecture\n\
9626 -mfpe-old don't allow floating-point multiple instructions\n\
9627 -mno-fpu don't allow any floating-point instructions.\n\
9628 -k generate PIC code.\n"));
9629 #if defined OBJ_COFF || defined OBJ_ELF
9631 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
9632 -matpcs use ARM/Thumb Procedure Calling Standard\n\
9633 -mapcs-float floating point args are passed in FP regs\n\
9634 -mapcs-reentrant the code is position independent/reentrant\n"));
9638 -moabi support the old ELF ABI\n"));
9640 #ifdef ARM_BI_ENDIAN
9642 -EB assemble code for a big endian cpu\n\
9643 -EL assemble code for a little endian cpu\n"));
9647 /* We need to be able to fix up arbitrary expressions in some statements.
9648 This is so that we can handle symbols that are an arbitrary distance from
9649 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
9650 which returns part of an address in a form which will be valid for
9651 a data instruction. We do this by pushing the expression into a symbol
9652 in the expr_section, and creating a fix for that. */
9655 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
9664 arm_fix_data
* arm_data
;
9672 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
9676 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
9681 /* Mark whether the fix is to a THUMB instruction, or an ARM
9683 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
9684 new_fix
->tc_fix_data
= (PTR
) arm_data
;
9685 arm_data
->thumb_mode
= thumb_mode
;
9690 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
9693 cons_fix_new_arm (frag
, where
, size
, exp
)
9699 bfd_reloc_code_real_type type
;
9703 FIXME: @@ Should look at CPU word size. */
9710 type
= BFD_RELOC_16
;
9714 type
= BFD_RELOC_32
;
9717 type
= BFD_RELOC_64
;
9721 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
9724 /* A good place to do this, although this was probably not intended
9725 for this kind of use. We need to dump the literal pool before
9726 references are made to a null symbol pointer. */
9731 if (current_poolP
== NULL
)
9734 /* Put it at the end of text section. */
9735 subseg_set (text_section
, 0);
9737 listing_prev_line ();
9741 arm_start_line_hook ()
9743 last_label_seen
= NULL
;
9747 arm_frob_label (sym
)
9750 last_label_seen
= sym
;
9752 ARM_SET_THUMB (sym
, thumb_mode
);
9754 #if defined OBJ_COFF || defined OBJ_ELF
9755 ARM_SET_INTERWORK (sym
, support_interwork
);
9758 /* Note - do not allow local symbols (.Lxxx) to be labeled
9759 as Thumb functions. This is because these labels, whilst
9760 they exist inside Thumb code, are not the entry points for
9761 possible ARM->Thumb calls. Also, these labels can be used
9762 as part of a computed goto or switch statement. eg gcc
9763 can generate code that looks like this:
9775 The first instruction loads the address of the jump table.
9776 The second instruction converts a table index into a byte offset.
9777 The third instruction gets the jump address out of the table.
9778 The fourth instruction performs the jump.
9780 If the address stored at .Laaa is that of a symbol which has the
9781 Thumb_Func bit set, then the linker will arrange for this address
9782 to have the bottom bit set, which in turn would mean that the
9783 address computation performed by the third instruction would end
9784 up with the bottom bit set. Since the ARM is capable of unaligned
9785 word loads, the instruction would then load the incorrect address
9786 out of the jump table, and chaos would ensue. */
9787 if (label_is_thumb_function_name
9788 && (S_GET_NAME (sym
)[0] != '.' || S_GET_NAME (sym
)[1] != 'L')
9789 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
9791 /* When the address of a Thumb function is taken the bottom
9792 bit of that address should be set. This will allow
9793 interworking between Arm and Thumb functions to work
9796 THUMB_SET_FUNC (sym
, 1);
9798 label_is_thumb_function_name
= false;
9802 /* Adjust the symbol table. This marks Thumb symbols as distinct from
9806 arm_adjust_symtab ()
9811 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
9813 if (ARM_IS_THUMB (sym
))
9815 if (THUMB_IS_FUNC (sym
))
9817 /* Mark the symbol as a Thumb function. */
9818 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
9819 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
9820 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
9822 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
9823 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
9825 as_bad (_("%s: unexpected function type: %d"),
9826 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
9828 else switch (S_GET_STORAGE_CLASS (sym
))
9831 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
9834 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
9837 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
9845 if (ARM_IS_INTERWORK (sym
))
9846 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
9853 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
9855 if (ARM_IS_THUMB (sym
))
9857 elf_symbol_type
* elf_sym
;
9859 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
9860 bind
= ELF_ST_BIND (elf_sym
);
9862 /* If it's a .thumb_func, declare it as so,
9863 otherwise tag label as .code 16. */
9864 if (THUMB_IS_FUNC (sym
))
9865 elf_sym
->internal_elf_sym
.st_info
=
9866 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
9868 elf_sym
->internal_elf_sym
.st_info
=
9869 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
9878 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
9880 *input_line_pointer
= '/';
9881 input_line_pointer
+= 5;
9882 *input_line_pointer
= 0;
9890 arm_canonicalize_symbol_name (name
)
9895 if (thumb_mode
&& (len
= strlen (name
)) > 5
9896 && streq (name
+ len
- 5, "/data"))
9897 *(name
+ len
- 5) = 0;
9903 arm_validate_fix (fixP
)
9906 /* If the destination of the branch is a defined symbol which does not have
9907 the THUMB_FUNC attribute, then we must be calling a function which has
9908 the (interfacearm) attribute. We look for the Thumb entry point to that
9909 function and change the branch to refer to that function instead. */
9910 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
9911 && fixP
->fx_addsy
!= NULL
9912 && S_IS_DEFINED (fixP
->fx_addsy
)
9913 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
9915 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
9923 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
9924 local labels from being added to the output symbol table when they
9925 are used with the ADRL pseudo op. The ADRL relocation should always
9926 be resolved before the binbary is emitted, so it is safe to say that
9927 it is adjustable. */
9930 arm_fix_adjustable (fixP
)
9933 if (fixP
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
9939 /* Relocations against Thumb function names must be left unadjusted,
9940 so that the linker can use this information to correctly set the
9941 bottom bit of their addresses. The MIPS version of this function
9942 also prevents relocations that are mips-16 specific, but I do not
9943 know why it does this.
9946 There is one other problem that ought to be addressed here, but
9947 which currently is not: Taking the address of a label (rather
9948 than a function) and then later jumping to that address. Such
9949 addresses also ought to have their bottom bit set (assuming that
9950 they reside in Thumb code), but at the moment they will not. */
9953 arm_fix_adjustable (fixP
)
9956 if (fixP
->fx_addsy
== NULL
)
9959 /* Prevent all adjustments to global symbols. */
9960 if (S_IS_EXTERN (fixP
->fx_addsy
))
9963 if (S_IS_WEAK (fixP
->fx_addsy
))
9966 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
9967 && fixP
->fx_subsy
== NULL
)
9970 /* We need the symbol name for the VTABLE entries. */
9971 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
9972 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
9979 elf32_arm_target_format ()
9981 if (target_big_endian
)
9984 return "elf32-bigarm-oabi";
9986 return "elf32-bigarm";
9991 return "elf32-littlearm-oabi";
9993 return "elf32-littlearm";
9998 armelf_frob_symbol (symp
, puntp
)
10002 elf_frob_symbol (symp
, puntp
);
10006 arm_force_relocation (fixp
)
10009 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
10010 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
10011 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
10012 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
10013 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
10014 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
10020 static bfd_reloc_code_real_type
10030 bfd_reloc_code_real_type reloc
;
10034 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
10035 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
10036 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
10037 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
10038 branch instructions generated by GCC for PLT relocs. */
10039 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
10040 { NULL
, 0, BFD_RELOC_UNUSED
}
10044 for (i
= 0, ip
= input_line_pointer
;
10045 i
< sizeof (id
) && (ISALNUM (*ip
) || ISPUNCT (*ip
));
10047 id
[i
] = TOLOWER (*ip
);
10049 for (i
= 0; reloc_map
[i
].str
; i
++)
10050 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
10053 input_line_pointer
+= reloc_map
[i
].len
;
10055 return reloc_map
[i
].reloc
;
10059 s_arm_elf_cons (nbytes
)
10064 #ifdef md_flush_pending_output
10065 md_flush_pending_output ();
10068 if (is_it_end_of_statement ())
10070 demand_empty_rest_of_line ();
10074 #ifdef md_cons_align
10075 md_cons_align (nbytes
);
10080 bfd_reloc_code_real_type reloc
;
10082 expression (& exp
);
10084 if (exp
.X_op
== O_symbol
10085 && * input_line_pointer
== '('
10086 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
10088 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
10089 int size
= bfd_get_reloc_size (howto
);
10092 as_bad ("%s relocations do not fit in %d bytes",
10093 howto
->name
, nbytes
);
10096 register char *p
= frag_more ((int) nbytes
);
10097 int offset
= nbytes
- size
;
10099 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
10104 emit_expr (&exp
, (unsigned int) nbytes
);
10106 while (*input_line_pointer
++ == ',');
10108 /* Put terminator back into stream. */
10109 input_line_pointer
--;
10110 demand_empty_rest_of_line ();
10113 #endif /* OBJ_ELF */
10115 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
10116 of an rs_align_code fragment. */
10119 arm_handle_align (fragP
)
10122 static char const arm_noop
[4] = { 0x00, 0x00, 0xa0, 0xe1 };
10123 static char const thumb_noop
[2] = { 0xc0, 0x46 };
10124 static char const arm_bigend_noop
[4] = { 0xe1, 0xa0, 0x00, 0x00 };
10125 static char const thumb_bigend_noop
[2] = { 0x46, 0xc0 };
10127 int bytes
, fix
, noop_size
;
10131 if (fragP
->fr_type
!= rs_align_code
)
10134 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
10135 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
10138 if (bytes
> MAX_MEM_FOR_RS_ALIGN_CODE
)
10139 bytes
&= MAX_MEM_FOR_RS_ALIGN_CODE
;
10141 if (fragP
->tc_frag_data
)
10143 if (target_big_endian
)
10144 noop
= thumb_bigend_noop
;
10147 noop_size
= sizeof (thumb_noop
);
10151 if (target_big_endian
)
10152 noop
= arm_bigend_noop
;
10155 noop_size
= sizeof (arm_noop
);
10158 if (bytes
& (noop_size
- 1))
10160 fix
= bytes
& (noop_size
- 1);
10161 memset (p
, 0, fix
);
10166 while (bytes
>= noop_size
)
10168 memcpy (p
, noop
, noop_size
);
10170 bytes
-= noop_size
;
10174 fragP
->fr_fix
+= fix
;
10175 fragP
->fr_var
= noop_size
;
10178 /* Called from md_do_align. Used to create an alignment
10179 frag in a code section. */
10182 arm_frag_align_code (n
, max
)
10188 /* We assume that there will never be a requirment
10189 to support alignments greater than 32 bytes. */
10190 if (max
> MAX_MEM_FOR_RS_ALIGN_CODE
)
10191 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
10193 p
= frag_var (rs_align_code
,
10194 MAX_MEM_FOR_RS_ALIGN_CODE
,
10196 (relax_substateT
) max
,
10204 /* Perform target specific initialisation of a frag. */
10207 arm_init_frag (fragP
)
10210 /* Record whether this frag is in an ARM or a THUMB area. */
10211 fragP
->tc_frag_data
= thumb_mode
;