1 /* tc-arm.c -- Assemble for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
3 Free Software Foundation, Inc.
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 #include "safe-ctype.h"
30 /* Need TARGET_CPU. */
39 #include "dwarf2dbg.h"
42 /* XXX Set this to 1 after the next binutils release */
43 #define WARN_DEPRECATED 0
45 /* The following bitmasks control CPU extensions: */
46 #define ARM_EXT_V1 0x00000001 /* All processors (core set). */
47 #define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
48 #define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
49 #define ARM_EXT_V3 0x00000008 /* MSR MRS. */
50 #define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
51 #define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
52 #define ARM_EXT_V4T 0x00000040 /* Thumb v1. */
53 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
54 #define ARM_EXT_V5T 0x00000100 /* Thumb v2. */
55 #define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
56 #define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
57 #define ARM_EXT_V5J 0x00000800 /* Jazelle extension. */
59 /* Co-processor space extensions. */
60 #define ARM_CEXT_XSCALE 0x00800000 /* Allow MIA etc. */
61 #define ARM_CEXT_MAVERICK 0x00400000 /* Use Cirrus/DSP coprocessor. */
63 /* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
64 defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
65 ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
66 three more to cover cores prior to ARM6. Finally, there are cores which
67 implement further extensions in the co-processor space. */
68 #define ARM_ARCH_V1 ARM_EXT_V1
69 #define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)
70 #define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)
71 #define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)
72 #define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)
73 #define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)
74 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)
75 #define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)
76 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)
77 #define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)
78 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
79 #define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
80 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
81 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)
82 #define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)
83 #define ARM_ARCH_V5TEJ (ARM_ARCH_V5TE | ARM_EXT_V5J)
85 /* Processors with specific extensions in the co-processor space. */
86 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_CEXT_XSCALE)
88 /* Some useful combinations: */
89 #define ARM_ANY 0x0000ffff /* Any basic core. */
90 #define ARM_ALL 0x00ffffff /* Any core + co-processor */
91 #define CPROC_ANY 0x00ff0000 /* Any co-processor */
92 #define FPU_ANY 0xff000000 /* Note this is ~ARM_ALL. */
95 #define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */
96 #define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */
97 #define FPU_VFP_EXT_NONE 0x20000000 /* Use VFP word-ordering. */
98 #define FPU_VFP_EXT_V1xD 0x10000000 /* Base VFP instruction set. */
99 #define FPU_VFP_EXT_V1 0x08000000 /* Double-precision insns. */
100 #define FPU_VFP_EXT_V2 0x04000000 /* ARM10E VFPr1. */
103 #define FPU_ARCH_FPE FPU_FPA_EXT_V1
104 #define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
106 #define FPU_ARCH_VFP FPU_VFP_EXT_NONE
107 #define FPU_ARCH_VFP_V1xD (FPU_VFP_EXT_V1xD | FPU_VFP_EXT_NONE)
108 #define FPU_ARCH_VFP_V1 (FPU_ARCH_VFP_V1xD | FPU_VFP_EXT_V1)
109 #define FPU_ARCH_VFP_V2 (FPU_ARCH_VFP_V1 | FPU_VFP_EXT_V2)
111 /* Types of processor to assemble for. */
112 #define ARM_1 ARM_ARCH_V1
113 #define ARM_2 ARM_ARCH_V2
114 #define ARM_3 ARM_ARCH_V2S
115 #define ARM_250 ARM_ARCH_V2S
116 #define ARM_6 ARM_ARCH_V3
117 #define ARM_7 ARM_ARCH_V3
118 #define ARM_8 ARM_ARCH_V4
119 #define ARM_9 ARM_ARCH_V4T
120 #define ARM_STRONG ARM_ARCH_V4
121 #define ARM_CPU_MASK 0x0000000f /* XXX? */
124 #if defined __XSCALE__
125 #define CPU_DEFAULT (ARM_ARCH_XSCALE)
127 #if defined __thumb__
128 #define CPU_DEFAULT (ARM_ARCH_V5T)
130 #define CPU_DEFAULT ARM_ANY
135 /* For backwards compatibility we default to the FPA. */
137 #define FPU_DEFAULT FPU_ARCH_FPA
140 #define streq(a, b) (strcmp (a, b) == 0)
141 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
143 static unsigned long cpu_variant;
144 static int target_oabi = 0;
146 /* Flags stored in private area of BFD structure. */
147 static int uses_apcs_26 = FALSE;
148 static int atpcs = FALSE;
149 static int support_interwork = FALSE;
150 static int uses_apcs_float = FALSE;
151 static int pic_code = FALSE;
153 /* Variables that we set while parsing command-line options. Once all
154 options have been read we re-process these values to set the real
156 static int legacy_cpu = -1;
157 static int legacy_fpu = -1;
159 static int mcpu_cpu_opt = -1;
160 static int mcpu_fpu_opt = -1;
161 static int march_cpu_opt = -1;
162 static int march_fpu_opt = -1;
163 static int mfpu_opt = -1;
165 /* This array holds the chars that always start a comment. If the
166 pre-processor is disabled, these aren't very useful. */
167 const char comment_chars[] = "@";
169 /* This array holds the chars that only start a comment at the beginning of
170 a line. If the line seems to have the form '# 123 filename'
171 .line and .file directives will appear in the pre-processed output. */
172 /* Note that input_file.c hand checks for '#' at the beginning of the
173 first line of the input file. This is because the compiler outputs
174 #NO_APP at the beginning of its output. */
175 /* Also note that comments like this one will always work. */
176 const char line_comment_chars[] = "#";
178 const char line_separator_chars[] = ";";
180 /* Chars that can be used to separate mant
181 from exp in floating point numbers. */
182 const char EXP_CHARS[] = "eE";
184 /* Chars that mean this number is a floating point constant. */
188 const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
190 /* Prefix characters that indicate the start of an immediate
192 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
195 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
196 symbolS * GOT_symbol;
199 /* Size of relocation record. */
200 const int md_reloc_size = 8;
202 /* 0: assemble for ARM,
203 1: assemble for Thumb,
204 2: assemble for Thumb even though target CPU does not support thumb
206 static int thumb_mode = 0;
208 typedef struct arm_fix
216 unsigned long instruction;
220 bfd_reloc_code_real_type type;
237 struct asm_shift_properties
239 enum asm_shift_index index;
240 unsigned long bit_field;
241 unsigned int allows_0 : 1;
242 unsigned int allows_32 : 1;
245 static const struct asm_shift_properties shift_properties [] =
247 { SHIFT_LSL, 0, 1, 0},
248 { SHIFT_LSR, 0x20, 0, 1},
249 { SHIFT_ASR, 0x40, 0, 1},
250 { SHIFT_ROR, 0x60, 0, 0},
251 { SHIFT_RRX, 0x60, 0, 0}
254 struct asm_shift_name
257 const struct asm_shift_properties * properties;
260 static const struct asm_shift_name shift_names [] =
262 { "asl", shift_properties + SHIFT_LSL },
263 { "lsl", shift_properties + SHIFT_LSL },
264 { "lsr", shift_properties + SHIFT_LSR },
265 { "asr", shift_properties + SHIFT_ASR },
266 { "ror", shift_properties + SHIFT_ROR },
267 { "rrx", shift_properties + SHIFT_RRX },
268 { "ASL", shift_properties + SHIFT_LSL },
269 { "LSL", shift_properties + SHIFT_LSL },
270 { "LSR", shift_properties + SHIFT_LSR },
271 { "ASR", shift_properties + SHIFT_ASR },
272 { "ROR", shift_properties + SHIFT_ROR },
273 { "RRX", shift_properties + SHIFT_RRX }
276 #define NO_SHIFT_RESTRICT 1
277 #define SHIFT_RESTRICT 0
279 #define NUM_FLOAT_VALS 8
281 const char * fp_const[] =
283 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
286 /* Number of littlenums required to hold an extended precision number. */
287 #define MAX_LITTLENUMS 6
289 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
294 /* Whether a Co-processor load/store operation accepts write-back forms. */
303 #define CP_T_X 0x00008000
304 #define CP_T_Y 0x00400000
305 #define CP_T_Pre 0x01000000
306 #define CP_T_UD 0x00800000
307 #define CP_T_WB 0x00200000
309 #define CONDS_BIT 0x00100000
310 #define LOAD_BIT 0x00100000
312 #define DOUBLE_LOAD_FLAG 0x00000001
316 const char * template;
320 #define COND_ALWAYS 0xe0000000
321 #define COND_MASK 0xf0000000
323 static const struct asm_cond conds[] =
327 {"cs", 0x20000000}, {"hs", 0x20000000},
328 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
345 const char *template;
350 /* The bit that distnguishes CPSR and SPSR. */
351 #define SPSR_BIT (1 << 22)
353 /* How many bits to shift the PSR_xxx bits up by. */
356 #define PSR_c (1 << 0)
357 #define PSR_x (1 << 1)
358 #define PSR_s (1 << 2)
359 #define PSR_f (1 << 3)
361 static const struct asm_psr psrs[] =
363 {"CPSR", TRUE, PSR_c | PSR_f},
364 {"CPSR_all", TRUE, PSR_c | PSR_f},
365 {"SPSR", FALSE, PSR_c | PSR_f},
366 {"SPSR_all", FALSE, PSR_c | PSR_f},
367 {"CPSR_flg", TRUE, PSR_f},
368 {"CPSR_f", TRUE, PSR_f},
369 {"SPSR_flg", FALSE, PSR_f},
370 {"SPSR_f", FALSE, PSR_f},
371 {"CPSR_c", TRUE, PSR_c},
372 {"CPSR_ctl", TRUE, PSR_c},
373 {"SPSR_c", FALSE, PSR_c},
374 {"SPSR_ctl", FALSE, PSR_c},
375 {"CPSR_x", TRUE, PSR_x},
376 {"CPSR_s", TRUE, PSR_s},
377 {"SPSR_x", FALSE, PSR_x},
378 {"SPSR_s", FALSE, PSR_s},
379 /* Combinations of flags. */
380 {"CPSR_fs", TRUE, PSR_f | PSR_s},
381 {"CPSR_fx", TRUE, PSR_f | PSR_x},
382 {"CPSR_fc", TRUE, PSR_f | PSR_c},
383 {"CPSR_sf", TRUE, PSR_s | PSR_f},
384 {"CPSR_sx", TRUE, PSR_s | PSR_x},
385 {"CPSR_sc", TRUE, PSR_s | PSR_c},
386 {"CPSR_xf", TRUE, PSR_x | PSR_f},
387 {"CPSR_xs", TRUE, PSR_x | PSR_s},
388 {"CPSR_xc", TRUE, PSR_x | PSR_c},
389 {"CPSR_cf", TRUE, PSR_c | PSR_f},
390 {"CPSR_cs", TRUE, PSR_c | PSR_s},
391 {"CPSR_cx", TRUE, PSR_c | PSR_x},
392 {"CPSR_fsx", TRUE, PSR_f | PSR_s | PSR_x},
393 {"CPSR_fsc", TRUE, PSR_f | PSR_s | PSR_c},
394 {"CPSR_fxs", TRUE, PSR_f | PSR_x | PSR_s},
395 {"CPSR_fxc", TRUE, PSR_f | PSR_x | PSR_c},
396 {"CPSR_fcs", TRUE, PSR_f | PSR_c | PSR_s},
397 {"CPSR_fcx", TRUE, PSR_f | PSR_c | PSR_x},
398 {"CPSR_sfx", TRUE, PSR_s | PSR_f | PSR_x},
399 {"CPSR_sfc", TRUE, PSR_s | PSR_f | PSR_c},
400 {"CPSR_sxf", TRUE, PSR_s | PSR_x | PSR_f},
401 {"CPSR_sxc", TRUE, PSR_s | PSR_x | PSR_c},
402 {"CPSR_scf", TRUE, PSR_s | PSR_c | PSR_f},
403 {"CPSR_scx", TRUE, PSR_s | PSR_c | PSR_x},
404 {"CPSR_xfs", TRUE, PSR_x | PSR_f | PSR_s},
405 {"CPSR_xfc", TRUE, PSR_x | PSR_f | PSR_c},
406 {"CPSR_xsf", TRUE, PSR_x | PSR_s | PSR_f},
407 {"CPSR_xsc", TRUE, PSR_x | PSR_s | PSR_c},
408 {"CPSR_xcf", TRUE, PSR_x | PSR_c | PSR_f},
409 {"CPSR_xcs", TRUE, PSR_x | PSR_c | PSR_s},
410 {"CPSR_cfs", TRUE, PSR_c | PSR_f | PSR_s},
411 {"CPSR_cfx", TRUE, PSR_c | PSR_f | PSR_x},
412 {"CPSR_csf", TRUE, PSR_c | PSR_s | PSR_f},
413 {"CPSR_csx", TRUE, PSR_c | PSR_s | PSR_x},
414 {"CPSR_cxf", TRUE, PSR_c | PSR_x | PSR_f},
415 {"CPSR_cxs", TRUE, PSR_c | PSR_x | PSR_s},
416 {"CPSR_fsxc", TRUE, PSR_f | PSR_s | PSR_x | PSR_c},
417 {"CPSR_fscx", TRUE, PSR_f | PSR_s | PSR_c | PSR_x},
418 {"CPSR_fxsc", TRUE, PSR_f | PSR_x | PSR_s | PSR_c},
419 {"CPSR_fxcs", TRUE, PSR_f | PSR_x | PSR_c | PSR_s},
420 {"CPSR_fcsx", TRUE, PSR_f | PSR_c | PSR_s | PSR_x},
421 {"CPSR_fcxs", TRUE, PSR_f | PSR_c | PSR_x | PSR_s},
422 {"CPSR_sfxc", TRUE, PSR_s | PSR_f | PSR_x | PSR_c},
423 {"CPSR_sfcx", TRUE, PSR_s | PSR_f | PSR_c | PSR_x},
424 {"CPSR_sxfc", TRUE, PSR_s | PSR_x | PSR_f | PSR_c},
425 {"CPSR_sxcf", TRUE, PSR_s | PSR_x | PSR_c | PSR_f},
426 {"CPSR_scfx", TRUE, PSR_s | PSR_c | PSR_f | PSR_x},
427 {"CPSR_scxf", TRUE, PSR_s | PSR_c | PSR_x | PSR_f},
428 {"CPSR_xfsc", TRUE, PSR_x | PSR_f | PSR_s | PSR_c},
429 {"CPSR_xfcs", TRUE, PSR_x | PSR_f | PSR_c | PSR_s},
430 {"CPSR_xsfc", TRUE, PSR_x | PSR_s | PSR_f | PSR_c},
431 {"CPSR_xscf", TRUE, PSR_x | PSR_s | PSR_c | PSR_f},
432 {"CPSR_xcfs", TRUE, PSR_x | PSR_c | PSR_f | PSR_s},
433 {"CPSR_xcsf", TRUE, PSR_x | PSR_c | PSR_s | PSR_f},
434 {"CPSR_cfsx", TRUE, PSR_c | PSR_f | PSR_s | PSR_x},
435 {"CPSR_cfxs", TRUE, PSR_c | PSR_f | PSR_x | PSR_s},
436 {"CPSR_csfx", TRUE, PSR_c | PSR_s | PSR_f | PSR_x},
437 {"CPSR_csxf", TRUE, PSR_c | PSR_s | PSR_x | PSR_f},
438 {"CPSR_cxfs", TRUE, PSR_c | PSR_x | PSR_f | PSR_s},
439 {"CPSR_cxsf", TRUE, PSR_c | PSR_x | PSR_s | PSR_f},
440 {"SPSR_fs", FALSE, PSR_f | PSR_s},
441 {"SPSR_fx", FALSE, PSR_f | PSR_x},
442 {"SPSR_fc", FALSE, PSR_f | PSR_c},
443 {"SPSR_sf", FALSE, PSR_s | PSR_f},
444 {"SPSR_sx", FALSE, PSR_s | PSR_x},
445 {"SPSR_sc", FALSE, PSR_s | PSR_c},
446 {"SPSR_xf", FALSE, PSR_x | PSR_f},
447 {"SPSR_xs", FALSE, PSR_x | PSR_s},
448 {"SPSR_xc", FALSE, PSR_x | PSR_c},
449 {"SPSR_cf", FALSE, PSR_c | PSR_f},
450 {"SPSR_cs", FALSE, PSR_c | PSR_s},
451 {"SPSR_cx", FALSE, PSR_c | PSR_x},
452 {"SPSR_fsx", FALSE, PSR_f | PSR_s | PSR_x},
453 {"SPSR_fsc", FALSE, PSR_f | PSR_s | PSR_c},
454 {"SPSR_fxs", FALSE, PSR_f | PSR_x | PSR_s},
455 {"SPSR_fxc", FALSE, PSR_f | PSR_x | PSR_c},
456 {"SPSR_fcs", FALSE, PSR_f | PSR_c | PSR_s},
457 {"SPSR_fcx", FALSE, PSR_f | PSR_c | PSR_x},
458 {"SPSR_sfx", FALSE, PSR_s | PSR_f | PSR_x},
459 {"SPSR_sfc", FALSE, PSR_s | PSR_f | PSR_c},
460 {"SPSR_sxf", FALSE, PSR_s | PSR_x | PSR_f},
461 {"SPSR_sxc", FALSE, PSR_s | PSR_x | PSR_c},
462 {"SPSR_scf", FALSE, PSR_s | PSR_c | PSR_f},
463 {"SPSR_scx", FALSE, PSR_s | PSR_c | PSR_x},
464 {"SPSR_xfs", FALSE, PSR_x | PSR_f | PSR_s},
465 {"SPSR_xfc", FALSE, PSR_x | PSR_f | PSR_c},
466 {"SPSR_xsf", FALSE, PSR_x | PSR_s | PSR_f},
467 {"SPSR_xsc", FALSE, PSR_x | PSR_s | PSR_c},
468 {"SPSR_xcf", FALSE, PSR_x | PSR_c | PSR_f},
469 {"SPSR_xcs", FALSE, PSR_x | PSR_c | PSR_s},
470 {"SPSR_cfs", FALSE, PSR_c | PSR_f | PSR_s},
471 {"SPSR_cfx", FALSE, PSR_c | PSR_f | PSR_x},
472 {"SPSR_csf", FALSE, PSR_c | PSR_s | PSR_f},
473 {"SPSR_csx", FALSE, PSR_c | PSR_s | PSR_x},
474 {"SPSR_cxf", FALSE, PSR_c | PSR_x | PSR_f},
475 {"SPSR_cxs", FALSE, PSR_c | PSR_x | PSR_s},
476 {"SPSR_fsxc", FALSE, PSR_f | PSR_s | PSR_x | PSR_c},
477 {"SPSR_fscx", FALSE, PSR_f | PSR_s | PSR_c | PSR_x},
478 {"SPSR_fxsc", FALSE, PSR_f | PSR_x | PSR_s | PSR_c},
479 {"SPSR_fxcs", FALSE, PSR_f | PSR_x | PSR_c | PSR_s},
480 {"SPSR_fcsx", FALSE, PSR_f | PSR_c | PSR_s | PSR_x},
481 {"SPSR_fcxs", FALSE, PSR_f | PSR_c | PSR_x | PSR_s},
482 {"SPSR_sfxc", FALSE, PSR_s | PSR_f | PSR_x | PSR_c},
483 {"SPSR_sfcx", FALSE, PSR_s | PSR_f | PSR_c | PSR_x},
484 {"SPSR_sxfc", FALSE, PSR_s | PSR_x | PSR_f | PSR_c},
485 {"SPSR_sxcf", FALSE, PSR_s | PSR_x | PSR_c | PSR_f},
486 {"SPSR_scfx", FALSE, PSR_s | PSR_c | PSR_f | PSR_x},
487 {"SPSR_scxf", FALSE, PSR_s | PSR_c | PSR_x | PSR_f},
488 {"SPSR_xfsc", FALSE, PSR_x | PSR_f | PSR_s | PSR_c},
489 {"SPSR_xfcs", FALSE, PSR_x | PSR_f | PSR_c | PSR_s},
490 {"SPSR_xsfc", FALSE, PSR_x | PSR_s | PSR_f | PSR_c},
491 {"SPSR_xscf", FALSE, PSR_x | PSR_s | PSR_c | PSR_f},
492 {"SPSR_xcfs", FALSE, PSR_x | PSR_c | PSR_f | PSR_s},
493 {"SPSR_xcsf", FALSE, PSR_x | PSR_c | PSR_s | PSR_f},
494 {"SPSR_cfsx", FALSE, PSR_c | PSR_f | PSR_s | PSR_x},
495 {"SPSR_cfxs", FALSE, PSR_c | PSR_f | PSR_x | PSR_s},
496 {"SPSR_csfx", FALSE, PSR_c | PSR_s | PSR_f | PSR_x},
497 {"SPSR_csxf", FALSE, PSR_c | PSR_s | PSR_x | PSR_f},
498 {"SPSR_cxfs", FALSE, PSR_c | PSR_x | PSR_f | PSR_s},
499 {"SPSR_cxsf", FALSE, PSR_c | PSR_x | PSR_s | PSR_f},
504 VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
509 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
514 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
517 /* VFP system registers. */
524 static const struct vfp_reg vfp_regs[] =
526 {"fpsid", 0x00000000},
527 {"FPSID", 0x00000000},
528 {"fpscr", 0x00010000},
529 {"FPSCR", 0x00010000},
530 {"fpexc", 0x00080000},
531 {"FPEXC", 0x00080000}
534 /* Structure for a hash table entry for a register. */
541 /* Some well known registers that we refer to directly elsewhere. */
546 /* These are the standard names. Users can add aliases with .req. */
547 /* Integer Register Numbers. */
548 static const struct reg_entry rn_table[] =
550 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
551 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
552 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
553 {"r12", 12}, {"r13", REG_SP}, {"r14", REG_LR}, {"r15", REG_PC},
554 /* ATPCS Synonyms. */
555 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
556 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7},
557 {"v5", 8}, {"v6", 9}, {"v7", 10}, {"v8", 11},
558 /* Well-known aliases. */
560 {"sb", 9}, {"sl", 10}, {"fp", 11},
561 {"ip", 12}, {"sp", REG_SP}, {"lr", REG_LR}, {"pc", REG_PC},
565 /* Co-processor Numbers. */
566 static const struct reg_entry cp_table[] =
568 {"p0", 0}, {"p1", 1}, {"p2", 2}, {"p3", 3},
569 {"p4", 4}, {"p5", 5}, {"p6", 6}, {"p7", 7},
570 {"p8", 8}, {"p9", 9}, {"p10", 10}, {"p11", 11},
571 {"p12", 12}, {"p13", 13}, {"p14", 14}, {"p15", 15},
575 /* Co-processor Register Numbers. */
576 static const struct reg_entry cn_table[] =
578 {"c0", 0}, {"c1", 1}, {"c2", 2}, {"c3", 3},
579 {"c4", 4}, {"c5", 5}, {"c6", 6}, {"c7", 7},
580 {"c8", 8}, {"c9", 9}, {"c10", 10}, {"c11", 11},
581 {"c12", 12}, {"c13", 13}, {"c14", 14}, {"c15", 15},
582 /* Not really valid, but kept for back-wards compatibility. */
583 {"cr0", 0}, {"cr1", 1}, {"cr2", 2}, {"cr3", 3},
584 {"cr4", 4}, {"cr5", 5}, {"cr6", 6}, {"cr7", 7},
585 {"cr8", 8}, {"cr9", 9}, {"cr10", 10}, {"cr11", 11},
586 {"cr12", 12}, {"cr13", 13}, {"cr14", 14}, {"cr15", 15},
591 static const struct reg_entry fn_table[] =
593 {"f0", 0}, {"f1", 1}, {"f2", 2}, {"f3", 3},
594 {"f4", 4}, {"f5", 5}, {"f6", 6}, {"f7", 7},
598 /* VFP SP Registers. */
599 static const struct reg_entry sn_table[] =
601 {"s0", 0}, {"s1", 1}, {"s2", 2}, {"s3", 3},
602 {"s4", 4}, {"s5", 5}, {"s6", 6}, {"s7", 7},
603 {"s8", 8}, {"s9", 9}, {"s10", 10}, {"s11", 11},
604 {"s12", 12}, {"s13", 13}, {"s14", 14}, {"s15", 15},
605 {"s16", 16}, {"s17", 17}, {"s18", 18}, {"s19", 19},
606 {"s20", 20}, {"s21", 21}, {"s22", 22}, {"s23", 23},
607 {"s24", 24}, {"s25", 25}, {"s26", 26}, {"s27", 27},
608 {"s28", 28}, {"s29", 29}, {"s30", 30}, {"s31", 31},
612 /* VFP DP Registers. */
613 static const struct reg_entry dn_table[] =
615 {"d0", 0}, {"d1", 1}, {"d2", 2}, {"d3", 3},
616 {"d4", 4}, {"d5", 5}, {"d6", 6}, {"d7", 7},
617 {"d8", 8}, {"d9", 9}, {"d10", 10}, {"d11", 11},
618 {"d12", 12}, {"d13", 13}, {"d14", 14}, {"d15", 15},
622 /* Maverick DSP coprocessor registers. */
623 static const struct reg_entry mav_mvf_table[] =
625 {"mvf0", 0}, {"mvf1", 1}, {"mvf2", 2}, {"mvf3", 3},
626 {"mvf4", 4}, {"mvf5", 5}, {"mvf6", 6}, {"mvf7", 7},
627 {"mvf8", 8}, {"mvf9", 9}, {"mvf10", 10}, {"mvf11", 11},
628 {"mvf12", 12}, {"mvf13", 13}, {"mvf14", 14}, {"mvf15", 15},
632 static const struct reg_entry mav_mvd_table[] =
634 {"mvd0", 0}, {"mvd1", 1}, {"mvd2", 2}, {"mvd3", 3},
635 {"mvd4", 4}, {"mvd5", 5}, {"mvd6", 6}, {"mvd7", 7},
636 {"mvd8", 8}, {"mvd9", 9}, {"mvd10", 10}, {"mvd11", 11},
637 {"mvd12", 12}, {"mvd13", 13}, {"mvd14", 14}, {"mvd15", 15},
641 static const struct reg_entry mav_mvfx_table[] =
643 {"mvfx0", 0}, {"mvfx1", 1}, {"mvfx2", 2}, {"mvfx3", 3},
644 {"mvfx4", 4}, {"mvfx5", 5}, {"mvfx6", 6}, {"mvfx7", 7},
645 {"mvfx8", 8}, {"mvfx9", 9}, {"mvfx10", 10}, {"mvfx11", 11},
646 {"mvfx12", 12}, {"mvfx13", 13}, {"mvfx14", 14}, {"mvfx15", 15},
650 static const struct reg_entry mav_mvdx_table[] =
652 {"mvdx0", 0}, {"mvdx1", 1}, {"mvdx2", 2}, {"mvdx3", 3},
653 {"mvdx4", 4}, {"mvdx5", 5}, {"mvdx6", 6}, {"mvdx7", 7},
654 {"mvdx8", 8}, {"mvdx9", 9}, {"mvdx10", 10}, {"mvdx11", 11},
655 {"mvdx12", 12}, {"mvdx13", 13}, {"mvdx14", 14}, {"mvdx15", 15},
659 static const struct reg_entry mav_mvax_table[] =
661 {"mvax0", 0}, {"mvax1", 1}, {"mvax2", 2}, {"mvax3", 3},
665 static const struct reg_entry mav_dspsc_table[] =
673 const struct reg_entry *names;
675 struct hash_control *htab;
676 const char *expected;
679 struct reg_map all_reg_maps[] =
681 {rn_table, 15, NULL, N_("ARM register expected")},
682 {cp_table, 15, NULL, N_("bad or missing co-processor number")},
683 {cn_table, 15, NULL, N_("co-processor register expected")},
684 {fn_table, 7, NULL, N_("FPA register expected")},
685 {sn_table, 31, NULL, N_("VFP single precision register expected")},
686 {dn_table, 15, NULL, N_("VFP double precision register expected")},
687 {mav_mvf_table, 15, NULL, N_("Maverick MVF register expected")},
688 {mav_mvd_table, 15, NULL, N_("Maverick MVD register expected")},
689 {mav_mvfx_table, 15, NULL, N_("Maverick MVFX register expected")},
690 {mav_mvdx_table, 15, NULL, N_("Maverick MVFX register expected")},
691 {mav_mvax_table, 3, NULL, N_("Maverick MVAX register expected")},
692 {mav_dspsc_table, 0, NULL, N_("Maverick DSPSC register expected")},
695 /* Enumeration matching entries in table above. */
699 #define REG_TYPE_FIRST REG_TYPE_RN
715 /* Functions called by parser. */
716 /* ARM instructions. */
717 static void do_arit PARAMS ((char *));
718 static void do_cmp PARAMS ((char *));
719 static void do_mov PARAMS ((char *));
720 static void do_ldst PARAMS ((char *));
721 static void do_ldstt PARAMS ((char *));
722 static void do_ldmstm PARAMS ((char *));
723 static void do_branch PARAMS ((char *));
724 static void do_swi PARAMS ((char *));
726 /* Pseudo Op codes. */
727 static void do_adr PARAMS ((char *));
728 static void do_adrl PARAMS ((char *));
729 static void do_empty PARAMS ((char *));
732 static void do_mul PARAMS ((char *));
733 static void do_mla PARAMS ((char *));
736 static void do_swap PARAMS ((char *));
739 static void do_msr PARAMS ((char *));
740 static void do_mrs PARAMS ((char *));
743 static void do_mull PARAMS ((char *));
746 static void do_ldstv4 PARAMS ((char *));
749 static void do_bx PARAMS ((char *));
752 static void do_blx PARAMS ((char *));
753 static void do_bkpt PARAMS ((char *));
754 static void do_clz PARAMS ((char *));
755 static void do_lstc2 PARAMS ((char *));
756 static void do_cdp2 PARAMS ((char *));
757 static void do_co_reg2 PARAMS ((char *));
760 static void do_smla PARAMS ((char *));
761 static void do_smlal PARAMS ((char *));
762 static void do_smul PARAMS ((char *));
763 static void do_qadd PARAMS ((char *));
766 static void do_pld PARAMS ((char *));
767 static void do_ldrd PARAMS ((char *));
768 static void do_co_reg2c PARAMS ((char *));
771 static void do_bxj PARAMS ((char *));
773 /* Coprocessor Instructions. */
774 static void do_cdp PARAMS ((char *));
775 static void do_lstc PARAMS ((char *));
776 static void do_co_reg PARAMS ((char *));
778 /* FPA instructions. */
779 static void do_fpa_ctrl PARAMS ((char *));
780 static void do_fpa_ldst PARAMS ((char *));
781 static void do_fpa_ldmstm PARAMS ((char *));
782 static void do_fpa_dyadic PARAMS ((char *));
783 static void do_fpa_monadic PARAMS ((char *));
784 static void do_fpa_cmp PARAMS ((char *));
785 static void do_fpa_from_reg PARAMS ((char *));
786 static void do_fpa_to_reg PARAMS ((char *));
788 /* VFP instructions. */
789 static void do_vfp_sp_monadic PARAMS ((char *));
790 static void do_vfp_dp_monadic PARAMS ((char *));
791 static void do_vfp_sp_dyadic PARAMS ((char *));
792 static void do_vfp_dp_dyadic PARAMS ((char *));
793 static void do_vfp_reg_from_sp PARAMS ((char *));
794 static void do_vfp_sp_from_reg PARAMS ((char *));
795 static void do_vfp_sp_reg2 PARAMS ((char *));
796 static void do_vfp_reg_from_dp PARAMS ((char *));
797 static void do_vfp_reg2_from_dp PARAMS ((char *));
798 static void do_vfp_dp_from_reg PARAMS ((char *));
799 static void do_vfp_dp_from_reg2 PARAMS ((char *));
800 static void do_vfp_reg_from_ctrl PARAMS ((char *));
801 static void do_vfp_ctrl_from_reg PARAMS ((char *));
802 static void do_vfp_sp_ldst PARAMS ((char *));
803 static void do_vfp_dp_ldst PARAMS ((char *));
804 static void do_vfp_sp_ldstmia PARAMS ((char *));
805 static void do_vfp_sp_ldstmdb PARAMS ((char *));
806 static void do_vfp_dp_ldstmia PARAMS ((char *));
807 static void do_vfp_dp_ldstmdb PARAMS ((char *));
808 static void do_vfp_xp_ldstmia PARAMS ((char *));
809 static void do_vfp_xp_ldstmdb PARAMS ((char *));
810 static void do_vfp_sp_compare_z PARAMS ((char *));
811 static void do_vfp_dp_compare_z PARAMS ((char *));
812 static void do_vfp_dp_sp_cvt PARAMS ((char *));
813 static void do_vfp_sp_dp_cvt PARAMS ((char *));
816 static void do_xsc_mia PARAMS ((char *));
817 static void do_xsc_mar PARAMS ((char *));
818 static void do_xsc_mra PARAMS ((char *));
821 static void do_mav_binops PARAMS ((char *, int, enum arm_reg_type,
823 static void do_mav_binops_1a PARAMS ((char *));
824 static void do_mav_binops_1b PARAMS ((char *));
825 static void do_mav_binops_1c PARAMS ((char *));
826 static void do_mav_binops_1d PARAMS ((char *));
827 static void do_mav_binops_1e PARAMS ((char *));
828 static void do_mav_binops_1f PARAMS ((char *));
829 static void do_mav_binops_1g PARAMS ((char *));
830 static void do_mav_binops_1h PARAMS ((char *));
831 static void do_mav_binops_1i PARAMS ((char *));
832 static void do_mav_binops_1j PARAMS ((char *));
833 static void do_mav_binops_1k PARAMS ((char *));
834 static void do_mav_binops_1l PARAMS ((char *));
835 static void do_mav_binops_1m PARAMS ((char *));
836 static void do_mav_binops_1n PARAMS ((char *));
837 static void do_mav_binops_1o PARAMS ((char *));
838 static void do_mav_binops_2a PARAMS ((char *));
839 static void do_mav_binops_2b PARAMS ((char *));
840 static void do_mav_binops_2c PARAMS ((char *));
841 static void do_mav_binops_3a PARAMS ((char *));
842 static void do_mav_binops_3b PARAMS ((char *));
843 static void do_mav_binops_3c PARAMS ((char *));
844 static void do_mav_binops_3d PARAMS ((char *));
845 static void do_mav_triple PARAMS ((char *, int, enum arm_reg_type,
848 static void do_mav_triple_4a PARAMS ((char *));
849 static void do_mav_triple_4b PARAMS ((char *));
850 static void do_mav_triple_5a PARAMS ((char *));
851 static void do_mav_triple_5b PARAMS ((char *));
852 static void do_mav_triple_5c PARAMS ((char *));
853 static void do_mav_triple_5d PARAMS ((char *));
854 static void do_mav_triple_5e PARAMS ((char *));
855 static void do_mav_triple_5f PARAMS ((char *));
856 static void do_mav_triple_5g PARAMS ((char *));
857 static void do_mav_triple_5h PARAMS ((char *));
858 static void do_mav_quad PARAMS ((char *, int, enum arm_reg_type,
862 static void do_mav_quad_6a PARAMS ((char *));
863 static void do_mav_quad_6b PARAMS ((char *));
864 static void do_mav_dspsc_1 PARAMS ((char *));
865 static void do_mav_dspsc_2 PARAMS ((char *));
866 static void do_mav_shift PARAMS ((char *, enum arm_reg_type,
868 static void do_mav_shift_1 PARAMS ((char *));
869 static void do_mav_shift_2 PARAMS ((char *));
870 static void do_mav_ldst PARAMS ((char *, enum arm_reg_type));
871 static void do_mav_ldst_1 PARAMS ((char *));
872 static void do_mav_ldst_2 PARAMS ((char *));
873 static void do_mav_ldst_3 PARAMS ((char *));
874 static void do_mav_ldst_4 PARAMS ((char *));
876 static int mav_reg_required_here PARAMS ((char **, int,
878 static int mav_parse_offset PARAMS ((char **, int *));
880 static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *,
882 static int arm_reg_parse PARAMS ((char **, struct hash_control *));
883 static enum arm_reg_type arm_reg_parse_any PARAMS ((char *));
884 static const struct asm_psr * arm_psr_parse PARAMS ((char **));
885 static void symbol_locate PARAMS ((symbolS *, const char *, segT, valueT,
887 static int add_to_lit_pool PARAMS ((void));
888 static unsigned validate_immediate PARAMS ((unsigned));
889 static unsigned validate_immediate_twopart PARAMS ((unsigned int,
891 static int validate_offset_imm PARAMS ((unsigned int, int));
892 static void opcode_select PARAMS ((int));
893 static void end_of_line PARAMS ((char *));
894 static int reg_required_here PARAMS ((char **, int));
895 static int psr_required_here PARAMS ((char **));
896 static int co_proc_number PARAMS ((char **));
897 static int cp_opc_expr PARAMS ((char **, int, int));
898 static int cp_reg_required_here PARAMS ((char **, int));
899 static int fp_reg_required_here PARAMS ((char **, int));
900 static int vfp_sp_reg_required_here PARAMS ((char **, enum vfp_sp_reg_pos));
901 static int vfp_dp_reg_required_here PARAMS ((char **, enum vfp_dp_reg_pos));
902 static void vfp_sp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
903 static void vfp_dp_ldstm PARAMS ((char *, enum vfp_ldstm_type));
904 static long vfp_sp_reg_list PARAMS ((char **, enum vfp_sp_reg_pos));
905 static long vfp_dp_reg_list PARAMS ((char **));
906 static int vfp_psr_required_here PARAMS ((char **str));
907 static const struct vfp_reg *vfp_psr_parse PARAMS ((char **str));
908 static int cp_address_offset PARAMS ((char **));
909 static int cp_address_required_here PARAMS ((char **, int));
910 static int my_get_float_expression PARAMS ((char **));
911 static int skip_past_comma PARAMS ((char **));
912 static int walk_no_bignums PARAMS ((symbolS *));
913 static int negate_data_op PARAMS ((unsigned long *, unsigned long));
914 static int data_op2 PARAMS ((char **));
915 static int fp_op2 PARAMS ((char **));
916 static long reg_list PARAMS ((char **));
917 static void thumb_load_store PARAMS ((char *, int, int));
918 static int decode_shift PARAMS ((char **, int));
919 static int ldst_extend PARAMS ((char **));
920 static int ldst_extend_v4 PARAMS ((char **));
921 static void thumb_add_sub PARAMS ((char *, int));
922 static void insert_reg PARAMS ((const struct reg_entry *,
923 struct hash_control *));
924 static void thumb_shift PARAMS ((char *, int));
925 static void thumb_mov_compare PARAMS ((char *, int));
926 static void build_arm_ops_hsh PARAMS ((void));
927 static void set_constant_flonums PARAMS ((void));
928 static valueT md_chars_to_number PARAMS ((char *, int));
929 static void build_reg_hsh PARAMS ((struct reg_map *));
930 static void insert_reg_alias PARAMS ((char *, int, struct hash_control *));
931 static int create_register_alias PARAMS ((char *, char *));
932 static void output_inst PARAMS ((const char *));
933 static int accum0_required_here PARAMS ((char **));
934 static int ld_mode_required_here PARAMS ((char **));
935 static void do_branch25 PARAMS ((char *));
936 static symbolS * find_real_start PARAMS ((symbolS *));
938 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
941 /* ARM instructions take 4bytes in the object file, Thumb instructions
945 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
946 #define MAV_MODE1 0x100c
948 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
949 #define MAV_MODE2 0x0c10
951 /* "INSN<cond> X,Y" where X:0, Y:bit16. */
952 #define MAV_MODE3 0x1000
954 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
955 #define MAV_MODE4 0x0c0010
957 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
958 #define MAV_MODE5 0x00100c
960 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
961 #define MAV_MODE6 0x00100c05
965 /* Basic string to match. */
966 const char * template;
968 /* Basic instruction code. */
971 /* Offset into the template where the condition code (if any) will be.
972 If zero, then the instruction is never conditional. */
973 unsigned cond_offset;
975 /* Which architecture variant provides this instruction. */
976 unsigned long variant;
978 /* Function to call to parse args. */
979 void (* parms) PARAMS ((char *));
982 static const struct asm_opcode insns[] =
984 /* Core ARM Instructions. */
985 {"and", 0xe0000000, 3, ARM_EXT_V1, do_arit},
986 {"ands", 0xe0100000, 3, ARM_EXT_V1, do_arit},
987 {"eor", 0xe0200000, 3, ARM_EXT_V1, do_arit},
988 {"eors", 0xe0300000, 3, ARM_EXT_V1, do_arit},
989 {"sub", 0xe0400000, 3, ARM_EXT_V1, do_arit},
990 {"subs", 0xe0500000, 3, ARM_EXT_V1, do_arit},
991 {"rsb", 0xe0600000, 3, ARM_EXT_V1, do_arit},
992 {"rsbs", 0xe0700000, 3, ARM_EXT_V1, do_arit},
993 {"add", 0xe0800000, 3, ARM_EXT_V1, do_arit},
994 {"adds", 0xe0900000, 3, ARM_EXT_V1, do_arit},
995 {"adc", 0xe0a00000, 3, ARM_EXT_V1, do_arit},
996 {"adcs", 0xe0b00000, 3, ARM_EXT_V1, do_arit},
997 {"sbc", 0xe0c00000, 3, ARM_EXT_V1, do_arit},
998 {"sbcs", 0xe0d00000, 3, ARM_EXT_V1, do_arit},
999 {"rsc", 0xe0e00000, 3, ARM_EXT_V1, do_arit},
1000 {"rscs", 0xe0f00000, 3, ARM_EXT_V1, do_arit},
1001 {"orr", 0xe1800000, 3, ARM_EXT_V1, do_arit},
1002 {"orrs", 0xe1900000, 3, ARM_EXT_V1, do_arit},
1003 {"bic", 0xe1c00000, 3, ARM_EXT_V1, do_arit},
1004 {"bics", 0xe1d00000, 3, ARM_EXT_V1, do_arit},
1006 {"tst", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
1007 {"tsts", 0xe1100000, 3, ARM_EXT_V1, do_cmp},
1008 {"tstp", 0xe110f000, 3, ARM_EXT_V1, do_cmp},
1009 {"teq", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
1010 {"teqs", 0xe1300000, 3, ARM_EXT_V1, do_cmp},
1011 {"teqp", 0xe130f000, 3, ARM_EXT_V1, do_cmp},
1012 {"cmp", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
1013 {"cmps", 0xe1500000, 3, ARM_EXT_V1, do_cmp},
1014 {"cmpp", 0xe150f000, 3, ARM_EXT_V1, do_cmp},
1015 {"cmn", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
1016 {"cmns", 0xe1700000, 3, ARM_EXT_V1, do_cmp},
1017 {"cmnp", 0xe170f000, 3, ARM_EXT_V1, do_cmp},
1019 {"mov", 0xe1a00000, 3, ARM_EXT_V1, do_mov},
1020 {"movs", 0xe1b00000, 3, ARM_EXT_V1, do_mov},
1021 {"mvn", 0xe1e00000, 3, ARM_EXT_V1, do_mov},
1022 {"mvns", 0xe1f00000, 3, ARM_EXT_V1, do_mov},
1024 {"ldr", 0xe4100000, 3, ARM_EXT_V1, do_ldst},
1025 {"ldrb", 0xe4500000, 3, ARM_EXT_V1, do_ldst},
1026 {"ldrt", 0xe4300000, 3, ARM_EXT_V1, do_ldstt},
1027 {"ldrbt", 0xe4700000, 3, ARM_EXT_V1, do_ldstt},
1028 {"str", 0xe4000000, 3, ARM_EXT_V1, do_ldst},
1029 {"strb", 0xe4400000, 3, ARM_EXT_V1, do_ldst},
1030 {"strt", 0xe4200000, 3, ARM_EXT_V1, do_ldstt},
1031 {"strbt", 0xe4600000, 3, ARM_EXT_V1, do_ldstt},
1033 {"stmia", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
1034 {"stmib", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
1035 {"stmda", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
1036 {"stmdb", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
1037 {"stmfd", 0xe9000000, 3, ARM_EXT_V1, do_ldmstm},
1038 {"stmfa", 0xe9800000, 3, ARM_EXT_V1, do_ldmstm},
1039 {"stmea", 0xe8800000, 3, ARM_EXT_V1, do_ldmstm},
1040 {"stmed", 0xe8000000, 3, ARM_EXT_V1, do_ldmstm},
1042 {"ldmia", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
1043 {"ldmib", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
1044 {"ldmda", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
1045 {"ldmdb", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
1046 {"ldmfd", 0xe8900000, 3, ARM_EXT_V1, do_ldmstm},
1047 {"ldmfa", 0xe8100000, 3, ARM_EXT_V1, do_ldmstm},
1048 {"ldmea", 0xe9100000, 3, ARM_EXT_V1, do_ldmstm},
1049 {"ldmed", 0xe9900000, 3, ARM_EXT_V1, do_ldmstm},
1051 {"swi", 0xef000000, 3, ARM_EXT_V1, do_swi},
1053 /* XXX This is the wrong place to do this. Think multi-arch. */
1054 {"bl", 0xeb000000, 2, ARM_EXT_V1, do_branch},
1055 {"b", 0xea000000, 1, ARM_EXT_V1, do_branch},
1057 {"bl", 0xebfffffe, 2, ARM_EXT_V1, do_branch},
1058 {"b", 0xeafffffe, 1, ARM_EXT_V1, do_branch},
1062 {"adr", 0xe28f0000, 3, ARM_EXT_V1, do_adr},
1063 {"adrl", 0xe28f0000, 3, ARM_EXT_V1, do_adrl},
1064 {"nop", 0xe1a00000, 3, ARM_EXT_V1, do_empty},
1066 /* ARM 2 multiplies. */
1067 {"mul", 0xe0000090, 3, ARM_EXT_V2, do_mul},
1068 {"muls", 0xe0100090, 3, ARM_EXT_V2, do_mul},
1069 {"mla", 0xe0200090, 3, ARM_EXT_V2, do_mla},
1070 {"mlas", 0xe0300090, 3, ARM_EXT_V2, do_mla},
1072 /* Generic copressor instructions. */
1073 {"cdp", 0xee000000, 3, ARM_EXT_V2, do_cdp},
1074 {"ldc", 0xec100000, 3, ARM_EXT_V2, do_lstc},
1075 {"ldcl", 0xec500000, 3, ARM_EXT_V2, do_lstc},
1076 {"stc", 0xec000000, 3, ARM_EXT_V2, do_lstc},
1077 {"stcl", 0xec400000, 3, ARM_EXT_V2, do_lstc},
1078 {"mcr", 0xee000010, 3, ARM_EXT_V2, do_co_reg},
1079 {"mrc", 0xee100010, 3, ARM_EXT_V2, do_co_reg},
1081 /* ARM 3 - swp instructions. */
1082 {"swp", 0xe1000090, 3, ARM_EXT_V2S, do_swap},
1083 {"swpb", 0xe1400090, 3, ARM_EXT_V2S, do_swap},
1085 /* ARM 6 Status register instructions. */
1086 {"mrs", 0xe10f0000, 3, ARM_EXT_V3, do_mrs},
1087 {"msr", 0xe120f000, 3, ARM_EXT_V3, do_msr},
1088 /* ScottB: our code uses 0xe128f000 for msr.
1089 NickC: but this is wrong because the bits 16 through 19 are
1090 handled by the PSR_xxx defines above. */
1092 /* ARM 7M long multiplies. */
1093 {"smull", 0xe0c00090, 5, ARM_EXT_V3M, do_mull},
1094 {"smulls", 0xe0d00090, 5, ARM_EXT_V3M, do_mull},
1095 {"umull", 0xe0800090, 5, ARM_EXT_V3M, do_mull},
1096 {"umulls", 0xe0900090, 5, ARM_EXT_V3M, do_mull},
1097 {"smlal", 0xe0e00090, 5, ARM_EXT_V3M, do_mull},
1098 {"smlals", 0xe0f00090, 5, ARM_EXT_V3M, do_mull},
1099 {"umlal", 0xe0a00090, 5, ARM_EXT_V3M, do_mull},
1100 {"umlals", 0xe0b00090, 5, ARM_EXT_V3M, do_mull},
1102 /* ARM Architecture 4. */
1103 {"ldrh", 0xe01000b0, 3, ARM_EXT_V4, do_ldstv4},
1104 {"ldrsh", 0xe01000f0, 3, ARM_EXT_V4, do_ldstv4},
1105 {"ldrsb", 0xe01000d0, 3, ARM_EXT_V4, do_ldstv4},
1106 {"strh", 0xe00000b0, 3, ARM_EXT_V4, do_ldstv4},
1108 /* ARM Architecture 4T. */
1109 /* Note: bx (and blx) are required on V5, even if the processor does
1110 not support Thumb. */
1111 {"bx", 0xe12fff10, 2, ARM_EXT_V4T | ARM_EXT_V5, do_bx},
1113 /* ARM Architecture 5T. */
1114 /* Note: blx has 2 variants, so the .value is set dynamically.
1115 Only one of the variants has conditional execution. */
1116 {"blx", 0xe0000000, 3, ARM_EXT_V5, do_blx},
1117 {"clz", 0xe16f0f10, 3, ARM_EXT_V5, do_clz},
1118 {"bkpt", 0xe1200070, 0, ARM_EXT_V5, do_bkpt},
1119 {"ldc2", 0xfc100000, 0, ARM_EXT_V5, do_lstc2},
1120 {"ldc2l", 0xfc500000, 0, ARM_EXT_V5, do_lstc2},
1121 {"stc2", 0xfc000000, 0, ARM_EXT_V5, do_lstc2},
1122 {"stc2l", 0xfc400000, 0, ARM_EXT_V5, do_lstc2},
1123 {"cdp2", 0xfe000000, 0, ARM_EXT_V5, do_cdp2},
1124 {"mcr2", 0xfe000010, 0, ARM_EXT_V5, do_co_reg2},
1125 {"mrc2", 0xfe100010, 0, ARM_EXT_V5, do_co_reg2},
1127 /* ARM Architecture 5TExP. */
1128 {"smlabb", 0xe1000080, 6, ARM_EXT_V5ExP, do_smla},
1129 {"smlatb", 0xe10000a0, 6, ARM_EXT_V5ExP, do_smla},
1130 {"smlabt", 0xe10000c0, 6, ARM_EXT_V5ExP, do_smla},
1131 {"smlatt", 0xe10000e0, 6, ARM_EXT_V5ExP, do_smla},
1133 {"smlawb", 0xe1200080, 6, ARM_EXT_V5ExP, do_smla},
1134 {"smlawt", 0xe12000c0, 6, ARM_EXT_V5ExP, do_smla},
1136 {"smlalbb", 0xe1400080, 7, ARM_EXT_V5ExP, do_smlal},
1137 {"smlaltb", 0xe14000a0, 7, ARM_EXT_V5ExP, do_smlal},
1138 {"smlalbt", 0xe14000c0, 7, ARM_EXT_V5ExP, do_smlal},
1139 {"smlaltt", 0xe14000e0, 7, ARM_EXT_V5ExP, do_smlal},
1141 {"smulbb", 0xe1600080, 6, ARM_EXT_V5ExP, do_smul},
1142 {"smultb", 0xe16000a0, 6, ARM_EXT_V5ExP, do_smul},
1143 {"smulbt", 0xe16000c0, 6, ARM_EXT_V5ExP, do_smul},
1144 {"smultt", 0xe16000e0, 6, ARM_EXT_V5ExP, do_smul},
1146 {"smulwb", 0xe12000a0, 6, ARM_EXT_V5ExP, do_smul},
1147 {"smulwt", 0xe12000e0, 6, ARM_EXT_V5ExP, do_smul},
1149 {"qadd", 0xe1000050, 4, ARM_EXT_V5ExP, do_qadd},
1150 {"qdadd", 0xe1400050, 5, ARM_EXT_V5ExP, do_qadd},
1151 {"qsub", 0xe1200050, 4, ARM_EXT_V5ExP, do_qadd},
1152 {"qdsub", 0xe1600050, 5, ARM_EXT_V5ExP, do_qadd},
1154 /* ARM Architecture 5TE. */
1155 {"pld", 0xf450f000, 0, ARM_EXT_V5E, do_pld},
1156 {"ldrd", 0xe00000d0, 3, ARM_EXT_V5E, do_ldrd},
1157 {"strd", 0xe00000f0, 3, ARM_EXT_V5E, do_ldrd},
1159 {"mcrr", 0xec400000, 4, ARM_EXT_V5E, do_co_reg2c},
1160 {"mrrc", 0xec500000, 4, ARM_EXT_V5E, do_co_reg2c},
1162 /* ARM Architecture 5TEJ. */
1163 {"bxj", 0xe12fff20, 3, ARM_EXT_V5J, do_bxj},
1165 /* Core FPA instruction set (V1). */
1166 {"wfs", 0xee200110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1167 {"rfs", 0xee300110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1168 {"wfc", 0xee400110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1169 {"rfc", 0xee500110, 3, FPU_FPA_EXT_V1, do_fpa_ctrl},
1171 {"ldfs", 0xec100100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1172 {"ldfd", 0xec108100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1173 {"ldfe", 0xec500100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1174 {"ldfp", 0xec508100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1176 {"stfs", 0xec000100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1177 {"stfd", 0xec008100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1178 {"stfe", 0xec400100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1179 {"stfp", 0xec408100, 3, FPU_FPA_EXT_V1, do_fpa_ldst},
1181 {"mvfs", 0xee008100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1182 {"mvfsp", 0xee008120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1183 {"mvfsm", 0xee008140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1184 {"mvfsz", 0xee008160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1185 {"mvfd", 0xee008180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1186 {"mvfdp", 0xee0081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1187 {"mvfdm", 0xee0081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1188 {"mvfdz", 0xee0081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1189 {"mvfe", 0xee088100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1190 {"mvfep", 0xee088120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1191 {"mvfem", 0xee088140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1192 {"mvfez", 0xee088160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1194 {"mnfs", 0xee108100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1195 {"mnfsp", 0xee108120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1196 {"mnfsm", 0xee108140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1197 {"mnfsz", 0xee108160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1198 {"mnfd", 0xee108180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1199 {"mnfdp", 0xee1081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1200 {"mnfdm", 0xee1081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1201 {"mnfdz", 0xee1081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1202 {"mnfe", 0xee188100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1203 {"mnfep", 0xee188120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1204 {"mnfem", 0xee188140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1205 {"mnfez", 0xee188160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1207 {"abss", 0xee208100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1208 {"abssp", 0xee208120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1209 {"abssm", 0xee208140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1210 {"abssz", 0xee208160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1211 {"absd", 0xee208180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1212 {"absdp", 0xee2081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1213 {"absdm", 0xee2081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1214 {"absdz", 0xee2081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1215 {"abse", 0xee288100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1216 {"absep", 0xee288120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1217 {"absem", 0xee288140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1218 {"absez", 0xee288160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1220 {"rnds", 0xee308100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1221 {"rndsp", 0xee308120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1222 {"rndsm", 0xee308140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1223 {"rndsz", 0xee308160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1224 {"rndd", 0xee308180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1225 {"rnddp", 0xee3081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1226 {"rnddm", 0xee3081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1227 {"rnddz", 0xee3081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1228 {"rnde", 0xee388100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1229 {"rndep", 0xee388120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1230 {"rndem", 0xee388140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1231 {"rndez", 0xee388160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1233 {"sqts", 0xee408100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1234 {"sqtsp", 0xee408120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1235 {"sqtsm", 0xee408140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1236 {"sqtsz", 0xee408160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1237 {"sqtd", 0xee408180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1238 {"sqtdp", 0xee4081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1239 {"sqtdm", 0xee4081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1240 {"sqtdz", 0xee4081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1241 {"sqte", 0xee488100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1242 {"sqtep", 0xee488120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1243 {"sqtem", 0xee488140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1244 {"sqtez", 0xee488160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1246 {"logs", 0xee508100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1247 {"logsp", 0xee508120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1248 {"logsm", 0xee508140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1249 {"logsz", 0xee508160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1250 {"logd", 0xee508180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1251 {"logdp", 0xee5081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1252 {"logdm", 0xee5081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1253 {"logdz", 0xee5081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1254 {"loge", 0xee588100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1255 {"logep", 0xee588120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1256 {"logem", 0xee588140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1257 {"logez", 0xee588160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1259 {"lgns", 0xee608100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1260 {"lgnsp", 0xee608120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1261 {"lgnsm", 0xee608140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1262 {"lgnsz", 0xee608160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1263 {"lgnd", 0xee608180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1264 {"lgndp", 0xee6081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1265 {"lgndm", 0xee6081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1266 {"lgndz", 0xee6081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1267 {"lgne", 0xee688100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1268 {"lgnep", 0xee688120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1269 {"lgnem", 0xee688140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1270 {"lgnez", 0xee688160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1272 {"exps", 0xee708100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1273 {"expsp", 0xee708120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1274 {"expsm", 0xee708140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1275 {"expsz", 0xee708160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1276 {"expd", 0xee708180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1277 {"expdp", 0xee7081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1278 {"expdm", 0xee7081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1279 {"expdz", 0xee7081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1280 {"expe", 0xee788100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1281 {"expep", 0xee788120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1282 {"expem", 0xee788140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1283 {"expdz", 0xee788160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1285 {"sins", 0xee808100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1286 {"sinsp", 0xee808120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1287 {"sinsm", 0xee808140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1288 {"sinsz", 0xee808160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1289 {"sind", 0xee808180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1290 {"sindp", 0xee8081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1291 {"sindm", 0xee8081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1292 {"sindz", 0xee8081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1293 {"sine", 0xee888100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1294 {"sinep", 0xee888120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1295 {"sinem", 0xee888140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1296 {"sinez", 0xee888160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1298 {"coss", 0xee908100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1299 {"cossp", 0xee908120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1300 {"cossm", 0xee908140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1301 {"cossz", 0xee908160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1302 {"cosd", 0xee908180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1303 {"cosdp", 0xee9081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1304 {"cosdm", 0xee9081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1305 {"cosdz", 0xee9081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1306 {"cose", 0xee988100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1307 {"cosep", 0xee988120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1308 {"cosem", 0xee988140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1309 {"cosez", 0xee988160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1311 {"tans", 0xeea08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1312 {"tansp", 0xeea08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1313 {"tansm", 0xeea08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1314 {"tansz", 0xeea08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1315 {"tand", 0xeea08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1316 {"tandp", 0xeea081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1317 {"tandm", 0xeea081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1318 {"tandz", 0xeea081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1319 {"tane", 0xeea88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1320 {"tanep", 0xeea88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1321 {"tanem", 0xeea88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1322 {"tanez", 0xeea88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1324 {"asns", 0xeeb08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1325 {"asnsp", 0xeeb08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1326 {"asnsm", 0xeeb08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1327 {"asnsz", 0xeeb08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1328 {"asnd", 0xeeb08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1329 {"asndp", 0xeeb081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1330 {"asndm", 0xeeb081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1331 {"asndz", 0xeeb081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1332 {"asne", 0xeeb88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1333 {"asnep", 0xeeb88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1334 {"asnem", 0xeeb88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1335 {"asnez", 0xeeb88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1337 {"acss", 0xeec08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1338 {"acssp", 0xeec08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1339 {"acssm", 0xeec08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1340 {"acssz", 0xeec08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1341 {"acsd", 0xeec08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1342 {"acsdp", 0xeec081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1343 {"acsdm", 0xeec081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1344 {"acsdz", 0xeec081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1345 {"acse", 0xeec88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1346 {"acsep", 0xeec88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1347 {"acsem", 0xeec88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1348 {"acsez", 0xeec88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1350 {"atns", 0xeed08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1351 {"atnsp", 0xeed08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1352 {"atnsm", 0xeed08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1353 {"atnsz", 0xeed08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1354 {"atnd", 0xeed08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1355 {"atndp", 0xeed081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1356 {"atndm", 0xeed081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1357 {"atndz", 0xeed081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1358 {"atne", 0xeed88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1359 {"atnep", 0xeed88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1360 {"atnem", 0xeed88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1361 {"atnez", 0xeed88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1363 {"urds", 0xeee08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1364 {"urdsp", 0xeee08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1365 {"urdsm", 0xeee08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1366 {"urdsz", 0xeee08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1367 {"urdd", 0xeee08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1368 {"urddp", 0xeee081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1369 {"urddm", 0xeee081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1370 {"urddz", 0xeee081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1371 {"urde", 0xeee88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1372 {"urdep", 0xeee88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1373 {"urdem", 0xeee88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1374 {"urdez", 0xeee88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1376 {"nrms", 0xeef08100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1377 {"nrmsp", 0xeef08120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1378 {"nrmsm", 0xeef08140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1379 {"nrmsz", 0xeef08160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1380 {"nrmd", 0xeef08180, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1381 {"nrmdp", 0xeef081a0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1382 {"nrmdm", 0xeef081c0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1383 {"nrmdz", 0xeef081e0, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1384 {"nrme", 0xeef88100, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1385 {"nrmep", 0xeef88120, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1386 {"nrmem", 0xeef88140, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1387 {"nrmez", 0xeef88160, 3, FPU_FPA_EXT_V1, do_fpa_monadic},
1389 {"adfs", 0xee000100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1390 {"adfsp", 0xee000120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1391 {"adfsm", 0xee000140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1392 {"adfsz", 0xee000160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1393 {"adfd", 0xee000180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1394 {"adfdp", 0xee0001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1395 {"adfdm", 0xee0001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1396 {"adfdz", 0xee0001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1397 {"adfe", 0xee080100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1398 {"adfep", 0xee080120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1399 {"adfem", 0xee080140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1400 {"adfez", 0xee080160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1402 {"sufs", 0xee200100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1403 {"sufsp", 0xee200120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1404 {"sufsm", 0xee200140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1405 {"sufsz", 0xee200160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1406 {"sufd", 0xee200180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1407 {"sufdp", 0xee2001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1408 {"sufdm", 0xee2001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1409 {"sufdz", 0xee2001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1410 {"sufe", 0xee280100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1411 {"sufep", 0xee280120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1412 {"sufem", 0xee280140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1413 {"sufez", 0xee280160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1415 {"rsfs", 0xee300100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1416 {"rsfsp", 0xee300120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1417 {"rsfsm", 0xee300140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1418 {"rsfsz", 0xee300160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1419 {"rsfd", 0xee300180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1420 {"rsfdp", 0xee3001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1421 {"rsfdm", 0xee3001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1422 {"rsfdz", 0xee3001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1423 {"rsfe", 0xee380100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1424 {"rsfep", 0xee380120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1425 {"rsfem", 0xee380140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1426 {"rsfez", 0xee380160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1428 {"mufs", 0xee100100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1429 {"mufsp", 0xee100120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1430 {"mufsm", 0xee100140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1431 {"mufsz", 0xee100160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1432 {"mufd", 0xee100180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1433 {"mufdp", 0xee1001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1434 {"mufdm", 0xee1001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1435 {"mufdz", 0xee1001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1436 {"mufe", 0xee180100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1437 {"mufep", 0xee180120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1438 {"mufem", 0xee180140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1439 {"mufez", 0xee180160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1441 {"dvfs", 0xee400100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1442 {"dvfsp", 0xee400120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1443 {"dvfsm", 0xee400140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1444 {"dvfsz", 0xee400160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1445 {"dvfd", 0xee400180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1446 {"dvfdp", 0xee4001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1447 {"dvfdm", 0xee4001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1448 {"dvfdz", 0xee4001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1449 {"dvfe", 0xee480100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1450 {"dvfep", 0xee480120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1451 {"dvfem", 0xee480140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1452 {"dvfez", 0xee480160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1454 {"rdfs", 0xee500100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1455 {"rdfsp", 0xee500120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1456 {"rdfsm", 0xee500140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1457 {"rdfsz", 0xee500160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1458 {"rdfd", 0xee500180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1459 {"rdfdp", 0xee5001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1460 {"rdfdm", 0xee5001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1461 {"rdfdz", 0xee5001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1462 {"rdfe", 0xee580100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1463 {"rdfep", 0xee580120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1464 {"rdfem", 0xee580140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1465 {"rdfez", 0xee580160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1467 {"pows", 0xee600100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1468 {"powsp", 0xee600120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1469 {"powsm", 0xee600140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1470 {"powsz", 0xee600160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1471 {"powd", 0xee600180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1472 {"powdp", 0xee6001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1473 {"powdm", 0xee6001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1474 {"powdz", 0xee6001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1475 {"powe", 0xee680100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1476 {"powep", 0xee680120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1477 {"powem", 0xee680140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1478 {"powez", 0xee680160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1480 {"rpws", 0xee700100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1481 {"rpwsp", 0xee700120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1482 {"rpwsm", 0xee700140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1483 {"rpwsz", 0xee700160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1484 {"rpwd", 0xee700180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1485 {"rpwdp", 0xee7001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1486 {"rpwdm", 0xee7001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1487 {"rpwdz", 0xee7001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1488 {"rpwe", 0xee780100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1489 {"rpwep", 0xee780120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1490 {"rpwem", 0xee780140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1491 {"rpwez", 0xee780160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1493 {"rmfs", 0xee800100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1494 {"rmfsp", 0xee800120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1495 {"rmfsm", 0xee800140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1496 {"rmfsz", 0xee800160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1497 {"rmfd", 0xee800180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1498 {"rmfdp", 0xee8001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1499 {"rmfdm", 0xee8001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1500 {"rmfdz", 0xee8001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1501 {"rmfe", 0xee880100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1502 {"rmfep", 0xee880120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1503 {"rmfem", 0xee880140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1504 {"rmfez", 0xee880160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1506 {"fmls", 0xee900100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1507 {"fmlsp", 0xee900120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1508 {"fmlsm", 0xee900140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1509 {"fmlsz", 0xee900160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1510 {"fmld", 0xee900180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1511 {"fmldp", 0xee9001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1512 {"fmldm", 0xee9001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1513 {"fmldz", 0xee9001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1514 {"fmle", 0xee980100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1515 {"fmlep", 0xee980120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1516 {"fmlem", 0xee980140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1517 {"fmlez", 0xee980160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1519 {"fdvs", 0xeea00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1520 {"fdvsp", 0xeea00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1521 {"fdvsm", 0xeea00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1522 {"fdvsz", 0xeea00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1523 {"fdvd", 0xeea00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1524 {"fdvdp", 0xeea001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1525 {"fdvdm", 0xeea001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1526 {"fdvdz", 0xeea001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1527 {"fdve", 0xeea80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1528 {"fdvep", 0xeea80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1529 {"fdvem", 0xeea80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1530 {"fdvez", 0xeea80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1532 {"frds", 0xeeb00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1533 {"frdsp", 0xeeb00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1534 {"frdsm", 0xeeb00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1535 {"frdsz", 0xeeb00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1536 {"frdd", 0xeeb00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1537 {"frddp", 0xeeb001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1538 {"frddm", 0xeeb001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1539 {"frddz", 0xeeb001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1540 {"frde", 0xeeb80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1541 {"frdep", 0xeeb80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1542 {"frdem", 0xeeb80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1543 {"frdez", 0xeeb80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1545 {"pols", 0xeec00100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1546 {"polsp", 0xeec00120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1547 {"polsm", 0xeec00140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1548 {"polsz", 0xeec00160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1549 {"pold", 0xeec00180, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1550 {"poldp", 0xeec001a0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1551 {"poldm", 0xeec001c0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1552 {"poldz", 0xeec001e0, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1553 {"pole", 0xeec80100, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1554 {"polep", 0xeec80120, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1555 {"polem", 0xeec80140, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1556 {"polez", 0xeec80160, 3, FPU_FPA_EXT_V1, do_fpa_dyadic},
1558 {"cmf", 0xee90f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1559 {"cmfe", 0xeed0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1560 {"cnf", 0xeeb0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1561 {"cnfe", 0xeef0f110, 3, FPU_FPA_EXT_V1, do_fpa_cmp},
1562 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should
1563 not be an optional suffix, but part of the instruction. To be
1564 compatible, we accept either. */
1565 {"cmfe", 0xeed0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
1566 {"cnfe", 0xeef0f110, 4, FPU_FPA_EXT_V1, do_fpa_cmp},
1568 {"flts", 0xee000110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1569 {"fltsp", 0xee000130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1570 {"fltsm", 0xee000150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1571 {"fltsz", 0xee000170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1572 {"fltd", 0xee000190, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1573 {"fltdp", 0xee0001b0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1574 {"fltdm", 0xee0001d0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1575 {"fltdz", 0xee0001f0, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1576 {"flte", 0xee080110, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1577 {"fltep", 0xee080130, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1578 {"fltem", 0xee080150, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1579 {"fltez", 0xee080170, 3, FPU_FPA_EXT_V1, do_fpa_from_reg},
1581 /* The implementation of the FIX instruction is broken on some
1582 assemblers, in that it accepts a precision specifier as well as a
1583 rounding specifier, despite the fact that this is meaningless.
1584 To be more compatible, we accept it as well, though of course it
1585 does not set any bits. */
1586 {"fix", 0xee100110, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1587 {"fixp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1588 {"fixm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1589 {"fixz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1590 {"fixsp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1591 {"fixsm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1592 {"fixsz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1593 {"fixdp", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1594 {"fixdm", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1595 {"fixdz", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1596 {"fixep", 0xee100130, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1597 {"fixem", 0xee100150, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1598 {"fixez", 0xee100170, 3, FPU_FPA_EXT_V1, do_fpa_to_reg},
1600 /* Instructions that were new with the real FPA, call them V2. */
1601 {"lfm", 0xec100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1602 {"lfmfd", 0xec900200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1603 {"lfmea", 0xed100200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1604 {"sfm", 0xec000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1605 {"sfmfd", 0xed000200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1606 {"sfmea", 0xec800200, 3, FPU_FPA_EXT_V2, do_fpa_ldmstm},
1608 /* VFP V1xD (single precision). */
1609 /* Moves and type conversions. */
1610 {"fcpys", 0xeeb00a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1611 {"fmrs", 0xee100a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_sp},
1612 {"fmsr", 0xee000a10, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_from_reg},
1613 {"fmstat", 0xeef1fa10, 6, FPU_VFP_EXT_V1xD, do_empty},
1614 {"fsitos", 0xeeb80ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1615 {"fuitos", 0xeeb80a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1616 {"ftosis", 0xeebd0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1617 {"ftosizs", 0xeebd0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1618 {"ftouis", 0xeebc0a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1619 {"ftouizs", 0xeebc0ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1620 {"fmrx", 0xeef00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_reg_from_ctrl},
1621 {"fmxr", 0xeee00a10, 4, FPU_VFP_EXT_V1xD, do_vfp_ctrl_from_reg},
1623 /* Memory operations. */
1624 {"flds", 0xed100a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1625 {"fsts", 0xed000a00, 4, FPU_VFP_EXT_V1xD, do_vfp_sp_ldst},
1626 {"fldmias", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1627 {"fldmfds", 0xec900a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1628 {"fldmdbs", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1629 {"fldmeas", 0xed300a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1630 {"fldmiax", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1631 {"fldmfdx", 0xec900b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1632 {"fldmdbx", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1633 {"fldmeax", 0xed300b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1634 {"fstmias", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1635 {"fstmeas", 0xec800a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmia},
1636 {"fstmdbs", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1637 {"fstmfds", 0xed200a00, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_ldstmdb},
1638 {"fstmiax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1639 {"fstmeax", 0xec800b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmia},
1640 {"fstmdbx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1641 {"fstmfdx", 0xed200b00, 7, FPU_VFP_EXT_V1xD, do_vfp_xp_ldstmdb},
1643 /* Monadic operations. */
1644 {"fabss", 0xeeb00ac0, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1645 {"fnegs", 0xeeb10a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1646 {"fsqrts", 0xeeb10ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1648 /* Dyadic operations. */
1649 {"fadds", 0xee300a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1650 {"fsubs", 0xee300a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1651 {"fmuls", 0xee200a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1652 {"fdivs", 0xee800a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1653 {"fmacs", 0xee000a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1654 {"fmscs", 0xee100a00, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1655 {"fnmuls", 0xee200a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1656 {"fnmacs", 0xee000a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1657 {"fnmscs", 0xee100a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_dyadic},
1660 {"fcmps", 0xeeb40a40, 5, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1661 {"fcmpzs", 0xeeb50a40, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1662 {"fcmpes", 0xeeb40ac0, 6, FPU_VFP_EXT_V1xD, do_vfp_sp_monadic},
1663 {"fcmpezs", 0xeeb50ac0, 7, FPU_VFP_EXT_V1xD, do_vfp_sp_compare_z},
1665 /* VFP V1 (Double precision). */
1666 /* Moves and type conversions. */
1667 {"fcpyd", 0xeeb00b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1668 {"fcvtds", 0xeeb70ac0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1669 {"fcvtsd", 0xeeb70bc0, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1670 {"fmdhr", 0xee200b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
1671 {"fmdlr", 0xee000b10, 5, FPU_VFP_EXT_V1, do_vfp_dp_from_reg},
1672 {"fmrdh", 0xee300b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
1673 {"fmrdl", 0xee100b10, 5, FPU_VFP_EXT_V1, do_vfp_reg_from_dp},
1674 {"fsitod", 0xeeb80bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1675 {"fuitod", 0xeeb80b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_sp_cvt},
1676 {"ftosid", 0xeebd0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1677 {"ftosizd", 0xeebd0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1678 {"ftouid", 0xeebc0b40, 6, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1679 {"ftouizd", 0xeebc0bc0, 7, FPU_VFP_EXT_V1, do_vfp_sp_dp_cvt},
1681 /* Memory operations. */
1682 {"fldd", 0xed100b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
1683 {"fstd", 0xed000b00, 4, FPU_VFP_EXT_V1, do_vfp_dp_ldst},
1684 {"fldmiad", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1685 {"fldmfdd", 0xec900b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1686 {"fldmdbd", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1687 {"fldmead", 0xed300b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1688 {"fstmiad", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1689 {"fstmead", 0xec800b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmia},
1690 {"fstmdbd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1691 {"fstmfdd", 0xed200b00, 7, FPU_VFP_EXT_V1, do_vfp_dp_ldstmdb},
1693 /* Monadic operations. */
1694 {"fabsd", 0xeeb00bc0, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1695 {"fnegd", 0xeeb10b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1696 {"fsqrtd", 0xeeb10bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1698 /* Dyadic operations. */
1699 {"faddd", 0xee300b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1700 {"fsubd", 0xee300b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1701 {"fmuld", 0xee200b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1702 {"fdivd", 0xee800b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1703 {"fmacd", 0xee000b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1704 {"fmscd", 0xee100b00, 5, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1705 {"fnmuld", 0xee200b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1706 {"fnmacd", 0xee000b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1707 {"fnmscd", 0xee100b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_dyadic},
1710 {"fcmpd", 0xeeb40b40, 5, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1711 {"fcmpzd", 0xeeb50b40, 6, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
1712 {"fcmped", 0xeeb40bc0, 6, FPU_VFP_EXT_V1, do_vfp_dp_monadic},
1713 {"fcmpezd", 0xeeb50bc0, 7, FPU_VFP_EXT_V1, do_vfp_dp_compare_z},
1716 {"fmsrr", 0xec400a10, 5, FPU_VFP_EXT_V2, do_vfp_sp_reg2},
1717 {"fmrrs", 0xec500a10, 5, FPU_VFP_EXT_V2, do_vfp_sp_reg2},
1718 {"fmdrr", 0xec400b10, 5, FPU_VFP_EXT_V2, do_vfp_dp_from_reg2},
1719 {"fmrrd", 0xec500b10, 5, FPU_VFP_EXT_V2, do_vfp_reg2_from_dp},
1721 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
1722 {"mia", 0xee200010, 3, ARM_CEXT_XSCALE, do_xsc_mia},
1723 {"miaph", 0xee280010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1724 {"miabb", 0xee2c0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1725 {"miabt", 0xee2d0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1726 {"miatb", 0xee2e0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1727 {"miatt", 0xee2f0010, 5, ARM_CEXT_XSCALE, do_xsc_mia},
1728 {"mar", 0xec400000, 3, ARM_CEXT_XSCALE, do_xsc_mar},
1729 {"mra", 0xec500000, 3, ARM_CEXT_XSCALE, do_xsc_mra},
1731 /* Cirrus Maverick instructions. */
1732 {"cfldrs", 0xec100400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
1733 {"cfldrd", 0xec500400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
1734 {"cfldr32", 0xec100500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_3},
1735 {"cfldr64", 0xec500500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_4},
1736 {"cfstrs", 0xec000400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_1},
1737 {"cfstrd", 0xec400400, 6, ARM_CEXT_MAVERICK, do_mav_ldst_2},
1738 {"cfstr32", 0xec000500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_3},
1739 {"cfstr64", 0xec400500, 7, ARM_CEXT_MAVERICK, do_mav_ldst_4},
1740 {"cfmvsr", 0xee000450, 6, ARM_CEXT_MAVERICK, do_mav_binops_2a},
1741 {"cfmvrs", 0xee100450, 6, ARM_CEXT_MAVERICK, do_mav_binops_1a},
1742 {"cfmvdlr", 0xee000410, 7, ARM_CEXT_MAVERICK, do_mav_binops_2b},
1743 {"cfmvrdl", 0xee100410, 7, ARM_CEXT_MAVERICK, do_mav_binops_1b},
1744 {"cfmvdhr", 0xee000430, 7, ARM_CEXT_MAVERICK, do_mav_binops_2b},
1745 {"cfmvrdh", 0xee100430, 7, ARM_CEXT_MAVERICK, do_mav_binops_1b},
1746 {"cfmv64lr", 0xee000510, 8, ARM_CEXT_MAVERICK, do_mav_binops_2c},
1747 {"cfmvr64l", 0xee100510, 8, ARM_CEXT_MAVERICK, do_mav_binops_1c},
1748 {"cfmv64hr", 0xee000530, 8, ARM_CEXT_MAVERICK, do_mav_binops_2c},
1749 {"cfmvr64h", 0xee100530, 8, ARM_CEXT_MAVERICK, do_mav_binops_1c},
1750 {"cfmval32", 0xee100610, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
1751 {"cfmv32al", 0xee000610, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
1752 {"cfmvam32", 0xee100630, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
1753 {"cfmv32am", 0xee000630, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
1754 {"cfmvah32", 0xee100650, 8, ARM_CEXT_MAVERICK, do_mav_binops_3a},
1755 {"cfmv32ah", 0xee000650, 8, ARM_CEXT_MAVERICK, do_mav_binops_3b},
1756 {"cfmva32", 0xee100670, 7, ARM_CEXT_MAVERICK, do_mav_binops_3a},
1757 {"cfmv32a", 0xee000670, 7, ARM_CEXT_MAVERICK, do_mav_binops_3b},
1758 {"cfmva64", 0xee100690, 7, ARM_CEXT_MAVERICK, do_mav_binops_3c},
1759 {"cfmv64a", 0xee000690, 7, ARM_CEXT_MAVERICK, do_mav_binops_3d},
1760 {"cfmvsc32", 0xee1006b0, 8, ARM_CEXT_MAVERICK, do_mav_dspsc_1},
1761 {"cfmv32sc", 0xee0006b0, 8, ARM_CEXT_MAVERICK, do_mav_dspsc_2},
1762 {"cfcpys", 0xee000400, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
1763 {"cfcpyd", 0xee000420, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
1764 {"cfcvtsd", 0xee000460, 7, ARM_CEXT_MAVERICK, do_mav_binops_1f},
1765 {"cfcvtds", 0xee000440, 7, ARM_CEXT_MAVERICK, do_mav_binops_1g},
1766 {"cfcvt32s", 0xee000480, 8, ARM_CEXT_MAVERICK, do_mav_binops_1h},
1767 {"cfcvt32d", 0xee0004a0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1i},
1768 {"cfcvt64s", 0xee0004c0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1j},
1769 {"cfcvt64d", 0xee0004e0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1k},
1770 {"cfcvts32", 0xee100580, 8, ARM_CEXT_MAVERICK, do_mav_binops_1l},
1771 {"cfcvtd32", 0xee1005a0, 8, ARM_CEXT_MAVERICK, do_mav_binops_1m},
1772 {"cftruncs32", 0xee1005c0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1l},
1773 {"cftruncd32", 0xee1005e0, 10, ARM_CEXT_MAVERICK, do_mav_binops_1m},
1774 {"cfrshl32", 0xee000550, 8, ARM_CEXT_MAVERICK, do_mav_triple_4a},
1775 {"cfrshl64", 0xee000570, 8, ARM_CEXT_MAVERICK, do_mav_triple_4b},
1776 {"cfsh32", 0xee000500, 6, ARM_CEXT_MAVERICK, do_mav_shift_1},
1777 {"cfsh64", 0xee200500, 6, ARM_CEXT_MAVERICK, do_mav_shift_2},
1778 {"cfcmps", 0xee100490, 6, ARM_CEXT_MAVERICK, do_mav_triple_5a},
1779 {"cfcmpd", 0xee1004b0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5b},
1780 {"cfcmp32", 0xee100590, 7, ARM_CEXT_MAVERICK, do_mav_triple_5c},
1781 {"cfcmp64", 0xee1005b0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5d},
1782 {"cfabss", 0xee300400, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
1783 {"cfabsd", 0xee300420, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
1784 {"cfnegs", 0xee300440, 6, ARM_CEXT_MAVERICK, do_mav_binops_1d},
1785 {"cfnegd", 0xee300460, 6, ARM_CEXT_MAVERICK, do_mav_binops_1e},
1786 {"cfadds", 0xee300480, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
1787 {"cfaddd", 0xee3004a0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
1788 {"cfsubs", 0xee3004c0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
1789 {"cfsubd", 0xee3004e0, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
1790 {"cfmuls", 0xee100400, 6, ARM_CEXT_MAVERICK, do_mav_triple_5e},
1791 {"cfmuld", 0xee100420, 6, ARM_CEXT_MAVERICK, do_mav_triple_5f},
1792 {"cfabs32", 0xee300500, 7, ARM_CEXT_MAVERICK, do_mav_binops_1n},
1793 {"cfabs64", 0xee300520, 7, ARM_CEXT_MAVERICK, do_mav_binops_1o},
1794 {"cfneg32", 0xee300540, 7, ARM_CEXT_MAVERICK, do_mav_binops_1n},
1795 {"cfneg64", 0xee300560, 7, ARM_CEXT_MAVERICK, do_mav_binops_1o},
1796 {"cfadd32", 0xee300580, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
1797 {"cfadd64", 0xee3005a0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
1798 {"cfsub32", 0xee3005c0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
1799 {"cfsub64", 0xee3005e0, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
1800 {"cfmul32", 0xee100500, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
1801 {"cfmul64", 0xee100520, 7, ARM_CEXT_MAVERICK, do_mav_triple_5h},
1802 {"cfmac32", 0xee100540, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
1803 {"cfmsc32", 0xee100560, 7, ARM_CEXT_MAVERICK, do_mav_triple_5g},
1804 {"cfmadd32", 0xee000600, 8, ARM_CEXT_MAVERICK, do_mav_quad_6a},
1805 {"cfmsub32", 0xee100600, 8, ARM_CEXT_MAVERICK, do_mav_quad_6a},
1806 {"cfmadda32", 0xee200600, 9, ARM_CEXT_MAVERICK, do_mav_quad_6b},
1807 {"cfmsuba32", 0xee300600, 9, ARM_CEXT_MAVERICK, do_mav_quad_6b},
1810 /* Defines for various bits that we will want to toggle. */
1811 #define INST_IMMEDIATE 0x02000000
1812 #define OFFSET_REG 0x02000000
1813 #define HWOFFSET_IMM 0x00400000
1814 #define SHIFT_BY_REG 0x00000010
1815 #define PRE_INDEX 0x01000000
1816 #define INDEX_UP 0x00800000
1817 #define WRITE_BACK 0x00200000
1818 #define LDM_TYPE_2_OR_3 0x00400000
1820 #define LITERAL_MASK 0xf000f000
1821 #define OPCODE_MASK 0xfe1fffff
1822 #define V4_STR_BIT 0x00000020
1824 #define DATA_OP_SHIFT 21
1826 /* Codes to distinguish the arithmetic instructions. */
1827 #define OPCODE_AND 0
1828 #define OPCODE_EOR 1
1829 #define OPCODE_SUB 2
1830 #define OPCODE_RSB 3
1831 #define OPCODE_ADD 4
1832 #define OPCODE_ADC 5
1833 #define OPCODE_SBC 6
1834 #define OPCODE_RSC 7
1835 #define OPCODE_TST 8
1836 #define OPCODE_TEQ 9
1837 #define OPCODE_CMP 10
1838 #define OPCODE_CMN 11
1839 #define OPCODE_ORR 12
1840 #define OPCODE_MOV 13
1841 #define OPCODE_BIC 14
1842 #define OPCODE_MVN 15
1844 /* Thumb v1 (ARMv4T). */
1845 static void do_t_nop PARAMS ((char *));
1846 static void do_t_arit PARAMS ((char *));
1847 static void do_t_add PARAMS ((char *));
1848 static void do_t_asr PARAMS ((char *));
1849 static void do_t_branch9 PARAMS ((char *));
1850 static void do_t_branch12 PARAMS ((char *));
1851 static void do_t_branch23 PARAMS ((char *));
1852 static void do_t_bx PARAMS ((char *));
1853 static void do_t_compare PARAMS ((char *));
1854 static void do_t_ldmstm PARAMS ((char *));
1855 static void do_t_ldr PARAMS ((char *));
1856 static void do_t_ldrb PARAMS ((char *));
1857 static void do_t_ldrh PARAMS ((char *));
1858 static void do_t_lds PARAMS ((char *));
1859 static void do_t_lsl PARAMS ((char *));
1860 static void do_t_lsr PARAMS ((char *));
1861 static void do_t_mov PARAMS ((char *));
1862 static void do_t_push_pop PARAMS ((char *));
1863 static void do_t_str PARAMS ((char *));
1864 static void do_t_strb PARAMS ((char *));
1865 static void do_t_strh PARAMS ((char *));
1866 static void do_t_sub PARAMS ((char *));
1867 static void do_t_swi PARAMS ((char *));
1868 static void do_t_adr PARAMS ((char *));
1870 /* Thumb v2 (ARMv5T). */
1871 static void do_t_blx PARAMS ((char *));
1872 static void do_t_bkpt PARAMS ((char *));
1874 #define T_OPCODE_MUL 0x4340
1875 #define T_OPCODE_TST 0x4200
1876 #define T_OPCODE_CMN 0x42c0
1877 #define T_OPCODE_NEG 0x4240
1878 #define T_OPCODE_MVN 0x43c0
1880 #define T_OPCODE_ADD_R3 0x1800
1881 #define T_OPCODE_SUB_R3 0x1a00
1882 #define T_OPCODE_ADD_HI 0x4400
1883 #define T_OPCODE_ADD_ST 0xb000
1884 #define T_OPCODE_SUB_ST 0xb080
1885 #define T_OPCODE_ADD_SP 0xa800
1886 #define T_OPCODE_ADD_PC 0xa000
1887 #define T_OPCODE_ADD_I8 0x3000
1888 #define T_OPCODE_SUB_I8 0x3800
1889 #define T_OPCODE_ADD_I3 0x1c00
1890 #define T_OPCODE_SUB_I3 0x1e00
1892 #define T_OPCODE_ASR_R 0x4100
1893 #define T_OPCODE_LSL_R 0x4080
1894 #define T_OPCODE_LSR_R 0x40c0
1895 #define T_OPCODE_ASR_I 0x1000
1896 #define T_OPCODE_LSL_I 0x0000
1897 #define T_OPCODE_LSR_I 0x0800
1899 #define T_OPCODE_MOV_I8 0x2000
1900 #define T_OPCODE_CMP_I8 0x2800
1901 #define T_OPCODE_CMP_LR 0x4280
1902 #define T_OPCODE_MOV_HR 0x4600
1903 #define T_OPCODE_CMP_HR 0x4500
1905 #define T_OPCODE_LDR_PC 0x4800
1906 #define T_OPCODE_LDR_SP 0x9800
1907 #define T_OPCODE_STR_SP 0x9000
1908 #define T_OPCODE_LDR_IW 0x6800
1909 #define T_OPCODE_STR_IW 0x6000
1910 #define T_OPCODE_LDR_IH 0x8800
1911 #define T_OPCODE_STR_IH 0x8000
1912 #define T_OPCODE_LDR_IB 0x7800
1913 #define T_OPCODE_STR_IB 0x7000
1914 #define T_OPCODE_LDR_RW 0x5800
1915 #define T_OPCODE_STR_RW 0x5000
1916 #define T_OPCODE_LDR_RH 0x5a00
1917 #define T_OPCODE_STR_RH 0x5200
1918 #define T_OPCODE_LDR_RB 0x5c00
1919 #define T_OPCODE_STR_RB 0x5400
1921 #define T_OPCODE_PUSH 0xb400
1922 #define T_OPCODE_POP 0xbc00
1924 #define T_OPCODE_BRANCH 0xe7fe
1926 static int thumb_reg PARAMS ((char ** str, int hi_lo));
1928 #define THUMB_SIZE 2 /* Size of thumb instruction. */
1929 #define THUMB_REG_LO 0x1
1930 #define THUMB_REG_HI 0x2
1931 #define THUMB_REG_ANY 0x3
1933 #define THUMB_H1 0x0080
1934 #define THUMB_H2 0x0040
1940 #define THUMB_MOVE 0
1941 #define THUMB_COMPARE 1
1943 #define THUMB_LOAD 0
1944 #define THUMB_STORE 1
1946 #define THUMB_PP_PC_LR 0x0100
1948 /* These three are used for immediate shifts, do not alter. */
1949 #define THUMB_WORD 2
1950 #define THUMB_HALFWORD 1
1951 #define THUMB_BYTE 0
1955 /* Basic string to match. */
1956 const char * template;
1958 /* Basic instruction code. */
1959 unsigned long value;
1963 /* Which CPU variants this exists for. */
1964 unsigned long variant;
1966 /* Function to call to parse args. */
1967 void (* parms) PARAMS ((char *));
1970 static const struct thumb_opcode tinsns[] =
1972 /* Thumb v1 (ARMv4T). */
1973 {"adc", 0x4140, 2, ARM_EXT_V4T, do_t_arit},
1974 {"add", 0x0000, 2, ARM_EXT_V4T, do_t_add},
1975 {"and", 0x4000, 2, ARM_EXT_V4T, do_t_arit},
1976 {"asr", 0x0000, 2, ARM_EXT_V4T, do_t_asr},
1977 {"b", T_OPCODE_BRANCH, 2, ARM_EXT_V4T, do_t_branch12},
1978 {"beq", 0xd0fe, 2, ARM_EXT_V4T, do_t_branch9},
1979 {"bne", 0xd1fe, 2, ARM_EXT_V4T, do_t_branch9},
1980 {"bcs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
1981 {"bhs", 0xd2fe, 2, ARM_EXT_V4T, do_t_branch9},
1982 {"bcc", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
1983 {"bul", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
1984 {"blo", 0xd3fe, 2, ARM_EXT_V4T, do_t_branch9},
1985 {"bmi", 0xd4fe, 2, ARM_EXT_V4T, do_t_branch9},
1986 {"bpl", 0xd5fe, 2, ARM_EXT_V4T, do_t_branch9},
1987 {"bvs", 0xd6fe, 2, ARM_EXT_V4T, do_t_branch9},
1988 {"bvc", 0xd7fe, 2, ARM_EXT_V4T, do_t_branch9},
1989 {"bhi", 0xd8fe, 2, ARM_EXT_V4T, do_t_branch9},
1990 {"bls", 0xd9fe, 2, ARM_EXT_V4T, do_t_branch9},
1991 {"bge", 0xdafe, 2, ARM_EXT_V4T, do_t_branch9},
1992 {"blt", 0xdbfe, 2, ARM_EXT_V4T, do_t_branch9},
1993 {"bgt", 0xdcfe, 2, ARM_EXT_V4T, do_t_branch9},
1994 {"ble", 0xddfe, 2, ARM_EXT_V4T, do_t_branch9},
1995 {"bal", 0xdefe, 2, ARM_EXT_V4T, do_t_branch9},
1996 {"bic", 0x4380, 2, ARM_EXT_V4T, do_t_arit},
1997 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T, do_t_branch23},
1998 {"bx", 0x4700, 2, ARM_EXT_V4T, do_t_bx},
1999 {"cmn", T_OPCODE_CMN, 2, ARM_EXT_V4T, do_t_arit},
2000 {"cmp", 0x0000, 2, ARM_EXT_V4T, do_t_compare},
2001 {"eor", 0x4040, 2, ARM_EXT_V4T, do_t_arit},
2002 {"ldmia", 0xc800, 2, ARM_EXT_V4T, do_t_ldmstm},
2003 {"ldr", 0x0000, 2, ARM_EXT_V4T, do_t_ldr},
2004 {"ldrb", 0x0000, 2, ARM_EXT_V4T, do_t_ldrb},
2005 {"ldrh", 0x0000, 2, ARM_EXT_V4T, do_t_ldrh},
2006 {"ldrsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
2007 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
2008 {"ldsb", 0x5600, 2, ARM_EXT_V4T, do_t_lds},
2009 {"ldsh", 0x5e00, 2, ARM_EXT_V4T, do_t_lds},
2010 {"lsl", 0x0000, 2, ARM_EXT_V4T, do_t_lsl},
2011 {"lsr", 0x0000, 2, ARM_EXT_V4T, do_t_lsr},
2012 {"mov", 0x0000, 2, ARM_EXT_V4T, do_t_mov},
2013 {"mul", T_OPCODE_MUL, 2, ARM_EXT_V4T, do_t_arit},
2014 {"mvn", T_OPCODE_MVN, 2, ARM_EXT_V4T, do_t_arit},
2015 {"neg", T_OPCODE_NEG, 2, ARM_EXT_V4T, do_t_arit},
2016 {"orr", 0x4300, 2, ARM_EXT_V4T, do_t_arit},
2017 {"pop", 0xbc00, 2, ARM_EXT_V4T, do_t_push_pop},
2018 {"push", 0xb400, 2, ARM_EXT_V4T, do_t_push_pop},
2019 {"ror", 0x41c0, 2, ARM_EXT_V4T, do_t_arit},
2020 {"sbc", 0x4180, 2, ARM_EXT_V4T, do_t_arit},
2021 {"stmia", 0xc000, 2, ARM_EXT_V4T, do_t_ldmstm},
2022 {"str", 0x0000, 2, ARM_EXT_V4T, do_t_str},
2023 {"strb", 0x0000, 2, ARM_EXT_V4T, do_t_strb},
2024 {"strh", 0x0000, 2, ARM_EXT_V4T, do_t_strh},
2025 {"swi", 0xdf00, 2, ARM_EXT_V4T, do_t_swi},
2026 {"sub", 0x0000, 2, ARM_EXT_V4T, do_t_sub},
2027 {"tst", T_OPCODE_TST, 2, ARM_EXT_V4T, do_t_arit},
2029 {"adr", 0x0000, 2, ARM_EXT_V4T, do_t_adr},
2030 {"nop", 0x46C0, 2, ARM_EXT_V4T, do_t_nop}, /* mov r8,r8 */
2031 /* Thumb v2 (ARMv5T). */
2032 {"blx", 0, 0, ARM_EXT_V5T, do_t_blx},
2033 {"bkpt", 0xbe00, 2, ARM_EXT_V5T, do_t_bkpt},
2036 #define BAD_ARGS _("bad arguments to instruction")
2037 #define BAD_PC _("r15 not allowed here")
2038 #define BAD_COND _("instruction is not conditional")
2039 #define ERR_NO_ACCUM _("acc0 expected")
2041 static struct hash_control * arm_ops_hsh = NULL;
2042 static struct hash_control * arm_tops_hsh = NULL;
2043 static struct hash_control * arm_cond_hsh = NULL;
2044 static struct hash_control * arm_shift_hsh = NULL;
2045 static struct hash_control * arm_psr_hsh = NULL;
2047 /* This table describes all the machine specific pseudo-ops the assembler
2048 has to support. The fields are:
2049 pseudo-op name without dot
2050 function to call to execute this pseudo-op
2051 Integer arg to pass to the function. */
2053 static void s_req PARAMS ((int));
2054 static void s_align PARAMS ((int));
2055 static void s_bss PARAMS ((int));
2056 static void s_even PARAMS ((int));
2057 static void s_ltorg PARAMS ((int));
2058 static void s_arm PARAMS ((int));
2059 static void s_thumb PARAMS ((int));
2060 static void s_code PARAMS ((int));
2061 static void s_force_thumb PARAMS ((int));
2062 static void s_thumb_func PARAMS ((int));
2063 static void s_thumb_set PARAMS ((int));
2065 static void s_arm_elf_cons PARAMS ((int));
2068 static int my_get_expression PARAMS ((expressionS *, char **));
2070 const pseudo_typeS md_pseudo_table[] =
2072 /* Never called becasue '.req' does not start line. */
2073 { "req", s_req, 0 },
2074 { "bss", s_bss, 0 },
2075 { "align", s_align, 0 },
2076 { "arm", s_arm, 0 },
2077 { "thumb", s_thumb, 0 },
2078 { "code", s_code, 0 },
2079 { "force_thumb", s_force_thumb, 0 },
2080 { "thumb_func", s_thumb_func, 0 },
2081 { "thumb_set", s_thumb_set, 0 },
2082 { "even", s_even, 0 },
2083 { "ltorg", s_ltorg, 0 },
2084 { "pool", s_ltorg, 0 },
2086 { "word", s_arm_elf_cons, 4 },
2087 { "long", s_arm_elf_cons, 4 },
2088 { "file", (void (*) PARAMS ((int))) dwarf2_directive_file, 0 },
2089 { "loc", dwarf2_directive_loc, 0 },
2093 { "extend", float_cons, 'x' },
2094 { "ldouble", float_cons, 'x' },
2095 { "packed", float_cons, 'p' },
2099 /* Other internal functions. */
2100 static int arm_parse_extension PARAMS ((char *, int *));
2101 static int arm_parse_cpu PARAMS ((char *));
2102 static int arm_parse_arch PARAMS ((char *));
2103 static int arm_parse_fpu PARAMS ((char *));
2105 /* Stuff needed to resolve the label ambiguity
2115 symbolS * last_label_seen;
2116 static int label_is_thumb_function_name = FALSE;
2118 /* Literal Pool stuff. */
2120 #define MAX_LITERAL_POOL_SIZE 1024
2122 /* Literal pool structure. Held on a per-section
2123 and per-sub-section basis. */
2124 typedef struct literal_pool
2126 expressionS literals [MAX_LITERAL_POOL_SIZE];
2127 unsigned int next_free_entry;
2131 subsegT sub_section;
2132 struct literal_pool * next;
2135 /* Pointer to a linked list of literal pools. */
2136 literal_pool * list_of_pools = NULL;
2138 static literal_pool * find_literal_pool PARAMS ((void));
2139 static literal_pool * find_or_make_literal_pool PARAMS ((void));
2141 static literal_pool *
2142 find_literal_pool ()
2144 literal_pool * pool;
2146 for (pool = list_of_pools; pool != NULL; pool = pool->next)
2148 if (pool->section == now_seg
2149 && pool->sub_section == now_subseg)
2156 static literal_pool *
2157 find_or_make_literal_pool ()
2159 /* Next literal pool ID number. */
2160 static unsigned int latest_pool_num = 1;
2161 literal_pool * pool;
2163 pool = find_literal_pool ();
2167 /* Create a new pool. */
2168 pool = (literal_pool *) xmalloc (sizeof (* pool));
2172 pool->next_free_entry = 0;
2173 pool->section = now_seg;
2174 pool->sub_section = now_subseg;
2175 pool->next = list_of_pools;
2176 pool->symbol = NULL;
2178 /* Add it to the list. */
2179 list_of_pools = pool;
2182 /* New pools, and emptied pools, will have a NULL symbol. */
2183 if (pool->symbol == NULL)
2185 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
2186 (valueT) 0, &zero_address_frag);
2187 pool->id = latest_pool_num ++;
2194 /* Add the literal in the global 'inst'
2195 structure to the relevent literal pool. */
2199 literal_pool * pool;
2202 pool = find_or_make_literal_pool ();
2204 /* Check if this literal value is already in the pool. */
2205 for (entry = 0; entry < pool->next_free_entry; entry ++)
2207 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2208 && (inst.reloc.exp.X_op == O_constant)
2209 && (pool->literals[entry].X_add_number
2210 == inst.reloc.exp.X_add_number)
2211 && (pool->literals[entry].X_unsigned
2212 == inst.reloc.exp.X_unsigned))
2215 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
2216 && (inst.reloc.exp.X_op == O_symbol)
2217 && (pool->literals[entry].X_add_number
2218 == inst.reloc.exp.X_add_number)
2219 && (pool->literals[entry].X_add_symbol
2220 == inst.reloc.exp.X_add_symbol)
2221 && (pool->literals[entry].X_op_symbol
2222 == inst.reloc.exp.X_op_symbol))
2226 /* Do we need to create a new entry? */
2227 if (entry == pool->next_free_entry)
2229 if (entry >= MAX_LITERAL_POOL_SIZE)
2231 inst.error = _("literal pool overflow");
2235 pool->literals[entry] = inst.reloc.exp;
2236 pool->next_free_entry += 1;
2239 inst.reloc.exp.X_op = O_symbol;
2240 inst.reloc.exp.X_add_number = ((int) entry) * 4 - 8;
2241 inst.reloc.exp.X_add_symbol = pool->symbol;
2246 /* Can't use symbol_new here, so have to create a symbol and then at
2247 a later date assign it a value. Thats what these functions do. */
2250 symbol_locate (symbolP, name, segment, valu, frag)
2252 const char * name; /* It is copied, the caller can modify. */
2253 segT segment; /* Segment identifier (SEG_<something>). */
2254 valueT valu; /* Symbol value. */
2255 fragS * frag; /* Associated fragment. */
2257 unsigned int name_length;
2258 char * preserved_copy_of_name;
2260 name_length = strlen (name) + 1; /* +1 for \0. */
2261 obstack_grow (¬es, name, name_length);
2262 preserved_copy_of_name = obstack_finish (¬es);
2263 #ifdef STRIP_UNDERSCORE
2264 if (preserved_copy_of_name[0] == '_')
2265 preserved_copy_of_name++;
2268 #ifdef tc_canonicalize_symbol_name
2269 preserved_copy_of_name =
2270 tc_canonicalize_symbol_name (preserved_copy_of_name);
2273 S_SET_NAME (symbolP, preserved_copy_of_name);
2275 S_SET_SEGMENT (symbolP, segment);
2276 S_SET_VALUE (symbolP, valu);
2277 symbol_clear_list_pointers (symbolP);
2279 symbol_set_frag (symbolP, frag);
2281 /* Link to end of symbol chain. */
2283 extern int symbol_table_frozen;
2284 if (symbol_table_frozen)
2288 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
2290 obj_symbol_new_hook (symbolP);
2292 #ifdef tc_symbol_new_hook
2293 tc_symbol_new_hook (symbolP);
2297 verify_symbol_chain (symbol_rootP, symbol_lastP);
2298 #endif /* DEBUG_SYMS */
2301 /* Check that an immediate is valid.
2302 If so, convert it to the right format. */
2305 validate_immediate (val)
2311 #define rotate_left(v, n) (v << n | v >> (32 - n))
2313 for (i = 0; i < 32; i += 2)
2314 if ((a = rotate_left (val, i)) <= 0xff)
2315 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
2320 /* Check to see if an immediate can be computed as two seperate immediate
2321 values, added together. We already know that this value cannot be
2322 computed by just one ARM instruction. */
2325 validate_immediate_twopart (val, highpart)
2327 unsigned int * highpart;
2332 for (i = 0; i < 32; i += 2)
2333 if (((a = rotate_left (val, i)) & 0xff) != 0)
2339 * highpart = (a >> 8) | ((i + 24) << 7);
2341 else if (a & 0xff0000)
2345 * highpart = (a >> 16) | ((i + 16) << 7);
2349 assert (a & 0xff000000);
2350 * highpart = (a >> 24) | ((i + 8) << 7);
2353 return (a & 0xff) | (i << 7);
2360 validate_offset_imm (val, hwse)
2364 if ((hwse && val > 255) || val > 4095)
2371 int a ATTRIBUTE_UNUSED;
2373 as_bad (_("invalid syntax for .req directive"));
2378 int ignore ATTRIBUTE_UNUSED;
2380 /* We don't support putting frags in the BSS segment, we fake it by
2381 marking in_bss, then looking at s_skip for clues. */
2382 subseg_set (bss_section, 0);
2383 demand_empty_rest_of_line ();
2388 int ignore ATTRIBUTE_UNUSED;
2390 /* Never make frag if expect extra pass. */
2392 frag_align (1, 0, 0);
2394 record_alignment (now_seg, 1);
2396 demand_empty_rest_of_line ();
2401 int ignored ATTRIBUTE_UNUSED;
2404 literal_pool * pool;
2407 pool = find_literal_pool ();
2409 || pool->symbol == NULL
2410 || pool->next_free_entry == 0)
2413 /* Align pool as you have word accesses.
2414 Only make a frag if we have to. */
2416 frag_align (2, 0, 0);
2418 record_alignment (now_seg, 2);
2420 sprintf (sym_name, "$$lit_\002%x", pool->id);
2422 symbol_locate (pool->symbol, sym_name, now_seg,
2423 (valueT) frag_now_fix (), frag_now);
2424 symbol_table_insert (pool->symbol);
2426 ARM_SET_THUMB (pool->symbol, thumb_mode);
2428 #if defined OBJ_COFF || defined OBJ_ELF
2429 ARM_SET_INTERWORK (pool->symbol, support_interwork);
2432 for (entry = 0; entry < pool->next_free_entry; entry ++)
2433 /* First output the expression in the instruction to the pool. */
2434 emit_expr (&(pool->literals[entry]), 4); /* .word */
2436 /* Mark the pool as empty. */
2437 pool->next_free_entry = 0;
2438 pool->symbol = NULL;
2441 /* Same as s_align_ptwo but align 0 => align 2. */
2445 int unused ATTRIBUTE_UNUSED;
2448 register long temp_fill;
2449 long max_alignment = 15;
2451 temp = get_absolute_expression ();
2452 if (temp > max_alignment)
2453 as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
2456 as_bad (_("alignment negative. 0 assumed."));
2460 if (*input_line_pointer == ',')
2462 input_line_pointer++;
2463 temp_fill = get_absolute_expression ();
2471 /* Only make a frag if we HAVE to. */
2472 if (temp && !need_pass_2)
2473 frag_align (temp, (int) temp_fill, 0);
2474 demand_empty_rest_of_line ();
2476 record_alignment (now_seg, temp);
2480 s_force_thumb (ignore)
2481 int ignore ATTRIBUTE_UNUSED;
2483 /* If we are not already in thumb mode go into it, EVEN if
2484 the target processor does not support thumb instructions.
2485 This is used by gcc/config/arm/lib1funcs.asm for example
2486 to compile interworking support functions even if the
2487 target processor should not support interworking. */
2492 record_alignment (now_seg, 1);
2495 demand_empty_rest_of_line ();
2499 s_thumb_func (ignore)
2500 int ignore ATTRIBUTE_UNUSED;
2505 /* The following label is the name/address of the start of a Thumb function.
2506 We need to know this for the interworking support. */
2507 label_is_thumb_function_name = TRUE;
2509 demand_empty_rest_of_line ();
2512 /* Perform a .set directive, but also mark the alias as
2513 being a thumb function. */
2519 /* XXX the following is a duplicate of the code for s_set() in read.c
2520 We cannot just call that code as we need to get at the symbol that
2522 register char * name;
2523 register char delim;
2524 register char * end_name;
2525 register symbolS * symbolP;
2527 /* Especial apologies for the random logic:
2528 This just grew, and could be parsed much more simply!
2530 name = input_line_pointer;
2531 delim = get_symbol_end ();
2532 end_name = input_line_pointer;
2537 if (*input_line_pointer != ',')
2540 as_bad (_("expected comma after name \"%s\""), name);
2542 ignore_rest_of_line ();
2546 input_line_pointer++;
2549 if (name[0] == '.' && name[1] == '\0')
2551 /* XXX - this should not happen to .thumb_set. */
2555 if ((symbolP = symbol_find (name)) == NULL
2556 && (symbolP = md_undefined_symbol (name)) == NULL)
2559 /* When doing symbol listings, play games with dummy fragments living
2560 outside the normal fragment chain to record the file and line info
2562 if (listing & LISTING_SYMBOLS)
2564 extern struct list_info_struct * listing_tail;
2565 fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
2567 memset (dummy_frag, 0, sizeof (fragS));
2568 dummy_frag->fr_type = rs_fill;
2569 dummy_frag->line = listing_tail;
2570 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
2571 dummy_frag->fr_symbol = symbolP;
2575 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
2578 /* "set" symbols are local unless otherwise specified. */
2579 SF_SET_LOCAL (symbolP);
2580 #endif /* OBJ_COFF */
2581 } /* Make a new symbol. */
2583 symbol_table_insert (symbolP);
2588 && S_IS_DEFINED (symbolP)
2589 && S_GET_SEGMENT (symbolP) != reg_section)
2590 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
2592 pseudo_set (symbolP);
2594 demand_empty_rest_of_line ();
2596 /* XXX Now we come to the Thumb specific bit of code. */
2598 THUMB_SET_FUNC (symbolP, 1);
2599 ARM_SET_THUMB (symbolP, 1);
2600 #if defined OBJ_ELF || defined OBJ_COFF
2601 ARM_SET_INTERWORK (symbolP, support_interwork);
2606 opcode_select (width)
2614 if (! (cpu_variant & ARM_EXT_V4T))
2615 as_bad (_("selected processor does not support THUMB opcodes"));
2618 /* No need to force the alignment, since we will have been
2619 coming from ARM mode, which is word-aligned. */
2620 record_alignment (now_seg, 1);
2627 if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
2628 as_bad (_("selected processor does not support ARM opcodes"));
2633 frag_align (2, 0, 0);
2635 record_alignment (now_seg, 1);
2640 as_bad (_("invalid instruction size selected (%d)"), width);
2646 int ignore ATTRIBUTE_UNUSED;
2649 demand_empty_rest_of_line ();
2654 int ignore ATTRIBUTE_UNUSED;
2657 demand_empty_rest_of_line ();
2662 int unused ATTRIBUTE_UNUSED;
2666 temp = get_absolute_expression ();
2671 opcode_select (temp);
2675 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
2683 skip_whitespace (str);
2685 if (*str != '\0' && !inst.error)
2686 inst.error = _("garbage following instruction");
2690 skip_past_comma (str)
2693 char * p = * str, c;
2696 while ((c = *p) == ' ' || c == ',')
2699 if (c == ',' && comma++)
2707 return comma ? SUCCESS : FAIL;
2710 /* A standard register must be given at this point.
2711 SHIFT is the place to put it in inst.instruction.
2712 Restores input start point on error.
2713 Returns the reg#, or FAIL. */
2716 reg_required_here (str, shift)
2720 static char buff [128]; /* XXX */
2722 char * start = * str;
2724 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
2727 inst.instruction |= reg << shift;
2731 /* Restore the start point, we may have got a reg of the wrong class. */
2734 /* In the few cases where we might be able to accept something else
2735 this error can be overridden. */
2736 sprintf (buff, _("register expected, not '%.100s'"), start);
2742 static const struct asm_psr *
2744 register char ** ccp;
2746 char * start = * ccp;
2749 const struct asm_psr * psr;
2753 /* Skip to the end of the next word in the input stream. */
2758 while (ISALPHA (c) || c == '_');
2760 /* Terminate the word. */
2763 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
2764 feature for ease of use and backwards compatibility. */
2765 if (!strncmp (start, "cpsr", 4))
2766 strncpy (start, "CPSR", 4);
2767 else if (!strncmp (start, "spsr", 4))
2768 strncpy (start, "SPSR", 4);
2770 /* Now locate the word in the psr hash table. */
2771 psr = (const struct asm_psr *) hash_find (arm_psr_hsh, start);
2773 /* Restore the input stream. */
2776 /* If we found a valid match, advance the
2777 stream pointer past the end of the word. */
2783 /* Parse the input looking for a PSR flag. */
2786 psr_required_here (str)
2789 char * start = * str;
2790 const struct asm_psr * psr;
2792 psr = arm_psr_parse (str);
2796 /* If this is the SPSR that is being modified, set the R bit. */
2798 inst.instruction |= SPSR_BIT;
2800 /* Set the psr flags in the MSR instruction. */
2801 inst.instruction |= psr->field << PSR_SHIFT;
2806 /* In the few cases where we might be able to accept
2807 something else this error can be overridden. */
2808 inst.error = _("flag for {c}psr instruction expected");
2810 /* Restore the start point. */
2816 co_proc_number (str)
2819 int processor, pchar;
2822 skip_whitespace (*str);
2825 /* The data sheet seems to imply that just a number on its own is valid
2826 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
2828 if ((processor = arm_reg_parse (str, all_reg_maps[REG_TYPE_CP].htab))
2834 if (pchar >= '0' && pchar <= '9')
2836 processor = pchar - '0';
2837 if (**str >= '0' && **str <= '9')
2839 processor = processor * 10 + *(*str)++ - '0';
2842 inst.error = _("illegal co-processor number");
2849 inst.error = _("bad or missing co-processor number");
2854 inst.instruction |= processor << 8;
2859 cp_opc_expr (str, where, length)
2866 skip_whitespace (* str);
2868 memset (&expr, '\0', sizeof (expr));
2870 if (my_get_expression (&expr, str))
2872 if (expr.X_op != O_constant)
2874 inst.error = _("bad or missing expression");
2878 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
2880 inst.error = _("immediate co-processor expression too large");
2884 inst.instruction |= expr.X_add_number << where;
2889 cp_reg_required_here (str, where)
2894 char * start = *str;
2896 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_CN].htab)) != FAIL)
2898 inst.instruction |= reg << where;
2902 /* In the few cases where we might be able to accept something else
2903 this error can be overridden. */
2904 inst.error = _("co-processor register expected");
2906 /* Restore the start point. */
2912 fp_reg_required_here (str, where)
2917 char * start = * str;
2919 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_FN].htab)) != FAIL)
2921 inst.instruction |= reg << where;
2925 /* In the few cases where we might be able to accept something else
2926 this error can be overridden. */
2927 inst.error = _("floating point register expected");
2929 /* Restore the start point. */
2935 cp_address_offset (str)
2940 skip_whitespace (* str);
2942 if (! is_immediate_prefix (**str))
2944 inst.error = _("immediate expression expected");
2950 if (my_get_expression (& inst.reloc.exp, str))
2953 if (inst.reloc.exp.X_op == O_constant)
2955 offset = inst.reloc.exp.X_add_number;
2959 inst.error = _("co-processor address must be word aligned");
2963 if (offset > 1023 || offset < -1023)
2965 inst.error = _("offset too large");
2970 inst.instruction |= INDEX_UP;
2974 inst.instruction |= offset >> 2;
2977 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2983 cp_address_required_here (str, wb_ok)
2996 skip_whitespace (p);
2998 if ((reg = reg_required_here (& p, 16)) == FAIL)
3001 skip_whitespace (p);
3007 if (wb_ok && skip_past_comma (& p) == SUCCESS)
3010 write_back = WRITE_BACK;
3014 inst.error = _("pc may not be used in post-increment");
3018 if (cp_address_offset (& p) == FAIL)
3022 pre_inc = PRE_INDEX | INDEX_UP;
3026 /* '['Rn, #expr']'[!] */
3028 if (skip_past_comma (& p) == FAIL)
3030 inst.error = _("pre-indexed expression expected");
3034 pre_inc = PRE_INDEX;
3036 if (cp_address_offset (& p) == FAIL)
3039 skip_whitespace (p);
3043 inst.error = _("missing ]");
3047 skip_whitespace (p);
3049 if (wb_ok && *p == '!')
3053 inst.error = _("pc may not be used with write-back");
3058 write_back = WRITE_BACK;
3064 if (my_get_expression (&inst.reloc.exp, &p))
3067 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
3068 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3069 inst.reloc.pc_rel = 1;
3070 inst.instruction |= (REG_PC << 16);
3071 pre_inc = PRE_INDEX;
3074 inst.instruction |= write_back | pre_inc;
3083 /* Do nothing really. */
3094 /* Only one syntax. */
3095 skip_whitespace (str);
3097 if (reg_required_here (&str, 12) == FAIL)
3099 inst.error = BAD_ARGS;
3103 if (skip_past_comma (&str) == FAIL)
3105 inst.error = _("comma expected after register name");
3109 skip_whitespace (str);
3111 if ( strcmp (str, "CPSR") == 0
3112 || strcmp (str, "SPSR") == 0
3113 /* Lower case versions for backwards compatability. */
3114 || strcmp (str, "cpsr") == 0
3115 || strcmp (str, "spsr") == 0)
3118 /* This is for backwards compatability with older toolchains. */
3119 else if ( strcmp (str, "cpsr_all") == 0
3120 || strcmp (str, "spsr_all") == 0)
3124 inst.error = _("CPSR or SPSR expected");
3128 if (* str == 's' || * str == 'S')
3129 inst.instruction |= SPSR_BIT;
3135 /* Two possible forms:
3136 "{C|S}PSR_<field>, Rm",
3137 "{C|S}PSR_f, #expression". */
3143 skip_whitespace (str);
3145 if (psr_required_here (& str) == FAIL)
3148 if (skip_past_comma (& str) == FAIL)
3150 inst.error = _("comma missing after psr flags");
3154 skip_whitespace (str);
3156 if (reg_required_here (& str, 0) != FAIL)
3163 if (! is_immediate_prefix (* str))
3166 _("only a register or immediate value can follow a psr flag");
3173 if (my_get_expression (& inst.reloc.exp, & str))
3176 _("only a register or immediate value can follow a psr flag");
3180 #if 0 /* The first edition of the ARM architecture manual stated that
3181 writing anything other than the flags with an immediate operation
3182 had UNPREDICTABLE effects. This constraint was removed in the
3183 second edition of the specification. */
3184 if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
3185 && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
3187 inst.error = _("immediate value cannot be used to set this field");
3192 inst.instruction |= INST_IMMEDIATE;
3194 if (inst.reloc.exp.X_add_symbol)
3196 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
3197 inst.reloc.pc_rel = 0;
3201 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
3203 if (value == (unsigned) FAIL)
3205 inst.error = _("invalid constant");
3209 inst.instruction |= value;
3216 /* Long Multiply Parser
3217 UMULL RdLo, RdHi, Rm, Rs
3218 SMULL RdLo, RdHi, Rm, Rs
3219 UMLAL RdLo, RdHi, Rm, Rs
3220 SMLAL RdLo, RdHi, Rm, Rs. */
3226 int rdlo, rdhi, rm, rs;
3228 /* Only one format "rdlo, rdhi, rm, rs". */
3229 skip_whitespace (str);
3231 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
3233 inst.error = BAD_ARGS;
3237 if (skip_past_comma (&str) == FAIL
3238 || (rdhi = reg_required_here (&str, 16)) == FAIL)
3240 inst.error = BAD_ARGS;
3244 if (skip_past_comma (&str) == FAIL
3245 || (rm = reg_required_here (&str, 0)) == FAIL)
3247 inst.error = BAD_ARGS;
3251 /* rdhi, rdlo and rm must all be different. */
3252 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
3253 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
3255 if (skip_past_comma (&str) == FAIL
3256 || (rs = reg_required_here (&str, 8)) == FAIL)
3258 inst.error = BAD_ARGS;
3262 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
3264 inst.error = BAD_PC;
3278 /* Only one format "rd, rm, rs". */
3279 skip_whitespace (str);
3281 if ((rd = reg_required_here (&str, 16)) == FAIL)
3283 inst.error = BAD_ARGS;
3289 inst.error = BAD_PC;
3293 if (skip_past_comma (&str) == FAIL
3294 || (rm = reg_required_here (&str, 0)) == FAIL)
3296 inst.error = BAD_ARGS;
3302 inst.error = BAD_PC;
3307 as_tsktsk (_("rd and rm should be different in mul"));
3309 if (skip_past_comma (&str) == FAIL
3310 || (rm = reg_required_here (&str, 8)) == FAIL)
3312 inst.error = BAD_ARGS;
3318 inst.error = BAD_PC;
3332 /* Only one format "rd, rm, rs, rn". */
3333 skip_whitespace (str);
3335 if ((rd = reg_required_here (&str, 16)) == FAIL)
3337 inst.error = BAD_ARGS;
3343 inst.error = BAD_PC;
3347 if (skip_past_comma (&str) == FAIL
3348 || (rm = reg_required_here (&str, 0)) == FAIL)
3350 inst.error = BAD_ARGS;
3356 inst.error = BAD_PC;
3361 as_tsktsk (_("rd and rm should be different in mla"));
3363 if (skip_past_comma (&str) == FAIL
3364 || (rd = reg_required_here (&str, 8)) == FAIL
3365 || skip_past_comma (&str) == FAIL
3366 || (rm = reg_required_here (&str, 12)) == FAIL)
3368 inst.error = BAD_ARGS;
3372 if (rd == REG_PC || rm == REG_PC)
3374 inst.error = BAD_PC;
3382 /* Expects *str -> the characters "acc0", possibly with leading blanks.
3383 Advances *str to the next non-alphanumeric.
3384 Returns 0, or else FAIL (in which case sets inst.error).
3386 (In a future XScale, there may be accumulators other than zero.
3387 At that time this routine and its callers can be upgraded to suit.) */
3390 accum0_required_here (str)
3393 static char buff [128]; /* Note the address is taken. Hence, static. */
3396 int result = 0; /* The accum number. */
3398 skip_whitespace (p);
3400 *str = p; /* Advance caller's string pointer too. */
3405 *--p = 0; /* Aap nul into input buffer at non-alnum. */
3407 if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
3409 sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
3414 *p = c; /* Unzap. */
3415 *str = p; /* Caller's string pointer to after match. */
3419 /* Expects **str -> after a comma. May be leading blanks.
3420 Advances *str, recognizing a load mode, and setting inst.instruction.
3421 Returns rn, or else FAIL (in which case may set inst.error
3422 and not advance str)
3424 Note: doesn't know Rd, so no err checks that require such knowledge. */
3427 ld_mode_required_here (string)
3430 char * str = * string;
3434 skip_whitespace (str);
3440 skip_whitespace (str);
3442 if ((rn = reg_required_here (& str, 16)) == FAIL)
3445 skip_whitespace (str);
3451 if (skip_past_comma (& str) == SUCCESS)
3453 /* [Rn],... (post inc) */
3454 if (ldst_extend_v4 (&str) == FAIL)
3459 skip_whitespace (str);
3464 inst.instruction |= WRITE_BACK;
3467 inst.instruction |= INDEX_UP | HWOFFSET_IMM;
3473 if (skip_past_comma (& str) == FAIL)
3475 inst.error = _("pre-indexed expression expected");
3481 if (ldst_extend_v4 (&str) == FAIL)
3484 skip_whitespace (str);
3486 if (* str ++ != ']')
3488 inst.error = _("missing ]");
3492 skip_whitespace (str);
3497 inst.instruction |= WRITE_BACK;
3501 else if (* str == '=') /* ldr's "r,=label" syntax */
3502 /* We should never reach here, because <text> = <expression> is
3503 caught gas/read.c read_a_source_file() as a .set operation. */
3505 else /* PC +- 8 bit immediate offset. */
3507 if (my_get_expression (& inst.reloc.exp, & str))
3510 inst.instruction |= HWOFFSET_IMM; /* The I bit. */
3511 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
3512 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
3513 inst.reloc.pc_rel = 1;
3514 inst.instruction |= (REG_PC << 16);
3520 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
3526 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
3527 SMLAxy{cond} Rd,Rm,Rs,Rn
3528 SMLAWy{cond} Rd,Rm,Rs,Rn
3529 Error if any register is R15. */
3537 skip_whitespace (str);
3539 if ((rd = reg_required_here (& str, 16)) == FAIL
3540 || skip_past_comma (& str) == FAIL
3541 || (rm = reg_required_here (& str, 0)) == FAIL
3542 || skip_past_comma (& str) == FAIL
3543 || (rs = reg_required_here (& str, 8)) == FAIL
3544 || skip_past_comma (& str) == FAIL
3545 || (rn = reg_required_here (& str, 12)) == FAIL)
3546 inst.error = BAD_ARGS;
3548 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
3549 inst.error = BAD_PC;
3555 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
3556 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
3557 Error if any register is R15.
3558 Warning if Rdlo == Rdhi. */
3564 int rdlo, rdhi, rm, rs;
3566 skip_whitespace (str);
3568 if ((rdlo = reg_required_here (& str, 12)) == FAIL
3569 || skip_past_comma (& str) == FAIL
3570 || (rdhi = reg_required_here (& str, 16)) == FAIL
3571 || skip_past_comma (& str) == FAIL
3572 || (rm = reg_required_here (& str, 0)) == FAIL
3573 || skip_past_comma (& str) == FAIL
3574 || (rs = reg_required_here (& str, 8)) == FAIL)
3576 inst.error = BAD_ARGS;
3580 if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
3582 inst.error = BAD_PC;
3587 as_tsktsk (_("rdhi and rdlo must be different"));
3592 /* ARM V5E (El Segundo) signed-multiply (argument parse)
3593 SMULxy{cond} Rd,Rm,Rs
3594 Error if any register is R15. */
3602 skip_whitespace (str);
3604 if ((rd = reg_required_here (& str, 16)) == FAIL
3605 || skip_past_comma (& str) == FAIL
3606 || (rm = reg_required_here (& str, 0)) == FAIL
3607 || skip_past_comma (& str) == FAIL
3608 || (rs = reg_required_here (& str, 8)) == FAIL)
3609 inst.error = BAD_ARGS;
3611 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
3612 inst.error = BAD_PC;
3618 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
3619 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
3620 Error if any register is R15. */
3628 skip_whitespace (str);
3630 if ((rd = reg_required_here (& str, 12)) == FAIL
3631 || skip_past_comma (& str) == FAIL
3632 || (rm = reg_required_here (& str, 0)) == FAIL
3633 || skip_past_comma (& str) == FAIL
3634 || (rn = reg_required_here (& str, 16)) == FAIL)
3635 inst.error = BAD_ARGS;
3637 else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
3638 inst.error = BAD_PC;
3644 /* ARM V5E (el Segundo)
3645 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3646 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
3648 These are equivalent to the XScale instructions MAR and MRA,
3649 respectively, when coproc == 0, opcode == 0, and CRm == 0.
3651 Result unpredicatable if Rd or Rn is R15. */
3659 skip_whitespace (str);
3661 if (co_proc_number (& str) == FAIL)
3664 inst.error = BAD_ARGS;
3668 if (skip_past_comma (& str) == FAIL
3669 || cp_opc_expr (& str, 4, 4) == FAIL)
3672 inst.error = BAD_ARGS;
3676 if (skip_past_comma (& str) == FAIL
3677 || (rd = reg_required_here (& str, 12)) == FAIL)
3680 inst.error = BAD_ARGS;
3684 if (skip_past_comma (& str) == FAIL
3685 || (rn = reg_required_here (& str, 16)) == FAIL)
3688 inst.error = BAD_ARGS;
3692 /* Unpredictable result if rd or rn is R15. */
3693 if (rd == REG_PC || rn == REG_PC)
3695 (_("Warning: instruction unpredictable when using r15"));
3697 if (skip_past_comma (& str) == FAIL
3698 || cp_reg_required_here (& str, 0) == FAIL)
3701 inst.error = BAD_ARGS;
3708 /* ARM V5 count-leading-zeroes instruction (argument parse)
3709 CLZ{<cond>} <Rd>, <Rm>
3710 Condition defaults to COND_ALWAYS.
3711 Error if Rd or Rm are R15. */
3719 skip_whitespace (str);
3721 if (((rd = reg_required_here (& str, 12)) == FAIL)
3722 || (skip_past_comma (& str) == FAIL)
3723 || ((rm = reg_required_here (& str, 0)) == FAIL))
3724 inst.error = BAD_ARGS;
3726 else if (rd == REG_PC || rm == REG_PC )
3727 inst.error = BAD_PC;
3733 /* ARM V5 (argument parse)
3734 LDC2{L} <coproc>, <CRd>, <addressing mode>
3735 STC2{L} <coproc>, <CRd>, <addressing mode>
3736 Instruction is not conditional, and has 0xf in the codition field.
3737 Otherwise, it's the same as LDC/STC. */
3743 skip_whitespace (str);
3745 if (co_proc_number (& str) == FAIL)
3748 inst.error = BAD_ARGS;
3750 else if (skip_past_comma (& str) == FAIL
3751 || cp_reg_required_here (& str, 12) == FAIL)
3754 inst.error = BAD_ARGS;
3756 else if (skip_past_comma (& str) == FAIL
3757 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
3760 inst.error = BAD_ARGS;
3766 /* ARM V5 (argument parse)
3767 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3768 Instruction is not conditional, and has 0xf in the condition field.
3769 Otherwise, it's the same as CDP. */
3775 skip_whitespace (str);
3777 if (co_proc_number (& str) == FAIL)
3780 inst.error = BAD_ARGS;
3784 if (skip_past_comma (& str) == FAIL
3785 || cp_opc_expr (& str, 20,4) == FAIL)
3788 inst.error = BAD_ARGS;
3792 if (skip_past_comma (& str) == FAIL
3793 || cp_reg_required_here (& str, 12) == FAIL)
3796 inst.error = BAD_ARGS;
3800 if (skip_past_comma (& str) == FAIL
3801 || cp_reg_required_here (& str, 16) == FAIL)
3804 inst.error = BAD_ARGS;
3808 if (skip_past_comma (& str) == FAIL
3809 || cp_reg_required_here (& str, 0) == FAIL)
3812 inst.error = BAD_ARGS;
3816 if (skip_past_comma (& str) == SUCCESS)
3818 if (cp_opc_expr (& str, 5, 3) == FAIL)
3821 inst.error = BAD_ARGS;
3829 /* ARM V5 (argument parse)
3830 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3831 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3832 Instruction is not conditional, and has 0xf in the condition field.
3833 Otherwise, it's the same as MCR/MRC. */
3839 skip_whitespace (str);
3841 if (co_proc_number (& str) == FAIL)
3844 inst.error = BAD_ARGS;
3848 if (skip_past_comma (& str) == FAIL
3849 || cp_opc_expr (& str, 21, 3) == FAIL)
3852 inst.error = BAD_ARGS;
3856 if (skip_past_comma (& str) == FAIL
3857 || reg_required_here (& str, 12) == FAIL)
3860 inst.error = BAD_ARGS;
3864 if (skip_past_comma (& str) == FAIL
3865 || cp_reg_required_here (& str, 16) == FAIL)
3868 inst.error = BAD_ARGS;
3872 if (skip_past_comma (& str) == FAIL
3873 || cp_reg_required_here (& str, 0) == FAIL)
3876 inst.error = BAD_ARGS;
3880 if (skip_past_comma (& str) == SUCCESS)
3882 if (cp_opc_expr (& str, 5, 3) == FAIL)
3885 inst.error = BAD_ARGS;
3893 /* ARM v5TEJ. Jump to Jazelle code. */
3900 skip_whitespace (str);
3902 if ((reg = reg_required_here (&str, 0)) == FAIL)
3904 inst.error = BAD_ARGS;
3908 /* Note - it is not illegal to do a "bxj pc". Useless, but not illegal. */
3910 as_tsktsk (_("use of r15 in bxj is not really useful"));
3915 /* THUMB V5 breakpoint instruction (argument parse)
3923 unsigned long number;
3925 skip_whitespace (str);
3927 /* Allow optional leading '#'. */
3928 if (is_immediate_prefix (*str))
3931 memset (& expr, '\0', sizeof (expr));
3932 if (my_get_expression (& expr, & str)
3933 || (expr.X_op != O_constant
3934 /* As a convenience we allow 'bkpt' without an operand. */
3935 && expr.X_op != O_absent))
3937 inst.error = _("bad expression");
3941 number = expr.X_add_number;
3943 /* Check it fits an 8 bit unsigned. */
3944 if (number != (number & 0xff))
3946 inst.error = _("immediate value out of range");
3950 inst.instruction |= number;
3955 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3956 Expects inst.instruction is set for BLX(1).
3957 Note: this is cloned from do_branch, and the reloc changed to be a
3958 new one that can cope with setting one extra bit (the H bit). */
3964 if (my_get_expression (& inst.reloc.exp, & str))
3971 /* ScottB: February 5, 1998 */
3972 /* Check to see of PLT32 reloc required for the instruction. */
3974 /* arm_parse_reloc() works on input_line_pointer.
3975 We actually want to parse the operands to the branch instruction
3976 passed in 'str'. Save the input pointer and restore it later. */
3977 save_in = input_line_pointer;
3978 input_line_pointer = str;
3980 if (inst.reloc.exp.X_op == O_symbol
3982 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3984 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3985 inst.reloc.pc_rel = 0;
3986 /* Modify str to point to after parsed operands, otherwise
3987 end_of_line() will complain about the (PLT) left in str. */
3988 str = input_line_pointer;
3992 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
3993 inst.reloc.pc_rel = 1;
3996 input_line_pointer = save_in;
3999 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
4000 inst.reloc.pc_rel = 1;
4001 #endif /* OBJ_ELF */
4006 /* ARM V5 branch-link-exchange instruction (argument parse)
4007 BLX <target_addr> ie BLX(1)
4008 BLX{<condition>} <Rm> ie BLX(2)
4009 Unfortunately, there are two different opcodes for this mnemonic.
4010 So, the insns[].value is not used, and the code here zaps values
4011 into inst.instruction.
4012 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
4021 skip_whitespace (mystr);
4022 rm = reg_required_here (& mystr, 0);
4024 /* The above may set inst.error. Ignore his opinion. */
4029 /* Arg is a register.
4030 Use the condition code our caller put in inst.instruction.
4031 Pass ourselves off as a BX with a funny opcode. */
4032 inst.instruction |= 0x012fff30;
4037 /* This must be is BLX <target address>, no condition allowed. */
4038 if (inst.instruction != COND_ALWAYS)
4040 inst.error = BAD_COND;
4044 inst.instruction = 0xfafffffe;
4046 /* Process like a B/BL, but with a different reloc.
4047 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
4052 /* ARM V5 Thumb BLX (argument parse)
4053 BLX <target_addr> which is BLX(1)
4054 BLX <Rm> which is BLX(2)
4055 Unfortunately, there are two different opcodes for this mnemonic.
4056 So, the tinsns[].value is not used, and the code here zaps values
4057 into inst.instruction. */
4066 skip_whitespace (mystr);
4067 inst.instruction = 0x4780;
4069 /* Note that this call is to the ARM register recognizer. BLX(2)
4070 uses the ARM register space, not the Thumb one, so a call to
4071 thumb_reg() would be wrong. */
4072 rm = reg_required_here (& mystr, 3);
4077 /* It's BLX(2). The .instruction was zapped with rm & is final. */
4082 /* No ARM register. This must be BLX(1). Change the .instruction. */
4083 inst.instruction = 0xf7ffeffe;
4086 if (my_get_expression (& inst.reloc.exp, & mystr))
4089 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
4090 inst.reloc.pc_rel = 1;
4093 end_of_line (mystr);
4096 /* ARM V5 breakpoint instruction (argument parse)
4097 BKPT <16 bit unsigned immediate>
4098 Instruction is not conditional.
4099 The bit pattern given in insns[] has the COND_ALWAYS condition,
4100 and it is an error if the caller tried to override that. */
4107 unsigned long number;
4109 skip_whitespace (str);
4111 /* Allow optional leading '#'. */
4112 if (is_immediate_prefix (* str))
4115 memset (& expr, '\0', sizeof (expr));
4117 if (my_get_expression (& expr, & str)
4118 || (expr.X_op != O_constant
4119 /* As a convenience we allow 'bkpt' without an operand. */
4120 && expr.X_op != O_absent))
4122 inst.error = _("bad expression");
4126 number = expr.X_add_number;
4128 /* Check it fits a 16 bit unsigned. */
4129 if (number != (number & 0xffff))
4131 inst.error = _("immediate value out of range");
4135 /* Top 12 of 16 bits to bits 19:8. */
4136 inst.instruction |= (number & 0xfff0) << 4;
4138 /* Bottom 4 of 16 bits to bits 3:0. */
4139 inst.instruction |= number & 0xf;
4144 /* Xscale multiply-accumulate (argument parse)
4147 MIAxycc acc0,Rm,Rs. */
4156 if (accum0_required_here (& str) == FAIL)
4157 inst.error = ERR_NO_ACCUM;
4159 else if (skip_past_comma (& str) == FAIL
4160 || (rm = reg_required_here (& str, 0)) == FAIL)
4161 inst.error = BAD_ARGS;
4163 else if (skip_past_comma (& str) == FAIL
4164 || (rs = reg_required_here (& str, 12)) == FAIL)
4165 inst.error = BAD_ARGS;
4167 /* inst.instruction has now been zapped with both rm and rs. */
4168 else if (rm == REG_PC || rs == REG_PC)
4169 inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */
4175 /* Xscale move-accumulator-register (argument parse)
4177 MARcc acc0,RdLo,RdHi. */
4185 if (accum0_required_here (& str) == FAIL)
4186 inst.error = ERR_NO_ACCUM;
4188 else if (skip_past_comma (& str) == FAIL
4189 || (rdlo = reg_required_here (& str, 12)) == FAIL)
4190 inst.error = BAD_ARGS;
4192 else if (skip_past_comma (& str) == FAIL
4193 || (rdhi = reg_required_here (& str, 16)) == FAIL)
4194 inst.error = BAD_ARGS;
4196 /* inst.instruction has now been zapped with both rdlo and rdhi. */
4197 else if (rdlo == REG_PC || rdhi == REG_PC)
4198 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
4204 /* Xscale move-register-accumulator (argument parse)
4206 MRAcc RdLo,RdHi,acc0. */
4215 skip_whitespace (str);
4217 if ((rdlo = reg_required_here (& str, 12)) == FAIL)
4218 inst.error = BAD_ARGS;
4220 else if (skip_past_comma (& str) == FAIL
4221 || (rdhi = reg_required_here (& str, 16)) == FAIL)
4222 inst.error = BAD_ARGS;
4224 else if (skip_past_comma (& str) == FAIL
4225 || accum0_required_here (& str) == FAIL)
4226 inst.error = ERR_NO_ACCUM;
4228 /* inst.instruction has now been zapped with both rdlo and rdhi. */
4229 else if (rdlo == rdhi)
4230 inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */
4232 else if (rdlo == REG_PC || rdhi == REG_PC)
4233 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
4238 /* ARMv5TE: Preload-Cache
4242 Syntactically, like LDR with B=1, W=0, L=1. */
4250 skip_whitespace (str);
4254 inst.error = _("'[' expected after PLD mnemonic");
4259 skip_whitespace (str);
4261 if ((rd = reg_required_here (& str, 16)) == FAIL)
4264 skip_whitespace (str);
4270 skip_whitespace (str);
4272 /* Post-indexed addressing is not allowed with PLD. */
4273 if (skip_past_comma (&str) == SUCCESS)
4276 = _("post-indexed expression used in preload instruction");
4279 else if (*str == '!') /* [Rn]! */
4281 inst.error = _("writeback used in preload instruction");
4285 inst.instruction |= INDEX_UP | PRE_INDEX;
4287 else /* [Rn, ...] */
4289 if (skip_past_comma (& str) == FAIL)
4291 inst.error = _("pre-indexed expression expected");
4295 if (ldst_extend (&str) == FAIL)
4298 skip_whitespace (str);
4302 inst.error = _("missing ]");
4307 skip_whitespace (str);
4309 if (* str == '!') /* [Rn]! */
4311 inst.error = _("writeback used in preload instruction");
4315 inst.instruction |= PRE_INDEX;
4321 /* ARMv5TE load-consecutive (argument parse)
4334 skip_whitespace (str);
4336 if ((rd = reg_required_here (& str, 12)) == FAIL)
4338 inst.error = BAD_ARGS;
4342 if (skip_past_comma (& str) == FAIL
4343 || (rn = ld_mode_required_here (& str)) == FAIL)
4346 inst.error = BAD_ARGS;
4350 /* inst.instruction has now been zapped with Rd and the addressing mode. */
4351 if (rd & 1) /* Unpredictable result if Rd is odd. */
4353 inst.error = _("destination register must be even");
4359 inst.error = _("r14 not allowed here");
4363 if (((rd == rn) || (rd + 1 == rn))
4364 && ((inst.instruction & WRITE_BACK)
4365 || (!(inst.instruction & PRE_INDEX))))
4366 as_warn (_("pre/post-indexing used when modified address register is destination"));
4368 /* For an index-register load, the index register must not overlap the
4369 destination (even if not write-back). */
4370 if ((inst.instruction & V4_STR_BIT) == 0
4371 && (inst.instruction & HWOFFSET_IMM) == 0)
4373 int rm = inst.instruction & 0x0000000f;
4375 if (rm == rd || (rm == rd + 1))
4376 as_warn (_("ldrd destination registers must not overlap index register"));
4382 /* Returns the index into fp_values of a floating point number,
4383 or -1 if not in the table. */
4386 my_get_float_expression (str)
4389 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4395 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
4397 /* Look for a raw floating point number. */
4398 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
4399 && is_end_of_line[(unsigned char) *save_in])
4401 for (i = 0; i < NUM_FLOAT_VALS; i++)
4403 for (j = 0; j < MAX_LITTLENUMS; j++)
4405 if (words[j] != fp_values[i][j])
4409 if (j == MAX_LITTLENUMS)
4417 /* Try and parse a more complex expression, this will probably fail
4418 unless the code uses a floating point prefix (eg "0f"). */
4419 save_in = input_line_pointer;
4420 input_line_pointer = *str;
4421 if (expression (&exp) == absolute_section
4422 && exp.X_op == O_big
4423 && exp.X_add_number < 0)
4425 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
4427 if (gen_to_words (words, 5, (long) 15) == 0)
4429 for (i = 0; i < NUM_FLOAT_VALS; i++)
4431 for (j = 0; j < MAX_LITTLENUMS; j++)
4433 if (words[j] != fp_values[i][j])
4437 if (j == MAX_LITTLENUMS)
4439 *str = input_line_pointer;
4440 input_line_pointer = save_in;
4447 *str = input_line_pointer;
4448 input_line_pointer = save_in;
4452 /* Return TRUE if anything in the expression is a bignum. */
4455 walk_no_bignums (sp)
4458 if (symbol_get_value_expression (sp)->X_op == O_big)
4461 if (symbol_get_value_expression (sp)->X_add_symbol)
4463 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
4464 || (symbol_get_value_expression (sp)->X_op_symbol
4465 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
4471 static int in_my_get_expression = 0;
4474 my_get_expression (ep, str)
4481 save_in = input_line_pointer;
4482 input_line_pointer = *str;
4483 in_my_get_expression = 1;
4484 seg = expression (ep);
4485 in_my_get_expression = 0;
4487 if (ep->X_op == O_illegal)
4489 /* We found a bad expression in md_operand(). */
4490 *str = input_line_pointer;
4491 input_line_pointer = save_in;
4496 if (seg != absolute_section
4497 && seg != text_section
4498 && seg != data_section
4499 && seg != bss_section
4500 && seg != undefined_section)
4502 inst.error = _("bad_segment");
4503 *str = input_line_pointer;
4504 input_line_pointer = save_in;
4509 /* Get rid of any bignums now, so that we don't generate an error for which
4510 we can't establish a line number later on. Big numbers are never valid
4511 in instructions, which is where this routine is always called. */
4512 if (ep->X_op == O_big
4513 || (ep->X_add_symbol
4514 && (walk_no_bignums (ep->X_add_symbol)
4516 && walk_no_bignums (ep->X_op_symbol)))))
4518 inst.error = _("invalid constant");
4519 *str = input_line_pointer;
4520 input_line_pointer = save_in;
4524 *str = input_line_pointer;
4525 input_line_pointer = save_in;
4529 /* We handle all bad expressions here, so that we can report the faulty
4530 instruction in the error message. */
4535 if (in_my_get_expression)
4537 expr->X_op = O_illegal;
4538 if (inst.error == NULL)
4539 inst.error = _("bad expression");
4543 /* UNRESTRICT should be one if <shift> <register> is permitted for this
4547 decode_shift (str, unrestrict)
4551 const struct asm_shift_name * shift;
4555 skip_whitespace (* str);
4557 for (p = * str; ISALPHA (* p); p ++)
4562 inst.error = _("shift expression expected");
4568 shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
4573 inst.error = _("shift expression expected");
4577 assert (shift->properties->index == shift_properties[shift->properties->index].index);
4579 if (shift->properties->index == SHIFT_RRX)
4582 inst.instruction |= shift->properties->bit_field;
4586 skip_whitespace (p);
4588 if (unrestrict && reg_required_here (& p, 8) != FAIL)
4590 inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
4594 else if (! is_immediate_prefix (* p))
4596 inst.error = (unrestrict
4597 ? _("shift requires register or #expression")
4598 : _("shift requires #expression"));
4606 if (my_get_expression (& inst.reloc.exp, & p))
4609 /* Validate some simple #expressions. */
4610 if (inst.reloc.exp.X_op == O_constant)
4612 unsigned num = inst.reloc.exp.X_add_number;
4614 /* Reject operations greater than 32. */
4616 /* Reject a shift of 0 unless the mode allows it. */
4617 || (num == 0 && shift->properties->allows_0 == 0)
4618 /* Reject a shift of 32 unless the mode allows it. */
4619 || (num == 32 && shift->properties->allows_32 == 0)
4622 /* As a special case we allow a shift of zero for
4623 modes that do not support it to be recoded as an
4624 logical shift left of zero (ie nothing). We warn
4625 about this though. */
4628 as_warn (_("shift of 0 ignored."));
4629 shift = & shift_names[0];
4630 assert (shift->properties->index == SHIFT_LSL);
4634 inst.error = _("invalid immediate shift");
4639 /* Shifts of 32 are encoded as 0, for those shifts that
4644 inst.instruction |= (num << 7) | shift->properties->bit_field;
4648 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
4649 inst.reloc.pc_rel = 0;
4650 inst.instruction |= shift->properties->bit_field;
4657 /* Do those data_ops which can take a negative immediate constant
4658 by altering the instuction. A bit of a hack really.
4662 by inverting the second operand, and
4665 by negating the second operand. */
4668 negate_data_op (instruction, value)
4669 unsigned long * instruction;
4670 unsigned long value;
4673 unsigned long negated, inverted;
4675 negated = validate_immediate (-value);
4676 inverted = validate_immediate (~value);
4678 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
4681 /* First negates. */
4682 case OPCODE_SUB: /* ADD <-> SUB */
4683 new_inst = OPCODE_ADD;
4688 new_inst = OPCODE_SUB;
4692 case OPCODE_CMP: /* CMP <-> CMN */
4693 new_inst = OPCODE_CMN;
4698 new_inst = OPCODE_CMP;
4702 /* Now Inverted ops. */
4703 case OPCODE_MOV: /* MOV <-> MVN */
4704 new_inst = OPCODE_MVN;
4709 new_inst = OPCODE_MOV;
4713 case OPCODE_AND: /* AND <-> BIC */
4714 new_inst = OPCODE_BIC;
4719 new_inst = OPCODE_AND;
4723 case OPCODE_ADC: /* ADC <-> SBC */
4724 new_inst = OPCODE_SBC;
4729 new_inst = OPCODE_ADC;
4733 /* We cannot do anything. */
4738 if (value == (unsigned) FAIL)
4741 *instruction &= OPCODE_MASK;
4742 *instruction |= new_inst << DATA_OP_SHIFT;
4753 skip_whitespace (* str);
4755 if (reg_required_here (str, 0) != FAIL)
4757 if (skip_past_comma (str) == SUCCESS)
4758 /* Shift operation on register. */
4759 return decode_shift (str, NO_SHIFT_RESTRICT);
4765 /* Immediate expression. */
4766 if (is_immediate_prefix (**str))
4771 if (my_get_expression (&inst.reloc.exp, str))
4774 if (inst.reloc.exp.X_add_symbol)
4776 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4777 inst.reloc.pc_rel = 0;
4781 if (skip_past_comma (str) == SUCCESS)
4783 /* #x, y -- ie explicit rotation by Y. */
4784 if (my_get_expression (&expr, str))
4787 if (expr.X_op != O_constant)
4789 inst.error = _("constant expression expected");
4793 /* Rotate must be a multiple of 2. */
4794 if (((unsigned) expr.X_add_number) > 30
4795 || (expr.X_add_number & 1) != 0
4796 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
4798 inst.error = _("invalid constant");
4801 inst.instruction |= INST_IMMEDIATE;
4802 inst.instruction |= inst.reloc.exp.X_add_number;
4803 inst.instruction |= expr.X_add_number << 7;
4807 /* Implicit rotation, select a suitable one. */
4808 value = validate_immediate (inst.reloc.exp.X_add_number);
4812 /* Can't be done. Perhaps the code reads something like
4813 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
4814 if ((value = negate_data_op (&inst.instruction,
4815 inst.reloc.exp.X_add_number))
4818 inst.error = _("invalid constant");
4823 inst.instruction |= value;
4826 inst.instruction |= INST_IMMEDIATE;
4831 inst.error = _("register or shift expression expected");
4840 skip_whitespace (* str);
4842 if (fp_reg_required_here (str, 0) != FAIL)
4846 /* Immediate expression. */
4847 if (*((*str)++) == '#')
4853 skip_whitespace (* str);
4855 /* First try and match exact strings, this is to guarantee
4856 that some formats will work even for cross assembly. */
4858 for (i = 0; fp_const[i]; i++)
4860 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
4864 *str += strlen (fp_const[i]);
4865 if (is_end_of_line[(unsigned char) **str])
4867 inst.instruction |= i + 8;
4874 /* Just because we didn't get a match doesn't mean that the
4875 constant isn't valid, just that it is in a format that we
4876 don't automatically recognize. Try parsing it with
4877 the standard expression routines. */
4878 if ((i = my_get_float_expression (str)) >= 0)
4880 inst.instruction |= i + 8;
4884 inst.error = _("invalid floating point immediate expression");
4888 _("floating point register or immediate expression expected");
4897 skip_whitespace (str);
4899 if (reg_required_here (&str, 12) == FAIL
4900 || skip_past_comma (&str) == FAIL
4901 || reg_required_here (&str, 16) == FAIL
4902 || skip_past_comma (&str) == FAIL
4903 || data_op2 (&str) == FAIL)
4906 inst.error = BAD_ARGS;
4918 /* This is a pseudo-op of the form "adr rd, label" to be converted
4919 into a relative address of the form "add rd, pc, #label-.-8". */
4920 skip_whitespace (str);
4922 if (reg_required_here (&str, 12) == FAIL
4923 || skip_past_comma (&str) == FAIL
4924 || my_get_expression (&inst.reloc.exp, &str))
4927 inst.error = BAD_ARGS;
4931 /* Frag hacking will turn this into a sub instruction if the offset turns
4932 out to be negative. */
4933 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4934 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
4935 inst.reloc.pc_rel = 1;
4944 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4945 into a relative address of the form:
4946 add rd, pc, #low(label-.-8)"
4947 add rd, rd, #high(label-.-8)" */
4949 skip_whitespace (str);
4951 if (reg_required_here (&str, 12) == FAIL
4952 || skip_past_comma (&str) == FAIL
4953 || my_get_expression (&inst.reloc.exp, &str))
4956 inst.error = BAD_ARGS;
4962 /* Frag hacking will turn this into a sub instruction if the offset turns
4963 out to be negative. */
4964 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
4965 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
4966 inst.reloc.pc_rel = 1;
4967 inst.size = INSN_SIZE * 2;
4976 skip_whitespace (str);
4978 if (reg_required_here (&str, 16) == FAIL)
4981 inst.error = BAD_ARGS;
4985 if (skip_past_comma (&str) == FAIL
4986 || data_op2 (&str) == FAIL)
4989 inst.error = BAD_ARGS;
5001 skip_whitespace (str);
5003 if (reg_required_here (&str, 12) == FAIL)
5006 inst.error = BAD_ARGS;
5010 if (skip_past_comma (&str) == FAIL
5011 || data_op2 (&str) == FAIL)
5014 inst.error = BAD_ARGS;
5033 if (my_get_expression (& inst.reloc.exp, str))
5036 if (inst.reloc.exp.X_op == O_constant)
5038 int value = inst.reloc.exp.X_add_number;
5040 if (value < -4095 || value > 4095)
5042 inst.error = _("address offset too large");
5052 inst.instruction |= add | value;
5056 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5057 inst.reloc.pc_rel = 0;
5070 if (reg_required_here (str, 0) == FAIL)
5073 inst.instruction |= add | OFFSET_REG;
5074 if (skip_past_comma (str) == SUCCESS)
5075 return decode_shift (str, SHIFT_RESTRICT);
5089 skip_whitespace (str);
5091 if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
5094 inst.error = BAD_ARGS;
5098 if (skip_past_comma (&str) == FAIL)
5100 inst.error = _("address expected");
5110 skip_whitespace (str);
5112 if ((reg = reg_required_here (&str, 16)) == FAIL)
5115 /* Conflicts can occur on stores as well as loads. */
5116 conflict_reg = (conflict_reg == reg);
5118 skip_whitespace (str);
5124 if (skip_past_comma (&str) == SUCCESS)
5126 /* [Rn],... (post inc) */
5127 if (ldst_extend (&str) == FAIL)
5130 as_warn (_("%s register same as write-back base"),
5131 ((inst.instruction & LOAD_BIT)
5132 ? _("destination") : _("source")));
5137 skip_whitespace (str);
5142 as_warn (_("%s register same as write-back base"),
5143 ((inst.instruction & LOAD_BIT)
5144 ? _("destination") : _("source")));
5146 inst.instruction |= WRITE_BACK;
5149 inst.instruction |= INDEX_UP;
5156 if (skip_past_comma (&str) == FAIL)
5158 inst.error = _("pre-indexed expression expected");
5163 if (ldst_extend (&str) == FAIL)
5166 skip_whitespace (str);
5170 inst.error = _("missing ]");
5174 skip_whitespace (str);
5179 as_warn (_("%s register same as write-back base"),
5180 ((inst.instruction & LOAD_BIT)
5181 ? _("destination") : _("source")));
5183 inst.instruction |= WRITE_BACK;
5187 else if (*str == '=')
5189 if ((inst.instruction & LOAD_BIT) == 0)
5191 inst.error = _("invalid pseudo operation");
5195 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5198 skip_whitespace (str);
5200 if (my_get_expression (&inst.reloc.exp, &str))
5203 if (inst.reloc.exp.X_op != O_constant
5204 && inst.reloc.exp.X_op != O_symbol)
5206 inst.error = _("constant expression expected");
5210 if (inst.reloc.exp.X_op == O_constant)
5212 value = validate_immediate (inst.reloc.exp.X_add_number);
5216 /* This can be done with a mov instruction. */
5217 inst.instruction &= LITERAL_MASK;
5218 inst.instruction |= (INST_IMMEDIATE
5219 | (OPCODE_MOV << DATA_OP_SHIFT));
5220 inst.instruction |= value & 0xfff;
5225 value = validate_immediate (~inst.reloc.exp.X_add_number);
5229 /* This can be done with a mvn instruction. */
5230 inst.instruction &= LITERAL_MASK;
5231 inst.instruction |= (INST_IMMEDIATE
5232 | (OPCODE_MVN << DATA_OP_SHIFT));
5233 inst.instruction |= value & 0xfff;
5239 /* Insert into literal pool. */
5240 if (add_to_lit_pool () == FAIL)
5243 inst.error = _("literal pool insertion failed");
5247 /* Change the instruction exp to point to the pool. */
5248 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
5249 inst.reloc.pc_rel = 1;
5250 inst.instruction |= (REG_PC << 16);
5255 if (my_get_expression (&inst.reloc.exp, &str))
5258 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
5260 /* PC rel adjust. */
5261 inst.reloc.exp.X_add_number -= 8;
5263 inst.reloc.pc_rel = 1;
5264 inst.instruction |= (REG_PC << 16);
5268 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
5279 skip_whitespace (str);
5281 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
5284 inst.error = BAD_ARGS;
5288 if (skip_past_comma (& str) == FAIL)
5290 inst.error = _("address expected");
5300 skip_whitespace (str);
5302 if ((reg = reg_required_here (&str, 16)) == FAIL)
5305 /* ldrt/strt always use post-indexed addressing, so if the base is
5306 the same as Rd, we warn. */
5307 if (conflict_reg == reg)
5308 as_warn (_("%s register same as write-back base"),
5309 ((inst.instruction & LOAD_BIT)
5310 ? _("destination") : _("source")));
5312 skip_whitespace (str);
5318 if (skip_past_comma (&str) == SUCCESS)
5320 /* [Rn],... (post inc) */
5321 if (ldst_extend (&str) == FAIL)
5327 skip_whitespace (str);
5329 /* Skip a write-back '!'. */
5333 inst.instruction |= INDEX_UP;
5338 inst.error = _("post-indexed expression expected");
5344 inst.error = _("post-indexed expression expected");
5353 ldst_extend_v4 (str)
5363 if (my_get_expression (& inst.reloc.exp, str))
5366 if (inst.reloc.exp.X_op == O_constant)
5368 int value = inst.reloc.exp.X_add_number;
5370 if (value < -255 || value > 255)
5372 inst.error = _("address offset too large");
5382 /* Halfword and signextension instructions have the
5383 immediate value split across bits 11..8 and bits 3..0. */
5384 inst.instruction |= (add | HWOFFSET_IMM
5385 | ((value >> 4) << 8) | (value & 0xF));
5389 inst.instruction |= HWOFFSET_IMM;
5390 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
5391 inst.reloc.pc_rel = 0;
5404 if (reg_required_here (str, 0) == FAIL)
5407 inst.instruction |= add;
5412 /* Halfword and signed-byte load/store operations. */
5421 skip_whitespace (str);
5423 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
5426 inst.error = BAD_ARGS;
5430 if (skip_past_comma (& str) == FAIL)
5432 inst.error = _("address expected");
5442 skip_whitespace (str);
5444 if ((reg = reg_required_here (&str, 16)) == FAIL)
5447 /* Conflicts can occur on stores as well as loads. */
5448 conflict_reg = (conflict_reg == reg);
5450 skip_whitespace (str);
5456 if (skip_past_comma (&str) == SUCCESS)
5458 /* [Rn],... (post inc) */
5459 if (ldst_extend_v4 (&str) == FAIL)
5462 as_warn (_("%s register same as write-back base"),
5463 ((inst.instruction & LOAD_BIT)
5464 ? _("destination") : _("source")));
5469 inst.instruction |= HWOFFSET_IMM;
5471 skip_whitespace (str);
5476 as_warn (_("%s register same as write-back base"),
5477 ((inst.instruction & LOAD_BIT)
5478 ? _("destination") : _("source")));
5480 inst.instruction |= WRITE_BACK;
5483 inst.instruction |= INDEX_UP;
5490 if (skip_past_comma (&str) == FAIL)
5492 inst.error = _("pre-indexed expression expected");
5497 if (ldst_extend_v4 (&str) == FAIL)
5500 skip_whitespace (str);
5504 inst.error = _("missing ]");
5508 skip_whitespace (str);
5513 as_warn (_("%s register same as write-back base"),
5514 ((inst.instruction & LOAD_BIT)
5515 ? _("destination") : _("source")));
5517 inst.instruction |= WRITE_BACK;
5521 else if (*str == '=')
5523 if ((inst.instruction & LOAD_BIT) == 0)
5525 inst.error = _("invalid pseudo operation");
5529 /* XXX Does this work correctly for half-word/byte ops? */
5530 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5533 skip_whitespace (str);
5535 if (my_get_expression (&inst.reloc.exp, &str))
5538 if (inst.reloc.exp.X_op != O_constant
5539 && inst.reloc.exp.X_op != O_symbol)
5541 inst.error = _("constant expression expected");
5545 if (inst.reloc.exp.X_op == O_constant)
5547 value = validate_immediate (inst.reloc.exp.X_add_number);
5551 /* This can be done with a mov instruction. */
5552 inst.instruction &= LITERAL_MASK;
5553 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
5554 inst.instruction |= value & 0xfff;
5559 value = validate_immediate (~ inst.reloc.exp.X_add_number);
5563 /* This can be done with a mvn instruction. */
5564 inst.instruction &= LITERAL_MASK;
5565 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
5566 inst.instruction |= value & 0xfff;
5572 /* Insert into literal pool. */
5573 if (add_to_lit_pool () == FAIL)
5576 inst.error = _("literal pool insertion failed");
5580 /* Change the instruction exp to point to the pool. */
5581 inst.instruction |= HWOFFSET_IMM;
5582 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
5583 inst.reloc.pc_rel = 1;
5584 inst.instruction |= (REG_PC << 16);
5589 if (my_get_expression (&inst.reloc.exp, &str))
5592 inst.instruction |= HWOFFSET_IMM;
5593 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
5595 /* PC rel adjust. */
5596 inst.reloc.exp.X_add_number -= 8;
5598 inst.reloc.pc_rel = 1;
5599 inst.instruction |= (REG_PC << 16);
5603 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
5612 char * str = * strp;
5616 /* We come back here if we get ranges concatenated by '+' or '|'. */
5631 skip_whitespace (str);
5633 if ((reg = reg_required_here (& str, -1)) == FAIL)
5642 inst.error = _("bad range in register list");
5646 for (i = cur_reg + 1; i < reg; i++)
5648 if (range & (1 << i))
5650 (_("Warning: duplicated register (r%d) in register list"),
5658 if (range & (1 << reg))
5659 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
5661 else if (reg <= cur_reg)
5662 as_tsktsk (_("Warning: register range not in ascending order"));
5667 while (skip_past_comma (&str) != FAIL
5668 || (in_range = 1, *str++ == '-'));
5670 skip_whitespace (str);
5674 inst.error = _("missing `}'");
5682 if (my_get_expression (&expr, &str))
5685 if (expr.X_op == O_constant)
5687 if (expr.X_add_number
5688 != (expr.X_add_number & 0x0000ffff))
5690 inst.error = _("invalid register mask");
5694 if ((range & expr.X_add_number) != 0)
5696 int regno = range & expr.X_add_number;
5699 regno = (1 << regno) - 1;
5701 (_("Warning: duplicated register (r%d) in register list"),
5705 range |= expr.X_add_number;
5709 if (inst.reloc.type != 0)
5711 inst.error = _("expression too complex");
5715 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
5716 inst.reloc.type = BFD_RELOC_ARM_MULTI;
5717 inst.reloc.pc_rel = 0;
5721 skip_whitespace (str);
5723 if (*str == '|' || *str == '+')
5729 while (another_range);
5742 skip_whitespace (str);
5744 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
5747 if (base_reg == REG_PC)
5749 inst.error = _("r15 not allowed as base register");
5753 skip_whitespace (str);
5757 inst.instruction |= WRITE_BACK;
5761 if (skip_past_comma (&str) == FAIL
5762 || (range = reg_list (&str)) == FAIL)
5765 inst.error = BAD_ARGS;
5772 inst.instruction |= LDM_TYPE_2_OR_3;
5775 if (inst.instruction & WRITE_BACK)
5777 /* Check for unpredictable uses of writeback. */
5778 if (inst.instruction & LOAD_BIT)
5780 /* Not allowed in LDM type 2. */
5781 if ((inst.instruction & LDM_TYPE_2_OR_3)
5782 && ((range & (1 << REG_PC)) == 0))
5783 as_warn (_("writeback of base register is UNPREDICTABLE"));
5784 /* Only allowed if base reg not in list for other types. */
5785 else if (range & (1 << base_reg))
5786 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
5790 /* Not allowed for type 2. */
5791 if (inst.instruction & LDM_TYPE_2_OR_3)
5792 as_warn (_("writeback of base register is UNPREDICTABLE"));
5793 /* Only allowed if base reg not in list, or first in list. */
5794 else if ((range & (1 << base_reg))
5795 && (range & ((1 << base_reg) - 1)))
5796 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
5800 inst.instruction |= range;
5809 skip_whitespace (str);
5811 /* Allow optional leading '#'. */
5812 if (is_immediate_prefix (*str))
5815 if (my_get_expression (& inst.reloc.exp, & str))
5818 inst.reloc.type = BFD_RELOC_ARM_SWI;
5819 inst.reloc.pc_rel = 0;
5831 skip_whitespace (str);
5833 if ((reg = reg_required_here (&str, 12)) == FAIL)
5838 inst.error = _("r15 not allowed in swap");
5842 if (skip_past_comma (&str) == FAIL
5843 || (reg = reg_required_here (&str, 0)) == FAIL)
5846 inst.error = BAD_ARGS;
5852 inst.error = _("r15 not allowed in swap");
5856 if (skip_past_comma (&str) == FAIL
5859 inst.error = BAD_ARGS;
5863 skip_whitespace (str);
5865 if ((reg = reg_required_here (&str, 16)) == FAIL)
5870 inst.error = BAD_PC;
5874 skip_whitespace (str);
5878 inst.error = _("missing ]");
5890 if (my_get_expression (&inst.reloc.exp, &str))
5897 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
5898 required for the instruction. */
5900 /* arm_parse_reloc () works on input_line_pointer.
5901 We actually want to parse the operands to the branch instruction
5902 passed in 'str'. Save the input pointer and restore it later. */
5903 save_in = input_line_pointer;
5904 input_line_pointer = str;
5905 if (inst.reloc.exp.X_op == O_symbol
5907 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
5909 inst.reloc.type = BFD_RELOC_ARM_PLT32;
5910 inst.reloc.pc_rel = 0;
5911 /* Modify str to point to after parsed operands, otherwise
5912 end_of_line() will complain about the (PLT) left in str. */
5913 str = input_line_pointer;
5917 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
5918 inst.reloc.pc_rel = 1;
5920 input_line_pointer = save_in;
5923 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
5924 inst.reloc.pc_rel = 1;
5925 #endif /* OBJ_ELF */
5937 skip_whitespace (str);
5939 if ((reg = reg_required_here (&str, 0)) == FAIL)
5941 inst.error = BAD_ARGS;
5945 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
5947 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
5956 /* Co-processor data operation.
5957 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
5958 skip_whitespace (str);
5960 if (co_proc_number (&str) == FAIL)
5963 inst.error = BAD_ARGS;
5967 if (skip_past_comma (&str) == FAIL
5968 || cp_opc_expr (&str, 20,4) == FAIL)
5971 inst.error = BAD_ARGS;
5975 if (skip_past_comma (&str) == FAIL
5976 || cp_reg_required_here (&str, 12) == FAIL)
5979 inst.error = BAD_ARGS;
5983 if (skip_past_comma (&str) == FAIL
5984 || cp_reg_required_here (&str, 16) == FAIL)
5987 inst.error = BAD_ARGS;
5991 if (skip_past_comma (&str) == FAIL
5992 || cp_reg_required_here (&str, 0) == FAIL)
5995 inst.error = BAD_ARGS;
5999 if (skip_past_comma (&str) == SUCCESS)
6001 if (cp_opc_expr (&str, 5, 3) == FAIL)
6004 inst.error = BAD_ARGS;
6017 /* Co-processor register load/store.
6018 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
6020 skip_whitespace (str);
6022 if (co_proc_number (&str) == FAIL)
6025 inst.error = BAD_ARGS;
6029 if (skip_past_comma (&str) == FAIL
6030 || cp_reg_required_here (&str, 12) == FAIL)
6033 inst.error = BAD_ARGS;
6037 if (skip_past_comma (&str) == FAIL
6038 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6041 inst.error = BAD_ARGS;
6053 /* Co-processor register transfer.
6054 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
6056 skip_whitespace (str);
6058 if (co_proc_number (&str) == FAIL)
6061 inst.error = BAD_ARGS;
6065 if (skip_past_comma (&str) == FAIL
6066 || cp_opc_expr (&str, 21, 3) == FAIL)
6069 inst.error = BAD_ARGS;
6073 if (skip_past_comma (&str) == FAIL
6074 || reg_required_here (&str, 12) == FAIL)
6077 inst.error = BAD_ARGS;
6081 if (skip_past_comma (&str) == FAIL
6082 || cp_reg_required_here (&str, 16) == FAIL)
6085 inst.error = BAD_ARGS;
6089 if (skip_past_comma (&str) == FAIL
6090 || cp_reg_required_here (&str, 0) == FAIL)
6093 inst.error = BAD_ARGS;
6097 if (skip_past_comma (&str) == SUCCESS)
6099 if (cp_opc_expr (&str, 5, 3) == FAIL)
6102 inst.error = BAD_ARGS;
6115 /* FP control registers.
6116 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
6118 skip_whitespace (str);
6120 if (reg_required_here (&str, 12) == FAIL)
6123 inst.error = BAD_ARGS;
6135 skip_whitespace (str);
6137 if (fp_reg_required_here (&str, 12) == FAIL)
6140 inst.error = BAD_ARGS;
6144 if (skip_past_comma (&str) == FAIL
6145 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6148 inst.error = BAD_ARGS;
6161 skip_whitespace (str);
6163 if (fp_reg_required_here (&str, 12) == FAIL)
6166 inst.error = BAD_ARGS;
6170 /* Get Number of registers to transfer. */
6171 if (skip_past_comma (&str) == FAIL
6172 || my_get_expression (&inst.reloc.exp, &str))
6175 inst.error = _("constant expression expected");
6179 if (inst.reloc.exp.X_op != O_constant)
6181 inst.error = _("constant value required for number of registers");
6185 num_regs = inst.reloc.exp.X_add_number;
6187 if (num_regs < 1 || num_regs > 4)
6189 inst.error = _("number of registers must be in the range [1:4]");
6196 inst.instruction |= CP_T_X;
6199 inst.instruction |= CP_T_Y;
6202 inst.instruction |= CP_T_Y | CP_T_X;
6210 if (inst.instruction & (CP_T_Pre | CP_T_UD)) /* ea/fd format. */
6216 /* The instruction specified "ea" or "fd", so we can only accept
6217 [Rn]{!}. The instruction does not really support stacking or
6218 unstacking, so we have to emulate these by setting appropriate
6219 bits and offsets. */
6220 if (skip_past_comma (&str) == FAIL
6224 inst.error = BAD_ARGS;
6229 skip_whitespace (str);
6231 if ((reg = reg_required_here (&str, 16)) == FAIL)
6234 skip_whitespace (str);
6238 inst.error = BAD_ARGS;
6250 _("r15 not allowed as base register with write-back");
6257 if (inst.instruction & CP_T_Pre)
6259 /* Pre-decrement. */
6260 offset = 3 * num_regs;
6262 inst.instruction |= CP_T_WB;
6266 /* Post-increment. */
6269 inst.instruction |= CP_T_WB;
6270 offset = 3 * num_regs;
6274 /* No write-back, so convert this into a standard pre-increment
6275 instruction -- aesthetically more pleasing. */
6276 inst.instruction |= CP_T_Pre | CP_T_UD;
6281 inst.instruction |= offset;
6283 else if (skip_past_comma (&str) == FAIL
6284 || cp_address_required_here (&str, CP_WB_OK) == FAIL)
6287 inst.error = BAD_ARGS;
6298 skip_whitespace (str);
6300 if (fp_reg_required_here (&str, 12) == FAIL)
6303 inst.error = BAD_ARGS;
6307 if (skip_past_comma (&str) == FAIL
6308 || fp_reg_required_here (&str, 16) == FAIL)
6311 inst.error = BAD_ARGS;
6315 if (skip_past_comma (&str) == FAIL
6316 || fp_op2 (&str) == FAIL)
6319 inst.error = BAD_ARGS;
6328 do_fpa_monadic (str)
6331 skip_whitespace (str);
6333 if (fp_reg_required_here (&str, 12) == FAIL)
6336 inst.error = BAD_ARGS;
6340 if (skip_past_comma (&str) == FAIL
6341 || fp_op2 (&str) == FAIL)
6344 inst.error = BAD_ARGS;
6356 skip_whitespace (str);
6358 if (fp_reg_required_here (&str, 16) == FAIL)
6361 inst.error = BAD_ARGS;
6365 if (skip_past_comma (&str) == FAIL
6366 || fp_op2 (&str) == FAIL)
6369 inst.error = BAD_ARGS;
6378 do_fpa_from_reg (str)
6381 skip_whitespace (str);
6383 if (fp_reg_required_here (&str, 16) == FAIL)
6386 inst.error = BAD_ARGS;
6390 if (skip_past_comma (&str) == FAIL
6391 || reg_required_here (&str, 12) == FAIL)
6394 inst.error = BAD_ARGS;
6406 skip_whitespace (str);
6408 if (reg_required_here (&str, 12) == FAIL)
6411 if (skip_past_comma (&str) == FAIL
6412 || fp_reg_required_here (&str, 0) == FAIL)
6415 inst.error = BAD_ARGS;
6424 vfp_sp_reg_required_here (str, pos)
6426 enum vfp_sp_reg_pos pos;
6431 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab)) != FAIL)
6436 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
6440 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
6444 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
6453 /* In the few cases where we might be able to accept something else
6454 this error can be overridden. */
6455 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
6457 /* Restore the start point. */
6463 vfp_dp_reg_required_here (str, pos)
6465 enum vfp_dp_reg_pos pos;
6470 if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab)) != FAIL)
6475 inst.instruction |= reg << 12;
6479 inst.instruction |= reg << 16;
6483 inst.instruction |= reg << 0;
6492 /* In the few cases where we might be able to accept something else
6493 this error can be overridden. */
6494 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
6496 /* Restore the start point. */
6502 do_vfp_sp_monadic (str)
6505 skip_whitespace (str);
6507 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
6510 if (skip_past_comma (&str) == FAIL
6511 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
6514 inst.error = BAD_ARGS;
6523 do_vfp_dp_monadic (str)
6526 skip_whitespace (str);
6528 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
6531 if (skip_past_comma (&str) == FAIL
6532 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6535 inst.error = BAD_ARGS;
6544 do_vfp_sp_dyadic (str)
6547 skip_whitespace (str);
6549 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
6552 if (skip_past_comma (&str) == FAIL
6553 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL
6554 || skip_past_comma (&str) == FAIL
6555 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
6558 inst.error = BAD_ARGS;
6567 do_vfp_dp_dyadic (str)
6570 skip_whitespace (str);
6572 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
6575 if (skip_past_comma (&str) == FAIL
6576 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL
6577 || skip_past_comma (&str) == FAIL
6578 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6581 inst.error = BAD_ARGS;
6590 do_vfp_reg_from_sp (str)
6593 skip_whitespace (str);
6595 if (reg_required_here (&str, 12) == FAIL)
6598 if (skip_past_comma (&str) == FAIL
6599 || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
6602 inst.error = BAD_ARGS;
6611 do_vfp_sp_reg2 (str)
6614 skip_whitespace (str);
6616 if (reg_required_here (&str, 12) == FAIL)
6619 if (skip_past_comma (&str) == FAIL
6620 || reg_required_here (&str, 16) == FAIL
6621 || skip_past_comma (&str) == FAIL)
6624 inst.error = BAD_ARGS;
6628 /* We require exactly two consecutive SP registers. */
6629 if (vfp_sp_reg_list (&str, VFP_REG_Sm) != 2)
6632 inst.error = _("only two consecutive VFP SP registers allowed here");
6640 do_vfp_sp_from_reg (str)
6643 skip_whitespace (str);
6645 if (vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
6648 if (skip_past_comma (&str) == FAIL
6649 || reg_required_here (&str, 12) == FAIL)
6652 inst.error = BAD_ARGS;
6661 do_vfp_reg_from_dp (str)
6664 skip_whitespace (str);
6666 if (reg_required_here (&str, 12) == FAIL)
6669 if (skip_past_comma (&str) == FAIL
6670 || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
6673 inst.error = BAD_ARGS;
6682 do_vfp_reg2_from_dp (str)
6685 skip_whitespace (str);
6687 if (reg_required_here (&str, 12) == FAIL)
6690 if (skip_past_comma (&str) == FAIL
6691 || reg_required_here (&str, 16) == FAIL
6692 || skip_past_comma (&str) == FAIL
6693 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6696 inst.error = BAD_ARGS;
6705 do_vfp_dp_from_reg (str)
6708 skip_whitespace (str);
6710 if (vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
6713 if (skip_past_comma (&str) == FAIL
6714 || reg_required_here (&str, 12) == FAIL)
6717 inst.error = BAD_ARGS;
6726 do_vfp_dp_from_reg2 (str)
6729 skip_whitespace (str);
6731 if (vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
6734 if (skip_past_comma (&str) == FAIL
6735 || reg_required_here (&str, 12) == FAIL
6736 || skip_past_comma (&str) == FAIL
6737 || reg_required_here (&str, 16))
6740 inst.error = BAD_ARGS;
6748 static const struct vfp_reg *
6755 const struct vfp_reg *vreg;
6759 /* Find the end of the current token. */
6764 while (ISALPHA (c));
6769 for (vreg = vfp_regs + 0;
6770 vreg < vfp_regs + sizeof (vfp_regs) / sizeof (struct vfp_reg);
6773 if (strcmp (start, vreg->name) == 0)
6786 vfp_psr_required_here (str)
6790 const struct vfp_reg *vreg;
6792 vreg = vfp_psr_parse (str);
6796 inst.instruction |= vreg->regno;
6800 inst.error = _("VFP system register expected");
6807 do_vfp_reg_from_ctrl (str)
6810 skip_whitespace (str);
6812 if (reg_required_here (&str, 12) == FAIL)
6815 if (skip_past_comma (&str) == FAIL
6816 || vfp_psr_required_here (&str) == FAIL)
6819 inst.error = BAD_ARGS;
6828 do_vfp_ctrl_from_reg (str)
6831 skip_whitespace (str);
6833 if (vfp_psr_required_here (&str) == FAIL)
6836 if (skip_past_comma (&str) == FAIL
6837 || reg_required_here (&str, 12) == FAIL)
6840 inst.error = BAD_ARGS;
6849 do_vfp_sp_ldst (str)
6852 skip_whitespace (str);
6854 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
6857 inst.error = BAD_ARGS;
6861 if (skip_past_comma (&str) == FAIL
6862 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
6865 inst.error = BAD_ARGS;
6874 do_vfp_dp_ldst (str)
6877 skip_whitespace (str);
6879 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
6882 inst.error = BAD_ARGS;
6886 if (skip_past_comma (&str) == FAIL
6887 || cp_address_required_here (&str, CP_NO_WB) == FAIL)
6890 inst.error = BAD_ARGS;
6898 /* Parse and encode a VFP SP register list, storing the initial
6899 register in position POS and returning the range as the result. If
6900 the string is invalid return FAIL (an invalid range). */
6902 vfp_sp_reg_list (str, pos)
6904 enum vfp_sp_reg_pos pos;
6912 unsigned long mask = 0;
6919 skip_whitespace (*str);
6921 tempinst = inst.instruction;
6925 inst.instruction = 0;
6927 if ((new_base = vfp_sp_reg_required_here (str, pos)) == FAIL)
6930 if (count == 0 || base_reg > new_base)
6932 base_reg = new_base;
6933 base_bits = inst.instruction;
6936 if (mask & (1 << new_base))
6938 inst.error = _("invalid register list");
6942 if ((mask >> new_base) != 0 && ! warned)
6944 as_tsktsk (_("register list not in ascending order"));
6948 mask |= 1 << new_base;
6951 skip_whitespace (*str);
6953 if (**str == '-') /* We have the start of a range expression */
6960 = arm_reg_parse (str, all_reg_maps[REG_TYPE_SN].htab))
6963 inst.error = _(all_reg_maps[REG_TYPE_SN].expected);
6967 if (high_range <= new_base)
6969 inst.error = _("register range not in ascending order");
6973 for (new_base++; new_base <= high_range; new_base++)
6975 if (mask & (1 << new_base))
6977 inst.error = _("invalid register list");
6981 mask |= 1 << new_base;
6986 while (skip_past_comma (str) != FAIL);
6990 inst.error = _("invalid register list");
6998 /* Sanity check -- should have raised a parse error above. */
6999 if (count == 0 || count > 32)
7002 /* Final test -- the registers must be consecutive. */
7005 if ((mask & (1 << base_reg++)) == 0)
7007 inst.error = _("non-contiguous register range");
7012 inst.instruction = tempinst | base_bits;
7017 vfp_dp_reg_list (str)
7025 unsigned long mask = 0;
7032 skip_whitespace (*str);
7034 tempinst = inst.instruction;
7038 inst.instruction = 0;
7040 if ((new_base = vfp_dp_reg_required_here (str, VFP_REG_Dd)) == FAIL)
7043 if (count == 0 || base_reg > new_base)
7045 base_reg = new_base;
7046 range = inst.instruction;
7049 if (mask & (1 << new_base))
7051 inst.error = _("invalid register list");
7055 if ((mask >> new_base) != 0 && ! warned)
7057 as_tsktsk (_("register list not in ascending order"));
7061 mask |= 1 << new_base;
7064 skip_whitespace (*str);
7066 if (**str == '-') /* We have the start of a range expression */
7073 = arm_reg_parse (str, all_reg_maps[REG_TYPE_DN].htab))
7076 inst.error = _(all_reg_maps[REG_TYPE_DN].expected);
7080 if (high_range <= new_base)
7082 inst.error = _("register range not in ascending order");
7086 for (new_base++; new_base <= high_range; new_base++)
7088 if (mask & (1 << new_base))
7090 inst.error = _("invalid register list");
7094 mask |= 1 << new_base;
7099 while (skip_past_comma (str) != FAIL);
7103 inst.error = _("invalid register list");
7111 /* Sanity check -- should have raised a parse error above. */
7112 if (count == 0 || count > 16)
7115 /* Final test -- the registers must be consecutive. */
7118 if ((mask & (1 << base_reg++)) == 0)
7120 inst.error = _("non-contiguous register range");
7125 inst.instruction = tempinst;
7130 vfp_sp_ldstm (str, ldstm_type)
7132 enum vfp_ldstm_type ldstm_type;
7136 skip_whitespace (str);
7138 if (reg_required_here (&str, 16) == FAIL)
7141 skip_whitespace (str);
7145 inst.instruction |= WRITE_BACK;
7148 else if (ldstm_type != VFP_LDSTMIA)
7150 inst.error = _("this addressing mode requires base-register writeback");
7154 if (skip_past_comma (&str) == FAIL
7155 || (range = vfp_sp_reg_list (&str, VFP_REG_Sd)) == FAIL)
7158 inst.error = BAD_ARGS;
7162 inst.instruction |= range;
7167 vfp_dp_ldstm (str, ldstm_type)
7169 enum vfp_ldstm_type ldstm_type;
7173 skip_whitespace (str);
7175 if (reg_required_here (&str, 16) == FAIL)
7178 skip_whitespace (str);
7182 inst.instruction |= WRITE_BACK;
7185 else if (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX)
7187 inst.error = _("this addressing mode requires base-register writeback");
7191 if (skip_past_comma (&str) == FAIL
7192 || (range = vfp_dp_reg_list (&str)) == FAIL)
7195 inst.error = BAD_ARGS;
7199 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
7202 inst.instruction |= range;
7207 do_vfp_sp_ldstmia (str)
7210 vfp_sp_ldstm (str, VFP_LDSTMIA);
7214 do_vfp_sp_ldstmdb (str)
7217 vfp_sp_ldstm (str, VFP_LDSTMDB);
7221 do_vfp_dp_ldstmia (str)
7224 vfp_dp_ldstm (str, VFP_LDSTMIA);
7228 do_vfp_dp_ldstmdb (str)
7231 vfp_dp_ldstm (str, VFP_LDSTMDB);
7235 do_vfp_xp_ldstmia (str)
7238 vfp_dp_ldstm (str, VFP_LDSTMIAX);
7242 do_vfp_xp_ldstmdb (str)
7245 vfp_dp_ldstm (str, VFP_LDSTMDBX);
7249 do_vfp_sp_compare_z (str)
7252 skip_whitespace (str);
7254 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7257 inst.error = BAD_ARGS;
7266 do_vfp_dp_compare_z (str)
7269 skip_whitespace (str);
7271 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7274 inst.error = BAD_ARGS;
7283 do_vfp_dp_sp_cvt (str)
7286 skip_whitespace (str);
7288 if (vfp_dp_reg_required_here (&str, VFP_REG_Dd) == FAIL)
7291 if (skip_past_comma (&str) == FAIL
7292 || vfp_sp_reg_required_here (&str, VFP_REG_Sm) == FAIL)
7295 inst.error = BAD_ARGS;
7304 do_vfp_sp_dp_cvt (str)
7307 skip_whitespace (str);
7309 if (vfp_sp_reg_required_here (&str, VFP_REG_Sd) == FAIL)
7312 if (skip_past_comma (&str) == FAIL
7313 || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
7316 inst.error = BAD_ARGS;
7324 /* Thumb specific routines. */
7326 /* Parse and validate that a register is of the right form, this saves
7327 repeated checking of this information in many similar cases.
7328 Unlike the 32-bit case we do not insert the register into the opcode
7329 here, since the position is often unknown until the full instruction
7333 thumb_reg (strp, hi_lo)
7339 if ((reg = reg_required_here (strp, -1)) == FAIL)
7347 inst.error = _("lo register required");
7355 inst.error = _("hi register required");
7367 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
7371 thumb_add_sub (str, subtract)
7375 int Rd, Rs, Rn = FAIL;
7377 skip_whitespace (str);
7379 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
7380 || skip_past_comma (&str) == FAIL)
7383 inst.error = BAD_ARGS;
7387 if (is_immediate_prefix (*str))
7391 if (my_get_expression (&inst.reloc.exp, &str))
7396 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7399 if (skip_past_comma (&str) == FAIL)
7401 /* Two operand format, shuffle the registers
7402 and pretend there are 3. */
7406 else if (is_immediate_prefix (*str))
7409 if (my_get_expression (&inst.reloc.exp, &str))
7412 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7416 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
7417 for the latter case, EXPR contains the immediate that was found. */
7420 /* All register format. */
7421 if (Rd > 7 || Rs > 7 || Rn > 7)
7425 inst.error = _("dest and source1 must be the same register");
7429 /* Can't do this for SUB. */
7432 inst.error = _("subtract valid only on lo regs");
7436 inst.instruction = (T_OPCODE_ADD_HI
7437 | (Rd > 7 ? THUMB_H1 : 0)
7438 | (Rn > 7 ? THUMB_H2 : 0));
7439 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
7443 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
7444 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
7449 /* Immediate expression, now things start to get nasty. */
7451 /* First deal with HI regs, only very restricted cases allowed:
7452 Adjusting SP, and using PC or SP to get an address. */
7453 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
7454 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
7456 inst.error = _("invalid Hi register with immediate");
7460 if (inst.reloc.exp.X_op != O_constant)
7462 /* Value isn't known yet, all we can do is store all the fragments
7463 we know about in the instruction and let the reloc hacking
7465 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
7466 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
7470 int offset = inst.reloc.exp.X_add_number;
7480 /* Quick check, in case offset is MIN_INT. */
7483 inst.error = _("immediate value out of range");
7487 /* Note - you cannot convert a subtract of 0 into an
7488 add of 0 because the carry flag is set differently. */
7489 else if (offset > 0)
7494 if (offset & ~0x1fc)
7496 inst.error = _("invalid immediate value for stack adjust");
7499 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
7500 inst.instruction |= offset >> 2;
7502 else if (Rs == REG_PC || Rs == REG_SP)
7505 || (offset & ~0x3fc))
7507 inst.error = _("invalid immediate for address calculation");
7510 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
7512 inst.instruction |= (Rd << 8) | (offset >> 2);
7518 inst.error = _("immediate value out of range");
7521 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
7522 inst.instruction |= (Rd << 8) | offset;
7528 inst.error = _("immediate value out of range");
7531 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
7532 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
7541 thumb_shift (str, shift)
7545 int Rd, Rs, Rn = FAIL;
7547 skip_whitespace (str);
7549 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
7550 || skip_past_comma (&str) == FAIL)
7553 inst.error = BAD_ARGS;
7557 if (is_immediate_prefix (*str))
7559 /* Two operand immediate format, set Rs to Rd. */
7562 if (my_get_expression (&inst.reloc.exp, &str))
7567 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
7570 if (skip_past_comma (&str) == FAIL)
7572 /* Two operand format, shuffle the registers
7573 and pretend there are 3. */
7577 else if (is_immediate_prefix (*str))
7580 if (my_get_expression (&inst.reloc.exp, &str))
7583 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
7587 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
7588 for the latter case, EXPR contains the immediate that was found. */
7594 inst.error = _("source1 and dest must be same register");
7600 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
7601 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
7602 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
7605 inst.instruction |= Rd | (Rn << 3);
7611 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
7612 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
7613 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
7616 if (inst.reloc.exp.X_op != O_constant)
7618 /* Value isn't known yet, create a dummy reloc and let reloc
7619 hacking fix it up. */
7620 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
7624 unsigned shift_value = inst.reloc.exp.X_add_number;
7626 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
7628 inst.error = _("invalid immediate for shift");
7632 /* Shifts of zero are handled by converting to LSL. */
7633 if (shift_value == 0)
7634 inst.instruction = T_OPCODE_LSL_I;
7636 /* Shifts of 32 are encoded as a shift of zero. */
7637 if (shift_value == 32)
7640 inst.instruction |= shift_value << 6;
7643 inst.instruction |= Rd | (Rs << 3);
7650 thumb_mov_compare (str, move)
7656 skip_whitespace (str);
7658 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
7659 || skip_past_comma (&str) == FAIL)
7662 inst.error = BAD_ARGS;
7666 if (is_immediate_prefix (*str))
7669 if (my_get_expression (&inst.reloc.exp, &str))
7672 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7677 if (Rs < 8 && Rd < 8)
7679 if (move == THUMB_MOVE)
7680 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
7681 since a MOV instruction produces unpredictable results. */
7682 inst.instruction = T_OPCODE_ADD_I3;
7684 inst.instruction = T_OPCODE_CMP_LR;
7685 inst.instruction |= Rd | (Rs << 3);
7689 if (move == THUMB_MOVE)
7690 inst.instruction = T_OPCODE_MOV_HR;
7692 inst.instruction = T_OPCODE_CMP_HR;
7695 inst.instruction |= THUMB_H1;
7698 inst.instruction |= THUMB_H2;
7700 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
7707 inst.error = _("only lo regs allowed with immediate");
7711 if (move == THUMB_MOVE)
7712 inst.instruction = T_OPCODE_MOV_I8;
7714 inst.instruction = T_OPCODE_CMP_I8;
7716 inst.instruction |= Rd << 8;
7718 if (inst.reloc.exp.X_op != O_constant)
7719 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
7722 unsigned value = inst.reloc.exp.X_add_number;
7726 inst.error = _("invalid immediate");
7730 inst.instruction |= value;
7738 thumb_load_store (str, load_store, size)
7743 int Rd, Rb, Ro = FAIL;
7745 skip_whitespace (str);
7747 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
7748 || skip_past_comma (&str) == FAIL)
7751 inst.error = BAD_ARGS;
7758 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
7761 if (skip_past_comma (&str) != FAIL)
7763 if (is_immediate_prefix (*str))
7766 if (my_get_expression (&inst.reloc.exp, &str))
7769 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
7774 inst.reloc.exp.X_op = O_constant;
7775 inst.reloc.exp.X_add_number = 0;
7780 inst.error = _("expected ']'");
7785 else if (*str == '=')
7787 if (load_store != THUMB_LOAD)
7789 inst.error = _("invalid pseudo operation");
7793 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
7796 skip_whitespace (str);
7798 if (my_get_expression (& inst.reloc.exp, & str))
7803 if ( inst.reloc.exp.X_op != O_constant
7804 && inst.reloc.exp.X_op != O_symbol)
7806 inst.error = "Constant expression expected";
7810 if (inst.reloc.exp.X_op == O_constant
7811 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
7813 /* This can be done with a mov instruction. */
7815 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
7816 inst.instruction |= inst.reloc.exp.X_add_number;
7820 /* Insert into literal pool. */
7821 if (add_to_lit_pool () == FAIL)
7824 inst.error = "literal pool insertion failed";
7828 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7829 inst.reloc.pc_rel = 1;
7830 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
7831 /* Adjust ARM pipeline offset to Thumb. */
7832 inst.reloc.exp.X_add_number += 4;
7838 if (my_get_expression (&inst.reloc.exp, &str))
7841 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
7842 inst.reloc.pc_rel = 1;
7843 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
7844 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7849 if (Rb == REG_PC || Rb == REG_SP)
7851 if (size != THUMB_WORD)
7853 inst.error = _("byte or halfword not valid for base register");
7856 else if (Rb == REG_PC && load_store != THUMB_LOAD)
7858 inst.error = _("r15 based store not allowed");
7861 else if (Ro != FAIL)
7863 inst.error = _("invalid base register for register offset");
7868 inst.instruction = T_OPCODE_LDR_PC;
7869 else if (load_store == THUMB_LOAD)
7870 inst.instruction = T_OPCODE_LDR_SP;
7872 inst.instruction = T_OPCODE_STR_SP;
7874 inst.instruction |= Rd << 8;
7875 if (inst.reloc.exp.X_op == O_constant)
7877 unsigned offset = inst.reloc.exp.X_add_number;
7879 if (offset & ~0x3fc)
7881 inst.error = _("invalid offset");
7885 inst.instruction |= offset >> 2;
7888 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7892 inst.error = _("invalid base register in load/store");
7895 else if (Ro == FAIL)
7897 /* Immediate offset. */
7898 if (size == THUMB_WORD)
7899 inst.instruction = (load_store == THUMB_LOAD
7900 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
7901 else if (size == THUMB_HALFWORD)
7902 inst.instruction = (load_store == THUMB_LOAD
7903 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
7905 inst.instruction = (load_store == THUMB_LOAD
7906 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
7908 inst.instruction |= Rd | (Rb << 3);
7910 if (inst.reloc.exp.X_op == O_constant)
7912 unsigned offset = inst.reloc.exp.X_add_number;
7914 if (offset & ~(0x1f << size))
7916 inst.error = _("invalid offset");
7919 inst.instruction |= (offset >> size) << 6;
7922 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
7926 /* Register offset. */
7927 if (size == THUMB_WORD)
7928 inst.instruction = (load_store == THUMB_LOAD
7929 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
7930 else if (size == THUMB_HALFWORD)
7931 inst.instruction = (load_store == THUMB_LOAD
7932 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
7934 inst.instruction = (load_store == THUMB_LOAD
7935 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
7937 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
7943 /* A register must be given at this point.
7945 Shift is the place to put it in inst.instruction.
7947 Restores input start point on err.
7948 Returns the reg#, or FAIL. */
7951 mav_reg_required_here (str, shift, regtype)
7954 enum arm_reg_type regtype;
7959 if ((reg = arm_reg_parse (str, all_reg_maps[regtype].htab)) != FAIL)
7962 inst.instruction |= reg << shift;
7967 /* Restore the start point. */
7970 /* In the few cases where we might be able to accept something else
7971 this error can be overridden. */
7972 inst.error = _(all_reg_maps[regtype].expected);
7977 /* Cirrus Maverick Instructions. */
7979 /* Wrapper functions. */
7982 do_mav_binops_1a (str)
7985 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVF);
7989 do_mav_binops_1b (str)
7992 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVD);
7996 do_mav_binops_1c (str)
7999 do_mav_binops (str, MAV_MODE1, REG_TYPE_RN, REG_TYPE_MVDX);
8003 do_mav_binops_1d (str)
8006 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVF);
8010 do_mav_binops_1e (str)
8013 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVD);
8017 do_mav_binops_1f (str)
8020 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVF);
8024 do_mav_binops_1g (str)
8027 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVD);
8031 do_mav_binops_1h (str)
8034 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVFX);
8038 do_mav_binops_1i (str)
8041 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVFX);
8045 do_mav_binops_1j (str)
8048 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVF, REG_TYPE_MVDX);
8052 do_mav_binops_1k (str)
8055 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVD, REG_TYPE_MVDX);
8059 do_mav_binops_1l (str)
8062 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVF);
8066 do_mav_binops_1m (str)
8069 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVD);
8073 do_mav_binops_1n (str)
8076 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVFX, REG_TYPE_MVFX);
8080 do_mav_binops_1o (str)
8083 do_mav_binops (str, MAV_MODE1, REG_TYPE_MVDX, REG_TYPE_MVDX);
8087 do_mav_binops_2a (str)
8090 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVF, REG_TYPE_RN);
8094 do_mav_binops_2b (str)
8097 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVD, REG_TYPE_RN);
8101 do_mav_binops_2c (str)
8104 do_mav_binops (str, MAV_MODE2, REG_TYPE_MVDX, REG_TYPE_RN);
8108 do_mav_binops_3a (str)
8111 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVFX);
8115 do_mav_binops_3b (str)
8118 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVFX, REG_TYPE_MVAX);
8122 do_mav_binops_3c (str)
8125 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVAX, REG_TYPE_MVDX);
8129 do_mav_binops_3d (str)
8132 do_mav_binops (str, MAV_MODE3, REG_TYPE_MVDX, REG_TYPE_MVAX);
8136 do_mav_triple_4a (str)
8139 do_mav_triple (str, MAV_MODE4, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_RN);
8143 do_mav_triple_4b (str)
8146 do_mav_triple (str, MAV_MODE4, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_RN);
8150 do_mav_triple_5a (str)
8153 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVF, REG_TYPE_MVF);
8157 do_mav_triple_5b (str)
8160 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVD, REG_TYPE_MVD);
8164 do_mav_triple_5c (str)
8167 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVFX, REG_TYPE_MVFX);
8171 do_mav_triple_5d (str)
8174 do_mav_triple (str, MAV_MODE5, REG_TYPE_RN, REG_TYPE_MVDX, REG_TYPE_MVDX);
8178 do_mav_triple_5e (str)
8181 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVF, REG_TYPE_MVF, REG_TYPE_MVF);
8185 do_mav_triple_5f (str)
8188 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVD, REG_TYPE_MVD, REG_TYPE_MVD);
8192 do_mav_triple_5g (str)
8195 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVFX, REG_TYPE_MVFX, REG_TYPE_MVFX);
8199 do_mav_triple_5h (str)
8202 do_mav_triple (str, MAV_MODE5, REG_TYPE_MVDX, REG_TYPE_MVDX, REG_TYPE_MVDX);
8206 do_mav_quad_6a (str)
8209 do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVFX, REG_TYPE_MVFX,
8214 do_mav_quad_6b (str)
8217 do_mav_quad (str, MAV_MODE6, REG_TYPE_MVAX, REG_TYPE_MVAX, REG_TYPE_MVFX,
8221 /* cfmvsc32<cond> DSPSC,MVFX[15:0]. */
8223 do_mav_dspsc_1 (str)
8226 skip_whitespace (str);
8229 if (mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL
8230 || skip_past_comma (&str) == FAIL
8231 || mav_reg_required_here (&str, 16, REG_TYPE_MVFX) == FAIL)
8234 inst.error = BAD_ARGS;
8242 /* cfmv32sc<cond> MVFX[15:0],DSPSC. */
8244 do_mav_dspsc_2 (str)
8247 skip_whitespace (str);
8250 if (mav_reg_required_here (&str, 0, REG_TYPE_MVFX) == FAIL
8251 || skip_past_comma (&str) == FAIL
8252 || mav_reg_required_here (&str, -1, REG_TYPE_DSPSC) == FAIL)
8255 inst.error = BAD_ARGS;
8264 do_mav_shift_1 (str)
8267 do_mav_shift (str, REG_TYPE_MVFX, REG_TYPE_MVFX);
8271 do_mav_shift_2 (str)
8274 do_mav_shift (str, REG_TYPE_MVDX, REG_TYPE_MVDX);
8281 do_mav_ldst (str, REG_TYPE_MVF);
8288 do_mav_ldst (str, REG_TYPE_MVD);
8295 do_mav_ldst (str, REG_TYPE_MVFX);
8302 do_mav_ldst (str, REG_TYPE_MVDX);
8305 /* Isnsn like "foo X,Y". */
8308 do_mav_binops (str, mode, reg0, reg1)
8311 enum arm_reg_type reg0;
8312 enum arm_reg_type reg1;
8316 shift0 = mode & 0xff;
8317 shift1 = (mode >> 8) & 0xff;
8319 skip_whitespace (str);
8321 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8322 || skip_past_comma (&str) == FAIL
8323 || mav_reg_required_here (&str, shift1, reg1) == FAIL)
8326 inst.error = BAD_ARGS;
8332 /* Isnsn like "foo X,Y,Z". */
8335 do_mav_triple (str, mode, reg0, reg1, reg2)
8338 enum arm_reg_type reg0;
8339 enum arm_reg_type reg1;
8340 enum arm_reg_type reg2;
8342 int shift0, shift1, shift2;
8344 shift0 = mode & 0xff;
8345 shift1 = (mode >> 8) & 0xff;
8346 shift2 = (mode >> 16) & 0xff;
8348 skip_whitespace (str);
8350 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8351 || skip_past_comma (&str) == FAIL
8352 || mav_reg_required_here (&str, shift1, reg1) == FAIL
8353 || skip_past_comma (&str) == FAIL
8354 || mav_reg_required_here (&str, shift2, reg2) == FAIL)
8357 inst.error = BAD_ARGS;
8363 /* Isnsn like "foo W,X,Y,Z".
8364 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
8367 do_mav_quad (str, mode, reg0, reg1, reg2, reg3)
8370 enum arm_reg_type reg0;
8371 enum arm_reg_type reg1;
8372 enum arm_reg_type reg2;
8373 enum arm_reg_type reg3;
8375 int shift0, shift1, shift2, shift3;
8377 shift0= mode & 0xff;
8378 shift1 = (mode >> 8) & 0xff;
8379 shift2 = (mode >> 16) & 0xff;
8380 shift3 = (mode >> 24) & 0xff;
8382 skip_whitespace (str);
8384 if (mav_reg_required_here (&str, shift0, reg0) == FAIL
8385 || skip_past_comma (&str) == FAIL
8386 || mav_reg_required_here (&str, shift1, reg1) == FAIL
8387 || skip_past_comma (&str) == FAIL
8388 || mav_reg_required_here (&str, shift2, reg2) == FAIL
8389 || skip_past_comma (&str) == FAIL
8390 || mav_reg_required_here (&str, shift3, reg3) == FAIL)
8393 inst.error = BAD_ARGS;
8399 /* Maverick shift immediate instructions.
8400 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
8401 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
8404 do_mav_shift (str, reg0, reg1)
8406 enum arm_reg_type reg0;
8407 enum arm_reg_type reg1;
8412 skip_whitespace (str);
8416 if (mav_reg_required_here (&str, 12, reg0) == FAIL
8417 || skip_past_comma (&str) == FAIL
8418 || mav_reg_required_here (&str, 16, reg1) == FAIL
8419 || skip_past_comma (&str) == FAIL)
8422 inst.error = BAD_ARGS;
8426 /* Calculate the immediate operand.
8427 The operand is a 7bit signed number. */
8428 skip_whitespace (str);
8433 if (!ISDIGIT (*str) && *str != '-')
8435 inst.error = _("expecting immediate, 7bit operand");
8445 for (imm = 0; *str && ISDIGIT (*str); ++str)
8446 imm = imm * 10 + *str - '0';
8450 inst.error = _("immediate out of range");
8454 /* Make negative imm's into 7bit signed numbers. */
8461 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
8462 Bits 5-7 of the insn should have bits 4-6 of the immediate.
8463 Bit 4 should be 0. */
8464 imm = (imm & 0xf) | ((imm & 0x70) << 1);
8466 inst.instruction |= imm;
8471 mav_parse_offset (str, negative)
8480 skip_whitespace (p);
8493 inst.error = _("offset expected");
8497 for (offset = 0; *p && ISDIGIT (*p); ++p)
8498 offset = offset * 10 + *p - '0';
8502 inst.error = _("offset out of range");
8508 return *negative ? -offset : offset;
8511 /* Maverick load/store instructions.
8512 <insn><cond> CRd,[Rn,<offset>]{!}.
8513 <insn><cond> CRd,[Rn],<offset>. */
8516 do_mav_ldst (str, reg0)
8518 enum arm_reg_type reg0;
8520 int offset, negative;
8522 skip_whitespace (str);
8524 if (mav_reg_required_here (&str, 12, reg0) == FAIL
8525 || skip_past_comma (&str) == FAIL
8527 || reg_required_here (&str, 16) == FAIL)
8530 if (skip_past_comma (&str) == SUCCESS)
8532 /* You are here: "<offset>]{!}". */
8533 inst.instruction |= PRE_INDEX;
8535 offset = mav_parse_offset (&str, &negative);
8542 inst.error = _("missing ]");
8548 inst.instruction |= WRITE_BACK;
8554 /* You are here: "], <offset>". */
8557 inst.error = _("missing ]");
8561 if (skip_past_comma (&str) == FAIL
8562 || (offset = mav_parse_offset (&str, &negative), inst.error))
8565 inst.instruction |= CP_T_WB; /* Post indexed, set bit W. */
8571 inst.instruction |= CP_T_UD; /* Postive, so set bit U. */
8573 inst.instruction |= offset >> 2;
8579 inst.error = BAD_ARGS;
8592 /* Handle the Format 4 instructions that do not have equivalents in other
8593 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
8602 skip_whitespace (str);
8604 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8605 || skip_past_comma (&str) == FAIL
8606 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8608 inst.error = BAD_ARGS;
8612 if (skip_past_comma (&str) != FAIL)
8614 /* Three operand format not allowed for TST, CMN, NEG and MVN.
8615 (It isn't allowed for CMP either, but that isn't handled by this
8617 if (inst.instruction == T_OPCODE_TST
8618 || inst.instruction == T_OPCODE_CMN
8619 || inst.instruction == T_OPCODE_NEG
8620 || inst.instruction == T_OPCODE_MVN)
8622 inst.error = BAD_ARGS;
8626 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8631 inst.error = _("dest and source1 must be the same register");
8637 if (inst.instruction == T_OPCODE_MUL
8639 as_tsktsk (_("Rs and Rd must be different in MUL"));
8641 inst.instruction |= Rd | (Rs << 3);
8649 thumb_add_sub (str, 0);
8656 thumb_shift (str, THUMB_ASR);
8663 if (my_get_expression (&inst.reloc.exp, &str))
8665 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
8666 inst.reloc.pc_rel = 1;
8674 if (my_get_expression (&inst.reloc.exp, &str))
8676 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
8677 inst.reloc.pc_rel = 1;
8681 /* Find the real, Thumb encoded start of a Thumb function. */
8684 find_real_start (symbolP)
8688 const char * name = S_GET_NAME (symbolP);
8689 symbolS * new_target;
8691 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
8692 #define STUB_NAME ".real_start_of"
8697 /* Names that start with '.' are local labels, not function entry points.
8698 The compiler may generate BL instructions to these labels because it
8699 needs to perform a branch to a far away location. */
8703 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
8704 sprintf (real_start, "%s%s", STUB_NAME, name);
8706 new_target = symbol_find (real_start);
8708 if (new_target == NULL)
8710 as_warn ("Failed to find real start of function: %s\n", name);
8711 new_target = symbolP;
8723 if (my_get_expression (& inst.reloc.exp, & str))
8726 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
8727 inst.reloc.pc_rel = 1;
8730 /* If the destination of the branch is a defined symbol which does not have
8731 the THUMB_FUNC attribute, then we must be calling a function which has
8732 the (interfacearm) attribute. We look for the Thumb entry point to that
8733 function and change the branch to refer to that function instead. */
8734 if ( inst.reloc.exp.X_op == O_symbol
8735 && inst.reloc.exp.X_add_symbol != NULL
8736 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
8737 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
8738 inst.reloc.exp.X_add_symbol =
8739 find_real_start (inst.reloc.exp.X_add_symbol);
8748 skip_whitespace (str);
8750 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
8753 /* This sets THUMB_H2 from the top bit of reg. */
8754 inst.instruction |= reg << 3;
8756 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
8757 should cause the alignment to be checked once it is known. This is
8758 because BX PC only works if the instruction is word aligned. */
8767 thumb_mov_compare (str, THUMB_COMPARE);
8777 skip_whitespace (str);
8779 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
8783 as_warn (_("inserted missing '!': load/store multiple always writes back base register"));
8787 if (skip_past_comma (&str) == FAIL
8788 || (range = reg_list (&str)) == FAIL)
8791 inst.error = BAD_ARGS;
8795 if (inst.reloc.type != BFD_RELOC_NONE)
8797 /* This really doesn't seem worth it. */
8798 inst.reloc.type = BFD_RELOC_NONE;
8799 inst.error = _("expression too complex");
8805 inst.error = _("only lo-regs valid in load/store multiple");
8809 inst.instruction |= (Rb << 8) | range;
8817 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
8824 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
8831 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
8840 skip_whitespace (str);
8842 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8843 || skip_past_comma (&str) == FAIL
8845 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8846 || skip_past_comma (&str) == FAIL
8847 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
8851 inst.error = _("syntax: ldrs[b] Rd, [Rb, Ro]");
8855 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
8863 thumb_shift (str, THUMB_LSL);
8870 thumb_shift (str, THUMB_LSR);
8877 thumb_mov_compare (str, THUMB_MOVE);
8886 skip_whitespace (str);
8888 if ((range = reg_list (&str)) == FAIL)
8891 inst.error = BAD_ARGS;
8895 if (inst.reloc.type != BFD_RELOC_NONE)
8897 /* This really doesn't seem worth it. */
8898 inst.reloc.type = BFD_RELOC_NONE;
8899 inst.error = _("expression too complex");
8905 if ((inst.instruction == T_OPCODE_PUSH
8906 && (range & ~0xff) == 1 << REG_LR)
8907 || (inst.instruction == T_OPCODE_POP
8908 && (range & ~0xff) == 1 << REG_PC))
8910 inst.instruction |= THUMB_PP_PC_LR;
8915 inst.error = _("invalid register list to push/pop instruction");
8920 inst.instruction |= range;
8928 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
8935 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
8942 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
8949 thumb_add_sub (str, 1);
8956 skip_whitespace (str);
8958 if (my_get_expression (&inst.reloc.exp, &str))
8961 inst.reloc.type = BFD_RELOC_ARM_SWI;
8972 /* This is a pseudo-op of the form "adr rd, label" to be converted
8973 into a relative address of the form "add rd, pc, #label-.-4". */
8974 skip_whitespace (str);
8976 /* Store Rd in temporary location inside instruction. */
8977 if ((reg = reg_required_here (&str, 4)) == FAIL
8978 || (reg > 7) /* For Thumb reg must be r0..r7. */
8979 || skip_past_comma (&str) == FAIL
8980 || my_get_expression (&inst.reloc.exp, &str))
8983 inst.error = BAD_ARGS;
8987 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
8988 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
8989 inst.reloc.pc_rel = 1;
8990 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
8996 insert_reg (r, htab)
8997 const struct reg_entry *r;
8998 struct hash_control *htab;
9000 int len = strlen (r->name) + 2;
9001 char * buf = (char *) xmalloc (len);
9002 char * buf2 = (char *) xmalloc (len);
9005 #ifdef REGISTER_PREFIX
9006 buf[i++] = REGISTER_PREFIX;
9009 strcpy (buf + i, r->name);
9011 for (i = 0; buf[i]; i++)
9012 buf2[i] = TOUPPER (buf[i]);
9016 hash_insert (htab, buf, (PTR) r);
9017 hash_insert (htab, buf2, (PTR) r);
9022 struct reg_map *map;
9024 const struct reg_entry *r;
9026 if ((map->htab = hash_new ()) == NULL)
9027 as_fatal (_("virtual memory exhausted"));
9029 for (r = map->names; r->name != NULL; r++)
9030 insert_reg (r, map->htab);
9034 insert_reg_alias (str, regnum, htab)
9037 struct hash_control *htab;
9039 struct reg_entry *new =
9040 (struct reg_entry *) xmalloc (sizeof (struct reg_entry));
9041 char *name = xmalloc (strlen (str) + 1);
9045 new->number = regnum;
9047 hash_insert (htab, name, (PTR) new);
9050 /* Look for the .req directive. This is of the form:
9052 newname .req existing_name
9054 If we find one, or if it looks sufficiently like one that we want to
9055 handle any error here, return non-zero. Otherwise return zero. */
9057 create_register_alias (newname, p)
9065 skip_whitespace (q);
9070 if (*q && !strncmp (q, ".req ", 5))
9075 #ifdef IGNORE_OPCODE_CASE
9076 newname = original_case_string;
9078 copy_of_str = newname;
9081 skip_whitespace (q);
9083 for (r = q; *r != '\0'; r++)
9089 enum arm_reg_type new_type, old_type;
9094 old_type = arm_reg_parse_any (q);
9097 new_type = arm_reg_parse_any (newname);
9099 if (new_type == REG_TYPE_MAX)
9101 if (old_type != REG_TYPE_MAX)
9103 old_regno = arm_reg_parse (&q, all_reg_maps[old_type].htab);
9104 insert_reg_alias (newname, old_regno,
9105 all_reg_maps[old_type].htab);
9108 as_warn (_("register '%s' does not exist\n"), q);
9110 else if (old_type == REG_TYPE_MAX)
9112 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
9117 /* Do not warn about redefinitions to the same alias. */
9118 if (new_type != old_type
9119 || (arm_reg_parse (&q, all_reg_maps[old_type].htab)
9120 != arm_reg_parse (&q, all_reg_maps[new_type].htab)))
9121 as_warn (_("ignoring redefinition of register alias '%s'"),
9127 as_warn (_("ignoring incomplete .req pseuso op"));
9137 set_constant_flonums ()
9141 for (i = 0; i < NUM_FLOAT_VALS; i++)
9142 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
9146 /* Iterate over the base tables to create the instruction patterns. */
9148 build_arm_ops_hsh ()
9152 static struct obstack insn_obstack;
9154 obstack_begin (&insn_obstack, 4000);
9156 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
9158 const struct asm_opcode *insn = insns + i;
9160 if (insn->cond_offset != 0)
9162 /* Insn supports conditional execution. Build the varaints
9163 and insert them in the hash table. */
9164 for (j = 0; j < sizeof (conds) / sizeof (struct asm_cond); j++)
9166 unsigned len = strlen (insn->template);
9167 struct asm_opcode *new;
9170 new = obstack_alloc (&insn_obstack, sizeof (struct asm_opcode));
9171 /* All condition codes are two characters. */
9172 template = obstack_alloc (&insn_obstack, len + 3);
9174 strncpy (template, insn->template, insn->cond_offset);
9175 strcpy (template + insn->cond_offset, conds[j].template);
9176 if (len > insn->cond_offset)
9177 strcpy (template + insn->cond_offset + 2,
9178 insn->template + insn->cond_offset);
9179 new->template = template;
9180 new->cond_offset = 0;
9181 new->variant = insn->variant;
9182 new->parms = insn->parms;
9183 new->value = (insn->value & ~COND_MASK) | conds[j].value;
9185 hash_insert (arm_ops_hsh, new->template, (PTR) new);
9188 /* Finally, insert the unconditional insn in the table directly;
9189 no need to build a copy. */
9190 hash_insert (arm_ops_hsh, insn->template, (PTR) insn);
9200 if ( (arm_ops_hsh = hash_new ()) == NULL
9201 || (arm_tops_hsh = hash_new ()) == NULL
9202 || (arm_cond_hsh = hash_new ()) == NULL
9203 || (arm_shift_hsh = hash_new ()) == NULL
9204 || (arm_psr_hsh = hash_new ()) == NULL)
9205 as_fatal (_("virtual memory exhausted"));
9207 build_arm_ops_hsh ();
9208 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
9209 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
9210 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
9211 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
9212 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
9213 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
9214 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
9215 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
9217 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
9218 build_reg_hsh (all_reg_maps + i);
9220 set_constant_flonums ();
9222 /* Set the cpu variant based on the command-line options. We prefer
9223 -mcpu= over -march= if both are set (as for GCC); and we prefer
9224 -mfpu= over any other way of setting the floating point unit.
9225 Use of legacy options with new options are faulted. */
9226 if (legacy_cpu != -1)
9228 if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
9229 as_bad (_("use of old and new-style options to set CPU type"));
9231 mcpu_cpu_opt = legacy_cpu;
9233 else if (mcpu_cpu_opt == -1)
9234 mcpu_cpu_opt = march_cpu_opt;
9236 if (legacy_fpu != -1)
9239 as_bad (_("use of old and new-style options to set FPU type"));
9241 mfpu_opt = legacy_fpu;
9243 else if (mfpu_opt == -1)
9245 if (mcpu_fpu_opt != -1)
9246 mfpu_opt = mcpu_fpu_opt;
9248 mfpu_opt = march_fpu_opt;
9253 if (mcpu_cpu_opt == -1)
9254 mfpu_opt = FPU_DEFAULT;
9255 else if (mcpu_cpu_opt & ARM_EXT_V5)
9256 mfpu_opt = FPU_ARCH_VFP_V2;
9258 mfpu_opt = FPU_ARCH_FPA;
9261 if (mcpu_cpu_opt == -1)
9262 mcpu_cpu_opt = CPU_DEFAULT;
9264 cpu_variant = mcpu_cpu_opt | mfpu_opt;
9266 #if defined OBJ_COFF || defined OBJ_ELF
9268 unsigned int flags = 0;
9270 /* Set the flags in the private structure. */
9271 if (uses_apcs_26) flags |= F_APCS26;
9272 if (support_interwork) flags |= F_INTERWORK;
9273 if (uses_apcs_float) flags |= F_APCS_FLOAT;
9274 if (pic_code) flags |= F_PIC;
9275 if ((cpu_variant & FPU_ANY) == FPU_NONE
9276 || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only. */
9277 flags |= F_SOFT_FLOAT;
9278 /* Using VFP conventions (even if soft-float). */
9279 if (cpu_variant & FPU_VFP_EXT_NONE) flags |= F_VFP_FLOAT;
9282 bfd_set_private_flags (stdoutput, flags);
9284 /* We have run out flags in the COFF header to encode the
9285 status of ATPCS support, so instead we create a dummy,
9286 empty, debug section called .arm.atpcs. */
9291 sec = bfd_make_section (stdoutput, ".arm.atpcs");
9295 bfd_set_section_flags
9296 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
9297 bfd_set_section_size (stdoutput, sec, 0);
9298 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
9304 /* Record the CPU type as well. */
9305 switch (cpu_variant & ARM_CPU_MASK)
9308 mach = bfd_mach_arm_2;
9311 case ARM_3: /* Also ARM_250. */
9312 mach = bfd_mach_arm_2a;
9315 case ARM_6: /* Also ARM_7. */
9316 mach = bfd_mach_arm_3;
9320 mach = bfd_mach_arm_4;
9324 /* Catch special cases. */
9325 if (cpu_variant & ARM_CEXT_XSCALE)
9326 mach = bfd_mach_arm_XScale;
9327 else if (cpu_variant & ARM_EXT_V5E)
9328 mach = bfd_mach_arm_5TE;
9329 else if (cpu_variant & ARM_EXT_V5)
9331 if (cpu_variant & ARM_EXT_V4T)
9332 mach = bfd_mach_arm_5T;
9334 mach = bfd_mach_arm_5;
9336 else if (cpu_variant & ARM_EXT_V4)
9338 if (cpu_variant & ARM_EXT_V4T)
9339 mach = bfd_mach_arm_4T;
9341 mach = bfd_mach_arm_4;
9343 else if (cpu_variant & ARM_EXT_V3M)
9344 mach = bfd_mach_arm_3M;
9346 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
9349 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
9350 for use in the a.out file, and stores them in the array pointed to by buf.
9351 This knows about the endian-ness of the target machine and does
9352 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
9353 2 (short) and 4 (long) Floating numbers are put out as a series of
9354 LITTLENUMS (shorts, here at least). */
9357 md_number_to_chars (buf, val, n)
9362 if (target_big_endian)
9363 number_to_chars_bigendian (buf, val, n);
9365 number_to_chars_littleendian (buf, val, n);
9369 md_chars_to_number (buf, n)
9374 unsigned char * where = (unsigned char *) buf;
9376 if (target_big_endian)
9381 result |= (*where++ & 255);
9389 result |= (where[n] & 255);
9396 /* Turn a string in input_line_pointer into a floating point constant
9397 of type TYPE, and store the appropriate bytes in *LITP. The number
9398 of LITTLENUMS emitted is stored in *SIZEP. An error message is
9399 returned, or NULL on OK.
9401 Note that fp constants aren't represent in the normal way on the ARM.
9402 In big endian mode, things are as expected. However, in little endian
9403 mode fp constants are big-endian word-wise, and little-endian byte-wise
9404 within the words. For example, (double) 1.1 in big endian mode is
9405 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
9406 the byte sequence 99 99 f1 3f 9a 99 99 99.
9408 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
9411 md_atof (type, litP, sizeP)
9417 LITTLENUM_TYPE words[MAX_LITTLENUMS];
9449 return _("bad call to MD_ATOF()");
9452 t = atof_ieee (input_line_pointer, type, words);
9454 input_line_pointer = t;
9457 if (target_big_endian)
9459 for (i = 0; i < prec; i++)
9461 md_number_to_chars (litP, (valueT) words[i], 2);
9467 if (cpu_variant & FPU_ARCH_VFP)
9468 for (i = prec - 1; i >= 0; i--)
9470 md_number_to_chars (litP, (valueT) words[i], 2);
9474 /* For a 4 byte float the order of elements in `words' is 1 0.
9475 For an 8 byte float the order is 1 0 3 2. */
9476 for (i = 0; i < prec; i += 2)
9478 md_number_to_chars (litP, (valueT) words[i + 1], 2);
9479 md_number_to_chars (litP + 2, (valueT) words[i], 2);
9487 /* The knowledge of the PC's pipeline offset is built into the insns
9491 md_pcrel_from (fixP)
9495 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
9496 && fixP->fx_subsy == NULL)
9499 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
9501 /* PC relative addressing on the Thumb is slightly odd
9502 as the bottom two bits of the PC are forced to zero
9503 for the calculation. */
9504 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
9508 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
9509 so we un-adjust here to compensate for the accomodation. */
9510 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
9512 return fixP->fx_where + fixP->fx_frag->fr_address;
9516 /* Round up a section size to the appropriate boundary. */
9519 md_section_align (segment, size)
9520 segT segment ATTRIBUTE_UNUSED;
9526 /* Round all sects to multiple of 4. */
9527 return (size + 3) & ~3;
9531 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
9532 Otherwise we have no need to default values of symbols. */
9535 md_undefined_symbol (name)
9536 char * name ATTRIBUTE_UNUSED;
9539 if (name[0] == '_' && name[1] == 'G'
9540 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
9544 if (symbol_find (name))
9545 as_bad ("GOT already in the symbol table");
9547 GOT_symbol = symbol_new (name, undefined_section,
9548 (valueT) 0, & zero_address_frag);
9558 /* arm_reg_parse () := if it looks like a register, return its token and
9559 advance the pointer. */
9562 arm_reg_parse (ccp, htab)
9563 register char ** ccp;
9564 struct hash_control *htab;
9566 char * start = * ccp;
9569 struct reg_entry * reg;
9571 #ifdef REGISTER_PREFIX
9572 if (*start != REGISTER_PREFIX)
9577 #ifdef OPTIONAL_REGISTER_PREFIX
9578 if (*p == OPTIONAL_REGISTER_PREFIX)
9582 if (!ISALPHA (*p) || !is_name_beginner (*p))
9586 while (ISALPHA (c) || ISDIGIT (c) || c == '_')
9590 reg = (struct reg_entry *) hash_find (htab, start);
9602 /* Search for the following register name in each of the possible reg name
9603 tables. Return the classification if found, or REG_TYPE_MAX if not
9605 static enum arm_reg_type
9606 arm_reg_parse_any (cp)
9611 for (i = (int) REG_TYPE_FIRST; i < (int) REG_TYPE_MAX; i++)
9612 if (arm_reg_parse (&cp, all_reg_maps[i].htab) != FAIL)
9613 return (enum arm_reg_type) i;
9615 return REG_TYPE_MAX;
9619 md_apply_fix3 (fixP, valP, seg)
9624 offsetT value = * valP;
9626 unsigned int newimm;
9629 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
9630 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
9632 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
9634 /* Note whether this will delete the relocation. */
9636 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
9637 doesn't work fully.) */
9638 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
9641 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
9645 /* If this symbol is in a different section then we need to leave it for
9646 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
9647 so we have to undo it's effects here. */
9650 if (fixP->fx_addsy != NULL
9651 && S_IS_DEFINED (fixP->fx_addsy)
9652 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
9655 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
9656 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
9660 value += md_pcrel_from (fixP);
9664 /* Remember value for emit_reloc. */
9665 fixP->fx_addnumber = value;
9667 switch (fixP->fx_r_type)
9669 case BFD_RELOC_ARM_IMMEDIATE:
9670 newimm = validate_immediate (value);
9671 temp = md_chars_to_number (buf, INSN_SIZE);
9673 /* If the instruction will fail, see if we can fix things up by
9674 changing the opcode. */
9675 if (newimm == (unsigned int) FAIL
9676 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
9678 as_bad_where (fixP->fx_file, fixP->fx_line,
9679 _("invalid constant (%lx) after fixup"),
9680 (unsigned long) value);
9684 newimm |= (temp & 0xfffff000);
9685 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
9689 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
9691 unsigned int highpart = 0;
9692 unsigned int newinsn = 0xe1a00000; /* nop. */
9694 newimm = validate_immediate (value);
9695 temp = md_chars_to_number (buf, INSN_SIZE);
9697 /* If the instruction will fail, see if we can fix things up by
9698 changing the opcode. */
9699 if (newimm == (unsigned int) FAIL
9700 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
9702 /* No ? OK - try using two ADD instructions to generate
9704 newimm = validate_immediate_twopart (value, & highpart);
9706 /* Yes - then make sure that the second instruction is
9708 if (newimm != (unsigned int) FAIL)
9710 /* Still No ? Try using a negated value. */
9711 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
9712 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
9713 /* Otherwise - give up. */
9716 as_bad_where (fixP->fx_file, fixP->fx_line,
9717 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
9722 /* Replace the first operand in the 2nd instruction (which
9723 is the PC) with the destination register. We have
9724 already added in the PC in the first instruction and we
9725 do not want to do it again. */
9726 newinsn &= ~ 0xf0000;
9727 newinsn |= ((newinsn & 0x0f000) << 4);
9730 newimm |= (temp & 0xfffff000);
9731 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
9733 highpart |= (newinsn & 0xfffff000);
9734 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
9738 case BFD_RELOC_ARM_OFFSET_IMM:
9744 if (validate_offset_imm (value, 0) == FAIL)
9746 as_bad_where (fixP->fx_file, fixP->fx_line,
9747 _("bad immediate value for offset (%ld)"),
9752 newval = md_chars_to_number (buf, INSN_SIZE);
9753 newval &= 0xff7ff000;
9754 newval |= value | (sign ? INDEX_UP : 0);
9755 md_number_to_chars (buf, newval, INSN_SIZE);
9758 case BFD_RELOC_ARM_OFFSET_IMM8:
9759 case BFD_RELOC_ARM_HWLITERAL:
9765 if (validate_offset_imm (value, 1) == FAIL)
9767 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
9768 as_bad_where (fixP->fx_file, fixP->fx_line,
9769 _("invalid literal constant: pool needs to be closer"));
9771 as_bad (_("bad immediate value for half-word offset (%ld)"),
9776 newval = md_chars_to_number (buf, INSN_SIZE);
9777 newval &= 0xff7ff0f0;
9778 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
9779 md_number_to_chars (buf, newval, INSN_SIZE);
9782 case BFD_RELOC_ARM_LITERAL:
9788 if (validate_offset_imm (value, 0) == FAIL)
9790 as_bad_where (fixP->fx_file, fixP->fx_line,
9791 _("invalid literal constant: pool needs to be closer"));
9795 newval = md_chars_to_number (buf, INSN_SIZE);
9796 newval &= 0xff7ff000;
9797 newval |= value | (sign ? INDEX_UP : 0);
9798 md_number_to_chars (buf, newval, INSN_SIZE);
9801 case BFD_RELOC_ARM_SHIFT_IMM:
9802 newval = md_chars_to_number (buf, INSN_SIZE);
9803 if (((unsigned long) value) > 32
9805 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
9807 as_bad_where (fixP->fx_file, fixP->fx_line,
9808 _("shift expression is too large"));
9813 /* Shifts of zero must be done as lsl. */
9815 else if (value == 32)
9817 newval &= 0xfffff07f;
9818 newval |= (value & 0x1f) << 7;
9819 md_number_to_chars (buf, newval, INSN_SIZE);
9822 case BFD_RELOC_ARM_SWI:
9823 if (arm_data->thumb_mode)
9825 if (((unsigned long) value) > 0xff)
9826 as_bad_where (fixP->fx_file, fixP->fx_line,
9827 _("invalid swi expression"));
9828 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
9830 md_number_to_chars (buf, newval, THUMB_SIZE);
9834 if (((unsigned long) value) > 0x00ffffff)
9835 as_bad_where (fixP->fx_file, fixP->fx_line,
9836 _("invalid swi expression"));
9837 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
9839 md_number_to_chars (buf, newval, INSN_SIZE);
9843 case BFD_RELOC_ARM_MULTI:
9844 if (((unsigned long) value) > 0xffff)
9845 as_bad_where (fixP->fx_file, fixP->fx_line,
9846 _("invalid expression in load/store multiple"));
9847 newval = value | md_chars_to_number (buf, INSN_SIZE);
9848 md_number_to_chars (buf, newval, INSN_SIZE);
9851 case BFD_RELOC_ARM_PCREL_BRANCH:
9852 newval = md_chars_to_number (buf, INSN_SIZE);
9854 /* Sign-extend a 24-bit number. */
9855 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
9859 value = fixP->fx_offset;
9862 /* We are going to store value (shifted right by two) in the
9863 instruction, in a 24 bit, signed field. Thus we need to check
9864 that none of the top 8 bits of the shifted value (top 7 bits of
9865 the unshifted, unsigned value) are set, or that they are all set. */
9866 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
9867 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
9870 /* Normally we would be stuck at this point, since we cannot store
9871 the absolute address that is the destination of the branch in the
9872 24 bits of the branch instruction. If however, we happen to know
9873 that the destination of the branch is in the same section as the
9874 branch instruciton itself, then we can compute the relocation for
9875 ourselves and not have to bother the linker with it.
9877 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
9878 because I have not worked out how to do this for OBJ_COFF or
9881 && fixP->fx_addsy != NULL
9882 && S_IS_DEFINED (fixP->fx_addsy)
9883 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
9885 /* Get pc relative value to go into the branch. */
9888 /* Permit a backward branch provided that enough bits
9889 are set. Allow a forwards branch, provided that
9890 enough bits are clear. */
9891 if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
9892 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
9896 if (! fixP->fx_done)
9898 as_bad_where (fixP->fx_file, fixP->fx_line,
9899 _("GAS can't handle same-section branch dest >= 0x04000000"));
9903 value += SEXT24 (newval);
9905 if ( (value & ~ ((offsetT) 0xffffff)) != 0
9906 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
9907 as_bad_where (fixP->fx_file, fixP->fx_line,
9908 _("out of range branch"));
9910 newval = (value & 0x00ffffff) | (newval & 0xff000000);
9911 md_number_to_chars (buf, newval, INSN_SIZE);
9914 case BFD_RELOC_ARM_PCREL_BLX:
9917 newval = md_chars_to_number (buf, INSN_SIZE);
9921 value = fixP->fx_offset;
9923 hbit = (value >> 1) & 1;
9924 value = (value >> 2) & 0x00ffffff;
9925 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
9926 newval = value | (newval & 0xfe000000) | (hbit << 24);
9927 md_number_to_chars (buf, newval, INSN_SIZE);
9931 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
9932 newval = md_chars_to_number (buf, THUMB_SIZE);
9934 addressT diff = (newval & 0xff) << 1;
9939 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
9940 as_bad_where (fixP->fx_file, fixP->fx_line,
9941 _("branch out of range"));
9942 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
9944 md_number_to_chars (buf, newval, THUMB_SIZE);
9947 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
9948 newval = md_chars_to_number (buf, THUMB_SIZE);
9950 addressT diff = (newval & 0x7ff) << 1;
9955 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
9956 as_bad_where (fixP->fx_file, fixP->fx_line,
9957 _("branch out of range"));
9958 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
9960 md_number_to_chars (buf, newval, THUMB_SIZE);
9963 case BFD_RELOC_THUMB_PCREL_BLX:
9964 case BFD_RELOC_THUMB_PCREL_BRANCH23:
9969 newval = md_chars_to_number (buf, THUMB_SIZE);
9970 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
9971 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
9972 if (diff & 0x400000)
9975 value = fixP->fx_offset;
9979 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
9980 as_bad_where (fixP->fx_file, fixP->fx_line,
9981 _("branch with link out of range"));
9983 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
9984 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
9985 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
9986 /* For a BLX instruction, make sure that the relocation is rounded up
9987 to a word boundary. This follows the semantics of the instruction
9988 which specifies that bit 1 of the target address will come from bit
9989 1 of the base address. */
9990 newval2 = (newval2 + 1) & ~ 1;
9991 md_number_to_chars (buf, newval, THUMB_SIZE);
9992 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
9997 if (fixP->fx_done || fixP->fx_pcrel)
9998 md_number_to_chars (buf, value, 1);
10000 else if (!target_oabi)
10002 value = fixP->fx_offset;
10003 md_number_to_chars (buf, value, 1);
10009 if (fixP->fx_done || fixP->fx_pcrel)
10010 md_number_to_chars (buf, value, 2);
10012 else if (!target_oabi)
10014 value = fixP->fx_offset;
10015 md_number_to_chars (buf, value, 2);
10021 case BFD_RELOC_ARM_GOT32:
10022 case BFD_RELOC_ARM_GOTOFF:
10023 md_number_to_chars (buf, 0, 4);
10027 case BFD_RELOC_RVA:
10029 if (fixP->fx_done || fixP->fx_pcrel)
10030 md_number_to_chars (buf, value, 4);
10032 else if (!target_oabi)
10034 value = fixP->fx_offset;
10035 md_number_to_chars (buf, value, 4);
10041 case BFD_RELOC_ARM_PLT32:
10042 /* It appears the instruction is fully prepared at this point. */
10046 case BFD_RELOC_ARM_CP_OFF_IMM:
10048 if (value < -1023 || value > 1023 || (value & 3))
10049 as_bad_where (fixP->fx_file, fixP->fx_line,
10050 _("illegal value for co-processor offset"));
10053 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
10054 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
10055 md_number_to_chars (buf, newval, INSN_SIZE);
10058 case BFD_RELOC_ARM_THUMB_OFFSET:
10059 newval = md_chars_to_number (buf, THUMB_SIZE);
10060 /* Exactly what ranges, and where the offset is inserted depends
10061 on the type of instruction, we can establish this from the
10063 switch (newval >> 12)
10065 case 4: /* PC load. */
10066 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
10067 forced to zero for these loads, so we will need to round
10068 up the offset if the instruction address is not word
10069 aligned (since the final address produced must be, and
10070 we can only describe word-aligned immediate offsets). */
10072 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
10073 as_bad_where (fixP->fx_file, fixP->fx_line,
10074 _("invalid offset, target not word aligned (0x%08X)"),
10075 (unsigned int) (fixP->fx_frag->fr_address
10076 + fixP->fx_where + value));
10078 if ((value + 2) & ~0x3fe)
10079 as_bad_where (fixP->fx_file, fixP->fx_line,
10080 _("invalid offset, value too big (0x%08lX)"),
10083 /* Round up, since pc will be rounded down. */
10084 newval |= (value + 2) >> 2;
10087 case 9: /* SP load/store. */
10088 if (value & ~0x3fc)
10089 as_bad_where (fixP->fx_file, fixP->fx_line,
10090 _("invalid offset, value too big (0x%08lX)"),
10092 newval |= value >> 2;
10095 case 6: /* Word load/store. */
10097 as_bad_where (fixP->fx_file, fixP->fx_line,
10098 _("invalid offset, value too big (0x%08lX)"),
10100 newval |= value << 4; /* 6 - 2. */
10103 case 7: /* Byte load/store. */
10105 as_bad_where (fixP->fx_file, fixP->fx_line,
10106 _("invalid offset, value too big (0x%08lX)"),
10108 newval |= value << 6;
10111 case 8: /* Halfword load/store. */
10113 as_bad_where (fixP->fx_file, fixP->fx_line,
10114 _("invalid offset, value too big (0x%08lX)"),
10116 newval |= value << 5; /* 6 - 1. */
10120 as_bad_where (fixP->fx_file, fixP->fx_line,
10121 "Unable to process relocation for thumb opcode: %lx",
10122 (unsigned long) newval);
10125 md_number_to_chars (buf, newval, THUMB_SIZE);
10128 case BFD_RELOC_ARM_THUMB_ADD:
10129 /* This is a complicated relocation, since we use it for all of
10130 the following immediate relocations:
10134 9bit ADD/SUB SP word-aligned
10135 10bit ADD PC/SP word-aligned
10137 The type of instruction being processed is encoded in the
10144 newval = md_chars_to_number (buf, THUMB_SIZE);
10146 int rd = (newval >> 4) & 0xf;
10147 int rs = newval & 0xf;
10148 int subtract = newval & 0x8000;
10152 if (value & ~0x1fc)
10153 as_bad_where (fixP->fx_file, fixP->fx_line,
10154 _("invalid immediate for stack address calculation"));
10155 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
10156 newval |= value >> 2;
10158 else if (rs == REG_PC || rs == REG_SP)
10162 as_bad_where (fixP->fx_file, fixP->fx_line,
10163 _("invalid immediate for address calculation (value = 0x%08lX)"),
10164 (unsigned long) value);
10165 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
10167 newval |= value >> 2;
10172 as_bad_where (fixP->fx_file, fixP->fx_line,
10173 _("invalid 8bit immediate"));
10174 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
10175 newval |= (rd << 8) | value;
10180 as_bad_where (fixP->fx_file, fixP->fx_line,
10181 _("invalid 3bit immediate"));
10182 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
10183 newval |= rd | (rs << 3) | (value << 6);
10186 md_number_to_chars (buf, newval, THUMB_SIZE);
10189 case BFD_RELOC_ARM_THUMB_IMM:
10190 newval = md_chars_to_number (buf, THUMB_SIZE);
10191 switch (newval >> 11)
10193 case 0x04: /* 8bit immediate MOV. */
10194 case 0x05: /* 8bit immediate CMP. */
10195 if (value < 0 || value > 255)
10196 as_bad_where (fixP->fx_file, fixP->fx_line,
10197 _("invalid immediate: %ld is too large"),
10205 md_number_to_chars (buf, newval, THUMB_SIZE);
10208 case BFD_RELOC_ARM_THUMB_SHIFT:
10209 /* 5bit shift value (0..31). */
10210 if (value < 0 || value > 31)
10211 as_bad_where (fixP->fx_file, fixP->fx_line,
10212 _("illegal Thumb shift value: %ld"), (long) value);
10213 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
10214 newval |= value << 6;
10215 md_number_to_chars (buf, newval, THUMB_SIZE);
10218 case BFD_RELOC_VTABLE_INHERIT:
10219 case BFD_RELOC_VTABLE_ENTRY:
10223 case BFD_RELOC_NONE:
10225 as_bad_where (fixP->fx_file, fixP->fx_line,
10226 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
10230 /* Translate internal representation of relocation info to BFD target
10234 tc_gen_reloc (section, fixp)
10235 asection * section ATTRIBUTE_UNUSED;
10239 bfd_reloc_code_real_type code;
10241 reloc = (arelent *) xmalloc (sizeof (arelent));
10243 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
10244 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
10245 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
10247 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
10249 if (fixp->fx_pcrel == 0)
10250 reloc->addend = fixp->fx_offset;
10252 reloc->addend = fixp->fx_offset = reloc->address;
10253 #else /* OBJ_ELF */
10254 reloc->addend = fixp->fx_offset;
10257 switch (fixp->fx_r_type)
10260 if (fixp->fx_pcrel)
10262 code = BFD_RELOC_8_PCREL;
10267 if (fixp->fx_pcrel)
10269 code = BFD_RELOC_16_PCREL;
10274 if (fixp->fx_pcrel)
10276 code = BFD_RELOC_32_PCREL;
10280 case BFD_RELOC_ARM_PCREL_BRANCH:
10281 case BFD_RELOC_ARM_PCREL_BLX:
10282 case BFD_RELOC_RVA:
10283 case BFD_RELOC_THUMB_PCREL_BRANCH9:
10284 case BFD_RELOC_THUMB_PCREL_BRANCH12:
10285 case BFD_RELOC_THUMB_PCREL_BRANCH23:
10286 case BFD_RELOC_THUMB_PCREL_BLX:
10287 case BFD_RELOC_VTABLE_ENTRY:
10288 case BFD_RELOC_VTABLE_INHERIT:
10289 code = fixp->fx_r_type;
10292 case BFD_RELOC_ARM_LITERAL:
10293 case BFD_RELOC_ARM_HWLITERAL:
10294 /* If this is called then the a literal has
10295 been referenced across a section boundary. */
10296 as_bad_where (fixp->fx_file, fixp->fx_line,
10297 _("literal referenced across section boundary"));
10301 case BFD_RELOC_ARM_GOT32:
10302 case BFD_RELOC_ARM_GOTOFF:
10303 case BFD_RELOC_ARM_PLT32:
10304 code = fixp->fx_r_type;
10308 case BFD_RELOC_ARM_IMMEDIATE:
10309 as_bad_where (fixp->fx_file, fixp->fx_line,
10310 _("internal relocation (type: IMMEDIATE) not fixed up"));
10313 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
10314 as_bad_where (fixp->fx_file, fixp->fx_line,
10315 _("ADRL used for a symbol not defined in the same file"));
10318 case BFD_RELOC_ARM_OFFSET_IMM:
10319 as_bad_where (fixp->fx_file, fixp->fx_line,
10320 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
10327 switch (fixp->fx_r_type)
10329 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
10330 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
10331 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
10332 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
10333 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
10334 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
10335 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
10336 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
10337 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
10338 default: type = _("<unknown>"); break;
10340 as_bad_where (fixp->fx_file, fixp->fx_line,
10341 _("cannot represent %s relocation in this object file format"),
10348 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
10350 && fixp->fx_addsy == GOT_symbol)
10352 code = BFD_RELOC_ARM_GOTPC;
10353 reloc->addend = fixp->fx_offset = reloc->address;
10357 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
10359 if (reloc->howto == NULL)
10361 as_bad_where (fixp->fx_file, fixp->fx_line,
10362 _("cannot represent %s relocation in this object file format"),
10363 bfd_get_reloc_code_name (code));
10367 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
10368 vtable entry to be used in the relocation's section offset. */
10369 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
10370 reloc->address = fixp->fx_offset;
10376 md_estimate_size_before_relax (fragP, segtype)
10377 fragS * fragP ATTRIBUTE_UNUSED;
10378 segT segtype ATTRIBUTE_UNUSED;
10380 as_fatal (_("md_estimate_size_before_relax\n"));
10392 as_bad ("%s -- `%s'", inst.error, str);
10396 to = frag_more (inst.size);
10398 if (thumb_mode && (inst.size > THUMB_SIZE))
10400 assert (inst.size == (2 * THUMB_SIZE));
10401 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
10402 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
10404 else if (inst.size > INSN_SIZE)
10406 assert (inst.size == (2 * INSN_SIZE));
10407 md_number_to_chars (to, inst.instruction, INSN_SIZE);
10408 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
10411 md_number_to_chars (to, inst.instruction, inst.size);
10413 if (inst.reloc.type != BFD_RELOC_NONE)
10414 fix_new_arm (frag_now, to - frag_now->fr_literal,
10415 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
10419 dwarf2_emit_insn (inst.size);
10431 /* Align the instruction.
10432 This may not be the right thing to do but ... */
10437 /* Align the previous label if needed. */
10438 if (last_label_seen != NULL)
10440 symbol_set_frag (last_label_seen, frag_now);
10441 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
10442 S_SET_SEGMENT (last_label_seen, now_seg);
10445 memset (&inst, '\0', sizeof (inst));
10446 inst.reloc.type = BFD_RELOC_NONE;
10448 skip_whitespace (str);
10450 /* Scan up to the end of the op-code, which must end in white space or
10452 for (start = p = str; *p != '\0'; p++)
10458 as_bad (_("no operator -- statement `%s'\n"), str);
10464 const struct thumb_opcode * opcode;
10468 opcode = (const struct thumb_opcode *) hash_find (arm_tops_hsh, str);
10473 /* Check that this instruction is supported for this CPU. */
10474 if (thumb_mode == 1 && (opcode->variant & cpu_variant) == 0)
10476 as_bad (_("selected processor does not support `%s'"), str);
10480 inst.instruction = opcode->value;
10481 inst.size = opcode->size;
10482 (*opcode->parms) (p);
10489 const struct asm_opcode * opcode;
10493 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, str);
10498 /* Check that this instruction is supported for this CPU. */
10499 if ((opcode->variant & cpu_variant) == 0)
10501 as_bad (_("selected processor does not support `%s'"), str);
10505 inst.instruction = opcode->value;
10506 inst.size = INSN_SIZE;
10507 (*opcode->parms) (p);
10513 /* It wasn't an instruction, but it might be a register alias of the form
10515 if (create_register_alias (str, p))
10518 as_bad (_("bad instruction `%s'"), start);
10522 Invocation line includes a switch not recognized by the base assembler.
10523 See if it's a processor-specific option.
10525 This routine is somewhat complicated by the need for backwards
10526 compatibility (since older releases of gcc can't be changed).
10527 The new options try to make the interface as compatible as
10530 New options (supported) are:
10532 -mcpu=<cpu name> Assemble for selected processor
10533 -march=<architecture name> Assemble for selected architecture
10534 -mfpu=<fpu architecture> Assemble for selected FPU.
10535 -EB/-mbig-endian Big-endian
10536 -EL/-mlittle-endian Little-endian
10537 -k Generate PIC code
10538 -mthumb Start in Thumb mode
10539 -mthumb-interwork Code supports ARM/Thumb interworking
10541 For now we will also provide support for:
10543 -mapcs-32 32-bit Program counter
10544 -mapcs-26 26-bit Program counter
10545 -macps-float Floats passed in FP registers
10546 -mapcs-reentrant Reentrant code
10548 (sometime these will probably be replaced with -mapcs=<list of options>
10549 and -matpcs=<list of options>)
10551 The remaining options are only supported for back-wards compatibility.
10552 Cpu variants, the arm part is optional:
10553 -m[arm]1 Currently not supported.
10554 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
10555 -m[arm]3 Arm 3 processor
10556 -m[arm]6[xx], Arm 6 processors
10557 -m[arm]7[xx][t][[d]m] Arm 7 processors
10558 -m[arm]8[10] Arm 8 processors
10559 -m[arm]9[20][tdmi] Arm 9 processors
10560 -mstrongarm[110[0]] StrongARM processors
10561 -mxscale XScale processors
10562 -m[arm]v[2345[t[e]]] Arm architectures
10563 -mall All (except the ARM1)
10565 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
10566 -mfpe-old (No float load/store multiples)
10567 -mvfpxd VFP Single precision
10569 -mno-fpu Disable all floating point instructions
10571 The following CPU names are recognized:
10572 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
10573 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
10574 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
10575 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
10576 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
10577 arm10t arm10e, arm1020t, arm1020e, arm10200e,
10578 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
10582 const char * md_shortopts = "m:k";
10584 #ifdef ARM_BI_ENDIAN
10585 #define OPTION_EB (OPTION_MD_BASE + 0)
10586 #define OPTION_EL (OPTION_MD_BASE + 1)
10588 #if TARGET_BYTES_BIG_ENDIAN
10589 #define OPTION_EB (OPTION_MD_BASE + 0)
10591 #define OPTION_EL (OPTION_MD_BASE + 1)
10595 struct option md_longopts[] =
10598 {"EB", no_argument, NULL, OPTION_EB},
10601 {"EL", no_argument, NULL, OPTION_EL},
10603 {NULL, no_argument, NULL, 0}
10606 size_t md_longopts_size = sizeof (md_longopts);
10608 struct arm_option_table
10610 char *option; /* Option name to match. */
10611 char *help; /* Help information. */
10612 int *var; /* Variable to change. */
10613 int value; /* What to change it to. */
10614 char *deprecated; /* If non-null, print this message. */
10617 struct arm_option_table arm_opts[] =
10619 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
10620 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
10621 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
10622 &support_interwork, 1, NULL},
10623 {"moabi", N_("use old ABI (ELF only)"), &target_oabi, 1, NULL},
10624 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
10625 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
10626 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
10628 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
10629 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
10630 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
10631 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 1,
10634 /* These are recognized by the assembler, but have no affect on code. */
10635 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
10636 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
10638 /* DON'T add any new processors to this list -- we want the whole list
10639 to go away... Add them to the processors table instead. */
10640 {"marm1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
10641 {"m1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
10642 {"marm2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
10643 {"m2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
10644 {"marm250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
10645 {"m250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
10646 {"marm3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
10647 {"m3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
10648 {"marm6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
10649 {"m6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
10650 {"marm600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
10651 {"m600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
10652 {"marm610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
10653 {"m610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
10654 {"marm620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
10655 {"m620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
10656 {"marm7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
10657 {"m7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
10658 {"marm70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
10659 {"m70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
10660 {"marm700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
10661 {"m700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
10662 {"marm700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
10663 {"m700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
10664 {"marm710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
10665 {"m710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
10666 {"marm710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
10667 {"m710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
10668 {"marm720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
10669 {"m720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
10670 {"marm7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
10671 {"m7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
10672 {"marm7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
10673 {"m7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
10674 {"marm7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
10675 {"m7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
10676 {"marm7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
10677 {"m7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
10678 {"marm7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
10679 {"m7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
10680 {"marm7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
10681 {"m7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
10682 {"marm7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
10683 {"m7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
10684 {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
10685 {"m7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
10686 {"marm7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10687 {"m7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10688 {"marm7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10689 {"m7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
10690 {"marm710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
10691 {"m710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
10692 {"marm720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
10693 {"m720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
10694 {"marm740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
10695 {"m740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
10696 {"marm8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
10697 {"m8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
10698 {"marm810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
10699 {"m810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
10700 {"marm9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
10701 {"m9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
10702 {"marm9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
10703 {"m9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
10704 {"marm920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
10705 {"m920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
10706 {"marm940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
10707 {"m940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
10708 {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
10709 {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
10710 N_("use -mcpu=strongarm110")},
10711 {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
10712 N_("use -mcpu=strongarm1100")},
10713 {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
10714 N_("use -mcpu=strongarm1110")},
10715 {"mxscale", NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
10716 {"mall", NULL, &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
10718 /* Architecture variants -- don't add any more to this list either. */
10719 {"mv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
10720 {"marmv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
10721 {"mv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
10722 {"marmv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
10723 {"mv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
10724 {"marmv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
10725 {"mv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
10726 {"marmv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
10727 {"mv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
10728 {"marmv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
10729 {"mv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
10730 {"marmv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
10731 {"mv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
10732 {"marmv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
10733 {"mv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
10734 {"marmv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
10735 {"mv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
10736 {"marmv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
10738 /* Floating point variants -- don't add any more to this list either. */
10739 {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
10740 {"mfpa10", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
10741 {"mfpa11", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
10742 {"mno-fpu", NULL, &legacy_fpu, 0,
10743 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
10745 {NULL, NULL, NULL, 0, NULL}
10748 struct arm_cpu_option_table
10752 /* For some CPUs we assume an FPU unless the user explicitly sets
10757 /* This list should, at a minimum, contain all the cpu names
10758 recognized by GCC. */
10759 static struct arm_cpu_option_table arm_cpus[] =
10761 {"all", ARM_ANY, FPU_ARCH_FPA},
10762 {"arm1", ARM_ARCH_V1, FPU_ARCH_FPA},
10763 {"arm2", ARM_ARCH_V2, FPU_ARCH_FPA},
10764 {"arm250", ARM_ARCH_V2S, FPU_ARCH_FPA},
10765 {"arm3", ARM_ARCH_V2S, FPU_ARCH_FPA},
10766 {"arm6", ARM_ARCH_V3, FPU_ARCH_FPA},
10767 {"arm60", ARM_ARCH_V3, FPU_ARCH_FPA},
10768 {"arm600", ARM_ARCH_V3, FPU_ARCH_FPA},
10769 {"arm610", ARM_ARCH_V3, FPU_ARCH_FPA},
10770 {"arm620", ARM_ARCH_V3, FPU_ARCH_FPA},
10771 {"arm7", ARM_ARCH_V3, FPU_ARCH_FPA},
10772 {"arm7m", ARM_ARCH_V3M, FPU_ARCH_FPA},
10773 {"arm7d", ARM_ARCH_V3, FPU_ARCH_FPA},
10774 {"arm7dm", ARM_ARCH_V3M, FPU_ARCH_FPA},
10775 {"arm7di", ARM_ARCH_V3, FPU_ARCH_FPA},
10776 {"arm7dmi", ARM_ARCH_V3M, FPU_ARCH_FPA},
10777 {"arm70", ARM_ARCH_V3, FPU_ARCH_FPA},
10778 {"arm700", ARM_ARCH_V3, FPU_ARCH_FPA},
10779 {"arm700i", ARM_ARCH_V3, FPU_ARCH_FPA},
10780 {"arm710", ARM_ARCH_V3, FPU_ARCH_FPA},
10781 {"arm710t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10782 {"arm720", ARM_ARCH_V3, FPU_ARCH_FPA},
10783 {"arm720t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10784 {"arm740t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10785 {"arm710c", ARM_ARCH_V3, FPU_ARCH_FPA},
10786 {"arm7100", ARM_ARCH_V3, FPU_ARCH_FPA},
10787 {"arm7500", ARM_ARCH_V3, FPU_ARCH_FPA},
10788 {"arm7500fe", ARM_ARCH_V3, FPU_ARCH_FPA},
10789 {"arm7t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10790 {"arm7tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
10791 {"arm8", ARM_ARCH_V4, FPU_ARCH_FPA},
10792 {"arm810", ARM_ARCH_V4, FPU_ARCH_FPA},
10793 {"strongarm", ARM_ARCH_V4, FPU_ARCH_FPA},
10794 {"strongarm1", ARM_ARCH_V4, FPU_ARCH_FPA},
10795 {"strongarm110", ARM_ARCH_V4, FPU_ARCH_FPA},
10796 {"strongarm1100", ARM_ARCH_V4, FPU_ARCH_FPA},
10797 {"strongarm1110", ARM_ARCH_V4, FPU_ARCH_FPA},
10798 {"arm9", ARM_ARCH_V4T, FPU_ARCH_FPA},
10799 {"arm920", ARM_ARCH_V4T, FPU_ARCH_FPA},
10800 {"arm920t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10801 {"arm922t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10802 {"arm940t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10803 {"arm9tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA},
10804 /* For V5 or later processors we default to using VFP; but the user
10805 should really set the FPU type explicitly. */
10806 {"arm9e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
10807 {"arm9e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10808 {"arm926ej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2},
10809 {"arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
10810 {"arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10811 {"arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2},
10812 {"arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10813 {"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
10814 {"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10815 {"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10816 {"arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1},
10817 {"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2},
10818 /* ??? XSCALE is really an architecture. */
10819 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
10820 {"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2},
10822 {"ep9312", ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_NONE},
10826 struct arm_arch_option_table
10833 /* This list should, at a minimum, contain all the architecture names
10834 recognized by GCC. */
10835 static struct arm_arch_option_table arm_archs[] =
10837 {"all", ARM_ANY, FPU_ARCH_FPA},
10838 {"armv1", ARM_ARCH_V1, FPU_ARCH_FPA},
10839 {"armv2", ARM_ARCH_V2, FPU_ARCH_FPA},
10840 {"armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA},
10841 {"armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA},
10842 {"armv3", ARM_ARCH_V3, FPU_ARCH_FPA},
10843 {"armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA},
10844 {"armv4", ARM_ARCH_V4, FPU_ARCH_FPA},
10845 {"armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA},
10846 {"armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA},
10847 {"armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA},
10848 {"armv5", ARM_ARCH_V5, FPU_ARCH_VFP},
10849 {"armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP},
10850 {"armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP},
10851 {"armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP},
10852 {"armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP},
10853 {"armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP},
10854 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
10858 /* ISA extensions in the co-processor space. */
10859 struct arm_arch_extension_table
10865 static struct arm_arch_extension_table arm_extensions[] =
10867 {"maverick", ARM_CEXT_MAVERICK},
10868 {"xscale", ARM_CEXT_XSCALE},
10872 struct arm_fpu_option_table
10878 /* This list should, at a minimum, contain all the fpu names
10879 recognized by GCC. */
10880 static struct arm_fpu_option_table arm_fpus[] =
10882 {"softfpa", FPU_NONE},
10883 {"fpe", FPU_ARCH_FPE},
10884 {"fpe2", FPU_ARCH_FPE},
10885 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
10886 {"fpa", FPU_ARCH_FPA},
10887 {"fpa10", FPU_ARCH_FPA},
10888 {"fpa11", FPU_ARCH_FPA},
10889 {"arm7500fe", FPU_ARCH_FPA},
10890 {"softvfp", FPU_ARCH_VFP},
10891 {"softvfp+vfp", FPU_ARCH_VFP_V2},
10892 {"vfp", FPU_ARCH_VFP_V2},
10893 {"vfp9", FPU_ARCH_VFP_V2},
10894 {"vfp10", FPU_ARCH_VFP_V2},
10895 {"vfp10-r0", FPU_ARCH_VFP_V1},
10896 {"vfpxd", FPU_ARCH_VFP_V1xD},
10897 {"arm1020t", FPU_ARCH_VFP_V1},
10898 {"arm1020e", FPU_ARCH_VFP_V2},
10902 struct arm_long_option_table
10904 char *option; /* Substring to match. */
10905 char *help; /* Help information. */
10906 int (*func) PARAMS ((char *subopt)); /* Function to decode sub-option. */
10907 char *deprecated; /* If non-null, print this message. */
10911 arm_parse_extension (str, opt_p)
10915 while (str != NULL && *str != 0)
10917 struct arm_arch_extension_table *opt;
10923 as_bad (_("invalid architectural extension"));
10928 ext = strchr (str, '+');
10931 optlen = ext - str;
10933 optlen = strlen (str);
10937 as_bad (_("missing architectural extension"));
10941 for (opt = arm_extensions; opt->name != NULL; opt++)
10942 if (strncmp (opt->name, str, optlen) == 0)
10944 *opt_p |= opt->value;
10948 if (opt->name == NULL)
10950 as_bad (_("unknown architectural extnsion `%s'"), str);
10961 arm_parse_cpu (str)
10964 struct arm_cpu_option_table *opt;
10965 char *ext = strchr (str, '+');
10969 optlen = ext - str;
10971 optlen = strlen (str);
10975 as_bad (_("missing cpu name `%s'"), str);
10979 for (opt = arm_cpus; opt->name != NULL; opt++)
10980 if (strncmp (opt->name, str, optlen) == 0)
10982 mcpu_cpu_opt = opt->value;
10983 mcpu_fpu_opt = opt->default_fpu;
10986 return arm_parse_extension (ext, &mcpu_cpu_opt);
10991 as_bad (_("unknown cpu `%s'"), str);
10996 arm_parse_arch (str)
10999 struct arm_arch_option_table *opt;
11000 char *ext = strchr (str, '+');
11004 optlen = ext - str;
11006 optlen = strlen (str);
11010 as_bad (_("missing architecture name `%s'"), str);
11015 for (opt = arm_archs; opt->name != NULL; opt++)
11016 if (strcmp (opt->name, str) == 0)
11018 march_cpu_opt = opt->value;
11019 march_fpu_opt = opt->default_fpu;
11022 return arm_parse_extension (ext, &march_cpu_opt);
11027 as_bad (_("unknown architecture `%s'\n"), str);
11032 arm_parse_fpu (str)
11035 struct arm_fpu_option_table *opt;
11037 for (opt = arm_fpus; opt->name != NULL; opt++)
11038 if (strcmp (opt->name, str) == 0)
11040 mfpu_opt = opt->value;
11044 as_bad (_("unknown floating point format `%s'\n"), str);
11048 struct arm_long_option_table arm_long_opts[] =
11050 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
11051 arm_parse_cpu, NULL},
11052 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
11053 arm_parse_arch, NULL},
11054 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
11055 arm_parse_fpu, NULL},
11056 {NULL, NULL, 0, NULL}
11060 md_parse_option (c, arg)
11064 struct arm_option_table *opt;
11065 struct arm_long_option_table *lopt;
11071 target_big_endian = 1;
11077 target_big_endian = 0;
11082 /* Listing option. Just ignore these, we don't support additional
11087 for (opt = arm_opts; opt->option != NULL; opt++)
11089 if (c == opt->option[0]
11090 && ((arg == NULL && opt->option[1] == 0)
11091 || strcmp (arg, opt->option + 1) == 0))
11093 #if WARN_DEPRECATED
11094 /* If the option is deprecated, tell the user. */
11095 if (opt->deprecated != NULL)
11096 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
11097 arg ? arg : "", _(opt->deprecated));
11100 if (opt->var != NULL)
11101 *opt->var = opt->value;
11107 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
11109 /* These options are expected to have an argument. */
11110 if (c == lopt->option[0]
11112 && strncmp (arg, lopt->option + 1,
11113 strlen (lopt->option + 1)) == 0)
11115 #if WARN_DEPRECATED
11116 /* If the option is deprecated, tell the user. */
11117 if (lopt->deprecated != NULL)
11118 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
11119 _(lopt->deprecated));
11122 /* Call the sup-option parser. */
11123 return (*lopt->func)(arg + strlen (lopt->option) - 1);
11127 as_bad (_("unrecognized option `-%c%s'"), c, arg ? arg : "");
11138 struct arm_option_table *opt;
11139 struct arm_long_option_table *lopt;
11141 fprintf (fp, _(" ARM-specific assembler options:\n"));
11143 for (opt = arm_opts; opt->option != NULL; opt++)
11144 if (opt->help != NULL)
11145 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
11147 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
11148 if (lopt->help != NULL)
11149 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
11153 -EB assemble code for a big-endian cpu\n"));
11158 -EL assemble code for a little-endian cpu\n"));
11162 /* We need to be able to fix up arbitrary expressions in some statements.
11163 This is so that we can handle symbols that are an arbitrary distance from
11164 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
11165 which returns part of an address in a form which will be valid for
11166 a data instruction. We do this by pushing the expression into a symbol
11167 in the expr_section, and creating a fix for that. */
11170 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
11179 arm_fix_data * arm_data;
11187 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
11191 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
11196 /* Mark whether the fix is to a THUMB instruction, or an ARM
11198 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
11199 new_fix->tc_fix_data = (PTR) arm_data;
11200 arm_data->thumb_mode = thumb_mode;
11205 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
11208 cons_fix_new_arm (frag, where, size, exp)
11214 bfd_reloc_code_real_type type;
11218 FIXME: @@ Should look at CPU word size. */
11222 type = BFD_RELOC_8;
11225 type = BFD_RELOC_16;
11229 type = BFD_RELOC_32;
11232 type = BFD_RELOC_64;
11236 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
11239 /* A good place to do this, although this was probably not intended
11240 for this kind of use. We need to dump the literal pool before
11241 references are made to a null symbol pointer. */
11246 literal_pool * pool;
11248 for (pool = list_of_pools; pool; pool = pool->next)
11250 /* Put it at the end of the relevent section. */
11251 subseg_set (pool->section, pool->sub_section);
11257 arm_start_line_hook ()
11259 last_label_seen = NULL;
11263 arm_frob_label (sym)
11266 last_label_seen = sym;
11268 ARM_SET_THUMB (sym, thumb_mode);
11270 #if defined OBJ_COFF || defined OBJ_ELF
11271 ARM_SET_INTERWORK (sym, support_interwork);
11274 /* Note - do not allow local symbols (.Lxxx) to be labeled
11275 as Thumb functions. This is because these labels, whilst
11276 they exist inside Thumb code, are not the entry points for
11277 possible ARM->Thumb calls. Also, these labels can be used
11278 as part of a computed goto or switch statement. eg gcc
11279 can generate code that looks like this:
11281 ldr r2, [pc, .Laaa]
11291 The first instruction loads the address of the jump table.
11292 The second instruction converts a table index into a byte offset.
11293 The third instruction gets the jump address out of the table.
11294 The fourth instruction performs the jump.
11296 If the address stored at .Laaa is that of a symbol which has the
11297 Thumb_Func bit set, then the linker will arrange for this address
11298 to have the bottom bit set, which in turn would mean that the
11299 address computation performed by the third instruction would end
11300 up with the bottom bit set. Since the ARM is capable of unaligned
11301 word loads, the instruction would then load the incorrect address
11302 out of the jump table, and chaos would ensue. */
11303 if (label_is_thumb_function_name
11304 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
11305 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
11307 /* When the address of a Thumb function is taken the bottom
11308 bit of that address should be set. This will allow
11309 interworking between Arm and Thumb functions to work
11312 THUMB_SET_FUNC (sym, 1);
11314 label_is_thumb_function_name = FALSE;
11318 /* Adjust the symbol table. This marks Thumb symbols as distinct from
11322 arm_adjust_symtab ()
11327 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
11329 if (ARM_IS_THUMB (sym))
11331 if (THUMB_IS_FUNC (sym))
11333 /* Mark the symbol as a Thumb function. */
11334 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
11335 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
11336 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
11338 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
11339 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
11341 as_bad (_("%s: unexpected function type: %d"),
11342 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
11344 else switch (S_GET_STORAGE_CLASS (sym))
11347 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
11350 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
11353 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
11361 if (ARM_IS_INTERWORK (sym))
11362 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
11369 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
11371 if (ARM_IS_THUMB (sym))
11373 elf_symbol_type * elf_sym;
11375 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
11376 bind = ELF_ST_BIND (elf_sym);
11378 /* If it's a .thumb_func, declare it as so,
11379 otherwise tag label as .code 16. */
11380 if (THUMB_IS_FUNC (sym))
11381 elf_sym->internal_elf_sym.st_info =
11382 ELF_ST_INFO (bind, STT_ARM_TFUNC);
11384 elf_sym->internal_elf_sym.st_info =
11385 ELF_ST_INFO (bind, STT_ARM_16BIT);
11392 arm_data_in_code ()
11394 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
11396 *input_line_pointer = '/';
11397 input_line_pointer += 5;
11398 *input_line_pointer = 0;
11406 arm_canonicalize_symbol_name (name)
11411 if (thumb_mode && (len = strlen (name)) > 5
11412 && streq (name + len - 5, "/data"))
11413 *(name + len - 5) = 0;
11419 arm_validate_fix (fixP)
11422 /* If the destination of the branch is a defined symbol which does not have
11423 the THUMB_FUNC attribute, then we must be calling a function which has
11424 the (interfacearm) attribute. We look for the Thumb entry point to that
11425 function and change the branch to refer to that function instead. */
11426 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
11427 && fixP->fx_addsy != NULL
11428 && S_IS_DEFINED (fixP->fx_addsy)
11429 && ! THUMB_IS_FUNC (fixP->fx_addsy))
11431 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
11436 arm_force_relocation (fixp)
11439 #if defined (OBJ_COFF) && defined (TE_PE)
11440 if (fixp->fx_r_type == BFD_RELOC_RVA)
11444 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
11445 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
11446 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
11447 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
11448 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
11449 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
11453 /* Resolve these relocations even if the symbol is extern or weak. */
11454 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
11455 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
11458 return S_FORCE_RELOC (fixp->fx_addsy);
11462 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
11463 local labels from being added to the output symbol table when they
11464 are used with the ADRL pseudo op. The ADRL relocation should always
11465 be resolved before the binbary is emitted, so it is safe to say that
11466 it is adjustable. */
11469 arm_fix_adjustable (fixP)
11472 if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
11479 /* Relocations against Thumb function names must be left unadjusted,
11480 so that the linker can use this information to correctly set the
11481 bottom bit of their addresses. The MIPS version of this function
11482 also prevents relocations that are mips-16 specific, but I do not
11483 know why it does this.
11486 There is one other problem that ought to be addressed here, but
11487 which currently is not: Taking the address of a label (rather
11488 than a function) and then later jumping to that address. Such
11489 addresses also ought to have their bottom bit set (assuming that
11490 they reside in Thumb code), but at the moment they will not. */
11493 arm_fix_adjustable (fixP)
11496 if (fixP->fx_addsy == NULL)
11499 if (THUMB_IS_FUNC (fixP->fx_addsy)
11500 && fixP->fx_subsy == NULL)
11503 /* We need the symbol name for the VTABLE entries. */
11504 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
11505 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
11508 /* Don't allow symbols to be discarded on GOT related relocs. */
11509 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
11510 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
11511 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF)
11518 elf32_arm_target_format ()
11520 if (target_big_endian)
11523 return "elf32-bigarm-oabi";
11525 return "elf32-bigarm";
11530 return "elf32-littlearm-oabi";
11532 return "elf32-littlearm";
11537 armelf_frob_symbol (symp, puntp)
11541 elf_frob_symbol (symp, puntp);
11544 static bfd_reloc_code_real_type
11554 bfd_reloc_code_real_type reloc;
11558 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
11559 MAP ("(got)", BFD_RELOC_ARM_GOT32),
11560 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
11561 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
11562 branch instructions generated by GCC for PLT relocs. */
11563 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
11564 { NULL, 0, BFD_RELOC_UNUSED }
11568 for (i = 0, ip = input_line_pointer;
11569 i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
11571 id[i] = TOLOWER (*ip);
11573 for (i = 0; reloc_map[i].str; i++)
11574 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
11577 input_line_pointer += reloc_map[i].len;
11579 return reloc_map[i].reloc;
11583 s_arm_elf_cons (nbytes)
11588 #ifdef md_flush_pending_output
11589 md_flush_pending_output ();
11592 if (is_it_end_of_statement ())
11594 demand_empty_rest_of_line ();
11598 #ifdef md_cons_align
11599 md_cons_align (nbytes);
11604 bfd_reloc_code_real_type reloc;
11606 expression (& exp);
11608 if (exp.X_op == O_symbol
11609 && * input_line_pointer == '('
11610 && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
11612 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
11613 int size = bfd_get_reloc_size (howto);
11616 as_bad ("%s relocations do not fit in %d bytes",
11617 howto->name, nbytes);
11620 register char *p = frag_more ((int) nbytes);
11621 int offset = nbytes - size;
11623 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
11628 emit_expr (&exp, (unsigned int) nbytes);
11630 while (*input_line_pointer++ == ',');
11632 /* Put terminator back into stream. */
11633 input_line_pointer --;
11634 demand_empty_rest_of_line ();
11637 #endif /* OBJ_ELF */
11639 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
11640 of an rs_align_code fragment. */
11643 arm_handle_align (fragP)
11646 static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
11647 static char const thumb_noop[2] = { 0xc0, 0x46 };
11648 static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
11649 static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
11651 int bytes, fix, noop_size;
11655 if (fragP->fr_type != rs_align_code)
11658 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
11659 p = fragP->fr_literal + fragP->fr_fix;
11662 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
11663 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
11665 if (fragP->tc_frag_data)
11667 if (target_big_endian)
11668 noop = thumb_bigend_noop;
11671 noop_size = sizeof (thumb_noop);
11675 if (target_big_endian)
11676 noop = arm_bigend_noop;
11679 noop_size = sizeof (arm_noop);
11682 if (bytes & (noop_size - 1))
11684 fix = bytes & (noop_size - 1);
11685 memset (p, 0, fix);
11690 while (bytes >= noop_size)
11692 memcpy (p, noop, noop_size);
11694 bytes -= noop_size;
11698 fragP->fr_fix += fix;
11699 fragP->fr_var = noop_size;
11702 /* Called from md_do_align. Used to create an alignment
11703 frag in a code section. */
11706 arm_frag_align_code (n, max)
11712 /* We assume that there will never be a requirment
11713 to support alignments greater than 32 bytes. */
11714 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
11715 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
11717 p = frag_var (rs_align_code,
11718 MAX_MEM_FOR_RS_ALIGN_CODE,
11720 (relax_substateT) max,
11728 /* Perform target specific initialisation of a frag. */
11731 arm_init_frag (fragP)
11734 /* Record whether this frag is in an ARM or a THUMB area. */
11735 fragP->tc_frag_data = thumb_mode;