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));
625 /* Pseudo Op codes. */
626 static void do_adr
PARAMS ((char *, unsigned long));
627 static void do_nop
PARAMS ((char *, unsigned long));
629 static void do_mul
PARAMS ((char *, unsigned long));
630 static void do_mla
PARAMS ((char *, unsigned long));
632 static void do_swap
PARAMS ((char *, unsigned long));
634 static void do_msr
PARAMS ((char *, unsigned long));
635 static void do_mrs
PARAMS ((char *, unsigned long));
637 static void do_mull
PARAMS ((char *, unsigned long));
639 static void do_bx
PARAMS ((char *, unsigned long));
641 /* ARM_EXT_XScale. */
642 static void do_mia
PARAMS ((char *, unsigned long));
643 static void do_mar
PARAMS ((char *, unsigned long));
644 static void do_mra
PARAMS ((char *, unsigned long));
645 static void do_pld
PARAMS ((char *, unsigned long));
646 static void do_ldrd
PARAMS ((char *, unsigned long));
649 static void do_blx
PARAMS ((char *, unsigned long));
650 static void do_bkpt
PARAMS ((char *, unsigned long));
651 static void do_clz
PARAMS ((char *, unsigned long));
652 static void do_lstc2
PARAMS ((char *, unsigned long));
653 static void do_cdp2
PARAMS ((char *, unsigned long));
654 static void do_co_reg2
PARAMS ((char *, unsigned long));
656 static void do_t_blx
PARAMS ((char *));
657 static void do_t_bkpt
PARAMS ((char *));
660 static void do_smla
PARAMS ((char *, unsigned long));
661 static void do_smlal
PARAMS ((char *, unsigned long));
662 static void do_smul
PARAMS ((char *, unsigned long));
663 static void do_qadd
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));
670 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
671 static void do_fp_ldst
PARAMS ((char *, unsigned long));
672 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
673 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
674 static void do_fp_monadic
PARAMS ((char *, unsigned long));
675 static void do_fp_cmp
PARAMS ((char *, unsigned long));
676 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
677 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
679 /* ARM_EXT_MAVERICK. */
680 static void do_c_binops
PARAMS ((char *, unsigned long, int));
681 static void do_c_binops_1
PARAMS ((char *, unsigned long));
682 static void do_c_binops_2
PARAMS ((char *, unsigned long));
683 static void do_c_binops_3
PARAMS ((char *, unsigned long));
684 static void do_c_triple
PARAMS ((char *, unsigned long, int));
685 static void do_c_triple_4
PARAMS ((char *, unsigned long));
686 static void do_c_triple_5
PARAMS ((char *, unsigned long));
687 static void do_c_quad
PARAMS ((char *, unsigned long, int));
688 static void do_c_quad_6
PARAMS ((char *, unsigned long));
689 static void do_c_dspsc
PARAMS ((char *, unsigned long, int));
690 static void do_c_dspsc_1
PARAMS ((char *, unsigned long));
691 static void do_c_dspsc_2
PARAMS ((char *, unsigned long));
692 static void do_c_shift
PARAMS ((char *, unsigned long, int));
693 static void do_c_shift_1
PARAMS ((char *, unsigned long));
694 static void do_c_shift_2
PARAMS ((char *, unsigned long));
695 static void do_c_ldst
PARAMS ((char *, unsigned long, int));
696 static void do_c_ldst_1
PARAMS ((char *, unsigned long));
697 static void do_c_ldst_2
PARAMS ((char *, unsigned long));
698 static void do_c_ldst_3
PARAMS ((char *, unsigned long));
699 static void do_c_ldst_4
PARAMS ((char *, unsigned long));
700 static int cirrus_reg_required_here
PARAMS ((char **, int, enum cirrus_regtype
));
701 static int cirrus_valid_reg
PARAMS ((int, enum cirrus_regtype
));
702 static int cirrus_parse_offset
PARAMS ((char **, int *));
704 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
705 static int arm_reg_parse
PARAMS ((char **));
706 static const struct asm_psr
* arm_psr_parse
PARAMS ((char **));
707 static void symbol_locate
PARAMS ((symbolS
*, const char *, segT
, valueT
, fragS
*));
708 static int add_to_lit_pool
PARAMS ((void));
709 static unsigned validate_immediate
PARAMS ((unsigned));
710 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
711 static int validate_offset_imm
PARAMS ((unsigned int, int));
712 static void opcode_select
PARAMS ((int));
713 static void end_of_line
PARAMS ((char *));
714 static int reg_required_here
PARAMS ((char **, int));
715 static int psr_required_here
PARAMS ((char **));
716 static int co_proc_number
PARAMS ((char **));
717 static int cp_opc_expr
PARAMS ((char **, int, int));
718 static int cp_reg_required_here
PARAMS ((char **, int));
719 static int fp_reg_required_here
PARAMS ((char **, int));
720 static int cp_address_offset
PARAMS ((char **));
721 static int cp_address_required_here
PARAMS ((char **));
722 static int my_get_float_expression
PARAMS ((char **));
723 static int skip_past_comma
PARAMS ((char **));
724 static int walk_no_bignums
PARAMS ((symbolS
*));
725 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
726 static int data_op2
PARAMS ((char **));
727 static int fp_op2
PARAMS ((char **));
728 static long reg_list
PARAMS ((char **));
729 static void thumb_load_store
PARAMS ((char *, int, int));
730 static int decode_shift
PARAMS ((char **, int));
731 static int ldst_extend
PARAMS ((char **, int));
732 static void thumb_add_sub
PARAMS ((char *, int));
733 static void insert_reg
PARAMS ((int));
734 static void thumb_shift
PARAMS ((char *, int));
735 static void thumb_mov_compare
PARAMS ((char *, int));
736 static void set_constant_flonums
PARAMS ((void));
737 static valueT md_chars_to_number
PARAMS ((char *, int));
738 static void insert_reg_alias
PARAMS ((char *, int));
739 static void output_inst
PARAMS ((void));
740 static int accum0_required_here
PARAMS ((char **));
741 static int ld_mode_required_here
PARAMS ((char **));
742 static void do_branch25
PARAMS ((char *, unsigned long));
743 static symbolS
* find_real_start
PARAMS ((symbolS
*));
745 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
748 /* ARM instructions take 4bytes in the object file, Thumb instructions
752 /* LONGEST_INST is the longest basic instruction name without
753 conditions or flags. ARM7M has 4 of length 5. El Segundo
754 has one basic instruction name of length 7 (SMLALxy). */
755 #define LONGEST_INST 10
757 /* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
758 #define CIRRUS_MODE1 0x100c
760 /* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
761 #define CIRRUS_MODE2 0x0c10
763 /* "INSN<cond> X,Y" where X:0, Y:bit16. */
764 #define CIRRUS_MODE3 0x1000
766 /* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
767 #define CIRRUS_MODE4 0x0c0010
769 /* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
770 #define CIRRUS_MODE5 0x00100c
772 /* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
773 #define CIRRUS_MODE6 0x00100c05
777 /* Basic string to match. */
778 const char * template;
780 /* Basic instruction code. */
783 /* Compulsory suffix that must follow conds. If "", then the
784 instruction is not conditional and must have no suffix. */
785 const char * comp_suffix
;
787 /* Bits to toggle if flag 'n' set. */
788 const struct asm_flg
* flags
;
790 /* Which CPU variants this exists for. */
791 unsigned long variants
;
793 /* Function to call to parse args. */
794 void (* parms
) PARAMS ((char *, unsigned long));
797 static const struct asm_opcode insns
[] =
799 /* Intel XScale extensions to ARM V5 ISA. */
800 {"mia", 0x0e200010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
801 {"miaph", 0x0e280010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
802 {"miabb", 0x0e2c0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
803 {"miabt", 0x0e2d0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
804 {"miatb", 0x0e2e0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
805 {"miatt", 0x0e2f0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
806 {"mar", 0x0c400000, NULL
, NULL
, ARM_EXT_XSCALE
, do_mar
},
807 {"mra", 0x0c500000, NULL
, NULL
, ARM_EXT_XSCALE
, do_mra
},
808 {"pld", 0xf450f000, "", NULL
, ARM_EXT_XSCALE
, do_pld
},
809 {"ldr", 0x000000d0, NULL
, ldr_flags
, ARM_EXT_V1
, do_ldrd
},
810 {"str", 0x000000f0, NULL
, str_flags
, ARM_EXT_V1
, do_ldrd
},
812 /* ARM Instructions. */
813 {"and", 0x00000000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
814 {"eor", 0x00200000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
815 {"sub", 0x00400000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
816 {"rsb", 0x00600000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
817 {"add", 0x00800000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
818 {"adc", 0x00a00000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
819 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
820 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
821 {"orr", 0x01800000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
822 {"bic", 0x01c00000, NULL
, s_flag
, ARM_EXT_V1
, do_arit
},
823 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_EXT_V1
, do_cmp
},
824 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_EXT_V1
, do_cmp
},
825 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_EXT_V1
, do_cmp
},
826 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_EXT_V1
, do_cmp
},
827 {"mov", 0x01a00000, NULL
, s_flag
, ARM_EXT_V1
, do_mov
},
828 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_EXT_V1
, do_mov
},
829 {"str", 0x04000000, NULL
, str_flags
, ARM_EXT_V1
, do_ldst
},
830 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_EXT_V1
, do_ldst
},
831 {"stm", 0x08000000, NULL
, stm_flags
, ARM_EXT_V1
, do_ldmstm
},
832 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_EXT_V1
, do_ldmstm
},
833 {"swi", 0x0f000000, NULL
, NULL
, ARM_EXT_V1
, do_swi
},
835 {"bl", 0x0b000000, NULL
, NULL
, ARM_EXT_V1
, do_branch
},
836 {"b", 0x0a000000, NULL
, NULL
, ARM_EXT_V1
, do_branch
},
838 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_EXT_V1
, do_branch
},
839 {"b", 0x0afffffe, NULL
, NULL
, ARM_EXT_V1
, do_branch
},
843 {"adr", 0x028f0000, NULL
, long_flag
, ARM_EXT_V1
, do_adr
},
844 {"nop", 0x01a00000, NULL
, NULL
, ARM_EXT_V1
, do_nop
},
846 /* ARM 2 multiplies. */
847 {"mul", 0x00000090, NULL
, s_flag
, ARM_EXT_V2
, do_mul
},
848 {"mla", 0x00200090, NULL
, s_flag
, ARM_EXT_V2
, do_mla
},
850 /* ARM 3 - swp instructions. */
851 {"swp", 0x01000090, NULL
, byte_flag
, ARM_EXT_V2S
, do_swap
},
853 /* ARM 6 Coprocessor instructions. */
854 {"mrs", 0x010f0000, NULL
, NULL
, ARM_EXT_V3
, do_mrs
},
855 {"msr", 0x0120f000, NULL
, NULL
, ARM_EXT_V3
, do_msr
},
856 /* ScottB: our code uses 0x0128f000 for msr.
857 NickC: but this is wrong because the bits 16 through 19 are
858 handled by the PSR_xxx defines above. */
860 /* ARM 7M long multiplies - need signed/unsigned flags! */
861 {"smull", 0x00c00090, NULL
, s_flag
, ARM_EXT_V3M
, do_mull
},
862 {"umull", 0x00800090, NULL
, s_flag
, ARM_EXT_V3M
, do_mull
},
863 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_EXT_V3M
, do_mull
},
864 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_EXT_V3M
, do_mull
},
866 /* ARM THUMB interworking. */
867 /* Note: bx (and blx) are required on V5, even if the processor does
868 not support Thumb. */
869 {"bx", 0x012fff10, NULL
, NULL
, ARM_EXT_V4T
| ARM_EXT_V5
, do_bx
},
871 /* Floating point instructions. */
872 {"wfs", 0x0e200110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fp_ctrl
},
873 {"rfs", 0x0e300110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fp_ctrl
},
874 {"wfc", 0x0e400110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fp_ctrl
},
875 {"rfc", 0x0e500110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fp_ctrl
},
876 {"ldf", 0x0c100100, "sdep", NULL
, FPU_FPA_EXT_V1
, do_fp_ldst
},
877 {"stf", 0x0c000100, "sdep", NULL
, FPU_FPA_EXT_V1
, do_fp_ldst
},
878 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_FPA_EXT_V2
, do_fp_ldmstm
},
879 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_FPA_EXT_V2
, do_fp_ldmstm
},
880 {"mvf", 0x0e008100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
881 {"mnf", 0x0e108100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
882 {"abs", 0x0e208100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
883 {"rnd", 0x0e308100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
884 {"sqt", 0x0e408100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
885 {"log", 0x0e508100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
886 {"lgn", 0x0e608100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
887 {"exp", 0x0e708100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
888 {"sin", 0x0e808100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
889 {"cos", 0x0e908100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
890 {"tan", 0x0ea08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
891 {"asn", 0x0eb08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
892 {"acs", 0x0ec08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
893 {"atn", 0x0ed08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
894 {"urd", 0x0ee08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
895 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_monadic
},
896 {"adf", 0x0e000100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
897 {"suf", 0x0e200100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
898 {"rsf", 0x0e300100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
899 {"muf", 0x0e100100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
900 {"dvf", 0x0e400100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
901 {"rdf", 0x0e500100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
902 {"pow", 0x0e600100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
903 {"rpw", 0x0e700100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
904 {"rmf", 0x0e800100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
905 {"fml", 0x0e900100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
906 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
907 {"frd", 0x0eb00100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
908 {"pol", 0x0ec00100, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_dyadic
},
909 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_FPA_EXT_V1
, do_fp_cmp
},
910 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_FPA_EXT_V1
, do_fp_cmp
},
911 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
912 be an optional suffix, but part of the instruction. To be compatible,
914 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fp_cmp
},
915 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_FPA_EXT_V1
, do_fp_cmp
},
916 {"flt", 0x0e000110, "sde", round_flags
, FPU_FPA_EXT_V1
, do_fp_from_reg
},
917 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_FPA_EXT_V1
, do_fp_to_reg
},
919 /* Generic copressor instructions. */
920 {"cdp", 0x0e000000, NULL
, NULL
, ARM_EXT_V2
, do_cdp
},
921 {"ldc", 0x0c100000, NULL
, long_flag
, ARM_EXT_V2
, do_lstc
},
922 {"stc", 0x0c000000, NULL
, long_flag
, ARM_EXT_V2
, do_lstc
},
923 {"mcr", 0x0e000010, NULL
, NULL
, ARM_EXT_V2
, do_co_reg
},
924 {"mrc", 0x0e100010, NULL
, NULL
, ARM_EXT_V2
, do_co_reg
},
926 /* ARM ISA extension 5. */
927 /* Note: blx is actually 2 opcodes, so the .value is set dynamically.
928 And it's sometimes conditional and sometimes not. */
929 {"blx", 0, NULL
, NULL
, ARM_EXT_V5
, do_blx
},
930 {"clz", 0x016f0f10, NULL
, NULL
, ARM_EXT_V5
, do_clz
},
931 {"bkpt", 0xe1200070, "", NULL
, ARM_EXT_V5
, do_bkpt
},
932 {"ldc2", 0xfc100000, "", long_flag
, ARM_EXT_V5
, do_lstc2
},
933 {"stc2", 0xfc000000, "", long_flag
, ARM_EXT_V5
, do_lstc2
},
934 {"cdp2", 0xfe000000, "", NULL
, ARM_EXT_V5
, do_cdp2
},
935 {"mcr2", 0xfe000010, "", NULL
, ARM_EXT_V5
, do_co_reg2
},
936 {"mrc2", 0xfe100010, "", NULL
, ARM_EXT_V5
, do_co_reg2
},
938 /* ARM ISA extension 5E, El Segundo. */
939 {"smlabb", 0x01000080, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
940 {"smlatb", 0x010000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
941 {"smlabt", 0x010000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
942 {"smlatt", 0x010000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
944 {"smlawb", 0x01200080, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
945 {"smlawt", 0x012000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
947 {"smlalbb",0x01400080, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
948 {"smlaltb",0x014000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
949 {"smlalbt",0x014000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
950 {"smlaltt",0x014000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
952 {"smulbb", 0x01600080, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
953 {"smultb", 0x016000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
954 {"smulbt", 0x016000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
955 {"smultt", 0x016000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
957 {"smulwb", 0x012000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
958 {"smulwt", 0x012000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
960 {"qadd", 0x01000050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
961 {"qdadd", 0x01400050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
962 {"qsub", 0x01200050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
963 {"qdsub", 0x01600050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
965 {"mcrr", 0x0c400000, NULL
, NULL
, ARM_EXT_V5E
, do_co_reg2c
},
966 {"mrrc", 0x0c500000, NULL
, NULL
, ARM_EXT_V5E
, do_co_reg2c
},
968 /* Cirrus DSP instructions. */
969 {"cfldrs", 0x0c100400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_1
},
970 {"cfldrd", 0x0c500400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_2
},
971 {"cfldr32", 0x0c100500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_3
},
972 {"cfldr64", 0x0c500500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_4
},
973 {"cfstrs", 0x0c000400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_1
},
974 {"cfstrd", 0x0c400400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_2
},
975 {"cfstr32", 0x0c000500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_3
},
976 {"cfstr64", 0x0c400500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_ldst_4
},
977 {"cfmvsr", 0x0e000450, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_2
},
978 {"cfmvrs", 0x0e100450, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
979 {"cfmvdlr", 0x0e000410, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_2
},
980 {"cfmvrdl", 0x0e100410, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
981 {"cfmvdhr", 0x0e000430, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_2
},
982 {"cfmvrdh", 0x0e100430, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
983 {"cfmv64lr", 0x0e000510, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_2
},
984 {"cfmvr64l", 0x0e100510, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
985 {"cfmv64hr", 0x0e000530, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_2
},
986 {"cfmvr64h", 0x0e100530, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
987 {"cfmval32", 0x0e100610, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
988 {"cfmv32al", 0x0e000610, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
989 {"cfmvam32", 0x0e100630, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
990 {"cfmv32am", 0x0e000630, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
991 {"cfmvah32", 0x0e100650, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
992 {"cfmv32ah", 0x0e000650, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
993 {"cfmv32a", 0x0e000670, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
994 {"cfmva32", 0x0e100670, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
995 {"cfmv64a", 0x0e000690, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
996 {"cfmva64", 0x0e100690, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_3
},
997 {"cfmvsc32", 0x0e1006b0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_dspsc_1
},
998 {"cfmv32sc", 0x0e0006b0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_dspsc_2
},
999 {"cfcpys", 0x0e000400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1000 {"cfcpyd", 0x0e000420, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1001 {"cfcvtsd", 0x0e000460, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1002 {"cfcvtds", 0x0e000440, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1003 {"cfcvt32s", 0x0e000480, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1004 {"cfcvt32d", 0x0e0004a0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1005 {"cfcvt64s", 0x0e0004c0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1006 {"cfcvt64d", 0x0e0004e0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1007 {"cfcvts32", 0x0e100580, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1008 {"cfcvtd32", 0x0e1005a0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1009 {"cftruncs32",0x0e1005c0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1010 {"cftruncd32",0x0e1005e0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1011 {"cfrshl32", 0x0e000550, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_4
},
1012 {"cfrshl64", 0x0e000570, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_4
},
1013 {"cfsh32", 0x0e000500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_shift_1
},
1014 {"cfsh64", 0x0e200500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_shift_2
},
1015 {"cfcmps", 0x0e100490, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1016 {"cfcmpd", 0x0e1004b0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1017 {"cfcmp32", 0x0e100590, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1018 {"cfcmp64", 0x0e1005b0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1019 {"cfabss", 0x0e300400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1020 {"cfabsd", 0x0e300420, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1021 {"cfnegs", 0x0e300440, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1022 {"cfnegd", 0x0e300460, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1023 {"cfadds", 0x0e300480, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1024 {"cfaddd", 0x0e3004a0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1025 {"cfsubs", 0x0e3004c0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1026 {"cfsubd", 0x0e3004e0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1027 {"cfmuls", 0x0e100400, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1028 {"cfmuld", 0x0e100420, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1029 {"cfabs32", 0x0e300500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1030 {"cfabs64", 0x0e300520, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1031 {"cfneg32", 0x0e300540, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1032 {"cfneg64", 0x0e300560, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_binops_1
},
1033 {"cfadd32", 0x0e300580, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1034 {"cfadd64", 0x0e3005a0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1035 {"cfsub32", 0x0e3005c0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1036 {"cfsub64", 0x0e3005e0, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1037 {"cfmul32", 0x0e100500, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1038 {"cfmul64", 0x0e100520, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1039 {"cfmac32", 0x0e100540, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1040 {"cfmsc32", 0x0e100560, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_triple_5
},
1041 {"cfmadd32", 0x0e000600, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_quad_6
},
1042 {"cfmsub32", 0x0e100600, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_quad_6
},
1043 {"cfmadda32", 0x0e200600, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_quad_6
},
1044 {"cfmsuba32", 0x0e300600, NULL
, NULL
, ARM_EXT_MAVERICK
, do_c_quad_6
},
1047 /* Defines for various bits that we will want to toggle. */
1048 #define INST_IMMEDIATE 0x02000000
1049 #define OFFSET_REG 0x02000000
1050 #define HWOFFSET_IMM 0x00400000
1051 #define SHIFT_BY_REG 0x00000010
1052 #define PRE_INDEX 0x01000000
1053 #define INDEX_UP 0x00800000
1054 #define WRITE_BACK 0x00200000
1055 #define LDM_TYPE_2_OR_3 0x00400000
1057 #define LITERAL_MASK 0xf000f000
1058 #define COND_MASK 0xf0000000
1059 #define OPCODE_MASK 0xfe1fffff
1060 #define DATA_OP_SHIFT 21
1062 /* Codes to distinguish the arithmetic instructions. */
1063 #define OPCODE_AND 0
1064 #define OPCODE_EOR 1
1065 #define OPCODE_SUB 2
1066 #define OPCODE_RSB 3
1067 #define OPCODE_ADD 4
1068 #define OPCODE_ADC 5
1069 #define OPCODE_SBC 6
1070 #define OPCODE_RSC 7
1071 #define OPCODE_TST 8
1072 #define OPCODE_TEQ 9
1073 #define OPCODE_CMP 10
1074 #define OPCODE_CMN 11
1075 #define OPCODE_ORR 12
1076 #define OPCODE_MOV 13
1077 #define OPCODE_BIC 14
1078 #define OPCODE_MVN 15
1080 static void do_t_nop
PARAMS ((char *));
1081 static void do_t_arit
PARAMS ((char *));
1082 static void do_t_add
PARAMS ((char *));
1083 static void do_t_asr
PARAMS ((char *));
1084 static void do_t_branch9
PARAMS ((char *));
1085 static void do_t_branch12
PARAMS ((char *));
1086 static void do_t_branch23
PARAMS ((char *));
1087 static void do_t_bx
PARAMS ((char *));
1088 static void do_t_compare
PARAMS ((char *));
1089 static void do_t_ldmstm
PARAMS ((char *));
1090 static void do_t_ldr
PARAMS ((char *));
1091 static void do_t_ldrb
PARAMS ((char *));
1092 static void do_t_ldrh
PARAMS ((char *));
1093 static void do_t_lds
PARAMS ((char *));
1094 static void do_t_lsl
PARAMS ((char *));
1095 static void do_t_lsr
PARAMS ((char *));
1096 static void do_t_mov
PARAMS ((char *));
1097 static void do_t_push_pop
PARAMS ((char *));
1098 static void do_t_str
PARAMS ((char *));
1099 static void do_t_strb
PARAMS ((char *));
1100 static void do_t_strh
PARAMS ((char *));
1101 static void do_t_sub
PARAMS ((char *));
1102 static void do_t_swi
PARAMS ((char *));
1103 static void do_t_adr
PARAMS ((char *));
1105 #define T_OPCODE_MUL 0x4340
1106 #define T_OPCODE_TST 0x4200
1107 #define T_OPCODE_CMN 0x42c0
1108 #define T_OPCODE_NEG 0x4240
1109 #define T_OPCODE_MVN 0x43c0
1111 #define T_OPCODE_ADD_R3 0x1800
1112 #define T_OPCODE_SUB_R3 0x1a00
1113 #define T_OPCODE_ADD_HI 0x4400
1114 #define T_OPCODE_ADD_ST 0xb000
1115 #define T_OPCODE_SUB_ST 0xb080
1116 #define T_OPCODE_ADD_SP 0xa800
1117 #define T_OPCODE_ADD_PC 0xa000
1118 #define T_OPCODE_ADD_I8 0x3000
1119 #define T_OPCODE_SUB_I8 0x3800
1120 #define T_OPCODE_ADD_I3 0x1c00
1121 #define T_OPCODE_SUB_I3 0x1e00
1123 #define T_OPCODE_ASR_R 0x4100
1124 #define T_OPCODE_LSL_R 0x4080
1125 #define T_OPCODE_LSR_R 0x40c0
1126 #define T_OPCODE_ASR_I 0x1000
1127 #define T_OPCODE_LSL_I 0x0000
1128 #define T_OPCODE_LSR_I 0x0800
1130 #define T_OPCODE_MOV_I8 0x2000
1131 #define T_OPCODE_CMP_I8 0x2800
1132 #define T_OPCODE_CMP_LR 0x4280
1133 #define T_OPCODE_MOV_HR 0x4600
1134 #define T_OPCODE_CMP_HR 0x4500
1136 #define T_OPCODE_LDR_PC 0x4800
1137 #define T_OPCODE_LDR_SP 0x9800
1138 #define T_OPCODE_STR_SP 0x9000
1139 #define T_OPCODE_LDR_IW 0x6800
1140 #define T_OPCODE_STR_IW 0x6000
1141 #define T_OPCODE_LDR_IH 0x8800
1142 #define T_OPCODE_STR_IH 0x8000
1143 #define T_OPCODE_LDR_IB 0x7800
1144 #define T_OPCODE_STR_IB 0x7000
1145 #define T_OPCODE_LDR_RW 0x5800
1146 #define T_OPCODE_STR_RW 0x5000
1147 #define T_OPCODE_LDR_RH 0x5a00
1148 #define T_OPCODE_STR_RH 0x5200
1149 #define T_OPCODE_LDR_RB 0x5c00
1150 #define T_OPCODE_STR_RB 0x5400
1152 #define T_OPCODE_PUSH 0xb400
1153 #define T_OPCODE_POP 0xbc00
1155 #define T_OPCODE_BRANCH 0xe7fe
1157 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
1159 #define THUMB_SIZE 2 /* Size of thumb instruction. */
1160 #define THUMB_REG_LO 0x1
1161 #define THUMB_REG_HI 0x2
1162 #define THUMB_REG_ANY 0x3
1164 #define THUMB_H1 0x0080
1165 #define THUMB_H2 0x0040
1171 #define THUMB_MOVE 0
1172 #define THUMB_COMPARE 1
1174 #define THUMB_LOAD 0
1175 #define THUMB_STORE 1
1177 #define THUMB_PP_PC_LR 0x0100
1179 /* These three are used for immediate shifts, do not alter. */
1180 #define THUMB_WORD 2
1181 #define THUMB_HALFWORD 1
1182 #define THUMB_BYTE 0
1186 /* Basic string to match. */
1187 const char * template;
1189 /* Basic instruction code. */
1190 unsigned long value
;
1194 /* Which CPU variants this exists for. */
1195 unsigned long variants
;
1197 /* Function to call to parse args. */
1198 void (* parms
) PARAMS ((char *));
1201 static const struct thumb_opcode tinsns
[] =
1203 {"adc", 0x4140, 2, ARM_EXT_V4T
, do_t_arit
},
1204 {"add", 0x0000, 2, ARM_EXT_V4T
, do_t_add
},
1205 {"and", 0x4000, 2, ARM_EXT_V4T
, do_t_arit
},
1206 {"asr", 0x0000, 2, ARM_EXT_V4T
, do_t_asr
},
1207 {"b", T_OPCODE_BRANCH
, 2, ARM_EXT_V4T
, do_t_branch12
},
1208 {"beq", 0xd0fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1209 {"bne", 0xd1fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1210 {"bcs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1211 {"bhs", 0xd2fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1212 {"bcc", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1213 {"bul", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1214 {"blo", 0xd3fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1215 {"bmi", 0xd4fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1216 {"bpl", 0xd5fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1217 {"bvs", 0xd6fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1218 {"bvc", 0xd7fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1219 {"bhi", 0xd8fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1220 {"bls", 0xd9fe, 2, ARM_EXT_V4T
, do_t_branch9
},
1221 {"bge", 0xdafe, 2, ARM_EXT_V4T
, do_t_branch9
},
1222 {"blt", 0xdbfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1223 {"bgt", 0xdcfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1224 {"ble", 0xddfe, 2, ARM_EXT_V4T
, do_t_branch9
},
1225 {"bal", 0xdefe, 2, ARM_EXT_V4T
, do_t_branch9
},
1226 {"bic", 0x4380, 2, ARM_EXT_V4T
, do_t_arit
},
1227 {"bl", 0xf7fffffe, 4, ARM_EXT_V4T
, do_t_branch23
},
1228 {"blx", 0, 0, ARM_EXT_V5
, do_t_blx
},
1229 {"bkpt", 0xbe00, 2, ARM_EXT_V5
, do_t_bkpt
},
1230 {"bx", 0x4700, 2, ARM_EXT_V4T
, do_t_bx
},
1231 {"cmn", T_OPCODE_CMN
, 2, ARM_EXT_V4T
, do_t_arit
},
1232 {"cmp", 0x0000, 2, ARM_EXT_V4T
, do_t_compare
},
1233 {"eor", 0x4040, 2, ARM_EXT_V4T
, do_t_arit
},
1234 {"ldmia", 0xc800, 2, ARM_EXT_V4T
, do_t_ldmstm
},
1235 {"ldr", 0x0000, 2, ARM_EXT_V4T
, do_t_ldr
},
1236 {"ldrb", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrb
},
1237 {"ldrh", 0x0000, 2, ARM_EXT_V4T
, do_t_ldrh
},
1238 {"ldrsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
1239 {"ldrsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
1240 {"ldsb", 0x5600, 2, ARM_EXT_V4T
, do_t_lds
},
1241 {"ldsh", 0x5e00, 2, ARM_EXT_V4T
, do_t_lds
},
1242 {"lsl", 0x0000, 2, ARM_EXT_V4T
, do_t_lsl
},
1243 {"lsr", 0x0000, 2, ARM_EXT_V4T
, do_t_lsr
},
1244 {"mov", 0x0000, 2, ARM_EXT_V4T
, do_t_mov
},
1245 {"mul", T_OPCODE_MUL
, 2, ARM_EXT_V4T
, do_t_arit
},
1246 {"mvn", T_OPCODE_MVN
, 2, ARM_EXT_V4T
, do_t_arit
},
1247 {"neg", T_OPCODE_NEG
, 2, ARM_EXT_V4T
, do_t_arit
},
1248 {"orr", 0x4300, 2, ARM_EXT_V4T
, do_t_arit
},
1249 {"pop", 0xbc00, 2, ARM_EXT_V4T
, do_t_push_pop
},
1250 {"push", 0xb400, 2, ARM_EXT_V4T
, do_t_push_pop
},
1251 {"ror", 0x41c0, 2, ARM_EXT_V4T
, do_t_arit
},
1252 {"sbc", 0x4180, 2, ARM_EXT_V4T
, do_t_arit
},
1253 {"stmia", 0xc000, 2, ARM_EXT_V4T
, do_t_ldmstm
},
1254 {"str", 0x0000, 2, ARM_EXT_V4T
, do_t_str
},
1255 {"strb", 0x0000, 2, ARM_EXT_V4T
, do_t_strb
},
1256 {"strh", 0x0000, 2, ARM_EXT_V4T
, do_t_strh
},
1257 {"swi", 0xdf00, 2, ARM_EXT_V4T
, do_t_swi
},
1258 {"sub", 0x0000, 2, ARM_EXT_V4T
, do_t_sub
},
1259 {"tst", T_OPCODE_TST
, 2, ARM_EXT_V4T
, do_t_arit
},
1261 {"adr", 0x0000, 2, ARM_EXT_V4T
, do_t_adr
},
1262 {"nop", 0x46C0, 2, ARM_EXT_V4T
, do_t_nop
}, /* mov r8,r8 */
1271 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
1272 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
1273 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
1275 #define ARM_EXT_MAVERICKSC_REG 134
1277 #define cirrus_register(reg) ((reg) >= 50 && (reg) <= 134)
1278 #define cirrus_mvf_register(reg) ((reg) >= 50 && (reg) <= 65)
1279 #define cirrus_mvd_register(reg) ((reg) >= 70 && (reg) <= 85)
1280 #define cirrus_mvfx_register(reg) ((reg) >= 90 && (reg) <= 105)
1281 #define cirrus_mvdx_register(reg) ((reg) >= 110 && (reg) <= 125)
1282 #define cirrus_mvax_register(reg) ((reg) >= 130 && (reg) <= 133)
1283 #define ARM_EXT_MAVERICKsc_register(reg) ((reg) == ARM_EXT_MAVERICKSC_REG)
1289 /* These are the standard names. Users can add aliases with .req. */
1290 static const struct reg_entry reg_table
[] =
1292 /* Processor Register Numbers. */
1293 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
1294 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
1295 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
1296 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
1297 /* APCS conventions. */
1298 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
1299 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
1300 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
1301 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
1302 /* ATPCS additions to APCS conventions. */
1303 {"wr", 7}, {"v8", 11},
1305 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
1306 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
1307 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
1308 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
1309 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
1310 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
1311 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
1312 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
1313 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
1314 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1315 /* ATPCS additions to float register names. */
1316 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
1317 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
1318 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
1319 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
1320 /* Cirrus DSP coprocessor registers. */
1321 {"mvf0", 50}, {"mvf1", 51}, {"mvf2", 52}, {"mvf3", 53},
1322 {"mvf4", 54}, {"mvf5", 55}, {"mvf6", 56}, {"mvf7", 57},
1323 {"mvf8", 58}, {"mvf9", 59}, {"mvf10", 60}, {"mvf11", 61},
1324 {"mvf12", 62},{"mvf13", 63}, {"mvf14", 64}, {"mvf15", 65},
1325 {"mvd0", 70}, {"mvd1", 71}, {"mvd2", 72}, {"mvd3", 73},
1326 {"mvd4", 74}, {"mvd5", 75}, {"mvd6", 76}, {"mvd7", 77},
1327 {"mvd8", 78}, {"mvd9", 79}, {"mvd10", 80}, {"mvd11", 81},
1328 {"mvd12", 82},{"mvd13", 83}, {"mvd14", 84}, {"mvd15", 85},
1329 {"mvfx0", 90},{"mvfx1", 91}, {"mvfx2", 92}, {"mvfx3", 93},
1330 {"mvfx4", 94},{"mvfx5", 95}, {"mvfx6", 96}, {"mvfx7", 97},
1331 {"mvfx8", 98},{"mvfx9", 99}, {"mvfx10", 100},{"mvfx11", 101},
1332 {"mvfx12", 102},{"mvfx13", 103},{"mvfx14", 104},{"mvfx15", 105},
1333 {"mvdx0", 110}, {"mvdx1", 111}, {"mvdx2", 112}, {"mvdx3", 113},
1334 {"mvdx4", 114}, {"mvdx5", 115}, {"mvdx6", 116}, {"mvdx7", 117},
1335 {"mvdx8", 118}, {"mvdx9", 119}, {"mvdx10", 120},{"mvdx11", 121},
1336 {"mvdx12", 122},{"mvdx13", 123},{"mvdx14", 124},{"mvdx15", 125},
1337 {"mvax0", 130}, {"mvax1", 131}, {"mvax2", 132}, {"mvax3", 133},
1338 {"dspsc", ARM_EXT_MAVERICKSC_REG
},
1339 /* FIXME: At some point we need to add VFP register names. */
1340 /* Array terminator. */
1344 #define BAD_ARGS _("Bad arguments to instruction")
1345 #define BAD_PC _("r15 not allowed here")
1346 #define BAD_FLAGS _("Instruction should not have flags")
1347 #define BAD_COND _("Instruction is not conditional")
1348 #define ERR_NO_ACCUM _("acc0 expected")
1350 static struct hash_control
* arm_ops_hsh
= NULL
;
1351 static struct hash_control
* arm_tops_hsh
= NULL
;
1352 static struct hash_control
* arm_cond_hsh
= NULL
;
1353 static struct hash_control
* arm_shift_hsh
= NULL
;
1354 static struct hash_control
* arm_reg_hsh
= NULL
;
1355 static struct hash_control
* arm_psr_hsh
= NULL
;
1357 /* This table describes all the machine specific pseudo-ops the assembler
1358 has to support. The fields are:
1359 pseudo-op name without dot
1360 function to call to execute this pseudo-op
1361 Integer arg to pass to the function. */
1363 static void s_req
PARAMS ((int));
1364 static void s_align
PARAMS ((int));
1365 static void s_bss
PARAMS ((int));
1366 static void s_even
PARAMS ((int));
1367 static void s_ltorg
PARAMS ((int));
1368 static void s_arm
PARAMS ((int));
1369 static void s_thumb
PARAMS ((int));
1370 static void s_code
PARAMS ((int));
1371 static void s_force_thumb
PARAMS ((int));
1372 static void s_thumb_func
PARAMS ((int));
1373 static void s_thumb_set
PARAMS ((int));
1374 static void arm_s_text
PARAMS ((int));
1375 static void arm_s_data
PARAMS ((int));
1377 static void arm_s_section
PARAMS ((int));
1378 static void s_arm_elf_cons
PARAMS ((int));
1381 static int my_get_expression
PARAMS ((expressionS
*, char **));
1383 const pseudo_typeS md_pseudo_table
[] =
1385 /* Never called becasue '.req' does not start line. */
1386 { "req", s_req
, 0 },
1387 { "bss", s_bss
, 0 },
1388 { "align", s_align
, 0 },
1389 { "arm", s_arm
, 0 },
1390 { "thumb", s_thumb
, 0 },
1391 { "code", s_code
, 0 },
1392 { "force_thumb", s_force_thumb
, 0 },
1393 { "thumb_func", s_thumb_func
, 0 },
1394 { "thumb_set", s_thumb_set
, 0 },
1395 { "even", s_even
, 0 },
1396 { "ltorg", s_ltorg
, 0 },
1397 { "pool", s_ltorg
, 0 },
1398 /* Allow for the effect of section changes. */
1399 { "text", arm_s_text
, 0 },
1400 { "data", arm_s_data
, 0 },
1402 { "section", arm_s_section
, 0 },
1403 { "section.s", arm_s_section
, 0 },
1404 { "sect", arm_s_section
, 0 },
1405 { "sect.s", arm_s_section
, 0 },
1406 { "word", s_arm_elf_cons
, 4 },
1407 { "long", s_arm_elf_cons
, 4 },
1408 { "file", dwarf2_directive_file
, 0 },
1409 { "loc", dwarf2_directive_loc
, 0 },
1413 { "extend", float_cons
, 'x' },
1414 { "ldouble", float_cons
, 'x' },
1415 { "packed", float_cons
, 'p' },
1419 /* Stuff needed to resolve the label ambiguity
1429 symbolS
* last_label_seen
;
1430 static int label_is_thumb_function_name
= false;
1432 /* Literal stuff. */
1434 #define MAX_LITERAL_POOL_SIZE 1024
1436 typedef struct literalS
1438 struct expressionS exp
;
1439 struct arm_it
* inst
;
1442 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1444 /* Next free entry in the pool. */
1445 int next_literal_pool_place
= 0;
1447 /* Next literal pool number. */
1448 int lit_pool_num
= 1;
1450 symbolS
* current_poolP
= NULL
;
1457 if (current_poolP
== NULL
)
1458 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1459 (valueT
) 0, &zero_address_frag
);
1461 /* Check if this literal value is already in the pool: */
1462 while (lit_count
< next_literal_pool_place
)
1464 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1465 && inst
.reloc
.exp
.X_op
== O_constant
1466 && (literals
[lit_count
].exp
.X_add_number
1467 == inst
.reloc
.exp
.X_add_number
)
1468 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1471 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1472 && inst
.reloc
.exp
.X_op
== O_symbol
1473 && (literals
[lit_count
].exp
.X_add_number
1474 == inst
.reloc
.exp
.X_add_number
)
1475 && (literals
[lit_count
].exp
.X_add_symbol
1476 == inst
.reloc
.exp
.X_add_symbol
)
1477 && (literals
[lit_count
].exp
.X_op_symbol
1478 == inst
.reloc
.exp
.X_op_symbol
))
1484 if (lit_count
== next_literal_pool_place
) /* New entry. */
1486 if (next_literal_pool_place
>= MAX_LITERAL_POOL_SIZE
)
1488 inst
.error
= _("Literal Pool Overflow");
1492 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1493 lit_count
= next_literal_pool_place
++;
1496 inst
.reloc
.exp
.X_op
= O_symbol
;
1497 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1498 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1503 /* Can't use symbol_new here, so have to create a symbol and then at
1504 a later date assign it a value. Thats what these functions do. */
1507 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1509 const char * name
; /* It is copied, the caller can modify. */
1510 segT segment
; /* Segment identifier (SEG_<something>). */
1511 valueT valu
; /* Symbol value. */
1512 fragS
* frag
; /* Associated fragment. */
1514 unsigned int name_length
;
1515 char * preserved_copy_of_name
;
1517 name_length
= strlen (name
) + 1; /* +1 for \0. */
1518 obstack_grow (¬es
, name
, name_length
);
1519 preserved_copy_of_name
= obstack_finish (¬es
);
1520 #ifdef STRIP_UNDERSCORE
1521 if (preserved_copy_of_name
[0] == '_')
1522 preserved_copy_of_name
++;
1525 #ifdef tc_canonicalize_symbol_name
1526 preserved_copy_of_name
=
1527 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1530 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1532 S_SET_SEGMENT (symbolP
, segment
);
1533 S_SET_VALUE (symbolP
, valu
);
1534 symbol_clear_list_pointers(symbolP
);
1536 symbol_set_frag (symbolP
, frag
);
1538 /* Link to end of symbol chain. */
1540 extern int symbol_table_frozen
;
1541 if (symbol_table_frozen
)
1545 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1547 obj_symbol_new_hook (symbolP
);
1549 #ifdef tc_symbol_new_hook
1550 tc_symbol_new_hook (symbolP
);
1554 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1555 #endif /* DEBUG_SYMS */
1558 /* Check that an immediate is valid.
1559 If so, convert it to the right format. */
1562 validate_immediate (val
)
1568 #define rotate_left(v, n) (v << n | v >> (32 - n))
1570 for (i
= 0; i
< 32; i
+= 2)
1571 if ((a
= rotate_left (val
, i
)) <= 0xff)
1572 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
1577 /* Check to see if an immediate can be computed as two seperate immediate
1578 values, added together. We already know that this value cannot be
1579 computed by just one ARM instruction. */
1582 validate_immediate_twopart (val
, highpart
)
1584 unsigned int * highpart
;
1589 for (i
= 0; i
< 32; i
+= 2)
1590 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1596 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1598 else if (a
& 0xff0000)
1602 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1606 assert (a
& 0xff000000);
1607 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1610 return (a
& 0xff) | (i
<< 7);
1617 validate_offset_imm (val
, hwse
)
1621 if ((hwse
&& val
> 255) || val
> 4095)
1628 int a ATTRIBUTE_UNUSED
;
1630 as_bad (_("Invalid syntax for .req directive."));
1635 int ignore ATTRIBUTE_UNUSED
;
1637 /* We don't support putting frags in the BSS segment, we fake it by
1638 marking in_bss, then looking at s_skip for clues. */
1639 subseg_set (bss_section
, 0);
1640 demand_empty_rest_of_line ();
1645 int ignore ATTRIBUTE_UNUSED
;
1647 /* Never make frag if expect extra pass. */
1649 frag_align (1, 0, 0);
1651 record_alignment (now_seg
, 1);
1653 demand_empty_rest_of_line ();
1658 int ignored ATTRIBUTE_UNUSED
;
1663 if (current_poolP
== NULL
)
1666 /* Align pool as you have word accesses.
1667 Only make a frag if we have to. */
1669 frag_align (2, 0, 0);
1671 record_alignment (now_seg
, 2);
1673 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1675 symbol_locate (current_poolP
, sym_name
, now_seg
,
1676 (valueT
) frag_now_fix (), frag_now
);
1677 symbol_table_insert (current_poolP
);
1679 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1681 #if defined OBJ_COFF || defined OBJ_ELF
1682 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1685 while (lit_count
< next_literal_pool_place
)
1686 /* First output the expression in the instruction to the pool. */
1687 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1689 next_literal_pool_place
= 0;
1690 current_poolP
= NULL
;
1693 /* Same as s_align_ptwo but align 0 => align 2. */
1697 int unused ATTRIBUTE_UNUSED
;
1700 register long temp_fill
;
1701 long max_alignment
= 15;
1703 temp
= get_absolute_expression ();
1704 if (temp
> max_alignment
)
1705 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1708 as_bad (_("Alignment negative. 0 assumed."));
1712 if (*input_line_pointer
== ',')
1714 input_line_pointer
++;
1715 temp_fill
= get_absolute_expression ();
1723 /* Only make a frag if we HAVE to. */
1724 if (temp
&& !need_pass_2
)
1725 frag_align (temp
, (int) temp_fill
, 0);
1726 demand_empty_rest_of_line ();
1728 record_alignment (now_seg
, temp
);
1732 s_force_thumb (ignore
)
1733 int ignore ATTRIBUTE_UNUSED
;
1735 /* If we are not already in thumb mode go into it, EVEN if
1736 the target processor does not support thumb instructions.
1737 This is used by gcc/config/arm/lib1funcs.asm for example
1738 to compile interworking support functions even if the
1739 target processor should not support interworking. */
1744 record_alignment (now_seg
, 1);
1747 demand_empty_rest_of_line ();
1751 s_thumb_func (ignore
)
1752 int ignore ATTRIBUTE_UNUSED
;
1757 /* The following label is the name/address of the start of a Thumb function.
1758 We need to know this for the interworking support. */
1759 label_is_thumb_function_name
= true;
1761 demand_empty_rest_of_line ();
1764 /* Perform a .set directive, but also mark the alias as
1765 being a thumb function. */
1771 /* XXX the following is a duplicate of the code for s_set() in read.c
1772 We cannot just call that code as we need to get at the symbol that
1774 register char * name
;
1775 register char delim
;
1776 register char * end_name
;
1777 register symbolS
* symbolP
;
1779 /* Especial apologies for the random logic:
1780 This just grew, and could be parsed much more simply!
1782 name
= input_line_pointer
;
1783 delim
= get_symbol_end ();
1784 end_name
= input_line_pointer
;
1789 if (*input_line_pointer
!= ',')
1792 as_bad (_("Expected comma after name \"%s\""), name
);
1794 ignore_rest_of_line ();
1798 input_line_pointer
++;
1801 if (name
[0] == '.' && name
[1] == '\0')
1803 /* XXX - this should not happen to .thumb_set. */
1807 if ((symbolP
= symbol_find (name
)) == NULL
1808 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1811 /* When doing symbol listings, play games with dummy fragments living
1812 outside the normal fragment chain to record the file and line info
1814 if (listing
& LISTING_SYMBOLS
)
1816 extern struct list_info_struct
* listing_tail
;
1817 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
1819 memset (dummy_frag
, 0, sizeof (fragS
));
1820 dummy_frag
->fr_type
= rs_fill
;
1821 dummy_frag
->line
= listing_tail
;
1822 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1823 dummy_frag
->fr_symbol
= symbolP
;
1827 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1830 /* "set" symbols are local unless otherwise specified. */
1831 SF_SET_LOCAL (symbolP
);
1832 #endif /* OBJ_COFF */
1833 } /* Make a new symbol. */
1835 symbol_table_insert (symbolP
);
1840 && S_IS_DEFINED (symbolP
)
1841 && S_GET_SEGMENT (symbolP
) != reg_section
)
1842 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1844 pseudo_set (symbolP
);
1846 demand_empty_rest_of_line ();
1848 /* XXX Now we come to the Thumb specific bit of code. */
1850 THUMB_SET_FUNC (symbolP
, 1);
1851 ARM_SET_THUMB (symbolP
, 1);
1852 #if defined OBJ_ELF || defined OBJ_COFF
1853 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1857 /* If we change section we must dump the literal pool first. */
1863 if (now_seg
!= text_section
)
1867 obj_elf_text (ignore
);
1877 if (flag_readonly_data_in_text
)
1879 if (now_seg
!= text_section
)
1882 else if (now_seg
!= data_section
)
1886 obj_elf_data (ignore
);
1894 arm_s_section (ignore
)
1899 obj_elf_section (ignore
);
1904 opcode_select (width
)
1912 if (! (cpu_variant
& ARM_EXT_V4T
))
1913 as_bad (_("selected processor does not support THUMB opcodes"));
1916 /* No need to force the alignment, since we will have been
1917 coming from ARM mode, which is word-aligned. */
1918 record_alignment (now_seg
, 1);
1925 if ((cpu_variant
& ARM_ANY
) == ARM_EXT_V4T
)
1926 as_bad (_("selected processor does not support ARM opcodes"));
1931 frag_align (2, 0, 0);
1933 record_alignment (now_seg
, 1);
1938 as_bad (_("invalid instruction size selected (%d)"), width
);
1944 int ignore ATTRIBUTE_UNUSED
;
1947 demand_empty_rest_of_line ();
1952 int ignore ATTRIBUTE_UNUSED
;
1955 demand_empty_rest_of_line ();
1960 int unused ATTRIBUTE_UNUSED
;
1964 temp
= get_absolute_expression ();
1969 opcode_select (temp
);
1973 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1981 skip_whitespace (str
);
1984 inst
.error
= _("Garbage following instruction");
1988 skip_past_comma (str
)
1991 char * p
= * str
, c
;
1994 while ((c
= *p
) == ' ' || c
== ',')
1997 if (c
== ',' && comma
++)
2005 return comma
? SUCCESS
: FAIL
;
2008 /* A standard register must be given at this point.
2009 SHIFT is the place to put it in inst.instruction.
2010 Restores input start point on error.
2011 Returns the reg#, or FAIL. */
2014 reg_required_here (str
, shift
)
2018 static char buff
[128]; /* XXX */
2020 char * start
= * str
;
2022 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
2025 inst
.instruction
|= reg
<< shift
;
2029 /* Restore the start point, we may have got a reg of the wrong class. */
2032 /* In the few cases where we might be able to accept something else
2033 this error can be overridden. */
2034 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
2040 static const struct asm_psr
*
2042 register char ** ccp
;
2044 char * start
= * ccp
;
2047 const struct asm_psr
* psr
;
2051 /* Skip to the end of the next word in the input stream. */
2056 while (ISALPHA (c
) || c
== '_');
2058 /* Terminate the word. */
2061 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
2062 feature for ease of use and backwards compatibility. */
2063 if (!strncmp (start
, "cpsr", 4))
2064 strncpy (start
, "CPSR", 4);
2065 else if (!strncmp (start
, "spsr", 4))
2066 strncpy (start
, "SPSR", 4);
2068 /* Now locate the word in the psr hash table. */
2069 psr
= (const struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
2071 /* Restore the input stream. */
2074 /* If we found a valid match, advance the
2075 stream pointer past the end of the word. */
2081 /* Parse the input looking for a PSR flag. */
2084 psr_required_here (str
)
2087 char * start
= * str
;
2088 const struct asm_psr
* psr
;
2090 psr
= arm_psr_parse (str
);
2094 /* If this is the SPSR that is being modified, set the R bit. */
2096 inst
.instruction
|= SPSR_BIT
;
2098 /* Set the psr flags in the MSR instruction. */
2099 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
2104 /* In the few cases where we might be able to accept
2105 something else this error can be overridden. */
2106 inst
.error
= _("flag for {c}psr instruction expected");
2108 /* Restore the start point. */
2114 co_proc_number (str
)
2117 int processor
, pchar
;
2119 skip_whitespace (* str
);
2121 /* The data sheet seems to imply that just a number on its own is valid
2122 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
2124 if (**str
== 'p' || **str
== 'P')
2128 if (pchar
>= '0' && pchar
<= '9')
2130 processor
= pchar
- '0';
2131 if (**str
>= '0' && **str
<= '9')
2133 processor
= processor
* 10 + *(*str
)++ - '0';
2136 inst
.error
= _("Illegal co-processor number");
2143 inst
.error
= _("Bad or missing co-processor number");
2147 inst
.instruction
|= processor
<< 8;
2152 cp_opc_expr (str
, where
, length
)
2159 skip_whitespace (* str
);
2161 memset (&expr
, '\0', sizeof (expr
));
2163 if (my_get_expression (&expr
, str
))
2165 if (expr
.X_op
!= O_constant
)
2167 inst
.error
= _("bad or missing expression");
2171 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
2173 inst
.error
= _("immediate co-processor expression too large");
2177 inst
.instruction
|= expr
.X_add_number
<< where
;
2182 cp_reg_required_here (str
, where
)
2187 char * start
= *str
;
2189 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
2192 inst
.instruction
|= reg
<< where
;
2196 /* In the few cases where we might be able to accept something else
2197 this error can be overridden. */
2198 inst
.error
= _("Co-processor register expected");
2200 /* Restore the start point. */
2206 fp_reg_required_here (str
, where
)
2211 char * start
= * str
;
2213 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
2216 inst
.instruction
|= reg
<< where
;
2220 /* In the few cases where we might be able to accept something else
2221 this error can be overridden. */
2222 inst
.error
= _("Floating point register expected");
2224 /* Restore the start point. */
2230 cp_address_offset (str
)
2235 skip_whitespace (* str
);
2237 if (! is_immediate_prefix (**str
))
2239 inst
.error
= _("immediate expression expected");
2245 if (my_get_expression (& inst
.reloc
.exp
, str
))
2248 if (inst
.reloc
.exp
.X_op
== O_constant
)
2250 offset
= inst
.reloc
.exp
.X_add_number
;
2254 inst
.error
= _("co-processor address must be word aligned");
2258 if (offset
> 1023 || offset
< -1023)
2260 inst
.error
= _("offset too large");
2265 inst
.instruction
|= INDEX_UP
;
2269 inst
.instruction
|= offset
>> 2;
2272 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2278 cp_address_required_here (str
)
2290 skip_whitespace (p
);
2292 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
2295 skip_whitespace (p
);
2301 if (skip_past_comma (& p
) == SUCCESS
)
2304 write_back
= WRITE_BACK
;
2308 inst
.error
= _("pc may not be used in post-increment");
2312 if (cp_address_offset (& p
) == FAIL
)
2316 pre_inc
= PRE_INDEX
| INDEX_UP
;
2320 /* '['Rn, #expr']'[!] */
2322 if (skip_past_comma (& p
) == FAIL
)
2324 inst
.error
= _("pre-indexed expression expected");
2328 pre_inc
= PRE_INDEX
;
2330 if (cp_address_offset (& p
) == FAIL
)
2333 skip_whitespace (p
);
2337 inst
.error
= _("missing ]");
2341 skip_whitespace (p
);
2347 inst
.error
= _("pc may not be used with write-back");
2352 write_back
= WRITE_BACK
;
2358 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2361 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2362 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2363 inst
.reloc
.pc_rel
= 1;
2364 inst
.instruction
|= (REG_PC
<< 16);
2365 pre_inc
= PRE_INDEX
;
2368 inst
.instruction
|= write_back
| pre_inc
;
2376 unsigned long flags
;
2378 /* Do nothing really. */
2379 inst
.instruction
|= flags
; /* This is pointless. */
2387 unsigned long flags
;
2391 /* Only one syntax. */
2392 skip_whitespace (str
);
2394 if (reg_required_here (&str
, 12) == FAIL
)
2396 inst
.error
= BAD_ARGS
;
2400 if (skip_past_comma (&str
) == FAIL
)
2402 inst
.error
= _("comma expected after register name");
2406 skip_whitespace (str
);
2408 if ( strcmp (str
, "CPSR") == 0
2409 || strcmp (str
, "SPSR") == 0
2410 /* Lower case versions for backwards compatability. */
2411 || strcmp (str
, "cpsr") == 0
2412 || strcmp (str
, "spsr") == 0)
2415 /* This is for backwards compatability with older toolchains. */
2416 else if ( strcmp (str
, "cpsr_all") == 0
2417 || strcmp (str
, "spsr_all") == 0)
2421 inst
.error
= _("{C|S}PSR expected");
2425 if (* str
== 's' || * str
== 'S')
2426 inst
.instruction
|= SPSR_BIT
;
2429 inst
.instruction
|= flags
;
2433 /* Two possible forms:
2434 "{C|S}PSR_<field>, Rm",
2435 "{C|S}PSR_f, #expression". */
2440 unsigned long flags
;
2442 skip_whitespace (str
);
2444 if (psr_required_here (& str
) == FAIL
)
2447 if (skip_past_comma (& str
) == FAIL
)
2449 inst
.error
= _("comma missing after psr flags");
2453 skip_whitespace (str
);
2455 if (reg_required_here (& str
, 0) != FAIL
)
2458 inst
.instruction
|= flags
;
2463 if (! is_immediate_prefix (* str
))
2466 _("only a register or immediate value can follow a psr flag");
2473 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2476 _("only a register or immediate value can follow a psr flag");
2480 #if 0 /* The first edition of the ARM architecture manual stated that
2481 writing anything other than the flags with an immediate operation
2482 had UNPREDICTABLE effects. This constraint was removed in the
2483 second edition of the specification. */
2484 if ((cpu_variant
& ARM_EXT_V5
) != ARM_EXT_V5
2485 && inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2487 inst
.error
= _("immediate value cannot be used to set this field");
2492 flags
|= INST_IMMEDIATE
;
2494 if (inst
.reloc
.exp
.X_add_symbol
)
2496 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2497 inst
.reloc
.pc_rel
= 0;
2501 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2503 if (value
== (unsigned) FAIL
)
2505 inst
.error
= _("Invalid constant");
2509 inst
.instruction
|= value
;
2513 inst
.instruction
|= flags
;
2517 /* Long Multiply Parser
2518 UMULL RdLo, RdHi, Rm, Rs
2519 SMULL RdLo, RdHi, Rm, Rs
2520 UMLAL RdLo, RdHi, Rm, Rs
2521 SMLAL RdLo, RdHi, Rm, Rs. */
2524 do_mull (str
, flags
)
2526 unsigned long flags
;
2528 int rdlo
, rdhi
, rm
, rs
;
2530 /* Only one format "rdlo, rdhi, rm, rs". */
2531 skip_whitespace (str
);
2533 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2535 inst
.error
= BAD_ARGS
;
2539 if (skip_past_comma (&str
) == FAIL
2540 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2542 inst
.error
= BAD_ARGS
;
2546 if (skip_past_comma (&str
) == FAIL
2547 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2549 inst
.error
= BAD_ARGS
;
2553 /* rdhi, rdlo and rm must all be different. */
2554 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2555 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2557 if (skip_past_comma (&str
) == FAIL
2558 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2560 inst
.error
= BAD_ARGS
;
2564 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2566 inst
.error
= BAD_PC
;
2570 inst
.instruction
|= flags
;
2578 unsigned long flags
;
2582 /* Only one format "rd, rm, rs". */
2583 skip_whitespace (str
);
2585 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2587 inst
.error
= BAD_ARGS
;
2593 inst
.error
= BAD_PC
;
2597 if (skip_past_comma (&str
) == FAIL
2598 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2600 inst
.error
= BAD_ARGS
;
2606 inst
.error
= BAD_PC
;
2611 as_tsktsk (_("rd and rm should be different in mul"));
2613 if (skip_past_comma (&str
) == FAIL
2614 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2616 inst
.error
= BAD_ARGS
;
2622 inst
.error
= BAD_PC
;
2626 inst
.instruction
|= flags
;
2634 unsigned long flags
;
2638 /* Only one format "rd, rm, rs, rn". */
2639 skip_whitespace (str
);
2641 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2643 inst
.error
= BAD_ARGS
;
2649 inst
.error
= BAD_PC
;
2653 if (skip_past_comma (&str
) == FAIL
2654 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2656 inst
.error
= BAD_ARGS
;
2662 inst
.error
= BAD_PC
;
2667 as_tsktsk (_("rd and rm should be different in mla"));
2669 if (skip_past_comma (&str
) == FAIL
2670 || (rd
= reg_required_here (&str
, 8)) == FAIL
2671 || skip_past_comma (&str
) == FAIL
2672 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2674 inst
.error
= BAD_ARGS
;
2678 if (rd
== REG_PC
|| rm
== REG_PC
)
2680 inst
.error
= BAD_PC
;
2684 inst
.instruction
|= flags
;
2689 /* Expects *str -> the characters "acc0", possibly with leading blanks.
2690 Advances *str to the next non-alphanumeric.
2691 Returns 0, or else FAIL (in which case sets inst.error).
2693 (In a future XScale, there may be accumulators other than zero.
2694 At that time this routine and its callers can be upgraded to suit.) */
2697 accum0_required_here (str
)
2700 static char buff
[128]; /* Note the address is taken. Hence, static. */
2703 int result
= 0; /* The accum number. */
2705 skip_whitespace (p
);
2707 *str
= p
; /* Advance caller's string pointer too. */
2712 *--p
= 0; /* Aap nul into input buffer at non-alnum. */
2714 if (! ( streq (*str
, "acc0") || streq (*str
, "ACC0")))
2716 sprintf (buff
, _("acc0 expected, not '%.100s'"), *str
);
2721 *p
= c
; /* Unzap. */
2722 *str
= p
; /* Caller's string pointer to after match. */
2726 /* Expects **str -> after a comma. May be leading blanks.
2727 Advances *str, recognizing a load mode, and setting inst.instruction.
2728 Returns rn, or else FAIL (in which case may set inst.error
2729 and not advance str)
2731 Note: doesn't know Rd, so no err checks that require such knowledge. */
2734 ld_mode_required_here (string
)
2737 char * str
= * string
;
2741 skip_whitespace (str
);
2747 skip_whitespace (str
);
2749 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
2752 skip_whitespace (str
);
2758 if (skip_past_comma (& str
) == SUCCESS
)
2760 /* [Rn],... (post inc) */
2761 if (ldst_extend (& str
, 1) == FAIL
)
2766 skip_whitespace (str
);
2771 inst
.instruction
|= WRITE_BACK
;
2774 inst
.instruction
|= INDEX_UP
| HWOFFSET_IMM
;
2780 if (skip_past_comma (& str
) == FAIL
)
2782 inst
.error
= _("pre-indexed expression expected");
2788 if (ldst_extend (& str
, 1) == FAIL
)
2791 skip_whitespace (str
);
2793 if (* str
++ != ']')
2795 inst
.error
= _("missing ]");
2799 skip_whitespace (str
);
2804 inst
.instruction
|= WRITE_BACK
;
2808 else if (* str
== '=') /* ldr's "r,=label" syntax */
2809 /* We should never reach here, because <text> = <expression> is
2810 caught gas/read.c read_a_source_file() as a .set operation. */
2812 else /* PC +- 8 bit immediate offset. */
2814 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2817 inst
.instruction
|= HWOFFSET_IMM
; /* The I bit. */
2818 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2819 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2820 inst
.reloc
.pc_rel
= 1;
2821 inst
.instruction
|= (REG_PC
<< 16);
2827 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
2833 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
2834 SMLAxy{cond} Rd,Rm,Rs,Rn
2835 SMLAWy{cond} Rd,Rm,Rs,Rn
2836 Error if any register is R15. */
2839 do_smla (str
, flags
)
2841 unsigned long flags
;
2845 skip_whitespace (str
);
2847 if ((rd
= reg_required_here (& str
, 16)) == FAIL
2848 || skip_past_comma (& str
) == FAIL
2849 || (rm
= reg_required_here (& str
, 0)) == FAIL
2850 || skip_past_comma (& str
) == FAIL
2851 || (rs
= reg_required_here (& str
, 8)) == FAIL
2852 || skip_past_comma (& str
) == FAIL
2853 || (rn
= reg_required_here (& str
, 12)) == FAIL
)
2854 inst
.error
= BAD_ARGS
;
2856 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
|| rn
== REG_PC
)
2857 inst
.error
= BAD_PC
;
2860 inst
.error
= BAD_FLAGS
;
2866 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
2867 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
2868 Error if any register is R15.
2869 Warning if Rdlo == Rdhi. */
2872 do_smlal (str
, flags
)
2874 unsigned long flags
;
2876 int rdlo
, rdhi
, rm
, rs
;
2878 skip_whitespace (str
);
2880 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
2881 || skip_past_comma (& str
) == FAIL
2882 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
2883 || skip_past_comma (& str
) == FAIL
2884 || (rm
= reg_required_here (& str
, 0)) == FAIL
2885 || skip_past_comma (& str
) == FAIL
2886 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
2888 inst
.error
= BAD_ARGS
;
2892 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
2894 inst
.error
= BAD_PC
;
2899 as_tsktsk (_("rdhi and rdlo must be different"));
2902 inst
.error
= BAD_FLAGS
;
2907 /* ARM V5E (El Segundo) signed-multiply (argument parse)
2908 SMULxy{cond} Rd,Rm,Rs
2909 Error if any register is R15. */
2912 do_smul (str
, flags
)
2914 unsigned long flags
;
2918 skip_whitespace (str
);
2920 if ((rd
= reg_required_here (& str
, 16)) == FAIL
2921 || skip_past_comma (& str
) == FAIL
2922 || (rm
= reg_required_here (& str
, 0)) == FAIL
2923 || skip_past_comma (& str
) == FAIL
2924 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
2925 inst
.error
= BAD_ARGS
;
2927 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
2928 inst
.error
= BAD_PC
;
2931 inst
.error
= BAD_FLAGS
;
2937 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
2938 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
2939 Error if any register is R15. */
2942 do_qadd (str
, flags
)
2944 unsigned long flags
;
2948 skip_whitespace (str
);
2950 if ((rd
= reg_required_here (& str
, 12)) == FAIL
2951 || skip_past_comma (& str
) == FAIL
2952 || (rm
= reg_required_here (& str
, 0)) == FAIL
2953 || skip_past_comma (& str
) == FAIL
2954 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
2955 inst
.error
= BAD_ARGS
;
2957 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
2958 inst
.error
= BAD_PC
;
2961 inst
.error
= BAD_FLAGS
;
2967 /* ARM V5E (el Segundo)
2968 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2969 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2971 These are equivalent to the XScale instructions MAR and MRA,
2972 respectively, when coproc == 0, opcode == 0, and CRm == 0.
2974 Result unpredicatable if Rd or Rn is R15. */
2977 do_co_reg2c (str
, flags
)
2979 unsigned long flags
;
2983 skip_whitespace (str
);
2985 if (co_proc_number (& str
) == FAIL
)
2988 inst
.error
= BAD_ARGS
;
2992 if (skip_past_comma (& str
) == FAIL
2993 || cp_opc_expr (& str
, 4, 4) == FAIL
)
2996 inst
.error
= BAD_ARGS
;
3000 if (skip_past_comma (& str
) == FAIL
3001 || (rd
= reg_required_here (& str
, 12)) == FAIL
)
3004 inst
.error
= BAD_ARGS
;
3008 if (skip_past_comma (& str
) == FAIL
3009 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
3012 inst
.error
= BAD_ARGS
;
3016 /* Unpredictable result if rd or rn is R15. */
3017 if (rd
== REG_PC
|| rn
== REG_PC
)
3019 (_("Warning: Instruction unpredictable when using r15"));
3021 if (skip_past_comma (& str
) == FAIL
3022 || cp_reg_required_here (& str
, 0) == FAIL
)
3025 inst
.error
= BAD_ARGS
;
3030 inst
.error
= BAD_COND
;
3035 /* ARM V5 count-leading-zeroes instruction (argument parse)
3036 CLZ{<cond>} <Rd>, <Rm>
3037 Condition defaults to COND_ALWAYS.
3038 Error if Rd or Rm are R15. */
3043 unsigned long flags
;
3053 skip_whitespace (str
);
3055 if (((rd
= reg_required_here (& str
, 12)) == FAIL
)
3056 || (skip_past_comma (& str
) == FAIL
)
3057 || ((rm
= reg_required_here (& str
, 0)) == FAIL
))
3058 inst
.error
= BAD_ARGS
;
3060 else if (rd
== REG_PC
|| rm
== REG_PC
)
3061 inst
.error
= BAD_PC
;
3067 /* ARM V5 (argument parse)
3068 LDC2{L} <coproc>, <CRd>, <addressing mode>
3069 STC2{L} <coproc>, <CRd>, <addressing mode>
3070 Instruction is not conditional, and has 0xf in the codition field.
3071 Otherwise, it's the same as LDC/STC. */
3074 do_lstc2 (str
, flags
)
3076 unsigned long flags
;
3079 inst
.error
= BAD_COND
;
3081 skip_whitespace (str
);
3083 if (co_proc_number (& str
) == FAIL
)
3086 inst
.error
= BAD_ARGS
;
3088 else if (skip_past_comma (& str
) == FAIL
3089 || cp_reg_required_here (& str
, 12) == FAIL
)
3092 inst
.error
= BAD_ARGS
;
3094 else if (skip_past_comma (& str
) == FAIL
3095 || cp_address_required_here (& str
) == FAIL
)
3098 inst
.error
= BAD_ARGS
;
3104 /* ARM V5 (argument parse)
3105 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3106 Instruction is not conditional, and has 0xf in the condition field.
3107 Otherwise, it's the same as CDP. */
3110 do_cdp2 (str
, flags
)
3112 unsigned long flags
;
3114 skip_whitespace (str
);
3116 if (co_proc_number (& str
) == FAIL
)
3119 inst
.error
= BAD_ARGS
;
3123 if (skip_past_comma (& str
) == FAIL
3124 || cp_opc_expr (& str
, 20,4) == FAIL
)
3127 inst
.error
= BAD_ARGS
;
3131 if (skip_past_comma (& str
) == FAIL
3132 || cp_reg_required_here (& str
, 12) == FAIL
)
3135 inst
.error
= BAD_ARGS
;
3139 if (skip_past_comma (& str
) == FAIL
3140 || cp_reg_required_here (& str
, 16) == FAIL
)
3143 inst
.error
= BAD_ARGS
;
3147 if (skip_past_comma (& str
) == FAIL
3148 || cp_reg_required_here (& str
, 0) == FAIL
)
3151 inst
.error
= BAD_ARGS
;
3155 if (skip_past_comma (& str
) == SUCCESS
)
3157 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3160 inst
.error
= BAD_ARGS
;
3166 inst
.error
= BAD_FLAGS
;
3171 /* ARM V5 (argument parse)
3172 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3173 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3174 Instruction is not conditional, and has 0xf in the condition field.
3175 Otherwise, it's the same as MCR/MRC. */
3178 do_co_reg2 (str
, flags
)
3180 unsigned long flags
;
3182 skip_whitespace (str
);
3184 if (co_proc_number (& str
) == FAIL
)
3187 inst
.error
= BAD_ARGS
;
3191 if (skip_past_comma (& str
) == FAIL
3192 || cp_opc_expr (& str
, 21, 3) == FAIL
)
3195 inst
.error
= BAD_ARGS
;
3199 if (skip_past_comma (& str
) == FAIL
3200 || reg_required_here (& str
, 12) == FAIL
)
3203 inst
.error
= BAD_ARGS
;
3207 if (skip_past_comma (& str
) == FAIL
3208 || cp_reg_required_here (& str
, 16) == FAIL
)
3211 inst
.error
= BAD_ARGS
;
3215 if (skip_past_comma (& str
) == FAIL
3216 || cp_reg_required_here (& str
, 0) == FAIL
)
3219 inst
.error
= BAD_ARGS
;
3223 if (skip_past_comma (& str
) == SUCCESS
)
3225 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3228 inst
.error
= BAD_ARGS
;
3234 inst
.error
= BAD_COND
;
3239 /* THUMB V5 breakpoint instruction (argument parse)
3247 unsigned long number
;
3249 skip_whitespace (str
);
3251 /* Allow optional leading '#'. */
3252 if (is_immediate_prefix (*str
))
3255 memset (& expr
, '\0', sizeof (expr
));
3256 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3258 inst
.error
= _("bad or missing expression");
3262 number
= expr
.X_add_number
;
3264 /* Check it fits an 8 bit unsigned. */
3265 if (number
!= (number
& 0xff))
3267 inst
.error
= _("immediate value out of range");
3271 inst
.instruction
|= number
;
3276 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3277 Expects inst.instruction is set for BLX(1).
3278 Note: this is cloned from do_branch, and the reloc changed to be a
3279 new one that can cope with setting one extra bit (the H bit). */
3282 do_branch25 (str
, flags
)
3284 unsigned long flags ATTRIBUTE_UNUSED
;
3286 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3293 /* ScottB: February 5, 1998 */
3294 /* Check to see of PLT32 reloc required for the instruction. */
3296 /* arm_parse_reloc() works on input_line_pointer.
3297 We actually want to parse the operands to the branch instruction
3298 passed in 'str'. Save the input pointer and restore it later. */
3299 save_in
= input_line_pointer
;
3300 input_line_pointer
= str
;
3302 if (inst
.reloc
.exp
.X_op
== O_symbol
3304 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3306 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3307 inst
.reloc
.pc_rel
= 0;
3308 /* Modify str to point to after parsed operands, otherwise
3309 end_of_line() will complain about the (PLT) left in str. */
3310 str
= input_line_pointer
;
3314 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3315 inst
.reloc
.pc_rel
= 1;
3318 input_line_pointer
= save_in
;
3321 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3322 inst
.reloc
.pc_rel
= 1;
3323 #endif /* OBJ_ELF */
3328 /* ARM V5 branch-link-exchange instruction (argument parse)
3329 BLX <target_addr> ie BLX(1)
3330 BLX{<condition>} <Rm> ie BLX(2)
3331 Unfortunately, there are two different opcodes for this mnemonic.
3332 So, the insns[].value is not used, and the code here zaps values
3333 into inst.instruction.
3334 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
3339 unsigned long flags
;
3350 skip_whitespace (mystr
);
3351 rm
= reg_required_here (& mystr
, 0);
3353 /* The above may set inst.error. Ignore his opinion. */
3358 /* Arg is a register.
3359 Use the condition code our caller put in inst.instruction.
3360 Pass ourselves off as a BX with a funny opcode. */
3361 inst
.instruction
|= 0x012fff30;
3366 /* This must be is BLX <target address>, no condition allowed. */
3367 if (inst
.instruction
!= COND_ALWAYS
)
3369 inst
.error
= BAD_COND
;
3373 inst
.instruction
= 0xfafffffe;
3375 /* Process like a B/BL, but with a different reloc.
3376 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
3377 do_branch25 (str
, flags
);
3381 /* ARM V5 Thumb BLX (argument parse)
3382 BLX <target_addr> which is BLX(1)
3383 BLX <Rm> which is BLX(2)
3384 Unfortunately, there are two different opcodes for this mnemonic.
3385 So, the tinsns[].value is not used, and the code here zaps values
3386 into inst.instruction. */
3395 skip_whitespace (mystr
);
3396 inst
.instruction
= 0x4780;
3398 /* Note that this call is to the ARM register recognizer. BLX(2)
3399 uses the ARM register space, not the Thumb one, so a call to
3400 thumb_reg() would be wrong. */
3401 rm
= reg_required_here (& mystr
, 3);
3406 /* It's BLX(2). The .instruction was zapped with rm & is final. */
3411 /* No ARM register. This must be BLX(1). Change the .instruction. */
3412 inst
.instruction
= 0xf7ffeffe;
3415 if (my_get_expression (& inst
.reloc
.exp
, & mystr
))
3418 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BLX
;
3419 inst
.reloc
.pc_rel
= 1;
3422 end_of_line (mystr
);
3425 /* ARM V5 breakpoint instruction (argument parse)
3426 BKPT <16 bit unsigned immediate>
3427 Instruction is not conditional.
3428 The bit pattern given in insns[] has the COND_ALWAYS condition,
3429 and it is an error if the caller tried to override that.
3430 Note "flags" is nonzero if a flag was supplied (which is an error). */
3433 do_bkpt (str
, flags
)
3435 unsigned long flags
;
3438 unsigned long number
;
3440 skip_whitespace (str
);
3442 /* Allow optional leading '#'. */
3443 if (is_immediate_prefix (* str
))
3446 memset (& expr
, '\0', sizeof (expr
));
3448 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3450 inst
.error
= _("bad or missing expression");
3454 number
= expr
.X_add_number
;
3456 /* Check it fits a 16 bit unsigned. */
3457 if (number
!= (number
& 0xffff))
3459 inst
.error
= _("immediate value out of range");
3463 /* Top 12 of 16 bits to bits 19:8. */
3464 inst
.instruction
|= (number
& 0xfff0) << 4;
3466 /* Bottom 4 of 16 bits to bits 3:0. */
3467 inst
.instruction
|= number
& 0xf;
3472 inst
.error
= BAD_FLAGS
;
3475 /* Xscale multiply-accumulate (argument parse)
3478 MIAxycc acc0,Rm,Rs. */
3483 unsigned long flags
;
3491 else if (accum0_required_here (& str
) == FAIL
)
3492 inst
.error
= ERR_NO_ACCUM
;
3494 else if (skip_past_comma (& str
) == FAIL
3495 || (rm
= reg_required_here (& str
, 0)) == FAIL
)
3496 inst
.error
= BAD_ARGS
;
3498 else if (skip_past_comma (& str
) == FAIL
3499 || (rs
= reg_required_here (& str
, 12)) == FAIL
)
3500 inst
.error
= BAD_ARGS
;
3502 /* inst.instruction has now been zapped with both rm and rs. */
3503 else if (rm
== REG_PC
|| rs
== REG_PC
)
3504 inst
.error
= BAD_PC
; /* Undefined result if rm or rs is R15. */
3510 /* Xscale move-accumulator-register (argument parse)
3512 MARcc acc0,RdLo,RdHi. */
3517 unsigned long flags
;
3524 else if (accum0_required_here (& str
) == FAIL
)
3525 inst
.error
= ERR_NO_ACCUM
;
3527 else if (skip_past_comma (& str
) == FAIL
3528 || (rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3529 inst
.error
= BAD_ARGS
;
3531 else if (skip_past_comma (& str
) == FAIL
3532 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3533 inst
.error
= BAD_ARGS
;
3535 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3536 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3537 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3543 /* Xscale move-register-accumulator (argument parse)
3545 MRAcc RdLo,RdHi,acc0. */
3550 unsigned long flags
;
3561 skip_whitespace (str
);
3563 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3564 inst
.error
= BAD_ARGS
;
3566 else if (skip_past_comma (& str
) == FAIL
3567 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3568 inst
.error
= BAD_ARGS
;
3570 else if (skip_past_comma (& str
) == FAIL
3571 || accum0_required_here (& str
) == FAIL
)
3572 inst
.error
= ERR_NO_ACCUM
;
3574 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3575 else if (rdlo
== rdhi
)
3576 inst
.error
= BAD_ARGS
; /* Undefined result if 2 writes to same reg. */
3578 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3579 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3584 /* Xscale: Preload-Cache
3588 Syntactically, like LDR with B=1, W=0, L=1. */
3593 unsigned long flags
;
3603 skip_whitespace (str
);
3607 inst
.error
= _("'[' expected after PLD mnemonic");
3612 skip_whitespace (str
);
3614 if ((rd
= reg_required_here (& str
, 16)) == FAIL
)
3617 skip_whitespace (str
);
3623 skip_whitespace (str
);
3625 if (skip_past_comma (& str
) == SUCCESS
)
3627 if (ldst_extend (& str
, 0) == FAIL
)
3630 else if (* str
== '!') /* [Rn]! */
3632 inst
.error
= _("writeback used in preload instruction");
3636 inst
.instruction
|= INDEX_UP
| PRE_INDEX
;
3638 else /* [Rn, ...] */
3640 if (skip_past_comma (& str
) == FAIL
)
3642 inst
.error
= _("pre-indexed expression expected");
3646 if (ldst_extend (& str
, 0) == FAIL
)
3649 skip_whitespace (str
);
3653 inst
.error
= _("missing ]");
3658 skip_whitespace (str
);
3660 if (* str
== '!') /* [Rn]! */
3662 inst
.error
= _("writeback used in preload instruction");
3666 inst
.instruction
|= PRE_INDEX
;
3672 /* Xscale load-consecutive (argument parse)
3679 do_ldrd (str
, flags
)
3681 unsigned long flags
;
3686 if (flags
!= DOUBLE_LOAD_FLAG
)
3688 /* Change instruction pattern to normal ldr/str. */
3689 if (inst
.instruction
& 0x20)
3690 inst
.instruction
= (inst
.instruction
& COND_MASK
) | 0x04000000; /* str */
3692 inst
.instruction
= (inst
.instruction
& COND_MASK
) | 0x04100000; /* ldr */
3694 /* Perform a normal load/store instruction parse. */
3695 do_ldst (str
, flags
);
3700 if ((cpu_variant
& ARM_EXT_XSCALE
) != ARM_EXT_XSCALE
)
3702 static char buff
[128];
3705 while (ISSPACE (*str
))
3709 /* Deny all knowledge. */
3710 sprintf (buff
, _("bad instruction '%.100s'"), str
);
3715 skip_whitespace (str
);
3717 if ((rd
= reg_required_here (& str
, 12)) == FAIL
)
3719 inst
.error
= BAD_ARGS
;
3723 if (skip_past_comma (& str
) == FAIL
3724 || (rn
= ld_mode_required_here (& str
)) == FAIL
)
3727 inst
.error
= BAD_ARGS
;
3731 /* inst.instruction has now been zapped with Rd and the addressing mode. */
3732 if (rd
& 1) /* Unpredictable result if Rd is odd. */
3734 inst
.error
= _("Destination register must be even");
3738 if (rd
== REG_LR
|| rd
== 12)
3740 inst
.error
= _("r12 or r14 not allowed here");
3744 if (((rd
== rn
) || (rd
+ 1 == rn
))
3746 ((inst
.instruction
& WRITE_BACK
)
3747 || (!(inst
.instruction
& PRE_INDEX
))))
3748 as_warn (_("pre/post-indexing used when modified address register is destination"));
3753 /* Returns the index into fp_values of a floating point number,
3754 or -1 if not in the table. */
3757 my_get_float_expression (str
)
3760 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
3766 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
3768 /* Look for a raw floating point number. */
3769 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
3770 && is_end_of_line
[(unsigned char) *save_in
])
3772 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
3774 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
3776 if (words
[j
] != fp_values
[i
][j
])
3780 if (j
== MAX_LITTLENUMS
)
3788 /* Try and parse a more complex expression, this will probably fail
3789 unless the code uses a floating point prefix (eg "0f"). */
3790 save_in
= input_line_pointer
;
3791 input_line_pointer
= *str
;
3792 if (expression (&exp
) == absolute_section
3793 && exp
.X_op
== O_big
3794 && exp
.X_add_number
< 0)
3796 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
3798 if (gen_to_words (words
, 5, (long) 15) == 0)
3800 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
3802 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
3804 if (words
[j
] != fp_values
[i
][j
])
3808 if (j
== MAX_LITTLENUMS
)
3810 *str
= input_line_pointer
;
3811 input_line_pointer
= save_in
;
3818 *str
= input_line_pointer
;
3819 input_line_pointer
= save_in
;
3823 /* Return true if anything in the expression is a bignum. */
3826 walk_no_bignums (sp
)
3829 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
3832 if (symbol_get_value_expression (sp
)->X_add_symbol
)
3834 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
3835 || (symbol_get_value_expression (sp
)->X_op_symbol
3836 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
3843 my_get_expression (ep
, str
)
3850 save_in
= input_line_pointer
;
3851 input_line_pointer
= *str
;
3852 seg
= expression (ep
);
3855 if (seg
!= absolute_section
3856 && seg
!= text_section
3857 && seg
!= data_section
3858 && seg
!= bss_section
3859 && seg
!= undefined_section
)
3861 inst
.error
= _("bad_segment");
3862 *str
= input_line_pointer
;
3863 input_line_pointer
= save_in
;
3868 /* Get rid of any bignums now, so that we don't generate an error for which
3869 we can't establish a line number later on. Big numbers are never valid
3870 in instructions, which is where this routine is always called. */
3871 if (ep
->X_op
== O_big
3872 || (ep
->X_add_symbol
3873 && (walk_no_bignums (ep
->X_add_symbol
)
3875 && walk_no_bignums (ep
->X_op_symbol
)))))
3877 inst
.error
= _("Invalid constant");
3878 *str
= input_line_pointer
;
3879 input_line_pointer
= save_in
;
3883 *str
= input_line_pointer
;
3884 input_line_pointer
= save_in
;
3888 /* UNRESTRICT should be one if <shift> <register> is permitted for this
3892 decode_shift (str
, unrestrict
)
3896 const struct asm_shift_name
* shift
;
3900 skip_whitespace (* str
);
3902 for (p
= * str
; ISALPHA (* p
); p
++)
3907 inst
.error
= _("Shift expression expected");
3913 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
3918 inst
.error
= _("Shift expression expected");
3922 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
3924 if (shift
->properties
->index
== SHIFT_RRX
)
3927 inst
.instruction
|= shift
->properties
->bit_field
;
3931 skip_whitespace (p
);
3933 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
3935 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
3939 else if (! is_immediate_prefix (* p
))
3941 inst
.error
= (unrestrict
3942 ? _("shift requires register or #expression")
3943 : _("shift requires #expression"));
3951 if (my_get_expression (& inst
.reloc
.exp
, & p
))
3954 /* Validate some simple #expressions. */
3955 if (inst
.reloc
.exp
.X_op
== O_constant
)
3957 unsigned num
= inst
.reloc
.exp
.X_add_number
;
3959 /* Reject operations greater than 32. */
3961 /* Reject a shift of 0 unless the mode allows it. */
3962 || (num
== 0 && shift
->properties
->allows_0
== 0)
3963 /* Reject a shift of 32 unless the mode allows it. */
3964 || (num
== 32 && shift
->properties
->allows_32
== 0)
3967 /* As a special case we allow a shift of zero for
3968 modes that do not support it to be recoded as an
3969 logical shift left of zero (ie nothing). We warn
3970 about this though. */
3973 as_warn (_("Shift of 0 ignored."));
3974 shift
= & shift_names
[0];
3975 assert (shift
->properties
->index
== SHIFT_LSL
);
3979 inst
.error
= _("Invalid immediate shift");
3984 /* Shifts of 32 are encoded as 0, for those shifts that
3989 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
3993 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
3994 inst
.reloc
.pc_rel
= 0;
3995 inst
.instruction
|= shift
->properties
->bit_field
;
4002 /* Do those data_ops which can take a negative immediate constant
4003 by altering the instuction. A bit of a hack really.
4007 by inverting the second operand, and
4010 by negating the second operand. */
4013 negate_data_op (instruction
, value
)
4014 unsigned long * instruction
;
4015 unsigned long value
;
4018 unsigned long negated
, inverted
;
4020 negated
= validate_immediate (-value
);
4021 inverted
= validate_immediate (~value
);
4023 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
4026 /* First negates. */
4027 case OPCODE_SUB
: /* ADD <-> SUB */
4028 new_inst
= OPCODE_ADD
;
4033 new_inst
= OPCODE_SUB
;
4037 case OPCODE_CMP
: /* CMP <-> CMN */
4038 new_inst
= OPCODE_CMN
;
4043 new_inst
= OPCODE_CMP
;
4047 /* Now Inverted ops. */
4048 case OPCODE_MOV
: /* MOV <-> MVN */
4049 new_inst
= OPCODE_MVN
;
4054 new_inst
= OPCODE_MOV
;
4058 case OPCODE_AND
: /* AND <-> BIC */
4059 new_inst
= OPCODE_BIC
;
4064 new_inst
= OPCODE_AND
;
4068 case OPCODE_ADC
: /* ADC <-> SBC */
4069 new_inst
= OPCODE_SBC
;
4074 new_inst
= OPCODE_ADC
;
4078 /* We cannot do anything. */
4083 if (value
== (unsigned) FAIL
)
4086 *instruction
&= OPCODE_MASK
;
4087 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
4098 skip_whitespace (* str
);
4100 if (reg_required_here (str
, 0) != FAIL
)
4102 if (skip_past_comma (str
) == SUCCESS
)
4103 /* Shift operation on register. */
4104 return decode_shift (str
, NO_SHIFT_RESTRICT
);
4110 /* Immediate expression. */
4111 if (is_immediate_prefix (**str
))
4116 if (my_get_expression (&inst
.reloc
.exp
, str
))
4119 if (inst
.reloc
.exp
.X_add_symbol
)
4121 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4122 inst
.reloc
.pc_rel
= 0;
4126 if (skip_past_comma (str
) == SUCCESS
)
4128 /* #x, y -- ie explicit rotation by Y. */
4129 if (my_get_expression (&expr
, str
))
4132 if (expr
.X_op
!= O_constant
)
4134 inst
.error
= _("Constant expression expected");
4138 /* Rotate must be a multiple of 2. */
4139 if (((unsigned) expr
.X_add_number
) > 30
4140 || (expr
.X_add_number
& 1) != 0
4141 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
4143 inst
.error
= _("Invalid constant");
4146 inst
.instruction
|= INST_IMMEDIATE
;
4147 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4148 inst
.instruction
|= expr
.X_add_number
<< 7;
4152 /* Implicit rotation, select a suitable one. */
4153 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4157 /* Can't be done. Perhaps the code reads something like
4158 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
4159 if ((value
= negate_data_op (&inst
.instruction
,
4160 inst
.reloc
.exp
.X_add_number
))
4163 inst
.error
= _("Invalid constant");
4168 inst
.instruction
|= value
;
4171 inst
.instruction
|= INST_IMMEDIATE
;
4176 inst
.error
= _("Register or shift expression expected");
4185 skip_whitespace (* str
);
4187 if (fp_reg_required_here (str
, 0) != FAIL
)
4191 /* Immediate expression. */
4192 if (*((*str
)++) == '#')
4198 skip_whitespace (* str
);
4200 /* First try and match exact strings, this is to guarantee
4201 that some formats will work even for cross assembly. */
4203 for (i
= 0; fp_const
[i
]; i
++)
4205 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
4209 *str
+= strlen (fp_const
[i
]);
4210 if (is_end_of_line
[(unsigned char) **str
])
4212 inst
.instruction
|= i
+ 8;
4219 /* Just because we didn't get a match doesn't mean that the
4220 constant isn't valid, just that it is in a format that we
4221 don't automatically recognize. Try parsing it with
4222 the standard expression routines. */
4223 if ((i
= my_get_float_expression (str
)) >= 0)
4225 inst
.instruction
|= i
+ 8;
4229 inst
.error
= _("Invalid floating point immediate expression");
4233 _("Floating point register or immediate expression expected");
4239 do_arit (str
, flags
)
4241 unsigned long flags
;
4243 skip_whitespace (str
);
4245 if (reg_required_here (&str
, 12) == FAIL
4246 || skip_past_comma (&str
) == FAIL
4247 || reg_required_here (&str
, 16) == FAIL
4248 || skip_past_comma (&str
) == FAIL
4249 || data_op2 (&str
) == FAIL
)
4252 inst
.error
= BAD_ARGS
;
4256 inst
.instruction
|= flags
;
4264 unsigned long flags
;
4266 skip_whitespace (str
);
4268 if (reg_required_here (&str
, 12) == FAIL
4269 || skip_past_comma (&str
) == FAIL
4270 || my_get_expression (&inst
.reloc
.exp
, &str
))
4273 inst
.error
= BAD_ARGS
;
4277 if (flags
& 0x00400000)
4279 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4280 into a relative address of the form:
4281 add rd, pc, #low(label-.-8)"
4282 add rd, rd, #high(label-.-8)" */
4283 /* Frag hacking will turn this into a sub instruction if the offset turns
4284 out to be negative. */
4285 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
4286 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
4287 inst
.reloc
.pc_rel
= 1;
4288 inst
.instruction
|= flags
& ~0x00400000;
4289 inst
.size
= INSN_SIZE
* 2;
4293 /* This is a pseudo-op of the form "adr rd, label" to be converted
4294 into a relative address of the form "add rd, pc, #label-.-8". */
4295 /* Frag hacking will turn this into a sub instruction if the offset turns
4296 out to be negative. */
4297 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4298 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
4299 inst
.reloc
.pc_rel
= 1;
4300 inst
.instruction
|= flags
;
4309 unsigned long flags
;
4311 skip_whitespace (str
);
4313 if (reg_required_here (&str
, 16) == FAIL
)
4316 inst
.error
= BAD_ARGS
;
4320 if (skip_past_comma (&str
) == FAIL
4321 || data_op2 (&str
) == FAIL
)
4324 inst
.error
= BAD_ARGS
;
4328 inst
.instruction
|= flags
;
4329 if ((flags
& 0x0000f000) == 0)
4330 inst
.instruction
|= CONDS_BIT
;
4339 unsigned long flags
;
4341 skip_whitespace (str
);
4343 if (reg_required_here (&str
, 12) == FAIL
)
4346 inst
.error
= BAD_ARGS
;
4350 if (skip_past_comma (&str
) == FAIL
4351 || data_op2 (&str
) == FAIL
)
4354 inst
.error
= BAD_ARGS
;
4358 inst
.instruction
|= flags
;
4364 ldst_extend (str
, hwse
)
4375 if (my_get_expression (& inst
.reloc
.exp
, str
))
4378 if (inst
.reloc
.exp
.X_op
== O_constant
)
4380 int value
= inst
.reloc
.exp
.X_add_number
;
4382 if ((hwse
&& (value
< -255 || value
> 255))
4383 || (value
< -4095 || value
> 4095))
4385 inst
.error
= _("address offset too large");
4395 /* Halfword and signextension instructions have the
4396 immediate value split across bits 11..8 and bits 3..0. */
4398 inst
.instruction
|= (add
| HWOFFSET_IMM
4399 | ((value
>> 4) << 8) | (value
& 0xF));
4401 inst
.instruction
|= add
| value
;
4407 inst
.instruction
|= HWOFFSET_IMM
;
4408 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
4411 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4412 inst
.reloc
.pc_rel
= 0;
4425 if (reg_required_here (str
, 0) == FAIL
)
4429 inst
.instruction
|= add
;
4432 inst
.instruction
|= add
| OFFSET_REG
;
4433 if (skip_past_comma (str
) == SUCCESS
)
4434 return decode_shift (str
, SHIFT_RESTRICT
);
4442 do_ldst (str
, flags
)
4444 unsigned long flags
;
4451 /* This is not ideal, but it is the simplest way of dealing with the
4452 ARM7T halfword instructions (since they use a different
4453 encoding, but the same mnemonic): */
4454 halfword
= (flags
& 0x80000000) != 0;
4457 /* This is actually a load/store of a halfword, or a
4458 signed-extension load. */
4459 if ((cpu_variant
& ARM_EXT_V4
) == 0)
4462 = _("Processor does not support halfwords or signed bytes");
4466 inst
.instruction
= ((inst
.instruction
& COND_MASK
)
4467 | (flags
& ~COND_MASK
));
4472 skip_whitespace (str
);
4474 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
4477 inst
.error
= BAD_ARGS
;
4481 if (skip_past_comma (& str
) == FAIL
)
4483 inst
.error
= _("Address expected");
4493 skip_whitespace (str
);
4495 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4498 /* Conflicts can occur on stores as well as loads. */
4499 conflict_reg
= (conflict_reg
== reg
);
4501 skip_whitespace (str
);
4507 if (skip_past_comma (&str
) == SUCCESS
)
4509 /* [Rn],... (post inc) */
4510 if (ldst_extend (&str
, halfword
) == FAIL
)
4514 if (flags
& TRANS_BIT
)
4515 as_warn (_("Rn and Rd must be different in %s"),
4516 ((inst
.instruction
& LOAD_BIT
)
4517 ? "LDRT" : "STRT"));
4519 as_warn (_("%s register same as write-back base"),
4520 ((inst
.instruction
& LOAD_BIT
)
4521 ? _("destination") : _("source")));
4528 inst
.instruction
|= HWOFFSET_IMM
;
4530 skip_whitespace (str
);
4535 as_warn (_("%s register same as write-back base"),
4536 ((inst
.instruction
& LOAD_BIT
)
4537 ? _("destination") : _("source")));
4539 inst
.instruction
|= WRITE_BACK
;
4543 if (flags
& TRANS_BIT
)
4546 as_warn (_("Rn and Rd must be different in %s"),
4547 ((inst
.instruction
& LOAD_BIT
)
4548 ? "LDRT" : "STRT"));
4557 if (skip_past_comma (&str
) == FAIL
)
4559 inst
.error
= _("pre-indexed expression expected");
4564 if (ldst_extend (&str
, halfword
) == FAIL
)
4567 skip_whitespace (str
);
4571 inst
.error
= _("missing ]");
4575 skip_whitespace (str
);
4580 as_warn (_("%s register same as write-back base"),
4581 ((inst
.instruction
& LOAD_BIT
)
4582 ? _("destination") : _("source")));
4584 inst
.instruction
|= WRITE_BACK
;
4588 else if (*str
== '=')
4590 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4593 skip_whitespace (str
);
4595 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4598 if (inst
.reloc
.exp
.X_op
!= O_constant
4599 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4601 inst
.error
= _("Constant expression expected");
4605 if (inst
.reloc
.exp
.X_op
== O_constant
)
4607 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4611 /* This can be done with a mov instruction. */
4612 inst
.instruction
&= LITERAL_MASK
;
4613 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
4614 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
4619 value
= validate_immediate (~ inst
.reloc
.exp
.X_add_number
);
4623 /* This can be done with a mvn instruction. */
4624 inst
.instruction
&= LITERAL_MASK
;
4625 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MVN
<< DATA_OP_SHIFT
);
4626 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
4632 /* Insert into literal pool. */
4633 if (add_to_lit_pool () == FAIL
)
4636 inst
.error
= _("literal pool insertion failed");
4640 /* Change the instruction exp to point to the pool. */
4643 inst
.instruction
|= HWOFFSET_IMM
;
4644 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
4647 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
4649 inst
.reloc
.pc_rel
= 1;
4650 inst
.instruction
|= (REG_PC
<< 16);
4655 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4660 inst
.instruction
|= HWOFFSET_IMM
;
4661 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
4664 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4666 /* PC rel adjust. */
4667 inst
.reloc
.exp
.X_add_number
-= 8;
4669 inst
.reloc
.pc_rel
= 1;
4670 inst
.instruction
|= (REG_PC
<< 16);
4674 if (pre_inc
&& (flags
& TRANS_BIT
))
4675 inst
.error
= _("Pre-increment instruction with translate");
4677 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
4686 char * str
= * strp
;
4690 /* We come back here if we get ranges concatenated by '+' or '|'. */
4705 skip_whitespace (str
);
4707 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
4716 inst
.error
= _("Bad range in register list");
4720 for (i
= cur_reg
+ 1; i
< reg
; i
++)
4722 if (range
& (1 << i
))
4724 (_("Warning: Duplicated register (r%d) in register list"),
4732 if (range
& (1 << reg
))
4733 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
4735 else if (reg
<= cur_reg
)
4736 as_tsktsk (_("Warning: Register range not in ascending order"));
4741 while (skip_past_comma (&str
) != FAIL
4742 || (in_range
= 1, *str
++ == '-'));
4744 skip_whitespace (str
);
4748 inst
.error
= _("Missing `}'");
4756 if (my_get_expression (&expr
, &str
))
4759 if (expr
.X_op
== O_constant
)
4761 if (expr
.X_add_number
4762 != (expr
.X_add_number
& 0x0000ffff))
4764 inst
.error
= _("invalid register mask");
4768 if ((range
& expr
.X_add_number
) != 0)
4770 int regno
= range
& expr
.X_add_number
;
4773 regno
= (1 << regno
) - 1;
4775 (_("Warning: Duplicated register (r%d) in register list"),
4779 range
|= expr
.X_add_number
;
4783 if (inst
.reloc
.type
!= 0)
4785 inst
.error
= _("expression too complex");
4789 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
4790 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
4791 inst
.reloc
.pc_rel
= 0;
4795 skip_whitespace (str
);
4797 if (*str
== '|' || *str
== '+')
4803 while (another_range
);
4810 do_ldmstm (str
, flags
)
4812 unsigned long flags
;
4817 skip_whitespace (str
);
4819 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
4822 if (base_reg
== REG_PC
)
4824 inst
.error
= _("r15 not allowed as base register");
4828 skip_whitespace (str
);
4832 flags
|= WRITE_BACK
;
4836 if (skip_past_comma (&str
) == FAIL
4837 || (range
= reg_list (&str
)) == FAIL
)
4840 inst
.error
= BAD_ARGS
;
4847 flags
|= LDM_TYPE_2_OR_3
;
4850 inst
.instruction
|= flags
| range
;
4858 unsigned long flags
;
4860 skip_whitespace (str
);
4862 /* Allow optional leading '#'. */
4863 if (is_immediate_prefix (*str
))
4866 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4869 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4870 inst
.reloc
.pc_rel
= 0;
4871 inst
.instruction
|= flags
;
4879 do_swap (str
, flags
)
4881 unsigned long flags
;
4885 skip_whitespace (str
);
4887 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
4892 inst
.error
= _("r15 not allowed in swap");
4896 if (skip_past_comma (&str
) == FAIL
4897 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
4900 inst
.error
= BAD_ARGS
;
4906 inst
.error
= _("r15 not allowed in swap");
4910 if (skip_past_comma (&str
) == FAIL
4913 inst
.error
= BAD_ARGS
;
4917 skip_whitespace (str
);
4919 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4924 inst
.error
= BAD_PC
;
4928 skip_whitespace (str
);
4932 inst
.error
= _("missing ]");
4936 inst
.instruction
|= flags
;
4942 do_branch (str
, flags
)
4944 unsigned long flags ATTRIBUTE_UNUSED
;
4946 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4953 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
4954 required for the instruction. */
4956 /* arm_parse_reloc () works on input_line_pointer.
4957 We actually want to parse the operands to the branch instruction
4958 passed in 'str'. Save the input pointer and restore it later. */
4959 save_in
= input_line_pointer
;
4960 input_line_pointer
= str
;
4961 if (inst
.reloc
.exp
.X_op
== O_symbol
4963 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
4965 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
4966 inst
.reloc
.pc_rel
= 0;
4967 /* Modify str to point to after parsed operands, otherwise
4968 end_of_line() will complain about the (PLT) left in str. */
4969 str
= input_line_pointer
;
4973 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
4974 inst
.reloc
.pc_rel
= 1;
4976 input_line_pointer
= save_in
;
4979 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
4980 inst
.reloc
.pc_rel
= 1;
4981 #endif /* OBJ_ELF */
4990 unsigned long flags ATTRIBUTE_UNUSED
;
4994 skip_whitespace (str
);
4996 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
4998 inst
.error
= BAD_ARGS
;
5002 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
5004 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
5012 unsigned long flags ATTRIBUTE_UNUSED
;
5014 /* Co-processor data operation.
5015 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
5016 skip_whitespace (str
);
5018 if (co_proc_number (&str
) == FAIL
)
5021 inst
.error
= BAD_ARGS
;
5025 if (skip_past_comma (&str
) == FAIL
5026 || cp_opc_expr (&str
, 20,4) == FAIL
)
5029 inst
.error
= BAD_ARGS
;
5033 if (skip_past_comma (&str
) == FAIL
5034 || cp_reg_required_here (&str
, 12) == FAIL
)
5037 inst
.error
= BAD_ARGS
;
5041 if (skip_past_comma (&str
) == FAIL
5042 || cp_reg_required_here (&str
, 16) == FAIL
)
5045 inst
.error
= BAD_ARGS
;
5049 if (skip_past_comma (&str
) == FAIL
5050 || cp_reg_required_here (&str
, 0) == FAIL
)
5053 inst
.error
= BAD_ARGS
;
5057 if (skip_past_comma (&str
) == SUCCESS
)
5059 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5062 inst
.error
= BAD_ARGS
;
5072 do_lstc (str
, flags
)
5074 unsigned long flags
;
5076 /* Co-processor register load/store.
5077 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
5079 skip_whitespace (str
);
5081 if (co_proc_number (&str
) == FAIL
)
5084 inst
.error
= BAD_ARGS
;
5088 if (skip_past_comma (&str
) == FAIL
5089 || cp_reg_required_here (&str
, 12) == FAIL
)
5092 inst
.error
= BAD_ARGS
;
5096 if (skip_past_comma (&str
) == FAIL
5097 || cp_address_required_here (&str
) == FAIL
)
5100 inst
.error
= BAD_ARGS
;
5104 inst
.instruction
|= flags
;
5110 do_co_reg (str
, flags
)
5112 unsigned long flags
;
5114 /* Co-processor register transfer.
5115 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
5117 skip_whitespace (str
);
5119 if (co_proc_number (&str
) == FAIL
)
5122 inst
.error
= BAD_ARGS
;
5126 if (skip_past_comma (&str
) == FAIL
5127 || cp_opc_expr (&str
, 21, 3) == FAIL
)
5130 inst
.error
= BAD_ARGS
;
5134 if (skip_past_comma (&str
) == FAIL
5135 || reg_required_here (&str
, 12) == FAIL
)
5138 inst
.error
= BAD_ARGS
;
5142 if (skip_past_comma (&str
) == FAIL
5143 || cp_reg_required_here (&str
, 16) == FAIL
)
5146 inst
.error
= BAD_ARGS
;
5150 if (skip_past_comma (&str
) == FAIL
5151 || cp_reg_required_here (&str
, 0) == FAIL
)
5154 inst
.error
= BAD_ARGS
;
5158 if (skip_past_comma (&str
) == SUCCESS
)
5160 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
5163 inst
.error
= BAD_ARGS
;
5169 inst
.error
= BAD_COND
;
5177 do_fp_ctrl (str
, flags
)
5179 unsigned long flags ATTRIBUTE_UNUSED
;
5181 /* FP control registers.
5182 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
5184 skip_whitespace (str
);
5186 if (reg_required_here (&str
, 12) == FAIL
)
5189 inst
.error
= BAD_ARGS
;
5198 do_fp_ldst (str
, flags
)
5200 unsigned long flags ATTRIBUTE_UNUSED
;
5202 skip_whitespace (str
);
5204 switch (inst
.suffix
)
5209 inst
.instruction
|= CP_T_X
;
5212 inst
.instruction
|= CP_T_Y
;
5215 inst
.instruction
|= CP_T_X
| CP_T_Y
;
5221 if (fp_reg_required_here (&str
, 12) == FAIL
)
5224 inst
.error
= BAD_ARGS
;
5228 if (skip_past_comma (&str
) == FAIL
5229 || cp_address_required_here (&str
) == FAIL
)
5232 inst
.error
= BAD_ARGS
;
5240 do_fp_ldmstm (str
, flags
)
5242 unsigned long flags
;
5246 skip_whitespace (str
);
5248 if (fp_reg_required_here (&str
, 12) == FAIL
)
5251 inst
.error
= BAD_ARGS
;
5255 /* Get Number of registers to transfer. */
5256 if (skip_past_comma (&str
) == FAIL
5257 || my_get_expression (&inst
.reloc
.exp
, &str
))
5260 inst
.error
= _("constant expression expected");
5264 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5266 inst
.error
= _("Constant value required for number of registers");
5270 num_regs
= inst
.reloc
.exp
.X_add_number
;
5272 if (num_regs
< 1 || num_regs
> 4)
5274 inst
.error
= _("number of registers must be in the range [1:4]");
5281 inst
.instruction
|= CP_T_X
;
5284 inst
.instruction
|= CP_T_Y
;
5287 inst
.instruction
|= CP_T_Y
| CP_T_X
;
5301 /* The instruction specified "ea" or "fd", so we can only accept
5302 [Rn]{!}. The instruction does not really support stacking or
5303 unstacking, so we have to emulate these by setting appropriate
5304 bits and offsets. */
5305 if (skip_past_comma (&str
) == FAIL
5309 inst
.error
= BAD_ARGS
;
5314 skip_whitespace (str
);
5316 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5319 skip_whitespace (str
);
5323 inst
.error
= BAD_ARGS
;
5335 _("R15 not allowed as base register with write-back");
5342 if (flags
& CP_T_Pre
)
5344 /* Pre-decrement. */
5345 offset
= 3 * num_regs
;
5351 /* Post-increment. */
5355 offset
= 3 * num_regs
;
5359 /* No write-back, so convert this into a standard pre-increment
5360 instruction -- aesthetically more pleasing. */
5361 flags
= CP_T_Pre
| CP_T_UD
;
5366 inst
.instruction
|= flags
| offset
;
5368 else if (skip_past_comma (&str
) == FAIL
5369 || cp_address_required_here (&str
) == FAIL
)
5372 inst
.error
= BAD_ARGS
;
5380 do_fp_dyadic (str
, flags
)
5382 unsigned long flags
;
5384 skip_whitespace (str
);
5386 switch (inst
.suffix
)
5391 inst
.instruction
|= 0x00000080;
5394 inst
.instruction
|= 0x00080000;
5400 if (fp_reg_required_here (&str
, 12) == FAIL
)
5403 inst
.error
= BAD_ARGS
;
5407 if (skip_past_comma (&str
) == FAIL
5408 || fp_reg_required_here (&str
, 16) == FAIL
)
5411 inst
.error
= BAD_ARGS
;
5415 if (skip_past_comma (&str
) == FAIL
5416 || fp_op2 (&str
) == FAIL
)
5419 inst
.error
= BAD_ARGS
;
5423 inst
.instruction
|= flags
;
5429 do_fp_monadic (str
, flags
)
5431 unsigned long flags
;
5433 skip_whitespace (str
);
5435 switch (inst
.suffix
)
5440 inst
.instruction
|= 0x00000080;
5443 inst
.instruction
|= 0x00080000;
5449 if (fp_reg_required_here (&str
, 12) == FAIL
)
5452 inst
.error
= BAD_ARGS
;
5456 if (skip_past_comma (&str
) == FAIL
5457 || fp_op2 (&str
) == FAIL
)
5460 inst
.error
= BAD_ARGS
;
5464 inst
.instruction
|= flags
;
5470 do_fp_cmp (str
, flags
)
5472 unsigned long flags
;
5474 skip_whitespace (str
);
5476 if (fp_reg_required_here (&str
, 16) == FAIL
)
5479 inst
.error
= BAD_ARGS
;
5483 if (skip_past_comma (&str
) == FAIL
5484 || fp_op2 (&str
) == FAIL
)
5487 inst
.error
= BAD_ARGS
;
5491 inst
.instruction
|= flags
;
5497 do_fp_from_reg (str
, flags
)
5499 unsigned long flags
;
5501 skip_whitespace (str
);
5503 switch (inst
.suffix
)
5508 inst
.instruction
|= 0x00000080;
5511 inst
.instruction
|= 0x00080000;
5517 if (fp_reg_required_here (&str
, 16) == FAIL
)
5520 inst
.error
= BAD_ARGS
;
5524 if (skip_past_comma (&str
) == FAIL
5525 || reg_required_here (&str
, 12) == FAIL
)
5528 inst
.error
= BAD_ARGS
;
5532 inst
.instruction
|= flags
;
5538 do_fp_to_reg (str
, flags
)
5540 unsigned long flags
;
5542 skip_whitespace (str
);
5544 if (reg_required_here (&str
, 12) == FAIL
)
5547 if (skip_past_comma (&str
) == FAIL
5548 || fp_reg_required_here (&str
, 0) == FAIL
)
5551 inst
.error
= BAD_ARGS
;
5555 inst
.instruction
|= flags
;
5560 /* Thumb specific routines. */
5562 /* Parse and validate that a register is of the right form, this saves
5563 repeated checking of this information in many similar cases.
5564 Unlike the 32-bit case we do not insert the register into the opcode
5565 here, since the position is often unknown until the full instruction
5569 thumb_reg (strp
, hi_lo
)
5575 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
5583 inst
.error
= _("lo register required");
5591 inst
.error
= _("hi register required");
5603 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
5607 thumb_add_sub (str
, subtract
)
5611 int Rd
, Rs
, Rn
= FAIL
;
5613 skip_whitespace (str
);
5615 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
5616 || skip_past_comma (&str
) == FAIL
)
5619 inst
.error
= BAD_ARGS
;
5623 if (is_immediate_prefix (*str
))
5627 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5632 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5635 if (skip_past_comma (&str
) == FAIL
)
5637 /* Two operand format, shuffle the registers
5638 and pretend there are 3. */
5642 else if (is_immediate_prefix (*str
))
5645 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5648 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5652 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5653 for the latter case, EXPR contains the immediate that was found. */
5656 /* All register format. */
5657 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
5661 inst
.error
= _("dest and source1 must be the same register");
5665 /* Can't do this for SUB. */
5668 inst
.error
= _("subtract valid only on lo regs");
5672 inst
.instruction
= (T_OPCODE_ADD_HI
5673 | (Rd
> 7 ? THUMB_H1
: 0)
5674 | (Rn
> 7 ? THUMB_H2
: 0));
5675 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
5679 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
5680 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
5685 /* Immediate expression, now things start to get nasty. */
5687 /* First deal with HI regs, only very restricted cases allowed:
5688 Adjusting SP, and using PC or SP to get an address. */
5689 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
5690 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
5692 inst
.error
= _("invalid Hi register with immediate");
5696 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5698 /* Value isn't known yet, all we can do is store all the fragments
5699 we know about in the instruction and let the reloc hacking
5701 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
5702 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
5706 int offset
= inst
.reloc
.exp
.X_add_number
;
5716 /* Quick check, in case offset is MIN_INT. */
5719 inst
.error
= _("immediate value out of range");
5728 if (offset
& ~0x1fc)
5730 inst
.error
= _("invalid immediate value for stack adjust");
5733 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5734 inst
.instruction
|= offset
>> 2;
5736 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
5739 || (offset
& ~0x3fc))
5741 inst
.error
= _("invalid immediate for address calculation");
5744 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
5746 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
5752 inst
.error
= _("immediate value out of range");
5755 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5756 inst
.instruction
|= (Rd
<< 8) | offset
;
5762 inst
.error
= _("immediate value out of range");
5765 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5766 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
5775 thumb_shift (str
, shift
)
5779 int Rd
, Rs
, Rn
= FAIL
;
5781 skip_whitespace (str
);
5783 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5784 || skip_past_comma (&str
) == FAIL
)
5787 inst
.error
= BAD_ARGS
;
5791 if (is_immediate_prefix (*str
))
5793 /* Two operand immediate format, set Rs to Rd. */
5796 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5801 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5804 if (skip_past_comma (&str
) == FAIL
)
5806 /* Two operand format, shuffle the registers
5807 and pretend there are 3. */
5811 else if (is_immediate_prefix (*str
))
5814 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5817 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5821 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5822 for the latter case, EXPR contains the immediate that was found. */
5828 inst
.error
= _("source1 and dest must be same register");
5834 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
5835 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
5836 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
5839 inst
.instruction
|= Rd
| (Rn
<< 3);
5845 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
5846 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
5847 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
5850 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5852 /* Value isn't known yet, create a dummy reloc and let reloc
5853 hacking fix it up. */
5854 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
5858 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
5860 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
5862 inst
.error
= _("Invalid immediate for shift");
5866 /* Shifts of zero are handled by converting to LSL. */
5867 if (shift_value
== 0)
5868 inst
.instruction
= T_OPCODE_LSL_I
;
5870 /* Shifts of 32 are encoded as a shift of zero. */
5871 if (shift_value
== 32)
5874 inst
.instruction
|= shift_value
<< 6;
5877 inst
.instruction
|= Rd
| (Rs
<< 3);
5884 thumb_mov_compare (str
, move
)
5890 skip_whitespace (str
);
5892 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
5893 || skip_past_comma (&str
) == FAIL
)
5896 inst
.error
= BAD_ARGS
;
5900 if (is_immediate_prefix (*str
))
5903 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5906 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5911 if (Rs
< 8 && Rd
< 8)
5913 if (move
== THUMB_MOVE
)
5914 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
5915 since a MOV instruction produces unpredictable results. */
5916 inst
.instruction
= T_OPCODE_ADD_I3
;
5918 inst
.instruction
= T_OPCODE_CMP_LR
;
5919 inst
.instruction
|= Rd
| (Rs
<< 3);
5923 if (move
== THUMB_MOVE
)
5924 inst
.instruction
= T_OPCODE_MOV_HR
;
5926 inst
.instruction
= T_OPCODE_CMP_HR
;
5929 inst
.instruction
|= THUMB_H1
;
5932 inst
.instruction
|= THUMB_H2
;
5934 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
5941 inst
.error
= _("only lo regs allowed with immediate");
5945 if (move
== THUMB_MOVE
)
5946 inst
.instruction
= T_OPCODE_MOV_I8
;
5948 inst
.instruction
= T_OPCODE_CMP_I8
;
5950 inst
.instruction
|= Rd
<< 8;
5952 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5953 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
5956 unsigned value
= inst
.reloc
.exp
.X_add_number
;
5960 inst
.error
= _("invalid immediate");
5964 inst
.instruction
|= value
;
5972 thumb_load_store (str
, load_store
, size
)
5977 int Rd
, Rb
, Ro
= FAIL
;
5979 skip_whitespace (str
);
5981 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5982 || skip_past_comma (&str
) == FAIL
)
5985 inst
.error
= BAD_ARGS
;
5992 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5995 if (skip_past_comma (&str
) != FAIL
)
5997 if (is_immediate_prefix (*str
))
6000 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6003 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6008 inst
.reloc
.exp
.X_op
= O_constant
;
6009 inst
.reloc
.exp
.X_add_number
= 0;
6014 inst
.error
= _("expected ']'");
6019 else if (*str
== '=')
6021 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
6024 skip_whitespace (str
);
6026 if (my_get_expression (& inst
.reloc
.exp
, & str
))
6031 if ( inst
.reloc
.exp
.X_op
!= O_constant
6032 && inst
.reloc
.exp
.X_op
!= O_symbol
)
6034 inst
.error
= "Constant expression expected";
6038 if (inst
.reloc
.exp
.X_op
== O_constant
6039 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
6041 /* This can be done with a mov instruction. */
6043 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
6044 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
6048 /* Insert into literal pool. */
6049 if (add_to_lit_pool () == FAIL
)
6052 inst
.error
= "literal pool insertion failed";
6056 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6057 inst
.reloc
.pc_rel
= 1;
6058 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
6059 /* Adjust ARM pipeline offset to Thumb. */
6060 inst
.reloc
.exp
.X_add_number
+= 4;
6066 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6069 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
6070 inst
.reloc
.pc_rel
= 1;
6071 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
6072 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6077 if (Rb
== REG_PC
|| Rb
== REG_SP
)
6079 if (size
!= THUMB_WORD
)
6081 inst
.error
= _("byte or halfword not valid for base register");
6084 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
6086 inst
.error
= _("R15 based store not allowed");
6089 else if (Ro
!= FAIL
)
6091 inst
.error
= _("Invalid base register for register offset");
6096 inst
.instruction
= T_OPCODE_LDR_PC
;
6097 else if (load_store
== THUMB_LOAD
)
6098 inst
.instruction
= T_OPCODE_LDR_SP
;
6100 inst
.instruction
= T_OPCODE_STR_SP
;
6102 inst
.instruction
|= Rd
<< 8;
6103 if (inst
.reloc
.exp
.X_op
== O_constant
)
6105 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
6107 if (offset
& ~0x3fc)
6109 inst
.error
= _("invalid offset");
6113 inst
.instruction
|= offset
>> 2;
6116 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6120 inst
.error
= _("invalid base register in load/store");
6123 else if (Ro
== FAIL
)
6125 /* Immediate offset. */
6126 if (size
== THUMB_WORD
)
6127 inst
.instruction
= (load_store
== THUMB_LOAD
6128 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
6129 else if (size
== THUMB_HALFWORD
)
6130 inst
.instruction
= (load_store
== THUMB_LOAD
6131 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
6133 inst
.instruction
= (load_store
== THUMB_LOAD
6134 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
6136 inst
.instruction
|= Rd
| (Rb
<< 3);
6138 if (inst
.reloc
.exp
.X_op
== O_constant
)
6140 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
6142 if (offset
& ~(0x1f << size
))
6144 inst
.error
= _("Invalid offset");
6147 inst
.instruction
|= (offset
>> size
) << 6;
6150 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
6154 /* Register offset. */
6155 if (size
== THUMB_WORD
)
6156 inst
.instruction
= (load_store
== THUMB_LOAD
6157 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
6158 else if (size
== THUMB_HALFWORD
)
6159 inst
.instruction
= (load_store
== THUMB_LOAD
6160 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
6162 inst
.instruction
= (load_store
== THUMB_LOAD
6163 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
6165 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
6171 /* Given a register and a register type, return 1 if
6172 the register is of the given type, else return 0. */
6175 cirrus_valid_reg (reg
, regtype
)
6177 enum cirrus_regtype regtype
;
6181 case CIRRUS_REGTYPE_ANY
:
6184 case CIRRUS_REGTYPE_MVF
:
6185 return cirrus_mvf_register (reg
);
6187 case CIRRUS_REGTYPE_MVFX
:
6188 return cirrus_mvfx_register (reg
);
6190 case CIRRUS_REGTYPE_MVD
:
6191 return cirrus_mvd_register (reg
);
6193 case CIRRUS_REGTYPE_MVDX
:
6194 return cirrus_mvdx_register (reg
);
6196 case CIRRUS_REGTYPE_MVAX
:
6197 return cirrus_mvax_register (reg
);
6199 case CIRRUS_REGTYPE_DSPSC
:
6200 return ARM_EXT_MAVERICKsc_register (reg
);
6206 /* A register must be given at this point.
6208 If the register is a Cirrus register, convert it's reg# appropriately.
6210 Shift is the place to put it in inst.instruction.
6212 regtype is type register type expected, and is:
6218 CIRRUS_REGTYPE_DSPSC
6220 Restores input start point on err.
6221 Returns the reg#, or FAIL. */
6224 cirrus_reg_required_here (str
, shift
, regtype
)
6227 enum cirrus_regtype regtype
;
6229 static char buff
[135]; /* XXX */
6231 char * start
= * str
;
6233 if ((reg
= arm_reg_parse (str
)) != FAIL
6234 && (int_register (reg
)
6235 || cirrus_register (reg
)))
6239 /* Calculate actual register # for opcode. */
6240 if (cirrus_register (reg
)
6241 && !ARM_EXT_MAVERICKsc_register (reg
)) /* Leave this one as is. */
6245 else if (reg
>= 110)
6255 if (!cirrus_valid_reg (orig_reg
, regtype
))
6257 sprintf (buff
, _("invalid register type at '%.100s'"), start
);
6263 inst
.instruction
|= reg
<< shift
;
6268 /* Restore the start point, we may have got a reg of the wrong class. */
6271 /* In the few cases where we might be able to accept something else
6272 this error can be overridden. */
6273 sprintf (buff
, _("Cirrus register expected, not '%.100s'"), start
);
6279 /* Cirrus Instructions. */
6281 /* Wrapper functions. */
6284 do_c_binops_1 (str
, flags
)
6286 unsigned long flags
;
6288 do_c_binops (str
, flags
, CIRRUS_MODE1
);
6292 do_c_binops_2 (str
, flags
)
6294 unsigned long flags
;
6296 do_c_binops (str
, flags
, CIRRUS_MODE2
);
6300 do_c_binops_3 (str
, flags
)
6302 unsigned long flags
;
6304 do_c_binops (str
, flags
, CIRRUS_MODE3
);
6308 do_c_triple_4 (str
, flags
)
6310 unsigned long flags
;
6312 do_c_triple (str
, flags
, CIRRUS_MODE4
);
6316 do_c_triple_5 (str
, flags
)
6318 unsigned long flags
;
6320 do_c_triple (str
, flags
, CIRRUS_MODE5
);
6324 do_c_quad_6 (str
, flags
)
6326 unsigned long flags
;
6328 do_c_quad (str
, flags
, CIRRUS_MODE6
);
6332 do_c_dspsc_1 (str
, flags
)
6334 unsigned long flags
;
6336 do_c_dspsc (str
, flags
, CIRRUS_MODE1
);
6340 do_c_dspsc_2 (str
, flags
)
6342 unsigned long flags
;
6344 do_c_dspsc (str
, flags
, CIRRUS_MODE2
);
6348 do_c_shift_1 (str
, flags
)
6350 unsigned long flags
;
6352 do_c_shift (str
, flags
, CIRRUS_MODE1
);
6356 do_c_shift_2 (str
, flags
)
6358 unsigned long flags
;
6360 do_c_shift (str
, flags
, CIRRUS_MODE2
);
6364 do_c_ldst_1 (str
, flags
)
6366 unsigned long flags
;
6368 do_c_ldst (str
, flags
, CIRRUS_MODE1
);
6372 do_c_ldst_2 (str
, flags
)
6374 unsigned long flags
;
6376 do_c_ldst (str
, flags
, CIRRUS_MODE2
);
6380 do_c_ldst_3 (str
, flags
)
6382 unsigned long flags
;
6384 do_c_ldst (str
, flags
, CIRRUS_MODE3
);
6388 do_c_ldst_4 (str
, flags
)
6390 unsigned long flags
;
6392 do_c_ldst (str
, flags
, CIRRUS_MODE4
);
6395 /* Isnsn like "foo X,Y". */
6398 do_c_binops (str
, flags
, mode
)
6400 unsigned long flags
;
6405 shift1
= mode
& 0xff;
6406 shift2
= (mode
>> 8) & 0xff;
6408 skip_whitespace (str
);
6410 if (cirrus_reg_required_here (&str
, shift1
, CIRRUS_REGTYPE_ANY
) == FAIL
6411 || skip_past_comma (&str
) == FAIL
6412 || cirrus_reg_required_here (&str
, shift2
, CIRRUS_REGTYPE_ANY
) == FAIL
)
6415 inst
.error
= BAD_ARGS
;
6420 inst
.instruction
|= flags
;
6424 /* Isnsn like "foo X,Y,Z". */
6427 do_c_triple (str
, flags
, mode
)
6429 unsigned long flags
;
6432 int shift1
, shift2
, shift3
;
6434 shift1
= mode
& 0xff;
6435 shift2
= (mode
>> 8) & 0xff;
6436 shift3
= (mode
>> 16) & 0xff;
6438 skip_whitespace (str
);
6440 if (cirrus_reg_required_here (&str
, shift1
, CIRRUS_REGTYPE_ANY
) == FAIL
6441 || skip_past_comma (&str
) == FAIL
6442 || cirrus_reg_required_here (&str
, shift2
, CIRRUS_REGTYPE_ANY
) == FAIL
6443 || skip_past_comma (&str
) == FAIL
6444 || cirrus_reg_required_here (&str
, shift3
, CIRRUS_REGTYPE_ANY
) == FAIL
)
6447 inst
.error
= BAD_ARGS
;
6452 inst
.instruction
|= flags
;
6456 /* Isnsn like "foo W,X,Y,Z".
6457 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
6460 do_c_quad (str
, flags
, mode
)
6462 unsigned long flags
;
6465 int shift1
, shift2
, shift3
, shift4
;
6466 enum cirrus_regtype rt
;
6468 rt
= (inst
.instruction
<< 4 == 0xe2006000
6469 || inst
.instruction
<< 4 == 0xe3006000) ? CIRRUS_REGTYPE_MVAX
6470 : CIRRUS_REGTYPE_MVFX
;
6472 shift1
= mode
& 0xff;
6473 shift2
= (mode
>> 8) & 0xff;
6474 shift3
= (mode
>> 16) & 0xff;
6475 shift4
= (mode
>> 24) & 0xff;
6477 skip_whitespace (str
);
6479 if (cirrus_reg_required_here (&str
, shift1
, CIRRUS_REGTYPE_MVAX
) == FAIL
6480 || skip_past_comma (&str
) == FAIL
6481 || cirrus_reg_required_here (&str
, shift2
, rt
) == FAIL
6482 || skip_past_comma (&str
) == FAIL
6483 || cirrus_reg_required_here (&str
, shift3
, CIRRUS_REGTYPE_MVFX
) == FAIL
6484 || skip_past_comma (&str
) == FAIL
6485 || cirrus_reg_required_here (&str
, shift4
, CIRRUS_REGTYPE_MVFX
) == FAIL
)
6488 inst
.error
= BAD_ARGS
;
6493 inst
.instruction
|= flags
;
6497 /* cfmvsc32<cond> DSPSC,MVFX[15:0].
6498 cfmv32sc<cond> MVFX[15:0],DSPSC. */
6501 do_c_dspsc (str
, flags
, mode
)
6503 unsigned long flags
;
6508 skip_whitespace (str
);
6512 if (mode
== CIRRUS_MODE1
)
6515 if (cirrus_reg_required_here (&str
, -1, CIRRUS_REGTYPE_DSPSC
) == FAIL
6516 || skip_past_comma (&str
) == FAIL
6517 || cirrus_reg_required_here (&str
, 16, CIRRUS_REGTYPE_MVFX
) == FAIL
)
6523 if (cirrus_reg_required_here (&str
, 0, CIRRUS_REGTYPE_MVFX
) == FAIL
6524 || skip_past_comma (&str
) == FAIL
6525 || cirrus_reg_required_here (&str
, -1, CIRRUS_REGTYPE_DSPSC
) == FAIL
)
6532 inst
.error
= BAD_ARGS
;
6536 inst
.instruction
|= flags
;
6543 /* Cirrus shift immediate instructions.
6544 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
6545 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
6548 do_c_shift (str
, flags
, mode
)
6550 unsigned long flags
;
6556 skip_whitespace (str
);
6560 if (cirrus_reg_required_here (&str
, 12,
6561 (mode
== CIRRUS_MODE1
)
6562 ? CIRRUS_REGTYPE_MVFX
6563 : CIRRUS_REGTYPE_MVDX
) == FAIL
6564 || skip_past_comma (&str
) == FAIL
6565 || cirrus_reg_required_here (&str
, 16,
6566 (mode
== CIRRUS_MODE1
)
6567 ? CIRRUS_REGTYPE_MVFX
6568 : CIRRUS_REGTYPE_MVDX
) == FAIL
6569 || skip_past_comma (&str
) == FAIL
)
6572 inst
.error
= BAD_ARGS
;
6576 /* Calculate the immediate operand.
6577 The operand is a 7bit signed number. */
6578 skip_whitespace (str
);
6583 if (!ISDIGIT (*str
) && *str
!= '-')
6585 inst
.error
= _("expecting immediate, 7bit operand");
6595 for (imm
= 0; *str
&& ISDIGIT (*str
); ++str
)
6596 imm
= imm
* 10 + *str
- '0';
6600 inst
.error
= _("immediate out of range");
6604 /* Make negative imm's into 7bit signed numbers. */
6611 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
6612 Bits 5-7 of the insn should have bits 4-6 of the immediate.
6613 Bit 4 should be 0. */
6614 imm
= (imm
& 0xf) | ((imm
& 0x70) << 1);
6616 inst
.instruction
|= imm
;
6617 inst
.instruction
|= flags
;
6625 cirrus_parse_offset (str
, negative
)
6634 skip_whitespace (p
);
6647 inst
.error
= _("offset expected");
6651 for (offset
= 0; *p
&& ISDIGIT (*p
); ++p
)
6652 offset
= offset
* 10 + *p
- '0';
6656 inst
.error
= _("offset out of range");
6662 return *negative
? -offset
: offset
;
6665 /* Cirrus load/store instructions.
6666 <insn><cond> CRd,[Rn,<offset>]{!}.
6667 <insn><cond> CRd,[Rn],<offset>. */
6670 do_c_ldst (str
, flags
, mode
)
6672 unsigned long flags
;
6675 int offset
, negative
;
6676 enum cirrus_regtype rt
;
6678 rt
= mode
== CIRRUS_MODE1
? CIRRUS_REGTYPE_MVF
6679 : mode
== CIRRUS_MODE2
? CIRRUS_REGTYPE_MVD
6680 : mode
== CIRRUS_MODE3
? CIRRUS_REGTYPE_MVFX
6681 : mode
== CIRRUS_MODE4
? CIRRUS_REGTYPE_MVDX
: CIRRUS_REGTYPE_MVF
;
6683 skip_whitespace (str
);
6685 if (cirrus_reg_required_here (& str
, 12, rt
) == FAIL
6686 || skip_past_comma (& str
) == FAIL
6688 || reg_required_here (& str
, 16) == FAIL
)
6691 if (skip_past_comma (& str
) == SUCCESS
)
6693 /* You are here: "<offset>]{!}". */
6694 inst
.instruction
|= PRE_INDEX
;
6696 offset
= cirrus_parse_offset (&str
, &negative
);
6703 inst
.error
= _("missing ]");
6709 inst
.instruction
|= WRITE_BACK
;
6715 /* You are here: "], <offset>". */
6718 inst
.error
= _("missing ]");
6722 if (skip_past_comma (&str
) == FAIL
6723 || (offset
= cirrus_parse_offset (&str
, &negative
), inst
.error
))
6726 inst
.instruction
|= CP_T_WB
; /* Post indexed, set bit W. */
6732 inst
.instruction
|= CP_T_UD
; /* Postive, so set bit U. */
6734 inst
.instruction
|= offset
>> 2;
6735 inst
.instruction
|= flags
;
6742 inst
.error
= BAD_ARGS
;
6755 /* Handle the Format 4 instructions that do not have equivalents in other
6756 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
6765 skip_whitespace (str
);
6767 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6768 || skip_past_comma (&str
) == FAIL
6769 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6771 inst
.error
= BAD_ARGS
;
6775 if (skip_past_comma (&str
) != FAIL
)
6777 /* Three operand format not allowed for TST, CMN, NEG and MVN.
6778 (It isn't allowed for CMP either, but that isn't handled by this
6780 if (inst
.instruction
== T_OPCODE_TST
6781 || inst
.instruction
== T_OPCODE_CMN
6782 || inst
.instruction
== T_OPCODE_NEG
6783 || inst
.instruction
== T_OPCODE_MVN
)
6785 inst
.error
= BAD_ARGS
;
6789 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6794 inst
.error
= _("dest and source1 must be the same register");
6800 if (inst
.instruction
== T_OPCODE_MUL
6802 as_tsktsk (_("Rs and Rd must be different in MUL"));
6804 inst
.instruction
|= Rd
| (Rs
<< 3);
6812 thumb_add_sub (str
, 0);
6819 thumb_shift (str
, THUMB_ASR
);
6826 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6828 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
6829 inst
.reloc
.pc_rel
= 1;
6837 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6839 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
6840 inst
.reloc
.pc_rel
= 1;
6844 /* Find the real, Thumb encoded start of a Thumb function. */
6847 find_real_start (symbolP
)
6851 const char * name
= S_GET_NAME (symbolP
);
6852 symbolS
* new_target
;
6854 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
6855 #define STUB_NAME ".real_start_of"
6860 /* Names that start with '.' are local labels, not function entry points.
6861 The compiler may generate BL instructions to these labels because it
6862 needs to perform a branch to a far away location. */
6866 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
6867 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
6869 new_target
= symbol_find (real_start
);
6871 if (new_target
== NULL
)
6873 as_warn ("Failed to find real start of function: %s\n", name
);
6874 new_target
= symbolP
;
6886 if (my_get_expression (& inst
.reloc
.exp
, & str
))
6889 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
6890 inst
.reloc
.pc_rel
= 1;
6893 /* If the destination of the branch is a defined symbol which does not have
6894 the THUMB_FUNC attribute, then we must be calling a function which has
6895 the (interfacearm) attribute. We look for the Thumb entry point to that
6896 function and change the branch to refer to that function instead. */
6897 if ( inst
.reloc
.exp
.X_op
== O_symbol
6898 && inst
.reloc
.exp
.X_add_symbol
!= NULL
6899 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
6900 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
6901 inst
.reloc
.exp
.X_add_symbol
=
6902 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
6911 skip_whitespace (str
);
6913 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6916 /* This sets THUMB_H2 from the top bit of reg. */
6917 inst
.instruction
|= reg
<< 3;
6919 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
6920 should cause the alignment to be checked once it is known. This is
6921 because BX PC only works if the instruction is word aligned. */
6930 thumb_mov_compare (str
, THUMB_COMPARE
);
6940 skip_whitespace (str
);
6942 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6946 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
6950 if (skip_past_comma (&str
) == FAIL
6951 || (range
= reg_list (&str
)) == FAIL
)
6954 inst
.error
= BAD_ARGS
;
6958 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6960 /* This really doesn't seem worth it. */
6961 inst
.reloc
.type
= BFD_RELOC_NONE
;
6962 inst
.error
= _("Expression too complex");
6968 inst
.error
= _("only lo-regs valid in load/store multiple");
6972 inst
.instruction
|= (Rb
<< 8) | range
;
6980 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
6987 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
6994 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
7003 skip_whitespace (str
);
7005 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7006 || skip_past_comma (&str
) == FAIL
7008 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7009 || skip_past_comma (&str
) == FAIL
7010 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
7014 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
7018 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
7026 thumb_shift (str
, THUMB_LSL
);
7033 thumb_shift (str
, THUMB_LSR
);
7040 thumb_mov_compare (str
, THUMB_MOVE
);
7049 skip_whitespace (str
);
7051 if ((range
= reg_list (&str
)) == FAIL
)
7054 inst
.error
= BAD_ARGS
;
7058 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
7060 /* This really doesn't seem worth it. */
7061 inst
.reloc
.type
= BFD_RELOC_NONE
;
7062 inst
.error
= _("Expression too complex");
7068 if ((inst
.instruction
== T_OPCODE_PUSH
7069 && (range
& ~0xff) == 1 << REG_LR
)
7070 || (inst
.instruction
== T_OPCODE_POP
7071 && (range
& ~0xff) == 1 << REG_PC
))
7073 inst
.instruction
|= THUMB_PP_PC_LR
;
7078 inst
.error
= _("invalid register list to push/pop instruction");
7083 inst
.instruction
|= range
;
7091 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
7098 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
7105 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
7112 thumb_add_sub (str
, 1);
7119 skip_whitespace (str
);
7121 if (my_get_expression (&inst
.reloc
.exp
, &str
))
7124 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
7135 /* This is a pseudo-op of the form "adr rd, label" to be converted
7136 into a relative address of the form "add rd, pc, #label-.-4". */
7137 skip_whitespace (str
);
7139 /* Store Rd in temporary location inside instruction. */
7140 if ((reg
= reg_required_here (&str
, 4)) == FAIL
7141 || (reg
> 7) /* For Thumb reg must be r0..r7. */
7142 || skip_past_comma (&str
) == FAIL
7143 || my_get_expression (&inst
.reloc
.exp
, &str
))
7146 inst
.error
= BAD_ARGS
;
7150 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
7151 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
7152 inst
.reloc
.pc_rel
= 1;
7153 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
7162 int len
= strlen (reg_table
[entry
].name
) + 2;
7163 char * buf
= (char *) xmalloc (len
);
7164 char * buf2
= (char *) xmalloc (len
);
7167 #ifdef REGISTER_PREFIX
7168 buf
[i
++] = REGISTER_PREFIX
;
7171 strcpy (buf
+ i
, reg_table
[entry
].name
);
7173 for (i
= 0; buf
[i
]; i
++)
7174 buf2
[i
] = TOUPPER (buf
[i
]);
7178 hash_insert (arm_reg_hsh
, buf
, (PTR
) & reg_table
[entry
]);
7179 hash_insert (arm_reg_hsh
, buf2
, (PTR
) & reg_table
[entry
]);
7183 insert_reg_alias (str
, regnum
)
7187 struct reg_entry
*new =
7188 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
7189 char *name
= xmalloc (strlen (str
) + 1);
7193 new->number
= regnum
;
7195 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
7199 set_constant_flonums ()
7203 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
7204 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
7214 if ( (arm_ops_hsh
= hash_new ()) == NULL
7215 || (arm_tops_hsh
= hash_new ()) == NULL
7216 || (arm_cond_hsh
= hash_new ()) == NULL
7217 || (arm_shift_hsh
= hash_new ()) == NULL
7218 || (arm_reg_hsh
= hash_new ()) == NULL
7219 || (arm_psr_hsh
= hash_new ()) == NULL
)
7220 as_fatal (_("Virtual memory exhausted"));
7222 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
7223 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
7224 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
7225 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
7226 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
7227 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
7228 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
7229 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
7230 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
7231 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
7233 for (i
= 0; reg_table
[i
].name
; i
++)
7236 set_constant_flonums ();
7238 #if defined OBJ_COFF || defined OBJ_ELF
7240 unsigned int flags
= 0;
7242 /* Set the flags in the private structure. */
7243 if (uses_apcs_26
) flags
|= F_APCS26
;
7244 if (support_interwork
) flags
|= F_INTERWORK
;
7245 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
7246 if (pic_code
) flags
|= F_PIC
;
7247 if ((cpu_variant
& FPU_ANY
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
7249 bfd_set_private_flags (stdoutput
, flags
);
7251 /* We have run out flags in the COFF header to encode the
7252 status of ATPCS support, so instead we create a dummy,
7253 empty, debug section called .arm.atpcs. */
7258 sec
= bfd_make_section (stdoutput
, ".arm.atpcs");
7262 bfd_set_section_flags
7263 (stdoutput
, sec
, SEC_READONLY
| SEC_DEBUGGING
/* | SEC_HAS_CONTENTS */);
7264 bfd_set_section_size (stdoutput
, sec
, 0);
7265 bfd_set_section_contents (stdoutput
, sec
, NULL
, 0, 0);
7271 /* Record the CPU type as well. */
7272 switch (cpu_variant
& ARM_CPU_MASK
)
7275 mach
= bfd_mach_arm_2
;
7278 case ARM_3
: /* Also ARM_250. */
7279 mach
= bfd_mach_arm_2a
;
7282 case ARM_6
: /* Also ARM_7. */
7283 mach
= bfd_mach_arm_3
;
7287 mach
= bfd_mach_arm_4
;
7292 /* Catch special cases. */
7293 if (cpu_variant
& ARM_EXT_XSCALE
)
7294 mach
= bfd_mach_arm_XScale
;
7295 else if (cpu_variant
& ARM_EXT_V5E
)
7296 mach
= bfd_mach_arm_5TE
;
7297 else if (cpu_variant
& ARM_EXT_V5
)
7299 if (cpu_variant
& ARM_EXT_V4T
)
7300 mach
= bfd_mach_arm_5T
;
7302 mach
= bfd_mach_arm_5
;
7304 else if (cpu_variant
& ARM_EXT_V4
)
7306 if (cpu_variant
& ARM_EXT_V4T
)
7307 mach
= bfd_mach_arm_4T
;
7309 mach
= bfd_mach_arm_4
;
7311 else if (cpu_variant
& ARM_EXT_V3M
)
7312 mach
= bfd_mach_arm_3M
;
7314 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
7317 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
7318 for use in the a.out file, and stores them in the array pointed to by buf.
7319 This knows about the endian-ness of the target machine and does
7320 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
7321 2 (short) and 4 (long) Floating numbers are put out as a series of
7322 LITTLENUMS (shorts, here at least). */
7325 md_number_to_chars (buf
, val
, n
)
7330 if (target_big_endian
)
7331 number_to_chars_bigendian (buf
, val
, n
);
7333 number_to_chars_littleendian (buf
, val
, n
);
7337 md_chars_to_number (buf
, n
)
7342 unsigned char * where
= (unsigned char *) buf
;
7344 if (target_big_endian
)
7349 result
|= (*where
++ & 255);
7357 result
|= (where
[n
] & 255);
7364 /* Turn a string in input_line_pointer into a floating point constant
7365 of type TYPE, and store the appropriate bytes in *LITP. The number
7366 of LITTLENUMS emitted is stored in *SIZEP. An error message is
7367 returned, or NULL on OK.
7369 Note that fp constants aren't represent in the normal way on the ARM.
7370 In big endian mode, things are as expected. However, in little endian
7371 mode fp constants are big-endian word-wise, and little-endian byte-wise
7372 within the words. For example, (double) 1.1 in big endian mode is
7373 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
7374 the byte sequence 99 99 f1 3f 9a 99 99 99.
7376 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
7379 md_atof (type
, litP
, sizeP
)
7385 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
7417 return _("Bad call to MD_ATOF()");
7420 t
= atof_ieee (input_line_pointer
, type
, words
);
7422 input_line_pointer
= t
;
7425 if (target_big_endian
)
7427 for (i
= 0; i
< prec
; i
++)
7429 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
7435 /* For a 4 byte float the order of elements in `words' is 1 0. For an
7436 8 byte float the order is 1 0 3 2. */
7437 for (i
= 0; i
< prec
; i
+= 2)
7439 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
7440 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
7448 /* The knowledge of the PC's pipeline offset is built into the insns
7452 md_pcrel_from (fixP
)
7456 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
7457 && fixP
->fx_subsy
== NULL
)
7460 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
7462 /* PC relative addressing on the Thumb is slightly odd
7463 as the bottom two bits of the PC are forced to zero
7464 for the calculation. */
7465 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
7469 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
7470 so we un-adjust here to compensate for the accomodation. */
7471 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
7473 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
7477 /* Round up a section size to the appropriate boundary. */
7480 md_section_align (segment
, size
)
7481 segT segment ATTRIBUTE_UNUSED
;
7487 /* Round all sects to multiple of 4. */
7488 return (size
+ 3) & ~3;
7492 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
7493 Otherwise we have no need to default values of symbols. */
7496 md_undefined_symbol (name
)
7497 char * name ATTRIBUTE_UNUSED
;
7500 if (name
[0] == '_' && name
[1] == 'G'
7501 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
7505 if (symbol_find (name
))
7506 as_bad ("GOT already in the symbol table");
7508 GOT_symbol
= symbol_new (name
, undefined_section
,
7509 (valueT
) 0, & zero_address_frag
);
7519 /* arm_reg_parse () := if it looks like a register, return its token and
7520 advance the pointer. */
7524 register char ** ccp
;
7526 char * start
= * ccp
;
7529 struct reg_entry
* reg
;
7531 #ifdef REGISTER_PREFIX
7532 if (*start
!= REGISTER_PREFIX
)
7537 #ifdef OPTIONAL_REGISTER_PREFIX
7538 if (*p
== OPTIONAL_REGISTER_PREFIX
)
7542 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
7546 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
7550 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
7563 md_apply_fix3 (fixP
, val
, seg
)
7568 offsetT value
= * val
;
7570 unsigned int newimm
;
7573 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
7574 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
7576 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
7578 /* Note whether this will delete the relocation. */
7580 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
7581 doesn't work fully.) */
7582 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
7585 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
7589 /* If this symbol is in a different section then we need to leave it for
7590 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
7591 so we have to undo it's effects here. */
7594 if (fixP
->fx_addsy
!= NULL
7595 && S_IS_DEFINED (fixP
->fx_addsy
)
7596 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
7599 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7600 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
7604 value
+= md_pcrel_from (fixP
);
7608 /* Remember value for emit_reloc. */
7609 fixP
->fx_addnumber
= value
;
7611 switch (fixP
->fx_r_type
)
7613 case BFD_RELOC_ARM_IMMEDIATE
:
7614 newimm
= validate_immediate (value
);
7615 temp
= md_chars_to_number (buf
, INSN_SIZE
);
7617 /* If the instruction will fail, see if we can fix things up by
7618 changing the opcode. */
7619 if (newimm
== (unsigned int) FAIL
7620 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
7622 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7623 _("invalid constant (%lx) after fixup"),
7624 (unsigned long) value
);
7628 newimm
|= (temp
& 0xfffff000);
7629 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
7632 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
7634 unsigned int highpart
= 0;
7635 unsigned int newinsn
= 0xe1a00000; /* nop. */
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 /* No ? OK - try using two ADD instructions to generate
7646 newimm
= validate_immediate_twopart (value
, & highpart
);
7648 /* Yes - then make sure that the second instruction is
7650 if (newimm
!= (unsigned int) FAIL
)
7652 /* Still No ? Try using a negated value. */
7653 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
7654 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
7655 /* Otherwise - give up. */
7658 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7659 _("Unable to compute ADRL instructions for PC offset of 0x%lx"),
7664 /* Replace the first operand in the 2nd instruction (which
7665 is the PC) with the destination register. We have
7666 already added in the PC in the first instruction and we
7667 do not want to do it again. */
7668 newinsn
&= ~ 0xf0000;
7669 newinsn
|= ((newinsn
& 0x0f000) << 4);
7672 newimm
|= (temp
& 0xfffff000);
7673 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
7675 highpart
|= (newinsn
& 0xfffff000);
7676 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
7680 case BFD_RELOC_ARM_OFFSET_IMM
:
7686 if (validate_offset_imm (value
, 0) == FAIL
)
7688 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7689 _("bad immediate value for offset (%ld)"),
7694 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7695 newval
&= 0xff7ff000;
7696 newval
|= value
| (sign
? INDEX_UP
: 0);
7697 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7700 case BFD_RELOC_ARM_OFFSET_IMM8
:
7701 case BFD_RELOC_ARM_HWLITERAL
:
7707 if (validate_offset_imm (value
, 1) == FAIL
)
7709 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
7710 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7711 _("invalid literal constant: pool needs to be closer"));
7713 as_bad (_("bad immediate value for half-word offset (%ld)"),
7718 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7719 newval
&= 0xff7ff0f0;
7720 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
7721 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7724 case BFD_RELOC_ARM_LITERAL
:
7730 if (validate_offset_imm (value
, 0) == FAIL
)
7732 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7733 _("invalid literal constant: pool needs to be closer"));
7737 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7738 newval
&= 0xff7ff000;
7739 newval
|= value
| (sign
? INDEX_UP
: 0);
7740 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7743 case BFD_RELOC_ARM_SHIFT_IMM
:
7744 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7745 if (((unsigned long) value
) > 32
7747 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
7749 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7750 _("shift expression is too large"));
7755 /* Shifts of zero must be done as lsl. */
7757 else if (value
== 32)
7759 newval
&= 0xfffff07f;
7760 newval
|= (value
& 0x1f) << 7;
7761 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7764 case BFD_RELOC_ARM_SWI
:
7765 if (arm_data
->thumb_mode
)
7767 if (((unsigned long) value
) > 0xff)
7768 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7769 _("Invalid swi expression"));
7770 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
7772 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7776 if (((unsigned long) value
) > 0x00ffffff)
7777 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7778 _("Invalid swi expression"));
7779 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
7781 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7785 case BFD_RELOC_ARM_MULTI
:
7786 if (((unsigned long) value
) > 0xffff)
7787 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7788 _("Invalid expression in load/store multiple"));
7789 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
7790 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7793 case BFD_RELOC_ARM_PCREL_BRANCH
:
7794 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7796 /* Sign-extend a 24-bit number. */
7797 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
7801 value
= fixP
->fx_offset
;
7804 /* We are going to store value (shifted right by two) in the
7805 instruction, in a 24 bit, signed field. Thus we need to check
7806 that none of the top 8 bits of the shifted value (top 7 bits of
7807 the unshifted, unsigned value) are set, or that they are all set. */
7808 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
7809 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
7812 /* Normally we would be stuck at this point, since we cannot store
7813 the absolute address that is the destination of the branch in the
7814 24 bits of the branch instruction. If however, we happen to know
7815 that the destination of the branch is in the same section as the
7816 branch instruciton itself, then we can compute the relocation for
7817 ourselves and not have to bother the linker with it.
7819 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
7820 because I have not worked out how to do this for OBJ_COFF or
7823 && fixP
->fx_addsy
!= NULL
7824 && S_IS_DEFINED (fixP
->fx_addsy
)
7825 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
7827 /* Get pc relative value to go into the branch. */
7830 /* Permit a backward branch provided that enough bits
7831 are set. Allow a forwards branch, provided that
7832 enough bits are clear. */
7833 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
7834 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
7838 if (! fixP
->fx_done
)
7840 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7841 _("gas can't handle same-section branch dest >= 0x04000000"));
7845 value
+= SEXT24 (newval
);
7847 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
7848 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
7849 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7850 _("out of range branch"));
7852 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
7853 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7856 case BFD_RELOC_ARM_PCREL_BLX
:
7859 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7863 value
= fixP
->fx_offset
;
7865 hbit
= (value
>> 1) & 1;
7866 value
= (value
>> 2) & 0x00ffffff;
7867 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
7868 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
7869 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7873 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
7874 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7876 addressT diff
= (newval
& 0xff) << 1;
7881 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
7882 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7883 _("Branch out of range"));
7884 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
7886 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7889 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
7890 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7892 addressT diff
= (newval
& 0x7ff) << 1;
7897 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
7898 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7899 _("Branch out of range"));
7900 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
7902 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7905 case BFD_RELOC_THUMB_PCREL_BLX
:
7906 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
7911 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7912 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
7913 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
7914 if (diff
& 0x400000)
7917 value
= fixP
->fx_offset
;
7920 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
7921 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7922 _("Branch with link out of range"));
7924 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
7925 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
7926 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
)
7927 /* Remove bit zero of the adjusted offset. Bit zero can only be
7928 set if the upper insn is at a half-word boundary, since the
7929 destination address, an ARM instruction, must always be on a
7930 word boundary. The semantics of the BLX (1) instruction, however,
7931 are that bit zero in the offset must always be zero, and the
7932 corresponding bit one in the target address will be set from bit
7933 one of the source address. */
7935 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7936 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
7941 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7942 md_number_to_chars (buf
, value
, 1);
7944 else if (!target_oabi
)
7946 value
= fixP
->fx_offset
;
7947 md_number_to_chars (buf
, value
, 1);
7953 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7954 md_number_to_chars (buf
, value
, 2);
7956 else if (!target_oabi
)
7958 value
= fixP
->fx_offset
;
7959 md_number_to_chars (buf
, value
, 2);
7965 case BFD_RELOC_ARM_GOT32
:
7966 case BFD_RELOC_ARM_GOTOFF
:
7967 md_number_to_chars (buf
, 0, 4);
7973 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7974 md_number_to_chars (buf
, value
, 4);
7976 else if (!target_oabi
)
7978 value
= fixP
->fx_offset
;
7979 md_number_to_chars (buf
, value
, 4);
7985 case BFD_RELOC_ARM_PLT32
:
7986 /* It appears the instruction is fully prepared at this point. */
7990 case BFD_RELOC_ARM_GOTPC
:
7991 md_number_to_chars (buf
, value
, 4);
7994 case BFD_RELOC_ARM_CP_OFF_IMM
:
7996 if (value
< -1023 || value
> 1023 || (value
& 3))
7997 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7998 _("Illegal value for co-processor offset"));
8001 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
8002 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
8003 md_number_to_chars (buf
, newval
, INSN_SIZE
);
8006 case BFD_RELOC_ARM_THUMB_OFFSET
:
8007 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8008 /* Exactly what ranges, and where the offset is inserted depends
8009 on the type of instruction, we can establish this from the
8011 switch (newval
>> 12)
8013 case 4: /* PC load. */
8014 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
8015 forced to zero for these loads, so we will need to round
8016 up the offset if the instruction address is not word
8017 aligned (since the final address produced must be, and
8018 we can only describe word-aligned immediate offsets). */
8020 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
8021 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8022 _("Invalid offset, target not word aligned (0x%08X)"),
8023 (unsigned int) (fixP
->fx_frag
->fr_address
8024 + fixP
->fx_where
+ value
));
8026 if ((value
+ 2) & ~0x3fe)
8027 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8028 _("Invalid offset, value too big (0x%08lX)"), value
);
8030 /* Round up, since pc will be rounded down. */
8031 newval
|= (value
+ 2) >> 2;
8034 case 9: /* SP load/store. */
8036 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8037 _("Invalid offset, value too big (0x%08lX)"), value
);
8038 newval
|= value
>> 2;
8041 case 6: /* Word load/store. */
8043 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8044 _("Invalid offset, value too big (0x%08lX)"), value
);
8045 newval
|= value
<< 4; /* 6 - 2. */
8048 case 7: /* Byte load/store. */
8050 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8051 _("Invalid offset, value too big (0x%08lX)"), value
);
8052 newval
|= value
<< 6;
8055 case 8: /* Halfword load/store. */
8057 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8058 _("Invalid offset, value too big (0x%08lX)"), value
);
8059 newval
|= value
<< 5; /* 6 - 1. */
8063 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8064 "Unable to process relocation for thumb opcode: %lx",
8065 (unsigned long) newval
);
8068 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8071 case BFD_RELOC_ARM_THUMB_ADD
:
8072 /* This is a complicated relocation, since we use it for all of
8073 the following immediate relocations:
8077 9bit ADD/SUB SP word-aligned
8078 10bit ADD PC/SP word-aligned
8080 The type of instruction being processed is encoded in the
8087 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8089 int rd
= (newval
>> 4) & 0xf;
8090 int rs
= newval
& 0xf;
8091 int subtract
= newval
& 0x8000;
8096 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8097 _("Invalid immediate for stack address calculation"));
8098 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
8099 newval
|= value
>> 2;
8101 else if (rs
== REG_PC
|| rs
== REG_SP
)
8105 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8106 _("Invalid immediate for address calculation (value = 0x%08lX)"),
8107 (unsigned long) value
);
8108 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
8110 newval
|= value
>> 2;
8115 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8116 _("Invalid 8bit immediate"));
8117 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
8118 newval
|= (rd
<< 8) | value
;
8123 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8124 _("Invalid 3bit immediate"));
8125 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
8126 newval
|= rd
| (rs
<< 3) | (value
<< 6);
8129 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8132 case BFD_RELOC_ARM_THUMB_IMM
:
8133 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
8134 switch (newval
>> 11)
8136 case 0x04: /* 8bit immediate MOV. */
8137 case 0x05: /* 8bit immediate CMP. */
8138 if (value
< 0 || value
> 255)
8139 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8140 _("Invalid immediate: %ld is too large"),
8148 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8151 case BFD_RELOC_ARM_THUMB_SHIFT
:
8152 /* 5bit shift value (0..31). */
8153 if (value
< 0 || value
> 31)
8154 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8155 _("Illegal Thumb shift value: %ld"), (long) value
);
8156 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
8157 newval
|= value
<< 6;
8158 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
8161 case BFD_RELOC_VTABLE_INHERIT
:
8162 case BFD_RELOC_VTABLE_ENTRY
:
8166 case BFD_RELOC_NONE
:
8168 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
8169 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
8175 /* Translate internal representation of relocation info to BFD target
8179 tc_gen_reloc (section
, fixp
)
8180 asection
* section ATTRIBUTE_UNUSED
;
8184 bfd_reloc_code_real_type code
;
8186 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
8188 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
8189 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
8190 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
8192 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
8194 if (fixp
->fx_pcrel
== 0)
8195 reloc
->addend
= fixp
->fx_offset
;
8197 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
8199 reloc
->addend
= fixp
->fx_offset
;
8202 switch (fixp
->fx_r_type
)
8207 code
= BFD_RELOC_8_PCREL
;
8214 code
= BFD_RELOC_16_PCREL
;
8221 code
= BFD_RELOC_32_PCREL
;
8225 case BFD_RELOC_ARM_PCREL_BRANCH
:
8226 case BFD_RELOC_ARM_PCREL_BLX
:
8228 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
8229 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
8230 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
8231 case BFD_RELOC_THUMB_PCREL_BLX
:
8232 case BFD_RELOC_VTABLE_ENTRY
:
8233 case BFD_RELOC_VTABLE_INHERIT
:
8234 code
= fixp
->fx_r_type
;
8237 case BFD_RELOC_ARM_LITERAL
:
8238 case BFD_RELOC_ARM_HWLITERAL
:
8239 /* If this is called then the a literal has been referenced across
8240 a section boundary - possibly due to an implicit dump. */
8241 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8242 _("Literal referenced across section boundary (Implicit dump?)"));
8246 case BFD_RELOC_ARM_GOT32
:
8247 case BFD_RELOC_ARM_GOTOFF
:
8248 case BFD_RELOC_ARM_PLT32
:
8249 code
= fixp
->fx_r_type
;
8253 case BFD_RELOC_ARM_IMMEDIATE
:
8254 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8255 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
8259 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
8260 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8261 _("ADRL used for a symbol not defined in the same file"));
8264 case BFD_RELOC_ARM_OFFSET_IMM
:
8265 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8266 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
8274 switch (fixp
->fx_r_type
)
8276 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
8277 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
8278 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
8279 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
8280 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
8281 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
8282 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
8283 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
8284 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
8285 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
8286 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
8287 default: type
= _("<unknown>"); break;
8289 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8290 _("Cannot represent %s relocation in this object file format"),
8297 if (code
== BFD_RELOC_32_PCREL
8299 && fixp
->fx_addsy
== GOT_symbol
)
8301 code
= BFD_RELOC_ARM_GOTPC
;
8302 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
8306 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
8308 if (reloc
->howto
== NULL
)
8310 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
8311 _("Can not represent %s relocation in this object file format"),
8312 bfd_get_reloc_code_name (code
));
8316 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
8317 vtable entry to be used in the relocation's section offset. */
8318 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
8319 reloc
->address
= fixp
->fx_offset
;
8325 md_estimate_size_before_relax (fragP
, segtype
)
8326 fragS
* fragP ATTRIBUTE_UNUSED
;
8327 segT segtype ATTRIBUTE_UNUSED
;
8329 as_fatal (_("md_estimate_size_before_relax\n"));
8334 output_inst
PARAMS ((void))
8340 as_bad (inst
.error
);
8344 to
= frag_more (inst
.size
);
8346 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
8348 assert (inst
.size
== (2 * THUMB_SIZE
));
8349 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
8350 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
8352 else if (inst
.size
> INSN_SIZE
)
8354 assert (inst
.size
== (2 * INSN_SIZE
));
8355 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
8356 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
8359 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
8361 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
8362 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
8363 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
8367 dwarf2_emit_insn (inst
.size
);
8380 /* Align the instruction.
8381 This may not be the right thing to do but ... */
8385 listing_prev_line (); /* Defined in listing.h. */
8387 /* Align the previous label if needed. */
8388 if (last_label_seen
!= NULL
)
8390 symbol_set_frag (last_label_seen
, frag_now
);
8391 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
8392 S_SET_SEGMENT (last_label_seen
, now_seg
);
8395 memset (&inst
, '\0', sizeof (inst
));
8396 inst
.reloc
.type
= BFD_RELOC_NONE
;
8398 skip_whitespace (str
);
8400 /* Scan up to the end of the op-code, which must end in white space or
8402 for (start
= p
= str
; *p
!= '\0'; p
++)
8408 as_bad (_("No operator -- statement `%s'\n"), str
);
8414 const struct thumb_opcode
* opcode
;
8418 opcode
= (const struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
8423 /* Check that this instruction is supported for this CPU. */
8424 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
8426 as_bad (_("selected processor does not support this opcode"));
8430 inst
.instruction
= opcode
->value
;
8431 inst
.size
= opcode
->size
;
8432 (*opcode
->parms
) (p
);
8439 const struct asm_opcode
* opcode
;
8440 unsigned long cond_code
;
8442 inst
.size
= INSN_SIZE
;
8443 /* P now points to the end of the opcode, probably white space, but we
8444 have to break the opcode up in case it contains condionals and flags;
8445 keep trying with progressively smaller basic instructions until one
8446 matches, or we run out of opcode. */
8447 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
8449 for (; q
!= str
; q
--)
8454 opcode
= (const struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
8457 if (opcode
&& opcode
->template)
8459 unsigned long flag_bits
= 0;
8462 /* Check that this instruction is supported for this CPU. */
8463 if ((opcode
->variants
& cpu_variant
) == 0)
8466 inst
.instruction
= opcode
->value
;
8467 if (q
== p
) /* Just a simple opcode. */
8469 if (opcode
->comp_suffix
)
8471 if (*opcode
->comp_suffix
!= '\0')
8472 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
8473 str
, opcode
->comp_suffix
);
8475 /* Not a conditional instruction. */
8476 (*opcode
->parms
) (q
, 0);
8480 /* A conditional instruction with default condition. */
8481 inst
.instruction
|= COND_ALWAYS
;
8482 (*opcode
->parms
) (q
, 0);
8488 /* Not just a simple opcode. Check if extra is a
8493 const struct asm_cond
*cond
;
8497 cond
= (const struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
8501 if (cond
->value
== 0xf0000000)
8503 _("Warning: Use of the 'nv' conditional is deprecated\n"));
8505 cond_code
= cond
->value
;
8509 cond_code
= COND_ALWAYS
;
8512 cond_code
= COND_ALWAYS
;
8514 /* Apply the conditional, or complain it's not allowed. */
8515 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
8517 /* Instruction isn't conditional. */
8518 if (cond_code
!= COND_ALWAYS
)
8520 as_bad (_("Opcode `%s' is unconditional\n"), str
);
8525 /* Instruction is conditional: set the condition into it. */
8526 inst
.instruction
|= cond_code
;
8528 /* If there is a compulsory suffix, it should come here
8529 before any optional flags. */
8530 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
8532 const char *s
= opcode
->comp_suffix
;
8544 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
8545 str
, opcode
->comp_suffix
);
8552 /* The remainder, if any should now be flags for the instruction;
8553 Scan these checking each one found with the opcode. */
8557 const struct asm_flg
*flag
= opcode
->flags
;
8566 for (flagno
= 0; flag
[flagno
].template; flagno
++)
8568 if (streq (r
, flag
[flagno
].template))
8570 flag_bits
|= flag
[flagno
].set_bits
;
8576 if (! flag
[flagno
].template)
8583 (*opcode
->parms
) (p
, flag_bits
);
8593 /* It wasn't an instruction, but it might be a register alias of the form
8596 skip_whitespace (q
);
8601 if (*q
&& !strncmp (q
, ".req ", 4))
8607 #ifdef IGNORE_OPCODE_CASE
8608 str
= original_case_string
;
8613 skip_whitespace (q
);
8615 for (r
= q
; *r
!= '\0'; r
++)
8625 regnum
= arm_reg_parse (& q
);
8628 reg
= arm_reg_parse (& str
);
8633 insert_reg_alias (str
, regnum
);
8635 as_warn (_("register '%s' does not exist\n"), q
);
8637 else if (regnum
!= FAIL
)
8640 as_warn (_("ignoring redefinition of register alias '%s'"),
8643 /* Do not warn about redefinitions to the same alias. */
8646 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
8650 as_warn (_("ignoring incomplete .req pseuso op"));
8657 as_bad (_("bad instruction `%s'"), start
);
8661 Invocation line includes a switch not recognized by the base assembler.
8662 See if it's a processor-specific option. These are:
8663 Cpu variants, the arm part is optional:
8664 -m[arm]1 Currently not supported.
8665 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
8666 -m[arm]3 Arm 3 processor
8667 -m[arm]6[xx], Arm 6 processors
8668 -m[arm]7[xx][t][[d]m] Arm 7 processors
8669 -m[arm]8[10] Arm 8 processors
8670 -m[arm]9[20][tdmi] Arm 9 processors
8671 -marm9e Allow Cirrus/DSP instructions
8672 -mstrongarm[110[0]] StrongARM processors
8673 -mxscale XScale processors
8674 -m[arm]v[2345[t[e]]] Arm architectures
8675 -mall All (except the ARM1)
8677 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
8678 -mfpe-old (No float load/store multiples)
8679 -mno-fpu Disable all floating point instructions
8680 Run-time endian selection:
8682 -EL little endian cpu
8683 ARM Procedure Calling Standard:
8684 -mapcs-32 32 bit APCS
8685 -mapcs-26 26 bit APCS
8686 -mapcs-float Pass floats in float regs
8687 -mapcs-reentrant Position independent code
8688 -mthumb-interwork Code supports Arm/Thumb interworking
8689 -matpcs ARM/Thumb Procedure Call Standard
8690 -moabi Old ELF ABI */
8692 const char * md_shortopts
= "m:k";
8694 struct option md_longopts
[] =
8696 #ifdef ARM_BI_ENDIAN
8697 #define OPTION_EB (OPTION_MD_BASE + 0)
8698 {"EB", no_argument
, NULL
, OPTION_EB
},
8699 #define OPTION_EL (OPTION_MD_BASE + 1)
8700 {"EL", no_argument
, NULL
, OPTION_EL
},
8702 #define OPTION_OABI (OPTION_MD_BASE +2)
8703 {"oabi", no_argument
, NULL
, OPTION_OABI
},
8706 {NULL
, no_argument
, NULL
, 0}
8709 size_t md_longopts_size
= sizeof (md_longopts
);
8712 md_parse_option (c
, arg
)
8720 #ifdef ARM_BI_ENDIAN
8722 target_big_endian
= 1;
8725 target_big_endian
= 0;
8733 if (streq (str
, "fpa10") || streq (str
, "fpa11"))
8734 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_ARCH_FPA
;
8735 else if (streq (str
, "fpe-old"))
8736 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_ARCH_FPE
;
8742 if (streq (str
, "no-fpu"))
8743 cpu_variant
&= ~FPU_ANY
;
8748 if (streq (str
, "oabi"))
8754 /* Limit assembler to generating only Thumb instructions: */
8755 if (streq (str
, "thumb"))
8757 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_EXT_V4T
;
8758 cpu_variant
= (cpu_variant
& ~FPU_ANY
) | FPU_NONE
;
8761 else if (streq (str
, "thumb-interwork"))
8763 if ((cpu_variant
& ARM_EXT_V4T
) == 0)
8764 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
8765 #if defined OBJ_COFF || defined OBJ_ELF
8766 support_interwork
= true;
8774 if (streq (str
, "all"))
8776 cpu_variant
= ARM_ALL
| FPU_DEFAULT
;
8779 #if defined OBJ_COFF || defined OBJ_ELF
8780 if (! strncmp (str
, "apcs-", 5))
8782 /* GCC passes on all command line options starting "-mapcs-..."
8783 to us, so we must parse them here. */
8787 if (streq (str
, "32"))
8789 uses_apcs_26
= false;
8792 else if (streq (str
, "26"))
8794 uses_apcs_26
= true;
8797 else if (streq (str
, "frame"))
8799 /* Stack frames are being generated - does not affect
8803 else if (streq (str
, "stack-check"))
8805 /* Stack checking is being performed - does not affect
8806 linkage, but does require that the functions
8807 __rt_stkovf_split_small and __rt_stkovf_split_big be
8808 present in the final link. */
8812 else if (streq (str
, "float"))
8814 /* Floating point arguments are being passed in the floating
8815 point registers. This does affect linking, since this
8816 version of the APCS is incompatible with the version that
8817 passes floating points in the integer registers. */
8819 uses_apcs_float
= true;
8822 else if (streq (str
, "reentrant"))
8824 /* Reentrant code has been generated. This does affect
8825 linking, since there is no point in linking reentrant/
8826 position independent code with absolute position code. */
8831 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
8835 if (! strcmp (str
, "atpcs"))
8841 /* Strip off optional "arm". */
8842 if (! strncmp (str
, "arm", 3))
8848 if (streq (str
, "1"))
8849 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
8855 if (streq (str
, "2"))
8856 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
8857 else if (streq (str
, "250"))
8858 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
8864 if (streq (str
, "3"))
8865 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
8871 switch (strtol (str
, NULL
, 10))
8878 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
8886 /* Eat the processor name. */
8887 switch (strtol (str
, & str
, 10))
8900 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
8906 cpu_variant
|= ARM_ARCH_V4T
;
8910 cpu_variant
|= ARM_EXT_V3M
;
8913 case 'f': /* fe => fp enabled cpu. */
8919 case 'c': /* Left over from 710c processor name. */
8920 case 'd': /* Debug. */
8921 case 'i': /* Embedded ICE. */
8922 /* Included for completeness in ARM processor naming. */
8932 if (streq (str
, "8") || streq (str
, "810"))
8933 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8934 | ARM_8
| ARM_ARCH_V4
;
8940 if (streq (str
, "9"))
8941 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8942 | ARM_9
| ARM_ARCH_V4T
;
8943 else if (streq (str
, "920"))
8944 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8945 | ARM_9
| ARM_ARCH_V4
;
8946 else if (streq (str
, "920t"))
8947 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8948 | ARM_9
| ARM_ARCH_V4T
;
8949 else if (streq (str
, "9tdmi"))
8950 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8951 | ARM_9
| ARM_ARCH_V4T
;
8952 else if (streq (str
, "9e"))
8953 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8954 | ARM_9
| ARM_ARCH_V4T
| ARM_EXT_MAVERICK
;
8960 if (streq (str
, "strongarm")
8961 || streq (str
, "strongarm110")
8962 || streq (str
, "strongarm1100"))
8963 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8964 | ARM_8
| ARM_ARCH_V4
;
8970 if (streq (str
, "xscale"))
8971 cpu_variant
= ARM_9
| ARM_ARCH_XSCALE
;
8977 /* Select variant based on architecture rather than
8985 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
8988 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
8991 as_bad (_("Invalid architecture variant -m%s"), arg
);
8997 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
9001 case 'm': cpu_variant
|= ARM_EXT_V3M
; break;
9004 as_bad (_("Invalid architecture variant -m%s"), arg
);
9010 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCH_V4
;
9014 case 't': cpu_variant
|= ARM_EXT_V4T
; break;
9017 as_bad (_("Invalid architecture variant -m%s"), arg
);
9023 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V5
;
9026 case 't': cpu_variant
|= ARM_EXT_V4T
; break;
9027 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
9030 as_bad (_("Invalid architecture variant -m%s"), arg
);
9036 as_bad (_("Invalid architecture variant -m%s"), arg
);
9043 as_bad (_("Invalid processor variant -m%s"), arg
);
9049 #if defined OBJ_ELF || defined OBJ_COFF
9067 ARM Specific Assembler Options:\n\
9068 -m[arm][<processor name>] select processor variant\n\
9069 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
9070 -marm9e allow Cirrus/DSP instructions\n\
9071 -mthumb only allow Thumb instructions\n\
9072 -mthumb-interwork mark the assembled code as supporting interworking\n\
9073 -mall allow any instruction\n\
9074 -mfpa10, -mfpa11 select floating point architecture\n\
9075 -mfpe-old don't allow floating-point multiple instructions\n\
9076 -mno-fpu don't allow any floating-point instructions.\n\
9077 -k generate PIC code.\n"));
9078 #if defined OBJ_COFF || defined OBJ_ELF
9080 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
9081 -matpcs use ARM/Thumb Procedure Calling Standard\n\
9082 -mapcs-float floating point args are passed in FP regs\n\
9083 -mapcs-reentrant the code is position independent/reentrant\n"));
9087 -moabi support the old ELF ABI\n"));
9089 #ifdef ARM_BI_ENDIAN
9091 -EB assemble code for a big endian cpu\n\
9092 -EL assemble code for a little endian cpu\n"));
9096 /* We need to be able to fix up arbitrary expressions in some statements.
9097 This is so that we can handle symbols that are an arbitrary distance from
9098 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
9099 which returns part of an address in a form which will be valid for
9100 a data instruction. We do this by pushing the expression into a symbol
9101 in the expr_section, and creating a fix for that. */
9104 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
9113 arm_fix_data
* arm_data
;
9121 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
9125 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
9130 /* Mark whether the fix is to a THUMB instruction, or an ARM
9132 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
9133 new_fix
->tc_fix_data
= (PTR
) arm_data
;
9134 arm_data
->thumb_mode
= thumb_mode
;
9139 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
9142 cons_fix_new_arm (frag
, where
, size
, exp
)
9148 bfd_reloc_code_real_type type
;
9152 FIXME: @@ Should look at CPU word size. */
9159 type
= BFD_RELOC_16
;
9163 type
= BFD_RELOC_32
;
9166 type
= BFD_RELOC_64
;
9170 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
9173 /* A good place to do this, although this was probably not intended
9174 for this kind of use. We need to dump the literal pool before
9175 references are made to a null symbol pointer. */
9180 if (current_poolP
== NULL
)
9183 /* Put it at the end of text section. */
9184 subseg_set (text_section
, 0);
9186 listing_prev_line ();
9190 arm_start_line_hook ()
9192 last_label_seen
= NULL
;
9196 arm_frob_label (sym
)
9199 last_label_seen
= sym
;
9201 ARM_SET_THUMB (sym
, thumb_mode
);
9203 #if defined OBJ_COFF || defined OBJ_ELF
9204 ARM_SET_INTERWORK (sym
, support_interwork
);
9207 /* Note - do not allow local symbols (.Lxxx) to be labeled
9208 as Thumb functions. This is because these labels, whilst
9209 they exist inside Thumb code, are not the entry points for
9210 possible ARM->Thumb calls. Also, these labels can be used
9211 as part of a computed goto or switch statement. eg gcc
9212 can generate code that looks like this:
9224 The first instruction loads the address of the jump table.
9225 The second instruction converts a table index into a byte offset.
9226 The third instruction gets the jump address out of the table.
9227 The fourth instruction performs the jump.
9229 If the address stored at .Laaa is that of a symbol which has the
9230 Thumb_Func bit set, then the linker will arrange for this address
9231 to have the bottom bit set, which in turn would mean that the
9232 address computation performed by the third instruction would end
9233 up with the bottom bit set. Since the ARM is capable of unaligned
9234 word loads, the instruction would then load the incorrect address
9235 out of the jump table, and chaos would ensue. */
9236 if (label_is_thumb_function_name
9237 && (S_GET_NAME (sym
)[0] != '.' || S_GET_NAME (sym
)[1] != 'L')
9238 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
9240 /* When the address of a Thumb function is taken the bottom
9241 bit of that address should be set. This will allow
9242 interworking between Arm and Thumb functions to work
9245 THUMB_SET_FUNC (sym
, 1);
9247 label_is_thumb_function_name
= false;
9251 /* Adjust the symbol table. This marks Thumb symbols as distinct from
9255 arm_adjust_symtab ()
9260 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
9262 if (ARM_IS_THUMB (sym
))
9264 if (THUMB_IS_FUNC (sym
))
9266 /* Mark the symbol as a Thumb function. */
9267 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
9268 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
9269 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
9271 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
9272 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
9274 as_bad (_("%s: unexpected function type: %d"),
9275 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
9277 else switch (S_GET_STORAGE_CLASS (sym
))
9280 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
9283 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
9286 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
9294 if (ARM_IS_INTERWORK (sym
))
9295 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
9302 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
9304 if (ARM_IS_THUMB (sym
))
9306 elf_symbol_type
* elf_sym
;
9308 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
9309 bind
= ELF_ST_BIND (elf_sym
);
9311 /* If it's a .thumb_func, declare it as so,
9312 otherwise tag label as .code 16. */
9313 if (THUMB_IS_FUNC (sym
))
9314 elf_sym
->internal_elf_sym
.st_info
=
9315 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
9317 elf_sym
->internal_elf_sym
.st_info
=
9318 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
9327 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
9329 *input_line_pointer
= '/';
9330 input_line_pointer
+= 5;
9331 *input_line_pointer
= 0;
9339 arm_canonicalize_symbol_name (name
)
9344 if (thumb_mode
&& (len
= strlen (name
)) > 5
9345 && streq (name
+ len
- 5, "/data"))
9346 *(name
+ len
- 5) = 0;
9352 arm_validate_fix (fixP
)
9355 /* If the destination of the branch is a defined symbol which does not have
9356 the THUMB_FUNC attribute, then we must be calling a function which has
9357 the (interfacearm) attribute. We look for the Thumb entry point to that
9358 function and change the branch to refer to that function instead. */
9359 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
9360 && fixP
->fx_addsy
!= NULL
9361 && S_IS_DEFINED (fixP
->fx_addsy
)
9362 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
9364 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
9372 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
9373 local labels from being added to the output symbol table when they
9374 are used with the ADRL pseudo op. The ADRL relocation should always
9375 be resolved before the binbary is emitted, so it is safe to say that
9376 it is adjustable. */
9379 arm_fix_adjustable (fixP
)
9382 if (fixP
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
9388 /* Relocations against Thumb function names must be left unadjusted,
9389 so that the linker can use this information to correctly set the
9390 bottom bit of their addresses. The MIPS version of this function
9391 also prevents relocations that are mips-16 specific, but I do not
9392 know why it does this.
9395 There is one other problem that ought to be addressed here, but
9396 which currently is not: Taking the address of a label (rather
9397 than a function) and then later jumping to that address. Such
9398 addresses also ought to have their bottom bit set (assuming that
9399 they reside in Thumb code), but at the moment they will not. */
9402 arm_fix_adjustable (fixP
)
9405 if (fixP
->fx_addsy
== NULL
)
9408 /* Prevent all adjustments to global symbols. */
9409 if (S_IS_EXTERN (fixP
->fx_addsy
))
9412 if (S_IS_WEAK (fixP
->fx_addsy
))
9415 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
9416 && fixP
->fx_subsy
== NULL
)
9419 /* We need the symbol name for the VTABLE entries. */
9420 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
9421 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
9428 elf32_arm_target_format ()
9430 if (target_big_endian
)
9433 return "elf32-bigarm-oabi";
9435 return "elf32-bigarm";
9440 return "elf32-littlearm-oabi";
9442 return "elf32-littlearm";
9447 armelf_frob_symbol (symp
, puntp
)
9451 elf_frob_symbol (symp
, puntp
);
9455 arm_force_relocation (fixp
)
9458 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
9459 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
9460 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
9461 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
9462 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
9463 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
9469 static bfd_reloc_code_real_type
9479 bfd_reloc_code_real_type reloc
;
9483 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
9484 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
9485 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
9486 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
9487 branch instructions generated by GCC for PLT relocs. */
9488 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
9489 { NULL
, 0, BFD_RELOC_UNUSED
}
9493 for (i
= 0, ip
= input_line_pointer
;
9494 i
< sizeof (id
) && (ISALNUM (*ip
) || ISPUNCT (*ip
));
9496 id
[i
] = TOLOWER (*ip
);
9498 for (i
= 0; reloc_map
[i
].str
; i
++)
9499 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
9502 input_line_pointer
+= reloc_map
[i
].len
;
9504 return reloc_map
[i
].reloc
;
9508 s_arm_elf_cons (nbytes
)
9513 #ifdef md_flush_pending_output
9514 md_flush_pending_output ();
9517 if (is_it_end_of_statement ())
9519 demand_empty_rest_of_line ();
9523 #ifdef md_cons_align
9524 md_cons_align (nbytes
);
9529 bfd_reloc_code_real_type reloc
;
9533 if (exp
.X_op
== O_symbol
9534 && * input_line_pointer
== '('
9535 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
9537 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
9538 int size
= bfd_get_reloc_size (howto
);
9541 as_bad ("%s relocations do not fit in %d bytes",
9542 howto
->name
, nbytes
);
9545 register char *p
= frag_more ((int) nbytes
);
9546 int offset
= nbytes
- size
;
9548 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
9553 emit_expr (&exp
, (unsigned int) nbytes
);
9555 while (*input_line_pointer
++ == ',');
9557 /* Put terminator back into stream. */
9558 input_line_pointer
--;
9559 demand_empty_rest_of_line ();
9562 #endif /* OBJ_ELF */
9564 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
9565 of an rs_align_code fragment. */
9568 arm_handle_align (fragP
)
9571 static char const arm_noop
[4] = { 0x00, 0x00, 0xa0, 0xe1 };
9572 static char const thumb_noop
[2] = { 0xc0, 0x46 };
9573 static char const arm_bigend_noop
[4] = { 0xe1, 0xa0, 0x00, 0x00 };
9574 static char const thumb_bigend_noop
[2] = { 0x46, 0xc0 };
9576 int bytes
, fix
, noop_size
;
9580 if (fragP
->fr_type
!= rs_align_code
)
9583 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
9584 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
9587 if (bytes
> MAX_MEM_FOR_RS_ALIGN_CODE
)
9588 bytes
&= MAX_MEM_FOR_RS_ALIGN_CODE
;
9590 if (fragP
->tc_frag_data
)
9592 if (target_big_endian
)
9593 noop
= thumb_bigend_noop
;
9596 noop_size
= sizeof (thumb_noop
);
9600 if (target_big_endian
)
9601 noop
= arm_bigend_noop
;
9604 noop_size
= sizeof (arm_noop
);
9607 if (bytes
& (noop_size
- 1))
9609 fix
= bytes
& (noop_size
- 1);
9615 while (bytes
>= noop_size
)
9617 memcpy (p
, noop
, noop_size
);
9623 fragP
->fr_fix
+= fix
;
9624 fragP
->fr_var
= noop_size
;
9627 /* Called from md_do_align. Used to create an alignment
9628 frag in a code section. */
9631 arm_frag_align_code (n
, max
)
9637 /* We assume that there will never be a requirment
9638 to support alignments greater than 32 bytes. */
9639 if (max
> MAX_MEM_FOR_RS_ALIGN_CODE
)
9640 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
9642 p
= frag_var (rs_align_code
,
9643 MAX_MEM_FOR_RS_ALIGN_CODE
,
9645 (relax_substateT
) max
,
9653 /* Perform target specific initialisation of a frag. */
9656 arm_init_frag (fragP
)
9659 /* Record whether this frag is in an ARM or a THUMB area. */
9660 fragP
->tc_frag_data
= thumb_mode
;