1 /* tc-arm.c -- Assemble for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modified by David Taylor (dtaylor@armltd.co.uk)
6 Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 #include "safe-ctype.h"
30 /* Need TARGET_CPU. */
39 #include "dwarf2dbg.h"
42 /* 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 ((const char *));
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
);
2428 if (*str
!= '\0' && !inst
.error
)
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
= _("CPSR or SPSR 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
)));
4185 static int in_my_get_expression
= 0;
4188 my_get_expression (ep
, str
)
4195 save_in
= input_line_pointer
;
4196 input_line_pointer
= *str
;
4197 in_my_get_expression
= 1;
4198 seg
= expression (ep
);
4199 in_my_get_expression
= 0;
4201 if (ep
->X_op
== O_illegal
)
4203 /* We found a bad expression in md_operand(). */
4204 *str
= input_line_pointer
;
4205 input_line_pointer
= save_in
;
4210 if (seg
!= absolute_section
4211 && seg
!= text_section
4212 && seg
!= data_section
4213 && seg
!= bss_section
4214 && seg
!= undefined_section
)
4216 inst
.error
= _("bad_segment");
4217 *str
= input_line_pointer
;
4218 input_line_pointer
= save_in
;
4223 /* Get rid of any bignums now, so that we don't generate an error for which
4224 we can't establish a line number later on. Big numbers are never valid
4225 in instructions, which is where this routine is always called. */
4226 if (ep
->X_op
== O_big
4227 || (ep
->X_add_symbol
4228 && (walk_no_bignums (ep
->X_add_symbol
)
4230 && walk_no_bignums (ep
->X_op_symbol
)))))
4232 inst
.error
= _("invalid constant");
4233 *str
= input_line_pointer
;
4234 input_line_pointer
= save_in
;
4238 *str
= input_line_pointer
;
4239 input_line_pointer
= save_in
;
4243 /* We handle all bad expressions here, so that we can report the faulty
4244 instruction in the error message. */
4249 if (in_my_get_expression
)
4251 expr
->X_op
= O_illegal
;
4252 if (inst
.error
== NULL
)
4253 inst
.error
= _("bad expression");
4257 /* UNRESTRICT should be one if <shift> <register> is permitted for this
4261 decode_shift (str
, unrestrict
)
4265 const struct asm_shift_name
* shift
;
4269 skip_whitespace (* str
);
4271 for (p
= * str
; ISALPHA (* p
); p
++)
4276 inst
.error
= _("shift expression expected");
4282 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
4287 inst
.error
= _("shift expression expected");
4291 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
4293 if (shift
->properties
->index
== SHIFT_RRX
)
4296 inst
.instruction
|= shift
->properties
->bit_field
;
4300 skip_whitespace (p
);
4302 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
4304 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
4308 else if (! is_immediate_prefix (* p
))
4310 inst
.error
= (unrestrict
4311 ? _("shift requires register or #expression")
4312 : _("shift requires #expression"));
4320 if (my_get_expression (& inst
.reloc
.exp
, & p
))
4323 /* Validate some simple #expressions. */
4324 if (inst
.reloc
.exp
.X_op
== O_constant
)
4326 unsigned num
= inst
.reloc
.exp
.X_add_number
;
4328 /* Reject operations greater than 32. */
4330 /* Reject a shift of 0 unless the mode allows it. */
4331 || (num
== 0 && shift
->properties
->allows_0
== 0)
4332 /* Reject a shift of 32 unless the mode allows it. */
4333 || (num
== 32 && shift
->properties
->allows_32
== 0)
4336 /* As a special case we allow a shift of zero for
4337 modes that do not support it to be recoded as an
4338 logical shift left of zero (ie nothing). We warn
4339 about this though. */
4342 as_warn (_("shift of 0 ignored."));
4343 shift
= & shift_names
[0];
4344 assert (shift
->properties
->index
== SHIFT_LSL
);
4348 inst
.error
= _("invalid immediate shift");
4353 /* Shifts of 32 are encoded as 0, for those shifts that
4358 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
4362 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
4363 inst
.reloc
.pc_rel
= 0;
4364 inst
.instruction
|= shift
->properties
->bit_field
;
4371 /* Do those data_ops which can take a negative immediate constant
4372 by altering the instuction. A bit of a hack really.
4376 by inverting the second operand, and
4379 by negating the second operand. */
4382 negate_data_op (instruction
, value
)
4383 unsigned long * instruction
;
4384 unsigned long value
;
4387 unsigned long negated
, inverted
;
4389 negated
= validate_immediate (-value
);
4390 inverted
= validate_immediate (~value
);
4392 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
4395 /* First negates. */
4396 case OPCODE_SUB
: /* ADD <-> SUB */
4397 new_inst
= OPCODE_ADD
;
4402 new_inst
= OPCODE_SUB
;
4406 case OPCODE_CMP
: /* CMP <-> CMN */
4407 new_inst
= OPCODE_CMN
;
4412 new_inst
= OPCODE_CMP
;
4416 /* Now Inverted ops. */
4417 case OPCODE_MOV
: /* MOV <-> MVN */
4418 new_inst
= OPCODE_MVN
;
4423 new_inst
= OPCODE_MOV
;
4427 case OPCODE_AND
: /* AND <-> BIC */
4428 new_inst
= OPCODE_BIC
;
4433 new_inst
= OPCODE_AND
;
4437 case OPCODE_ADC
: /* ADC <-> SBC */
4438 new_inst
= OPCODE_SBC
;
4443 new_inst
= OPCODE_ADC
;
4447 /* We cannot do anything. */
4452 if (value
== (unsigned) FAIL
)
4455 *instruction
&= OPCODE_MASK
;
4456 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
4467 skip_whitespace (* str
);
4469 if (reg_required_here (str
, 0) != FAIL
)
4471 if (skip_past_comma (str
) == SUCCESS
)
4472 /* Shift operation on register. */
4473 return decode_shift (str
, NO_SHIFT_RESTRICT
);
4479 /* Immediate expression. */
4480 if (is_immediate_prefix (**str
))
4485 if (my_get_expression (&inst
.reloc
.exp
, str
))
4488 if (inst
.reloc
.exp
.X_add_symbol
)
4490 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4491 inst
.reloc
.pc_rel
= 0;
4495 if (skip_past_comma (str
) == SUCCESS
)
4497 /* #x, y -- ie explicit rotation by Y. */
4498 if (my_get_expression (&expr
, str
))
4501 if (expr
.X_op
!= O_constant
)
4503 inst
.error
= _("constant expression expected");
4507 /* Rotate must be a multiple of 2. */
4508 if (((unsigned) expr
.X_add_number
) > 30
4509 || (expr
.X_add_number
& 1) != 0
4510 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
4512 inst
.error
= _("invalid constant");
4515 inst
.instruction
|= INST_IMMEDIATE
;
4516 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4517 inst
.instruction
|= expr
.X_add_number
<< 7;
4521 /* Implicit rotation, select a suitable one. */
4522 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4526 /* Can't be done. Perhaps the code reads something like
4527 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
4528 if ((value
= negate_data_op (&inst
.instruction
,
4529 inst
.reloc
.exp
.X_add_number
))
4532 inst
.error
= _("invalid constant");
4537 inst
.instruction
|= value
;
4540 inst
.instruction
|= INST_IMMEDIATE
;
4545 inst
.error
= _("register or shift expression expected");
4554 skip_whitespace (* str
);
4556 if (fp_reg_required_here (str
, 0) != FAIL
)
4560 /* Immediate expression. */
4561 if (*((*str
)++) == '#')
4567 skip_whitespace (* str
);
4569 /* First try and match exact strings, this is to guarantee
4570 that some formats will work even for cross assembly. */
4572 for (i
= 0; fp_const
[i
]; i
++)
4574 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
4578 *str
+= strlen (fp_const
[i
]);
4579 if (is_end_of_line
[(unsigned char) **str
])
4581 inst
.instruction
|= i
+ 8;
4588 /* Just because we didn't get a match doesn't mean that the
4589 constant isn't valid, just that it is in a format that we
4590 don't automatically recognize. Try parsing it with
4591 the standard expression routines. */
4592 if ((i
= my_get_float_expression (str
)) >= 0)
4594 inst
.instruction
|= i
+ 8;
4598 inst
.error
= _("invalid floating point immediate expression");
4602 _("floating point register or immediate expression expected");
4611 skip_whitespace (str
);
4613 if (reg_required_here (&str
, 12) == FAIL
4614 || skip_past_comma (&str
) == FAIL
4615 || reg_required_here (&str
, 16) == FAIL
4616 || skip_past_comma (&str
) == FAIL
4617 || data_op2 (&str
) == FAIL
)
4620 inst
.error
= BAD_ARGS
;
4632 /* This is a pseudo-op of the form "adr rd, label" to be converted
4633 into a relative address of the form "add rd, pc, #label-.-8". */
4634 skip_whitespace (str
);
4636 if (reg_required_here (&str
, 12) == FAIL
4637 || skip_past_comma (&str
) == FAIL
4638 || my_get_expression (&inst
.reloc
.exp
, &str
))
4641 inst
.error
= BAD_ARGS
;
4645 /* Frag hacking will turn this into a sub instruction if the offset turns
4646 out to be negative. */
4647 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4648 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
4649 inst
.reloc
.pc_rel
= 1;
4658 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4659 into a relative address of the form:
4660 add rd, pc, #low(label-.-8)"
4661 add rd, rd, #high(label-.-8)" */
4663 skip_whitespace (str
);
4665 if (reg_required_here (&str
, 12) == FAIL
4666 || skip_past_comma (&str
) == FAIL
4667 || my_get_expression (&inst
.reloc
.exp
, &str
))
4670 inst
.error
= BAD_ARGS
;
4676 /* Frag hacking will turn this into a sub instruction if the offset turns
4677 out to be negative. */
4678 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
4679 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
4680 inst
.reloc
.pc_rel
= 1;
4681 inst
.size
= INSN_SIZE
* 2;
4690 skip_whitespace (str
);
4692 if (reg_required_here (&str
, 16) == FAIL
)
4695 inst
.error
= BAD_ARGS
;
4699 if (skip_past_comma (&str
) == FAIL
4700 || data_op2 (&str
) == FAIL
)
4703 inst
.error
= BAD_ARGS
;
4715 skip_whitespace (str
);
4717 if (reg_required_here (&str
, 12) == FAIL
)
4720 inst
.error
= BAD_ARGS
;
4724 if (skip_past_comma (&str
) == FAIL
4725 || data_op2 (&str
) == FAIL
)
4728 inst
.error
= BAD_ARGS
;
4747 if (my_get_expression (& inst
.reloc
.exp
, str
))
4750 if (inst
.reloc
.exp
.X_op
== O_constant
)
4752 int value
= inst
.reloc
.exp
.X_add_number
;
4754 if (value
< -4095 || value
> 4095)
4756 inst
.error
= _("address offset too large");
4766 inst
.instruction
|= add
| value
;
4770 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4771 inst
.reloc
.pc_rel
= 0;
4784 if (reg_required_here (str
, 0) == FAIL
)
4787 inst
.instruction
|= add
| OFFSET_REG
;
4788 if (skip_past_comma (str
) == SUCCESS
)
4789 return decode_shift (str
, SHIFT_RESTRICT
);
4803 skip_whitespace (str
);
4805 if ((conflict_reg
= reg_required_here (&str
, 12)) == FAIL
)
4808 inst
.error
= BAD_ARGS
;
4812 if (skip_past_comma (&str
) == FAIL
)
4814 inst
.error
= _("address expected");
4824 skip_whitespace (str
);
4826 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4829 /* Conflicts can occur on stores as well as loads. */
4830 conflict_reg
= (conflict_reg
== reg
);
4832 skip_whitespace (str
);
4838 if (skip_past_comma (&str
) == SUCCESS
)
4840 /* [Rn],... (post inc) */
4841 if (ldst_extend (&str
) == FAIL
)
4844 as_warn (_("%s register same as write-back base"),
4845 ((inst
.instruction
& LOAD_BIT
)
4846 ? _("destination") : _("source")));
4851 skip_whitespace (str
);
4856 as_warn (_("%s register same as write-back base"),
4857 ((inst
.instruction
& LOAD_BIT
)
4858 ? _("destination") : _("source")));
4860 inst
.instruction
|= WRITE_BACK
;
4863 inst
.instruction
|= INDEX_UP
;
4870 if (skip_past_comma (&str
) == FAIL
)
4872 inst
.error
= _("pre-indexed expression expected");
4877 if (ldst_extend (&str
) == FAIL
)
4880 skip_whitespace (str
);
4884 inst
.error
= _("missing ]");
4888 skip_whitespace (str
);
4893 as_warn (_("%s register same as write-back base"),
4894 ((inst
.instruction
& LOAD_BIT
)
4895 ? _("destination") : _("source")));
4897 inst
.instruction
|= WRITE_BACK
;
4901 else if (*str
== '=')
4903 if ((inst
.instruction
& LOAD_BIT
) == 0)
4905 inst
.error
= _("invalid pseudo operation");
4909 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4912 skip_whitespace (str
);
4914 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4917 if (inst
.reloc
.exp
.X_op
!= O_constant
4918 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4920 inst
.error
= _("constant expression expected");
4924 if (inst
.reloc
.exp
.X_op
== O_constant
)
4926 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4930 /* This can be done with a mov instruction. */
4931 inst
.instruction
&= LITERAL_MASK
;
4932 inst
.instruction
|= (INST_IMMEDIATE
4933 | (OPCODE_MOV
<< DATA_OP_SHIFT
));
4934 inst
.instruction
|= value
& 0xfff;
4939 value
= validate_immediate (~inst
.reloc
.exp
.X_add_number
);
4943 /* This can be done with a mvn instruction. */
4944 inst
.instruction
&= LITERAL_MASK
;
4945 inst
.instruction
|= (INST_IMMEDIATE
4946 | (OPCODE_MVN
<< DATA_OP_SHIFT
));
4947 inst
.instruction
|= value
& 0xfff;
4953 /* Insert into literal pool. */
4954 if (add_to_lit_pool () == FAIL
)
4957 inst
.error
= _("literal pool insertion failed");
4961 /* Change the instruction exp to point to the pool. */
4962 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
4963 inst
.reloc
.pc_rel
= 1;
4964 inst
.instruction
|= (REG_PC
<< 16);
4969 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4972 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4974 /* PC rel adjust. */
4975 inst
.reloc
.exp
.X_add_number
-= 8;
4977 inst
.reloc
.pc_rel
= 1;
4978 inst
.instruction
|= (REG_PC
<< 16);
4982 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
4993 skip_whitespace (str
);
4995 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
4998 inst
.error
= BAD_ARGS
;
5002 if (skip_past_comma (& str
) == FAIL
)
5004 inst
.error
= _("address expected");
5014 skip_whitespace (str
);
5016 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5019 /* ldrt/strt always use post-indexed addressing, so if the base is
5020 the same as Rd, we warn. */
5021 if (conflict_reg
== reg
)
5022 as_warn (_("%s register same as write-back base"),
5023 ((inst
.instruction
& LOAD_BIT
)
5024 ? _("destination") : _("source")));
5026 skip_whitespace (str
);
5032 if (skip_past_comma (&str
) == SUCCESS
)
5034 /* [Rn],... (post inc) */
5035 if (ldst_extend (&str
) == FAIL
)
5041 skip_whitespace (str
);
5043 /* Skip a write-back '!'. */
5047 inst
.instruction
|= INDEX_UP
;
5052 inst
.error
= _("post-indexed expression expected");
5058 inst
.error
= _("post-indexed expression expected");
5067 ldst_extend_v4 (str
)
5077 if (my_get_expression (& inst
.reloc
.exp
, str
))
5080 if (inst
.reloc
.exp
.X_op
== O_constant
)
5082 int value
= inst
.reloc
.exp
.X_add_number
;
5084 if (value
< -255 || value
> 255)
5086 inst
.error
= _("address offset too large");
5096 /* Halfword and signextension instructions have the
5097 immediate value split across bits 11..8 and bits 3..0. */
5098 inst
.instruction
|= (add
| HWOFFSET_IMM
5099 | ((value
>> 4) << 8) | (value
& 0xF));
5103 inst
.instruction
|= HWOFFSET_IMM
;
5104 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
5105 inst
.reloc
.pc_rel
= 0;
5118 if (reg_required_here (str
, 0) == FAIL
)
5121 inst
.instruction
|= add
;
5126 /* Halfword and signed-byte load/store operations. */
5135 skip_whitespace (str
);
5137 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
5140 inst
.error
= BAD_ARGS
;
5144 if (skip_past_comma (& str
) == FAIL
)
5146 inst
.error
= _("address expected");
5156 skip_whitespace (str
);
5158 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5161 /* Conflicts can occur on stores as well as loads. */
5162 conflict_reg
= (conflict_reg
== reg
);
5164 skip_whitespace (str
);
5170 if (skip_past_comma (&str
) == SUCCESS
)
5172 /* [Rn],... (post inc) */
5173 if (ldst_extend_v4 (&str
) == FAIL
)
5176 as_warn (_("%s register same as write-back base"),
5177 ((inst
.instruction
& LOAD_BIT
)
5178 ? _("destination") : _("source")));
5183 inst
.instruction
|= HWOFFSET_IMM
;
5185 skip_whitespace (str
);
5190 as_warn (_("%s register same as write-back base"),
5191 ((inst
.instruction
& LOAD_BIT
)
5192 ? _("destination") : _("source")));
5194 inst
.instruction
|= WRITE_BACK
;
5197 inst
.instruction
|= INDEX_UP
;
5204 if (skip_past_comma (&str
) == FAIL
)
5206 inst
.error
= _("pre-indexed expression expected");
5211 if (ldst_extend_v4 (&str
) == FAIL
)
5214 skip_whitespace (str
);
5218 inst
.error
= _("missing ]");
5222 skip_whitespace (str
);
5227 as_warn (_("%s register same as write-back base"),
5228 ((inst
.instruction
& LOAD_BIT
)
5229 ? _("destination") : _("source")));
5231 inst
.instruction
|= WRITE_BACK
;
5235 else if (*str
== '=')
5237 if ((inst
.instruction
& LOAD_BIT
) == 0)
5239 inst
.error
= _("invalid pseudo operation");
5243 /* XXX Does this work correctly for half-word/byte ops? */
5244 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5247 skip_whitespace (str
);
5249 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5252 if (inst
.reloc
.exp
.X_op
!= O_constant
5253 && inst
.reloc
.exp
.X_op
!= O_symbol
)
5255 inst
.error
= _("constant expression expected");
5259 if (inst
.reloc
.exp
.X_op
== O_constant
)
5261 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
5265 /* This can be done with a mov instruction. */
5266 inst
.instruction
&= LITERAL_MASK
;
5267 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
5268 inst
.instruction
|= value
& 0xfff;
5273 value
= validate_immediate (~ inst
.reloc
.exp
.X_add_number
);
5277 /* This can be done with a mvn instruction. */
5278 inst
.instruction
&= LITERAL_MASK
;
5279 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MVN
<< DATA_OP_SHIFT
);
5280 inst
.instruction
|= value
& 0xfff;
5286 /* Insert into literal pool. */
5287 if (add_to_lit_pool () == FAIL
)
5290 inst
.error
= _("literal pool insertion failed");
5294 /* Change the instruction exp to point to the pool. */
5295 inst
.instruction
|= HWOFFSET_IMM
;
5296 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
5297 inst
.reloc
.pc_rel
= 1;
5298 inst
.instruction
|= (REG_PC
<< 16);
5303 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5306 inst
.instruction
|= HWOFFSET_IMM
;
5307 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
5309 /* PC rel adjust. */
5310 inst
.reloc
.exp
.X_add_number
-= 8;
5312 inst
.reloc
.pc_rel
= 1;
5313 inst
.instruction
|= (REG_PC
<< 16);
5317 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
5326 char * str
= * strp
;
5330 /* We come back here if we get ranges concatenated by '+' or '|'. */
5345 skip_whitespace (str
);
5347 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
5356 inst
.error
= _("bad range in register list");
5360 for (i
= cur_reg
+ 1; i
< reg
; i
++)
5362 if (range
& (1 << i
))
5364 (_("Warning: duplicated register (r%d) in register list"),
5372 if (range
& (1 << reg
))
5373 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
5375 else if (reg
<= cur_reg
)
5376 as_tsktsk (_("Warning: register range not in ascending order"));
5381 while (skip_past_comma (&str
) != FAIL
5382 || (in_range
= 1, *str
++ == '-'));
5384 skip_whitespace (str
);
5388 inst
.error
= _("missing `}'");
5396 if (my_get_expression (&expr
, &str
))
5399 if (expr
.X_op
== O_constant
)
5401 if (expr
.X_add_number
5402 != (expr
.X_add_number
& 0x0000ffff))
5404 inst
.error
= _("invalid register mask");
5408 if ((range
& expr
.X_add_number
) != 0)
5410 int regno
= range
& expr
.X_add_number
;
5413 regno
= (1 << regno
) - 1;
5415 (_("Warning: duplicated register (r%d) in register list"),
5419 range
|= expr
.X_add_number
;
5423 if (inst
.reloc
.type
!= 0)
5425 inst
.error
= _("expression too complex");
5429 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
5430 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
5431 inst
.reloc
.pc_rel
= 0;
5435 skip_whitespace (str
);
5437 if (*str
== '|' || *str
== '+')
5443 while (another_range
);
5456 skip_whitespace (str
);
5458 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
5461 if (base_reg
== REG_PC
)
5463 inst
.error
= _("r15 not allowed as base register");
5467 skip_whitespace (str
);
5471 inst
.instruction
|= WRITE_BACK
;
5475 if (skip_past_comma (&str
) == FAIL
5476 || (range
= reg_list (&str
)) == FAIL
)
5479 inst
.error
= BAD_ARGS
;
5486 inst
.instruction
|= LDM_TYPE_2_OR_3
;
5489 inst
.instruction
|= range
;
5498 skip_whitespace (str
);
5500 /* Allow optional leading '#'. */
5501 if (is_immediate_prefix (*str
))
5504 if (my_get_expression (& inst
.reloc
.exp
, & str
))
5507 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
5508 inst
.reloc
.pc_rel
= 0;
5520 skip_whitespace (str
);
5522 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
5527 inst
.error
= _("r15 not allowed in swap");
5531 if (skip_past_comma (&str
) == FAIL
5532 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
5535 inst
.error
= BAD_ARGS
;
5541 inst
.error
= _("r15 not allowed in swap");
5545 if (skip_past_comma (&str
) == FAIL
5548 inst
.error
= BAD_ARGS
;
5552 skip_whitespace (str
);
5554 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5559 inst
.error
= BAD_PC
;
5563 skip_whitespace (str
);
5567 inst
.error
= _("missing ]");
5579 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5586 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
5587 required for the instruction. */
5589 /* arm_parse_reloc () works on input_line_pointer.
5590 We actually want to parse the operands to the branch instruction
5591 passed in 'str'. Save the input pointer and restore it later. */
5592 save_in
= input_line_pointer
;
5593 input_line_pointer
= str
;
5594 if (inst
.reloc
.exp
.X_op
== O_symbol
5596 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
5598 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
5599 inst
.reloc
.pc_rel
= 0;
5600 /* Modify str to point to after parsed operands, otherwise
5601 end_of_line() will complain about the (PLT) left in str. */
5602 str
= input_line_pointer
;
5606 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
5607 inst
.reloc
.pc_rel
= 1;
5609 input_line_pointer
= save_in
;
5612 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
5613 inst
.reloc
.pc_rel
= 1;
5614 #endif /* OBJ_ELF */
5626 skip_whitespace (str
);
5628 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
5630 inst
.error
= BAD_ARGS
;
5634 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
5636 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
5645 /* Co-processor data operation.
5646 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
5647 skip_whitespace (str
);
5649 if (co_proc_number (&str
) == FAIL
)
5652 inst
.error
= BAD_ARGS
;
5656 if (skip_past_comma (&str
) == FAIL
5657 || cp_opc_expr (&str
, 20,4) == FAIL
)
5660 inst
.error
= BAD_ARGS
;
5664 if (skip_past_comma (&str
) == FAIL
5665 || cp_reg_required_here (&str
, 12) == FAIL
)
5668 inst
.error
= BAD_ARGS
;
5672 if (skip_past_comma (&str
) == FAIL
5673 || cp_reg_required_here (&str
, 16) == FAIL
)
5676 inst
.error
= BAD_ARGS
;
5680 if (skip_past_comma (&str
) == FAIL
5681 || cp_reg_required_here (&str
, 0) == FAIL
)
5684 inst
.error
= BAD_ARGS
;
5688 if (skip_past_comma (&str
) == SUCCESS
)
5690 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5693 inst
.error
= BAD_ARGS
;
5706 /* Co-processor register load/store.
5707 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
5709 skip_whitespace (str
);
5711 if (co_proc_number (&str
) == FAIL
)
5714 inst
.error
= BAD_ARGS
;
5718 if (skip_past_comma (&str
) == FAIL
5719 || cp_reg_required_here (&str
, 12) == FAIL
)
5722 inst
.error
= BAD_ARGS
;
5726 if (skip_past_comma (&str
) == FAIL
5727 || cp_address_required_here (&str
) == FAIL
)
5730 inst
.error
= BAD_ARGS
;
5742 /* Co-processor register transfer.
5743 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
5745 skip_whitespace (str
);
5747 if (co_proc_number (&str
) == FAIL
)
5750 inst
.error
= BAD_ARGS
;
5754 if (skip_past_comma (&str
) == FAIL
5755 || cp_opc_expr (&str
, 21, 3) == FAIL
)
5758 inst
.error
= BAD_ARGS
;
5762 if (skip_past_comma (&str
) == FAIL
5763 || reg_required_here (&str
, 12) == FAIL
)
5766 inst
.error
= BAD_ARGS
;
5770 if (skip_past_comma (&str
) == FAIL
5771 || cp_reg_required_here (&str
, 16) == FAIL
)
5774 inst
.error
= BAD_ARGS
;
5778 if (skip_past_comma (&str
) == FAIL
5779 || cp_reg_required_here (&str
, 0) == FAIL
)
5782 inst
.error
= BAD_ARGS
;
5786 if (skip_past_comma (&str
) == SUCCESS
)
5788 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5791 inst
.error
= BAD_ARGS
;
5804 /* FP control registers.
5805 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
5807 skip_whitespace (str
);
5809 if (reg_required_here (&str
, 12) == FAIL
)
5812 inst
.error
= BAD_ARGS
;
5824 skip_whitespace (str
);
5826 if (fp_reg_required_here (&str
, 12) == FAIL
)
5829 inst
.error
= BAD_ARGS
;
5833 if (skip_past_comma (&str
) == FAIL
5834 || cp_address_required_here (&str
) == FAIL
)
5837 inst
.error
= BAD_ARGS
;
5850 skip_whitespace (str
);
5852 if (fp_reg_required_here (&str
, 12) == FAIL
)
5855 inst
.error
= BAD_ARGS
;
5859 /* Get Number of registers to transfer. */
5860 if (skip_past_comma (&str
) == FAIL
5861 || my_get_expression (&inst
.reloc
.exp
, &str
))
5864 inst
.error
= _("constant expression expected");
5868 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5870 inst
.error
= _("constant value required for number of registers");
5874 num_regs
= inst
.reloc
.exp
.X_add_number
;
5876 if (num_regs
< 1 || num_regs
> 4)
5878 inst
.error
= _("number of registers must be in the range [1:4]");
5885 inst
.instruction
|= CP_T_X
;
5888 inst
.instruction
|= CP_T_Y
;
5891 inst
.instruction
|= CP_T_Y
| CP_T_X
;
5899 if (inst
.instruction
& (CP_T_Pre
| CP_T_UD
)) /* ea/fd format. */
5905 /* The instruction specified "ea" or "fd", so we can only accept
5906 [Rn]{!}. The instruction does not really support stacking or
5907 unstacking, so we have to emulate these by setting appropriate
5908 bits and offsets. */
5909 if (skip_past_comma (&str
) == FAIL
5913 inst
.error
= BAD_ARGS
;
5918 skip_whitespace (str
);
5920 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5923 skip_whitespace (str
);
5927 inst
.error
= BAD_ARGS
;
5939 _("r15 not allowed as base register with write-back");
5946 if (inst
.instruction
& CP_T_Pre
)
5948 /* Pre-decrement. */
5949 offset
= 3 * num_regs
;
5951 inst
.instruction
|= CP_T_WB
;
5955 /* Post-increment. */
5958 inst
.instruction
|= CP_T_WB
;
5959 offset
= 3 * num_regs
;
5963 /* No write-back, so convert this into a standard pre-increment
5964 instruction -- aesthetically more pleasing. */
5965 inst
.instruction
|= CP_T_Pre
| CP_T_UD
;
5970 inst
.instruction
|= offset
;
5972 else if (skip_past_comma (&str
) == FAIL
5973 || cp_address_required_here (&str
) == FAIL
)
5976 inst
.error
= BAD_ARGS
;
5987 skip_whitespace (str
);
5989 if (fp_reg_required_here (&str
, 12) == FAIL
)
5992 inst
.error
= BAD_ARGS
;
5996 if (skip_past_comma (&str
) == FAIL
5997 || fp_reg_required_here (&str
, 16) == FAIL
)
6000 inst
.error
= BAD_ARGS
;
6004 if (skip_past_comma (&str
) == FAIL
6005 || fp_op2 (&str
) == FAIL
)
6008 inst
.error
= BAD_ARGS
;
6017 do_fpa_monadic (str
)
6020 skip_whitespace (str
);
6022 if (fp_reg_required_here (&str
, 12) == FAIL
)
6025 inst
.error
= BAD_ARGS
;
6029 if (skip_past_comma (&str
) == FAIL
6030 || fp_op2 (&str
) == FAIL
)
6033 inst
.error
= BAD_ARGS
;
6045 skip_whitespace (str
);
6047 if (fp_reg_required_here (&str
, 16) == FAIL
)
6050 inst
.error
= BAD_ARGS
;
6054 if (skip_past_comma (&str
) == FAIL
6055 || fp_op2 (&str
) == FAIL
)
6058 inst
.error
= BAD_ARGS
;
6067 do_fpa_from_reg (str
)
6070 skip_whitespace (str
);
6072 if (fp_reg_required_here (&str
, 16) == FAIL
)
6075 inst
.error
= BAD_ARGS
;
6079 if (skip_past_comma (&str
) == FAIL
6080 || reg_required_here (&str
, 12) == FAIL
)
6083 inst
.error
= BAD_ARGS
;
6095 skip_whitespace (str
);
6097 if (reg_required_here (&str
, 12) == FAIL
)
6100 if (skip_past_comma (&str
) == FAIL
6101 || fp_reg_required_here (&str
, 0) == FAIL
)
6104 inst
.error
= BAD_ARGS
;
6112 /* Thumb specific routines. */
6114 /* Parse and validate that a register is of the right form, this saves
6115 repeated checking of this information in many similar cases.
6116 Unlike the 32-bit case we do not insert the register into the opcode
6117 here, since the position is often unknown until the full instruction
6121 thumb_reg (strp
, hi_lo
)
6127 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
6135 inst
.error
= _("lo register required");
6143 inst
.error
= _("hi register required");
6155 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
6159 thumb_add_sub (str
, subtract
)
6163 int Rd
, Rs
, Rn
= FAIL
;
6165 skip_whitespace (str
);
6167 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
6168 || skip_past_comma (&str
) == FAIL
)
6171 inst
.error
= BAD_ARGS
;
6175 if (is_immediate_prefix (*str
))
6179 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6184 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6187 if (skip_past_comma (&str
) == FAIL
)
6189 /* Two operand format, shuffle the registers
6190 and pretend there are 3. */
6194 else if (is_immediate_prefix (*str
))
6197 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6200 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6204 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
6205 for the latter case, EXPR contains the immediate that was found. */
6208 /* All register format. */
6209 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
6213 inst
.error
= _("dest and source1 must be the same register");
6217 /* Can't do this for SUB. */
6220 inst
.error
= _("subtract valid only on lo regs");
6224 inst
.instruction
= (T_OPCODE_ADD_HI
6225 | (Rd
> 7 ? THUMB_H1
: 0)
6226 | (Rn
> 7 ? THUMB_H2
: 0));
6227 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
6231 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
6232 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
6237 /* Immediate expression, now things start to get nasty. */
6239 /* First deal with HI regs, only very restricted cases allowed:
6240 Adjusting SP, and using PC or SP to get an address. */
6241 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
6242 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
6244 inst
.error
= _("invalid Hi register with immediate");
6248 if (inst
.reloc
.exp
.X_op
!= O_constant
)
6250 /* Value isn't known yet, all we can do is store all the fragments
6251 we know about in the instruction and let the reloc hacking
6253 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
6254 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
6258 int offset
= inst
.reloc
.exp
.X_add_number
;
6268 /* Quick check, in case offset is MIN_INT. */
6271 inst
.error
= _("immediate value out of range");
6280 if (offset
& ~0x1fc)
6282 inst
.error
= _("invalid immediate value for stack adjust");
6285 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
6286 inst
.instruction
|= offset
>> 2;
6288 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
6291 || (offset
& ~0x3fc))
6293 inst
.error
= _("invalid immediate for address calculation");
6296 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
6298 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
6304 inst
.error
= _("immediate value out of range");
6307 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
6308 inst
.instruction
|= (Rd
<< 8) | offset
;
6314 inst
.error
= _("immediate value out of range");
6317 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
6318 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
6327 thumb_shift (str
, shift
)
6331 int Rd
, Rs
, Rn
= FAIL
;
6333 skip_whitespace (str
);
6335 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6336 || skip_past_comma (&str
) == FAIL
)
6339 inst
.error
= BAD_ARGS
;
6343 if (is_immediate_prefix (*str
))
6345 /* Two operand immediate format, set Rs to Rd. */
6348 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6353 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6356 if (skip_past_comma (&str
) == FAIL
)
6358 /* Two operand format, shuffle the registers
6359 and pretend there are 3. */
6363 else if (is_immediate_prefix (*str
))
6366 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6369 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6373 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
6374 for the latter case, EXPR contains the immediate that was found. */
6380 inst
.error
= _("source1 and dest must be same register");
6386 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
6387 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
6388 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
6391 inst
.instruction
|= Rd
| (Rn
<< 3);
6397 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
6398 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
6399 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
6402 if (inst
.reloc
.exp
.X_op
!= O_constant
)
6404 /* Value isn't known yet, create a dummy reloc and let reloc
6405 hacking fix it up. */
6406 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
6410 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
6412 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
6414 inst
.error
= _("invalid immediate for shift");
6418 /* Shifts of zero are handled by converting to LSL. */
6419 if (shift_value
== 0)
6420 inst
.instruction
= T_OPCODE_LSL_I
;
6422 /* Shifts of 32 are encoded as a shift of zero. */
6423 if (shift_value
== 32)
6426 inst
.instruction
|= shift_value
<< 6;
6429 inst
.instruction
|= Rd
| (Rs
<< 3);
6436 thumb_mov_compare (str
, move
)
6442 skip_whitespace (str
);
6444 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
6445 || skip_past_comma (&str
) == FAIL
)
6448 inst
.error
= BAD_ARGS
;
6452 if (is_immediate_prefix (*str
))
6455 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6458 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6463 if (Rs
< 8 && Rd
< 8)
6465 if (move
== THUMB_MOVE
)
6466 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
6467 since a MOV instruction produces unpredictable results. */
6468 inst
.instruction
= T_OPCODE_ADD_I3
;
6470 inst
.instruction
= T_OPCODE_CMP_LR
;
6471 inst
.instruction
|= Rd
| (Rs
<< 3);
6475 if (move
== THUMB_MOVE
)
6476 inst
.instruction
= T_OPCODE_MOV_HR
;
6478 inst
.instruction
= T_OPCODE_CMP_HR
;
6481 inst
.instruction
|= THUMB_H1
;
6484 inst
.instruction
|= THUMB_H2
;
6486 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
6493 inst
.error
= _("only lo regs allowed with immediate");
6497 if (move
== THUMB_MOVE
)
6498 inst
.instruction
= T_OPCODE_MOV_I8
;
6500 inst
.instruction
= T_OPCODE_CMP_I8
;
6502 inst
.instruction
|= Rd
<< 8;
6504 if (inst
.reloc
.exp
.X_op
!= O_constant
)
6505 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
6508 unsigned value
= inst
.reloc
.exp
.X_add_number
;
6512 inst
.error
= _("invalid immediate");
6516 inst
.instruction
|= value
;
6524 thumb_load_store (str
, load_store
, size
)
6529 int Rd
, Rb
, Ro
= FAIL
;
6531 skip_whitespace (str
);
6533 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6534 || skip_past_comma (&str
) == FAIL
)
6537 inst
.error
= BAD_ARGS
;
6544 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6547 if (skip_past_comma (&str
) != FAIL
)
6549 if (is_immediate_prefix (*str
))
6552 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6555 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6560 inst
.reloc
.exp
.X_op
= O_constant
;
6561 inst
.reloc
.exp
.X_add_number
= 0;
6566 inst
.error
= _("expected ']'");
6571 else if (*str
== '=')
6573 if (load_store
!= THUMB_LOAD
)
6575 inst
.error
= _("invalid pseudo operation");
6579 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6582 skip_whitespace (str
);
6584 if (my_get_expression (& inst
.reloc
.exp
, & str
))
6589 if ( inst
.reloc
.exp
.X_op
!= O_constant
6590 && inst
.reloc
.exp
.X_op
!= O_symbol
)
6592 inst
.error
= "Constant expression expected";
6596 if (inst
.reloc
.exp
.X_op
== O_constant
6597 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
6599 /* This can be done with a mov instruction. */
6601 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
6602 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
6606 /* Insert into literal pool. */
6607 if (add_to_lit_pool () == FAIL
)
6610 inst
.error
= "literal pool insertion failed";
6614 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6615 inst
.reloc
.pc_rel
= 1;
6616 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
6617 /* Adjust ARM pipeline offset to Thumb. */
6618 inst
.reloc
.exp
.X_add_number
+= 4;
6624 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6627 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
6628 inst
.reloc
.pc_rel
= 1;
6629 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
6630 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6635 if (Rb
== REG_PC
|| Rb
== REG_SP
)
6637 if (size
!= THUMB_WORD
)
6639 inst
.error
= _("byte or halfword not valid for base register");
6642 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
6644 inst
.error
= _("r15 based store not allowed");
6647 else if (Ro
!= FAIL
)
6649 inst
.error
= _("invalid base register for register offset");
6654 inst
.instruction
= T_OPCODE_LDR_PC
;
6655 else if (load_store
== THUMB_LOAD
)
6656 inst
.instruction
= T_OPCODE_LDR_SP
;
6658 inst
.instruction
= T_OPCODE_STR_SP
;
6660 inst
.instruction
|= Rd
<< 8;
6661 if (inst
.reloc
.exp
.X_op
== O_constant
)
6663 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
6665 if (offset
& ~0x3fc)
6667 inst
.error
= _("invalid offset");
6671 inst
.instruction
|= offset
>> 2;
6674 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6678 inst
.error
= _("invalid base register in load/store");
6681 else if (Ro
== FAIL
)
6683 /* Immediate offset. */
6684 if (size
== THUMB_WORD
)
6685 inst
.instruction
= (load_store
== THUMB_LOAD
6686 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
6687 else if (size
== THUMB_HALFWORD
)
6688 inst
.instruction
= (load_store
== THUMB_LOAD
6689 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
6691 inst
.instruction
= (load_store
== THUMB_LOAD
6692 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
6694 inst
.instruction
|= Rd
| (Rb
<< 3);
6696 if (inst
.reloc
.exp
.X_op
== O_constant
)
6698 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
6700 if (offset
& ~(0x1f << size
))
6702 inst
.error
= _("invalid offset");
6705 inst
.instruction
|= (offset
>> size
) << 6;
6708 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6712 /* Register offset. */
6713 if (size
== THUMB_WORD
)
6714 inst
.instruction
= (load_store
== THUMB_LOAD
6715 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
6716 else if (size
== THUMB_HALFWORD
)
6717 inst
.instruction
= (load_store
== THUMB_LOAD
6718 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
6720 inst
.instruction
= (load_store
== THUMB_LOAD
6721 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
6723 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
6729 /* A register must be given at this point.
6731 Shift is the place to put it in inst.instruction.
6733 Restores input start point on err.
6734 Returns the reg#, or FAIL. */
6737 cirrus_reg_required_here (str
, shift
, regtype
)
6740 enum arm_reg_type regtype
;
6745 if ((reg
= arm_reg_parse (str
, all_reg_maps
[regtype
].htab
)) != FAIL
)
6748 inst
.instruction
|= reg
<< shift
;
6753 /* Restore the start point. */
6756 /* In the few cases where we might be able to accept something else
6757 this error can be overridden. */
6758 inst
.error
= _(all_reg_maps
[regtype
].expected
);
6763 /* Cirrus Instructions. */
6765 /* Wrapper functions. */
6768 do_c_binops_1a (str
)
6771 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_RN
, REG_TYPE_MVF
);
6775 do_c_binops_1b (str
)
6778 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_RN
, REG_TYPE_MVD
);
6782 do_c_binops_1c (str
)
6785 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_RN
, REG_TYPE_MVDX
);
6789 do_c_binops_1d (str
)
6792 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVF
);
6796 do_c_binops_1e (str
)
6799 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVD
);
6803 do_c_binops_1f (str
)
6806 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVF
);
6810 do_c_binops_1g (str
)
6813 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVD
);
6817 do_c_binops_1h (str
)
6820 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVFX
);
6824 do_c_binops_1i (str
)
6827 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVFX
);
6831 do_c_binops_1j (str
)
6834 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVF
, REG_TYPE_MVDX
);
6838 do_c_binops_1k (str
)
6841 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVD
, REG_TYPE_MVDX
);
6845 do_c_binops_1l (str
)
6848 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVF
);
6852 do_c_binops_1m (str
)
6855 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVD
);
6859 do_c_binops_1n (str
)
6862 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
6866 do_c_binops_1o (str
)
6869 do_c_binops (str
, CIRRUS_MODE1
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
6873 do_c_binops_2a (str
)
6876 do_c_binops (str
, CIRRUS_MODE2
, REG_TYPE_MVF
, REG_TYPE_RN
);
6880 do_c_binops_2b (str
)
6883 do_c_binops (str
, CIRRUS_MODE2
, REG_TYPE_MVD
, REG_TYPE_RN
);
6887 do_c_binops_2c (str
)
6890 do_c_binops (str
, CIRRUS_MODE2
, REG_TYPE_MVDX
, REG_TYPE_RN
);
6894 do_c_binops_3a (str
)
6897 do_c_binops (str
, CIRRUS_MODE3
, REG_TYPE_MVAX
, REG_TYPE_MVFX
);
6901 do_c_binops_3b (str
)
6904 do_c_binops (str
, CIRRUS_MODE3
, REG_TYPE_MVFX
, REG_TYPE_MVAX
);
6908 do_c_binops_3c (str
)
6911 do_c_binops (str
, CIRRUS_MODE3
, REG_TYPE_MVAX
, REG_TYPE_MVDX
);
6915 do_c_binops_3d (str
)
6918 do_c_binops (str
, CIRRUS_MODE3
, REG_TYPE_MVDX
, REG_TYPE_MVAX
);
6922 do_c_triple_4a (str
)
6925 do_c_triple (str
, CIRRUS_MODE4
, REG_TYPE_MVFX
, REG_TYPE_MVFX
, REG_TYPE_RN
);
6929 do_c_triple_4b (str
)
6932 do_c_triple (str
, CIRRUS_MODE4
, REG_TYPE_MVDX
, REG_TYPE_MVDX
, REG_TYPE_RN
);
6936 do_c_triple_5a (str
)
6939 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_RN
, REG_TYPE_MVF
, REG_TYPE_MVF
);
6943 do_c_triple_5b (str
)
6946 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_RN
, REG_TYPE_MVD
, REG_TYPE_MVD
);
6950 do_c_triple_5c (str
)
6953 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_RN
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
6957 do_c_triple_5d (str
)
6960 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_RN
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
6964 do_c_triple_5e (str
)
6967 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_MVF
, REG_TYPE_MVF
, REG_TYPE_MVF
);
6971 do_c_triple_5f (str
)
6974 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_MVD
, REG_TYPE_MVD
, REG_TYPE_MVD
);
6978 do_c_triple_5g (str
)
6981 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_MVFX
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
6985 do_c_triple_5h (str
)
6988 do_c_triple (str
, CIRRUS_MODE5
, REG_TYPE_MVDX
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
6995 do_c_quad (str
, CIRRUS_MODE6
, REG_TYPE_MVAX
, REG_TYPE_MVFX
, REG_TYPE_MVFX
,
7003 do_c_quad (str
, CIRRUS_MODE6
, REG_TYPE_MVAX
, REG_TYPE_MVAX
, REG_TYPE_MVFX
,
7007 /* cfmvsc32<cond> DSPSC,MVFX[15:0]. */
7012 skip_whitespace (str
);
7015 if (cirrus_reg_required_here (&str
, -1, REG_TYPE_DSPSC
) == FAIL
7016 || skip_past_comma (&str
) == FAIL
7017 || cirrus_reg_required_here (&str
, 16, REG_TYPE_MVFX
) == FAIL
)
7020 inst
.error
= BAD_ARGS
;
7028 /* cfmv32sc<cond> MVFX[15:0],DSPSC. */
7033 skip_whitespace (str
);
7036 if (cirrus_reg_required_here (&str
, 0, REG_TYPE_MVFX
) == FAIL
7037 || skip_past_comma (&str
) == FAIL
7038 || cirrus_reg_required_here (&str
, -1, REG_TYPE_DSPSC
) == FAIL
)
7041 inst
.error
= BAD_ARGS
;
7053 do_c_shift (str
, REG_TYPE_MVFX
, REG_TYPE_MVFX
);
7060 do_c_shift (str
, REG_TYPE_MVDX
, REG_TYPE_MVDX
);
7067 do_c_ldst (str
, REG_TYPE_MVF
);
7074 do_c_ldst (str
, REG_TYPE_MVD
);
7081 do_c_ldst (str
, REG_TYPE_MVFX
);
7088 do_c_ldst (str
, REG_TYPE_MVDX
);
7091 /* Isnsn like "foo X,Y". */
7094 do_c_binops (str
, mode
, reg0
, reg1
)
7097 enum arm_reg_type reg0
;
7098 enum arm_reg_type reg1
;
7102 shift0
= mode
& 0xff;
7103 shift1
= (mode
>> 8) & 0xff;
7105 skip_whitespace (str
);
7107 if (cirrus_reg_required_here (&str
, shift0
, reg0
) == FAIL
7108 || skip_past_comma (&str
) == FAIL
7109 || cirrus_reg_required_here (&str
, shift1
, reg1
) == FAIL
)
7112 inst
.error
= BAD_ARGS
;
7118 /* Isnsn like "foo X,Y,Z". */
7121 do_c_triple (str
, mode
, reg0
, reg1
, reg2
)
7124 enum arm_reg_type reg0
;
7125 enum arm_reg_type reg1
;
7126 enum arm_reg_type reg2
;
7128 int shift0
, shift1
, shift2
;
7130 shift0
= mode
& 0xff;
7131 shift1
= (mode
>> 8) & 0xff;
7132 shift2
= (mode
>> 16) & 0xff;
7134 skip_whitespace (str
);
7136 if (cirrus_reg_required_here (&str
, shift0
, reg0
) == FAIL
7137 || skip_past_comma (&str
) == FAIL
7138 || cirrus_reg_required_here (&str
, shift1
, reg1
) == FAIL
7139 || skip_past_comma (&str
) == FAIL
7140 || cirrus_reg_required_here (&str
, shift2
, reg2
) == FAIL
)
7143 inst
.error
= BAD_ARGS
;
7149 /* Isnsn like "foo W,X,Y,Z".
7150 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
7153 do_c_quad (str
, mode
, reg0
, reg1
, reg2
, reg3
)
7156 enum arm_reg_type reg0
;
7157 enum arm_reg_type reg1
;
7158 enum arm_reg_type reg2
;
7159 enum arm_reg_type reg3
;
7161 int shift0
, shift1
, shift2
, shift3
;
7163 shift0
= mode
& 0xff;
7164 shift1
= (mode
>> 8) & 0xff;
7165 shift2
= (mode
>> 16) & 0xff;
7166 shift3
= (mode
>> 24) & 0xff;
7168 skip_whitespace (str
);
7170 if (cirrus_reg_required_here (&str
, shift0
, reg0
) == FAIL
7171 || skip_past_comma (&str
) == FAIL
7172 || cirrus_reg_required_here (&str
, shift1
, reg1
) == FAIL
7173 || skip_past_comma (&str
) == FAIL
7174 || cirrus_reg_required_here (&str
, shift2
, reg2
) == FAIL
7175 || skip_past_comma (&str
) == FAIL
7176 || cirrus_reg_required_here (&str
, shift3
, reg3
) == FAIL
)
7179 inst
.error
= BAD_ARGS
;
7185 /* Cirrus shift immediate instructions.
7186 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
7187 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
7190 do_c_shift (str
, reg0
, reg1
)
7192 enum arm_reg_type reg0
;
7193 enum arm_reg_type reg1
;
7198 skip_whitespace (str
);
7202 if (cirrus_reg_required_here (&str
, 12, reg0
) == FAIL
7203 || skip_past_comma (&str
) == FAIL
7204 || cirrus_reg_required_here (&str
, 16, reg1
) == FAIL
7205 || skip_past_comma (&str
) == FAIL
)
7208 inst
.error
= BAD_ARGS
;
7212 /* Calculate the immediate operand.
7213 The operand is a 7bit signed number. */
7214 skip_whitespace (str
);
7219 if (!ISDIGIT (*str
) && *str
!= '-')
7221 inst
.error
= _("expecting immediate, 7bit operand");
7231 for (imm
= 0; *str
&& ISDIGIT (*str
); ++str
)
7232 imm
= imm
* 10 + *str
- '0';
7236 inst
.error
= _("immediate out of range");
7240 /* Make negative imm's into 7bit signed numbers. */
7247 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
7248 Bits 5-7 of the insn should have bits 4-6 of the immediate.
7249 Bit 4 should be 0. */
7250 imm
= (imm
& 0xf) | ((imm
& 0x70) << 1);
7252 inst
.instruction
|= imm
;
7257 cirrus_parse_offset (str
, negative
)
7266 skip_whitespace (p
);
7279 inst
.error
= _("offset expected");
7283 for (offset
= 0; *p
&& ISDIGIT (*p
); ++p
)
7284 offset
= offset
* 10 + *p
- '0';
7288 inst
.error
= _("offset out of range");
7294 return *negative
? -offset
: offset
;
7297 /* Cirrus load/store instructions.
7298 <insn><cond> CRd,[Rn,<offset>]{!}.
7299 <insn><cond> CRd,[Rn],<offset>. */
7302 do_c_ldst (str
, reg0
)
7304 enum arm_reg_type reg0
;
7306 int offset
, negative
;
7308 skip_whitespace (str
);
7310 if (cirrus_reg_required_here (&str
, 12, reg0
) == FAIL
7311 || skip_past_comma (&str
) == FAIL
7313 || reg_required_here (&str
, 16) == FAIL
)
7316 if (skip_past_comma (&str
) == SUCCESS
)
7318 /* You are here: "<offset>]{!}". */
7319 inst
.instruction
|= PRE_INDEX
;
7321 offset
= cirrus_parse_offset (&str
, &negative
);
7328 inst
.error
= _("missing ]");
7334 inst
.instruction
|= WRITE_BACK
;
7340 /* You are here: "], <offset>". */
7343 inst
.error
= _("missing ]");
7347 if (skip_past_comma (&str
) == FAIL
7348 || (offset
= cirrus_parse_offset (&str
, &negative
), inst
.error
))
7351 inst
.instruction
|= CP_T_WB
; /* Post indexed, set bit W. */
7357 inst
.instruction
|= CP_T_UD
; /* Postive, so set bit U. */
7359 inst
.instruction
|= offset
>> 2;
7365 inst
.error
= BAD_ARGS
;
7378 /* Handle the Format 4 instructions that do not have equivalents in other
7379 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
7388 skip_whitespace (str
);
7390 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7391 || skip_past_comma (&str
) == FAIL
7392 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7394 inst
.error
= BAD_ARGS
;
7398 if (skip_past_comma (&str
) != FAIL
)
7400 /* Three operand format not allowed for TST, CMN, NEG and MVN.
7401 (It isn't allowed for CMP either, but that isn't handled by this
7403 if (inst
.instruction
== T_OPCODE_TST
7404 || inst
.instruction
== T_OPCODE_CMN
7405 || inst
.instruction
== T_OPCODE_NEG
7406 || inst
.instruction
== T_OPCODE_MVN
)
7408 inst
.error
= BAD_ARGS
;
7412 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7417 inst
.error
= _("dest and source1 must be the same register");
7423 if (inst
.instruction
== T_OPCODE_MUL
7425 as_tsktsk (_("Rs and Rd must be different in MUL"));
7427 inst
.instruction
|= Rd
| (Rs
<< 3);
7435 thumb_add_sub (str
, 0);
7442 thumb_shift (str
, THUMB_ASR
);
7449 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7451 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
7452 inst
.reloc
.pc_rel
= 1;
7460 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7462 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
7463 inst
.reloc
.pc_rel
= 1;
7467 /* Find the real, Thumb encoded start of a Thumb function. */
7470 find_real_start (symbolP
)
7474 const char * name
= S_GET_NAME (symbolP
);
7475 symbolS
* new_target
;
7477 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
7478 #define STUB_NAME ".real_start_of"
7483 /* Names that start with '.' are local labels, not function entry points.
7484 The compiler may generate BL instructions to these labels because it
7485 needs to perform a branch to a far away location. */
7489 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
7490 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
7492 new_target
= symbol_find (real_start
);
7494 if (new_target
== NULL
)
7496 as_warn ("Failed to find real start of function: %s\n", name
);
7497 new_target
= symbolP
;
7509 if (my_get_expression (& inst
.reloc
.exp
, & str
))
7512 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
7513 inst
.reloc
.pc_rel
= 1;
7516 /* If the destination of the branch is a defined symbol which does not have
7517 the THUMB_FUNC attribute, then we must be calling a function which has
7518 the (interfacearm) attribute. We look for the Thumb entry point to that
7519 function and change the branch to refer to that function instead. */
7520 if ( inst
.reloc
.exp
.X_op
== O_symbol
7521 && inst
.reloc
.exp
.X_add_symbol
!= NULL
7522 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
7523 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
7524 inst
.reloc
.exp
.X_add_symbol
=
7525 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
7534 skip_whitespace (str
);
7536 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
7539 /* This sets THUMB_H2 from the top bit of reg. */
7540 inst
.instruction
|= reg
<< 3;
7542 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
7543 should cause the alignment to be checked once it is known. This is
7544 because BX PC only works if the instruction is word aligned. */
7553 thumb_mov_compare (str
, THUMB_COMPARE
);
7563 skip_whitespace (str
);
7565 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
7569 as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
7573 if (skip_past_comma (&str
) == FAIL
7574 || (range
= reg_list (&str
)) == FAIL
)
7577 inst
.error
= BAD_ARGS
;
7581 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
7583 /* This really doesn't seem worth it. */
7584 inst
.reloc
.type
= BFD_RELOC_NONE
;
7585 inst
.error
= _("expression too complex");
7591 inst
.error
= _("only lo-regs valid in load/store multiple");
7595 inst
.instruction
|= (Rb
<< 8) | range
;
7603 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
7610 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
7617 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
7626 skip_whitespace (str
);
7628 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7629 || skip_past_comma (&str
) == FAIL
7631 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7632 || skip_past_comma (&str
) == FAIL
7633 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7637 inst
.error
= _("syntax: ldrs[b] Rd, [Rb, Ro]");
7641 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
7649 thumb_shift (str
, THUMB_LSL
);
7656 thumb_shift (str
, THUMB_LSR
);
7663 thumb_mov_compare (str
, THUMB_MOVE
);
7672 skip_whitespace (str
);
7674 if ((range
= reg_list (&str
)) == FAIL
)
7677 inst
.error
= BAD_ARGS
;
7681 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
7683 /* This really doesn't seem worth it. */
7684 inst
.reloc
.type
= BFD_RELOC_NONE
;
7685 inst
.error
= _("expression too complex");
7691 if ((inst
.instruction
== T_OPCODE_PUSH
7692 && (range
& ~0xff) == 1 << REG_LR
)
7693 || (inst
.instruction
== T_OPCODE_POP
7694 && (range
& ~0xff) == 1 << REG_PC
))
7696 inst
.instruction
|= THUMB_PP_PC_LR
;
7701 inst
.error
= _("invalid register list to push/pop instruction");
7706 inst
.instruction
|= range
;
7714 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
7721 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
7728 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
7735 thumb_add_sub (str
, 1);
7742 skip_whitespace (str
);
7744 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7747 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
7758 /* This is a pseudo-op of the form "adr rd, label" to be converted
7759 into a relative address of the form "add rd, pc, #label-.-4". */
7760 skip_whitespace (str
);
7762 /* Store Rd in temporary location inside instruction. */
7763 if ((reg
= reg_required_here (&str
, 4)) == FAIL
7764 || (reg
> 7) /* For Thumb reg must be r0..r7. */
7765 || skip_past_comma (&str
) == FAIL
7766 || my_get_expression (&inst
.reloc
.exp
, &str
))
7769 inst
.error
= BAD_ARGS
;
7773 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
7774 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
7775 inst
.reloc
.pc_rel
= 1;
7776 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
7782 insert_reg (r
, htab
)
7783 const struct reg_entry
*r
;
7784 struct hash_control
*htab
;
7786 int len
= strlen (r
->name
) + 2;
7787 char * buf
= (char *) xmalloc (len
);
7788 char * buf2
= (char *) xmalloc (len
);
7791 #ifdef REGISTER_PREFIX
7792 buf
[i
++] = REGISTER_PREFIX
;
7795 strcpy (buf
+ i
, r
->name
);
7797 for (i
= 0; buf
[i
]; i
++)
7798 buf2
[i
] = TOUPPER (buf
[i
]);
7802 hash_insert (htab
, buf
, (PTR
) r
);
7803 hash_insert (htab
, buf2
, (PTR
) r
);
7808 struct reg_map
*map
;
7810 const struct reg_entry
*r
;
7812 if ((map
->htab
= hash_new ()) == NULL
)
7813 as_fatal (_("virtual memory exhausted"));
7815 for (r
= map
->names
; r
->name
!= NULL
; r
++)
7816 insert_reg (r
, map
->htab
);
7820 insert_reg_alias (str
, regnum
, htab
)
7823 struct hash_control
*htab
;
7825 struct reg_entry
*new =
7826 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
7827 char *name
= xmalloc (strlen (str
) + 1);
7831 new->number
= regnum
;
7833 hash_insert (htab
, name
, (PTR
) new);
7836 /* Look for the .req directive. This is of the form:
7838 newname .req existing_name
7840 If we find one, or if it looks sufficiently like one that we want to
7841 handle any error here, return non-zero. Otherwise return zero. */
7843 create_register_alias (newname
, p
)
7851 skip_whitespace (q
);
7856 if (*q
&& !strncmp (q
, ".req ", 5))
7861 #ifdef IGNORE_OPCODE_CASE
7862 newname
= original_case_string
;
7864 copy_of_str
= newname
;
7867 skip_whitespace (q
);
7869 for (r
= q
; *r
!= '\0'; r
++)
7875 enum arm_reg_type new_type
, old_type
;
7880 old_type
= arm_reg_parse_any (q
);
7883 new_type
= arm_reg_parse_any (newname
);
7885 if (new_type
== REG_TYPE_MAX
)
7887 if (old_type
!= REG_TYPE_MAX
)
7889 old_regno
= arm_reg_parse (&q
, all_reg_maps
[old_type
].htab
);
7890 insert_reg_alias (newname
, old_regno
,
7891 all_reg_maps
[old_type
].htab
);
7894 as_warn (_("register '%s' does not exist\n"), q
);
7896 else if (old_type
== REG_TYPE_MAX
)
7898 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
7903 /* Do not warn about redefinitions to the same alias. */
7904 if (new_type
!= old_type
7905 || (arm_reg_parse (&q
, all_reg_maps
[old_type
].htab
)
7906 != arm_reg_parse (&q
, all_reg_maps
[new_type
].htab
)))
7907 as_warn (_("ignoring redefinition of register alias '%s'"),
7913 as_warn (_("ignoring incomplete .req pseuso op"));
7923 set_constant_flonums ()
7927 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
7928 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
7932 /* Iterate over the base tables to create the instruction patterns. */
7934 build_arm_ops_hsh ()
7938 static struct obstack insn_obstack
;
7940 obstack_begin (&insn_obstack
, 4000);
7942 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
7944 const struct asm_opcode
*insn
= insns
+ i
;
7946 if (insn
->cond_offset
!= 0)
7948 /* Insn supports conditional execution. Build the varaints
7949 and insert them in the hash table. */
7950 for (j
= 0; j
< sizeof (conds
) / sizeof (struct asm_cond
); j
++)
7952 unsigned len
= strlen (insn
->template);
7953 struct asm_opcode
*new;
7956 new = obstack_alloc (&insn_obstack
, sizeof (struct asm_opcode
));
7957 /* All condition codes are two characters. */
7958 template = obstack_alloc (&insn_obstack
, len
+ 3);
7960 strncpy (template, insn
->template, insn
->cond_offset
);
7961 strcpy (template + insn
->cond_offset
, conds
[j
].template);
7962 if (len
> insn
->cond_offset
)
7963 strcpy (template + insn
->cond_offset
+ 2,
7964 insn
->template + insn
->cond_offset
);
7965 new->template = template;
7966 new->cond_offset
= 0;
7967 new->variant
= insn
->variant
;
7968 new->parms
= insn
->parms
;
7969 new->value
= (insn
->value
& ~COND_MASK
) | conds
[j
].value
;
7971 hash_insert (arm_ops_hsh
, new->template, (PTR
) new);
7974 /* Finally, insert the unconditional insn in the table directly;
7975 no need to build a copy. */
7976 hash_insert (arm_ops_hsh
, insn
->template, (PTR
) insn
);
7986 if ( (arm_ops_hsh
= hash_new ()) == NULL
7987 || (arm_tops_hsh
= hash_new ()) == NULL
7988 || (arm_cond_hsh
= hash_new ()) == NULL
7989 || (arm_shift_hsh
= hash_new ()) == NULL
7990 || (arm_psr_hsh
= hash_new ()) == NULL
)
7991 as_fatal (_("virtual memory exhausted"));
7993 build_arm_ops_hsh ();
7994 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
7995 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
7996 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
7997 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
7998 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
7999 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
8000 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
8001 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
8003 for (i
= (int) REG_TYPE_FIRST
; i
< (int) REG_TYPE_MAX
; i
++)
8004 build_reg_hsh (all_reg_maps
+ i
);
8006 set_constant_flonums ();
8008 #if defined OBJ_COFF || defined OBJ_ELF
8010 unsigned int flags
= 0;
8012 /* Set the flags in the private structure. */
8013 if (uses_apcs_26
) flags
|= F_APCS26
;
8014 if (support_interwork
) flags
|= F_INTERWORK
;
8015 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
8016 if (pic_code
) flags
|= F_PIC
;
8017 if ((cpu_variant
& FPU_ANY
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
8019 bfd_set_private_flags (stdoutput
, flags
);
8021 /* We have run out flags in the COFF header to encode the
8022 status of ATPCS support, so instead we create a dummy,
8023 empty, debug section called .arm.atpcs. */
8028 sec
= bfd_make_section (stdoutput
, ".arm.atpcs");
8032 bfd_set_section_flags
8033 (stdoutput
, sec
, SEC_READONLY
| SEC_DEBUGGING
/* | SEC_HAS_CONTENTS */);
8034 bfd_set_section_size (stdoutput
, sec
, 0);
8035 bfd_set_section_contents (stdoutput
, sec
, NULL
, 0, 0);
8041 /* Record the CPU type as well. */
8042 switch (cpu_variant
& ARM_CPU_MASK
)
8045 mach
= bfd_mach_arm_2
;
8048 case ARM_3
: /* Also ARM_250. */
8049 mach
= bfd_mach_arm_2a
;
8052 case ARM_6
: /* Also ARM_7. */
8053 mach
= bfd_mach_arm_3
;
8057 mach
= bfd_mach_arm_4
;
8061 /* Catch special cases. */
8062 if (cpu_variant
& ARM_EXT_XSCALE
)
8063 mach
= bfd_mach_arm_XScale
;
8064 else if (cpu_variant
& ARM_EXT_V5E
)
8065 mach
= bfd_mach_arm_5TE
;
8066 else if (cpu_variant
& ARM_EXT_V5
)
8068 if (cpu_variant
& ARM_EXT_V4T
)
8069 mach
= bfd_mach_arm_5T
;
8071 mach
= bfd_mach_arm_5
;
8073 else if (cpu_variant
& ARM_EXT_V4
)
8075 if (cpu_variant
& ARM_EXT_V4T
)
8076 mach
= bfd_mach_arm_4T
;
8078 mach
= bfd_mach_arm_4
;
8080 else if (cpu_variant
& ARM_EXT_V3M
)
8081 mach
= bfd_mach_arm_3M
;
8083 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
8086 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
8087 for use in the a.out file, and stores them in the array pointed to by buf.
8088 This knows about the endian-ness of the target machine and does
8089 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
8090 2 (short) and 4 (long) Floating numbers are put out as a series of
8091 LITTLENUMS (shorts, here at least). */
8094 md_number_to_chars (buf
, val
, n
)
8099 if (target_big_endian
)
8100 number_to_chars_bigendian (buf
, val
, n
);
8102 number_to_chars_littleendian (buf
, val
, n
);
8106 md_chars_to_number (buf
, n
)
8111 unsigned char * where
= (unsigned char *) buf
;
8113 if (target_big_endian
)
8118 result
|= (*where
++ & 255);
8126 result
|= (where
[n
] & 255);
8133 /* Turn a string in input_line_pointer into a floating point constant
8134 of type TYPE, and store the appropriate bytes in *LITP. The number
8135 of LITTLENUMS emitted is stored in *SIZEP. An error message is
8136 returned, or NULL on OK.
8138 Note that fp constants aren't represent in the normal way on the ARM.
8139 In big endian mode, things are as expected. However, in little endian
8140 mode fp constants are big-endian word-wise, and little-endian byte-wise
8141 within the words. For example, (double) 1.1 in big endian mode is
8142 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
8143 the byte sequence 99 99 f1 3f 9a 99 99 99.
8145 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
8148 md_atof (type
, litP
, sizeP
)
8154 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
8186 return _("bad call to MD_ATOF()");
8189 t
= atof_ieee (input_line_pointer
, type
, words
);
8191 input_line_pointer
= t
;
8194 if (target_big_endian
)
8196 for (i
= 0; i
< prec
; i
++)
8198 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
8204 /* For a 4 byte float the order of elements in `words' is 1 0. For an
8205 8 byte float the order is 1 0 3 2. */
8206 for (i
= 0; i
< prec
; i
+= 2)
8208 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
8209 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
8217 /* The knowledge of the PC's pipeline offset is built into the insns
8221 md_pcrel_from (fixP
)
8225 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
8226 && fixP
->fx_subsy
== NULL
)
8229 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
8231 /* PC relative addressing on the Thumb is slightly odd
8232 as the bottom two bits of the PC are forced to zero
8233 for the calculation. */
8234 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
8238 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
8239 so we un-adjust here to compensate for the accomodation. */
8240 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
8242 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
8246 /* Round up a section size to the appropriate boundary. */
8249 md_section_align (segment
, size
)
8250 segT segment ATTRIBUTE_UNUSED
;
8256 /* Round all sects to multiple of 4. */
8257 return (size
+ 3) & ~3;
8261 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
8262 Otherwise we have no need to default values of symbols. */
8265 md_undefined_symbol (name
)
8266 char * name ATTRIBUTE_UNUSED
;
8269 if (name
[0] == '_' && name
[1] == 'G'
8270 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
8274 if (symbol_find (name
))
8275 as_bad ("GOT already in the symbol table");
8277 GOT_symbol
= symbol_new (name
, undefined_section
,
8278 (valueT
) 0, & zero_address_frag
);
8288 /* arm_reg_parse () := if it looks like a register, return its token and
8289 advance the pointer. */
8292 arm_reg_parse (ccp
, htab
)
8293 register char ** ccp
;
8294 struct hash_control
*htab
;
8296 char * start
= * ccp
;
8299 struct reg_entry
* reg
;
8301 #ifdef REGISTER_PREFIX
8302 if (*start
!= REGISTER_PREFIX
)
8307 #ifdef OPTIONAL_REGISTER_PREFIX
8308 if (*p
== OPTIONAL_REGISTER_PREFIX
)
8312 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
8316 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
8320 reg
= (struct reg_entry
*) hash_find (htab
, start
);
8332 /* Search for the following register name in each of the possible reg name
8333 tables. Return the classification if found, or REG_TYPE_MAX if not
8335 static enum arm_reg_type
8336 arm_reg_parse_any (cp
)
8341 for (i
= (int) REG_TYPE_FIRST
; i
< (int) REG_TYPE_MAX
; i
++)
8342 if (arm_reg_parse (&cp
, all_reg_maps
[i
].htab
) != FAIL
)
8343 return (enum arm_reg_type
) i
;
8345 return REG_TYPE_MAX
;
8349 md_apply_fix3 (fixP
, valP
, seg
)
8354 offsetT value
= * valP
;
8356 unsigned int newimm
;
8359 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
8360 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
8362 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
8364 /* Note whether this will delete the relocation. */
8366 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
8367 doesn't work fully.) */
8368 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
8371 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
8375 /* If this symbol is in a different section then we need to leave it for
8376 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
8377 so we have to undo it's effects here. */
8380 if (fixP
->fx_addsy
!= NULL
8381 && S_IS_DEFINED (fixP
->fx_addsy
)
8382 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
8385 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
8386 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
8390 value
+= md_pcrel_from (fixP
);
8394 /* Remember value for emit_reloc. */
8395 fixP
->fx_addnumber
= value
;
8397 switch (fixP
->fx_r_type
)
8399 case BFD_RELOC_ARM_IMMEDIATE
:
8400 newimm
= validate_immediate (value
);
8401 temp
= md_chars_to_number (buf
, INSN_SIZE
);
8403 /* If the instruction will fail, see if we can fix things up by
8404 changing the opcode. */
8405 if (newimm
== (unsigned int) FAIL
8406 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
8408 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8409 _("invalid constant (%lx) after fixup"),
8410 (unsigned long) value
);
8414 newimm
|= (temp
& 0xfffff000);
8415 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
8418 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
8420 unsigned int highpart
= 0;
8421 unsigned int newinsn
= 0xe1a00000; /* nop. */
8422 newimm
= validate_immediate (value
);
8423 temp
= md_chars_to_number (buf
, INSN_SIZE
);
8425 /* If the instruction will fail, see if we can fix things up by
8426 changing the opcode. */
8427 if (newimm
== (unsigned int) FAIL
8428 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
8430 /* No ? OK - try using two ADD instructions to generate
8432 newimm
= validate_immediate_twopart (value
, & highpart
);
8434 /* Yes - then make sure that the second instruction is
8436 if (newimm
!= (unsigned int) FAIL
)
8438 /* Still No ? Try using a negated value. */
8439 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
8440 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
8441 /* Otherwise - give up. */
8444 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8445 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
8450 /* Replace the first operand in the 2nd instruction (which
8451 is the PC) with the destination register. We have
8452 already added in the PC in the first instruction and we
8453 do not want to do it again. */
8454 newinsn
&= ~ 0xf0000;
8455 newinsn
|= ((newinsn
& 0x0f000) << 4);
8458 newimm
|= (temp
& 0xfffff000);
8459 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
8461 highpart
|= (newinsn
& 0xfffff000);
8462 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
8466 case BFD_RELOC_ARM_OFFSET_IMM
:
8472 if (validate_offset_imm (value
, 0) == FAIL
)
8474 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8475 _("bad immediate value for offset (%ld)"),
8480 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8481 newval
&= 0xff7ff000;
8482 newval
|= value
| (sign
? INDEX_UP
: 0);
8483 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8486 case BFD_RELOC_ARM_OFFSET_IMM8
:
8487 case BFD_RELOC_ARM_HWLITERAL
:
8493 if (validate_offset_imm (value
, 1) == FAIL
)
8495 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
8496 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8497 _("invalid literal constant: pool needs to be closer"));
8499 as_bad (_("bad immediate value for half-word offset (%ld)"),
8504 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8505 newval
&= 0xff7ff0f0;
8506 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
8507 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8510 case BFD_RELOC_ARM_LITERAL
:
8516 if (validate_offset_imm (value
, 0) == FAIL
)
8518 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8519 _("invalid literal constant: pool needs to be closer"));
8523 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8524 newval
&= 0xff7ff000;
8525 newval
|= value
| (sign
? INDEX_UP
: 0);
8526 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8529 case BFD_RELOC_ARM_SHIFT_IMM
:
8530 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8531 if (((unsigned long) value
) > 32
8533 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
8535 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8536 _("shift expression is too large"));
8541 /* Shifts of zero must be done as lsl. */
8543 else if (value
== 32)
8545 newval
&= 0xfffff07f;
8546 newval
|= (value
& 0x1f) << 7;
8547 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8550 case BFD_RELOC_ARM_SWI
:
8551 if (arm_data
->thumb_mode
)
8553 if (((unsigned long) value
) > 0xff)
8554 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8555 _("invalid swi expression"));
8556 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
8558 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8562 if (((unsigned long) value
) > 0x00ffffff)
8563 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8564 _("invalid swi expression"));
8565 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
8567 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8571 case BFD_RELOC_ARM_MULTI
:
8572 if (((unsigned long) value
) > 0xffff)
8573 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8574 _("invalid expression in load/store multiple"));
8575 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
8576 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8579 case BFD_RELOC_ARM_PCREL_BRANCH
:
8580 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8582 /* Sign-extend a 24-bit number. */
8583 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
8587 value
= fixP
->fx_offset
;
8590 /* We are going to store value (shifted right by two) in the
8591 instruction, in a 24 bit, signed field. Thus we need to check
8592 that none of the top 8 bits of the shifted value (top 7 bits of
8593 the unshifted, unsigned value) are set, or that they are all set. */
8594 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
8595 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
8598 /* Normally we would be stuck at this point, since we cannot store
8599 the absolute address that is the destination of the branch in the
8600 24 bits of the branch instruction. If however, we happen to know
8601 that the destination of the branch is in the same section as the
8602 branch instruciton itself, then we can compute the relocation for
8603 ourselves and not have to bother the linker with it.
8605 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
8606 because I have not worked out how to do this for OBJ_COFF or
8609 && fixP
->fx_addsy
!= NULL
8610 && S_IS_DEFINED (fixP
->fx_addsy
)
8611 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
8613 /* Get pc relative value to go into the branch. */
8616 /* Permit a backward branch provided that enough bits
8617 are set. Allow a forwards branch, provided that
8618 enough bits are clear. */
8619 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
8620 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
8624 if (! fixP
->fx_done
)
8626 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8627 _("GAS can't handle same-section branch dest >= 0x04000000"));
8631 value
+= SEXT24 (newval
);
8633 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
8634 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
8635 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8636 _("out of range branch"));
8638 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
8639 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8642 case BFD_RELOC_ARM_PCREL_BLX
:
8645 newval
= md_chars_to_number (buf
, INSN_SIZE
);
8649 value
= fixP
->fx_offset
;
8651 hbit
= (value
>> 1) & 1;
8652 value
= (value
>> 2) & 0x00ffffff;
8653 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
8654 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
8655 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8659 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
8660 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8662 addressT diff
= (newval
& 0xff) << 1;
8667 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
8668 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8669 _("branch out of range"));
8670 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
8672 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8675 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
8676 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8678 addressT diff
= (newval
& 0x7ff) << 1;
8683 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
8684 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8685 _("branch out of range"));
8686 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
8688 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8691 case BFD_RELOC_THUMB_PCREL_BLX
:
8692 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
8697 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8698 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
8699 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
8700 if (diff
& 0x400000)
8703 value
= fixP
->fx_offset
;
8706 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
8707 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8708 _("branch with link out of range"));
8710 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
8711 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
8712 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
)
8713 /* Remove bit zero of the adjusted offset. Bit zero can only be
8714 set if the upper insn is at a half-word boundary, since the
8715 destination address, an ARM instruction, must always be on a
8716 word boundary. The semantics of the BLX (1) instruction, however,
8717 are that bit zero in the offset must always be zero, and the
8718 corresponding bit one in the target address will be set from bit
8719 one of the source address. */
8721 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8722 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
8727 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
8728 md_number_to_chars (buf
, value
, 1);
8730 else if (!target_oabi
)
8732 value
= fixP
->fx_offset
;
8733 md_number_to_chars (buf
, value
, 1);
8739 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
8740 md_number_to_chars (buf
, value
, 2);
8742 else if (!target_oabi
)
8744 value
= fixP
->fx_offset
;
8745 md_number_to_chars (buf
, value
, 2);
8751 case BFD_RELOC_ARM_GOT32
:
8752 case BFD_RELOC_ARM_GOTOFF
:
8753 md_number_to_chars (buf
, 0, 4);
8759 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
8760 md_number_to_chars (buf
, value
, 4);
8762 else if (!target_oabi
)
8764 value
= fixP
->fx_offset
;
8765 md_number_to_chars (buf
, value
, 4);
8771 case BFD_RELOC_ARM_PLT32
:
8772 /* It appears the instruction is fully prepared at this point. */
8776 case BFD_RELOC_ARM_GOTPC
:
8777 md_number_to_chars (buf
, value
, 4);
8780 case BFD_RELOC_ARM_CP_OFF_IMM
:
8782 if (value
< -1023 || value
> 1023 || (value
& 3))
8783 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8784 _("illegal value for co-processor offset"));
8787 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
8788 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
8789 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8792 case BFD_RELOC_ARM_THUMB_OFFSET
:
8793 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8794 /* Exactly what ranges, and where the offset is inserted depends
8795 on the type of instruction, we can establish this from the
8797 switch (newval
>> 12)
8799 case 4: /* PC load. */
8800 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
8801 forced to zero for these loads, so we will need to round
8802 up the offset if the instruction address is not word
8803 aligned (since the final address produced must be, and
8804 we can only describe word-aligned immediate offsets). */
8806 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
8807 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8808 _("invalid offset, target not word aligned (0x%08X)"),
8809 (unsigned int) (fixP
->fx_frag
->fr_address
8810 + fixP
->fx_where
+ value
));
8812 if ((value
+ 2) & ~0x3fe)
8813 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8814 _("invalid offset, value too big (0x%08lX)"), value
);
8816 /* Round up, since pc will be rounded down. */
8817 newval
|= (value
+ 2) >> 2;
8820 case 9: /* SP load/store. */
8822 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8823 _("invalid offset, value too big (0x%08lX)"), value
);
8824 newval
|= value
>> 2;
8827 case 6: /* Word load/store. */
8829 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8830 _("invalid offset, value too big (0x%08lX)"), value
);
8831 newval
|= value
<< 4; /* 6 - 2. */
8834 case 7: /* Byte load/store. */
8836 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8837 _("invalid offset, value too big (0x%08lX)"), value
);
8838 newval
|= value
<< 6;
8841 case 8: /* Halfword load/store. */
8843 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8844 _("invalid offset, value too big (0x%08lX)"), value
);
8845 newval
|= value
<< 5; /* 6 - 1. */
8849 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8850 "Unable to process relocation for thumb opcode: %lx",
8851 (unsigned long) newval
);
8854 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8857 case BFD_RELOC_ARM_THUMB_ADD
:
8858 /* This is a complicated relocation, since we use it for all of
8859 the following immediate relocations:
8863 9bit ADD/SUB SP word-aligned
8864 10bit ADD PC/SP word-aligned
8866 The type of instruction being processed is encoded in the
8873 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8875 int rd
= (newval
>> 4) & 0xf;
8876 int rs
= newval
& 0xf;
8877 int subtract
= newval
& 0x8000;
8882 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8883 _("invalid immediate for stack address calculation"));
8884 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
8885 newval
|= value
>> 2;
8887 else if (rs
== REG_PC
|| rs
== REG_SP
)
8891 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8892 _("invalid immediate for address calculation (value = 0x%08lX)"),
8893 (unsigned long) value
);
8894 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
8896 newval
|= value
>> 2;
8901 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8902 _("invalid 8bit immediate"));
8903 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
8904 newval
|= (rd
<< 8) | value
;
8909 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8910 _("invalid 3bit immediate"));
8911 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
8912 newval
|= rd
| (rs
<< 3) | (value
<< 6);
8915 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8918 case BFD_RELOC_ARM_THUMB_IMM
:
8919 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8920 switch (newval
>> 11)
8922 case 0x04: /* 8bit immediate MOV. */
8923 case 0x05: /* 8bit immediate CMP. */
8924 if (value
< 0 || value
> 255)
8925 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8926 _("invalid immediate: %ld is too large"),
8934 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8937 case BFD_RELOC_ARM_THUMB_SHIFT
:
8938 /* 5bit shift value (0..31). */
8939 if (value
< 0 || value
> 31)
8940 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8941 _("illegal Thumb shift value: %ld"), (long) value
);
8942 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
8943 newval
|= value
<< 6;
8944 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8947 case BFD_RELOC_VTABLE_INHERIT
:
8948 case BFD_RELOC_VTABLE_ENTRY
:
8952 case BFD_RELOC_NONE
:
8954 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8955 _("bad relocation fixup type (%d)"), fixP
->fx_r_type
);
8959 /* Translate internal representation of relocation info to BFD target
8963 tc_gen_reloc (section
, fixp
)
8964 asection
* section ATTRIBUTE_UNUSED
;
8968 bfd_reloc_code_real_type code
;
8970 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
8972 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
8973 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
8974 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
8976 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
8978 if (fixp
->fx_pcrel
== 0)
8979 reloc
->addend
= fixp
->fx_offset
;
8981 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
8983 reloc
->addend
= fixp
->fx_offset
;
8986 switch (fixp
->fx_r_type
)
8991 code
= BFD_RELOC_8_PCREL
;
8998 code
= BFD_RELOC_16_PCREL
;
9005 code
= BFD_RELOC_32_PCREL
;
9009 case BFD_RELOC_ARM_PCREL_BRANCH
:
9010 case BFD_RELOC_ARM_PCREL_BLX
:
9012 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
9013 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
9014 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
9015 case BFD_RELOC_THUMB_PCREL_BLX
:
9016 case BFD_RELOC_VTABLE_ENTRY
:
9017 case BFD_RELOC_VTABLE_INHERIT
:
9018 code
= fixp
->fx_r_type
;
9021 case BFD_RELOC_ARM_LITERAL
:
9022 case BFD_RELOC_ARM_HWLITERAL
:
9023 /* If this is called then the a literal has been referenced across
9024 a section boundary - possibly due to an implicit dump. */
9025 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9026 _("literal referenced across section boundary (Implicit dump?)"));
9030 case BFD_RELOC_ARM_GOT32
:
9031 case BFD_RELOC_ARM_GOTOFF
:
9032 case BFD_RELOC_ARM_PLT32
:
9033 code
= fixp
->fx_r_type
;
9037 case BFD_RELOC_ARM_IMMEDIATE
:
9038 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9039 _("internal relocation (type %d) not fixed up (IMMEDIATE)"),
9043 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
9044 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9045 _("ADRL used for a symbol not defined in the same file"));
9048 case BFD_RELOC_ARM_OFFSET_IMM
:
9049 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9050 _("internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
9058 switch (fixp
->fx_r_type
)
9060 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
9061 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
9062 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
9063 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
9064 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
9065 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
9066 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
9067 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
9068 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
9069 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
9070 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
9071 default: type
= _("<unknown>"); break;
9073 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9074 _("cannot represent %s relocation in this object file format"),
9081 if (code
== BFD_RELOC_32_PCREL
9083 && fixp
->fx_addsy
== GOT_symbol
)
9085 code
= BFD_RELOC_ARM_GOTPC
;
9086 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
9090 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
9092 if (reloc
->howto
== NULL
)
9094 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
9095 _("cannot represent %s relocation in this object file format"),
9096 bfd_get_reloc_code_name (code
));
9100 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
9101 vtable entry to be used in the relocation's section offset. */
9102 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
9103 reloc
->address
= fixp
->fx_offset
;
9109 md_estimate_size_before_relax (fragP
, segtype
)
9110 fragS
* fragP ATTRIBUTE_UNUSED
;
9111 segT segtype ATTRIBUTE_UNUSED
;
9113 as_fatal (_("md_estimate_size_before_relax\n"));
9125 as_bad ("%s -- `%s'", inst
.error
, str
);
9129 to
= frag_more (inst
.size
);
9131 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
9133 assert (inst
.size
== (2 * THUMB_SIZE
));
9134 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
9135 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
9137 else if (inst
.size
> INSN_SIZE
)
9139 assert (inst
.size
== (2 * INSN_SIZE
));
9140 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
9141 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
9144 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
9146 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
9147 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
9148 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
9152 dwarf2_emit_insn (inst
.size
);
9164 /* Align the instruction.
9165 This may not be the right thing to do but ... */
9169 listing_prev_line (); /* Defined in listing.h. */
9171 /* Align the previous label if needed. */
9172 if (last_label_seen
!= NULL
)
9174 symbol_set_frag (last_label_seen
, frag_now
);
9175 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
9176 S_SET_SEGMENT (last_label_seen
, now_seg
);
9179 memset (&inst
, '\0', sizeof (inst
));
9180 inst
.reloc
.type
= BFD_RELOC_NONE
;
9182 skip_whitespace (str
);
9184 /* Scan up to the end of the op-code, which must end in white space or
9186 for (start
= p
= str
; *p
!= '\0'; p
++)
9192 as_bad (_("no operator -- statement `%s'\n"), str
);
9198 const struct thumb_opcode
* opcode
;
9202 opcode
= (const struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
9207 /* Check that this instruction is supported for this CPU. */
9208 if (thumb_mode
== 1 && (opcode
->variant
& cpu_variant
) == 0)
9210 as_bad (_("selected processor does not support `%s'"), str
);
9214 inst
.instruction
= opcode
->value
;
9215 inst
.size
= opcode
->size
;
9216 (*opcode
->parms
) (p
);
9223 const struct asm_opcode
* opcode
;
9227 opcode
= (const struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
9232 /* Check that this instruction is supported for this CPU. */
9233 if ((opcode
->variant
& cpu_variant
) == 0)
9235 as_bad (_("selected processor does not support `%s'"), str
);
9239 inst
.instruction
= opcode
->value
;
9240 inst
.size
= INSN_SIZE
;
9241 (*opcode
->parms
) (p
);
9247 /* It wasn't an instruction, but it might be a register alias of the form
9249 if (create_register_alias (str
, p
))
9252 as_bad (_("bad instruction `%s'"), start
);
9256 Invocation line includes a switch not recognized by the base assembler.
9257 See if it's a processor-specific option. These are:
9258 Cpu variants, the arm part is optional:
9259 -m[arm]1 Currently not supported.
9260 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
9261 -m[arm]3 Arm 3 processor
9262 -m[arm]6[xx], Arm 6 processors
9263 -m[arm]7[xx][t][[d]m] Arm 7 processors
9264 -m[arm]8[10] Arm 8 processors
9265 -m[arm]9[20][tdmi] Arm 9 processors
9266 -marm9e Allow Cirrus/DSP instructions
9267 -mstrongarm[110[0]] StrongARM processors
9268 -mxscale XScale processors
9269 -m[arm]v[2345[t[e]]] Arm architectures
9270 -mall All (except the ARM1)
9272 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
9273 -mfpe-old (No float load/store multiples)
9274 -mno-fpu Disable all floating point instructions
9275 Run-time endian selection:
9277 -EL little endian cpu
9278 ARM Procedure Calling Standard:
9279 -mapcs-32 32 bit APCS
9280 -mapcs-26 26 bit APCS
9281 -mapcs-float Pass floats in float regs
9282 -mapcs-reentrant Position independent code
9283 -mthumb-interwork Code supports Arm/Thumb interworking
9284 -matpcs ARM/Thumb Procedure Call Standard
9285 -moabi Old ELF ABI */
9287 const char * md_shortopts
= "m:k";
9289 struct option md_longopts
[] =
9291 #ifdef ARM_BI_ENDIAN
9292 #define OPTION_EB (OPTION_MD_BASE + 0)
9293 {"EB", no_argument
, NULL
, OPTION_EB
},
9294 #define OPTION_EL (OPTION_MD_BASE + 1)
9295 {"EL", no_argument
, NULL
, OPTION_EL
},
9297 #define OPTION_OABI (OPTION_MD_BASE +2)
9298 {"oabi", no_argument
, NULL
, OPTION_OABI
},
9301 {NULL
, no_argument
, NULL
, 0}
9304 size_t md_longopts_size
= sizeof (md_longopts
);
9307 md_parse_option (c
, arg
)
9315 #ifdef ARM_BI_ENDIAN
9317 target_big_endian
= 1;
9320 target_big_endian
= 0;
9328 if (streq (str
, "fpa10") || streq (str
, "fpa11"))
9329 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_ARCH_FPA
;
9330 else if (streq (str
, "fpe-old"))
9331 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_ARCH_FPE
;
9337 if (streq (str
, "no-fpu"))
9338 cpu_variant
&= ~FPU_ANY
;
9343 if (streq (str
, "oabi"))
9349 /* Limit assembler to generating only Thumb instructions: */
9350 if (streq (str
, "thumb"))
9352 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_EXT_V4T
;
9353 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_NONE
;
9356 else if (streq (str
, "thumb-interwork"))
9358 if ((cpu_variant
& ARM_EXT_V4T
) == 0)
9359 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
9360 #if defined OBJ_COFF || defined OBJ_ELF
9361 support_interwork
= true;
9369 if (streq (str
, "all"))
9371 cpu_variant
= ARM_ALL
| FPU_DEFAULT
;
9374 #if defined OBJ_COFF || defined OBJ_ELF
9375 if (! strncmp (str
, "apcs-", 5))
9377 /* GCC passes on all command line options starting "-mapcs-..."
9378 to us, so we must parse them here. */
9382 if (streq (str
, "32"))
9384 uses_apcs_26
= false;
9387 else if (streq (str
, "26"))
9389 uses_apcs_26
= true;
9392 else if (streq (str
, "frame"))
9394 /* Stack frames are being generated - does not affect
9398 else if (streq (str
, "stack-check"))
9400 /* Stack checking is being performed - does not affect
9401 linkage, but does require that the functions
9402 __rt_stkovf_split_small and __rt_stkovf_split_big be
9403 present in the final link. */
9407 else if (streq (str
, "float"))
9409 /* Floating point arguments are being passed in the floating
9410 point registers. This does affect linking, since this
9411 version of the APCS is incompatible with the version that
9412 passes floating points in the integer registers. */
9414 uses_apcs_float
= true;
9417 else if (streq (str
, "reentrant"))
9419 /* Reentrant code has been generated. This does affect
9420 linking, since there is no point in linking reentrant/
9421 position independent code with absolute position code. */
9426 as_bad (_("unrecognised APCS switch -m%s"), arg
);
9430 if (! strcmp (str
, "atpcs"))
9436 /* Strip off optional "arm". */
9437 if (! strncmp (str
, "arm", 3))
9443 if (streq (str
, "1"))
9444 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
9450 if (streq (str
, "2"))
9451 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
9452 else if (streq (str
, "250"))
9453 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
9459 if (streq (str
, "3"))
9460 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
9466 switch (strtol (str
, NULL
, 10))
9473 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
9481 /* Eat the processor name. */
9482 switch (strtol (str
, & str
, 10))
9495 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
9501 cpu_variant
|= ARM_ARCH_V4T
;
9505 cpu_variant
|= ARM_EXT_V3M
;
9508 case 'f': /* fe => fp enabled cpu. */
9514 case 'c': /* Left over from 710c processor name. */
9515 case 'd': /* Debug. */
9516 case 'i': /* Embedded ICE. */
9517 /* Included for completeness in ARM processor naming. */
9527 if (streq (str
, "8") || streq (str
, "810"))
9528 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9529 | ARM_8
| ARM_ARCH_V4
;
9535 if (streq (str
, "9"))
9536 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9537 | ARM_9
| ARM_ARCH_V4T
;
9538 else if (streq (str
, "920"))
9539 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9540 | ARM_9
| ARM_ARCH_V4
;
9541 else if (streq (str
, "920t"))
9542 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9543 | ARM_9
| ARM_ARCH_V4T
;
9544 else if (streq (str
, "9tdmi"))
9545 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9546 | ARM_9
| ARM_ARCH_V4T
;
9547 else if (streq (str
, "9e"))
9548 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9549 | ARM_9
| ARM_ARCH_V4T
| ARM_EXT_MAVERICK
;
9555 if (streq (str
, "strongarm")
9556 || streq (str
, "strongarm110")
9557 || streq (str
, "strongarm1100"))
9558 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9559 | ARM_8
| ARM_ARCH_V4
;
9565 if (streq (str
, "xscale"))
9566 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
9567 | ARM_9
| ARM_ARCH_XSCALE
;
9573 /* Select variant based on architecture rather than
9581 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
9584 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
9587 as_bad (_("invalid architecture variant -m%s"), arg
);
9593 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
9597 case 'm': cpu_variant
|= ARM_EXT_V3M
; break;
9600 as_bad (_("invalid architecture variant -m%s"), arg
);
9606 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCH_V4
;
9610 case 't': cpu_variant
|= ARM_EXT_V4T
; break;
9613 as_bad (_("invalid architecture variant -m%s"), arg
);
9619 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V5
;
9622 case 't': cpu_variant
|= ARM_EXT_V4T
; break;
9623 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
9626 as_bad (_("invalid architecture variant -m%s"), arg
);
9632 as_bad (_("invalid architecture variant -m%s"), arg
);
9639 as_bad (_("invalid processor variant -m%s"), arg
);
9645 #if defined OBJ_ELF || defined OBJ_COFF
9663 ARM Specific Assembler Options:\n\
9664 -m[arm][<processor name>] select processor variant\n\
9665 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
9666 -marm9e allow Cirrus/DSP instructions\n\
9667 -mthumb only allow Thumb instructions\n\
9668 -mthumb-interwork mark the assembled code as supporting interworking\n\
9669 -mall allow any instruction\n\
9670 -mfpa10, -mfpa11 select floating point architecture\n\
9671 -mfpe-old don't allow floating-point multiple instructions\n\
9672 -mno-fpu don't allow any floating-point instructions.\n\
9673 -k generate PIC code.\n"));
9674 #if defined OBJ_COFF || defined OBJ_ELF
9676 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
9677 -matpcs use ARM/Thumb Procedure Calling Standard\n\
9678 -mapcs-float floating point args are passed in FP regs\n\
9679 -mapcs-reentrant the code is position independent/reentrant\n"));
9683 -moabi support the old ELF ABI\n"));
9685 #ifdef ARM_BI_ENDIAN
9687 -EB assemble code for a big endian cpu\n\
9688 -EL assemble code for a little endian cpu\n"));
9692 /* We need to be able to fix up arbitrary expressions in some statements.
9693 This is so that we can handle symbols that are an arbitrary distance from
9694 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
9695 which returns part of an address in a form which will be valid for
9696 a data instruction. We do this by pushing the expression into a symbol
9697 in the expr_section, and creating a fix for that. */
9700 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
9709 arm_fix_data
* arm_data
;
9717 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
9721 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
9726 /* Mark whether the fix is to a THUMB instruction, or an ARM
9728 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
9729 new_fix
->tc_fix_data
= (PTR
) arm_data
;
9730 arm_data
->thumb_mode
= thumb_mode
;
9735 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
9738 cons_fix_new_arm (frag
, where
, size
, exp
)
9744 bfd_reloc_code_real_type type
;
9748 FIXME: @@ Should look at CPU word size. */
9755 type
= BFD_RELOC_16
;
9759 type
= BFD_RELOC_32
;
9762 type
= BFD_RELOC_64
;
9766 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
9769 /* A good place to do this, although this was probably not intended
9770 for this kind of use. We need to dump the literal pool before
9771 references are made to a null symbol pointer. */
9776 if (current_poolP
== NULL
)
9779 /* Put it at the end of text section. */
9780 subseg_set (text_section
, 0);
9782 listing_prev_line ();
9786 arm_start_line_hook ()
9788 last_label_seen
= NULL
;
9792 arm_frob_label (sym
)
9795 last_label_seen
= sym
;
9797 ARM_SET_THUMB (sym
, thumb_mode
);
9799 #if defined OBJ_COFF || defined OBJ_ELF
9800 ARM_SET_INTERWORK (sym
, support_interwork
);
9803 /* Note - do not allow local symbols (.Lxxx) to be labeled
9804 as Thumb functions. This is because these labels, whilst
9805 they exist inside Thumb code, are not the entry points for
9806 possible ARM->Thumb calls. Also, these labels can be used
9807 as part of a computed goto or switch statement. eg gcc
9808 can generate code that looks like this:
9820 The first instruction loads the address of the jump table.
9821 The second instruction converts a table index into a byte offset.
9822 The third instruction gets the jump address out of the table.
9823 The fourth instruction performs the jump.
9825 If the address stored at .Laaa is that of a symbol which has the
9826 Thumb_Func bit set, then the linker will arrange for this address
9827 to have the bottom bit set, which in turn would mean that the
9828 address computation performed by the third instruction would end
9829 up with the bottom bit set. Since the ARM is capable of unaligned
9830 word loads, the instruction would then load the incorrect address
9831 out of the jump table, and chaos would ensue. */
9832 if (label_is_thumb_function_name
9833 && (S_GET_NAME (sym
)[0] != '.' || S_GET_NAME (sym
)[1] != 'L')
9834 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
9836 /* When the address of a Thumb function is taken the bottom
9837 bit of that address should be set. This will allow
9838 interworking between Arm and Thumb functions to work
9841 THUMB_SET_FUNC (sym
, 1);
9843 label_is_thumb_function_name
= false;
9847 /* Adjust the symbol table. This marks Thumb symbols as distinct from
9851 arm_adjust_symtab ()
9856 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
9858 if (ARM_IS_THUMB (sym
))
9860 if (THUMB_IS_FUNC (sym
))
9862 /* Mark the symbol as a Thumb function. */
9863 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
9864 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
9865 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
9867 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
9868 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
9870 as_bad (_("%s: unexpected function type: %d"),
9871 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
9873 else switch (S_GET_STORAGE_CLASS (sym
))
9876 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
9879 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
9882 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
9890 if (ARM_IS_INTERWORK (sym
))
9891 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
9898 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
9900 if (ARM_IS_THUMB (sym
))
9902 elf_symbol_type
* elf_sym
;
9904 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
9905 bind
= ELF_ST_BIND (elf_sym
);
9907 /* If it's a .thumb_func, declare it as so,
9908 otherwise tag label as .code 16. */
9909 if (THUMB_IS_FUNC (sym
))
9910 elf_sym
->internal_elf_sym
.st_info
=
9911 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
9913 elf_sym
->internal_elf_sym
.st_info
=
9914 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
9923 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
9925 *input_line_pointer
= '/';
9926 input_line_pointer
+= 5;
9927 *input_line_pointer
= 0;
9935 arm_canonicalize_symbol_name (name
)
9940 if (thumb_mode
&& (len
= strlen (name
)) > 5
9941 && streq (name
+ len
- 5, "/data"))
9942 *(name
+ len
- 5) = 0;
9948 arm_validate_fix (fixP
)
9951 /* If the destination of the branch is a defined symbol which does not have
9952 the THUMB_FUNC attribute, then we must be calling a function which has
9953 the (interfacearm) attribute. We look for the Thumb entry point to that
9954 function and change the branch to refer to that function instead. */
9955 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
9956 && fixP
->fx_addsy
!= NULL
9957 && S_IS_DEFINED (fixP
->fx_addsy
)
9958 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
9960 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
9968 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
9969 local labels from being added to the output symbol table when they
9970 are used with the ADRL pseudo op. The ADRL relocation should always
9971 be resolved before the binbary is emitted, so it is safe to say that
9972 it is adjustable. */
9975 arm_fix_adjustable (fixP
)
9978 if (fixP
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
9984 /* Relocations against Thumb function names must be left unadjusted,
9985 so that the linker can use this information to correctly set the
9986 bottom bit of their addresses. The MIPS version of this function
9987 also prevents relocations that are mips-16 specific, but I do not
9988 know why it does this.
9991 There is one other problem that ought to be addressed here, but
9992 which currently is not: Taking the address of a label (rather
9993 than a function) and then later jumping to that address. Such
9994 addresses also ought to have their bottom bit set (assuming that
9995 they reside in Thumb code), but at the moment they will not. */
9998 arm_fix_adjustable (fixP
)
10001 if (fixP
->fx_addsy
== NULL
)
10004 /* Prevent all adjustments to global symbols. */
10005 if (S_IS_EXTERN (fixP
->fx_addsy
))
10008 if (S_IS_WEAK (fixP
->fx_addsy
))
10011 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
10012 && fixP
->fx_subsy
== NULL
)
10015 /* We need the symbol name for the VTABLE entries. */
10016 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
10017 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
10024 elf32_arm_target_format ()
10026 if (target_big_endian
)
10029 return "elf32-bigarm-oabi";
10031 return "elf32-bigarm";
10036 return "elf32-littlearm-oabi";
10038 return "elf32-littlearm";
10043 armelf_frob_symbol (symp
, puntp
)
10047 elf_frob_symbol (symp
, puntp
);
10051 arm_force_relocation (fixp
)
10054 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
10055 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
10056 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
10057 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
10058 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
10059 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
10065 static bfd_reloc_code_real_type
10075 bfd_reloc_code_real_type reloc
;
10079 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
10080 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
10081 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
10082 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
10083 branch instructions generated by GCC for PLT relocs. */
10084 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
10085 { NULL
, 0, BFD_RELOC_UNUSED
}
10089 for (i
= 0, ip
= input_line_pointer
;
10090 i
< sizeof (id
) && (ISALNUM (*ip
) || ISPUNCT (*ip
));
10092 id
[i
] = TOLOWER (*ip
);
10094 for (i
= 0; reloc_map
[i
].str
; i
++)
10095 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
10098 input_line_pointer
+= reloc_map
[i
].len
;
10100 return reloc_map
[i
].reloc
;
10104 s_arm_elf_cons (nbytes
)
10109 #ifdef md_flush_pending_output
10110 md_flush_pending_output ();
10113 if (is_it_end_of_statement ())
10115 demand_empty_rest_of_line ();
10119 #ifdef md_cons_align
10120 md_cons_align (nbytes
);
10125 bfd_reloc_code_real_type reloc
;
10127 expression (& exp
);
10129 if (exp
.X_op
== O_symbol
10130 && * input_line_pointer
== '('
10131 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
10133 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
10134 int size
= bfd_get_reloc_size (howto
);
10137 as_bad ("%s relocations do not fit in %d bytes",
10138 howto
->name
, nbytes
);
10141 register char *p
= frag_more ((int) nbytes
);
10142 int offset
= nbytes
- size
;
10144 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
10149 emit_expr (&exp
, (unsigned int) nbytes
);
10151 while (*input_line_pointer
++ == ',');
10153 /* Put terminator back into stream. */
10154 input_line_pointer
--;
10155 demand_empty_rest_of_line ();
10158 #endif /* OBJ_ELF */
10160 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
10161 of an rs_align_code fragment. */
10164 arm_handle_align (fragP
)
10167 static char const arm_noop
[4] = { 0x00, 0x00, 0xa0, 0xe1 };
10168 static char const thumb_noop
[2] = { 0xc0, 0x46 };
10169 static char const arm_bigend_noop
[4] = { 0xe1, 0xa0, 0x00, 0x00 };
10170 static char const thumb_bigend_noop
[2] = { 0x46, 0xc0 };
10172 int bytes
, fix
, noop_size
;
10176 if (fragP
->fr_type
!= rs_align_code
)
10179 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
10180 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
10183 if (bytes
> MAX_MEM_FOR_RS_ALIGN_CODE
)
10184 bytes
&= MAX_MEM_FOR_RS_ALIGN_CODE
;
10186 if (fragP
->tc_frag_data
)
10188 if (target_big_endian
)
10189 noop
= thumb_bigend_noop
;
10192 noop_size
= sizeof (thumb_noop
);
10196 if (target_big_endian
)
10197 noop
= arm_bigend_noop
;
10200 noop_size
= sizeof (arm_noop
);
10203 if (bytes
& (noop_size
- 1))
10205 fix
= bytes
& (noop_size
- 1);
10206 memset (p
, 0, fix
);
10211 while (bytes
>= noop_size
)
10213 memcpy (p
, noop
, noop_size
);
10215 bytes
-= noop_size
;
10219 fragP
->fr_fix
+= fix
;
10220 fragP
->fr_var
= noop_size
;
10223 /* Called from md_do_align. Used to create an alignment
10224 frag in a code section. */
10227 arm_frag_align_code (n
, max
)
10233 /* We assume that there will never be a requirment
10234 to support alignments greater than 32 bytes. */
10235 if (max
> MAX_MEM_FOR_RS_ALIGN_CODE
)
10236 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
10238 p
= frag_var (rs_align_code
,
10239 MAX_MEM_FOR_RS_ALIGN_CODE
,
10241 (relax_substateT
) max
,
10249 /* Perform target specific initialisation of a frag. */
10252 arm_init_frag (fragP
)
10255 /* Record whether this frag is in an ARM or a THUMB area. */
10256 fragP
->tc_frag_data
= thumb_mode
;