1 /* tc-arm.c -- Assemble for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modified by David Taylor (dtaylor@armltd.co.uk)
6 Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
8 This file is part of GAS, the GNU Assembler.
10 GAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
15 GAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with GAS; see the file COPYING. If not, write to the Free
22 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
28 #include "safe-ctype.h"
30 /* Need TARGET_CPU. */
39 #include "dwarf2dbg.h"
42 /* The following bitmasks control CPU extensions: */
43 #define ARM_EXT_V1 0x00000001 /* All processors (core set). */
44 #define ARM_EXT_V2 0x00000002 /* Multiply instructions. */
45 #define ARM_EXT_V2S 0x00000004 /* SWP instructions. */
46 #define ARM_EXT_V3 0x00000008 /* MSR MRS. */
47 #define ARM_EXT_V3M 0x00000010 /* Allow long multiplies. */
48 #define ARM_EXT_V4 0x00000020 /* Allow half word loads. */
49 #define ARM_EXT_V4T 0x00000040 /* Thumb v1. */
50 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
51 #define ARM_EXT_V5T 0x00000100 /* Thumb v2. */
52 #define ARM_EXT_V5ExP 0x00000200 /* DSP core set. */
53 #define ARM_EXT_V5E 0x00000400 /* DSP Double transfers. */
54 /* Processor specific extensions. */
55 #define ARM_EXT_XSCALE 0x00000800 /* Allow MIA etc. */
56 #define ARM_EXT_MAVERICK 0x00001000 /* Use Cirrus/DSP coprocessor. */
58 /* Architectures are the sum of the base and extensions. The ARM ARM (rev E)
59 defines the following: ARMv3, ARMv3M, ARMv4xM, ARMv4, ARMv4TxM, ARMv4T,
60 ARMv5xM, ARMv5, ARMv5TxM, ARMv5T, ARMv5TExP, ARMv5TE. To these we add
61 three more to cover cores prior to ARM6. Finally, there are cores which
62 implement further extensions in the co-processor space. */
63 #define ARM_ARCH_V1 ARM_EXT_V1
64 #define ARM_ARCH_V2 (ARM_ARCH_V1 | ARM_EXT_V2)
65 #define ARM_ARCH_V2S (ARM_ARCH_V2 | ARM_EXT_V2S)
66 #define ARM_ARCH_V3 (ARM_ARCH_V2S | ARM_EXT_V3)
67 #define ARM_ARCH_V3M (ARM_ARCH_V3 | ARM_EXT_V3M)
68 #define ARM_ARCH_V4xM (ARM_ARCH_V3 | ARM_EXT_V4)
69 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_V4)
70 #define ARM_ARCH_V4TxM (ARM_ARCH_V4xM | ARM_EXT_V4T)
71 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_V4T)
72 #define ARM_ARCH_V5xM (ARM_ARCH_V4xM | ARM_EXT_V5)
73 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
74 #define ARM_ARCH_V5TxM (ARM_ARCH_V5xM | ARM_EXT_V4T | ARM_EXT_V5T)
75 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_V4T | ARM_EXT_V5T)
76 #define ARM_ARCH_V5TExP (ARM_ARCH_V5T | ARM_EXT_V5ExP)
77 #define ARM_ARCH_V5TE (ARM_ARCH_V5TExP | ARM_EXT_V5E)
78 /* Processors with specific extensions in the co-processor space. */
79 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_EXT_XSCALE)
81 /* Some useful combinations: */
82 #define ARM_ANY 0x00ffffff
83 #define ARM_2UP (ARM_ANY - ARM_1)
84 #define ARM_ALL ARM_ANY
86 #define FPU_FPA_EXT_V1 0x80000000 /* Base FPA instruction set. */
87 #define FPU_FPA_EXT_V2 0x40000000 /* LFM/SFM. */
90 #define FPU_ARCH_FPE FPU_FPA_EXT_V1
91 #define FPU_ARCH_FPA (FPU_ARCH_FPE | FPU_FPA_EXT_V2)
93 /* Some useful combinations. */
94 #define FPU_ANY 0xff000000 /* Note this is ~ARM_ANY. */
96 /* Types of processor to assemble for. */
97 #define ARM_1 ARM_ARCH_V1
98 #define ARM_2 ARM_ARCH_V2
99 #define ARM_3 ARM_ARCH_V2S
100 #define ARM_250 ARM_ARCH_V2S
101 #define ARM_6 ARM_ARCH_V3
102 #define ARM_7 ARM_ARCH_V3
103 #define ARM_8 ARM_ARCH_V4
104 #define ARM_9 ARM_ARCH_V4T
105 #define ARM_STRONG ARM_ARCH_V4
106 #define ARM_CPU_MASK 0x0000000f /* XXX? */
109 #if defined __XSCALE__
110 #define CPU_DEFAULT (ARM_ARCH_XSCALE)
112 #if defined __thumb__
113 #define CPU_DEFAULT (ARM_ARCH_V5T)
115 #define CPU_DEFAULT ARM_ALL
121 #define FPU_DEFAULT FPU_ARCH_FPA
124 #define streq(a, b) (strcmp (a, b) == 0)
125 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
127 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
128 static int target_oabi
= 0;
130 #if defined OBJ_COFF || defined OBJ_ELF
131 /* Flags stored in private area of BFD structure. */
132 static boolean uses_apcs_26
= false;
133 static boolean atpcs
= false;
134 static boolean support_interwork
= false;
135 static boolean uses_apcs_float
= false;
136 static boolean pic_code
= false;
139 /* This array holds the chars that always start a comment. If the
140 pre-processor is disabled, these aren't very useful. */
141 const char comment_chars
[] = "@";
143 /* This array holds the chars that only start a comment at the beginning of
144 a line. If the line seems to have the form '# 123 filename'
145 .line and .file directives will appear in the pre-processed output. */
146 /* Note that input_file.c hand checks for '#' at the beginning of the
147 first line of the input file. This is because the compiler outputs
148 #NO_APP at the beginning of its output. */
149 /* Also note that comments like this one will always work. */
150 const char line_comment_chars
[] = "#";
152 const char line_separator_chars
[] = ";";
154 /* Chars that can be used to separate mant
155 from exp in floating point numbers. */
156 const char EXP_CHARS
[] = "eE";
158 /* Chars that mean this number is a floating point constant. */
162 const char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
164 /* Prefix characters that indicate the start of an immediate
166 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
169 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
170 symbolS
* GOT_symbol
;
173 /* Size of relocation record. */
174 const int md_reloc_size
= 8;
176 /* 0: assemble for ARM,
177 1: assemble for Thumb,
178 2: assemble for Thumb even though target CPU does not support thumb
180 static int thumb_mode
= 0;
182 typedef struct arm_fix
190 unsigned long instruction
;
195 bfd_reloc_code_real_type type
;
212 struct asm_shift_properties
214 enum asm_shift_index index
;
215 unsigned long bit_field
;
216 unsigned int allows_0
: 1;
217 unsigned int allows_32
: 1;
220 static const struct asm_shift_properties shift_properties
[] =
222 { SHIFT_LSL
, 0, 1, 0},
223 { SHIFT_LSR
, 0x20, 0, 1},
224 { SHIFT_ASR
, 0x40, 0, 1},
225 { SHIFT_ROR
, 0x60, 0, 0},
226 { SHIFT_RRX
, 0x60, 0, 0}
229 struct asm_shift_name
232 const struct asm_shift_properties
* properties
;
235 static const struct asm_shift_name shift_names
[] =
237 { "asl", shift_properties
+ SHIFT_LSL
},
238 { "lsl", shift_properties
+ SHIFT_LSL
},
239 { "lsr", shift_properties
+ SHIFT_LSR
},
240 { "asr", shift_properties
+ SHIFT_ASR
},
241 { "ror", shift_properties
+ SHIFT_ROR
},
242 { "rrx", shift_properties
+ SHIFT_RRX
},
243 { "ASL", shift_properties
+ SHIFT_LSL
},
244 { "LSL", shift_properties
+ SHIFT_LSL
},
245 { "LSR", shift_properties
+ SHIFT_LSR
},
246 { "ASR", shift_properties
+ SHIFT_ASR
},
247 { "ROR", shift_properties
+ SHIFT_ROR
},
248 { "RRX", shift_properties
+ SHIFT_RRX
}
251 #define NO_SHIFT_RESTRICT 1
252 #define SHIFT_RESTRICT 0
254 #define NUM_FLOAT_VALS 8
256 const char * fp_const
[] =
258 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
261 /* Number of littlenums required to hold an extended precision number. */
262 #define MAX_LITTLENUMS 6
264 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
274 #define CP_T_X 0x00008000
275 #define CP_T_Y 0x00400000
276 #define CP_T_Pre 0x01000000
277 #define CP_T_UD 0x00800000
278 #define CP_T_WB 0x00200000
280 #define CONDS_BIT 0x00100000
281 #define LOAD_BIT 0x00100000
282 #define TRANS_BIT 0x00200000
284 #define DOUBLE_LOAD_FLAG 0x00000001
288 const char * template;
292 /* This is to save a hash look-up in the common case. */
293 #define COND_ALWAYS 0xe0000000
295 static const struct asm_cond conds
[] =
299 {"cs", 0x20000000}, {"hs", 0x20000000},
300 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
315 /* Warning: If the top bit of the set_bits is set, then the standard
316 instruction bitmask is ignored, and the new bitmask is taken from
320 const char * template; /* Basic flag string. */
321 unsigned long set_bits
; /* Bits to set. */
324 static const struct asm_flg s_flag
[] =
330 static const struct asm_flg ldr_flags
[] =
332 {"d", DOUBLE_LOAD_FLAG
},
335 {"bt", 0x00400000 | TRANS_BIT
},
342 static const struct asm_flg str_flags
[] =
344 {"d", DOUBLE_LOAD_FLAG
},
347 {"bt", 0x00400000 | TRANS_BIT
},
352 static const struct asm_flg byte_flag
[] =
358 static const struct asm_flg cmp_flags
[] =
365 static const struct asm_flg ldm_flags
[] =
378 static const struct asm_flg stm_flags
[] =
391 static const struct asm_flg lfm_flags
[] =
398 static const struct asm_flg sfm_flags
[] =
405 static const struct asm_flg round_flags
[] =
413 /* The implementation of the FIX instruction is broken on some assemblers,
414 in that it accepts a precision specifier as well as a rounding specifier,
415 despite the fact that this is meaningless. To be more compatible, we
416 accept it as well, though of course it does not set any bits. */
417 static const struct asm_flg fix_flags
[] =
434 static const struct asm_flg except_flag
[] =
440 static const struct asm_flg long_flag
[] =
448 const char * template;
453 /* The bit that distnguishes CPSR and SPSR. */
454 #define SPSR_BIT (1 << 22)
456 /* How many bits to shift the PSR_xxx bits up by. */
459 #define PSR_c (1 << 0)
460 #define PSR_x (1 << 1)
461 #define PSR_s (1 << 2)
462 #define PSR_f (1 << 3)
464 static const struct asm_psr psrs
[] =
466 {"CPSR", true, PSR_c
| PSR_f
},
467 {"CPSR_all", true, PSR_c
| PSR_f
},
468 {"SPSR", false, PSR_c
| PSR_f
},
469 {"SPSR_all", false, PSR_c
| PSR_f
},
470 {"CPSR_flg", true, PSR_f
},
471 {"CPSR_f", true, PSR_f
},
472 {"SPSR_flg", false, PSR_f
},
473 {"SPSR_f", false, PSR_f
},
474 {"CPSR_c", true, PSR_c
},
475 {"CPSR_ctl", true, PSR_c
},
476 {"SPSR_c", false, PSR_c
},
477 {"SPSR_ctl", false, PSR_c
},
478 {"CPSR_x", true, PSR_x
},
479 {"CPSR_s", true, PSR_s
},
480 {"SPSR_x", false, PSR_x
},
481 {"SPSR_s", false, PSR_s
},
482 /* Combinations of flags. */
483 {"CPSR_fs", true, PSR_f
| PSR_s
},
484 {"CPSR_fx", true, PSR_f
| PSR_x
},
485 {"CPSR_fc", true, PSR_f
| PSR_c
},
486 {"CPSR_sf", true, PSR_s
| PSR_f
},
487 {"CPSR_sx", true, PSR_s
| PSR_x
},
488 {"CPSR_sc", true, PSR_s
| PSR_c
},
489 {"CPSR_xf", true, PSR_x
| PSR_f
},
490 {"CPSR_xs", true, PSR_x
| PSR_s
},
491 {"CPSR_xc", true, PSR_x
| PSR_c
},
492 {"CPSR_cf", true, PSR_c
| PSR_f
},
493 {"CPSR_cs", true, PSR_c
| PSR_s
},
494 {"CPSR_cx", true, PSR_c
| PSR_x
},
495 {"CPSR_fsx", true, PSR_f
| PSR_s
| PSR_x
},
496 {"CPSR_fsc", true, PSR_f
| PSR_s
| PSR_c
},
497 {"CPSR_fxs", true, PSR_f
| PSR_x
| PSR_s
},
498 {"CPSR_fxc", true, PSR_f
| PSR_x
| PSR_c
},
499 {"CPSR_fcs", true, PSR_f
| PSR_c
| PSR_s
},
500 {"CPSR_fcx", true, PSR_f
| PSR_c
| PSR_x
},
501 {"CPSR_sfx", true, PSR_s
| PSR_f
| PSR_x
},
502 {"CPSR_sfc", true, PSR_s
| PSR_f
| PSR_c
},
503 {"CPSR_sxf", true, PSR_s
| PSR_x
| PSR_f
},
504 {"CPSR_sxc", true, PSR_s
| PSR_x
| PSR_c
},
505 {"CPSR_scf", true, PSR_s
| PSR_c
| PSR_f
},
506 {"CPSR_scx", true, PSR_s
| PSR_c
| PSR_x
},
507 {"CPSR_xfs", true, PSR_x
| PSR_f
| PSR_s
},
508 {"CPSR_xfc", true, PSR_x
| PSR_f
| PSR_c
},
509 {"CPSR_xsf", true, PSR_x
| PSR_s
| PSR_f
},
510 {"CPSR_xsc", true, PSR_x
| PSR_s
| PSR_c
},
511 {"CPSR_xcf", true, PSR_x
| PSR_c
| PSR_f
},
512 {"CPSR_xcs", true, PSR_x
| PSR_c
| PSR_s
},
513 {"CPSR_cfs", true, PSR_c
| PSR_f
| PSR_s
},
514 {"CPSR_cfx", true, PSR_c
| PSR_f
| PSR_x
},
515 {"CPSR_csf", true, PSR_c
| PSR_s
| PSR_f
},
516 {"CPSR_csx", true, PSR_c
| PSR_s
| PSR_x
},
517 {"CPSR_cxf", true, PSR_c
| PSR_x
| PSR_f
},
518 {"CPSR_cxs", true, PSR_c
| PSR_x
| PSR_s
},
519 {"CPSR_fsxc", true, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
520 {"CPSR_fscx", true, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
521 {"CPSR_fxsc", true, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
522 {"CPSR_fxcs", true, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
523 {"CPSR_fcsx", true, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
524 {"CPSR_fcxs", true, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
525 {"CPSR_sfxc", true, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
526 {"CPSR_sfcx", true, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
527 {"CPSR_sxfc", true, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
528 {"CPSR_sxcf", true, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
529 {"CPSR_scfx", true, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
530 {"CPSR_scxf", true, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
531 {"CPSR_xfsc", true, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
532 {"CPSR_xfcs", true, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
533 {"CPSR_xsfc", true, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
534 {"CPSR_xscf", true, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
535 {"CPSR_xcfs", true, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
536 {"CPSR_xcsf", true, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
537 {"CPSR_cfsx", true, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
538 {"CPSR_cfxs", true, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
539 {"CPSR_csfx", true, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
540 {"CPSR_csxf", true, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
541 {"CPSR_cxfs", true, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
542 {"CPSR_cxsf", true, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
543 {"SPSR_fs", false, PSR_f
| PSR_s
},
544 {"SPSR_fx", false, PSR_f
| PSR_x
},
545 {"SPSR_fc", false, PSR_f
| PSR_c
},
546 {"SPSR_sf", false, PSR_s
| PSR_f
},
547 {"SPSR_sx", false, PSR_s
| PSR_x
},
548 {"SPSR_sc", false, PSR_s
| PSR_c
},
549 {"SPSR_xf", false, PSR_x
| PSR_f
},
550 {"SPSR_xs", false, PSR_x
| PSR_s
},
551 {"SPSR_xc", false, PSR_x
| PSR_c
},
552 {"SPSR_cf", false, PSR_c
| PSR_f
},
553 {"SPSR_cs", false, PSR_c
| PSR_s
},
554 {"SPSR_cx", false, PSR_c
| PSR_x
},
555 {"SPSR_fsx", false, PSR_f
| PSR_s
| PSR_x
},
556 {"SPSR_fsc", false, PSR_f
| PSR_s
| PSR_c
},
557 {"SPSR_fxs", false, PSR_f
| PSR_x
| PSR_s
},
558 {"SPSR_fxc", false, PSR_f
| PSR_x
| PSR_c
},
559 {"SPSR_fcs", false, PSR_f
| PSR_c
| PSR_s
},
560 {"SPSR_fcx", false, PSR_f
| PSR_c
| PSR_x
},
561 {"SPSR_sfx", false, PSR_s
| PSR_f
| PSR_x
},
562 {"SPSR_sfc", false, PSR_s
| PSR_f
| PSR_c
},
563 {"SPSR_sxf", false, PSR_s
| PSR_x
| PSR_f
},
564 {"SPSR_sxc", false, PSR_s
| PSR_x
| PSR_c
},
565 {"SPSR_scf", false, PSR_s
| PSR_c
| PSR_f
},
566 {"SPSR_scx", false, PSR_s
| PSR_c
| PSR_x
},
567 {"SPSR_xfs", false, PSR_x
| PSR_f
| PSR_s
},
568 {"SPSR_xfc", false, PSR_x
| PSR_f
| PSR_c
},
569 {"SPSR_xsf", false, PSR_x
| PSR_s
| PSR_f
},
570 {"SPSR_xsc", false, PSR_x
| PSR_s
| PSR_c
},
571 {"SPSR_xcf", false, PSR_x
| PSR_c
| PSR_f
},
572 {"SPSR_xcs", false, PSR_x
| PSR_c
| PSR_s
},
573 {"SPSR_cfs", false, PSR_c
| PSR_f
| PSR_s
},
574 {"SPSR_cfx", false, PSR_c
| PSR_f
| PSR_x
},
575 {"SPSR_csf", false, PSR_c
| PSR_s
| PSR_f
},
576 {"SPSR_csx", false, PSR_c
| PSR_s
| PSR_x
},
577 {"SPSR_cxf", false, PSR_c
| PSR_x
| PSR_f
},
578 {"SPSR_cxs", false, PSR_c
| PSR_x
| PSR_s
},
579 {"SPSR_fsxc", false, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
580 {"SPSR_fscx", false, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
581 {"SPSR_fxsc", false, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
582 {"SPSR_fxcs", false, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
583 {"SPSR_fcsx", false, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
584 {"SPSR_fcxs", false, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
585 {"SPSR_sfxc", false, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
586 {"SPSR_sfcx", false, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
587 {"SPSR_sxfc", false, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
588 {"SPSR_sxcf", false, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
589 {"SPSR_scfx", false, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
590 {"SPSR_scxf", false, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
591 {"SPSR_xfsc", false, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
592 {"SPSR_xfcs", false, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
593 {"SPSR_xsfc", false, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
594 {"SPSR_xscf", false, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
595 {"SPSR_xcfs", false, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
596 {"SPSR_xcsf", false, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
597 {"SPSR_cfsx", false, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
598 {"SPSR_cfxs", false, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
599 {"SPSR_csfx", false, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
600 {"SPSR_csxf", false, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
601 {"SPSR_cxfs", false, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
602 {"SPSR_cxsf", false, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
607 CIRRUS_REGTYPE_MVF
= 1,
608 CIRRUS_REGTYPE_MVFX
= 2,
609 CIRRUS_REGTYPE_MVD
= 3,
610 CIRRUS_REGTYPE_MVDX
= 4,
611 CIRRUS_REGTYPE_MVAX
= 5,
612 CIRRUS_REGTYPE_DSPSC
= 6,
613 CIRRUS_REGTYPE_ANY
= 7
616 /* Functions called by parser. */
617 /* ARM instructions. */
618 static void do_arit
PARAMS ((char *, unsigned long));
619 static void do_cmp
PARAMS ((char *, unsigned long));
620 static void do_mov
PARAMS ((char *, unsigned long));
621 static void do_ldst
PARAMS ((char *, unsigned long));
622 static void do_ldmstm
PARAMS ((char *, unsigned long));
623 static void do_branch
PARAMS ((char *, unsigned long));
624 static void do_swi
PARAMS ((char *, unsigned long));
626 /* Pseudo Op codes. */
627 static void do_adr
PARAMS ((char *, unsigned long));
628 static void do_nop
PARAMS ((char *, unsigned long));
631 static void do_mul
PARAMS ((char *, unsigned long));
632 static void do_mla
PARAMS ((char *, unsigned long));
635 static void do_swap
PARAMS ((char *, unsigned long));
638 static void do_msr
PARAMS ((char *, unsigned long));
639 static void do_mrs
PARAMS ((char *, unsigned long));
642 static void do_mull
PARAMS ((char *, unsigned long));
645 static void do_bx
PARAMS ((char *, unsigned long));
648 static void do_blx
PARAMS ((char *, unsigned long));
649 static void do_bkpt
PARAMS ((char *, unsigned long));
650 static void do_clz
PARAMS ((char *, unsigned long));
651 static void do_lstc2
PARAMS ((char *, unsigned long));
652 static void do_cdp2
PARAMS ((char *, unsigned long));
653 static void do_co_reg2
PARAMS ((char *, unsigned long));
656 static void do_smla
PARAMS ((char *, unsigned long));
657 static void do_smlal
PARAMS ((char *, unsigned long));
658 static void do_smul
PARAMS ((char *, unsigned long));
659 static void do_qadd
PARAMS ((char *, unsigned long));
662 static void do_pld
PARAMS ((char *, unsigned long));
663 static void do_ldrd
PARAMS ((char *, unsigned long));
664 static void do_co_reg2c
PARAMS ((char *, unsigned long));
666 /* Coprocessor Instructions. */
667 static void do_cdp
PARAMS ((char *, unsigned long));
668 static void do_lstc
PARAMS ((char *, unsigned long));
669 static void do_co_reg
PARAMS ((char *, unsigned long));
671 /* FPA instructions. */
672 static void do_fpa_ctrl
PARAMS ((char *, unsigned long));
673 static void do_fpa_ldst
PARAMS ((char *, unsigned long));
674 static void do_fpa_ldmstm
PARAMS ((char *, unsigned long));
675 static void do_fpa_dyadic
PARAMS ((char *, unsigned long));
676 static void do_fpa_monadic
PARAMS ((char *, unsigned long));
677 static void do_fpa_cmp
PARAMS ((char *, unsigned long));
678 static void do_fpa_from_reg
PARAMS ((char *, unsigned long));
679 static void do_fpa_to_reg
PARAMS ((char *, unsigned long));
682 static void do_mia
PARAMS ((char *, unsigned long));
683 static void do_mar
PARAMS ((char *, unsigned long));
684 static void do_mra
PARAMS ((char *, unsigned long));
686 /* ARM_EXT_MAVERICK. */
687 static void do_c_binops
PARAMS ((char *, unsigned long, int));
688 static void do_c_binops_1
PARAMS ((char *, unsigned long));
689 static void do_c_binops_2
PARAMS ((char *, unsigned long));
690 static void do_c_binops_3
PARAMS ((char *, unsigned long));
691 static void do_c_triple
PARAMS ((char *, unsigned long, int));
692 static void do_c_triple_4
PARAMS ((char *, unsigned long));
693 static void do_c_triple_5
PARAMS ((char *, unsigned long));
694 static void do_c_quad
PARAMS ((char *, unsigned long, int));
695 static void do_c_quad_6
PARAMS ((char *, unsigned long));
696 static void do_c_dspsc
PARAMS ((char *, unsigned long, int));
697 static void do_c_dspsc_1
PARAMS ((char *, unsigned long));
698 static void do_c_dspsc_2
PARAMS ((char *, unsigned long));
699 static void do_c_shift
PARAMS ((char *, unsigned long, int));
700 static void do_c_shift_1
PARAMS ((char *, unsigned long));
701 static void do_c_shift_2
PARAMS ((char *, unsigned long));
702 static void do_c_ldst
PARAMS ((char *, unsigned long, int));
703 static void do_c_ldst_1
PARAMS ((char *, unsigned long));
704 static void do_c_ldst_2
PARAMS ((char *, unsigned long));
705 static void do_c_ldst_3
PARAMS ((char *, unsigned long));
706 static void do_c_ldst_4
PARAMS ((char *, unsigned long));
707 static int cirrus_reg_required_here
PARAMS ((char **, int, enum cirrus_regtype
));
708 static int cirrus_valid_reg
PARAMS ((int, enum cirrus_regtype
));
709 static int cirrus_parse_offset
PARAMS ((char **, int *));
711 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
712 static int arm_reg_parse
PARAMS ((char **));
713 static const struct asm_psr
* arm_psr_parse
PARAMS ((char **));
714 static void symbol_locate
PARAMS ((symbolS
*, const char *, segT
, valueT
, fragS
*));
715 static int add_to_lit_pool
PARAMS ((void));
716 static unsigned validate_immediate
PARAMS ((unsigned));
717 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
718 static int validate_offset_imm
PARAMS ((unsigned int, int));
719 static void opcode_select
PARAMS ((int));
720 static void end_of_line
PARAMS ((char *));
721 static int reg_required_here
PARAMS ((char **, int));
722 static int psr_required_here
PARAMS ((char **));
723 static int co_proc_number
PARAMS ((char **));
724 static int cp_opc_expr
PARAMS ((char **, int, int));
725 static int cp_reg_required_here
PARAMS ((char **, int));
726 static int fp_reg_required_here
PARAMS ((char **, int));
727 static int cp_address_offset
PARAMS ((char **));
728 static int cp_address_required_here
PARAMS ((char **));
729 static int my_get_float_expression
PARAMS ((char **));
730 static int skip_past_comma
PARAMS ((char **));
731 static int walk_no_bignums
PARAMS ((symbolS
*));
732 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
733 static int data_op2
PARAMS ((char **));
734 static int fp_op2
PARAMS ((char **));
735 static long reg_list
PARAMS ((char **));
736 static void thumb_load_store
PARAMS ((char *, int, int));
737 static int decode_shift
PARAMS ((char **, int));
738 static int ldst_extend
PARAMS ((char **, int));
739 static void thumb_add_sub
PARAMS ((char *, int));
740 static void insert_reg
PARAMS ((int));
741 static void thumb_shift
PARAMS ((char *, int));
742 static void thumb_mov_compare
PARAMS ((char *, int));
743 static void set_constant_flonums
PARAMS ((void));
744 static valueT md_chars_to_number
PARAMS ((char *, int));
745 static void insert_reg_alias
PARAMS ((char *, int));
746 static void output_inst
PARAMS ((void));
747 static int accum0_required_here
PARAMS ((char **));
748 static int ld_mode_required_here
PARAMS ((char **));
749 static void do_branch25
PARAMS ((char *, unsigned long));
750 static symbolS
* find_real_start
PARAMS ((symbolS
*));
752 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
755 /* ARM instructions take 4bytes in the object file, Thumb instructions
759 /* LONGEST_INST is the longest basic instruction name without
760 conditions or flags. ARM7M has 4 of length 5. El Segundo
761 has one basic instruction name of length 7 (SMLALxy). */
762 #define LONGEST_INST 10
764 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
765 #define CIRRUS_MODE1 0x100c
767 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
768 #define CIRRUS_MODE2 0x0c10
770 /* "INSN<cond> X,Y" where X:0, Y:bit16. */
771 #define CIRRUS_MODE3 0x1000
773 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
774 #define CIRRUS_MODE4 0x0c0010
776 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
777 #define CIRRUS_MODE5 0x00100c
779 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
780 #define CIRRUS_MODE6 0x00100c05
784 /* Basic string to match. */
785 const char * template;
787 /* Basic instruction code. */
790 /* Compulsory suffix that must follow conds. If "", then the
791 instruction is not conditional and must have no suffix. */
792 const char * comp_suffix
;
794 /* Bits to toggle if flag 'n' set. */
795 const struct asm_flg
* flags
;
797 /* Which CPU variants this exists for. */
798 unsigned long variants
;
800 /* Function to call to parse args. */
801 void (* parms
) PARAMS ((char *, unsigned long));
804 static const struct asm_opcode insns
[] =
806 /* XXX Temporary hack. Override the normal load/store entry points. */
807 {"ldr", 0x000000d0, NULL
, ldr_flags
, ARM_EXT_V1
, do_ldrd
},
808 {"str", 0x000000f0, NULL
, str_flags
, ARM_EXT_V1
, do_ldrd
},
810 /* Core ARM Instructions. */
811 {"and", 0x00000000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
812 {"eor", 0x00200000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
813 {"sub", 0x00400000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
814 {"rsb", 0x00600000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
815 {"add", 0x00800000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
816 {"adc", 0x00a00000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
817 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
818 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
819 {"orr", 0x01800000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
820 {"bic", 0x01c00000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
821 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_EXT_V1
, do_cmp
},
822 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_EXT_V1
, do_cmp
},
823 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_EXT_V1
, do_cmp
},
824 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_EXT_V1
, do_cmp
},
825 {"mov", 0x01a00000, NULL
, s_flag
, ARM_EXT_V1
, do_mov
},
826 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_EXT_V1
, do_mov
},
827 {"str", 0x04000000, NULL
, str_flags
, ARM_EXT_V1
, do_ldst
},
828 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_EXT_V1
, do_ldst
},
829 {"stm", 0x08000000, NULL
, stm_flags
, ARM_EXT_V1
, do_ldmstm
},
830 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_EXT_V1
, do_ldmstm
},
831 {"swi", 0x0f000000, NULL
, NULL
, ARM_EXT_V1
, do_swi
},
833 /* XXX This is the wrong place to do this. Think multi-arch. */
834 {"bl", 0x0b000000, NULL
, NULL
, ARM_EXT_V1
, do_branch
},
835 {"b", 0x0a000000, NULL
, NULL
, ARM_EXT_V1
, do_branch
},
837 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_EXT_V1
, do_branch
},
838 {"b", 0x0afffffe, NULL
, NULL
, ARM_EXT_V1
, do_branch
},
842 {"adr", 0x028f0000, NULL
, long_flag
, ARM_EXT_V1
, do_adr
},
843 {"nop", 0x01a00000, NULL
, NULL
, ARM_EXT_V1
, do_nop
},
845 /* ARM 2 multiplies. */
846 {"mul", 0x00000090, NULL
, s_flag
, ARM_EXT_V2
, do_mul
},
847 {"mla", 0x00200090, NULL
, s_flag
, ARM_EXT_V2
, do_mla
},
849 /* Generic copressor instructions. */
850 {"cdp", 0x0e000000, NULL
, NULL
, ARM_EXT_V2
, do_cdp
},
851 {"ldc", 0x0c100000, NULL
, long_flag
, ARM_EXT_V2
, do_lstc
},
852 {"stc", 0x0c000000, NULL
, long_flag
, ARM_EXT_V2
, do_lstc
},
853 {"mcr", 0x0e000010, NULL
, NULL
, ARM_EXT_V2
, do_co_reg
},
854 {"mrc", 0x0e100010, NULL
, NULL
, ARM_EXT_V2
, do_co_reg
},
856 /* ARM 3 - swp instructions. */
857 {"swp", 0x01000090, NULL
, byte_flag
, ARM_EXT_V2S
, do_swap
},
859 /* ARM 6 Status register instructions. */
860 {"mrs", 0x010f0000, NULL
, NULL
, ARM_EXT_V3
, do_mrs
},
861 {"msr", 0x0120f000, NULL
, NULL
, ARM_EXT_V3
, do_msr
},
862 /* ScottB: our code uses 0x0128f000 for msr.
863 NickC: but this is wrong because the bits 16 through 19 are
864 handled by the PSR_xxx defines above. */
866 /* ARM 7M long multiplies - need signed/unsigned flags! */
867 {"smull", 0x00c00090, NULL
, s_flag
, ARM_EXT_V3M
, do_mull
},
868 {"umull", 0x00800090, NULL
, s_flag
, ARM_EXT_V3M
, do_mull
},
869 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_EXT_V3M
, do_mull
},
870 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_EXT_V3M
, do_mull
},
872 /* ARM Architecture 4T. */
873 /* Note: bx (and blx) are required on V5, even if the processor does
874 not support Thumb. */
875 {"bx", 0x012fff10, NULL
, NULL
, ARM_EXT_V4T
| ARM_EXT_V5
, do_bx
},
877 /* ARM ISA extension 5. */
878 /* Note: blx is actually 2 opcodes, so the .value is set dynamically.
879 And it's sometimes conditional and sometimes not. */
880 {"blx", 0, NULL
, NULL
, ARM_EXT_V5
, do_blx
},
881 {"clz", 0x016f0f10, NULL
, NULL
, ARM_EXT_V5
, do_clz
},
882 {"bkpt", 0xe1200070, "", NULL
, ARM_EXT_V5
, do_bkpt
},
883 {"ldc2", 0xfc100000, "", long_flag
, ARM_EXT_V5
, do_lstc2
},
884 {"stc2", 0xfc000000, "", long_flag
, ARM_EXT_V5
, do_lstc2
},
885 {"cdp2", 0xfe000000, "", NULL
, ARM_EXT_V5
, do_cdp2
},
886 {"mcr2", 0xfe000010, "", NULL
, ARM_EXT_V5
, do_co_reg2
},
887 {"mrc2", 0xfe100010, "", NULL
, ARM_EXT_V5
, do_co_reg2
},
889 /* ARM Architecture 5ExP. */
890 {"smlabb", 0x01000080, NULL
, NULL
, ARM_EXT_V5ExP
, do_smla
},
891 {"smlatb", 0x010000a0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smla
},
892 {"smlabt", 0x010000c0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smla
},
893 {"smlatt", 0x010000e0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smla
},
895 {"smlawb", 0x01200080, NULL
, NULL
, ARM_EXT_V5ExP
, do_smla
},
896 {"smlawt", 0x012000c0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smla
},
898 {"smlalbb",0x01400080, NULL
, NULL
, ARM_EXT_V5ExP
, do_smlal
},
899 {"smlaltb",0x014000a0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smlal
},
900 {"smlalbt",0x014000c0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smlal
},
901 {"smlaltt",0x014000e0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smlal
},
903 {"smulbb", 0x01600080, NULL
, NULL
, ARM_EXT_V5ExP
, do_smul
},
904 {"smultb", 0x016000a0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smul
},
905 {"smulbt", 0x016000c0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smul
},
906 {"smultt", 0x016000e0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smul
},
908 {"smulwb", 0x012000a0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smul
},
909 {"smulwt", 0x012000e0, NULL
, NULL
, ARM_EXT_V5ExP
, do_smul
},
911 {"qadd", 0x01000050, NULL
, NULL
, ARM_EXT_V5ExP
, do_qadd
},
912 {"qdadd", 0x01400050, NULL
, NULL
, ARM_EXT_V5ExP
, do_qadd
},
913 {"qsub", 0x01200050, NULL
, NULL
, ARM_EXT_V5ExP
, do_qadd
},
914 {"qdsub", 0x01600050, NULL
, NULL
, ARM_EXT_V5ExP
, do_qadd
},
916 /* ARM Architecture 5E. */
917 {"pld", 0xf450f000, "", NULL
, ARM_EXT_V5E
, do_pld
},
918 {"ldr", 0x000000d0, NULL
, ldr_flags
, ARM_EXT_V5E
, do_ldrd
},
919 {"str", 0x000000f0, NULL
, str_flags
, ARM_EXT_V5E
, do_ldrd
},
920 {"mcrr", 0x0c400000, NULL
, NULL
, ARM_EXT_V5E
, do_co_reg2c
},
921 {"mrrc", 0x0c500000, NULL
, NULL
, ARM_EXT_V5E
, do_co_reg2c
},
923 /* Core FPA instruction set (V1). */
924 {"wfs", 0x0e200110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
925 {"rfs", 0x0e300110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
926 {"wfc", 0x0e400110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
927 {"rfc", 0x0e500110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fpa_ctrl
},
928 {"ldf", 0x0c100100, "sdep", NULL
, FPU_FPA_EXT_V1
, do_fpa_ldst
},
929 {"stf", 0x0c000100, "sdep", NULL
, FPU_FPA_EXT_V1
, do_fpa_ldst
},
930 {"mvf", 0x0e008100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
931 {"mnf", 0x0e108100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
932 {"abs", 0x0e208100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
933 {"rnd", 0x0e308100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
934 {"sqt", 0x0e408100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
935 {"log", 0x0e508100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
936 {"lgn", 0x0e608100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
937 {"exp", 0x0e708100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
938 {"sin", 0x0e808100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
939 {"cos", 0x0e908100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
940 {"tan", 0x0ea08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
941 {"asn", 0x0eb08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
942 {"acs", 0x0ec08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
943 {"atn", 0x0ed08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
944 {"urd", 0x0ee08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
945 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_monadic
},
946 {"adf", 0x0e000100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
947 {"suf", 0x0e200100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
948 {"rsf", 0x0e300100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
949 {"muf", 0x0e100100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
950 {"dvf", 0x0e400100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
951 {"rdf", 0x0e500100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
952 {"pow", 0x0e600100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
953 {"rpw", 0x0e700100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
954 {"rmf", 0x0e800100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
955 {"fml", 0x0e900100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
956 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
957 {"frd", 0x0eb00100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
958 {"pol", 0x0ec00100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_dyadic
},
959 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_FPA_EXT_V1
, do_fpa_cmp
},
960 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_FPA_EXT_V1
, do_fpa_cmp
},
961 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
962 be an optional suffix, but part of the instruction. To be compatible,
964 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fpa_cmp
},
965 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fpa_cmp
},
966 {"flt", 0x0e000110, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fpa_from_reg
},
967 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_FPA_EXT_V1
, do_fpa_to_reg
},
969 /* Instructions that were new with the real FPA, call them V2. */
970 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
971 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_FPA_EXT_V2
, do_fpa_ldmstm
},
973 /* Intel XScale extensions to ARM V5 ISA. (All use CP0). */
974 {"mia", 0x0e200010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
975 {"miaph", 0x0e280010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
976 {"miabb", 0x0e2c0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
977 {"miabt", 0x0e2d0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
978 {"miatb", 0x0e2e0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
979 {"miatt", 0x0e2f0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
980 {"mar", 0x0c400000, NULL
, NULL
, ARM_EXT_XSCALE
, do_mar
},
981 {"mra", 0x0c500000, NULL
, NULL
, ARM_EXT_XSCALE
, do_mra
},
983 /* Cirrus DSP instructions. */
984 {"cfldrs", 0x0c100400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_1
},
985 {"cfldrd", 0x0c500400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_2
},
986 {"cfldr32", 0x0c100500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_3
},
987 {"cfldr64", 0x0c500500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_4
},
988 {"cfstrs", 0x0c000400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_1
},
989 {"cfstrd", 0x0c400400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_2
},
990 {"cfstr32", 0x0c000500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_3
},
991 {"cfstr64", 0x0c400500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_4
},
992 {"cfmvsr", 0x0e000450, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_2
},
993 {"cfmvrs", 0x0e100450, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
994 {"cfmvdlr", 0x0e000410, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_2
},
995 {"cfmvrdl", 0x0e100410, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
996 {"cfmvdhr", 0x0e000430, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_2
},
997 {"cfmvrdh", 0x0e100430, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
998 {"cfmv64lr", 0x0e000510, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_2
},
999 {"cfmvr64l", 0x0e100510, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1000 {"cfmv64hr", 0x0e000530, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_2
},
1001 {"cfmvr64h", 0x0e100530, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1002 {"cfmval32", 0x0e100610, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
1003 {"cfmv32al", 0x0e000610, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
1004 {"cfmvam32", 0x0e100630, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
1005 {"cfmv32am", 0x0e000630, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
1006 {"cfmvah32", 0x0e100650, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
1007 {"cfmv32ah", 0x0e000650, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
1008 {"cfmv32a", 0x0e000670, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
1009 {"cfmva32", 0x0e100670, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
1010 {"cfmv64a", 0x0e000690, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
1011 {"cfmva64", 0x0e100690, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
1012 {"cfmvsc32", 0x0e1006b0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_dspsc_1
},
1013 {"cfmv32sc", 0x0e0006b0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_dspsc_2
},
1014 {"cfcpys", 0x0e000400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1015 {"cfcpyd", 0x0e000420, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1016 {"cfcvtsd", 0x0e000460, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1017 {"cfcvtds", 0x0e000440, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1018 {"cfcvt32s", 0x0e000480, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1019 {"cfcvt32d", 0x0e0004a0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1020 {"cfcvt64s", 0x0e0004c0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1021 {"cfcvt64d", 0x0e0004e0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1022 {"cfcvts32", 0x0e100580, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1023 {"cfcvtd32", 0x0e1005a0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1024 {"cftruncs32",0x0e1005c0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1025 {"cftruncd32",0x0e1005e0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1026 {"cfrshl32", 0x0e000550, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_4
},
1027 {"cfrshl64", 0x0e000570, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_4
},
1028 {"cfsh32", 0x0e000500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_shift_1
},
1029 {"cfsh64", 0x0e200500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_shift_2
},
1030 {"cfcmps", 0x0e100490, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1031 {"cfcmpd", 0x0e1004b0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1032 {"cfcmp32", 0x0e100590, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1033 {"cfcmp64", 0x0e1005b0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1034 {"cfabss", 0x0e300400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1035 {"cfabsd", 0x0e300420, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1036 {"cfnegs", 0x0e300440, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1037 {"cfnegd", 0x0e300460, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1038 {"cfadds", 0x0e300480, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1039 {"cfaddd", 0x0e3004a0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1040 {"cfsubs", 0x0e3004c0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1041 {"cfsubd", 0x0e3004e0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1042 {"cfmuls", 0x0e100400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1043 {"cfmuld", 0x0e100420, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1044 {"cfabs32", 0x0e300500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1045 {"cfabs64", 0x0e300520, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1046 {"cfneg32", 0x0e300540, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1047 {"cfneg64", 0x0e300560, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1048 {"cfadd32", 0x0e300580, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1049 {"cfadd64", 0x0e3005a0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1050 {"cfsub32", 0x0e3005c0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1051 {"cfsub64", 0x0e3005e0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1052 {"cfmul32", 0x0e100500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1053 {"cfmul64", 0x0e100520, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1054 {"cfmac32", 0x0e100540, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1055 {"cfmsc32", 0x0e100560, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1056 {"cfmadd32", 0x0e000600, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_quad_6
},
1057 {"cfmsub32", 0x0e100600, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_quad_6
},
1058 {"cfmadda32", 0x0e200600, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_quad_6
},
1059 {"cfmsuba32", 0x0e300600, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_quad_6
},
1062 /* Defines for various bits that we will want to toggle. */
1063 #define INST_IMMEDIATE 0x02000000
1064 #define OFFSET_REG 0x02000000
1065 #define HWOFFSET_IMM 0x00400000
1066 #define SHIFT_BY_REG 0x00000010
1067 #define PRE_INDEX 0x01000000
1068 #define INDEX_UP 0x00800000
1069 #define WRITE_BACK 0x00200000
1070 #define LDM_TYPE_2_OR_3 0x00400000
1072 #define LITERAL_MASK 0xf000f000
1073 #define COND_MASK 0xf0000000
1074 #define OPCODE_MASK 0xfe1fffff
1075 #define DATA_OP_SHIFT 21
1077 /* Codes to distinguish the arithmetic instructions. */
1078 #define OPCODE_AND 0
1079 #define OPCODE_EOR 1
1080 #define OPCODE_SUB 2
1081 #define OPCODE_RSB 3
1082 #define OPCODE_ADD 4
1083 #define OPCODE_ADC 5
1084 #define OPCODE_SBC 6
1085 #define OPCODE_RSC 7
1086 #define OPCODE_TST 8
1087 #define OPCODE_TEQ 9
1088 #define OPCODE_CMP 10
1089 #define OPCODE_CMN 11
1090 #define OPCODE_ORR 12
1091 #define OPCODE_MOV 13
1092 #define OPCODE_BIC 14
1093 #define OPCODE_MVN 15
1095 /* Thumb v1 (ARMv4T). */
1096 static void do_t_nop
PARAMS ((char *));
1097 static void do_t_arit
PARAMS ((char *));
1098 static void do_t_add
PARAMS ((char *));
1099 static void do_t_asr
PARAMS ((char *));
1100 static void do_t_branch9
PARAMS ((char *));
1101 static void do_t_branch12
PARAMS ((char *));
1102 static void do_t_branch23
PARAMS ((char *));
1103 static void do_t_bx
PARAMS ((char *));
1104 static void do_t_compare
PARAMS ((char *));
1105 static void do_t_ldmstm
PARAMS ((char *));
1106 static void do_t_ldr
PARAMS ((char *));
1107 static void do_t_ldrb
PARAMS ((char *));
1108 static void do_t_ldrh
PARAMS ((char *));
1109 static void do_t_lds
PARAMS ((char *));
1110 static void do_t_lsl
PARAMS ((char *));
1111 static void do_t_lsr
PARAMS ((char *));
1112 static void do_t_mov
PARAMS ((char *));
1113 static void do_t_push_pop
PARAMS ((char *));
1114 static void do_t_str
PARAMS ((char *));
1115 static void do_t_strb
PARAMS ((char *));
1116 static void do_t_strh
PARAMS ((char *));
1117 static void do_t_sub
PARAMS ((char *));
1118 static void do_t_swi
PARAMS ((char *));
1119 static void do_t_adr
PARAMS ((char *));
1121 /* Thumb v2 (ARMv5T). */
1122 static void do_t_blx
PARAMS ((char *));
1123 static void do_t_bkpt
PARAMS ((char *));
1125 #define T_OPCODE_MUL 0x4340
1126 #define T_OPCODE_TST 0x4200
1127 #define T_OPCODE_CMN 0x42c0
1128 #define T_OPCODE_NEG 0x4240
1129 #define T_OPCODE_MVN 0x43c0
1131 #define T_OPCODE_ADD_R3 0x1800
1132 #define T_OPCODE_SUB_R3 0x1a00
1133 #define T_OPCODE_ADD_HI 0x4400
1134 #define T_OPCODE_ADD_ST 0xb000
1135 #define T_OPCODE_SUB_ST 0xb080
1136 #define T_OPCODE_ADD_SP 0xa800
1137 #define T_OPCODE_ADD_PC 0xa000
1138 #define T_OPCODE_ADD_I8 0x3000
1139 #define T_OPCODE_SUB_I8 0x3800
1140 #define T_OPCODE_ADD_I3 0x1c00
1141 #define T_OPCODE_SUB_I3 0x1e00
1143 #define T_OPCODE_ASR_R 0x4100
1144 #define T_OPCODE_LSL_R 0x4080
1145 #define T_OPCODE_LSR_R 0x40c0
1146 #define T_OPCODE_ASR_I 0x1000
1147 #define T_OPCODE_LSL_I 0x0000
1148 #define T_OPCODE_LSR_I 0x0800
1150 #define T_OPCODE_MOV_I8 0x2000
1151 #define T_OPCODE_CMP_I8 0x2800
1152 #define T_OPCODE_CMP_LR 0x4280
1153 #define T_OPCODE_MOV_HR 0x4600
1154 #define T_OPCODE_CMP_HR 0x4500
1156 #define T_OPCODE_LDR_PC 0x4800
1157 #define T_OPCODE_LDR_SP 0x9800
1158 #define T_OPCODE_STR_SP 0x9000
1159 #define T_OPCODE_LDR_IW 0x6800
1160 #define T_OPCODE_STR_IW 0x6000
1161 #define T_OPCODE_LDR_IH 0x8800
1162 #define T_OPCODE_STR_IH 0x8000
1163 #define T_OPCODE_LDR_IB 0x7800
1164 #define T_OPCODE_STR_IB 0x7000
1165 #define T_OPCODE_LDR_RW 0x5800
1166 #define T_OPCODE_STR_RW 0x5000
1167 #define T_OPCODE_LDR_RH 0x5a00
1168 #define T_OPCODE_STR_RH 0x5200
1169 #define T_OPCODE_LDR_RB 0x5c00
1170 #define T_OPCODE_STR_RB 0x5400
1172 #define T_OPCODE_PUSH 0xb400
1173 #define T_OPCODE_POP 0xbc00
1175 #define T_OPCODE_BRANCH 0xe7fe
1177 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
1179 #define THUMB_SIZE 2 /* Size of thumb instruction. */
1180 #define THUMB_REG_LO 0x1
1181 #define THUMB_REG_HI 0x2
1182 #define THUMB_REG_ANY 0x3
1184 #define THUMB_H1 0x0080
1185 #define THUMB_H2 0x0040
1191 #define THUMB_MOVE 0
1192 #define THUMB_COMPARE 1
1194 #define THUMB_LOAD 0
1195 #define THUMB_STORE 1
1197 #define THUMB_PP_PC_LR 0x0100
1199 /* These three are used for immediate shifts, do not alter. */
1200 #define THUMB_WORD 2
1201 #define THUMB_HALFWORD 1
1202 #define THUMB_BYTE 0
1206 /* Basic string to match. */
1207 const char * template;
1209 /* Basic instruction code. */
1210 unsigned long value
;
1214 /* Which CPU variants this exists for. */
1215 unsigned long variants
;
1217 /* Function to call to parse args. */
1218 void (* parms
) PARAMS ((char *));
1221 static const struct thumb_opcode tinsns
[] =
1223 /* Thumb v1 (ARMv4T). */
1224 {"adc", 0x4140, 2, ARM_EXT_V4T
, do_t_arit
},
1225 {"add", 0x0000, 2, ARM_EXT_V4T
, do_t_add
},
1226 {"and", 0x4000, 2, ARM_EXT_V4T
, do_t_arit
},
1227 {"asr", 0x0000, 2, ARM_EXT_V4T
, do_t_asr
},
1228 {"b", T_OPCODE_BRANCH
, 2, ARM_EXT_V4T
, do_t_branch12
},
1229 {"beq", 0xd0fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1230 {"bne", 0xd1fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1231 {"bcs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1232 {"bhs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1233 {"bcc", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1234 {"bul", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1235 {"blo", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1236 {"bmi", 0xd4fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1237 {"bpl", 0xd5fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1238 {"bvs", 0xd6fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1239 {"bvc", 0xd7fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1240 {"bhi", 0xd8fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1241 {"bls", 0xd9fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1242 {"bge", 0xdafe, 2, ARM_EXT_V4T
, do_t_branch9
},
1243 {"blt", 0xdbfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1244 {"bgt", 0xdcfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1245 {"ble", 0xddfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1246 {"bal", 0xdefe, 2, ARM_EXT_V4T
, do_t_branch9
},
1247 {"bic", 0x4380, 2, ARM_EXT_V4T
, do_t_arit
},
1248 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T
, do_t_branch23
},
1249 {"bx", 0x4700, 2, ARM_EXT_V4T
, do_t_bx
},
1250 {"cmn", T_OPCODE_CMN
, 2, ARM_EXT_V4T
, do_t_arit
},
1251 {"cmp", 0x0000, 2, ARM_EXT_V4T
, do_t_compare
},
1252 {"eor", 0x4040, 2, ARM_EXT_V4T
, do_t_arit
},
1253 {"ldmia", 0xc800, 2, ARM_EXT_V4T
, do_t_ldmstm
},
1254 {"ldr", 0x0000, 2, ARM_EXT_V4T
, do_t_ldr
},
1255 {"ldrb", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrb
},
1256 {"ldrh", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrh
},
1257 {"ldrsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
1258 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
1259 {"ldsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
1260 {"ldsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
1261 {"lsl", 0x0000, 2, ARM_EXT_V4T
, do_t_lsl
},
1262 {"lsr", 0x0000, 2, ARM_EXT_V4T
, do_t_lsr
},
1263 {"mov", 0x0000, 2, ARM_EXT_V4T
, do_t_mov
},
1264 {"mul", T_OPCODE_MUL
, 2, ARM_EXT_V4T
, do_t_arit
},
1265 {"mvn", T_OPCODE_MVN
, 2, ARM_EXT_V4T
, do_t_arit
},
1266 {"neg", T_OPCODE_NEG
, 2, ARM_EXT_V4T
, do_t_arit
},
1267 {"orr", 0x4300, 2, ARM_EXT_V4T
, do_t_arit
},
1268 {"pop", 0xbc00, 2, ARM_EXT_V4T
, do_t_push_pop
},
1269 {"push", 0xb400, 2, ARM_EXT_V4T
, do_t_push_pop
},
1270 {"ror", 0x41c0, 2, ARM_EXT_V4T
, do_t_arit
},
1271 {"sbc", 0x4180, 2, ARM_EXT_V4T
, do_t_arit
},
1272 {"stmia", 0xc000, 2, ARM_EXT_V4T
, do_t_ldmstm
},
1273 {"str", 0x0000, 2, ARM_EXT_V4T
, do_t_str
},
1274 {"strb", 0x0000, 2, ARM_EXT_V4T
, do_t_strb
},
1275 {"strh", 0x0000, 2, ARM_EXT_V4T
, do_t_strh
},
1276 {"swi", 0xdf00, 2, ARM_EXT_V4T
, do_t_swi
},
1277 {"sub", 0x0000, 2, ARM_EXT_V4T
, do_t_sub
},
1278 {"tst", T_OPCODE_TST
, 2, ARM_EXT_V4T
, do_t_arit
},
1280 {"adr", 0x0000, 2, ARM_EXT_V4T
, do_t_adr
},
1281 {"nop", 0x46C0, 2, ARM_EXT_V4T
, do_t_nop
}, /* mov r8,r8 */
1282 /* Thumb v2 (ARMv5T). */
1283 {"blx", 0, 0, ARM_EXT_V5T
, do_t_blx
},
1284 {"bkpt", 0xbe00, 2, ARM_EXT_V5T
, do_t_bkpt
},
1293 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
1294 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
1295 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
1297 #define ARM_EXT_MAVERICKSC_REG 134
1299 #define cirrus_register(reg) ((reg) >= 50 && (reg) <= 134)
1300 #define cirrus_mvf_register(reg) ((reg) >= 50 && (reg) <= 65)
1301 #define cirrus_mvd_register(reg) ((reg) >= 70 && (reg) <= 85)
1302 #define cirrus_mvfx_register(reg) ((reg) >= 90 && (reg) <= 105)
1303 #define cirrus_mvdx_register(reg) ((reg) >= 110 && (reg) <= 125)
1304 #define cirrus_mvax_register(reg) ((reg) >= 130 && (reg) <= 133)
1305 #define ARM_EXT_MAVERICKsc_register(reg) ((reg) == ARM_EXT_MAVERICKSC_REG)
1311 /* These are the standard names. Users can add aliases with .req. */
1312 static const struct reg_entry reg_table
[] =
1314 /* Processor Register Numbers. */
1315 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
1316 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
1317 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
1318 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
1319 /* APCS conventions. */
1320 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
1321 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
1322 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
1323 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
1324 /* ATPCS additions to APCS conventions. */
1325 {"wr", 7}, {"v8", 11},
1327 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
1328 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
1329 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
1330 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
1331 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
1332 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
1333 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
1334 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
1335 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
1336 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1337 /* ATPCS additions to float register names. */
1338 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
1339 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
1340 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
1341 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
1342 /* Cirrus DSP coprocessor registers. */
1343 {"mvf0", 50}, {"mvf1", 51}, {"mvf2", 52}, {"mvf3", 53},
1344 {"mvf4", 54}, {"mvf5", 55}, {"mvf6", 56}, {"mvf7", 57},
1345 {"mvf8", 58}, {"mvf9", 59}, {"mvf10", 60}, {"mvf11", 61},
1346 {"mvf12", 62},{"mvf13", 63}, {"mvf14", 64}, {"mvf15", 65},
1347 {"mvd0", 70}, {"mvd1", 71}, {"mvd2", 72}, {"mvd3", 73},
1348 {"mvd4", 74}, {"mvd5", 75}, {"mvd6", 76}, {"mvd7", 77},
1349 {"mvd8", 78}, {"mvd9", 79}, {"mvd10", 80}, {"mvd11", 81},
1350 {"mvd12", 82},{"mvd13", 83}, {"mvd14", 84}, {"mvd15", 85},
1351 {"mvfx0", 90},{"mvfx1", 91}, {"mvfx2", 92}, {"mvfx3", 93},
1352 {"mvfx4", 94},{"mvfx5", 95}, {"mvfx6", 96}, {"mvfx7", 97},
1353 {"mvfx8", 98},{"mvfx9", 99}, {"mvfx10", 100},{"mvfx11", 101},
1354 {"mvfx12", 102},{"mvfx13", 103},{"mvfx14", 104},{"mvfx15", 105},
1355 {"mvdx0", 110}, {"mvdx1", 111}, {"mvdx2", 112}, {"mvdx3", 113},
1356 {"mvdx4", 114}, {"mvdx5", 115}, {"mvdx6", 116}, {"mvdx7", 117},
1357 {"mvdx8", 118}, {"mvdx9", 119}, {"mvdx10", 120},{"mvdx11", 121},
1358 {"mvdx12", 122},{"mvdx13", 123},{"mvdx14", 124},{"mvdx15", 125},
1359 {"mvax0", 130}, {"mvax1", 131}, {"mvax2", 132}, {"mvax3", 133},
1360 {"dspsc", ARM_EXT_MAVERICKSC_REG
},
1361 /* FIXME: At some point we need to add VFP register names. */
1362 /* Array terminator. */
1366 #define BAD_ARGS _("Bad arguments to instruction")
1367 #define BAD_PC _("r15 not allowed here")
1368 #define BAD_FLAGS _("Instruction should not have flags")
1369 #define BAD_COND _("Instruction is not conditional")
1370 #define ERR_NO_ACCUM _("acc0 expected")
1372 static struct hash_control
* arm_ops_hsh
= NULL
;
1373 static struct hash_control
* arm_tops_hsh
= NULL
;
1374 static struct hash_control
* arm_cond_hsh
= NULL
;
1375 static struct hash_control
* arm_shift_hsh
= NULL
;
1376 static struct hash_control
* arm_reg_hsh
= NULL
;
1377 static struct hash_control
* arm_psr_hsh
= NULL
;
1379 /* This table describes all the machine specific pseudo-ops the assembler
1380 has to support. The fields are:
1381 pseudo-op name without dot
1382 function to call to execute this pseudo-op
1383 Integer arg to pass to the function. */
1385 static void s_req
PARAMS ((int));
1386 static void s_align
PARAMS ((int));
1387 static void s_bss
PARAMS ((int));
1388 static void s_even
PARAMS ((int));
1389 static void s_ltorg
PARAMS ((int));
1390 static void s_arm
PARAMS ((int));
1391 static void s_thumb
PARAMS ((int));
1392 static void s_code
PARAMS ((int));
1393 static void s_force_thumb
PARAMS ((int));
1394 static void s_thumb_func
PARAMS ((int));
1395 static void s_thumb_set
PARAMS ((int));
1396 static void arm_s_text
PARAMS ((int));
1397 static void arm_s_data
PARAMS ((int));
1399 static void arm_s_section
PARAMS ((int));
1400 static void s_arm_elf_cons
PARAMS ((int));
1403 static int my_get_expression
PARAMS ((expressionS
*, char **));
1405 const pseudo_typeS md_pseudo_table
[] =
1407 /* Never called becasue '.req' does not start line. */
1408 { "req", s_req
, 0 },
1409 { "bss", s_bss
, 0 },
1410 { "align", s_align
, 0 },
1411 { "arm", s_arm
, 0 },
1412 { "thumb", s_thumb
, 0 },
1413 { "code", s_code
, 0 },
1414 { "force_thumb", s_force_thumb
, 0 },
1415 { "thumb_func", s_thumb_func
, 0 },
1416 { "thumb_set", s_thumb_set
, 0 },
1417 { "even", s_even
, 0 },
1418 { "ltorg", s_ltorg
, 0 },
1419 { "pool", s_ltorg
, 0 },
1420 /* Allow for the effect of section changes. */
1421 { "text", arm_s_text
, 0 },
1422 { "data", arm_s_data
, 0 },
1424 { "section", arm_s_section
, 0 },
1425 { "section.s", arm_s_section
, 0 },
1426 { "sect", arm_s_section
, 0 },
1427 { "sect.s", arm_s_section
, 0 },
1428 { "word", s_arm_elf_cons
, 4 },
1429 { "long", s_arm_elf_cons
, 4 },
1430 { "file", dwarf2_directive_file
, 0 },
1431 { "loc", dwarf2_directive_loc
, 0 },
1435 { "extend", float_cons
, 'x' },
1436 { "ldouble", float_cons
, 'x' },
1437 { "packed", float_cons
, 'p' },
1441 /* Stuff needed to resolve the label ambiguity
1451 symbolS
* last_label_seen
;
1452 static int label_is_thumb_function_name
= false;
1454 /* Literal stuff. */
1456 #define MAX_LITERAL_POOL_SIZE 1024
1458 typedef struct literalS
1460 struct expressionS exp
;
1461 struct arm_it
* inst
;
1464 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1466 /* Next free entry in the pool. */
1467 int next_literal_pool_place
= 0;
1469 /* Next literal pool number. */
1470 int lit_pool_num
= 1;
1472 symbolS
* current_poolP
= NULL
;
1479 if (current_poolP
== NULL
)
1480 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1481 (valueT
) 0, &zero_address_frag
);
1483 /* Check if this literal value is already in the pool: */
1484 while (lit_count
< next_literal_pool_place
)
1486 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1487 && inst
.reloc
.exp
.X_op
== O_constant
1488 && (literals
[lit_count
].exp
.X_add_number
1489 == inst
.reloc
.exp
.X_add_number
)
1490 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1493 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1494 && inst
.reloc
.exp
.X_op
== O_symbol
1495 && (literals
[lit_count
].exp
.X_add_number
1496 == inst
.reloc
.exp
.X_add_number
)
1497 && (literals
[lit_count
].exp
.X_add_symbol
1498 == inst
.reloc
.exp
.X_add_symbol
)
1499 && (literals
[lit_count
].exp
.X_op_symbol
1500 == inst
.reloc
.exp
.X_op_symbol
))
1506 if (lit_count
== next_literal_pool_place
) /* New entry. */
1508 if (next_literal_pool_place
>= MAX_LITERAL_POOL_SIZE
)
1510 inst
.error
= _("Literal Pool Overflow");
1514 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1515 lit_count
= next_literal_pool_place
++;
1518 inst
.reloc
.exp
.X_op
= O_symbol
;
1519 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1520 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1525 /* Can't use symbol_new here, so have to create a symbol and then at
1526 a later date assign it a value. Thats what these functions do. */
1529 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1531 const char * name
; /* It is copied, the caller can modify. */
1532 segT segment
; /* Segment identifier (SEG_<something>). */
1533 valueT valu
; /* Symbol value. */
1534 fragS
* frag
; /* Associated fragment. */
1536 unsigned int name_length
;
1537 char * preserved_copy_of_name
;
1539 name_length
= strlen (name
) + 1; /* +1 for \0. */
1540 obstack_grow (¬es
, name
, name_length
);
1541 preserved_copy_of_name
= obstack_finish (¬es
);
1542 #ifdef STRIP_UNDERSCORE
1543 if (preserved_copy_of_name
[0] == '_')
1544 preserved_copy_of_name
++;
1547 #ifdef tc_canonicalize_symbol_name
1548 preserved_copy_of_name
=
1549 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1552 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1554 S_SET_SEGMENT (symbolP
, segment
);
1555 S_SET_VALUE (symbolP
, valu
);
1556 symbol_clear_list_pointers(symbolP
);
1558 symbol_set_frag (symbolP
, frag
);
1560 /* Link to end of symbol chain. */
1562 extern int symbol_table_frozen
;
1563 if (symbol_table_frozen
)
1567 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1569 obj_symbol_new_hook (symbolP
);
1571 #ifdef tc_symbol_new_hook
1572 tc_symbol_new_hook (symbolP
);
1576 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1577 #endif /* DEBUG_SYMS */
1580 /* Check that an immediate is valid.
1581 If so, convert it to the right format. */
1584 validate_immediate (val
)
1590 #define rotate_left(v, n) (v << n | v >> (32 - n))
1592 for (i
= 0; i
< 32; i
+= 2)
1593 if ((a
= rotate_left (val
, i
)) <= 0xff)
1594 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
1599 /* Check to see if an immediate can be computed as two seperate immediate
1600 values, added together. We already know that this value cannot be
1601 computed by just one ARM instruction. */
1604 validate_immediate_twopart (val
, highpart
)
1606 unsigned int * highpart
;
1611 for (i
= 0; i
< 32; i
+= 2)
1612 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1618 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1620 else if (a
& 0xff0000)
1624 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1628 assert (a
& 0xff000000);
1629 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1632 return (a
& 0xff) | (i
<< 7);
1639 validate_offset_imm (val
, hwse
)
1643 if ((hwse
&& val
> 255) || val
> 4095)
1650 int a ATTRIBUTE_UNUSED
;
1652 as_bad (_("Invalid syntax for .req directive."));
1657 int ignore ATTRIBUTE_UNUSED
;
1659 /* We don't support putting frags in the BSS segment, we fake it by
1660 marking in_bss, then looking at s_skip for clues. */
1661 subseg_set (bss_section
, 0);
1662 demand_empty_rest_of_line ();
1667 int ignore ATTRIBUTE_UNUSED
;
1669 /* Never make frag if expect extra pass. */
1671 frag_align (1, 0, 0);
1673 record_alignment (now_seg
, 1);
1675 demand_empty_rest_of_line ();
1680 int ignored ATTRIBUTE_UNUSED
;
1685 if (current_poolP
== NULL
)
1688 /* Align pool as you have word accesses.
1689 Only make a frag if we have to. */
1691 frag_align (2, 0, 0);
1693 record_alignment (now_seg
, 2);
1695 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1697 symbol_locate (current_poolP
, sym_name
, now_seg
,
1698 (valueT
) frag_now_fix (), frag_now
);
1699 symbol_table_insert (current_poolP
);
1701 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1703 #if defined OBJ_COFF || defined OBJ_ELF
1704 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1707 while (lit_count
< next_literal_pool_place
)
1708 /* First output the expression in the instruction to the pool. */
1709 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1711 next_literal_pool_place
= 0;
1712 current_poolP
= NULL
;
1715 /* Same as s_align_ptwo but align 0 => align 2. */
1719 int unused ATTRIBUTE_UNUSED
;
1722 register long temp_fill
;
1723 long max_alignment
= 15;
1725 temp
= get_absolute_expression ();
1726 if (temp
> max_alignment
)
1727 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1730 as_bad (_("Alignment negative. 0 assumed."));
1734 if (*input_line_pointer
== ',')
1736 input_line_pointer
++;
1737 temp_fill
= get_absolute_expression ();
1745 /* Only make a frag if we HAVE to. */
1746 if (temp
&& !need_pass_2
)
1747 frag_align (temp
, (int) temp_fill
, 0);
1748 demand_empty_rest_of_line ();
1750 record_alignment (now_seg
, temp
);
1754 s_force_thumb (ignore
)
1755 int ignore ATTRIBUTE_UNUSED
;
1757 /* If we are not already in thumb mode go into it, EVEN if
1758 the target processor does not support thumb instructions.
1759 This is used by gcc/config/arm/lib1funcs.asm for example
1760 to compile interworking support functions even if the
1761 target processor should not support interworking. */
1766 record_alignment (now_seg
, 1);
1769 demand_empty_rest_of_line ();
1773 s_thumb_func (ignore
)
1774 int ignore ATTRIBUTE_UNUSED
;
1779 /* The following label is the name/address of the start of a Thumb function.
1780 We need to know this for the interworking support. */
1781 label_is_thumb_function_name
= true;
1783 demand_empty_rest_of_line ();
1786 /* Perform a .set directive, but also mark the alias as
1787 being a thumb function. */
1793 /* XXX the following is a duplicate of the code for s_set() in read.c
1794 We cannot just call that code as we need to get at the symbol that
1796 register char * name
;
1797 register char delim
;
1798 register char * end_name
;
1799 register symbolS
* symbolP
;
1801 /* Especial apologies for the random logic:
1802 This just grew, and could be parsed much more simply!
1804 name
= input_line_pointer
;
1805 delim
= get_symbol_end ();
1806 end_name
= input_line_pointer
;
1811 if (*input_line_pointer
!= ',')
1814 as_bad (_("Expected comma after name \"%s\""), name
);
1816 ignore_rest_of_line ();
1820 input_line_pointer
++;
1823 if (name
[0] == '.' && name
[1] == '\0')
1825 /* XXX - this should not happen to .thumb_set. */
1829 if ((symbolP
= symbol_find (name
)) == NULL
1830 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1833 /* When doing symbol listings, play games with dummy fragments living
1834 outside the normal fragment chain to record the file and line info
1836 if (listing
& LISTING_SYMBOLS
)
1838 extern struct list_info_struct
* listing_tail
;
1839 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
1841 memset (dummy_frag
, 0, sizeof (fragS
));
1842 dummy_frag
->fr_type
= rs_fill
;
1843 dummy_frag
->line
= listing_tail
;
1844 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1845 dummy_frag
->fr_symbol
= symbolP
;
1849 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1852 /* "set" symbols are local unless otherwise specified. */
1853 SF_SET_LOCAL (symbolP
);
1854 #endif /* OBJ_COFF */
1855 } /* Make a new symbol. */
1857 symbol_table_insert (symbolP
);
1862 && S_IS_DEFINED (symbolP
)
1863 && S_GET_SEGMENT (symbolP
) != reg_section
)
1864 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1866 pseudo_set (symbolP
);
1868 demand_empty_rest_of_line ();
1870 /* XXX Now we come to the Thumb specific bit of code. */
1872 THUMB_SET_FUNC (symbolP
, 1);
1873 ARM_SET_THUMB (symbolP
, 1);
1874 #if defined OBJ_ELF || defined OBJ_COFF
1875 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1879 /* If we change section we must dump the literal pool first. */
1885 if (now_seg
!= text_section
)
1889 obj_elf_text (ignore
);
1899 if (flag_readonly_data_in_text
)
1901 if (now_seg
!= text_section
)
1904 else if (now_seg
!= data_section
)
1908 obj_elf_data (ignore
);
1916 arm_s_section (ignore
)
1921 obj_elf_section (ignore
);
1926 opcode_select (width
)
1934 if (! (cpu_variant
& ARM_EXT_V4T
))
1935 as_bad (_("selected processor does not support THUMB opcodes"));
1938 /* No need to force the alignment, since we will have been
1939 coming from ARM mode, which is word-aligned. */
1940 record_alignment (now_seg
, 1);
1947 if ((cpu_variant
& ARM_ANY
) == ARM_EXT_V4T
)
1948 as_bad (_("selected processor does not support ARM opcodes"));
1953 frag_align (2, 0, 0);
1955 record_alignment (now_seg
, 1);
1960 as_bad (_("invalid instruction size selected (%d)"), width
);
1966 int ignore ATTRIBUTE_UNUSED
;
1969 demand_empty_rest_of_line ();
1974 int ignore ATTRIBUTE_UNUSED
;
1977 demand_empty_rest_of_line ();
1982 int unused ATTRIBUTE_UNUSED
;
1986 temp
= get_absolute_expression ();
1991 opcode_select (temp
);
1995 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
2003 skip_whitespace (str
);
2006 inst
.error
= _("Garbage following instruction");
2010 skip_past_comma (str
)
2013 char * p
= * str
, c
;
2016 while ((c
= *p
) == ' ' || c
== ',')
2019 if (c
== ',' && comma
++)
2027 return comma
? SUCCESS
: FAIL
;
2030 /* A standard register must be given at this point.
2031 SHIFT is the place to put it in inst.instruction.
2032 Restores input start point on error.
2033 Returns the reg#, or FAIL. */
2036 reg_required_here (str
, shift
)
2040 static char buff
[128]; /* XXX */
2042 char * start
= * str
;
2044 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
2047 inst
.instruction
|= reg
<< shift
;
2051 /* Restore the start point, we may have got a reg of the wrong class. */
2054 /* In the few cases where we might be able to accept something else
2055 this error can be overridden. */
2056 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
2062 static const struct asm_psr
*
2064 register char ** ccp
;
2066 char * start
= * ccp
;
2069 const struct asm_psr
* psr
;
2073 /* Skip to the end of the next word in the input stream. */
2078 while (ISALPHA (c
) || c
== '_');
2080 /* Terminate the word. */
2083 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
2084 feature for ease of use and backwards compatibility. */
2085 if (!strncmp (start
, "cpsr", 4))
2086 strncpy (start
, "CPSR", 4);
2087 else if (!strncmp (start
, "spsr", 4))
2088 strncpy (start
, "SPSR", 4);
2090 /* Now locate the word in the psr hash table. */
2091 psr
= (const struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
2093 /* Restore the input stream. */
2096 /* If we found a valid match, advance the
2097 stream pointer past the end of the word. */
2103 /* Parse the input looking for a PSR flag. */
2106 psr_required_here (str
)
2109 char * start
= * str
;
2110 const struct asm_psr
* psr
;
2112 psr
= arm_psr_parse (str
);
2116 /* If this is the SPSR that is being modified, set the R bit. */
2118 inst
.instruction
|= SPSR_BIT
;
2120 /* Set the psr flags in the MSR instruction. */
2121 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
2126 /* In the few cases where we might be able to accept
2127 something else this error can be overridden. */
2128 inst
.error
= _("flag for {c}psr instruction expected");
2130 /* Restore the start point. */
2136 co_proc_number (str
)
2139 int processor
, pchar
;
2141 skip_whitespace (* str
);
2143 /* The data sheet seems to imply that just a number on its own is valid
2144 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
2146 if (**str
== 'p' || **str
== 'P')
2150 if (pchar
>= '0' && pchar
<= '9')
2152 processor
= pchar
- '0';
2153 if (**str
>= '0' && **str
<= '9')
2155 processor
= processor
* 10 + *(*str
)++ - '0';
2158 inst
.error
= _("Illegal co-processor number");
2165 inst
.error
= _("Bad or missing co-processor number");
2169 inst
.instruction
|= processor
<< 8;
2174 cp_opc_expr (str
, where
, length
)
2181 skip_whitespace (* str
);
2183 memset (&expr
, '\0', sizeof (expr
));
2185 if (my_get_expression (&expr
, str
))
2187 if (expr
.X_op
!= O_constant
)
2189 inst
.error
= _("bad or missing expression");
2193 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
2195 inst
.error
= _("immediate co-processor expression too large");
2199 inst
.instruction
|= expr
.X_add_number
<< where
;
2204 cp_reg_required_here (str
, where
)
2209 char * start
= *str
;
2211 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
2214 inst
.instruction
|= reg
<< where
;
2218 /* In the few cases where we might be able to accept something else
2219 this error can be overridden. */
2220 inst
.error
= _("Co-processor register expected");
2222 /* Restore the start point. */
2228 fp_reg_required_here (str
, where
)
2233 char * start
= * str
;
2235 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
2238 inst
.instruction
|= reg
<< where
;
2242 /* In the few cases where we might be able to accept something else
2243 this error can be overridden. */
2244 inst
.error
= _("Floating point register expected");
2246 /* Restore the start point. */
2252 cp_address_offset (str
)
2257 skip_whitespace (* str
);
2259 if (! is_immediate_prefix (**str
))
2261 inst
.error
= _("immediate expression expected");
2267 if (my_get_expression (& inst
.reloc
.exp
, str
))
2270 if (inst
.reloc
.exp
.X_op
== O_constant
)
2272 offset
= inst
.reloc
.exp
.X_add_number
;
2276 inst
.error
= _("co-processor address must be word aligned");
2280 if (offset
> 1023 || offset
< -1023)
2282 inst
.error
= _("offset too large");
2287 inst
.instruction
|= INDEX_UP
;
2291 inst
.instruction
|= offset
>> 2;
2294 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2300 cp_address_required_here (str
)
2312 skip_whitespace (p
);
2314 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
2317 skip_whitespace (p
);
2323 if (skip_past_comma (& p
) == SUCCESS
)
2326 write_back
= WRITE_BACK
;
2330 inst
.error
= _("pc may not be used in post-increment");
2334 if (cp_address_offset (& p
) == FAIL
)
2338 pre_inc
= PRE_INDEX
| INDEX_UP
;
2342 /* '['Rn, #expr']'[!] */
2344 if (skip_past_comma (& p
) == FAIL
)
2346 inst
.error
= _("pre-indexed expression expected");
2350 pre_inc
= PRE_INDEX
;
2352 if (cp_address_offset (& p
) == FAIL
)
2355 skip_whitespace (p
);
2359 inst
.error
= _("missing ]");
2363 skip_whitespace (p
);
2369 inst
.error
= _("pc may not be used with write-back");
2374 write_back
= WRITE_BACK
;
2380 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2383 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2384 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2385 inst
.reloc
.pc_rel
= 1;
2386 inst
.instruction
|= (REG_PC
<< 16);
2387 pre_inc
= PRE_INDEX
;
2390 inst
.instruction
|= write_back
| pre_inc
;
2398 unsigned long flags
;
2400 /* Do nothing really. */
2401 inst
.instruction
|= flags
; /* This is pointless. */
2409 unsigned long flags
;
2413 /* Only one syntax. */
2414 skip_whitespace (str
);
2416 if (reg_required_here (&str
, 12) == FAIL
)
2418 inst
.error
= BAD_ARGS
;
2422 if (skip_past_comma (&str
) == FAIL
)
2424 inst
.error
= _("comma expected after register name");
2428 skip_whitespace (str
);
2430 if ( strcmp (str
, "CPSR") == 0
2431 || strcmp (str
, "SPSR") == 0
2432 /* Lower case versions for backwards compatability. */
2433 || strcmp (str
, "cpsr") == 0
2434 || strcmp (str
, "spsr") == 0)
2437 /* This is for backwards compatability with older toolchains. */
2438 else if ( strcmp (str
, "cpsr_all") == 0
2439 || strcmp (str
, "spsr_all") == 0)
2443 inst
.error
= _("{C|S}PSR expected");
2447 if (* str
== 's' || * str
== 'S')
2448 inst
.instruction
|= SPSR_BIT
;
2451 inst
.instruction
|= flags
;
2455 /* Two possible forms:
2456 "{C|S}PSR_<field>, Rm",
2457 "{C|S}PSR_f, #expression". */
2462 unsigned long flags
;
2464 skip_whitespace (str
);
2466 if (psr_required_here (& str
) == FAIL
)
2469 if (skip_past_comma (& str
) == FAIL
)
2471 inst
.error
= _("comma missing after psr flags");
2475 skip_whitespace (str
);
2477 if (reg_required_here (& str
, 0) != FAIL
)
2480 inst
.instruction
|= flags
;
2485 if (! is_immediate_prefix (* str
))
2488 _("only a register or immediate value can follow a psr flag");
2495 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2498 _("only a register or immediate value can follow a psr flag");
2502 #if 0 /* The first edition of the ARM architecture manual stated that
2503 writing anything other than the flags with an immediate operation
2504 had UNPREDICTABLE effects. This constraint was removed in the
2505 second edition of the specification. */
2506 if ((cpu_variant
& ARM_EXT_V5
) != ARM_EXT_V5
2507 && inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2509 inst
.error
= _("immediate value cannot be used to set this field");
2514 flags
|= INST_IMMEDIATE
;
2516 if (inst
.reloc
.exp
.X_add_symbol
)
2518 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2519 inst
.reloc
.pc_rel
= 0;
2523 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2525 if (value
== (unsigned) FAIL
)
2527 inst
.error
= _("Invalid constant");
2531 inst
.instruction
|= value
;
2535 inst
.instruction
|= flags
;
2539 /* Long Multiply Parser
2540 UMULL RdLo, RdHi, Rm, Rs
2541 SMULL RdLo, RdHi, Rm, Rs
2542 UMLAL RdLo, RdHi, Rm, Rs
2543 SMLAL RdLo, RdHi, Rm, Rs. */
2546 do_mull (str
, flags
)
2548 unsigned long flags
;
2550 int rdlo
, rdhi
, rm
, rs
;
2552 /* Only one format "rdlo, rdhi, rm, rs". */
2553 skip_whitespace (str
);
2555 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2557 inst
.error
= BAD_ARGS
;
2561 if (skip_past_comma (&str
) == FAIL
2562 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2564 inst
.error
= BAD_ARGS
;
2568 if (skip_past_comma (&str
) == FAIL
2569 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2571 inst
.error
= BAD_ARGS
;
2575 /* rdhi, rdlo and rm must all be different. */
2576 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2577 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2579 if (skip_past_comma (&str
) == FAIL
2580 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2582 inst
.error
= BAD_ARGS
;
2586 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2588 inst
.error
= BAD_PC
;
2592 inst
.instruction
|= flags
;
2600 unsigned long flags
;
2604 /* Only one format "rd, rm, rs". */
2605 skip_whitespace (str
);
2607 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2609 inst
.error
= BAD_ARGS
;
2615 inst
.error
= BAD_PC
;
2619 if (skip_past_comma (&str
) == FAIL
2620 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2622 inst
.error
= BAD_ARGS
;
2628 inst
.error
= BAD_PC
;
2633 as_tsktsk (_("rd and rm should be different in mul"));
2635 if (skip_past_comma (&str
) == FAIL
2636 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2638 inst
.error
= BAD_ARGS
;
2644 inst
.error
= BAD_PC
;
2648 inst
.instruction
|= flags
;
2656 unsigned long flags
;
2660 /* Only one format "rd, rm, rs, rn". */
2661 skip_whitespace (str
);
2663 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2665 inst
.error
= BAD_ARGS
;
2671 inst
.error
= BAD_PC
;
2675 if (skip_past_comma (&str
) == FAIL
2676 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2678 inst
.error
= BAD_ARGS
;
2684 inst
.error
= BAD_PC
;
2689 as_tsktsk (_("rd and rm should be different in mla"));
2691 if (skip_past_comma (&str
) == FAIL
2692 || (rd
= reg_required_here (&str
, 8)) == FAIL
2693 || skip_past_comma (&str
) == FAIL
2694 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2696 inst
.error
= BAD_ARGS
;
2700 if (rd
== REG_PC
|| rm
== REG_PC
)
2702 inst
.error
= BAD_PC
;
2706 inst
.instruction
|= flags
;
2711 /* Expects *str -> the characters "acc0", possibly with leading blanks.
2712 Advances *str to the next non-alphanumeric.
2713 Returns 0, or else FAIL (in which case sets inst.error).
2715 (In a future XScale, there may be accumulators other than zero.
2716 At that time this routine and its callers can be upgraded to suit.) */
2719 accum0_required_here (str
)
2722 static char buff
[128]; /* Note the address is taken. Hence, static. */
2725 int result
= 0; /* The accum number. */
2727 skip_whitespace (p
);
2729 *str
= p
; /* Advance caller's string pointer too. */
2734 *--p
= 0; /* Aap nul into input buffer at non-alnum. */
2736 if (! ( streq (*str
, "acc0") || streq (*str
, "ACC0")))
2738 sprintf (buff
, _("acc0 expected, not '%.100s'"), *str
);
2743 *p
= c
; /* Unzap. */
2744 *str
= p
; /* Caller's string pointer to after match. */
2748 /* Expects **str -> after a comma. May be leading blanks.
2749 Advances *str, recognizing a load mode, and setting inst.instruction.
2750 Returns rn, or else FAIL (in which case may set inst.error
2751 and not advance str)
2753 Note: doesn't know Rd, so no err checks that require such knowledge. */
2756 ld_mode_required_here (string
)
2759 char * str
= * string
;
2763 skip_whitespace (str
);
2769 skip_whitespace (str
);
2771 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
2774 skip_whitespace (str
);
2780 if (skip_past_comma (& str
) == SUCCESS
)
2782 /* [Rn],... (post inc) */
2783 if (ldst_extend (& str
, 1) == FAIL
)
2788 skip_whitespace (str
);
2793 inst
.instruction
|= WRITE_BACK
;
2796 inst
.instruction
|= INDEX_UP
| HWOFFSET_IMM
;
2802 if (skip_past_comma (& str
) == FAIL
)
2804 inst
.error
= _("pre-indexed expression expected");
2810 if (ldst_extend (& str
, 1) == FAIL
)
2813 skip_whitespace (str
);
2815 if (* str
++ != ']')
2817 inst
.error
= _("missing ]");
2821 skip_whitespace (str
);
2826 inst
.instruction
|= WRITE_BACK
;
2830 else if (* str
== '=') /* ldr's "r,=label" syntax */
2831 /* We should never reach here, because <text> = <expression> is
2832 caught gas/read.c read_a_source_file() as a .set operation. */
2834 else /* PC +- 8 bit immediate offset. */
2836 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2839 inst
.instruction
|= HWOFFSET_IMM
; /* The I bit. */
2840 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2841 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2842 inst
.reloc
.pc_rel
= 1;
2843 inst
.instruction
|= (REG_PC
<< 16);
2849 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
2855 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
2856 SMLAxy{cond} Rd,Rm,Rs,Rn
2857 SMLAWy{cond} Rd,Rm,Rs,Rn
2858 Error if any register is R15. */
2861 do_smla (str
, flags
)
2863 unsigned long flags
;
2867 skip_whitespace (str
);
2869 if ((rd
= reg_required_here (& str
, 16)) == FAIL
2870 || skip_past_comma (& str
) == FAIL
2871 || (rm
= reg_required_here (& str
, 0)) == FAIL
2872 || skip_past_comma (& str
) == FAIL
2873 || (rs
= reg_required_here (& str
, 8)) == FAIL
2874 || skip_past_comma (& str
) == FAIL
2875 || (rn
= reg_required_here (& str
, 12)) == FAIL
)
2876 inst
.error
= BAD_ARGS
;
2878 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
|| rn
== REG_PC
)
2879 inst
.error
= BAD_PC
;
2882 inst
.error
= BAD_FLAGS
;
2888 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
2889 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
2890 Error if any register is R15.
2891 Warning if Rdlo == Rdhi. */
2894 do_smlal (str
, flags
)
2896 unsigned long flags
;
2898 int rdlo
, rdhi
, rm
, rs
;
2900 skip_whitespace (str
);
2902 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
2903 || skip_past_comma (& str
) == FAIL
2904 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
2905 || skip_past_comma (& str
) == FAIL
2906 || (rm
= reg_required_here (& str
, 0)) == FAIL
2907 || skip_past_comma (& str
) == FAIL
2908 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
2910 inst
.error
= BAD_ARGS
;
2914 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
2916 inst
.error
= BAD_PC
;
2921 as_tsktsk (_("rdhi and rdlo must be different"));
2924 inst
.error
= BAD_FLAGS
;
2929 /* ARM V5E (El Segundo) signed-multiply (argument parse)
2930 SMULxy{cond} Rd,Rm,Rs
2931 Error if any register is R15. */
2934 do_smul (str
, flags
)
2936 unsigned long flags
;
2940 skip_whitespace (str
);
2942 if ((rd
= reg_required_here (& str
, 16)) == FAIL
2943 || skip_past_comma (& str
) == FAIL
2944 || (rm
= reg_required_here (& str
, 0)) == FAIL
2945 || skip_past_comma (& str
) == FAIL
2946 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
2947 inst
.error
= BAD_ARGS
;
2949 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
2950 inst
.error
= BAD_PC
;
2953 inst
.error
= BAD_FLAGS
;
2959 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
2960 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
2961 Error if any register is R15. */
2964 do_qadd (str
, flags
)
2966 unsigned long flags
;
2970 skip_whitespace (str
);
2972 if ((rd
= reg_required_here (& str
, 12)) == FAIL
2973 || skip_past_comma (& str
) == FAIL
2974 || (rm
= reg_required_here (& str
, 0)) == FAIL
2975 || skip_past_comma (& str
) == FAIL
2976 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
2977 inst
.error
= BAD_ARGS
;
2979 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
2980 inst
.error
= BAD_PC
;
2983 inst
.error
= BAD_FLAGS
;
2989 /* ARM V5E (el Segundo)
2990 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2991 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2993 These are equivalent to the XScale instructions MAR and MRA,
2994 respectively, when coproc == 0, opcode == 0, and CRm == 0.
2996 Result unpredicatable if Rd or Rn is R15. */
2999 do_co_reg2c (str
, flags
)
3001 unsigned long flags
;
3005 skip_whitespace (str
);
3007 if (co_proc_number (& str
) == FAIL
)
3010 inst
.error
= BAD_ARGS
;
3014 if (skip_past_comma (& str
) == FAIL
3015 || cp_opc_expr (& str
, 4, 4) == FAIL
)
3018 inst
.error
= BAD_ARGS
;
3022 if (skip_past_comma (& str
) == FAIL
3023 || (rd
= reg_required_here (& str
, 12)) == FAIL
)
3026 inst
.error
= BAD_ARGS
;
3030 if (skip_past_comma (& str
) == FAIL
3031 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
3034 inst
.error
= BAD_ARGS
;
3038 /* Unpredictable result if rd or rn is R15. */
3039 if (rd
== REG_PC
|| rn
== REG_PC
)
3041 (_("Warning: Instruction unpredictable when using r15"));
3043 if (skip_past_comma (& str
) == FAIL
3044 || cp_reg_required_here (& str
, 0) == FAIL
)
3047 inst
.error
= BAD_ARGS
;
3052 inst
.error
= BAD_COND
;
3057 /* ARM V5 count-leading-zeroes instruction (argument parse)
3058 CLZ{<cond>} <Rd>, <Rm>
3059 Condition defaults to COND_ALWAYS.
3060 Error if Rd or Rm are R15. */
3065 unsigned long flags
;
3075 skip_whitespace (str
);
3077 if (((rd
= reg_required_here (& str
, 12)) == FAIL
)
3078 || (skip_past_comma (& str
) == FAIL
)
3079 || ((rm
= reg_required_here (& str
, 0)) == FAIL
))
3080 inst
.error
= BAD_ARGS
;
3082 else if (rd
== REG_PC
|| rm
== REG_PC
)
3083 inst
.error
= BAD_PC
;
3089 /* ARM V5 (argument parse)
3090 LDC2{L} <coproc>, <CRd>, <addressing mode>
3091 STC2{L} <coproc>, <CRd>, <addressing mode>
3092 Instruction is not conditional, and has 0xf in the codition field.
3093 Otherwise, it's the same as LDC/STC. */
3096 do_lstc2 (str
, flags
)
3098 unsigned long flags
;
3101 inst
.error
= BAD_COND
;
3103 skip_whitespace (str
);
3105 if (co_proc_number (& str
) == FAIL
)
3108 inst
.error
= BAD_ARGS
;
3110 else if (skip_past_comma (& str
) == FAIL
3111 || cp_reg_required_here (& str
, 12) == FAIL
)
3114 inst
.error
= BAD_ARGS
;
3116 else if (skip_past_comma (& str
) == FAIL
3117 || cp_address_required_here (& str
) == FAIL
)
3120 inst
.error
= BAD_ARGS
;
3126 /* ARM V5 (argument parse)
3127 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3128 Instruction is not conditional, and has 0xf in the condition field.
3129 Otherwise, it's the same as CDP. */
3132 do_cdp2 (str
, flags
)
3134 unsigned long flags
;
3136 skip_whitespace (str
);
3138 if (co_proc_number (& str
) == FAIL
)
3141 inst
.error
= BAD_ARGS
;
3145 if (skip_past_comma (& str
) == FAIL
3146 || cp_opc_expr (& str
, 20,4) == FAIL
)
3149 inst
.error
= BAD_ARGS
;
3153 if (skip_past_comma (& str
) == FAIL
3154 || cp_reg_required_here (& str
, 12) == FAIL
)
3157 inst
.error
= BAD_ARGS
;
3161 if (skip_past_comma (& str
) == FAIL
3162 || cp_reg_required_here (& str
, 16) == FAIL
)
3165 inst
.error
= BAD_ARGS
;
3169 if (skip_past_comma (& str
) == FAIL
3170 || cp_reg_required_here (& str
, 0) == FAIL
)
3173 inst
.error
= BAD_ARGS
;
3177 if (skip_past_comma (& str
) == SUCCESS
)
3179 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3182 inst
.error
= BAD_ARGS
;
3188 inst
.error
= BAD_FLAGS
;
3193 /* ARM V5 (argument parse)
3194 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3195 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3196 Instruction is not conditional, and has 0xf in the condition field.
3197 Otherwise, it's the same as MCR/MRC. */
3200 do_co_reg2 (str
, flags
)
3202 unsigned long flags
;
3204 skip_whitespace (str
);
3206 if (co_proc_number (& str
) == FAIL
)
3209 inst
.error
= BAD_ARGS
;
3213 if (skip_past_comma (& str
) == FAIL
3214 || cp_opc_expr (& str
, 21, 3) == FAIL
)
3217 inst
.error
= BAD_ARGS
;
3221 if (skip_past_comma (& str
) == FAIL
3222 || reg_required_here (& str
, 12) == FAIL
)
3225 inst
.error
= BAD_ARGS
;
3229 if (skip_past_comma (& str
) == FAIL
3230 || cp_reg_required_here (& str
, 16) == FAIL
)
3233 inst
.error
= BAD_ARGS
;
3237 if (skip_past_comma (& str
) == FAIL
3238 || cp_reg_required_here (& str
, 0) == FAIL
)
3241 inst
.error
= BAD_ARGS
;
3245 if (skip_past_comma (& str
) == SUCCESS
)
3247 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3250 inst
.error
= BAD_ARGS
;
3256 inst
.error
= BAD_COND
;
3261 /* THUMB V5 breakpoint instruction (argument parse)
3269 unsigned long number
;
3271 skip_whitespace (str
);
3273 /* Allow optional leading '#'. */
3274 if (is_immediate_prefix (*str
))
3277 memset (& expr
, '\0', sizeof (expr
));
3278 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3280 inst
.error
= _("bad or missing expression");
3284 number
= expr
.X_add_number
;
3286 /* Check it fits an 8 bit unsigned. */
3287 if (number
!= (number
& 0xff))
3289 inst
.error
= _("immediate value out of range");
3293 inst
.instruction
|= number
;
3298 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3299 Expects inst.instruction is set for BLX(1).
3300 Note: this is cloned from do_branch, and the reloc changed to be a
3301 new one that can cope with setting one extra bit (the H bit). */
3304 do_branch25 (str
, flags
)
3306 unsigned long flags ATTRIBUTE_UNUSED
;
3308 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3315 /* ScottB: February 5, 1998 */
3316 /* Check to see of PLT32 reloc required for the instruction. */
3318 /* arm_parse_reloc() works on input_line_pointer.
3319 We actually want to parse the operands to the branch instruction
3320 passed in 'str'. Save the input pointer and restore it later. */
3321 save_in
= input_line_pointer
;
3322 input_line_pointer
= str
;
3324 if (inst
.reloc
.exp
.X_op
== O_symbol
3326 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3328 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3329 inst
.reloc
.pc_rel
= 0;
3330 /* Modify str to point to after parsed operands, otherwise
3331 end_of_line() will complain about the (PLT) left in str. */
3332 str
= input_line_pointer
;
3336 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3337 inst
.reloc
.pc_rel
= 1;
3340 input_line_pointer
= save_in
;
3343 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3344 inst
.reloc
.pc_rel
= 1;
3345 #endif /* OBJ_ELF */
3350 /* ARM V5 branch-link-exchange instruction (argument parse)
3351 BLX <target_addr> ie BLX(1)
3352 BLX{<condition>} <Rm> ie BLX(2)
3353 Unfortunately, there are two different opcodes for this mnemonic.
3354 So, the insns[].value is not used, and the code here zaps values
3355 into inst.instruction.
3356 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
3361 unsigned long flags
;
3372 skip_whitespace (mystr
);
3373 rm
= reg_required_here (& mystr
, 0);
3375 /* The above may set inst.error. Ignore his opinion. */
3380 /* Arg is a register.
3381 Use the condition code our caller put in inst.instruction.
3382 Pass ourselves off as a BX with a funny opcode. */
3383 inst
.instruction
|= 0x012fff30;
3388 /* This must be is BLX <target address>, no condition allowed. */
3389 if (inst
.instruction
!= COND_ALWAYS
)
3391 inst
.error
= BAD_COND
;
3395 inst
.instruction
= 0xfafffffe;
3397 /* Process like a B/BL, but with a different reloc.
3398 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
3399 do_branch25 (str
, flags
);
3403 /* ARM V5 Thumb BLX (argument parse)
3404 BLX <target_addr> which is BLX(1)
3405 BLX <Rm> which is BLX(2)
3406 Unfortunately, there are two different opcodes for this mnemonic.
3407 So, the tinsns[].value is not used, and the code here zaps values
3408 into inst.instruction. */
3417 skip_whitespace (mystr
);
3418 inst
.instruction
= 0x4780;
3420 /* Note that this call is to the ARM register recognizer. BLX(2)
3421 uses the ARM register space, not the Thumb one, so a call to
3422 thumb_reg() would be wrong. */
3423 rm
= reg_required_here (& mystr
, 3);
3428 /* It's BLX(2). The .instruction was zapped with rm & is final. */
3433 /* No ARM register. This must be BLX(1). Change the .instruction. */
3434 inst
.instruction
= 0xf7ffeffe;
3437 if (my_get_expression (& inst
.reloc
.exp
, & mystr
))
3440 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BLX
;
3441 inst
.reloc
.pc_rel
= 1;
3444 end_of_line (mystr
);
3447 /* ARM V5 breakpoint instruction (argument parse)
3448 BKPT <16 bit unsigned immediate>
3449 Instruction is not conditional.
3450 The bit pattern given in insns[] has the COND_ALWAYS condition,
3451 and it is an error if the caller tried to override that.
3452 Note "flags" is nonzero if a flag was supplied (which is an error). */
3455 do_bkpt (str
, flags
)
3457 unsigned long flags
;
3460 unsigned long number
;
3462 skip_whitespace (str
);
3464 /* Allow optional leading '#'. */
3465 if (is_immediate_prefix (* str
))
3468 memset (& expr
, '\0', sizeof (expr
));
3470 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3472 inst
.error
= _("bad or missing expression");
3476 number
= expr
.X_add_number
;
3478 /* Check it fits a 16 bit unsigned. */
3479 if (number
!= (number
& 0xffff))
3481 inst
.error
= _("immediate value out of range");
3485 /* Top 12 of 16 bits to bits 19:8. */
3486 inst
.instruction
|= (number
& 0xfff0) << 4;
3488 /* Bottom 4 of 16 bits to bits 3:0. */
3489 inst
.instruction
|= number
& 0xf;
3494 inst
.error
= BAD_FLAGS
;
3497 /* Xscale multiply-accumulate (argument parse)
3500 MIAxycc acc0,Rm,Rs. */
3505 unsigned long flags
;
3513 else if (accum0_required_here (& str
) == FAIL
)
3514 inst
.error
= ERR_NO_ACCUM
;
3516 else if (skip_past_comma (& str
) == FAIL
3517 || (rm
= reg_required_here (& str
, 0)) == FAIL
)
3518 inst
.error
= BAD_ARGS
;
3520 else if (skip_past_comma (& str
) == FAIL
3521 || (rs
= reg_required_here (& str
, 12)) == FAIL
)
3522 inst
.error
= BAD_ARGS
;
3524 /* inst.instruction has now been zapped with both rm and rs. */
3525 else if (rm
== REG_PC
|| rs
== REG_PC
)
3526 inst
.error
= BAD_PC
; /* Undefined result if rm or rs is R15. */
3532 /* Xscale move-accumulator-register (argument parse)
3534 MARcc acc0,RdLo,RdHi. */
3539 unsigned long flags
;
3546 else if (accum0_required_here (& str
) == FAIL
)
3547 inst
.error
= ERR_NO_ACCUM
;
3549 else if (skip_past_comma (& str
) == FAIL
3550 || (rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3551 inst
.error
= BAD_ARGS
;
3553 else if (skip_past_comma (& str
) == FAIL
3554 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3555 inst
.error
= BAD_ARGS
;
3557 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3558 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3559 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3565 /* Xscale move-register-accumulator (argument parse)
3567 MRAcc RdLo,RdHi,acc0. */
3572 unsigned long flags
;
3583 skip_whitespace (str
);
3585 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3586 inst
.error
= BAD_ARGS
;
3588 else if (skip_past_comma (& str
) == FAIL
3589 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3590 inst
.error
= BAD_ARGS
;
3592 else if (skip_past_comma (& str
) == FAIL
3593 || accum0_required_here (& str
) == FAIL
)
3594 inst
.error
= ERR_NO_ACCUM
;
3596 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3597 else if (rdlo
== rdhi
)
3598 inst
.error
= BAD_ARGS
; /* Undefined result if 2 writes to same reg. */
3600 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3601 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3606 /* ARMv5TE: Preload-Cache
3610 Syntactically, like LDR with B=1, W=0, L=1. */
3615 unsigned long flags
;
3625 skip_whitespace (str
);
3629 inst
.error
= _("'[' expected after PLD mnemonic");
3634 skip_whitespace (str
);
3636 if ((rd
= reg_required_here (& str
, 16)) == FAIL
)
3639 skip_whitespace (str
);
3645 skip_whitespace (str
);
3647 if (skip_past_comma (& str
) == SUCCESS
)
3649 if (ldst_extend (& str
, 0) == FAIL
)
3652 else if (* str
== '!') /* [Rn]! */
3654 inst
.error
= _("writeback used in preload instruction");
3658 inst
.instruction
|= INDEX_UP
| PRE_INDEX
;
3660 else /* [Rn, ...] */
3662 if (skip_past_comma (& str
) == FAIL
)
3664 inst
.error
= _("pre-indexed expression expected");
3668 if (ldst_extend (& str
, 0) == FAIL
)
3671 skip_whitespace (str
);
3675 inst
.error
= _("missing ]");
3680 skip_whitespace (str
);
3682 if (* str
== '!') /* [Rn]! */
3684 inst
.error
= _("writeback used in preload instruction");
3688 inst
.instruction
|= PRE_INDEX
;
3694 /* ARMv5TE load-consecutive (argument parse)
3701 do_ldrd (str
, flags
)
3703 unsigned long flags
;
3708 if (flags
!= DOUBLE_LOAD_FLAG
)
3710 /* Change instruction pattern to normal ldr/str. */
3711 if (inst
.instruction
& 0x20)
3712 inst
.instruction
= (inst
.instruction
& COND_MASK
) | 0x04000000; /* str */
3714 inst
.instruction
= (inst
.instruction
& COND_MASK
) | 0x04100000; /* ldr */
3716 /* Perform a normal load/store instruction parse. */
3717 do_ldst (str
, flags
);
3722 if ((cpu_variant
& ARM_EXT_XSCALE
) != ARM_EXT_XSCALE
)
3724 static char buff
[128];
3727 while (ISSPACE (*str
))
3731 /* Deny all knowledge. */
3732 sprintf (buff
, _("bad instruction '%.100s'"), str
);
3737 skip_whitespace (str
);
3739 if ((rd
= reg_required_here (& str
, 12)) == FAIL
)
3741 inst
.error
= BAD_ARGS
;
3745 if (skip_past_comma (& str
) == FAIL
3746 || (rn
= ld_mode_required_here (& str
)) == FAIL
)
3749 inst
.error
= BAD_ARGS
;
3753 /* inst.instruction has now been zapped with Rd and the addressing mode. */
3754 if (rd
& 1) /* Unpredictable result if Rd is odd. */
3756 inst
.error
= _("Destination register must be even");
3760 if (rd
== REG_LR
|| rd
== 12)
3762 inst
.error
= _("r12 or r14 not allowed here");
3766 if (((rd
== rn
) || (rd
+ 1 == rn
))
3768 ((inst
.instruction
& WRITE_BACK
)
3769 || (!(inst
.instruction
& PRE_INDEX
))))
3770 as_warn (_("pre/post-indexing used when modified address register is destination"));
3775 /* Returns the index into fp_values of a floating point number,
3776 or -1 if not in the table. */
3779 my_get_float_expression (str
)
3782 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
3788 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
3790 /* Look for a raw floating point number. */
3791 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
3792 && is_end_of_line
[(unsigned char) *save_in
])
3794 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
3796 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
3798 if (words
[j
] != fp_values
[i
][j
])
3802 if (j
== MAX_LITTLENUMS
)
3810 /* Try and parse a more complex expression, this will probably fail
3811 unless the code uses a floating point prefix (eg "0f"). */
3812 save_in
= input_line_pointer
;
3813 input_line_pointer
= *str
;
3814 if (expression (&exp
) == absolute_section
3815 && exp
.X_op
== O_big
3816 && exp
.X_add_number
< 0)
3818 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
3820 if (gen_to_words (words
, 5, (long) 15) == 0)
3822 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
3824 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
3826 if (words
[j
] != fp_values
[i
][j
])
3830 if (j
== MAX_LITTLENUMS
)
3832 *str
= input_line_pointer
;
3833 input_line_pointer
= save_in
;
3840 *str
= input_line_pointer
;
3841 input_line_pointer
= save_in
;
3845 /* Return true if anything in the expression is a bignum. */
3848 walk_no_bignums (sp
)
3851 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
3854 if (symbol_get_value_expression (sp
)->X_add_symbol
)
3856 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
3857 || (symbol_get_value_expression (sp
)->X_op_symbol
3858 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
3865 my_get_expression (ep
, str
)
3872 save_in
= input_line_pointer
;
3873 input_line_pointer
= *str
;
3874 seg
= expression (ep
);
3877 if (seg
!= absolute_section
3878 && seg
!= text_section
3879 && seg
!= data_section
3880 && seg
!= bss_section
3881 && seg
!= undefined_section
)
3883 inst
.error
= _("bad_segment");
3884 *str
= input_line_pointer
;
3885 input_line_pointer
= save_in
;
3890 /* Get rid of any bignums now, so that we don't generate an error for which
3891 we can't establish a line number later on. Big numbers are never valid
3892 in instructions, which is where this routine is always called. */
3893 if (ep
->X_op
== O_big
3894 || (ep
->X_add_symbol
3895 && (walk_no_bignums (ep
->X_add_symbol
)
3897 && walk_no_bignums (ep
->X_op_symbol
)))))
3899 inst
.error
= _("Invalid constant");
3900 *str
= input_line_pointer
;
3901 input_line_pointer
= save_in
;
3905 *str
= input_line_pointer
;
3906 input_line_pointer
= save_in
;
3910 /* UNRESTRICT should be one if <shift> <register> is permitted for this
3914 decode_shift (str
, unrestrict
)
3918 const struct asm_shift_name
* shift
;
3922 skip_whitespace (* str
);
3924 for (p
= * str
; ISALPHA (* p
); p
++)
3929 inst
.error
= _("Shift expression expected");
3935 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
3940 inst
.error
= _("Shift expression expected");
3944 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
3946 if (shift
->properties
->index
== SHIFT_RRX
)
3949 inst
.instruction
|= shift
->properties
->bit_field
;
3953 skip_whitespace (p
);
3955 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
3957 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
3961 else if (! is_immediate_prefix (* p
))
3963 inst
.error
= (unrestrict
3964 ? _("shift requires register or #expression")
3965 : _("shift requires #expression"));
3973 if (my_get_expression (& inst
.reloc
.exp
, & p
))
3976 /* Validate some simple #expressions. */
3977 if (inst
.reloc
.exp
.X_op
== O_constant
)
3979 unsigned num
= inst
.reloc
.exp
.X_add_number
;
3981 /* Reject operations greater than 32. */
3983 /* Reject a shift of 0 unless the mode allows it. */
3984 || (num
== 0 && shift
->properties
->allows_0
== 0)
3985 /* Reject a shift of 32 unless the mode allows it. */
3986 || (num
== 32 && shift
->properties
->allows_32
== 0)
3989 /* As a special case we allow a shift of zero for
3990 modes that do not support it to be recoded as an
3991 logical shift left of zero (ie nothing). We warn
3992 about this though. */
3995 as_warn (_("Shift of 0 ignored."));
3996 shift
= & shift_names
[0];
3997 assert (shift
->properties
->index
== SHIFT_LSL
);
4001 inst
.error
= _("Invalid immediate shift");
4006 /* Shifts of 32 are encoded as 0, for those shifts that
4011 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
4015 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
4016 inst
.reloc
.pc_rel
= 0;
4017 inst
.instruction
|= shift
->properties
->bit_field
;
4024 /* Do those data_ops which can take a negative immediate constant
4025 by altering the instuction. A bit of a hack really.
4029 by inverting the second operand, and
4032 by negating the second operand. */
4035 negate_data_op (instruction
, value
)
4036 unsigned long * instruction
;
4037 unsigned long value
;
4040 unsigned long negated
, inverted
;
4042 negated
= validate_immediate (-value
);
4043 inverted
= validate_immediate (~value
);
4045 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
4048 /* First negates. */
4049 case OPCODE_SUB
: /* ADD <-> SUB */
4050 new_inst
= OPCODE_ADD
;
4055 new_inst
= OPCODE_SUB
;
4059 case OPCODE_CMP
: /* CMP <-> CMN */
4060 new_inst
= OPCODE_CMN
;
4065 new_inst
= OPCODE_CMP
;
4069 /* Now Inverted ops. */
4070 case OPCODE_MOV
: /* MOV <-> MVN */
4071 new_inst
= OPCODE_MVN
;
4076 new_inst
= OPCODE_MOV
;
4080 case OPCODE_AND
: /* AND <-> BIC */
4081 new_inst
= OPCODE_BIC
;
4086 new_inst
= OPCODE_AND
;
4090 case OPCODE_ADC
: /* ADC <-> SBC */
4091 new_inst
= OPCODE_SBC
;
4096 new_inst
= OPCODE_ADC
;
4100 /* We cannot do anything. */
4105 if (value
== (unsigned) FAIL
)
4108 *instruction
&= OPCODE_MASK
;
4109 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
4120 skip_whitespace (* str
);
4122 if (reg_required_here (str
, 0) != FAIL
)
4124 if (skip_past_comma (str
) == SUCCESS
)
4125 /* Shift operation on register. */
4126 return decode_shift (str
, NO_SHIFT_RESTRICT
);
4132 /* Immediate expression. */
4133 if (is_immediate_prefix (**str
))
4138 if (my_get_expression (&inst
.reloc
.exp
, str
))
4141 if (inst
.reloc
.exp
.X_add_symbol
)
4143 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4144 inst
.reloc
.pc_rel
= 0;
4148 if (skip_past_comma (str
) == SUCCESS
)
4150 /* #x, y -- ie explicit rotation by Y. */
4151 if (my_get_expression (&expr
, str
))
4154 if (expr
.X_op
!= O_constant
)
4156 inst
.error
= _("Constant expression expected");
4160 /* Rotate must be a multiple of 2. */
4161 if (((unsigned) expr
.X_add_number
) > 30
4162 || (expr
.X_add_number
& 1) != 0
4163 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
4165 inst
.error
= _("Invalid constant");
4168 inst
.instruction
|= INST_IMMEDIATE
;
4169 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4170 inst
.instruction
|= expr
.X_add_number
<< 7;
4174 /* Implicit rotation, select a suitable one. */
4175 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4179 /* Can't be done. Perhaps the code reads something like
4180 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
4181 if ((value
= negate_data_op (&inst
.instruction
,
4182 inst
.reloc
.exp
.X_add_number
))
4185 inst
.error
= _("Invalid constant");
4190 inst
.instruction
|= value
;
4193 inst
.instruction
|= INST_IMMEDIATE
;
4198 inst
.error
= _("Register or shift expression expected");
4207 skip_whitespace (* str
);
4209 if (fp_reg_required_here (str
, 0) != FAIL
)
4213 /* Immediate expression. */
4214 if (*((*str
)++) == '#')
4220 skip_whitespace (* str
);
4222 /* First try and match exact strings, this is to guarantee
4223 that some formats will work even for cross assembly. */
4225 for (i
= 0; fp_const
[i
]; i
++)
4227 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
4231 *str
+= strlen (fp_const
[i
]);
4232 if (is_end_of_line
[(unsigned char) **str
])
4234 inst
.instruction
|= i
+ 8;
4241 /* Just because we didn't get a match doesn't mean that the
4242 constant isn't valid, just that it is in a format that we
4243 don't automatically recognize. Try parsing it with
4244 the standard expression routines. */
4245 if ((i
= my_get_float_expression (str
)) >= 0)
4247 inst
.instruction
|= i
+ 8;
4251 inst
.error
= _("Invalid floating point immediate expression");
4255 _("Floating point register or immediate expression expected");
4261 do_arit (str
, flags
)
4263 unsigned long flags
;
4265 skip_whitespace (str
);
4267 if (reg_required_here (&str
, 12) == FAIL
4268 || skip_past_comma (&str
) == FAIL
4269 || reg_required_here (&str
, 16) == FAIL
4270 || skip_past_comma (&str
) == FAIL
4271 || data_op2 (&str
) == FAIL
)
4274 inst
.error
= BAD_ARGS
;
4278 inst
.instruction
|= flags
;
4286 unsigned long flags
;
4288 skip_whitespace (str
);
4290 if (reg_required_here (&str
, 12) == FAIL
4291 || skip_past_comma (&str
) == FAIL
4292 || my_get_expression (&inst
.reloc
.exp
, &str
))
4295 inst
.error
= BAD_ARGS
;
4299 if (flags
& 0x00400000)
4301 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4302 into a relative address of the form:
4303 add rd, pc, #low(label-.-8)"
4304 add rd, rd, #high(label-.-8)" */
4305 /* Frag hacking will turn this into a sub instruction if the offset turns
4306 out to be negative. */
4307 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
4308 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
4309 inst
.reloc
.pc_rel
= 1;
4310 inst
.instruction
|= flags
& ~0x00400000;
4311 inst
.size
= INSN_SIZE
* 2;
4315 /* This is a pseudo-op of the form "adr rd, label" to be converted
4316 into a relative address of the form "add rd, pc, #label-.-8". */
4317 /* Frag hacking will turn this into a sub instruction if the offset turns
4318 out to be negative. */
4319 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4320 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
4321 inst
.reloc
.pc_rel
= 1;
4322 inst
.instruction
|= flags
;
4331 unsigned long flags
;
4333 skip_whitespace (str
);
4335 if (reg_required_here (&str
, 16) == FAIL
)
4338 inst
.error
= BAD_ARGS
;
4342 if (skip_past_comma (&str
) == FAIL
4343 || data_op2 (&str
) == FAIL
)
4346 inst
.error
= BAD_ARGS
;
4350 inst
.instruction
|= flags
;
4351 if ((flags
& 0x0000f000) == 0)
4352 inst
.instruction
|= CONDS_BIT
;
4361 unsigned long flags
;
4363 skip_whitespace (str
);
4365 if (reg_required_here (&str
, 12) == FAIL
)
4368 inst
.error
= BAD_ARGS
;
4372 if (skip_past_comma (&str
) == FAIL
4373 || data_op2 (&str
) == FAIL
)
4376 inst
.error
= BAD_ARGS
;
4380 inst
.instruction
|= flags
;
4386 ldst_extend (str
, hwse
)
4397 if (my_get_expression (& inst
.reloc
.exp
, str
))
4400 if (inst
.reloc
.exp
.X_op
== O_constant
)
4402 int value
= inst
.reloc
.exp
.X_add_number
;
4404 if ((hwse
&& (value
< -255 || value
> 255))
4405 || (value
< -4095 || value
> 4095))
4407 inst
.error
= _("address offset too large");
4417 /* Halfword and signextension instructions have the
4418 immediate value split across bits 11..8 and bits 3..0. */
4420 inst
.instruction
|= (add
| HWOFFSET_IMM
4421 | ((value
>> 4) << 8) | (value
& 0xF));
4423 inst
.instruction
|= add
| value
;
4429 inst
.instruction
|= HWOFFSET_IMM
;
4430 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
4433 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4434 inst
.reloc
.pc_rel
= 0;
4447 if (reg_required_here (str
, 0) == FAIL
)
4451 inst
.instruction
|= add
;
4454 inst
.instruction
|= add
| OFFSET_REG
;
4455 if (skip_past_comma (str
) == SUCCESS
)
4456 return decode_shift (str
, SHIFT_RESTRICT
);
4464 do_ldst (str
, flags
)
4466 unsigned long flags
;
4473 /* This is not ideal, but it is the simplest way of dealing with the
4474 ARM7T halfword instructions (since they use a different
4475 encoding, but the same mnemonic): */
4476 halfword
= (flags
& 0x80000000) != 0;
4479 /* This is actually a load/store of a halfword, or a
4480 signed-extension load. */
4481 if ((cpu_variant
& ARM_EXT_V4
) == 0)
4484 = _("Processor does not support halfwords or signed bytes");
4488 inst
.instruction
= ((inst
.instruction
& COND_MASK
)
4489 | (flags
& ~COND_MASK
));
4494 skip_whitespace (str
);
4496 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
4499 inst
.error
= BAD_ARGS
;
4503 if (skip_past_comma (& str
) == FAIL
)
4505 inst
.error
= _("Address expected");
4515 skip_whitespace (str
);
4517 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4520 /* Conflicts can occur on stores as well as loads. */
4521 conflict_reg
= (conflict_reg
== reg
);
4523 skip_whitespace (str
);
4529 if (skip_past_comma (&str
) == SUCCESS
)
4531 /* [Rn],... (post inc) */
4532 if (ldst_extend (&str
, halfword
) == FAIL
)
4536 if (flags
& TRANS_BIT
)
4537 as_warn (_("Rn and Rd must be different in %s"),
4538 ((inst
.instruction
& LOAD_BIT
)
4539 ? "LDRT" : "STRT"));
4541 as_warn (_("%s register same as write-back base"),
4542 ((inst
.instruction
& LOAD_BIT
)
4543 ? _("destination") : _("source")));
4550 inst
.instruction
|= HWOFFSET_IMM
;
4552 skip_whitespace (str
);
4557 as_warn (_("%s register same as write-back base"),
4558 ((inst
.instruction
& LOAD_BIT
)
4559 ? _("destination") : _("source")));
4561 inst
.instruction
|= WRITE_BACK
;
4565 if (flags
& TRANS_BIT
)
4568 as_warn (_("Rn and Rd must be different in %s"),
4569 ((inst
.instruction
& LOAD_BIT
)
4570 ? "LDRT" : "STRT"));
4579 if (skip_past_comma (&str
) == FAIL
)
4581 inst
.error
= _("pre-indexed expression expected");
4586 if (ldst_extend (&str
, halfword
) == FAIL
)
4589 skip_whitespace (str
);
4593 inst
.error
= _("missing ]");
4597 skip_whitespace (str
);
4602 as_warn (_("%s register same as write-back base"),
4603 ((inst
.instruction
& LOAD_BIT
)
4604 ? _("destination") : _("source")));
4606 inst
.instruction
|= WRITE_BACK
;
4610 else if (*str
== '=')
4612 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4615 skip_whitespace (str
);
4617 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4620 if (inst
.reloc
.exp
.X_op
!= O_constant
4621 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4623 inst
.error
= _("Constant expression expected");
4627 if (inst
.reloc
.exp
.X_op
== O_constant
)
4629 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4633 /* This can be done with a mov instruction. */
4634 inst
.instruction
&= LITERAL_MASK
;
4635 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
4636 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
4641 value
= validate_immediate (~ inst
.reloc
.exp
.X_add_number
);
4645 /* This can be done with a mvn instruction. */
4646 inst
.instruction
&= LITERAL_MASK
;
4647 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MVN
<< DATA_OP_SHIFT
);
4648 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
4654 /* Insert into literal pool. */
4655 if (add_to_lit_pool () == FAIL
)
4658 inst
.error
= _("literal pool insertion failed");
4662 /* Change the instruction exp to point to the pool. */
4665 inst
.instruction
|= HWOFFSET_IMM
;
4666 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
4669 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
4671 inst
.reloc
.pc_rel
= 1;
4672 inst
.instruction
|= (REG_PC
<< 16);
4677 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4682 inst
.instruction
|= HWOFFSET_IMM
;
4683 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
4686 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4688 /* PC rel adjust. */
4689 inst
.reloc
.exp
.X_add_number
-= 8;
4691 inst
.reloc
.pc_rel
= 1;
4692 inst
.instruction
|= (REG_PC
<< 16);
4696 if (pre_inc
&& (flags
& TRANS_BIT
))
4697 inst
.error
= _("Pre-increment instruction with translate");
4699 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
4708 char * str
= * strp
;
4712 /* We come back here if we get ranges concatenated by '+' or '|'. */
4727 skip_whitespace (str
);
4729 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
4738 inst
.error
= _("Bad range in register list");
4742 for (i
= cur_reg
+ 1; i
< reg
; i
++)
4744 if (range
& (1 << i
))
4746 (_("Warning: Duplicated register (r%d) in register list"),
4754 if (range
& (1 << reg
))
4755 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
4757 else if (reg
<= cur_reg
)
4758 as_tsktsk (_("Warning: Register range not in ascending order"));
4763 while (skip_past_comma (&str
) != FAIL
4764 || (in_range
= 1, *str
++ == '-'));
4766 skip_whitespace (str
);
4770 inst
.error
= _("Missing `}'");
4778 if (my_get_expression (&expr
, &str
))
4781 if (expr
.X_op
== O_constant
)
4783 if (expr
.X_add_number
4784 != (expr
.X_add_number
& 0x0000ffff))
4786 inst
.error
= _("invalid register mask");
4790 if ((range
& expr
.X_add_number
) != 0)
4792 int regno
= range
& expr
.X_add_number
;
4795 regno
= (1 << regno
) - 1;
4797 (_("Warning: Duplicated register (r%d) in register list"),
4801 range
|= expr
.X_add_number
;
4805 if (inst
.reloc
.type
!= 0)
4807 inst
.error
= _("expression too complex");
4811 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
4812 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
4813 inst
.reloc
.pc_rel
= 0;
4817 skip_whitespace (str
);
4819 if (*str
== '|' || *str
== '+')
4825 while (another_range
);
4832 do_ldmstm (str
, flags
)
4834 unsigned long flags
;
4839 skip_whitespace (str
);
4841 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
4844 if (base_reg
== REG_PC
)
4846 inst
.error
= _("r15 not allowed as base register");
4850 skip_whitespace (str
);
4854 flags
|= WRITE_BACK
;
4858 if (skip_past_comma (&str
) == FAIL
4859 || (range
= reg_list (&str
)) == FAIL
)
4862 inst
.error
= BAD_ARGS
;
4869 flags
|= LDM_TYPE_2_OR_3
;
4872 inst
.instruction
|= flags
| range
;
4880 unsigned long flags
;
4882 skip_whitespace (str
);
4884 /* Allow optional leading '#'. */
4885 if (is_immediate_prefix (*str
))
4888 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4891 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4892 inst
.reloc
.pc_rel
= 0;
4893 inst
.instruction
|= flags
;
4901 do_swap (str
, flags
)
4903 unsigned long flags
;
4907 skip_whitespace (str
);
4909 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
4914 inst
.error
= _("r15 not allowed in swap");
4918 if (skip_past_comma (&str
) == FAIL
4919 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
4922 inst
.error
= BAD_ARGS
;
4928 inst
.error
= _("r15 not allowed in swap");
4932 if (skip_past_comma (&str
) == FAIL
4935 inst
.error
= BAD_ARGS
;
4939 skip_whitespace (str
);
4941 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4946 inst
.error
= BAD_PC
;
4950 skip_whitespace (str
);
4954 inst
.error
= _("missing ]");
4958 inst
.instruction
|= flags
;
4964 do_branch (str
, flags
)
4966 unsigned long flags ATTRIBUTE_UNUSED
;
4968 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4975 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
4976 required for the instruction. */
4978 /* arm_parse_reloc () works on input_line_pointer.
4979 We actually want to parse the operands to the branch instruction
4980 passed in 'str'. Save the input pointer and restore it later. */
4981 save_in
= input_line_pointer
;
4982 input_line_pointer
= str
;
4983 if (inst
.reloc
.exp
.X_op
== O_symbol
4985 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
4987 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
4988 inst
.reloc
.pc_rel
= 0;
4989 /* Modify str to point to after parsed operands, otherwise
4990 end_of_line() will complain about the (PLT) left in str. */
4991 str
= input_line_pointer
;
4995 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
4996 inst
.reloc
.pc_rel
= 1;
4998 input_line_pointer
= save_in
;
5001 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
5002 inst
.reloc
.pc_rel
= 1;
5003 #endif /* OBJ_ELF */
5012 unsigned long flags ATTRIBUTE_UNUSED
;
5016 skip_whitespace (str
);
5018 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
5020 inst
.error
= BAD_ARGS
;
5024 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
5026 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
5034 unsigned long flags ATTRIBUTE_UNUSED
;
5036 /* Co-processor data operation.
5037 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
5038 skip_whitespace (str
);
5040 if (co_proc_number (&str
) == FAIL
)
5043 inst
.error
= BAD_ARGS
;
5047 if (skip_past_comma (&str
) == FAIL
5048 || cp_opc_expr (&str
, 20,4) == FAIL
)
5051 inst
.error
= BAD_ARGS
;
5055 if (skip_past_comma (&str
) == FAIL
5056 || cp_reg_required_here (&str
, 12) == FAIL
)
5059 inst
.error
= BAD_ARGS
;
5063 if (skip_past_comma (&str
) == FAIL
5064 || cp_reg_required_here (&str
, 16) == FAIL
)
5067 inst
.error
= BAD_ARGS
;
5071 if (skip_past_comma (&str
) == FAIL
5072 || cp_reg_required_here (&str
, 0) == FAIL
)
5075 inst
.error
= BAD_ARGS
;
5079 if (skip_past_comma (&str
) == SUCCESS
)
5081 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5084 inst
.error
= BAD_ARGS
;
5094 do_lstc (str
, flags
)
5096 unsigned long flags
;
5098 /* Co-processor register load/store.
5099 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
5101 skip_whitespace (str
);
5103 if (co_proc_number (&str
) == FAIL
)
5106 inst
.error
= BAD_ARGS
;
5110 if (skip_past_comma (&str
) == FAIL
5111 || cp_reg_required_here (&str
, 12) == FAIL
)
5114 inst
.error
= BAD_ARGS
;
5118 if (skip_past_comma (&str
) == FAIL
5119 || cp_address_required_here (&str
) == FAIL
)
5122 inst
.error
= BAD_ARGS
;
5126 inst
.instruction
|= flags
;
5132 do_co_reg (str
, flags
)
5134 unsigned long flags
;
5136 /* Co-processor register transfer.
5137 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
5139 skip_whitespace (str
);
5141 if (co_proc_number (&str
) == FAIL
)
5144 inst
.error
= BAD_ARGS
;
5148 if (skip_past_comma (&str
) == FAIL
5149 || cp_opc_expr (&str
, 21, 3) == FAIL
)
5152 inst
.error
= BAD_ARGS
;
5156 if (skip_past_comma (&str
) == FAIL
5157 || reg_required_here (&str
, 12) == FAIL
)
5160 inst
.error
= BAD_ARGS
;
5164 if (skip_past_comma (&str
) == FAIL
5165 || cp_reg_required_here (&str
, 16) == FAIL
)
5168 inst
.error
= BAD_ARGS
;
5172 if (skip_past_comma (&str
) == FAIL
5173 || cp_reg_required_here (&str
, 0) == FAIL
)
5176 inst
.error
= BAD_ARGS
;
5180 if (skip_past_comma (&str
) == SUCCESS
)
5182 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5185 inst
.error
= BAD_ARGS
;
5191 inst
.error
= BAD_COND
;
5199 do_fpa_ctrl (str
, flags
)
5201 unsigned long flags ATTRIBUTE_UNUSED
;
5203 /* FP control registers.
5204 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
5206 skip_whitespace (str
);
5208 if (reg_required_here (&str
, 12) == FAIL
)
5211 inst
.error
= BAD_ARGS
;
5220 do_fpa_ldst (str
, flags
)
5222 unsigned long flags ATTRIBUTE_UNUSED
;
5224 skip_whitespace (str
);
5226 switch (inst
.suffix
)
5231 inst
.instruction
|= CP_T_X
;
5234 inst
.instruction
|= CP_T_Y
;
5237 inst
.instruction
|= CP_T_X
| CP_T_Y
;
5243 if (fp_reg_required_here (&str
, 12) == FAIL
)
5246 inst
.error
= BAD_ARGS
;
5250 if (skip_past_comma (&str
) == FAIL
5251 || cp_address_required_here (&str
) == FAIL
)
5254 inst
.error
= BAD_ARGS
;
5262 do_fpa_ldmstm (str
, flags
)
5264 unsigned long flags
;
5268 skip_whitespace (str
);
5270 if (fp_reg_required_here (&str
, 12) == FAIL
)
5273 inst
.error
= BAD_ARGS
;
5277 /* Get Number of registers to transfer. */
5278 if (skip_past_comma (&str
) == FAIL
5279 || my_get_expression (&inst
.reloc
.exp
, &str
))
5282 inst
.error
= _("constant expression expected");
5286 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5288 inst
.error
= _("Constant value required for number of registers");
5292 num_regs
= inst
.reloc
.exp
.X_add_number
;
5294 if (num_regs
< 1 || num_regs
> 4)
5296 inst
.error
= _("number of registers must be in the range [1:4]");
5303 inst
.instruction
|= CP_T_X
;
5306 inst
.instruction
|= CP_T_Y
;
5309 inst
.instruction
|= CP_T_Y
| CP_T_X
;
5323 /* The instruction specified "ea" or "fd", so we can only accept
5324 [Rn]{!}. The instruction does not really support stacking or
5325 unstacking, so we have to emulate these by setting appropriate
5326 bits and offsets. */
5327 if (skip_past_comma (&str
) == FAIL
5331 inst
.error
= BAD_ARGS
;
5336 skip_whitespace (str
);
5338 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5341 skip_whitespace (str
);
5345 inst
.error
= BAD_ARGS
;
5357 _("R15 not allowed as base register with write-back");
5364 if (flags
& CP_T_Pre
)
5366 /* Pre-decrement. */
5367 offset
= 3 * num_regs
;
5373 /* Post-increment. */
5377 offset
= 3 * num_regs
;
5381 /* No write-back, so convert this into a standard pre-increment
5382 instruction -- aesthetically more pleasing. */
5383 flags
= CP_T_Pre
| CP_T_UD
;
5388 inst
.instruction
|= flags
| offset
;
5390 else if (skip_past_comma (&str
) == FAIL
5391 || cp_address_required_here (&str
) == FAIL
)
5394 inst
.error
= BAD_ARGS
;
5402 do_fpa_dyadic (str
, flags
)
5404 unsigned long flags
;
5406 skip_whitespace (str
);
5408 switch (inst
.suffix
)
5413 inst
.instruction
|= 0x00000080;
5416 inst
.instruction
|= 0x00080000;
5422 if (fp_reg_required_here (&str
, 12) == FAIL
)
5425 inst
.error
= BAD_ARGS
;
5429 if (skip_past_comma (&str
) == FAIL
5430 || fp_reg_required_here (&str
, 16) == FAIL
)
5433 inst
.error
= BAD_ARGS
;
5437 if (skip_past_comma (&str
) == FAIL
5438 || fp_op2 (&str
) == FAIL
)
5441 inst
.error
= BAD_ARGS
;
5445 inst
.instruction
|= flags
;
5451 do_fpa_monadic (str
, flags
)
5453 unsigned long flags
;
5455 skip_whitespace (str
);
5457 switch (inst
.suffix
)
5462 inst
.instruction
|= 0x00000080;
5465 inst
.instruction
|= 0x00080000;
5471 if (fp_reg_required_here (&str
, 12) == FAIL
)
5474 inst
.error
= BAD_ARGS
;
5478 if (skip_past_comma (&str
) == FAIL
5479 || fp_op2 (&str
) == FAIL
)
5482 inst
.error
= BAD_ARGS
;
5486 inst
.instruction
|= flags
;
5492 do_fpa_cmp (str
, flags
)
5494 unsigned long flags
;
5496 skip_whitespace (str
);
5498 if (fp_reg_required_here (&str
, 16) == FAIL
)
5501 inst
.error
= BAD_ARGS
;
5505 if (skip_past_comma (&str
) == FAIL
5506 || fp_op2 (&str
) == FAIL
)
5509 inst
.error
= BAD_ARGS
;
5513 inst
.instruction
|= flags
;
5519 do_fpa_from_reg (str
, flags
)
5521 unsigned long flags
;
5523 skip_whitespace (str
);
5525 switch (inst
.suffix
)
5530 inst
.instruction
|= 0x00000080;
5533 inst
.instruction
|= 0x00080000;
5539 if (fp_reg_required_here (&str
, 16) == FAIL
)
5542 inst
.error
= BAD_ARGS
;
5546 if (skip_past_comma (&str
) == FAIL
5547 || reg_required_here (&str
, 12) == FAIL
)
5550 inst
.error
= BAD_ARGS
;
5554 inst
.instruction
|= flags
;
5560 do_fpa_to_reg (str
, flags
)
5562 unsigned long flags
;
5564 skip_whitespace (str
);
5566 if (reg_required_here (&str
, 12) == FAIL
)
5569 if (skip_past_comma (&str
) == FAIL
5570 || fp_reg_required_here (&str
, 0) == FAIL
)
5573 inst
.error
= BAD_ARGS
;
5577 inst
.instruction
|= flags
;
5582 /* Thumb specific routines. */
5584 /* Parse and validate that a register is of the right form, this saves
5585 repeated checking of this information in many similar cases.
5586 Unlike the 32-bit case we do not insert the register into the opcode
5587 here, since the position is often unknown until the full instruction
5591 thumb_reg (strp
, hi_lo
)
5597 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
5605 inst
.error
= _("lo register required");
5613 inst
.error
= _("hi register required");
5625 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
5629 thumb_add_sub (str
, subtract
)
5633 int Rd
, Rs
, Rn
= FAIL
;
5635 skip_whitespace (str
);
5637 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
5638 || skip_past_comma (&str
) == FAIL
)
5641 inst
.error
= BAD_ARGS
;
5645 if (is_immediate_prefix (*str
))
5649 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5654 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5657 if (skip_past_comma (&str
) == FAIL
)
5659 /* Two operand format, shuffle the registers
5660 and pretend there are 3. */
5664 else if (is_immediate_prefix (*str
))
5667 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5670 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5674 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5675 for the latter case, EXPR contains the immediate that was found. */
5678 /* All register format. */
5679 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
5683 inst
.error
= _("dest and source1 must be the same register");
5687 /* Can't do this for SUB. */
5690 inst
.error
= _("subtract valid only on lo regs");
5694 inst
.instruction
= (T_OPCODE_ADD_HI
5695 | (Rd
> 7 ? THUMB_H1
: 0)
5696 | (Rn
> 7 ? THUMB_H2
: 0));
5697 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
5701 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
5702 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
5707 /* Immediate expression, now things start to get nasty. */
5709 /* First deal with HI regs, only very restricted cases allowed:
5710 Adjusting SP, and using PC or SP to get an address. */
5711 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
5712 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
5714 inst
.error
= _("invalid Hi register with immediate");
5718 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5720 /* Value isn't known yet, all we can do is store all the fragments
5721 we know about in the instruction and let the reloc hacking
5723 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
5724 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
5728 int offset
= inst
.reloc
.exp
.X_add_number
;
5738 /* Quick check, in case offset is MIN_INT. */
5741 inst
.error
= _("immediate value out of range");
5750 if (offset
& ~0x1fc)
5752 inst
.error
= _("invalid immediate value for stack adjust");
5755 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5756 inst
.instruction
|= offset
>> 2;
5758 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
5761 || (offset
& ~0x3fc))
5763 inst
.error
= _("invalid immediate for address calculation");
5766 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
5768 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
5774 inst
.error
= _("immediate value out of range");
5777 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5778 inst
.instruction
|= (Rd
<< 8) | offset
;
5784 inst
.error
= _("immediate value out of range");
5787 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5788 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
5797 thumb_shift (str
, shift
)
5801 int Rd
, Rs
, Rn
= FAIL
;
5803 skip_whitespace (str
);
5805 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5806 || skip_past_comma (&str
) == FAIL
)
5809 inst
.error
= BAD_ARGS
;
5813 if (is_immediate_prefix (*str
))
5815 /* Two operand immediate format, set Rs to Rd. */
5818 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5823 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5826 if (skip_past_comma (&str
) == FAIL
)
5828 /* Two operand format, shuffle the registers
5829 and pretend there are 3. */
5833 else if (is_immediate_prefix (*str
))
5836 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5839 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5843 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5844 for the latter case, EXPR contains the immediate that was found. */
5850 inst
.error
= _("source1 and dest must be same register");
5856 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
5857 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
5858 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
5861 inst
.instruction
|= Rd
| (Rn
<< 3);
5867 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
5868 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
5869 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
5872 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5874 /* Value isn't known yet, create a dummy reloc and let reloc
5875 hacking fix it up. */
5876 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
5880 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
5882 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
5884 inst
.error
= _("Invalid immediate for shift");
5888 /* Shifts of zero are handled by converting to LSL. */
5889 if (shift_value
== 0)
5890 inst
.instruction
= T_OPCODE_LSL_I
;
5892 /* Shifts of 32 are encoded as a shift of zero. */
5893 if (shift_value
== 32)
5896 inst
.instruction
|= shift_value
<< 6;
5899 inst
.instruction
|= Rd
| (Rs
<< 3);
5906 thumb_mov_compare (str
, move
)
5912 skip_whitespace (str
);
5914 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
5915 || skip_past_comma (&str
) == FAIL
)
5918 inst
.error
= BAD_ARGS
;
5922 if (is_immediate_prefix (*str
))
5925 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5928 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5933 if (Rs
< 8 && Rd
< 8)
5935 if (move
== THUMB_MOVE
)
5936 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
5937 since a MOV instruction produces unpredictable results. */
5938 inst
.instruction
= T_OPCODE_ADD_I3
;
5940 inst
.instruction
= T_OPCODE_CMP_LR
;
5941 inst
.instruction
|= Rd
| (Rs
<< 3);
5945 if (move
== THUMB_MOVE
)
5946 inst
.instruction
= T_OPCODE_MOV_HR
;
5948 inst
.instruction
= T_OPCODE_CMP_HR
;
5951 inst
.instruction
|= THUMB_H1
;
5954 inst
.instruction
|= THUMB_H2
;
5956 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
5963 inst
.error
= _("only lo regs allowed with immediate");
5967 if (move
== THUMB_MOVE
)
5968 inst
.instruction
= T_OPCODE_MOV_I8
;
5970 inst
.instruction
= T_OPCODE_CMP_I8
;
5972 inst
.instruction
|= Rd
<< 8;
5974 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5975 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
5978 unsigned value
= inst
.reloc
.exp
.X_add_number
;
5982 inst
.error
= _("invalid immediate");
5986 inst
.instruction
|= value
;
5994 thumb_load_store (str
, load_store
, size
)
5999 int Rd
, Rb
, Ro
= FAIL
;
6001 skip_whitespace (str
);
6003 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6004 || skip_past_comma (&str
) == FAIL
)
6007 inst
.error
= BAD_ARGS
;
6014 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6017 if (skip_past_comma (&str
) != FAIL
)
6019 if (is_immediate_prefix (*str
))
6022 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6025 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6030 inst
.reloc
.exp
.X_op
= O_constant
;
6031 inst
.reloc
.exp
.X_add_number
= 0;
6036 inst
.error
= _("expected ']'");
6041 else if (*str
== '=')
6043 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6046 skip_whitespace (str
);
6048 if (my_get_expression (& inst
.reloc
.exp
, & str
))
6053 if ( inst
.reloc
.exp
.X_op
!= O_constant
6054 && inst
.reloc
.exp
.X_op
!= O_symbol
)
6056 inst
.error
= "Constant expression expected";
6060 if (inst
.reloc
.exp
.X_op
== O_constant
6061 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
6063 /* This can be done with a mov instruction. */
6065 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
6066 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
6070 /* Insert into literal pool. */
6071 if (add_to_lit_pool () == FAIL
)
6074 inst
.error
= "literal pool insertion failed";
6078 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6079 inst
.reloc
.pc_rel
= 1;
6080 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
6081 /* Adjust ARM pipeline offset to Thumb. */
6082 inst
.reloc
.exp
.X_add_number
+= 4;
6088 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6091 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
6092 inst
.reloc
.pc_rel
= 1;
6093 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
6094 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6099 if (Rb
== REG_PC
|| Rb
== REG_SP
)
6101 if (size
!= THUMB_WORD
)
6103 inst
.error
= _("byte or halfword not valid for base register");
6106 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
6108 inst
.error
= _("R15 based store not allowed");
6111 else if (Ro
!= FAIL
)
6113 inst
.error
= _("Invalid base register for register offset");
6118 inst
.instruction
= T_OPCODE_LDR_PC
;
6119 else if (load_store
== THUMB_LOAD
)
6120 inst
.instruction
= T_OPCODE_LDR_SP
;
6122 inst
.instruction
= T_OPCODE_STR_SP
;
6124 inst
.instruction
|= Rd
<< 8;
6125 if (inst
.reloc
.exp
.X_op
== O_constant
)
6127 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
6129 if (offset
& ~0x3fc)
6131 inst
.error
= _("invalid offset");
6135 inst
.instruction
|= offset
>> 2;
6138 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6142 inst
.error
= _("invalid base register in load/store");
6145 else if (Ro
== FAIL
)
6147 /* Immediate offset. */
6148 if (size
== THUMB_WORD
)
6149 inst
.instruction
= (load_store
== THUMB_LOAD
6150 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
6151 else if (size
== THUMB_HALFWORD
)
6152 inst
.instruction
= (load_store
== THUMB_LOAD
6153 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
6155 inst
.instruction
= (load_store
== THUMB_LOAD
6156 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
6158 inst
.instruction
|= Rd
| (Rb
<< 3);
6160 if (inst
.reloc
.exp
.X_op
== O_constant
)
6162 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
6164 if (offset
& ~(0x1f << size
))
6166 inst
.error
= _("Invalid offset");
6169 inst
.instruction
|= (offset
>> size
) << 6;
6172 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6176 /* Register offset. */
6177 if (size
== THUMB_WORD
)
6178 inst
.instruction
= (load_store
== THUMB_LOAD
6179 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
6180 else if (size
== THUMB_HALFWORD
)
6181 inst
.instruction
= (load_store
== THUMB_LOAD
6182 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
6184 inst
.instruction
= (load_store
== THUMB_LOAD
6185 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
6187 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
6193 /* Given a register and a register type, return 1 if
6194 the register is of the given type, else return 0. */
6197 cirrus_valid_reg (reg
, regtype
)
6199 enum cirrus_regtype regtype
;
6203 case CIRRUS_REGTYPE_ANY
:
6206 case CIRRUS_REGTYPE_MVF
:
6207 return cirrus_mvf_register (reg
);
6209 case CIRRUS_REGTYPE_MVFX
:
6210 return cirrus_mvfx_register (reg
);
6212 case CIRRUS_REGTYPE_MVD
:
6213 return cirrus_mvd_register (reg
);
6215 case CIRRUS_REGTYPE_MVDX
:
6216 return cirrus_mvdx_register (reg
);
6218 case CIRRUS_REGTYPE_MVAX
:
6219 return cirrus_mvax_register (reg
);
6221 case CIRRUS_REGTYPE_DSPSC
:
6222 return ARM_EXT_MAVERICKsc_register (reg
);
6228 /* A register must be given at this point.
6230 If the register is a Cirrus register, convert it's reg# appropriately.
6232 Shift is the place to put it in inst.instruction.
6234 regtype is type register type expected, and is:
6240 CIRRUS_REGTYPE_DSPSC
6242 Restores input start point on err.
6243 Returns the reg#, or FAIL. */
6246 cirrus_reg_required_here (str
, shift
, regtype
)
6249 enum cirrus_regtype regtype
;
6251 static char buff
[135]; /* XXX */
6253 char * start
= * str
;
6255 if ((reg
= arm_reg_parse (str
)) != FAIL
6256 && (int_register (reg
)
6257 || cirrus_register (reg
)))
6261 /* Calculate actual register # for opcode. */
6262 if (cirrus_register (reg
)
6263 && !ARM_EXT_MAVERICKsc_register (reg
)) /* Leave this one as is. */
6267 else if (reg
>= 110)
6277 if (!cirrus_valid_reg (orig_reg
, regtype
))
6279 sprintf (buff
, _("invalid register type at '%.100s'"), start
);
6285 inst
.instruction
|= reg
<< shift
;
6290 /* Restore the start point, we may have got a reg of the wrong class. */
6293 /* In the few cases where we might be able to accept something else
6294 this error can be overridden. */
6295 sprintf (buff
, _("Cirrus register expected, not '%.100s'"), start
);
6301 /* Cirrus Instructions. */
6303 /* Wrapper functions. */
6306 do_c_binops_1 (str
, flags
)
6308 unsigned long flags
;
6310 do_c_binops (str
, flags
, CIRRUS_MODE1
);
6314 do_c_binops_2 (str
, flags
)
6316 unsigned long flags
;
6318 do_c_binops (str
, flags
, CIRRUS_MODE2
);
6322 do_c_binops_3 (str
, flags
)
6324 unsigned long flags
;
6326 do_c_binops (str
, flags
, CIRRUS_MODE3
);
6330 do_c_triple_4 (str
, flags
)
6332 unsigned long flags
;
6334 do_c_triple (str
, flags
, CIRRUS_MODE4
);
6338 do_c_triple_5 (str
, flags
)
6340 unsigned long flags
;
6342 do_c_triple (str
, flags
, CIRRUS_MODE5
);
6346 do_c_quad_6 (str
, flags
)
6348 unsigned long flags
;
6350 do_c_quad (str
, flags
, CIRRUS_MODE6
);
6354 do_c_dspsc_1 (str
, flags
)
6356 unsigned long flags
;
6358 do_c_dspsc (str
, flags
, CIRRUS_MODE1
);
6362 do_c_dspsc_2 (str
, flags
)
6364 unsigned long flags
;
6366 do_c_dspsc (str
, flags
, CIRRUS_MODE2
);
6370 do_c_shift_1 (str
, flags
)
6372 unsigned long flags
;
6374 do_c_shift (str
, flags
, CIRRUS_MODE1
);
6378 do_c_shift_2 (str
, flags
)
6380 unsigned long flags
;
6382 do_c_shift (str
, flags
, CIRRUS_MODE2
);
6386 do_c_ldst_1 (str
, flags
)
6388 unsigned long flags
;
6390 do_c_ldst (str
, flags
, CIRRUS_MODE1
);
6394 do_c_ldst_2 (str
, flags
)
6396 unsigned long flags
;
6398 do_c_ldst (str
, flags
, CIRRUS_MODE2
);
6402 do_c_ldst_3 (str
, flags
)
6404 unsigned long flags
;
6406 do_c_ldst (str
, flags
, CIRRUS_MODE3
);
6410 do_c_ldst_4 (str
, flags
)
6412 unsigned long flags
;
6414 do_c_ldst (str
, flags
, CIRRUS_MODE4
);
6417 /* Isnsn like "foo X,Y". */
6420 do_c_binops (str
, flags
, mode
)
6422 unsigned long flags
;
6427 shift1
= mode
& 0xff;
6428 shift2
= (mode
>> 8) & 0xff;
6430 skip_whitespace (str
);
6432 if (cirrus_reg_required_here (&str
, shift1
, CIRRUS_REGTYPE_ANY
) == FAIL
6433 || skip_past_comma (&str
) == FAIL
6434 || cirrus_reg_required_here (&str
, shift2
, CIRRUS_REGTYPE_ANY
) == FAIL
)
6437 inst
.error
= BAD_ARGS
;
6442 inst
.instruction
|= flags
;
6446 /* Isnsn like "foo X,Y,Z". */
6449 do_c_triple (str
, flags
, mode
)
6451 unsigned long flags
;
6454 int shift1
, shift2
, shift3
;
6456 shift1
= mode
& 0xff;
6457 shift2
= (mode
>> 8) & 0xff;
6458 shift3
= (mode
>> 16) & 0xff;
6460 skip_whitespace (str
);
6462 if (cirrus_reg_required_here (&str
, shift1
, CIRRUS_REGTYPE_ANY
) == FAIL
6463 || skip_past_comma (&str
) == FAIL
6464 || cirrus_reg_required_here (&str
, shift2
, CIRRUS_REGTYPE_ANY
) == FAIL
6465 || skip_past_comma (&str
) == FAIL
6466 || cirrus_reg_required_here (&str
, shift3
, CIRRUS_REGTYPE_ANY
) == FAIL
)
6469 inst
.error
= BAD_ARGS
;
6474 inst
.instruction
|= flags
;
6478 /* Isnsn like "foo W,X,Y,Z".
6479 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
6482 do_c_quad (str
, flags
, mode
)
6484 unsigned long flags
;
6487 int shift1
, shift2
, shift3
, shift4
;
6488 enum cirrus_regtype rt
;
6490 rt
= (inst
.instruction
<< 4 == 0xe2006000
6491 || inst
.instruction
<< 4 == 0xe3006000) ? CIRRUS_REGTYPE_MVAX
6492 : CIRRUS_REGTYPE_MVFX
;
6494 shift1
= mode
& 0xff;
6495 shift2
= (mode
>> 8) & 0xff;
6496 shift3
= (mode
>> 16) & 0xff;
6497 shift4
= (mode
>> 24) & 0xff;
6499 skip_whitespace (str
);
6501 if (cirrus_reg_required_here (&str
, shift1
, CIRRUS_REGTYPE_MVAX
) == FAIL
6502 || skip_past_comma (&str
) == FAIL
6503 || cirrus_reg_required_here (&str
, shift2
, rt
) == FAIL
6504 || skip_past_comma (&str
) == FAIL
6505 || cirrus_reg_required_here (&str
, shift3
, CIRRUS_REGTYPE_MVFX
) == FAIL
6506 || skip_past_comma (&str
) == FAIL
6507 || cirrus_reg_required_here (&str
, shift4
, CIRRUS_REGTYPE_MVFX
) == FAIL
)
6510 inst
.error
= BAD_ARGS
;
6515 inst
.instruction
|= flags
;
6519 /* cfmvsc32<cond> DSPSC,MVFX[15:0].
6520 cfmv32sc<cond> MVFX[15:0],DSPSC. */
6523 do_c_dspsc (str
, flags
, mode
)
6525 unsigned long flags
;
6530 skip_whitespace (str
);
6534 if (mode
== CIRRUS_MODE1
)
6537 if (cirrus_reg_required_here (&str
, -1, CIRRUS_REGTYPE_DSPSC
) == FAIL
6538 || skip_past_comma (&str
) == FAIL
6539 || cirrus_reg_required_here (&str
, 16, CIRRUS_REGTYPE_MVFX
) == FAIL
)
6545 if (cirrus_reg_required_here (&str
, 0, CIRRUS_REGTYPE_MVFX
) == FAIL
6546 || skip_past_comma (&str
) == FAIL
6547 || cirrus_reg_required_here (&str
, -1, CIRRUS_REGTYPE_DSPSC
) == FAIL
)
6554 inst
.error
= BAD_ARGS
;
6558 inst
.instruction
|= flags
;
6565 /* Cirrus shift immediate instructions.
6566 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
6567 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
6570 do_c_shift (str
, flags
, mode
)
6572 unsigned long flags
;
6578 skip_whitespace (str
);
6582 if (cirrus_reg_required_here (&str
, 12,
6583 (mode
== CIRRUS_MODE1
)
6584 ? CIRRUS_REGTYPE_MVFX
6585 : CIRRUS_REGTYPE_MVDX
) == FAIL
6586 || skip_past_comma (&str
) == FAIL
6587 || cirrus_reg_required_here (&str
, 16,
6588 (mode
== CIRRUS_MODE1
)
6589 ? CIRRUS_REGTYPE_MVFX
6590 : CIRRUS_REGTYPE_MVDX
) == FAIL
6591 || skip_past_comma (&str
) == FAIL
)
6594 inst
.error
= BAD_ARGS
;
6598 /* Calculate the immediate operand.
6599 The operand is a 7bit signed number. */
6600 skip_whitespace (str
);
6605 if (!ISDIGIT (*str
) && *str
!= '-')
6607 inst
.error
= _("expecting immediate, 7bit operand");
6617 for (imm
= 0; *str
&& ISDIGIT (*str
); ++str
)
6618 imm
= imm
* 10 + *str
- '0';
6622 inst
.error
= _("immediate out of range");
6626 /* Make negative imm's into 7bit signed numbers. */
6633 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
6634 Bits 5-7 of the insn should have bits 4-6 of the immediate.
6635 Bit 4 should be 0. */
6636 imm
= (imm
& 0xf) | ((imm
& 0x70) << 1);
6638 inst
.instruction
|= imm
;
6639 inst
.instruction
|= flags
;
6647 cirrus_parse_offset (str
, negative
)
6656 skip_whitespace (p
);
6669 inst
.error
= _("offset expected");
6673 for (offset
= 0; *p
&& ISDIGIT (*p
); ++p
)
6674 offset
= offset
* 10 + *p
- '0';
6678 inst
.error
= _("offset out of range");
6684 return *negative
? -offset
: offset
;
6687 /* Cirrus load/store instructions.
6688 <insn><cond> CRd,[Rn,<offset>]{!}.
6689 <insn><cond> CRd,[Rn],<offset>. */
6692 do_c_ldst (str
, flags
, mode
)
6694 unsigned long flags
;
6697 int offset
, negative
;
6698 enum cirrus_regtype rt
;
6700 rt
= mode
== CIRRUS_MODE1
? CIRRUS_REGTYPE_MVF
6701 : mode
== CIRRUS_MODE2
? CIRRUS_REGTYPE_MVD
6702 : mode
== CIRRUS_MODE3
? CIRRUS_REGTYPE_MVFX
6703 : mode
== CIRRUS_MODE4
? CIRRUS_REGTYPE_MVDX
: CIRRUS_REGTYPE_MVF
;
6705 skip_whitespace (str
);
6707 if (cirrus_reg_required_here (& str
, 12, rt
) == FAIL
6708 || skip_past_comma (& str
) == FAIL
6710 || reg_required_here (& str
, 16) == FAIL
)
6713 if (skip_past_comma (& str
) == SUCCESS
)
6715 /* You are here: "<offset>]{!}". */
6716 inst
.instruction
|= PRE_INDEX
;
6718 offset
= cirrus_parse_offset (&str
, &negative
);
6725 inst
.error
= _("missing ]");
6731 inst
.instruction
|= WRITE_BACK
;
6737 /* You are here: "], <offset>". */
6740 inst
.error
= _("missing ]");
6744 if (skip_past_comma (&str
) == FAIL
6745 || (offset
= cirrus_parse_offset (&str
, &negative
), inst
.error
))
6748 inst
.instruction
|= CP_T_WB
; /* Post indexed, set bit W. */
6754 inst
.instruction
|= CP_T_UD
; /* Postive, so set bit U. */
6756 inst
.instruction
|= offset
>> 2;
6757 inst
.instruction
|= flags
;
6764 inst
.error
= BAD_ARGS
;
6777 /* Handle the Format 4 instructions that do not have equivalents in other
6778 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
6787 skip_whitespace (str
);
6789 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6790 || skip_past_comma (&str
) == FAIL
6791 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6793 inst
.error
= BAD_ARGS
;
6797 if (skip_past_comma (&str
) != FAIL
)
6799 /* Three operand format not allowed for TST, CMN, NEG and MVN.
6800 (It isn't allowed for CMP either, but that isn't handled by this
6802 if (inst
.instruction
== T_OPCODE_TST
6803 || inst
.instruction
== T_OPCODE_CMN
6804 || inst
.instruction
== T_OPCODE_NEG
6805 || inst
.instruction
== T_OPCODE_MVN
)
6807 inst
.error
= BAD_ARGS
;
6811 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6816 inst
.error
= _("dest and source1 must be the same register");
6822 if (inst
.instruction
== T_OPCODE_MUL
6824 as_tsktsk (_("Rs and Rd must be different in MUL"));
6826 inst
.instruction
|= Rd
| (Rs
<< 3);
6834 thumb_add_sub (str
, 0);
6841 thumb_shift (str
, THUMB_ASR
);
6848 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6850 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
6851 inst
.reloc
.pc_rel
= 1;
6859 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6861 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
6862 inst
.reloc
.pc_rel
= 1;
6866 /* Find the real, Thumb encoded start of a Thumb function. */
6869 find_real_start (symbolP
)
6873 const char * name
= S_GET_NAME (symbolP
);
6874 symbolS
* new_target
;
6876 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
6877 #define STUB_NAME ".real_start_of"
6882 /* Names that start with '.' are local labels, not function entry points.
6883 The compiler may generate BL instructions to these labels because it
6884 needs to perform a branch to a far away location. */
6888 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
6889 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
6891 new_target
= symbol_find (real_start
);
6893 if (new_target
== NULL
)
6895 as_warn ("Failed to find real start of function: %s\n", name
);
6896 new_target
= symbolP
;
6908 if (my_get_expression (& inst
.reloc
.exp
, & str
))
6911 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
6912 inst
.reloc
.pc_rel
= 1;
6915 /* If the destination of the branch is a defined symbol which does not have
6916 the THUMB_FUNC attribute, then we must be calling a function which has
6917 the (interfacearm) attribute. We look for the Thumb entry point to that
6918 function and change the branch to refer to that function instead. */
6919 if ( inst
.reloc
.exp
.X_op
== O_symbol
6920 && inst
.reloc
.exp
.X_add_symbol
!= NULL
6921 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
6922 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
6923 inst
.reloc
.exp
.X_add_symbol
=
6924 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
6933 skip_whitespace (str
);
6935 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6938 /* This sets THUMB_H2 from the top bit of reg. */
6939 inst
.instruction
|= reg
<< 3;
6941 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
6942 should cause the alignment to be checked once it is known. This is
6943 because BX PC only works if the instruction is word aligned. */
6952 thumb_mov_compare (str
, THUMB_COMPARE
);
6962 skip_whitespace (str
);
6964 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6968 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
6972 if (skip_past_comma (&str
) == FAIL
6973 || (range
= reg_list (&str
)) == FAIL
)
6976 inst
.error
= BAD_ARGS
;
6980 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6982 /* This really doesn't seem worth it. */
6983 inst
.reloc
.type
= BFD_RELOC_NONE
;
6984 inst
.error
= _("Expression too complex");
6990 inst
.error
= _("only lo-regs valid in load/store multiple");
6994 inst
.instruction
|= (Rb
<< 8) | range
;
7002 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
7009 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
7016 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
7025 skip_whitespace (str
);
7027 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7028 || skip_past_comma (&str
) == FAIL
7030 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7031 || skip_past_comma (&str
) == FAIL
7032 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7036 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
7040 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
7048 thumb_shift (str
, THUMB_LSL
);
7055 thumb_shift (str
, THUMB_LSR
);
7062 thumb_mov_compare (str
, THUMB_MOVE
);
7071 skip_whitespace (str
);
7073 if ((range
= reg_list (&str
)) == FAIL
)
7076 inst
.error
= BAD_ARGS
;
7080 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
7082 /* This really doesn't seem worth it. */
7083 inst
.reloc
.type
= BFD_RELOC_NONE
;
7084 inst
.error
= _("Expression too complex");
7090 if ((inst
.instruction
== T_OPCODE_PUSH
7091 && (range
& ~0xff) == 1 << REG_LR
)
7092 || (inst
.instruction
== T_OPCODE_POP
7093 && (range
& ~0xff) == 1 << REG_PC
))
7095 inst
.instruction
|= THUMB_PP_PC_LR
;
7100 inst
.error
= _("invalid register list to push/pop instruction");
7105 inst
.instruction
|= range
;
7113 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
7120 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
7127 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
7134 thumb_add_sub (str
, 1);
7141 skip_whitespace (str
);
7143 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7146 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
7157 /* This is a pseudo-op of the form "adr rd, label" to be converted
7158 into a relative address of the form "add rd, pc, #label-.-4". */
7159 skip_whitespace (str
);
7161 /* Store Rd in temporary location inside instruction. */
7162 if ((reg
= reg_required_here (&str
, 4)) == FAIL
7163 || (reg
> 7) /* For Thumb reg must be r0..r7. */
7164 || skip_past_comma (&str
) == FAIL
7165 || my_get_expression (&inst
.reloc
.exp
, &str
))
7168 inst
.error
= BAD_ARGS
;
7172 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
7173 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
7174 inst
.reloc
.pc_rel
= 1;
7175 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
7184 int len
= strlen (reg_table
[entry
].name
) + 2;
7185 char * buf
= (char *) xmalloc (len
);
7186 char * buf2
= (char *) xmalloc (len
);
7189 #ifdef REGISTER_PREFIX
7190 buf
[i
++] = REGISTER_PREFIX
;
7193 strcpy (buf
+ i
, reg_table
[entry
].name
);
7195 for (i
= 0; buf
[i
]; i
++)
7196 buf2
[i
] = TOUPPER (buf
[i
]);
7200 hash_insert (arm_reg_hsh
, buf
, (PTR
) & reg_table
[entry
]);
7201 hash_insert (arm_reg_hsh
, buf2
, (PTR
) & reg_table
[entry
]);
7205 insert_reg_alias (str
, regnum
)
7209 struct reg_entry
*new =
7210 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
7211 char *name
= xmalloc (strlen (str
) + 1);
7215 new->number
= regnum
;
7217 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
7221 set_constant_flonums ()
7225 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
7226 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
7236 if ( (arm_ops_hsh
= hash_new ()) == NULL
7237 || (arm_tops_hsh
= hash_new ()) == NULL
7238 || (arm_cond_hsh
= hash_new ()) == NULL
7239 || (arm_shift_hsh
= hash_new ()) == NULL
7240 || (arm_reg_hsh
= hash_new ()) == NULL
7241 || (arm_psr_hsh
= hash_new ()) == NULL
)
7242 as_fatal (_("Virtual memory exhausted"));
7244 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
7245 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
7246 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
7247 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
7248 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
7249 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
7250 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
7251 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
7252 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
7253 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
7255 for (i
= 0; reg_table
[i
].name
; i
++)
7258 set_constant_flonums ();
7260 #if defined OBJ_COFF || defined OBJ_ELF
7262 unsigned int flags
= 0;
7264 /* Set the flags in the private structure. */
7265 if (uses_apcs_26
) flags
|= F_APCS26
;
7266 if (support_interwork
) flags
|= F_INTERWORK
;
7267 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
7268 if (pic_code
) flags
|= F_PIC
;
7269 if ((cpu_variant
& FPU_ANY
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
7271 bfd_set_private_flags (stdoutput
, flags
);
7273 /* We have run out flags in the COFF header to encode the
7274 status of ATPCS support, so instead we create a dummy,
7275 empty, debug section called .arm.atpcs. */
7280 sec
= bfd_make_section (stdoutput
, ".arm.atpcs");
7284 bfd_set_section_flags
7285 (stdoutput
, sec
, SEC_READONLY
| SEC_DEBUGGING
/* | SEC_HAS_CONTENTS */);
7286 bfd_set_section_size (stdoutput
, sec
, 0);
7287 bfd_set_section_contents (stdoutput
, sec
, NULL
, 0, 0);
7293 /* Record the CPU type as well. */
7294 switch (cpu_variant
& ARM_CPU_MASK
)
7297 mach
= bfd_mach_arm_2
;
7300 case ARM_3
: /* Also ARM_250. */
7301 mach
= bfd_mach_arm_2a
;
7304 case ARM_6
: /* Also ARM_7. */
7305 mach
= bfd_mach_arm_3
;
7309 mach
= bfd_mach_arm_4
;
7314 /* Catch special cases. */
7315 if (cpu_variant
& ARM_EXT_XSCALE
)
7316 mach
= bfd_mach_arm_XScale
;
7317 else if (cpu_variant
& ARM_EXT_V5E
)
7318 mach
= bfd_mach_arm_5TE
;
7319 else if (cpu_variant
& ARM_EXT_V5
)
7321 if (cpu_variant
& ARM_EXT_V4T
)
7322 mach
= bfd_mach_arm_5T
;
7324 mach
= bfd_mach_arm_5
;
7326 else if (cpu_variant
& ARM_EXT_V4
)
7328 if (cpu_variant
& ARM_EXT_V4T
)
7329 mach
= bfd_mach_arm_4T
;
7331 mach
= bfd_mach_arm_4
;
7333 else if (cpu_variant
& ARM_EXT_V3M
)
7334 mach
= bfd_mach_arm_3M
;
7336 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
7339 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
7340 for use in the a.out file, and stores them in the array pointed to by buf.
7341 This knows about the endian-ness of the target machine and does
7342 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
7343 2 (short) and 4 (long) Floating numbers are put out as a series of
7344 LITTLENUMS (shorts, here at least). */
7347 md_number_to_chars (buf
, val
, n
)
7352 if (target_big_endian
)
7353 number_to_chars_bigendian (buf
, val
, n
);
7355 number_to_chars_littleendian (buf
, val
, n
);
7359 md_chars_to_number (buf
, n
)
7364 unsigned char * where
= (unsigned char *) buf
;
7366 if (target_big_endian
)
7371 result
|= (*where
++ & 255);
7379 result
|= (where
[n
] & 255);
7386 /* Turn a string in input_line_pointer into a floating point constant
7387 of type TYPE, and store the appropriate bytes in *LITP. The number
7388 of LITTLENUMS emitted is stored in *SIZEP. An error message is
7389 returned, or NULL on OK.
7391 Note that fp constants aren't represent in the normal way on the ARM.
7392 In big endian mode, things are as expected. However, in little endian
7393 mode fp constants are big-endian word-wise, and little-endian byte-wise
7394 within the words. For example, (double) 1.1 in big endian mode is
7395 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
7396 the byte sequence 99 99 f1 3f 9a 99 99 99.
7398 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
7401 md_atof (type
, litP
, sizeP
)
7407 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
7439 return _("Bad call to MD_ATOF()");
7442 t
= atof_ieee (input_line_pointer
, type
, words
);
7444 input_line_pointer
= t
;
7447 if (target_big_endian
)
7449 for (i
= 0; i
< prec
; i
++)
7451 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
7457 /* For a 4 byte float the order of elements in `words' is 1 0. For an
7458 8 byte float the order is 1 0 3 2. */
7459 for (i
= 0; i
< prec
; i
+= 2)
7461 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
7462 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
7470 /* The knowledge of the PC's pipeline offset is built into the insns
7474 md_pcrel_from (fixP
)
7478 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
7479 && fixP
->fx_subsy
== NULL
)
7482 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
7484 /* PC relative addressing on the Thumb is slightly odd
7485 as the bottom two bits of the PC are forced to zero
7486 for the calculation. */
7487 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
7491 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
7492 so we un-adjust here to compensate for the accomodation. */
7493 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
7495 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
7499 /* Round up a section size to the appropriate boundary. */
7502 md_section_align (segment
, size
)
7503 segT segment ATTRIBUTE_UNUSED
;
7509 /* Round all sects to multiple of 4. */
7510 return (size
+ 3) & ~3;
7514 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
7515 Otherwise we have no need to default values of symbols. */
7518 md_undefined_symbol (name
)
7519 char * name ATTRIBUTE_UNUSED
;
7522 if (name
[0] == '_' && name
[1] == 'G'
7523 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
7527 if (symbol_find (name
))
7528 as_bad ("GOT already in the symbol table");
7530 GOT_symbol
= symbol_new (name
, undefined_section
,
7531 (valueT
) 0, & zero_address_frag
);
7541 /* arm_reg_parse () := if it looks like a register, return its token and
7542 advance the pointer. */
7546 register char ** ccp
;
7548 char * start
= * ccp
;
7551 struct reg_entry
* reg
;
7553 #ifdef REGISTER_PREFIX
7554 if (*start
!= REGISTER_PREFIX
)
7559 #ifdef OPTIONAL_REGISTER_PREFIX
7560 if (*p
== OPTIONAL_REGISTER_PREFIX
)
7564 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
7568 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
7572 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
7585 md_apply_fix3 (fixP
, val
, seg
)
7590 offsetT value
= * val
;
7592 unsigned int newimm
;
7595 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
7596 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
7598 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
7600 /* Note whether this will delete the relocation. */
7602 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
7603 doesn't work fully.) */
7604 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
7607 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
7611 /* If this symbol is in a different section then we need to leave it for
7612 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
7613 so we have to undo it's effects here. */
7616 if (fixP
->fx_addsy
!= NULL
7617 && S_IS_DEFINED (fixP
->fx_addsy
)
7618 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
7621 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7622 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
7626 value
+= md_pcrel_from (fixP
);
7630 /* Remember value for emit_reloc. */
7631 fixP
->fx_addnumber
= value
;
7633 switch (fixP
->fx_r_type
)
7635 case BFD_RELOC_ARM_IMMEDIATE
:
7636 newimm
= validate_immediate (value
);
7637 temp
= md_chars_to_number (buf
, INSN_SIZE
);
7639 /* If the instruction will fail, see if we can fix things up by
7640 changing the opcode. */
7641 if (newimm
== (unsigned int) FAIL
7642 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
7644 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7645 _("invalid constant (%lx) after fixup"),
7646 (unsigned long) value
);
7650 newimm
|= (temp
& 0xfffff000);
7651 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
7654 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
7656 unsigned int highpart
= 0;
7657 unsigned int newinsn
= 0xe1a00000; /* nop. */
7658 newimm
= validate_immediate (value
);
7659 temp
= md_chars_to_number (buf
, INSN_SIZE
);
7661 /* If the instruction will fail, see if we can fix things up by
7662 changing the opcode. */
7663 if (newimm
== (unsigned int) FAIL
7664 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
7666 /* No ? OK - try using two ADD instructions to generate
7668 newimm
= validate_immediate_twopart (value
, & highpart
);
7670 /* Yes - then make sure that the second instruction is
7672 if (newimm
!= (unsigned int) FAIL
)
7674 /* Still No ? Try using a negated value. */
7675 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
7676 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
7677 /* Otherwise - give up. */
7680 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7681 _("Unable to compute ADRL instructions for PC offset of 0x%lx"),
7686 /* Replace the first operand in the 2nd instruction (which
7687 is the PC) with the destination register. We have
7688 already added in the PC in the first instruction and we
7689 do not want to do it again. */
7690 newinsn
&= ~ 0xf0000;
7691 newinsn
|= ((newinsn
& 0x0f000) << 4);
7694 newimm
|= (temp
& 0xfffff000);
7695 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
7697 highpart
|= (newinsn
& 0xfffff000);
7698 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
7702 case BFD_RELOC_ARM_OFFSET_IMM
:
7708 if (validate_offset_imm (value
, 0) == FAIL
)
7710 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7711 _("bad immediate value for offset (%ld)"),
7716 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7717 newval
&= 0xff7ff000;
7718 newval
|= value
| (sign
? INDEX_UP
: 0);
7719 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7722 case BFD_RELOC_ARM_OFFSET_IMM8
:
7723 case BFD_RELOC_ARM_HWLITERAL
:
7729 if (validate_offset_imm (value
, 1) == FAIL
)
7731 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
7732 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7733 _("invalid literal constant: pool needs to be closer"));
7735 as_bad (_("bad immediate value for half-word offset (%ld)"),
7740 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7741 newval
&= 0xff7ff0f0;
7742 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
7743 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7746 case BFD_RELOC_ARM_LITERAL
:
7752 if (validate_offset_imm (value
, 0) == FAIL
)
7754 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7755 _("invalid literal constant: pool needs to be closer"));
7759 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7760 newval
&= 0xff7ff000;
7761 newval
|= value
| (sign
? INDEX_UP
: 0);
7762 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7765 case BFD_RELOC_ARM_SHIFT_IMM
:
7766 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7767 if (((unsigned long) value
) > 32
7769 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
7771 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7772 _("shift expression is too large"));
7777 /* Shifts of zero must be done as lsl. */
7779 else if (value
== 32)
7781 newval
&= 0xfffff07f;
7782 newval
|= (value
& 0x1f) << 7;
7783 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7786 case BFD_RELOC_ARM_SWI
:
7787 if (arm_data
->thumb_mode
)
7789 if (((unsigned long) value
) > 0xff)
7790 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7791 _("Invalid swi expression"));
7792 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
7794 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7798 if (((unsigned long) value
) > 0x00ffffff)
7799 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7800 _("Invalid swi expression"));
7801 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
7803 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7807 case BFD_RELOC_ARM_MULTI
:
7808 if (((unsigned long) value
) > 0xffff)
7809 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7810 _("Invalid expression in load/store multiple"));
7811 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
7812 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7815 case BFD_RELOC_ARM_PCREL_BRANCH
:
7816 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7818 /* Sign-extend a 24-bit number. */
7819 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
7823 value
= fixP
->fx_offset
;
7826 /* We are going to store value (shifted right by two) in the
7827 instruction, in a 24 bit, signed field. Thus we need to check
7828 that none of the top 8 bits of the shifted value (top 7 bits of
7829 the unshifted, unsigned value) are set, or that they are all set. */
7830 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
7831 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
7834 /* Normally we would be stuck at this point, since we cannot store
7835 the absolute address that is the destination of the branch in the
7836 24 bits of the branch instruction. If however, we happen to know
7837 that the destination of the branch is in the same section as the
7838 branch instruciton itself, then we can compute the relocation for
7839 ourselves and not have to bother the linker with it.
7841 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
7842 because I have not worked out how to do this for OBJ_COFF or
7845 && fixP
->fx_addsy
!= NULL
7846 && S_IS_DEFINED (fixP
->fx_addsy
)
7847 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
7849 /* Get pc relative value to go into the branch. */
7852 /* Permit a backward branch provided that enough bits
7853 are set. Allow a forwards branch, provided that
7854 enough bits are clear. */
7855 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
7856 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
7860 if (! fixP
->fx_done
)
7862 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7863 _("gas can't handle same-section branch dest >= 0x04000000"));
7867 value
+= SEXT24 (newval
);
7869 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
7870 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
7871 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7872 _("out of range branch"));
7874 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
7875 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7878 case BFD_RELOC_ARM_PCREL_BLX
:
7881 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7885 value
= fixP
->fx_offset
;
7887 hbit
= (value
>> 1) & 1;
7888 value
= (value
>> 2) & 0x00ffffff;
7889 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
7890 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
7891 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7895 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
7896 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7898 addressT diff
= (newval
& 0xff) << 1;
7903 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
7904 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7905 _("Branch out of range"));
7906 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
7908 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7911 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
7912 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7914 addressT diff
= (newval
& 0x7ff) << 1;
7919 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
7920 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7921 _("Branch out of range"));
7922 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
7924 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7927 case BFD_RELOC_THUMB_PCREL_BLX
:
7928 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
7933 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7934 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
7935 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
7936 if (diff
& 0x400000)
7939 value
= fixP
->fx_offset
;
7942 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
7943 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7944 _("Branch with link out of range"));
7946 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
7947 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
7948 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
)
7949 /* Remove bit zero of the adjusted offset. Bit zero can only be
7950 set if the upper insn is at a half-word boundary, since the
7951 destination address, an ARM instruction, must always be on a
7952 word boundary. The semantics of the BLX (1) instruction, however,
7953 are that bit zero in the offset must always be zero, and the
7954 corresponding bit one in the target address will be set from bit
7955 one of the source address. */
7957 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7958 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
7963 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7964 md_number_to_chars (buf
, value
, 1);
7966 else if (!target_oabi
)
7968 value
= fixP
->fx_offset
;
7969 md_number_to_chars (buf
, value
, 1);
7975 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7976 md_number_to_chars (buf
, value
, 2);
7978 else if (!target_oabi
)
7980 value
= fixP
->fx_offset
;
7981 md_number_to_chars (buf
, value
, 2);
7987 case BFD_RELOC_ARM_GOT32
:
7988 case BFD_RELOC_ARM_GOTOFF
:
7989 md_number_to_chars (buf
, 0, 4);
7995 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7996 md_number_to_chars (buf
, value
, 4);
7998 else if (!target_oabi
)
8000 value
= fixP
->fx_offset
;
8001 md_number_to_chars (buf
, value
, 4);
8007 case BFD_RELOC_ARM_PLT32
:
8008 /* It appears the instruction is fully prepared at this point. */
8012 case BFD_RELOC_ARM_GOTPC
:
8013 md_number_to_chars (buf
, value
, 4);
8016 case BFD_RELOC_ARM_CP_OFF_IMM
:
8018 if (value
< -1023 || value
> 1023 || (value
& 3))
8019 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8020 _("Illegal value for co-processor offset"));
8023 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
8024 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
8025 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8028 case BFD_RELOC_ARM_THUMB_OFFSET
:
8029 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8030 /* Exactly what ranges, and where the offset is inserted depends
8031 on the type of instruction, we can establish this from the
8033 switch (newval
>> 12)
8035 case 4: /* PC load. */
8036 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
8037 forced to zero for these loads, so we will need to round
8038 up the offset if the instruction address is not word
8039 aligned (since the final address produced must be, and
8040 we can only describe word-aligned immediate offsets). */
8042 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
8043 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8044 _("Invalid offset, target not word aligned (0x%08X)"),
8045 (unsigned int) (fixP
->fx_frag
->fr_address
8046 + fixP
->fx_where
+ value
));
8048 if ((value
+ 2) & ~0x3fe)
8049 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8050 _("Invalid offset, value too big (0x%08lX)"), value
);
8052 /* Round up, since pc will be rounded down. */
8053 newval
|= (value
+ 2) >> 2;
8056 case 9: /* SP load/store. */
8058 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8059 _("Invalid offset, value too big (0x%08lX)"), value
);
8060 newval
|= value
>> 2;
8063 case 6: /* Word load/store. */
8065 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8066 _("Invalid offset, value too big (0x%08lX)"), value
);
8067 newval
|= value
<< 4; /* 6 - 2. */
8070 case 7: /* Byte load/store. */
8072 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8073 _("Invalid offset, value too big (0x%08lX)"), value
);
8074 newval
|= value
<< 6;
8077 case 8: /* Halfword load/store. */
8079 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8080 _("Invalid offset, value too big (0x%08lX)"), value
);
8081 newval
|= value
<< 5; /* 6 - 1. */
8085 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8086 "Unable to process relocation for thumb opcode: %lx",
8087 (unsigned long) newval
);
8090 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8093 case BFD_RELOC_ARM_THUMB_ADD
:
8094 /* This is a complicated relocation, since we use it for all of
8095 the following immediate relocations:
8099 9bit ADD/SUB SP word-aligned
8100 10bit ADD PC/SP word-aligned
8102 The type of instruction being processed is encoded in the
8109 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8111 int rd
= (newval
>> 4) & 0xf;
8112 int rs
= newval
& 0xf;
8113 int subtract
= newval
& 0x8000;
8118 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8119 _("Invalid immediate for stack address calculation"));
8120 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
8121 newval
|= value
>> 2;
8123 else if (rs
== REG_PC
|| rs
== REG_SP
)
8127 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8128 _("Invalid immediate for address calculation (value = 0x%08lX)"),
8129 (unsigned long) value
);
8130 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
8132 newval
|= value
>> 2;
8137 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8138 _("Invalid 8bit immediate"));
8139 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
8140 newval
|= (rd
<< 8) | value
;
8145 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8146 _("Invalid 3bit immediate"));
8147 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
8148 newval
|= rd
| (rs
<< 3) | (value
<< 6);
8151 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8154 case BFD_RELOC_ARM_THUMB_IMM
:
8155 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8156 switch (newval
>> 11)
8158 case 0x04: /* 8bit immediate MOV. */
8159 case 0x05: /* 8bit immediate CMP. */
8160 if (value
< 0 || value
> 255)
8161 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8162 _("Invalid immediate: %ld is too large"),
8170 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8173 case BFD_RELOC_ARM_THUMB_SHIFT
:
8174 /* 5bit shift value (0..31). */
8175 if (value
< 0 || value
> 31)
8176 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8177 _("Illegal Thumb shift value: %ld"), (long) value
);
8178 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
8179 newval
|= value
<< 6;
8180 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8183 case BFD_RELOC_VTABLE_INHERIT
:
8184 case BFD_RELOC_VTABLE_ENTRY
:
8188 case BFD_RELOC_NONE
:
8190 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8191 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
8197 /* Translate internal representation of relocation info to BFD target
8201 tc_gen_reloc (section
, fixp
)
8202 asection
* section ATTRIBUTE_UNUSED
;
8206 bfd_reloc_code_real_type code
;
8208 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
8210 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
8211 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
8212 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
8214 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
8216 if (fixp
->fx_pcrel
== 0)
8217 reloc
->addend
= fixp
->fx_offset
;
8219 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
8221 reloc
->addend
= fixp
->fx_offset
;
8224 switch (fixp
->fx_r_type
)
8229 code
= BFD_RELOC_8_PCREL
;
8236 code
= BFD_RELOC_16_PCREL
;
8243 code
= BFD_RELOC_32_PCREL
;
8247 case BFD_RELOC_ARM_PCREL_BRANCH
:
8248 case BFD_RELOC_ARM_PCREL_BLX
:
8250 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
8251 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
8252 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
8253 case BFD_RELOC_THUMB_PCREL_BLX
:
8254 case BFD_RELOC_VTABLE_ENTRY
:
8255 case BFD_RELOC_VTABLE_INHERIT
:
8256 code
= fixp
->fx_r_type
;
8259 case BFD_RELOC_ARM_LITERAL
:
8260 case BFD_RELOC_ARM_HWLITERAL
:
8261 /* If this is called then the a literal has been referenced across
8262 a section boundary - possibly due to an implicit dump. */
8263 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8264 _("Literal referenced across section boundary (Implicit dump?)"));
8268 case BFD_RELOC_ARM_GOT32
:
8269 case BFD_RELOC_ARM_GOTOFF
:
8270 case BFD_RELOC_ARM_PLT32
:
8271 code
= fixp
->fx_r_type
;
8275 case BFD_RELOC_ARM_IMMEDIATE
:
8276 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8277 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
8281 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
8282 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8283 _("ADRL used for a symbol not defined in the same file"));
8286 case BFD_RELOC_ARM_OFFSET_IMM
:
8287 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8288 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
8296 switch (fixp
->fx_r_type
)
8298 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
8299 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
8300 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
8301 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
8302 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
8303 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
8304 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
8305 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
8306 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
8307 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
8308 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
8309 default: type
= _("<unknown>"); break;
8311 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8312 _("Cannot represent %s relocation in this object file format"),
8319 if (code
== BFD_RELOC_32_PCREL
8321 && fixp
->fx_addsy
== GOT_symbol
)
8323 code
= BFD_RELOC_ARM_GOTPC
;
8324 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
8328 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
8330 if (reloc
->howto
== NULL
)
8332 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8333 _("Can not represent %s relocation in this object file format"),
8334 bfd_get_reloc_code_name (code
));
8338 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
8339 vtable entry to be used in the relocation's section offset. */
8340 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
8341 reloc
->address
= fixp
->fx_offset
;
8347 md_estimate_size_before_relax (fragP
, segtype
)
8348 fragS
* fragP ATTRIBUTE_UNUSED
;
8349 segT segtype ATTRIBUTE_UNUSED
;
8351 as_fatal (_("md_estimate_size_before_relax\n"));
8356 output_inst
PARAMS ((void))
8362 as_bad (inst
.error
);
8366 to
= frag_more (inst
.size
);
8368 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
8370 assert (inst
.size
== (2 * THUMB_SIZE
));
8371 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
8372 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
8374 else if (inst
.size
> INSN_SIZE
)
8376 assert (inst
.size
== (2 * INSN_SIZE
));
8377 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
8378 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
8381 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
8383 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
8384 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
8385 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
8389 dwarf2_emit_insn (inst
.size
);
8402 /* Align the instruction.
8403 This may not be the right thing to do but ... */
8407 listing_prev_line (); /* Defined in listing.h. */
8409 /* Align the previous label if needed. */
8410 if (last_label_seen
!= NULL
)
8412 symbol_set_frag (last_label_seen
, frag_now
);
8413 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
8414 S_SET_SEGMENT (last_label_seen
, now_seg
);
8417 memset (&inst
, '\0', sizeof (inst
));
8418 inst
.reloc
.type
= BFD_RELOC_NONE
;
8420 skip_whitespace (str
);
8422 /* Scan up to the end of the op-code, which must end in white space or
8424 for (start
= p
= str
; *p
!= '\0'; p
++)
8430 as_bad (_("No operator -- statement `%s'\n"), str
);
8436 const struct thumb_opcode
* opcode
;
8440 opcode
= (const struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
8445 /* Check that this instruction is supported for this CPU. */
8446 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
8448 as_bad (_("selected processor does not support this opcode"));
8452 inst
.instruction
= opcode
->value
;
8453 inst
.size
= opcode
->size
;
8454 (*opcode
->parms
) (p
);
8461 const struct asm_opcode
* opcode
;
8462 unsigned long cond_code
;
8464 inst
.size
= INSN_SIZE
;
8465 /* P now points to the end of the opcode, probably white space, but we
8466 have to break the opcode up in case it contains condionals and flags;
8467 keep trying with progressively smaller basic instructions until one
8468 matches, or we run out of opcode. */
8469 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
8471 for (; q
!= str
; q
--)
8476 opcode
= (const struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
8479 if (opcode
&& opcode
->template)
8481 unsigned long flag_bits
= 0;
8484 /* Check that this instruction is supported for this CPU. */
8485 if ((opcode
->variants
& cpu_variant
) == 0)
8488 inst
.instruction
= opcode
->value
;
8489 if (q
== p
) /* Just a simple opcode. */
8491 if (opcode
->comp_suffix
)
8493 if (*opcode
->comp_suffix
!= '\0')
8494 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
8495 str
, opcode
->comp_suffix
);
8497 /* Not a conditional instruction. */
8498 (*opcode
->parms
) (q
, 0);
8502 /* A conditional instruction with default condition. */
8503 inst
.instruction
|= COND_ALWAYS
;
8504 (*opcode
->parms
) (q
, 0);
8510 /* Not just a simple opcode. Check if extra is a
8515 const struct asm_cond
*cond
;
8519 cond
= (const struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
8523 if (cond
->value
== 0xf0000000)
8525 _("Warning: Use of the 'nv' conditional is deprecated\n"));
8527 cond_code
= cond
->value
;
8531 cond_code
= COND_ALWAYS
;
8534 cond_code
= COND_ALWAYS
;
8536 /* Apply the conditional, or complain it's not allowed. */
8537 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
8539 /* Instruction isn't conditional. */
8540 if (cond_code
!= COND_ALWAYS
)
8542 as_bad (_("Opcode `%s' is unconditional\n"), str
);
8547 /* Instruction is conditional: set the condition into it. */
8548 inst
.instruction
|= cond_code
;
8550 /* If there is a compulsory suffix, it should come here
8551 before any optional flags. */
8552 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
8554 const char *s
= opcode
->comp_suffix
;
8566 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
8567 str
, opcode
->comp_suffix
);
8574 /* The remainder, if any should now be flags for the instruction;
8575 Scan these checking each one found with the opcode. */
8579 const struct asm_flg
*flag
= opcode
->flags
;
8588 for (flagno
= 0; flag
[flagno
].template; flagno
++)
8590 if (streq (r
, flag
[flagno
].template))
8592 flag_bits
|= flag
[flagno
].set_bits
;
8598 if (! flag
[flagno
].template)
8605 (*opcode
->parms
) (p
, flag_bits
);
8615 /* It wasn't an instruction, but it might be a register alias of the form
8618 skip_whitespace (q
);
8623 if (*q
&& !strncmp (q
, ".req ", 4))
8629 #ifdef IGNORE_OPCODE_CASE
8630 str
= original_case_string
;
8635 skip_whitespace (q
);
8637 for (r
= q
; *r
!= '\0'; r
++)
8647 regnum
= arm_reg_parse (& q
);
8650 reg
= arm_reg_parse (& str
);
8655 insert_reg_alias (str
, regnum
);
8657 as_warn (_("register '%s' does not exist\n"), q
);
8659 else if (regnum
!= FAIL
)
8662 as_warn (_("ignoring redefinition of register alias '%s'"),
8665 /* Do not warn about redefinitions to the same alias. */
8668 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
8672 as_warn (_("ignoring incomplete .req pseuso op"));
8679 as_bad (_("bad instruction `%s'"), start
);
8683 Invocation line includes a switch not recognized by the base assembler.
8684 See if it's a processor-specific option. These are:
8685 Cpu variants, the arm part is optional:
8686 -m[arm]1 Currently not supported.
8687 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
8688 -m[arm]3 Arm 3 processor
8689 -m[arm]6[xx], Arm 6 processors
8690 -m[arm]7[xx][t][[d]m] Arm 7 processors
8691 -m[arm]8[10] Arm 8 processors
8692 -m[arm]9[20][tdmi] Arm 9 processors
8693 -marm9e Allow Cirrus/DSP instructions
8694 -mstrongarm[110[0]] StrongARM processors
8695 -mxscale XScale processors
8696 -m[arm]v[2345[t[e]]] Arm architectures
8697 -mall All (except the ARM1)
8699 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
8700 -mfpe-old (No float load/store multiples)
8701 -mno-fpu Disable all floating point instructions
8702 Run-time endian selection:
8704 -EL little endian cpu
8705 ARM Procedure Calling Standard:
8706 -mapcs-32 32 bit APCS
8707 -mapcs-26 26 bit APCS
8708 -mapcs-float Pass floats in float regs
8709 -mapcs-reentrant Position independent code
8710 -mthumb-interwork Code supports Arm/Thumb interworking
8711 -matpcs ARM/Thumb Procedure Call Standard
8712 -moabi Old ELF ABI */
8714 const char * md_shortopts
= "m:k";
8716 struct option md_longopts
[] =
8718 #ifdef ARM_BI_ENDIAN
8719 #define OPTION_EB (OPTION_MD_BASE + 0)
8720 {"EB", no_argument
, NULL
, OPTION_EB
},
8721 #define OPTION_EL (OPTION_MD_BASE + 1)
8722 {"EL", no_argument
, NULL
, OPTION_EL
},
8724 #define OPTION_OABI (OPTION_MD_BASE +2)
8725 {"oabi", no_argument
, NULL
, OPTION_OABI
},
8728 {NULL
, no_argument
, NULL
, 0}
8731 size_t md_longopts_size
= sizeof (md_longopts
);
8734 md_parse_option (c
, arg
)
8742 #ifdef ARM_BI_ENDIAN
8744 target_big_endian
= 1;
8747 target_big_endian
= 0;
8755 if (streq (str
, "fpa10") || streq (str
, "fpa11"))
8756 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_ARCH_FPA
;
8757 else if (streq (str
, "fpe-old"))
8758 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_ARCH_FPE
;
8764 if (streq (str
, "no-fpu"))
8765 cpu_variant
&= ~FPU_ANY
;
8770 if (streq (str
, "oabi"))
8776 /* Limit assembler to generating only Thumb instructions: */
8777 if (streq (str
, "thumb"))
8779 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_EXT_V4T
;
8780 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_NONE
;
8783 else if (streq (str
, "thumb-interwork"))
8785 if ((cpu_variant
& ARM_EXT_V4T
) == 0)
8786 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
8787 #if defined OBJ_COFF || defined OBJ_ELF
8788 support_interwork
= true;
8796 if (streq (str
, "all"))
8798 cpu_variant
= ARM_ALL
| FPU_DEFAULT
;
8801 #if defined OBJ_COFF || defined OBJ_ELF
8802 if (! strncmp (str
, "apcs-", 5))
8804 /* GCC passes on all command line options starting "-mapcs-..."
8805 to us, so we must parse them here. */
8809 if (streq (str
, "32"))
8811 uses_apcs_26
= false;
8814 else if (streq (str
, "26"))
8816 uses_apcs_26
= true;
8819 else if (streq (str
, "frame"))
8821 /* Stack frames are being generated - does not affect
8825 else if (streq (str
, "stack-check"))
8827 /* Stack checking is being performed - does not affect
8828 linkage, but does require that the functions
8829 __rt_stkovf_split_small and __rt_stkovf_split_big be
8830 present in the final link. */
8834 else if (streq (str
, "float"))
8836 /* Floating point arguments are being passed in the floating
8837 point registers. This does affect linking, since this
8838 version of the APCS is incompatible with the version that
8839 passes floating points in the integer registers. */
8841 uses_apcs_float
= true;
8844 else if (streq (str
, "reentrant"))
8846 /* Reentrant code has been generated. This does affect
8847 linking, since there is no point in linking reentrant/
8848 position independent code with absolute position code. */
8853 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
8857 if (! strcmp (str
, "atpcs"))
8863 /* Strip off optional "arm". */
8864 if (! strncmp (str
, "arm", 3))
8870 if (streq (str
, "1"))
8871 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
8877 if (streq (str
, "2"))
8878 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
8879 else if (streq (str
, "250"))
8880 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
8886 if (streq (str
, "3"))
8887 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
8893 switch (strtol (str
, NULL
, 10))
8900 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
8908 /* Eat the processor name. */
8909 switch (strtol (str
, & str
, 10))
8922 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
8928 cpu_variant
|= ARM_ARCH_V4T
;
8932 cpu_variant
|= ARM_EXT_V3M
;
8935 case 'f': /* fe => fp enabled cpu. */
8941 case 'c': /* Left over from 710c processor name. */
8942 case 'd': /* Debug. */
8943 case 'i': /* Embedded ICE. */
8944 /* Included for completeness in ARM processor naming. */
8954 if (streq (str
, "8") || streq (str
, "810"))
8955 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8956 | ARM_8
| ARM_ARCH_V4
;
8962 if (streq (str
, "9"))
8963 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8964 | ARM_9
| ARM_ARCH_V4T
;
8965 else if (streq (str
, "920"))
8966 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8967 | ARM_9
| ARM_ARCH_V4
;
8968 else if (streq (str
, "920t"))
8969 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8970 | ARM_9
| ARM_ARCH_V4T
;
8971 else if (streq (str
, "9tdmi"))
8972 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8973 | ARM_9
| ARM_ARCH_V4T
;
8974 else if (streq (str
, "9e"))
8975 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8976 | ARM_9
| ARM_ARCH_V4T
| ARM_EXT_MAVERICK
;
8982 if (streq (str
, "strongarm")
8983 || streq (str
, "strongarm110")
8984 || streq (str
, "strongarm1100"))
8985 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8986 | ARM_8
| ARM_ARCH_V4
;
8992 if (streq (str
, "xscale"))
8993 cpu_variant
= ARM_9
| ARM_ARCH_XSCALE
;
8999 /* Select variant based on architecture rather than
9007 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
9010 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
9013 as_bad (_("Invalid architecture variant -m%s"), arg
);
9019 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
9023 case 'm': cpu_variant
|= ARM_EXT_V3M
; break;
9026 as_bad (_("Invalid architecture variant -m%s"), arg
);
9032 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCH_V4
;
9036 case 't': cpu_variant
|= ARM_EXT_V4T
; break;
9039 as_bad (_("Invalid architecture variant -m%s"), arg
);
9045 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V5
;
9048 case 't': cpu_variant
|= ARM_EXT_V4T
; break;
9049 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
9052 as_bad (_("Invalid architecture variant -m%s"), arg
);
9058 as_bad (_("Invalid architecture variant -m%s"), arg
);
9065 as_bad (_("Invalid processor variant -m%s"), arg
);
9071 #if defined OBJ_ELF || defined OBJ_COFF
9089 ARM Specific Assembler Options:\n\
9090 -m[arm][<processor name>] select processor variant\n\
9091 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
9092 -marm9e allow Cirrus/DSP instructions\n\
9093 -mthumb only allow Thumb instructions\n\
9094 -mthumb-interwork mark the assembled code as supporting interworking\n\
9095 -mall allow any instruction\n\
9096 -mfpa10, -mfpa11 select floating point architecture\n\
9097 -mfpe-old don't allow floating-point multiple instructions\n\
9098 -mno-fpu don't allow any floating-point instructions.\n\
9099 -k generate PIC code.\n"));
9100 #if defined OBJ_COFF || defined OBJ_ELF
9102 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
9103 -matpcs use ARM/Thumb Procedure Calling Standard\n\
9104 -mapcs-float floating point args are passed in FP regs\n\
9105 -mapcs-reentrant the code is position independent/reentrant\n"));
9109 -moabi support the old ELF ABI\n"));
9111 #ifdef ARM_BI_ENDIAN
9113 -EB assemble code for a big endian cpu\n\
9114 -EL assemble code for a little endian cpu\n"));
9118 /* We need to be able to fix up arbitrary expressions in some statements.
9119 This is so that we can handle symbols that are an arbitrary distance from
9120 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
9121 which returns part of an address in a form which will be valid for
9122 a data instruction. We do this by pushing the expression into a symbol
9123 in the expr_section, and creating a fix for that. */
9126 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
9135 arm_fix_data
* arm_data
;
9143 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
9147 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
9152 /* Mark whether the fix is to a THUMB instruction, or an ARM
9154 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
9155 new_fix
->tc_fix_data
= (PTR
) arm_data
;
9156 arm_data
->thumb_mode
= thumb_mode
;
9161 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
9164 cons_fix_new_arm (frag
, where
, size
, exp
)
9170 bfd_reloc_code_real_type type
;
9174 FIXME: @@ Should look at CPU word size. */
9181 type
= BFD_RELOC_16
;
9185 type
= BFD_RELOC_32
;
9188 type
= BFD_RELOC_64
;
9192 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
9195 /* A good place to do this, although this was probably not intended
9196 for this kind of use. We need to dump the literal pool before
9197 references are made to a null symbol pointer. */
9202 if (current_poolP
== NULL
)
9205 /* Put it at the end of text section. */
9206 subseg_set (text_section
, 0);
9208 listing_prev_line ();
9212 arm_start_line_hook ()
9214 last_label_seen
= NULL
;
9218 arm_frob_label (sym
)
9221 last_label_seen
= sym
;
9223 ARM_SET_THUMB (sym
, thumb_mode
);
9225 #if defined OBJ_COFF || defined OBJ_ELF
9226 ARM_SET_INTERWORK (sym
, support_interwork
);
9229 /* Note - do not allow local symbols (.Lxxx) to be labeled
9230 as Thumb functions. This is because these labels, whilst
9231 they exist inside Thumb code, are not the entry points for
9232 possible ARM->Thumb calls. Also, these labels can be used
9233 as part of a computed goto or switch statement. eg gcc
9234 can generate code that looks like this:
9246 The first instruction loads the address of the jump table.
9247 The second instruction converts a table index into a byte offset.
9248 The third instruction gets the jump address out of the table.
9249 The fourth instruction performs the jump.
9251 If the address stored at .Laaa is that of a symbol which has the
9252 Thumb_Func bit set, then the linker will arrange for this address
9253 to have the bottom bit set, which in turn would mean that the
9254 address computation performed by the third instruction would end
9255 up with the bottom bit set. Since the ARM is capable of unaligned
9256 word loads, the instruction would then load the incorrect address
9257 out of the jump table, and chaos would ensue. */
9258 if (label_is_thumb_function_name
9259 && (S_GET_NAME (sym
)[0] != '.' || S_GET_NAME (sym
)[1] != 'L')
9260 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
9262 /* When the address of a Thumb function is taken the bottom
9263 bit of that address should be set. This will allow
9264 interworking between Arm and Thumb functions to work
9267 THUMB_SET_FUNC (sym
, 1);
9269 label_is_thumb_function_name
= false;
9273 /* Adjust the symbol table. This marks Thumb symbols as distinct from
9277 arm_adjust_symtab ()
9282 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
9284 if (ARM_IS_THUMB (sym
))
9286 if (THUMB_IS_FUNC (sym
))
9288 /* Mark the symbol as a Thumb function. */
9289 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
9290 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
9291 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
9293 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
9294 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
9296 as_bad (_("%s: unexpected function type: %d"),
9297 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
9299 else switch (S_GET_STORAGE_CLASS (sym
))
9302 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
9305 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
9308 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
9316 if (ARM_IS_INTERWORK (sym
))
9317 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
9324 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
9326 if (ARM_IS_THUMB (sym
))
9328 elf_symbol_type
* elf_sym
;
9330 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
9331 bind
= ELF_ST_BIND (elf_sym
);
9333 /* If it's a .thumb_func, declare it as so,
9334 otherwise tag label as .code 16. */
9335 if (THUMB_IS_FUNC (sym
))
9336 elf_sym
->internal_elf_sym
.st_info
=
9337 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
9339 elf_sym
->internal_elf_sym
.st_info
=
9340 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
9349 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
9351 *input_line_pointer
= '/';
9352 input_line_pointer
+= 5;
9353 *input_line_pointer
= 0;
9361 arm_canonicalize_symbol_name (name
)
9366 if (thumb_mode
&& (len
= strlen (name
)) > 5
9367 && streq (name
+ len
- 5, "/data"))
9368 *(name
+ len
- 5) = 0;
9374 arm_validate_fix (fixP
)
9377 /* If the destination of the branch is a defined symbol which does not have
9378 the THUMB_FUNC attribute, then we must be calling a function which has
9379 the (interfacearm) attribute. We look for the Thumb entry point to that
9380 function and change the branch to refer to that function instead. */
9381 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
9382 && fixP
->fx_addsy
!= NULL
9383 && S_IS_DEFINED (fixP
->fx_addsy
)
9384 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
9386 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
9394 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
9395 local labels from being added to the output symbol table when they
9396 are used with the ADRL pseudo op. The ADRL relocation should always
9397 be resolved before the binbary is emitted, so it is safe to say that
9398 it is adjustable. */
9401 arm_fix_adjustable (fixP
)
9404 if (fixP
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
9410 /* Relocations against Thumb function names must be left unadjusted,
9411 so that the linker can use this information to correctly set the
9412 bottom bit of their addresses. The MIPS version of this function
9413 also prevents relocations that are mips-16 specific, but I do not
9414 know why it does this.
9417 There is one other problem that ought to be addressed here, but
9418 which currently is not: Taking the address of a label (rather
9419 than a function) and then later jumping to that address. Such
9420 addresses also ought to have their bottom bit set (assuming that
9421 they reside in Thumb code), but at the moment they will not. */
9424 arm_fix_adjustable (fixP
)
9427 if (fixP
->fx_addsy
== NULL
)
9430 /* Prevent all adjustments to global symbols. */
9431 if (S_IS_EXTERN (fixP
->fx_addsy
))
9434 if (S_IS_WEAK (fixP
->fx_addsy
))
9437 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
9438 && fixP
->fx_subsy
== NULL
)
9441 /* We need the symbol name for the VTABLE entries. */
9442 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
9443 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
9450 elf32_arm_target_format ()
9452 if (target_big_endian
)
9455 return "elf32-bigarm-oabi";
9457 return "elf32-bigarm";
9462 return "elf32-littlearm-oabi";
9464 return "elf32-littlearm";
9469 armelf_frob_symbol (symp
, puntp
)
9473 elf_frob_symbol (symp
, puntp
);
9477 arm_force_relocation (fixp
)
9480 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
9481 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
9482 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
9483 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
9484 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
9485 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
9491 static bfd_reloc_code_real_type
9501 bfd_reloc_code_real_type reloc
;
9505 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
9506 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
9507 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
9508 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
9509 branch instructions generated by GCC for PLT relocs. */
9510 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
9511 { NULL
, 0, BFD_RELOC_UNUSED
}
9515 for (i
= 0, ip
= input_line_pointer
;
9516 i
< sizeof (id
) && (ISALNUM (*ip
) || ISPUNCT (*ip
));
9518 id
[i
] = TOLOWER (*ip
);
9520 for (i
= 0; reloc_map
[i
].str
; i
++)
9521 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
9524 input_line_pointer
+= reloc_map
[i
].len
;
9526 return reloc_map
[i
].reloc
;
9530 s_arm_elf_cons (nbytes
)
9535 #ifdef md_flush_pending_output
9536 md_flush_pending_output ();
9539 if (is_it_end_of_statement ())
9541 demand_empty_rest_of_line ();
9545 #ifdef md_cons_align
9546 md_cons_align (nbytes
);
9551 bfd_reloc_code_real_type reloc
;
9555 if (exp
.X_op
== O_symbol
9556 && * input_line_pointer
== '('
9557 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
9559 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
9560 int size
= bfd_get_reloc_size (howto
);
9563 as_bad ("%s relocations do not fit in %d bytes",
9564 howto
->name
, nbytes
);
9567 register char *p
= frag_more ((int) nbytes
);
9568 int offset
= nbytes
- size
;
9570 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
9575 emit_expr (&exp
, (unsigned int) nbytes
);
9577 while (*input_line_pointer
++ == ',');
9579 /* Put terminator back into stream. */
9580 input_line_pointer
--;
9581 demand_empty_rest_of_line ();
9584 #endif /* OBJ_ELF */
9586 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
9587 of an rs_align_code fragment. */
9590 arm_handle_align (fragP
)
9593 static char const arm_noop
[4] = { 0x00, 0x00, 0xa0, 0xe1 };
9594 static char const thumb_noop
[2] = { 0xc0, 0x46 };
9595 static char const arm_bigend_noop
[4] = { 0xe1, 0xa0, 0x00, 0x00 };
9596 static char const thumb_bigend_noop
[2] = { 0x46, 0xc0 };
9598 int bytes
, fix
, noop_size
;
9602 if (fragP
->fr_type
!= rs_align_code
)
9605 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
9606 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
9609 if (bytes
> MAX_MEM_FOR_RS_ALIGN_CODE
)
9610 bytes
&= MAX_MEM_FOR_RS_ALIGN_CODE
;
9612 if (fragP
->tc_frag_data
)
9614 if (target_big_endian
)
9615 noop
= thumb_bigend_noop
;
9618 noop_size
= sizeof (thumb_noop
);
9622 if (target_big_endian
)
9623 noop
= arm_bigend_noop
;
9626 noop_size
= sizeof (arm_noop
);
9629 if (bytes
& (noop_size
- 1))
9631 fix
= bytes
& (noop_size
- 1);
9637 while (bytes
>= noop_size
)
9639 memcpy (p
, noop
, noop_size
);
9645 fragP
->fr_fix
+= fix
;
9646 fragP
->fr_var
= noop_size
;
9649 /* Called from md_do_align. Used to create an alignment
9650 frag in a code section. */
9653 arm_frag_align_code (n
, max
)
9659 /* We assume that there will never be a requirment
9660 to support alignments greater than 32 bytes. */
9661 if (max
> MAX_MEM_FOR_RS_ALIGN_CODE
)
9662 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
9664 p
= frag_var (rs_align_code
,
9665 MAX_MEM_FOR_RS_ALIGN_CODE
,
9667 (relax_substateT
) max
,
9675 /* Perform target specific initialisation of a frag. */
9678 arm_init_frag (fragP
)
9681 /* Record whether this frag is in an ARM or a THUMB area. */
9682 fragP
->tc_frag_data
= thumb_mode
;