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)
7 This file is part of GAS, the GNU Assembler.
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
27 #include "safe-ctype.h"
29 /* Need TARGET_CPU. */
38 #include "dwarf2dbg.h"
41 /* Types of processor to assemble for. */
42 #define ARM_1 0x00000001
43 #define ARM_2 0x00000002
44 #define ARM_3 0x00000004
46 #define ARM_6 0x00000008
47 #define ARM_7 ARM_6 /* Same core instruction set. */
48 #define ARM_8 ARM_6 /* Same core instruction set. */
49 #define ARM_9 ARM_6 /* Same core instruction set. */
50 #define ARM_CPU_MASK 0x0000000f
52 /* The following bitmasks control CPU extensions (ARM7 onwards): */
53 #define ARM_EXT_LONGMUL 0x00000010 /* Allow long multiplies. */
54 #define ARM_EXT_HALFWORD 0x00000020 /* Allow half word loads. */
55 #define ARM_EXT_THUMB 0x00000040 /* Allow BX instruction. */
56 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
57 #define ARM_EXT_V5E 0x00000100 /* "El Segundo". */
58 #define ARM_EXT_XSCALE 0x00000200 /* Allow MIA etc. */
60 /* Architectures are the sum of the base and extensions. */
61 #define ARM_ARCH_V3M ARM_EXT_LONGMUL
62 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_HALFWORD)
63 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_THUMB)
64 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
65 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_THUMB)
66 #define ARM_ARCH_V5TE (ARM_ARCH_V5T | ARM_EXT_V5E)
67 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_EXT_XSCALE)
69 /* Some useful combinations: */
70 #define ARM_ANY 0x00ffffff
71 #define ARM_2UP (ARM_ANY - ARM_1)
72 #define ARM_ALL ARM_2UP /* Not arm1 only. */
73 #define ARM_3UP 0x00fffffc
74 #define ARM_6UP 0x00fffff8 /* Includes ARM7. */
76 #define FPU_CORE 0x80000000
77 #define FPU_FPA10 0x40000000
78 #define FPU_FPA11 0x40000000
81 /* Some useful combinations. */
82 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY. */
83 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core. */
86 #if defined __XSCALE__
87 #define CPU_DEFAULT (ARM_9 | ARM_ARCH_XSCALE)
90 #define CPU_DEFAULT (ARM_7 | ARM_ARCH_V4T)
92 #define CPU_DEFAULT ARM_ALL
98 #define FPU_DEFAULT FPU_ALL
101 #define streq(a, b) (strcmp (a, b) == 0)
102 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
104 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
105 static int target_oabi
= 0;
107 #if defined OBJ_COFF || defined OBJ_ELF
108 /* Flags stored in private area of BFD structure. */
109 static boolean uses_apcs_26
= false;
110 static boolean atpcs
= false;
111 static boolean support_interwork
= false;
112 static boolean uses_apcs_float
= false;
113 static boolean pic_code
= false;
116 /* This array holds the chars that always start a comment. If the
117 pre-processor is disabled, these aren't very useful. */
118 CONST
char comment_chars
[] = "@";
120 /* This array holds the chars that only start a comment at the beginning of
121 a line. If the line seems to have the form '# 123 filename'
122 .line and .file directives will appear in the pre-processed output. */
123 /* Note that input_file.c hand checks for '#' at the beginning of the
124 first line of the input file. This is because the compiler outputs
125 #NO_APP at the beginning of its output. */
126 /* Also note that comments like this one will always work. */
127 CONST
char line_comment_chars
[] = "#";
129 CONST
char line_separator_chars
[] = ";";
131 /* Chars that can be used to separate mant
132 from exp in floating point numbers. */
133 CONST
char EXP_CHARS
[] = "eE";
135 /* Chars that mean this number is a floating point constant. */
139 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
141 /* Prefix characters that indicate the start of an immediate
143 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
146 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
147 symbolS
* GOT_symbol
;
150 /* Size of relocation record. */
151 CONST
int md_reloc_size
= 8;
153 /* 0: assemble for ARM,
154 1: assemble for Thumb,
155 2: assemble for Thumb even though target CPU does not support thumb
157 static int thumb_mode
= 0;
159 typedef struct arm_fix
167 unsigned long instruction
;
172 bfd_reloc_code_real_type type
;
189 struct asm_shift_properties
191 enum asm_shift_index index
;
192 unsigned long bit_field
;
193 unsigned int allows_0
: 1;
194 unsigned int allows_32
: 1;
197 static const struct asm_shift_properties shift_properties
[] =
199 { SHIFT_LSL
, 0, 1, 0},
200 { SHIFT_LSR
, 0x20, 0, 1},
201 { SHIFT_ASR
, 0x40, 0, 1},
202 { SHIFT_ROR
, 0x60, 0, 0},
203 { SHIFT_RRX
, 0x60, 0, 0}
206 struct asm_shift_name
209 const struct asm_shift_properties
* properties
;
212 static const struct asm_shift_name shift_names
[] =
214 { "asl", shift_properties
+ SHIFT_LSL
},
215 { "lsl", shift_properties
+ SHIFT_LSL
},
216 { "lsr", shift_properties
+ SHIFT_LSR
},
217 { "asr", shift_properties
+ SHIFT_ASR
},
218 { "ror", shift_properties
+ SHIFT_ROR
},
219 { "rrx", shift_properties
+ SHIFT_RRX
},
220 { "ASL", shift_properties
+ SHIFT_LSL
},
221 { "LSL", shift_properties
+ SHIFT_LSL
},
222 { "LSR", shift_properties
+ SHIFT_LSR
},
223 { "ASR", shift_properties
+ SHIFT_ASR
},
224 { "ROR", shift_properties
+ SHIFT_ROR
},
225 { "RRX", shift_properties
+ SHIFT_RRX
}
228 #define NO_SHIFT_RESTRICT 1
229 #define SHIFT_RESTRICT 0
231 #define NUM_FLOAT_VALS 8
233 CONST
char * fp_const
[] =
235 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
238 /* Number of littlenums required to hold an extended precision number. */
239 #define MAX_LITTLENUMS 6
241 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
251 #define CP_T_X 0x00008000
252 #define CP_T_Y 0x00400000
253 #define CP_T_Pre 0x01000000
254 #define CP_T_UD 0x00800000
255 #define CP_T_WB 0x00200000
257 #define CONDS_BIT 0x00100000
258 #define LOAD_BIT 0x00100000
259 #define TRANS_BIT 0x00200000
261 #define DOUBLE_LOAD_FLAG 0x00000001
265 CONST
char * template;
269 /* This is to save a hash look-up in the common case. */
270 #define COND_ALWAYS 0xe0000000
272 static CONST
struct asm_cond conds
[] =
276 {"cs", 0x20000000}, {"hs", 0x20000000},
277 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
292 /* Warning: If the top bit of the set_bits is set, then the standard
293 instruction bitmask is ignored, and the new bitmask is taken from
297 CONST
char * template; /* Basic flag string. */
298 unsigned long set_bits
; /* Bits to set. */
301 static CONST
struct asm_flg s_flag
[] =
307 static CONST
struct asm_flg ldr_flags
[] =
309 {"d", DOUBLE_LOAD_FLAG
},
312 {"bt", 0x00400000 | TRANS_BIT
},
319 static CONST
struct asm_flg str_flags
[] =
321 {"d", DOUBLE_LOAD_FLAG
},
324 {"bt", 0x00400000 | TRANS_BIT
},
329 static CONST
struct asm_flg byte_flag
[] =
335 static CONST
struct asm_flg cmp_flags
[] =
342 static CONST
struct asm_flg ldm_flags
[] =
355 static CONST
struct asm_flg stm_flags
[] =
368 static CONST
struct asm_flg lfm_flags
[] =
375 static CONST
struct asm_flg sfm_flags
[] =
382 static CONST
struct asm_flg round_flags
[] =
390 /* The implementation of the FIX instruction is broken on some assemblers,
391 in that it accepts a precision specifier as well as a rounding specifier,
392 despite the fact that this is meaningless. To be more compatible, we
393 accept it as well, though of course it does not set any bits. */
394 static CONST
struct asm_flg fix_flags
[] =
411 static CONST
struct asm_flg except_flag
[] =
417 static CONST
struct asm_flg long_flag
[] =
425 CONST
char * template;
430 /* The bit that distnguishes CPSR and SPSR. */
431 #define SPSR_BIT (1 << 22)
433 /* How many bits to shift the PSR_xxx bits up by. */
436 #define PSR_c (1 << 0)
437 #define PSR_x (1 << 1)
438 #define PSR_s (1 << 2)
439 #define PSR_f (1 << 3)
441 static CONST
struct asm_psr psrs
[] =
443 {"CPSR", true, PSR_c
| PSR_f
},
444 {"CPSR_all", true, PSR_c
| PSR_f
},
445 {"SPSR", false, PSR_c
| PSR_f
},
446 {"SPSR_all", false, PSR_c
| PSR_f
},
447 {"CPSR_flg", true, PSR_f
},
448 {"CPSR_f", true, PSR_f
},
449 {"SPSR_flg", false, PSR_f
},
450 {"SPSR_f", false, PSR_f
},
451 {"CPSR_c", true, PSR_c
},
452 {"CPSR_ctl", true, PSR_c
},
453 {"SPSR_c", false, PSR_c
},
454 {"SPSR_ctl", false, PSR_c
},
455 {"CPSR_x", true, PSR_x
},
456 {"CPSR_s", true, PSR_s
},
457 {"SPSR_x", false, PSR_x
},
458 {"SPSR_s", false, PSR_s
},
459 /* Combinations of flags. */
460 {"CPSR_fs", true, PSR_f
| PSR_s
},
461 {"CPSR_fx", true, PSR_f
| PSR_x
},
462 {"CPSR_fc", true, PSR_f
| PSR_c
},
463 {"CPSR_sf", true, PSR_s
| PSR_f
},
464 {"CPSR_sx", true, PSR_s
| PSR_x
},
465 {"CPSR_sc", true, PSR_s
| PSR_c
},
466 {"CPSR_xf", true, PSR_x
| PSR_f
},
467 {"CPSR_xs", true, PSR_x
| PSR_s
},
468 {"CPSR_xc", true, PSR_x
| PSR_c
},
469 {"CPSR_cf", true, PSR_c
| PSR_f
},
470 {"CPSR_cs", true, PSR_c
| PSR_s
},
471 {"CPSR_cx", true, PSR_c
| PSR_x
},
472 {"CPSR_fsx", true, PSR_f
| PSR_s
| PSR_x
},
473 {"CPSR_fsc", true, PSR_f
| PSR_s
| PSR_c
},
474 {"CPSR_fxs", true, PSR_f
| PSR_x
| PSR_s
},
475 {"CPSR_fxc", true, PSR_f
| PSR_x
| PSR_c
},
476 {"CPSR_fcs", true, PSR_f
| PSR_c
| PSR_s
},
477 {"CPSR_fcx", true, PSR_f
| PSR_c
| PSR_x
},
478 {"CPSR_sfx", true, PSR_s
| PSR_f
| PSR_x
},
479 {"CPSR_sfc", true, PSR_s
| PSR_f
| PSR_c
},
480 {"CPSR_sxf", true, PSR_s
| PSR_x
| PSR_f
},
481 {"CPSR_sxc", true, PSR_s
| PSR_x
| PSR_c
},
482 {"CPSR_scf", true, PSR_s
| PSR_c
| PSR_f
},
483 {"CPSR_scx", true, PSR_s
| PSR_c
| PSR_x
},
484 {"CPSR_xfs", true, PSR_x
| PSR_f
| PSR_s
},
485 {"CPSR_xfc", true, PSR_x
| PSR_f
| PSR_c
},
486 {"CPSR_xsf", true, PSR_x
| PSR_s
| PSR_f
},
487 {"CPSR_xsc", true, PSR_x
| PSR_s
| PSR_c
},
488 {"CPSR_xcf", true, PSR_x
| PSR_c
| PSR_f
},
489 {"CPSR_xcs", true, PSR_x
| PSR_c
| PSR_s
},
490 {"CPSR_cfs", true, PSR_c
| PSR_f
| PSR_s
},
491 {"CPSR_cfx", true, PSR_c
| PSR_f
| PSR_x
},
492 {"CPSR_csf", true, PSR_c
| PSR_s
| PSR_f
},
493 {"CPSR_csx", true, PSR_c
| PSR_s
| PSR_x
},
494 {"CPSR_cxf", true, PSR_c
| PSR_x
| PSR_f
},
495 {"CPSR_cxs", true, PSR_c
| PSR_x
| PSR_s
},
496 {"CPSR_fsxc", true, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
497 {"CPSR_fscx", true, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
498 {"CPSR_fxsc", true, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
499 {"CPSR_fxcs", true, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
500 {"CPSR_fcsx", true, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
501 {"CPSR_fcxs", true, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
502 {"CPSR_sfxc", true, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
503 {"CPSR_sfcx", true, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
504 {"CPSR_sxfc", true, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
505 {"CPSR_sxcf", true, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
506 {"CPSR_scfx", true, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
507 {"CPSR_scxf", true, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
508 {"CPSR_xfsc", true, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
509 {"CPSR_xfcs", true, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
510 {"CPSR_xsfc", true, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
511 {"CPSR_xscf", true, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
512 {"CPSR_xcfs", true, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
513 {"CPSR_xcsf", true, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
514 {"CPSR_cfsx", true, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
515 {"CPSR_cfxs", true, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
516 {"CPSR_csfx", true, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
517 {"CPSR_csxf", true, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
518 {"CPSR_cxfs", true, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
519 {"CPSR_cxsf", true, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
520 {"SPSR_fs", false, PSR_f
| PSR_s
},
521 {"SPSR_fx", false, PSR_f
| PSR_x
},
522 {"SPSR_fc", false, PSR_f
| PSR_c
},
523 {"SPSR_sf", false, PSR_s
| PSR_f
},
524 {"SPSR_sx", false, PSR_s
| PSR_x
},
525 {"SPSR_sc", false, PSR_s
| PSR_c
},
526 {"SPSR_xf", false, PSR_x
| PSR_f
},
527 {"SPSR_xs", false, PSR_x
| PSR_s
},
528 {"SPSR_xc", false, PSR_x
| PSR_c
},
529 {"SPSR_cf", false, PSR_c
| PSR_f
},
530 {"SPSR_cs", false, PSR_c
| PSR_s
},
531 {"SPSR_cx", false, PSR_c
| PSR_x
},
532 {"SPSR_fsx", false, PSR_f
| PSR_s
| PSR_x
},
533 {"SPSR_fsc", false, PSR_f
| PSR_s
| PSR_c
},
534 {"SPSR_fxs", false, PSR_f
| PSR_x
| PSR_s
},
535 {"SPSR_fxc", false, PSR_f
| PSR_x
| PSR_c
},
536 {"SPSR_fcs", false, PSR_f
| PSR_c
| PSR_s
},
537 {"SPSR_fcx", false, PSR_f
| PSR_c
| PSR_x
},
538 {"SPSR_sfx", false, PSR_s
| PSR_f
| PSR_x
},
539 {"SPSR_sfc", false, PSR_s
| PSR_f
| PSR_c
},
540 {"SPSR_sxf", false, PSR_s
| PSR_x
| PSR_f
},
541 {"SPSR_sxc", false, PSR_s
| PSR_x
| PSR_c
},
542 {"SPSR_scf", false, PSR_s
| PSR_c
| PSR_f
},
543 {"SPSR_scx", false, PSR_s
| PSR_c
| PSR_x
},
544 {"SPSR_xfs", false, PSR_x
| PSR_f
| PSR_s
},
545 {"SPSR_xfc", false, PSR_x
| PSR_f
| PSR_c
},
546 {"SPSR_xsf", false, PSR_x
| PSR_s
| PSR_f
},
547 {"SPSR_xsc", false, PSR_x
| PSR_s
| PSR_c
},
548 {"SPSR_xcf", false, PSR_x
| PSR_c
| PSR_f
},
549 {"SPSR_xcs", false, PSR_x
| PSR_c
| PSR_s
},
550 {"SPSR_cfs", false, PSR_c
| PSR_f
| PSR_s
},
551 {"SPSR_cfx", false, PSR_c
| PSR_f
| PSR_x
},
552 {"SPSR_csf", false, PSR_c
| PSR_s
| PSR_f
},
553 {"SPSR_csx", false, PSR_c
| PSR_s
| PSR_x
},
554 {"SPSR_cxf", false, PSR_c
| PSR_x
| PSR_f
},
555 {"SPSR_cxs", false, PSR_c
| PSR_x
| PSR_s
},
556 {"SPSR_fsxc", false, PSR_f
| PSR_s
| PSR_x
| PSR_c
},
557 {"SPSR_fscx", false, PSR_f
| PSR_s
| PSR_c
| PSR_x
},
558 {"SPSR_fxsc", false, PSR_f
| PSR_x
| PSR_s
| PSR_c
},
559 {"SPSR_fxcs", false, PSR_f
| PSR_x
| PSR_c
| PSR_s
},
560 {"SPSR_fcsx", false, PSR_f
| PSR_c
| PSR_s
| PSR_x
},
561 {"SPSR_fcxs", false, PSR_f
| PSR_c
| PSR_x
| PSR_s
},
562 {"SPSR_sfxc", false, PSR_s
| PSR_f
| PSR_x
| PSR_c
},
563 {"SPSR_sfcx", false, PSR_s
| PSR_f
| PSR_c
| PSR_x
},
564 {"SPSR_sxfc", false, PSR_s
| PSR_x
| PSR_f
| PSR_c
},
565 {"SPSR_sxcf", false, PSR_s
| PSR_x
| PSR_c
| PSR_f
},
566 {"SPSR_scfx", false, PSR_s
| PSR_c
| PSR_f
| PSR_x
},
567 {"SPSR_scxf", false, PSR_s
| PSR_c
| PSR_x
| PSR_f
},
568 {"SPSR_xfsc", false, PSR_x
| PSR_f
| PSR_s
| PSR_c
},
569 {"SPSR_xfcs", false, PSR_x
| PSR_f
| PSR_c
| PSR_s
},
570 {"SPSR_xsfc", false, PSR_x
| PSR_s
| PSR_f
| PSR_c
},
571 {"SPSR_xscf", false, PSR_x
| PSR_s
| PSR_c
| PSR_f
},
572 {"SPSR_xcfs", false, PSR_x
| PSR_c
| PSR_f
| PSR_s
},
573 {"SPSR_xcsf", false, PSR_x
| PSR_c
| PSR_s
| PSR_f
},
574 {"SPSR_cfsx", false, PSR_c
| PSR_f
| PSR_s
| PSR_x
},
575 {"SPSR_cfxs", false, PSR_c
| PSR_f
| PSR_x
| PSR_s
},
576 {"SPSR_csfx", false, PSR_c
| PSR_s
| PSR_f
| PSR_x
},
577 {"SPSR_csxf", false, PSR_c
| PSR_s
| PSR_x
| PSR_f
},
578 {"SPSR_cxfs", false, PSR_c
| PSR_x
| PSR_f
| PSR_s
},
579 {"SPSR_cxsf", false, PSR_c
| PSR_x
| PSR_s
| PSR_f
},
582 /* Functions called by parser. */
583 /* ARM instructions. */
584 static void do_arit
PARAMS ((char *, unsigned long));
585 static void do_cmp
PARAMS ((char *, unsigned long));
586 static void do_mov
PARAMS ((char *, unsigned long));
587 static void do_ldst
PARAMS ((char *, unsigned long));
588 static void do_ldmstm
PARAMS ((char *, unsigned long));
589 static void do_branch
PARAMS ((char *, unsigned long));
590 static void do_swi
PARAMS ((char *, unsigned long));
591 /* Pseudo Op codes. */
592 static void do_adr
PARAMS ((char *, unsigned long));
593 static void do_nop
PARAMS ((char *, unsigned long));
595 static void do_mul
PARAMS ((char *, unsigned long));
596 static void do_mla
PARAMS ((char *, unsigned long));
598 static void do_swap
PARAMS ((char *, unsigned long));
600 static void do_msr
PARAMS ((char *, unsigned long));
601 static void do_mrs
PARAMS ((char *, unsigned long));
603 static void do_mull
PARAMS ((char *, unsigned long));
605 static void do_bx
PARAMS ((char *, unsigned long));
607 /* ARM_EXT_XScale. */
608 static void do_mia
PARAMS ((char *, unsigned long));
609 static void do_mar
PARAMS ((char *, unsigned long));
610 static void do_mra
PARAMS ((char *, unsigned long));
611 static void do_pld
PARAMS ((char *, unsigned long));
612 static void do_ldrd
PARAMS ((char *, unsigned long));
615 static void do_blx
PARAMS ((char *, unsigned long));
616 static void do_bkpt
PARAMS ((char *, unsigned long));
617 static void do_clz
PARAMS ((char *, unsigned long));
618 static void do_lstc2
PARAMS ((char *, unsigned long));
619 static void do_cdp2
PARAMS ((char *, unsigned long));
620 static void do_co_reg2
PARAMS ((char *, unsigned long));
622 static void do_t_blx
PARAMS ((char *));
623 static void do_t_bkpt
PARAMS ((char *));
626 static void do_smla
PARAMS ((char *, unsigned long));
627 static void do_smlal
PARAMS ((char *, unsigned long));
628 static void do_smul
PARAMS ((char *, unsigned long));
629 static void do_qadd
PARAMS ((char *, unsigned long));
630 static void do_co_reg2c
PARAMS ((char *, unsigned long));
632 /* Coprocessor Instructions. */
633 static void do_cdp
PARAMS ((char *, unsigned long));
634 static void do_lstc
PARAMS ((char *, unsigned long));
635 static void do_co_reg
PARAMS ((char *, unsigned long));
636 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
637 static void do_fp_ldst
PARAMS ((char *, unsigned long));
638 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
639 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
640 static void do_fp_monadic
PARAMS ((char *, unsigned long));
641 static void do_fp_cmp
PARAMS ((char *, unsigned long));
642 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
643 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
645 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
646 static int arm_reg_parse
PARAMS ((char **));
647 static CONST
struct asm_psr
* arm_psr_parse
PARAMS ((char **));
648 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
649 static int add_to_lit_pool
PARAMS ((void));
650 static unsigned validate_immediate
PARAMS ((unsigned));
651 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
652 static int validate_offset_imm
PARAMS ((unsigned int, int));
653 static void opcode_select
PARAMS ((int));
654 static void end_of_line
PARAMS ((char *));
655 static int reg_required_here
PARAMS ((char **, int));
656 static int psr_required_here
PARAMS ((char **));
657 static int co_proc_number
PARAMS ((char **));
658 static int cp_opc_expr
PARAMS ((char **, int, int));
659 static int cp_reg_required_here
PARAMS ((char **, int));
660 static int fp_reg_required_here
PARAMS ((char **, int));
661 static int cp_address_offset
PARAMS ((char **));
662 static int cp_address_required_here
PARAMS ((char **));
663 static int my_get_float_expression
PARAMS ((char **));
664 static int skip_past_comma
PARAMS ((char **));
665 static int walk_no_bignums
PARAMS ((symbolS
*));
666 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
667 static int data_op2
PARAMS ((char **));
668 static int fp_op2
PARAMS ((char **));
669 static long reg_list
PARAMS ((char **));
670 static void thumb_load_store
PARAMS ((char *, int, int));
671 static int decode_shift
PARAMS ((char **, int));
672 static int ldst_extend
PARAMS ((char **, int));
673 static void thumb_add_sub
PARAMS ((char *, int));
674 static void insert_reg
PARAMS ((int));
675 static void thumb_shift
PARAMS ((char *, int));
676 static void thumb_mov_compare
PARAMS ((char *, int));
677 static void set_constant_flonums
PARAMS ((void));
678 static valueT md_chars_to_number
PARAMS ((char *, int));
679 static void insert_reg_alias
PARAMS ((char *, int));
680 static void output_inst
PARAMS ((void));
681 static int accum0_required_here
PARAMS ((char **));
682 static int ld_mode_required_here
PARAMS ((char **));
683 static void do_branch25
PARAMS ((char *, unsigned long));
684 static symbolS
* find_real_start
PARAMS ((symbolS
*));
686 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
689 /* ARM instructions take 4bytes in the object file, Thumb instructions
693 /* LONGEST_INST is the longest basic instruction name without
694 conditions or flags. ARM7M has 4 of length 5. El Segundo
695 has one basic instruction name of length 7 (SMLALxy). */
696 #define LONGEST_INST 7
700 /* Basic string to match. */
701 CONST
char * template;
703 /* Basic instruction code. */
706 /* Compulsory suffix that must follow conds. If "", then the
707 instruction is not conditional and must have no suffix. */
708 CONST
char * comp_suffix
;
710 /* Bits to toggle if flag 'n' set. */
711 CONST
struct asm_flg
* flags
;
713 /* Which CPU variants this exists for. */
714 unsigned long variants
;
716 /* Function to call to parse args. */
717 void (* parms
) PARAMS ((char *, unsigned long));
720 static CONST
struct asm_opcode insns
[] =
722 /* Intel XScale extensions to ARM V5 ISA. */
723 {"mia", 0x0e200010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
724 {"miaph", 0x0e280010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
725 {"miabb", 0x0e2c0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
726 {"miabt", 0x0e2d0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
727 {"miatb", 0x0e2e0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
728 {"miatt", 0x0e2f0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
729 {"mar", 0x0c400000, NULL
, NULL
, ARM_EXT_XSCALE
, do_mar
},
730 {"mra", 0x0c500000, NULL
, NULL
, ARM_EXT_XSCALE
, do_mra
},
731 {"pld", 0xf450f000, "", NULL
, ARM_EXT_XSCALE
, do_pld
},
732 {"ldr", 0x000000d0, NULL
, ldr_flags
, ARM_ANY
, do_ldrd
},
733 {"str", 0x000000f0, NULL
, str_flags
, ARM_ANY
, do_ldrd
},
735 /* ARM Instructions. */
736 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
737 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
738 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
739 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
740 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
741 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
742 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
743 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
744 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
745 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
746 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
747 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
748 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
749 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
750 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
751 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
752 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
753 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
754 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
755 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
756 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
758 {"bl", 0x0b000000, NULL
, NULL
, ARM_ANY
, do_branch
},
759 {"b", 0x0a000000, NULL
, NULL
, ARM_ANY
, do_branch
},
761 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
762 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
766 {"adr", 0x028f0000, NULL
, long_flag
, ARM_ANY
, do_adr
},
767 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
769 /* ARM 2 multiplies. */
770 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
771 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
773 /* ARM 3 - swp instructions. */
774 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
776 /* ARM 6 Coprocessor instructions. */
777 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
778 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
779 /* ScottB: our code uses 0x0128f000 for msr.
780 NickC: but this is wrong because the bits 16 through 19 are
781 handled by the PSR_xxx defines above. */
783 /* ARM 7M long multiplies - need signed/unsigned flags! */
784 {"smull", 0x00c00090, NULL
, s_flag
, ARM_EXT_LONGMUL
, do_mull
},
785 {"umull", 0x00800090, NULL
, s_flag
, ARM_EXT_LONGMUL
, do_mull
},
786 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_EXT_LONGMUL
, do_mull
},
787 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_EXT_LONGMUL
, do_mull
},
789 /* ARM THUMB interworking. */
790 {"bx", 0x012fff10, NULL
, NULL
, ARM_EXT_THUMB
, do_bx
},
792 /* Floating point instructions. */
793 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
794 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
795 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
796 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
797 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
798 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
799 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
800 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
801 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
802 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
803 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
804 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
805 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
806 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
807 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
808 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
809 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
810 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
811 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
812 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
813 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
814 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
815 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
816 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
817 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
818 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
819 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
820 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
821 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
822 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
823 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
824 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
825 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
826 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
827 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
828 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
829 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
830 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
831 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
832 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
833 be an optional suffix, but part of the instruction. To be compatible,
835 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
836 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
837 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
838 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
840 /* Generic copressor instructions. */
841 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
842 {"ldc", 0x0c100000, NULL
, long_flag
, ARM_2UP
, do_lstc
},
843 {"stc", 0x0c000000, NULL
, long_flag
, ARM_2UP
, do_lstc
},
844 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
845 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
847 /* ARM ISA extension 5. */
848 /* Note: blx is actually 2 opcodes, so the .value is set dynamically.
849 And it's sometimes conditional and sometimes not. */
850 {"blx", 0, NULL
, NULL
, ARM_EXT_V5
, do_blx
},
851 {"clz", 0x016f0f10, NULL
, NULL
, ARM_EXT_V5
, do_clz
},
852 {"bkpt", 0xe1200070, "", NULL
, ARM_EXT_V5
, do_bkpt
},
853 {"ldc2", 0xfc100000, "", long_flag
, ARM_EXT_V5
, do_lstc2
},
854 {"stc2", 0xfc000000, "", long_flag
, ARM_EXT_V5
, do_lstc2
},
855 {"cdp2", 0xfe000000, "", NULL
, ARM_EXT_V5
, do_cdp2
},
856 {"mcr2", 0xfe000010, "", NULL
, ARM_EXT_V5
, do_co_reg2
},
857 {"mrc2", 0xfe100010, "", NULL
, ARM_EXT_V5
, do_co_reg2
},
859 /* ARM ISA extension 5E, El Segundo. */
860 {"smlabb", 0x01000080, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
861 {"smlatb", 0x010000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
862 {"smlabt", 0x010000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
863 {"smlatt", 0x010000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
865 {"smlawb", 0x01200080, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
866 {"smlawt", 0x012000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
868 {"smlalbb",0x01400080, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
869 {"smlaltb",0x014000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
870 {"smlalbt",0x014000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
871 {"smlaltt",0x014000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
873 {"smulbb", 0x01600080, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
874 {"smultb", 0x016000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
875 {"smulbt", 0x016000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
876 {"smultt", 0x016000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
878 {"smulwb", 0x012000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
879 {"smulwt", 0x012000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
881 {"qadd", 0x01000050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
882 {"qdadd", 0x01400050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
883 {"qsub", 0x01200050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
884 {"qdsub", 0x01600050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
886 {"mcrr", 0x0c400000, NULL
, NULL
, ARM_EXT_V5E
, do_co_reg2c
},
887 {"mrrc", 0x0c500000, NULL
, NULL
, ARM_EXT_V5E
, do_co_reg2c
},
890 /* Defines for various bits that we will want to toggle. */
891 #define INST_IMMEDIATE 0x02000000
892 #define OFFSET_REG 0x02000000
893 #define HWOFFSET_IMM 0x00400000
894 #define SHIFT_BY_REG 0x00000010
895 #define PRE_INDEX 0x01000000
896 #define INDEX_UP 0x00800000
897 #define WRITE_BACK 0x00200000
898 #define LDM_TYPE_2_OR_3 0x00400000
900 #define LITERAL_MASK 0xf000f000
901 #define COND_MASK 0xf0000000
902 #define OPCODE_MASK 0xfe1fffff
903 #define DATA_OP_SHIFT 21
905 /* Codes to distinguish the arithmetic instructions. */
916 #define OPCODE_CMP 10
917 #define OPCODE_CMN 11
918 #define OPCODE_ORR 12
919 #define OPCODE_MOV 13
920 #define OPCODE_BIC 14
921 #define OPCODE_MVN 15
923 static void do_t_nop
PARAMS ((char *));
924 static void do_t_arit
PARAMS ((char *));
925 static void do_t_add
PARAMS ((char *));
926 static void do_t_asr
PARAMS ((char *));
927 static void do_t_branch9
PARAMS ((char *));
928 static void do_t_branch12
PARAMS ((char *));
929 static void do_t_branch23
PARAMS ((char *));
930 static void do_t_bx
PARAMS ((char *));
931 static void do_t_compare
PARAMS ((char *));
932 static void do_t_ldmstm
PARAMS ((char *));
933 static void do_t_ldr
PARAMS ((char *));
934 static void do_t_ldrb
PARAMS ((char *));
935 static void do_t_ldrh
PARAMS ((char *));
936 static void do_t_lds
PARAMS ((char *));
937 static void do_t_lsl
PARAMS ((char *));
938 static void do_t_lsr
PARAMS ((char *));
939 static void do_t_mov
PARAMS ((char *));
940 static void do_t_push_pop
PARAMS ((char *));
941 static void do_t_str
PARAMS ((char *));
942 static void do_t_strb
PARAMS ((char *));
943 static void do_t_strh
PARAMS ((char *));
944 static void do_t_sub
PARAMS ((char *));
945 static void do_t_swi
PARAMS ((char *));
946 static void do_t_adr
PARAMS ((char *));
948 #define T_OPCODE_MUL 0x4340
949 #define T_OPCODE_TST 0x4200
950 #define T_OPCODE_CMN 0x42c0
951 #define T_OPCODE_NEG 0x4240
952 #define T_OPCODE_MVN 0x43c0
954 #define T_OPCODE_ADD_R3 0x1800
955 #define T_OPCODE_SUB_R3 0x1a00
956 #define T_OPCODE_ADD_HI 0x4400
957 #define T_OPCODE_ADD_ST 0xb000
958 #define T_OPCODE_SUB_ST 0xb080
959 #define T_OPCODE_ADD_SP 0xa800
960 #define T_OPCODE_ADD_PC 0xa000
961 #define T_OPCODE_ADD_I8 0x3000
962 #define T_OPCODE_SUB_I8 0x3800
963 #define T_OPCODE_ADD_I3 0x1c00
964 #define T_OPCODE_SUB_I3 0x1e00
966 #define T_OPCODE_ASR_R 0x4100
967 #define T_OPCODE_LSL_R 0x4080
968 #define T_OPCODE_LSR_R 0x40c0
969 #define T_OPCODE_ASR_I 0x1000
970 #define T_OPCODE_LSL_I 0x0000
971 #define T_OPCODE_LSR_I 0x0800
973 #define T_OPCODE_MOV_I8 0x2000
974 #define T_OPCODE_CMP_I8 0x2800
975 #define T_OPCODE_CMP_LR 0x4280
976 #define T_OPCODE_MOV_HR 0x4600
977 #define T_OPCODE_CMP_HR 0x4500
979 #define T_OPCODE_LDR_PC 0x4800
980 #define T_OPCODE_LDR_SP 0x9800
981 #define T_OPCODE_STR_SP 0x9000
982 #define T_OPCODE_LDR_IW 0x6800
983 #define T_OPCODE_STR_IW 0x6000
984 #define T_OPCODE_LDR_IH 0x8800
985 #define T_OPCODE_STR_IH 0x8000
986 #define T_OPCODE_LDR_IB 0x7800
987 #define T_OPCODE_STR_IB 0x7000
988 #define T_OPCODE_LDR_RW 0x5800
989 #define T_OPCODE_STR_RW 0x5000
990 #define T_OPCODE_LDR_RH 0x5a00
991 #define T_OPCODE_STR_RH 0x5200
992 #define T_OPCODE_LDR_RB 0x5c00
993 #define T_OPCODE_STR_RB 0x5400
995 #define T_OPCODE_PUSH 0xb400
996 #define T_OPCODE_POP 0xbc00
998 #define T_OPCODE_BRANCH 0xe7fe
1000 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
1002 #define THUMB_SIZE 2 /* Size of thumb instruction. */
1003 #define THUMB_REG_LO 0x1
1004 #define THUMB_REG_HI 0x2
1005 #define THUMB_REG_ANY 0x3
1007 #define THUMB_H1 0x0080
1008 #define THUMB_H2 0x0040
1014 #define THUMB_MOVE 0
1015 #define THUMB_COMPARE 1
1017 #define THUMB_LOAD 0
1018 #define THUMB_STORE 1
1020 #define THUMB_PP_PC_LR 0x0100
1022 /* These three are used for immediate shifts, do not alter. */
1023 #define THUMB_WORD 2
1024 #define THUMB_HALFWORD 1
1025 #define THUMB_BYTE 0
1029 /* Basic string to match. */
1030 CONST
char * template;
1032 /* Basic instruction code. */
1033 unsigned long value
;
1037 /* Which CPU variants this exists for. */
1038 unsigned long variants
;
1040 /* Function to call to parse args. */
1041 void (* parms
) PARAMS ((char *));
1044 static CONST
struct thumb_opcode tinsns
[] =
1046 {"adc", 0x4140, 2, ARM_EXT_THUMB
, do_t_arit
},
1047 {"add", 0x0000, 2, ARM_EXT_THUMB
, do_t_add
},
1048 {"and", 0x4000, 2, ARM_EXT_THUMB
, do_t_arit
},
1049 {"asr", 0x0000, 2, ARM_EXT_THUMB
, do_t_asr
},
1050 {"b", T_OPCODE_BRANCH
, 2, ARM_EXT_THUMB
, do_t_branch12
},
1051 {"beq", 0xd0fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1052 {"bne", 0xd1fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1053 {"bcs", 0xd2fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1054 {"bhs", 0xd2fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1055 {"bcc", 0xd3fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1056 {"bul", 0xd3fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1057 {"blo", 0xd3fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1058 {"bmi", 0xd4fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1059 {"bpl", 0xd5fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1060 {"bvs", 0xd6fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1061 {"bvc", 0xd7fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1062 {"bhi", 0xd8fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1063 {"bls", 0xd9fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1064 {"bge", 0xdafe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1065 {"blt", 0xdbfe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1066 {"bgt", 0xdcfe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1067 {"ble", 0xddfe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1068 {"bal", 0xdefe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1069 {"bic", 0x4380, 2, ARM_EXT_THUMB
, do_t_arit
},
1070 {"bl", 0xf7fffffe, 4, ARM_EXT_THUMB
, do_t_branch23
},
1071 {"blx", 0, 0, ARM_EXT_V5
, do_t_blx
},
1072 {"bkpt", 0xbe00, 2, ARM_EXT_V5
, do_t_bkpt
},
1073 {"bx", 0x4700, 2, ARM_EXT_THUMB
, do_t_bx
},
1074 {"cmn", T_OPCODE_CMN
, 2, ARM_EXT_THUMB
, do_t_arit
},
1075 {"cmp", 0x0000, 2, ARM_EXT_THUMB
, do_t_compare
},
1076 {"eor", 0x4040, 2, ARM_EXT_THUMB
, do_t_arit
},
1077 {"ldmia", 0xc800, 2, ARM_EXT_THUMB
, do_t_ldmstm
},
1078 {"ldr", 0x0000, 2, ARM_EXT_THUMB
, do_t_ldr
},
1079 {"ldrb", 0x0000, 2, ARM_EXT_THUMB
, do_t_ldrb
},
1080 {"ldrh", 0x0000, 2, ARM_EXT_THUMB
, do_t_ldrh
},
1081 {"ldrsb", 0x5600, 2, ARM_EXT_THUMB
, do_t_lds
},
1082 {"ldrsh", 0x5e00, 2, ARM_EXT_THUMB
, do_t_lds
},
1083 {"ldsb", 0x5600, 2, ARM_EXT_THUMB
, do_t_lds
},
1084 {"ldsh", 0x5e00, 2, ARM_EXT_THUMB
, do_t_lds
},
1085 {"lsl", 0x0000, 2, ARM_EXT_THUMB
, do_t_lsl
},
1086 {"lsr", 0x0000, 2, ARM_EXT_THUMB
, do_t_lsr
},
1087 {"mov", 0x0000, 2, ARM_EXT_THUMB
, do_t_mov
},
1088 {"mul", T_OPCODE_MUL
, 2, ARM_EXT_THUMB
, do_t_arit
},
1089 {"mvn", T_OPCODE_MVN
, 2, ARM_EXT_THUMB
, do_t_arit
},
1090 {"neg", T_OPCODE_NEG
, 2, ARM_EXT_THUMB
, do_t_arit
},
1091 {"orr", 0x4300, 2, ARM_EXT_THUMB
, do_t_arit
},
1092 {"pop", 0xbc00, 2, ARM_EXT_THUMB
, do_t_push_pop
},
1093 {"push", 0xb400, 2, ARM_EXT_THUMB
, do_t_push_pop
},
1094 {"ror", 0x41c0, 2, ARM_EXT_THUMB
, do_t_arit
},
1095 {"sbc", 0x4180, 2, ARM_EXT_THUMB
, do_t_arit
},
1096 {"stmia", 0xc000, 2, ARM_EXT_THUMB
, do_t_ldmstm
},
1097 {"str", 0x0000, 2, ARM_EXT_THUMB
, do_t_str
},
1098 {"strb", 0x0000, 2, ARM_EXT_THUMB
, do_t_strb
},
1099 {"strh", 0x0000, 2, ARM_EXT_THUMB
, do_t_strh
},
1100 {"swi", 0xdf00, 2, ARM_EXT_THUMB
, do_t_swi
},
1101 {"sub", 0x0000, 2, ARM_EXT_THUMB
, do_t_sub
},
1102 {"tst", T_OPCODE_TST
, 2, ARM_EXT_THUMB
, do_t_arit
},
1104 {"adr", 0x0000, 2, ARM_EXT_THUMB
, do_t_adr
},
1105 {"nop", 0x46C0, 2, ARM_EXT_THUMB
, do_t_nop
}, /* mov r8,r8 */
1114 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
1115 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
1116 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
1122 /* These are the standard names. Users can add aliases with .req. */
1123 static CONST
struct reg_entry reg_table
[] =
1125 /* Processor Register Numbers. */
1126 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
1127 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
1128 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
1129 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
1130 /* APCS conventions. */
1131 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
1132 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
1133 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
1134 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
1135 /* ATPCS additions to APCS conventions. */
1136 {"wr", 7}, {"v8", 11},
1138 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
1139 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
1140 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
1141 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
1142 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
1143 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
1144 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
1145 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
1146 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
1147 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1148 /* ATPCS additions to float register names. */
1149 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
1150 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
1151 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
1152 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
1153 /* FIXME: At some point we need to add VFP register names. */
1154 /* Array terminator. */
1158 #define BAD_ARGS _("Bad arguments to instruction")
1159 #define BAD_PC _("r15 not allowed here")
1160 #define BAD_FLAGS _("Instruction should not have flags")
1161 #define BAD_COND _("Instruction is not conditional")
1162 #define ERR_NO_ACCUM _("acc0 expected")
1164 static struct hash_control
* arm_ops_hsh
= NULL
;
1165 static struct hash_control
* arm_tops_hsh
= NULL
;
1166 static struct hash_control
* arm_cond_hsh
= NULL
;
1167 static struct hash_control
* arm_shift_hsh
= NULL
;
1168 static struct hash_control
* arm_reg_hsh
= NULL
;
1169 static struct hash_control
* arm_psr_hsh
= NULL
;
1171 /* This table describes all the machine specific pseudo-ops the assembler
1172 has to support. The fields are:
1173 pseudo-op name without dot
1174 function to call to execute this pseudo-op
1175 Integer arg to pass to the function. */
1177 static void s_req
PARAMS ((int));
1178 static void s_align
PARAMS ((int));
1179 static void s_bss
PARAMS ((int));
1180 static void s_even
PARAMS ((int));
1181 static void s_ltorg
PARAMS ((int));
1182 static void s_arm
PARAMS ((int));
1183 static void s_thumb
PARAMS ((int));
1184 static void s_code
PARAMS ((int));
1185 static void s_force_thumb
PARAMS ((int));
1186 static void s_thumb_func
PARAMS ((int));
1187 static void s_thumb_set
PARAMS ((int));
1188 static void arm_s_text
PARAMS ((int));
1189 static void arm_s_data
PARAMS ((int));
1191 static void arm_s_section
PARAMS ((int));
1192 static void s_arm_elf_cons
PARAMS ((int));
1195 static int my_get_expression
PARAMS ((expressionS
*, char **));
1197 CONST pseudo_typeS md_pseudo_table
[] =
1199 /* Never called becasue '.req' does not start line. */
1200 { "req", s_req
, 0 },
1201 { "bss", s_bss
, 0 },
1202 { "align", s_align
, 0 },
1203 { "arm", s_arm
, 0 },
1204 { "thumb", s_thumb
, 0 },
1205 { "code", s_code
, 0 },
1206 { "force_thumb", s_force_thumb
, 0 },
1207 { "thumb_func", s_thumb_func
, 0 },
1208 { "thumb_set", s_thumb_set
, 0 },
1209 { "even", s_even
, 0 },
1210 { "ltorg", s_ltorg
, 0 },
1211 { "pool", s_ltorg
, 0 },
1212 /* Allow for the effect of section changes. */
1213 { "text", arm_s_text
, 0 },
1214 { "data", arm_s_data
, 0 },
1216 { "section", arm_s_section
, 0 },
1217 { "section.s", arm_s_section
, 0 },
1218 { "sect", arm_s_section
, 0 },
1219 { "sect.s", arm_s_section
, 0 },
1220 { "word", s_arm_elf_cons
, 4 },
1221 { "long", s_arm_elf_cons
, 4 },
1222 { "file", dwarf2_directive_file
, 0 },
1223 { "loc", dwarf2_directive_loc
, 0 },
1227 { "extend", float_cons
, 'x' },
1228 { "ldouble", float_cons
, 'x' },
1229 { "packed", float_cons
, 'p' },
1233 /* Stuff needed to resolve the label ambiguity
1243 symbolS
* last_label_seen
;
1244 static int label_is_thumb_function_name
= false;
1246 /* Literal stuff. */
1248 #define MAX_LITERAL_POOL_SIZE 1024
1250 typedef struct literalS
1252 struct expressionS exp
;
1253 struct arm_it
* inst
;
1256 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1258 /* Next free entry in the pool. */
1259 int next_literal_pool_place
= 0;
1261 /* Next literal pool number. */
1262 int lit_pool_num
= 1;
1264 symbolS
* current_poolP
= NULL
;
1271 if (current_poolP
== NULL
)
1272 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1273 (valueT
) 0, &zero_address_frag
);
1275 /* Check if this literal value is already in the pool: */
1276 while (lit_count
< next_literal_pool_place
)
1278 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1279 && inst
.reloc
.exp
.X_op
== O_constant
1280 && (literals
[lit_count
].exp
.X_add_number
1281 == inst
.reloc
.exp
.X_add_number
)
1282 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1285 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1286 && inst
.reloc
.exp
.X_op
== O_symbol
1287 && (literals
[lit_count
].exp
.X_add_number
1288 == inst
.reloc
.exp
.X_add_number
)
1289 && (literals
[lit_count
].exp
.X_add_symbol
1290 == inst
.reloc
.exp
.X_add_symbol
)
1291 && (literals
[lit_count
].exp
.X_op_symbol
1292 == inst
.reloc
.exp
.X_op_symbol
))
1298 if (lit_count
== next_literal_pool_place
) /* New entry. */
1300 if (next_literal_pool_place
>= MAX_LITERAL_POOL_SIZE
)
1302 inst
.error
= _("Literal Pool Overflow");
1306 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1307 lit_count
= next_literal_pool_place
++;
1310 inst
.reloc
.exp
.X_op
= O_symbol
;
1311 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1312 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1317 /* Can't use symbol_new here, so have to create a symbol and then at
1318 a later date assign it a value. Thats what these functions do. */
1321 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1323 CONST
char * name
; /* It is copied, the caller can modify. */
1324 segT segment
; /* Segment identifier (SEG_<something>). */
1325 valueT valu
; /* Symbol value. */
1326 fragS
* frag
; /* Associated fragment. */
1328 unsigned int name_length
;
1329 char * preserved_copy_of_name
;
1331 name_length
= strlen (name
) + 1; /* +1 for \0. */
1332 obstack_grow (¬es
, name
, name_length
);
1333 preserved_copy_of_name
= obstack_finish (¬es
);
1334 #ifdef STRIP_UNDERSCORE
1335 if (preserved_copy_of_name
[0] == '_')
1336 preserved_copy_of_name
++;
1339 #ifdef tc_canonicalize_symbol_name
1340 preserved_copy_of_name
=
1341 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1344 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1346 S_SET_SEGMENT (symbolP
, segment
);
1347 S_SET_VALUE (symbolP
, valu
);
1348 symbol_clear_list_pointers(symbolP
);
1350 symbol_set_frag (symbolP
, frag
);
1352 /* Link to end of symbol chain. */
1354 extern int symbol_table_frozen
;
1355 if (symbol_table_frozen
)
1359 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1361 obj_symbol_new_hook (symbolP
);
1363 #ifdef tc_symbol_new_hook
1364 tc_symbol_new_hook (symbolP
);
1368 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1369 #endif /* DEBUG_SYMS */
1372 /* Check that an immediate is valid.
1373 If so, convert it to the right format. */
1376 validate_immediate (val
)
1382 #define rotate_left(v, n) (v << n | v >> (32 - n))
1384 for (i
= 0; i
< 32; i
+= 2)
1385 if ((a
= rotate_left (val
, i
)) <= 0xff)
1386 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
1391 /* Check to see if an immediate can be computed as two seperate immediate
1392 values, added together. We already know that this value cannot be
1393 computed by just one ARM instruction. */
1396 validate_immediate_twopart (val
, highpart
)
1398 unsigned int * highpart
;
1403 for (i
= 0; i
< 32; i
+= 2)
1404 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1410 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1412 else if (a
& 0xff0000)
1416 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1420 assert (a
& 0xff000000);
1421 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1424 return (a
& 0xff) | (i
<< 7);
1431 validate_offset_imm (val
, hwse
)
1435 if ((hwse
&& val
> 255) || val
> 4095)
1442 int a ATTRIBUTE_UNUSED
;
1444 as_bad (_("Invalid syntax for .req directive."));
1449 int ignore ATTRIBUTE_UNUSED
;
1451 /* We don't support putting frags in the BSS segment, we fake it by
1452 marking in_bss, then looking at s_skip for clues. */
1453 subseg_set (bss_section
, 0);
1454 demand_empty_rest_of_line ();
1459 int ignore ATTRIBUTE_UNUSED
;
1461 /* Never make frag if expect extra pass. */
1463 frag_align (1, 0, 0);
1465 record_alignment (now_seg
, 1);
1467 demand_empty_rest_of_line ();
1472 int ignored ATTRIBUTE_UNUSED
;
1477 if (current_poolP
== NULL
)
1480 /* Align pool as you have word accesses.
1481 Only make a frag if we have to. */
1483 frag_align (2, 0, 0);
1485 record_alignment (now_seg
, 2);
1487 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1489 symbol_locate (current_poolP
, sym_name
, now_seg
,
1490 (valueT
) frag_now_fix (), frag_now
);
1491 symbol_table_insert (current_poolP
);
1493 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1495 #if defined OBJ_COFF || defined OBJ_ELF
1496 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1499 while (lit_count
< next_literal_pool_place
)
1500 /* First output the expression in the instruction to the pool. */
1501 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1503 next_literal_pool_place
= 0;
1504 current_poolP
= NULL
;
1507 /* Same as s_align_ptwo but align 0 => align 2. */
1511 int unused ATTRIBUTE_UNUSED
;
1514 register long temp_fill
;
1515 long max_alignment
= 15;
1517 temp
= get_absolute_expression ();
1518 if (temp
> max_alignment
)
1519 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1522 as_bad (_("Alignment negative. 0 assumed."));
1526 if (*input_line_pointer
== ',')
1528 input_line_pointer
++;
1529 temp_fill
= get_absolute_expression ();
1537 /* Only make a frag if we HAVE to. */
1538 if (temp
&& !need_pass_2
)
1539 frag_align (temp
, (int) temp_fill
, 0);
1540 demand_empty_rest_of_line ();
1542 record_alignment (now_seg
, temp
);
1546 s_force_thumb (ignore
)
1547 int ignore ATTRIBUTE_UNUSED
;
1549 /* If we are not already in thumb mode go into it, EVEN if
1550 the target processor does not support thumb instructions.
1551 This is used by gcc/config/arm/lib1funcs.asm for example
1552 to compile interworking support functions even if the
1553 target processor should not support interworking. */
1558 record_alignment (now_seg
, 1);
1561 demand_empty_rest_of_line ();
1565 s_thumb_func (ignore
)
1566 int ignore ATTRIBUTE_UNUSED
;
1571 /* The following label is the name/address of the start of a Thumb function.
1572 We need to know this for the interworking support. */
1573 label_is_thumb_function_name
= true;
1575 demand_empty_rest_of_line ();
1578 /* Perform a .set directive, but also mark the alias as
1579 being a thumb function. */
1585 /* XXX the following is a duplicate of the code for s_set() in read.c
1586 We cannot just call that code as we need to get at the symbol that
1588 register char * name
;
1589 register char delim
;
1590 register char * end_name
;
1591 register symbolS
* symbolP
;
1593 /* Especial apologies for the random logic:
1594 This just grew, and could be parsed much more simply!
1596 name
= input_line_pointer
;
1597 delim
= get_symbol_end ();
1598 end_name
= input_line_pointer
;
1603 if (*input_line_pointer
!= ',')
1606 as_bad (_("Expected comma after name \"%s\""), name
);
1608 ignore_rest_of_line ();
1612 input_line_pointer
++;
1615 if (name
[0] == '.' && name
[1] == '\0')
1617 /* XXX - this should not happen to .thumb_set. */
1621 if ((symbolP
= symbol_find (name
)) == NULL
1622 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1625 /* When doing symbol listings, play games with dummy fragments living
1626 outside the normal fragment chain to record the file and line info
1628 if (listing
& LISTING_SYMBOLS
)
1630 extern struct list_info_struct
* listing_tail
;
1631 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
1633 memset (dummy_frag
, 0, sizeof (fragS
));
1634 dummy_frag
->fr_type
= rs_fill
;
1635 dummy_frag
->line
= listing_tail
;
1636 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1637 dummy_frag
->fr_symbol
= symbolP
;
1641 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1644 /* "set" symbols are local unless otherwise specified. */
1645 SF_SET_LOCAL (symbolP
);
1646 #endif /* OBJ_COFF */
1647 } /* Make a new symbol. */
1649 symbol_table_insert (symbolP
);
1654 && S_IS_DEFINED (symbolP
)
1655 && S_GET_SEGMENT (symbolP
) != reg_section
)
1656 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1658 pseudo_set (symbolP
);
1660 demand_empty_rest_of_line ();
1662 /* XXX Now we come to the Thumb specific bit of code. */
1664 THUMB_SET_FUNC (symbolP
, 1);
1665 ARM_SET_THUMB (symbolP
, 1);
1666 #if defined OBJ_ELF || defined OBJ_COFF
1667 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1671 /* If we change section we must dump the literal pool first. */
1677 if (now_seg
!= text_section
)
1681 obj_elf_text (ignore
);
1691 if (flag_readonly_data_in_text
)
1693 if (now_seg
!= text_section
)
1696 else if (now_seg
!= data_section
)
1700 obj_elf_data (ignore
);
1708 arm_s_section (ignore
)
1713 obj_elf_section (ignore
);
1718 opcode_select (width
)
1726 if (! (cpu_variant
& ARM_EXT_THUMB
))
1727 as_bad (_("selected processor does not support THUMB opcodes"));
1730 /* No need to force the alignment, since we will have been
1731 coming from ARM mode, which is word-aligned. */
1732 record_alignment (now_seg
, 1);
1739 if ((cpu_variant
& ARM_ANY
) == ARM_EXT_THUMB
)
1740 as_bad (_("selected processor does not support ARM opcodes"));
1745 frag_align (2, 0, 0);
1747 record_alignment (now_seg
, 1);
1752 as_bad (_("invalid instruction size selected (%d)"), width
);
1758 int ignore ATTRIBUTE_UNUSED
;
1761 demand_empty_rest_of_line ();
1766 int ignore ATTRIBUTE_UNUSED
;
1769 demand_empty_rest_of_line ();
1774 int unused ATTRIBUTE_UNUSED
;
1778 temp
= get_absolute_expression ();
1783 opcode_select (temp
);
1787 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1795 skip_whitespace (str
);
1798 inst
.error
= _("Garbage following instruction");
1802 skip_past_comma (str
)
1805 char * p
= * str
, c
;
1808 while ((c
= *p
) == ' ' || c
== ',')
1811 if (c
== ',' && comma
++)
1819 return comma
? SUCCESS
: FAIL
;
1822 /* A standard register must be given at this point.
1823 SHIFT is the place to put it in inst.instruction.
1824 Restores input start point on error.
1825 Returns the reg#, or FAIL. */
1828 reg_required_here (str
, shift
)
1832 static char buff
[128]; /* XXX */
1834 char * start
= * str
;
1836 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1839 inst
.instruction
|= reg
<< shift
;
1843 /* Restore the start point, we may have got a reg of the wrong class. */
1846 /* In the few cases where we might be able to accept something else
1847 this error can be overridden. */
1848 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1854 static CONST
struct asm_psr
*
1856 register char ** ccp
;
1858 char * start
= * ccp
;
1861 CONST
struct asm_psr
* psr
;
1865 /* Skip to the end of the next word in the input stream. */
1870 while (ISALPHA (c
) || c
== '_');
1872 /* Terminate the word. */
1875 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
1876 feature for ease of use and backwards compatibility. */
1877 if (!strncmp (start
, "cpsr", 4))
1878 strncpy (start
, "CPSR", 4);
1879 else if (!strncmp (start
, "spsr", 4))
1880 strncpy (start
, "SPSR", 4);
1882 /* Now locate the word in the psr hash table. */
1883 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
1885 /* Restore the input stream. */
1888 /* If we found a valid match, advance the
1889 stream pointer past the end of the word. */
1895 /* Parse the input looking for a PSR flag. */
1898 psr_required_here (str
)
1901 char * start
= * str
;
1902 CONST
struct asm_psr
* psr
;
1904 psr
= arm_psr_parse (str
);
1908 /* If this is the SPSR that is being modified, set the R bit. */
1910 inst
.instruction
|= SPSR_BIT
;
1912 /* Set the psr flags in the MSR instruction. */
1913 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
1918 /* In the few cases where we might be able to accept
1919 something else this error can be overridden. */
1920 inst
.error
= _("flag for {c}psr instruction expected");
1922 /* Restore the start point. */
1928 co_proc_number (str
)
1931 int processor
, pchar
;
1933 skip_whitespace (* str
);
1935 /* The data sheet seems to imply that just a number on its own is valid
1936 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1938 if (**str
== 'p' || **str
== 'P')
1942 if (pchar
>= '0' && pchar
<= '9')
1944 processor
= pchar
- '0';
1945 if (**str
>= '0' && **str
<= '9')
1947 processor
= processor
* 10 + *(*str
)++ - '0';
1950 inst
.error
= _("Illegal co-processor number");
1957 inst
.error
= _("Bad or missing co-processor number");
1961 inst
.instruction
|= processor
<< 8;
1966 cp_opc_expr (str
, where
, length
)
1973 skip_whitespace (* str
);
1975 memset (&expr
, '\0', sizeof (expr
));
1977 if (my_get_expression (&expr
, str
))
1979 if (expr
.X_op
!= O_constant
)
1981 inst
.error
= _("bad or missing expression");
1985 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1987 inst
.error
= _("immediate co-processor expression too large");
1991 inst
.instruction
|= expr
.X_add_number
<< where
;
1996 cp_reg_required_here (str
, where
)
2001 char * start
= *str
;
2003 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
2006 inst
.instruction
|= reg
<< where
;
2010 /* In the few cases where we might be able to accept something else
2011 this error can be overridden. */
2012 inst
.error
= _("Co-processor register expected");
2014 /* Restore the start point. */
2020 fp_reg_required_here (str
, where
)
2025 char * start
= * str
;
2027 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
2030 inst
.instruction
|= reg
<< where
;
2034 /* In the few cases where we might be able to accept something else
2035 this error can be overridden. */
2036 inst
.error
= _("Floating point register expected");
2038 /* Restore the start point. */
2044 cp_address_offset (str
)
2049 skip_whitespace (* str
);
2051 if (! is_immediate_prefix (**str
))
2053 inst
.error
= _("immediate expression expected");
2059 if (my_get_expression (& inst
.reloc
.exp
, str
))
2062 if (inst
.reloc
.exp
.X_op
== O_constant
)
2064 offset
= inst
.reloc
.exp
.X_add_number
;
2068 inst
.error
= _("co-processor address must be word aligned");
2072 if (offset
> 1023 || offset
< -1023)
2074 inst
.error
= _("offset too large");
2079 inst
.instruction
|= INDEX_UP
;
2083 inst
.instruction
|= offset
>> 2;
2086 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2092 cp_address_required_here (str
)
2104 skip_whitespace (p
);
2106 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
2109 skip_whitespace (p
);
2115 if (skip_past_comma (& p
) == SUCCESS
)
2118 write_back
= WRITE_BACK
;
2122 inst
.error
= _("pc may not be used in post-increment");
2126 if (cp_address_offset (& p
) == FAIL
)
2130 pre_inc
= PRE_INDEX
| INDEX_UP
;
2134 /* '['Rn, #expr']'[!] */
2136 if (skip_past_comma (& p
) == FAIL
)
2138 inst
.error
= _("pre-indexed expression expected");
2142 pre_inc
= PRE_INDEX
;
2144 if (cp_address_offset (& p
) == FAIL
)
2147 skip_whitespace (p
);
2151 inst
.error
= _("missing ]");
2155 skip_whitespace (p
);
2161 inst
.error
= _("pc may not be used with write-back");
2166 write_back
= WRITE_BACK
;
2172 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2175 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2176 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2177 inst
.reloc
.pc_rel
= 1;
2178 inst
.instruction
|= (REG_PC
<< 16);
2179 pre_inc
= PRE_INDEX
;
2182 inst
.instruction
|= write_back
| pre_inc
;
2190 unsigned long flags
;
2192 /* Do nothing really. */
2193 inst
.instruction
|= flags
; /* This is pointless. */
2201 unsigned long flags
;
2205 /* Only one syntax. */
2206 skip_whitespace (str
);
2208 if (reg_required_here (&str
, 12) == FAIL
)
2210 inst
.error
= BAD_ARGS
;
2214 if (skip_past_comma (&str
) == FAIL
)
2216 inst
.error
= _("comma expected after register name");
2220 skip_whitespace (str
);
2222 if ( strcmp (str
, "CPSR") == 0
2223 || strcmp (str
, "SPSR") == 0
2224 /* Lower case versions for backwards compatability. */
2225 || strcmp (str
, "cpsr") == 0
2226 || strcmp (str
, "spsr") == 0)
2229 /* This is for backwards compatability with older toolchains. */
2230 else if ( strcmp (str
, "cpsr_all") == 0
2231 || strcmp (str
, "spsr_all") == 0)
2235 inst
.error
= _("{C|S}PSR expected");
2239 if (* str
== 's' || * str
== 'S')
2240 inst
.instruction
|= SPSR_BIT
;
2243 inst
.instruction
|= flags
;
2247 /* Two possible forms:
2248 "{C|S}PSR_<field>, Rm",
2249 "{C|S}PSR_f, #expression". */
2254 unsigned long flags
;
2256 skip_whitespace (str
);
2258 if (psr_required_here (& str
) == FAIL
)
2261 if (skip_past_comma (& str
) == FAIL
)
2263 inst
.error
= _("comma missing after psr flags");
2267 skip_whitespace (str
);
2269 if (reg_required_here (& str
, 0) != FAIL
)
2272 inst
.instruction
|= flags
;
2277 if (! is_immediate_prefix (* str
))
2280 _("only a register or immediate value can follow a psr flag");
2287 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2290 _("only a register or immediate value can follow a psr flag");
2294 #if 0 /* The first edition of the ARM architecture manual stated that
2295 writing anything other than the flags with an immediate operation
2296 had UNPREDICTABLE effects. This constraint was removed in the
2297 second edition of the specification. */
2298 if ((cpu_variant
& ARM_EXT_V5
) != ARM_EXT_V5
2299 && inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2301 inst
.error
= _("immediate value cannot be used to set this field");
2306 flags
|= INST_IMMEDIATE
;
2308 if (inst
.reloc
.exp
.X_add_symbol
)
2310 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2311 inst
.reloc
.pc_rel
= 0;
2315 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2317 if (value
== (unsigned) FAIL
)
2319 inst
.error
= _("Invalid constant");
2323 inst
.instruction
|= value
;
2327 inst
.instruction
|= flags
;
2331 /* Long Multiply Parser
2332 UMULL RdLo, RdHi, Rm, Rs
2333 SMULL RdLo, RdHi, Rm, Rs
2334 UMLAL RdLo, RdHi, Rm, Rs
2335 SMLAL RdLo, RdHi, Rm, Rs. */
2338 do_mull (str
, flags
)
2340 unsigned long flags
;
2342 int rdlo
, rdhi
, rm
, rs
;
2344 /* Only one format "rdlo, rdhi, rm, rs". */
2345 skip_whitespace (str
);
2347 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2349 inst
.error
= BAD_ARGS
;
2353 if (skip_past_comma (&str
) == FAIL
2354 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2356 inst
.error
= BAD_ARGS
;
2360 if (skip_past_comma (&str
) == FAIL
2361 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2363 inst
.error
= BAD_ARGS
;
2367 /* rdhi, rdlo and rm must all be different. */
2368 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2369 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2371 if (skip_past_comma (&str
) == FAIL
2372 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2374 inst
.error
= BAD_ARGS
;
2378 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2380 inst
.error
= BAD_PC
;
2384 inst
.instruction
|= flags
;
2392 unsigned long flags
;
2396 /* Only one format "rd, rm, rs". */
2397 skip_whitespace (str
);
2399 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2401 inst
.error
= BAD_ARGS
;
2407 inst
.error
= BAD_PC
;
2411 if (skip_past_comma (&str
) == FAIL
2412 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2414 inst
.error
= BAD_ARGS
;
2420 inst
.error
= BAD_PC
;
2425 as_tsktsk (_("rd and rm should be different in mul"));
2427 if (skip_past_comma (&str
) == FAIL
2428 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2430 inst
.error
= BAD_ARGS
;
2436 inst
.error
= BAD_PC
;
2440 inst
.instruction
|= flags
;
2448 unsigned long flags
;
2452 /* Only one format "rd, rm, rs, rn". */
2453 skip_whitespace (str
);
2455 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2457 inst
.error
= BAD_ARGS
;
2463 inst
.error
= BAD_PC
;
2467 if (skip_past_comma (&str
) == FAIL
2468 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2470 inst
.error
= BAD_ARGS
;
2476 inst
.error
= BAD_PC
;
2481 as_tsktsk (_("rd and rm should be different in mla"));
2483 if (skip_past_comma (&str
) == FAIL
2484 || (rd
= reg_required_here (&str
, 8)) == FAIL
2485 || skip_past_comma (&str
) == FAIL
2486 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2488 inst
.error
= BAD_ARGS
;
2492 if (rd
== REG_PC
|| rm
== REG_PC
)
2494 inst
.error
= BAD_PC
;
2498 inst
.instruction
|= flags
;
2503 /* Expects *str -> the characters "acc0", possibly with leading blanks.
2504 Advances *str to the next non-alphanumeric.
2505 Returns 0, or else FAIL (in which case sets inst.error).
2507 (In a future XScale, there may be accumulators other than zero.
2508 At that time this routine and its callers can be upgraded to suit.) */
2511 accum0_required_here (str
)
2514 static char buff
[128]; /* Note the address is taken. Hence, static. */
2517 int result
= 0; /* The accum number. */
2519 skip_whitespace (p
);
2521 *str
= p
; /* Advance caller's string pointer too. */
2526 *--p
= 0; /* Aap nul into input buffer at non-alnum. */
2528 if (! ( streq (*str
, "acc0") || streq (*str
, "ACC0")))
2530 sprintf (buff
, _("acc0 expected, not '%.100s'"), *str
);
2535 *p
= c
; /* Unzap. */
2536 *str
= p
; /* Caller's string pointer to after match. */
2540 /* Expects **str -> after a comma. May be leading blanks.
2541 Advances *str, recognizing a load mode, and setting inst.instruction.
2542 Returns rn, or else FAIL (in which case may set inst.error
2543 and not advance str)
2545 Note: doesn't know Rd, so no err checks that require such knowledge. */
2548 ld_mode_required_here (string
)
2551 char * str
= * string
;
2555 skip_whitespace (str
);
2561 skip_whitespace (str
);
2563 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
2566 skip_whitespace (str
);
2572 if (skip_past_comma (& str
) == SUCCESS
)
2574 /* [Rn],... (post inc) */
2575 if (ldst_extend (& str
, 1) == FAIL
)
2580 skip_whitespace (str
);
2585 inst
.instruction
|= WRITE_BACK
;
2588 inst
.instruction
|= INDEX_UP
| HWOFFSET_IMM
;
2594 if (skip_past_comma (& str
) == FAIL
)
2596 inst
.error
= _("pre-indexed expression expected");
2602 if (ldst_extend (& str
, 1) == FAIL
)
2605 skip_whitespace (str
);
2607 if (* str
++ != ']')
2609 inst
.error
= _("missing ]");
2613 skip_whitespace (str
);
2618 inst
.instruction
|= WRITE_BACK
;
2622 else if (* str
== '=') /* ldr's "r,=label" syntax */
2623 /* We should never reach here, because <text> = <expression> is
2624 caught gas/read.c read_a_source_file() as a .set operation. */
2626 else /* PC +- 8 bit immediate offset. */
2628 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2631 inst
.instruction
|= HWOFFSET_IMM
; /* The I bit. */
2632 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2633 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2634 inst
.reloc
.pc_rel
= 1;
2635 inst
.instruction
|= (REG_PC
<< 16);
2641 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
2647 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
2648 SMLAxy{cond} Rd,Rm,Rs,Rn
2649 SMLAWy{cond} Rd,Rm,Rs,Rn
2650 Error if any register is R15. */
2653 do_smla (str
, flags
)
2655 unsigned long flags
;
2659 skip_whitespace (str
);
2661 if ((rd
= reg_required_here (& str
, 16)) == FAIL
2662 || skip_past_comma (& str
) == FAIL
2663 || (rm
= reg_required_here (& str
, 0)) == FAIL
2664 || skip_past_comma (& str
) == FAIL
2665 || (rs
= reg_required_here (& str
, 8)) == FAIL
2666 || skip_past_comma (& str
) == FAIL
2667 || (rn
= reg_required_here (& str
, 12)) == FAIL
)
2668 inst
.error
= BAD_ARGS
;
2670 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
|| rn
== REG_PC
)
2671 inst
.error
= BAD_PC
;
2674 inst
.error
= BAD_FLAGS
;
2680 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
2681 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
2682 Error if any register is R15.
2683 Warning if Rdlo == Rdhi. */
2686 do_smlal (str
, flags
)
2688 unsigned long flags
;
2690 int rdlo
, rdhi
, rm
, rs
;
2692 skip_whitespace (str
);
2694 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
2695 || skip_past_comma (& str
) == FAIL
2696 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
2697 || skip_past_comma (& str
) == FAIL
2698 || (rm
= reg_required_here (& str
, 0)) == FAIL
2699 || skip_past_comma (& str
) == FAIL
2700 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
2702 inst
.error
= BAD_ARGS
;
2706 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
2708 inst
.error
= BAD_PC
;
2713 as_tsktsk (_("rdhi and rdlo must be different"));
2716 inst
.error
= BAD_FLAGS
;
2721 /* ARM V5E (El Segundo) signed-multiply (argument parse)
2722 SMULxy{cond} Rd,Rm,Rs
2723 Error if any register is R15. */
2726 do_smul (str
, flags
)
2728 unsigned long flags
;
2732 skip_whitespace (str
);
2734 if ((rd
= reg_required_here (& str
, 16)) == FAIL
2735 || skip_past_comma (& str
) == FAIL
2736 || (rm
= reg_required_here (& str
, 0)) == FAIL
2737 || skip_past_comma (& str
) == FAIL
2738 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
2739 inst
.error
= BAD_ARGS
;
2741 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
2742 inst
.error
= BAD_PC
;
2745 inst
.error
= BAD_FLAGS
;
2751 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
2752 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
2753 Error if any register is R15. */
2756 do_qadd (str
, flags
)
2758 unsigned long flags
;
2762 skip_whitespace (str
);
2764 if ((rd
= reg_required_here (& str
, 12)) == FAIL
2765 || skip_past_comma (& str
) == FAIL
2766 || (rm
= reg_required_here (& str
, 0)) == FAIL
2767 || skip_past_comma (& str
) == FAIL
2768 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
2769 inst
.error
= BAD_ARGS
;
2771 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
2772 inst
.error
= BAD_PC
;
2775 inst
.error
= BAD_FLAGS
;
2781 /* ARM V5E (el Segundo)
2782 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2783 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2785 These are equivalent to the XScale instructions MAR and MRA,
2786 respectively, when coproc == 0, opcode == 0, and CRm == 0.
2788 Result unpredicatable if Rd or Rn is R15. */
2791 do_co_reg2c (str
, flags
)
2793 unsigned long flags
;
2797 skip_whitespace (str
);
2799 if (co_proc_number (& str
) == FAIL
)
2802 inst
.error
= BAD_ARGS
;
2806 if (skip_past_comma (& str
) == FAIL
2807 || cp_opc_expr (& str
, 4, 4) == FAIL
)
2810 inst
.error
= BAD_ARGS
;
2814 if (skip_past_comma (& str
) == FAIL
2815 || (rd
= reg_required_here (& str
, 12)) == FAIL
)
2818 inst
.error
= BAD_ARGS
;
2822 if (skip_past_comma (& str
) == FAIL
2823 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
2826 inst
.error
= BAD_ARGS
;
2830 /* Unpredictable result if rd or rn is R15. */
2831 if (rd
== REG_PC
|| rn
== REG_PC
)
2833 (_("Warning: Instruction unpredictable when using r15"));
2835 if (skip_past_comma (& str
) == FAIL
2836 || cp_reg_required_here (& str
, 0) == FAIL
)
2839 inst
.error
= BAD_ARGS
;
2844 inst
.error
= BAD_COND
;
2849 /* ARM V5 count-leading-zeroes instruction (argument parse)
2850 CLZ{<cond>} <Rd>, <Rm>
2851 Condition defaults to COND_ALWAYS.
2852 Error if Rd or Rm are R15. */
2857 unsigned long flags
;
2867 skip_whitespace (str
);
2869 if (((rd
= reg_required_here (& str
, 12)) == FAIL
)
2870 || (skip_past_comma (& str
) == FAIL
)
2871 || ((rm
= reg_required_here (& str
, 0)) == FAIL
))
2872 inst
.error
= BAD_ARGS
;
2874 else if (rd
== REG_PC
|| rm
== REG_PC
)
2875 inst
.error
= BAD_PC
;
2881 /* ARM V5 (argument parse)
2882 LDC2{L} <coproc>, <CRd>, <addressing mode>
2883 STC2{L} <coproc>, <CRd>, <addressing mode>
2884 Instruction is not conditional, and has 0xf in the codition field.
2885 Otherwise, it's the same as LDC/STC. */
2888 do_lstc2 (str
, flags
)
2890 unsigned long flags
;
2893 inst
.error
= BAD_COND
;
2895 skip_whitespace (str
);
2897 if (co_proc_number (& str
) == FAIL
)
2900 inst
.error
= BAD_ARGS
;
2902 else if (skip_past_comma (& str
) == FAIL
2903 || cp_reg_required_here (& str
, 12) == FAIL
)
2906 inst
.error
= BAD_ARGS
;
2908 else if (skip_past_comma (& str
) == FAIL
2909 || cp_address_required_here (& str
) == FAIL
)
2912 inst
.error
= BAD_ARGS
;
2918 /* ARM V5 (argument parse)
2919 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
2920 Instruction is not conditional, and has 0xf in the condition field.
2921 Otherwise, it's the same as CDP. */
2924 do_cdp2 (str
, flags
)
2926 unsigned long flags
;
2928 skip_whitespace (str
);
2930 if (co_proc_number (& str
) == FAIL
)
2933 inst
.error
= BAD_ARGS
;
2937 if (skip_past_comma (& str
) == FAIL
2938 || cp_opc_expr (& str
, 20,4) == FAIL
)
2941 inst
.error
= BAD_ARGS
;
2945 if (skip_past_comma (& str
) == FAIL
2946 || cp_reg_required_here (& str
, 12) == FAIL
)
2949 inst
.error
= BAD_ARGS
;
2953 if (skip_past_comma (& str
) == FAIL
2954 || cp_reg_required_here (& str
, 16) == FAIL
)
2957 inst
.error
= BAD_ARGS
;
2961 if (skip_past_comma (& str
) == FAIL
2962 || cp_reg_required_here (& str
, 0) == FAIL
)
2965 inst
.error
= BAD_ARGS
;
2969 if (skip_past_comma (& str
) == SUCCESS
)
2971 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
2974 inst
.error
= BAD_ARGS
;
2980 inst
.error
= BAD_FLAGS
;
2985 /* ARM V5 (argument parse)
2986 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
2987 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
2988 Instruction is not conditional, and has 0xf in the condition field.
2989 Otherwise, it's the same as MCR/MRC. */
2992 do_co_reg2 (str
, flags
)
2994 unsigned long flags
;
2996 skip_whitespace (str
);
2998 if (co_proc_number (& str
) == FAIL
)
3001 inst
.error
= BAD_ARGS
;
3005 if (skip_past_comma (& str
) == FAIL
3006 || cp_opc_expr (& str
, 21, 3) == FAIL
)
3009 inst
.error
= BAD_ARGS
;
3013 if (skip_past_comma (& str
) == FAIL
3014 || reg_required_here (& str
, 12) == FAIL
)
3017 inst
.error
= BAD_ARGS
;
3021 if (skip_past_comma (& str
) == FAIL
3022 || cp_reg_required_here (& str
, 16) == FAIL
)
3025 inst
.error
= BAD_ARGS
;
3029 if (skip_past_comma (& str
) == FAIL
3030 || cp_reg_required_here (& str
, 0) == FAIL
)
3033 inst
.error
= BAD_ARGS
;
3037 if (skip_past_comma (& str
) == SUCCESS
)
3039 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3042 inst
.error
= BAD_ARGS
;
3048 inst
.error
= BAD_COND
;
3053 /* THUMB V5 breakpoint instruction (argument parse)
3061 unsigned long number
;
3063 skip_whitespace (str
);
3065 /* Allow optional leading '#'. */
3066 if (is_immediate_prefix (*str
))
3069 memset (& expr
, '\0', sizeof (expr
));
3070 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3072 inst
.error
= _("bad or missing expression");
3076 number
= expr
.X_add_number
;
3078 /* Check it fits an 8 bit unsigned. */
3079 if (number
!= (number
& 0xff))
3081 inst
.error
= _("immediate value out of range");
3085 inst
.instruction
|= number
;
3090 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3091 Expects inst.instruction is set for BLX(1).
3092 Note: this is cloned from do_branch, and the reloc changed to be a
3093 new one that can cope with setting one extra bit (the H bit). */
3096 do_branch25 (str
, flags
)
3098 unsigned long flags ATTRIBUTE_UNUSED
;
3100 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3107 /* ScottB: February 5, 1998 */
3108 /* Check to see of PLT32 reloc required for the instruction. */
3110 /* arm_parse_reloc() works on input_line_pointer.
3111 We actually want to parse the operands to the branch instruction
3112 passed in 'str'. Save the input pointer and restore it later. */
3113 save_in
= input_line_pointer
;
3114 input_line_pointer
= str
;
3116 if (inst
.reloc
.exp
.X_op
== O_symbol
3118 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3120 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3121 inst
.reloc
.pc_rel
= 0;
3122 /* Modify str to point to after parsed operands, otherwise
3123 end_of_line() will complain about the (PLT) left in str. */
3124 str
= input_line_pointer
;
3128 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3129 inst
.reloc
.pc_rel
= 1;
3132 input_line_pointer
= save_in
;
3135 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3136 inst
.reloc
.pc_rel
= 1;
3137 #endif /* OBJ_ELF */
3142 /* ARM V5 branch-link-exchange instruction (argument parse)
3143 BLX <target_addr> ie BLX(1)
3144 BLX{<condition>} <Rm> ie BLX(2)
3145 Unfortunately, there are two different opcodes for this mnemonic.
3146 So, the insns[].value is not used, and the code here zaps values
3147 into inst.instruction.
3148 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
3153 unsigned long flags
;
3164 skip_whitespace (mystr
);
3165 rm
= reg_required_here (& mystr
, 0);
3167 /* The above may set inst.error. Ignore his opinion. */
3172 /* Arg is a register.
3173 Use the condition code our caller put in inst.instruction.
3174 Pass ourselves off as a BX with a funny opcode. */
3175 inst
.instruction
|= 0x012fff30;
3180 /* This must be is BLX <target address>, no condition allowed. */
3181 if (inst
.instruction
!= COND_ALWAYS
)
3183 inst
.error
= BAD_COND
;
3187 inst
.instruction
= 0xfafffffe;
3189 /* Process like a B/BL, but with a different reloc.
3190 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
3191 do_branch25 (str
, flags
);
3195 /* ARM V5 Thumb BLX (argument parse)
3196 BLX <target_addr> which is BLX(1)
3197 BLX <Rm> which is BLX(2)
3198 Unfortunately, there are two different opcodes for this mnemonic.
3199 So, the tinsns[].value is not used, and the code here zaps values
3200 into inst.instruction. */
3209 skip_whitespace (mystr
);
3210 inst
.instruction
= 0x4780;
3212 /* Note that this call is to the ARM register recognizer. BLX(2)
3213 uses the ARM register space, not the Thumb one, so a call to
3214 thumb_reg() would be wrong. */
3215 rm
= reg_required_here (& mystr
, 3);
3220 /* It's BLX(2). The .instruction was zapped with rm & is final. */
3225 /* No ARM register. This must be BLX(1). Change the .instruction. */
3226 inst
.instruction
= 0xf7ffeffe;
3229 if (my_get_expression (& inst
.reloc
.exp
, & mystr
))
3232 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BLX
;
3233 inst
.reloc
.pc_rel
= 1;
3236 end_of_line (mystr
);
3239 /* ARM V5 breakpoint instruction (argument parse)
3240 BKPT <16 bit unsigned immediate>
3241 Instruction is not conditional.
3242 The bit pattern given in insns[] has the COND_ALWAYS condition,
3243 and it is an error if the caller tried to override that.
3244 Note "flags" is nonzero if a flag was supplied (which is an error). */
3247 do_bkpt (str
, flags
)
3249 unsigned long flags
;
3252 unsigned long number
;
3254 skip_whitespace (str
);
3256 /* Allow optional leading '#'. */
3257 if (is_immediate_prefix (* str
))
3260 memset (& expr
, '\0', sizeof (expr
));
3262 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3264 inst
.error
= _("bad or missing expression");
3268 number
= expr
.X_add_number
;
3270 /* Check it fits a 16 bit unsigned. */
3271 if (number
!= (number
& 0xffff))
3273 inst
.error
= _("immediate value out of range");
3277 /* Top 12 of 16 bits to bits 19:8. */
3278 inst
.instruction
|= (number
& 0xfff0) << 4;
3280 /* Bottom 4 of 16 bits to bits 3:0. */
3281 inst
.instruction
|= number
& 0xf;
3286 inst
.error
= BAD_FLAGS
;
3289 /* Xscale multiply-accumulate (argument parse)
3292 MIAxycc acc0,Rm,Rs. */
3297 unsigned long flags
;
3305 else if (accum0_required_here (& str
) == FAIL
)
3306 inst
.error
= ERR_NO_ACCUM
;
3308 else if (skip_past_comma (& str
) == FAIL
3309 || (rm
= reg_required_here (& str
, 0)) == FAIL
)
3310 inst
.error
= BAD_ARGS
;
3312 else if (skip_past_comma (& str
) == FAIL
3313 || (rs
= reg_required_here (& str
, 12)) == FAIL
)
3314 inst
.error
= BAD_ARGS
;
3316 /* inst.instruction has now been zapped with both rm and rs. */
3317 else if (rm
== REG_PC
|| rs
== REG_PC
)
3318 inst
.error
= BAD_PC
; /* Undefined result if rm or rs is R15. */
3324 /* Xscale move-accumulator-register (argument parse)
3326 MARcc acc0,RdLo,RdHi. */
3331 unsigned long flags
;
3338 else if (accum0_required_here (& str
) == FAIL
)
3339 inst
.error
= ERR_NO_ACCUM
;
3341 else if (skip_past_comma (& str
) == FAIL
3342 || (rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3343 inst
.error
= BAD_ARGS
;
3345 else if (skip_past_comma (& str
) == FAIL
3346 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3347 inst
.error
= BAD_ARGS
;
3349 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3350 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3351 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3357 /* Xscale move-register-accumulator (argument parse)
3359 MRAcc RdLo,RdHi,acc0. */
3364 unsigned long flags
;
3375 skip_whitespace (str
);
3377 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3378 inst
.error
= BAD_ARGS
;
3380 else if (skip_past_comma (& str
) == FAIL
3381 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3382 inst
.error
= BAD_ARGS
;
3384 else if (skip_past_comma (& str
) == FAIL
3385 || accum0_required_here (& str
) == FAIL
)
3386 inst
.error
= ERR_NO_ACCUM
;
3388 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3389 else if (rdlo
== rdhi
)
3390 inst
.error
= BAD_ARGS
; /* Undefined result if 2 writes to same reg. */
3392 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3393 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3398 /* Xscale: Preload-Cache
3402 Syntactically, like LDR with B=1, W=0, L=1. */
3407 unsigned long flags
;
3417 skip_whitespace (str
);
3421 inst
.error
= _("'[' expected after PLD mnemonic");
3426 skip_whitespace (str
);
3428 if ((rd
= reg_required_here (& str
, 16)) == FAIL
)
3431 skip_whitespace (str
);
3437 skip_whitespace (str
);
3439 if (skip_past_comma (& str
) == SUCCESS
)
3441 if (ldst_extend (& str
, 0) == FAIL
)
3444 else if (* str
== '!') /* [Rn]! */
3446 inst
.error
= _("writeback used in preload instruction");
3450 inst
.instruction
|= INDEX_UP
| PRE_INDEX
;
3452 else /* [Rn, ...] */
3454 if (skip_past_comma (& str
) == FAIL
)
3456 inst
.error
= _("pre-indexed expression expected");
3460 if (ldst_extend (& str
, 0) == FAIL
)
3463 skip_whitespace (str
);
3467 inst
.error
= _("missing ]");
3472 skip_whitespace (str
);
3474 if (* str
== '!') /* [Rn]! */
3476 inst
.error
= _("writeback used in preload instruction");
3480 inst
.instruction
|= PRE_INDEX
;
3486 /* Xscale load-consecutive (argument parse)
3493 do_ldrd (str
, flags
)
3495 unsigned long flags
;
3500 if (flags
!= DOUBLE_LOAD_FLAG
)
3502 /* Change instruction pattern to normal ldr/str. */
3503 if (inst
.instruction
& 0x20)
3504 inst
.instruction
= (inst
.instruction
& COND_MASK
) | 0x04000000; /* str */
3506 inst
.instruction
= (inst
.instruction
& COND_MASK
) | 0x04100000; /* ldr */
3508 /* Perform a normal load/store instruction parse. */
3509 do_ldst (str
, flags
);
3514 if ((cpu_variant
& ARM_EXT_XSCALE
) != ARM_EXT_XSCALE
)
3516 static char buff
[128];
3519 while (ISSPACE (*str
))
3523 /* Deny all knowledge. */
3524 sprintf (buff
, _("bad instruction '%.100s'"), str
);
3529 skip_whitespace (str
);
3531 if ((rd
= reg_required_here (& str
, 12)) == FAIL
)
3533 inst
.error
= BAD_ARGS
;
3537 if (skip_past_comma (& str
) == FAIL
3538 || (rn
= ld_mode_required_here (& str
)) == FAIL
)
3541 inst
.error
= BAD_ARGS
;
3545 /* inst.instruction has now been zapped with Rd and the addressing mode. */
3546 if (rd
& 1) /* Unpredictable result if Rd is odd. */
3548 inst
.error
= _("Destination register must be even");
3552 if (rd
== REG_LR
|| rd
== 12)
3554 inst
.error
= _("r12 or r14 not allowed here");
3558 if (((rd
== rn
) || (rd
+ 1 == rn
))
3560 ((inst
.instruction
& WRITE_BACK
)
3561 || (!(inst
.instruction
& PRE_INDEX
))))
3562 as_warn (_("pre/post-indexing used when modified address register is destination"));
3567 /* Returns the index into fp_values of a floating point number,
3568 or -1 if not in the table. */
3571 my_get_float_expression (str
)
3574 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
3580 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
3582 /* Look for a raw floating point number. */
3583 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
3584 && is_end_of_line
[(unsigned char) *save_in
])
3586 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
3588 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
3590 if (words
[j
] != fp_values
[i
][j
])
3594 if (j
== MAX_LITTLENUMS
)
3602 /* Try and parse a more complex expression, this will probably fail
3603 unless the code uses a floating point prefix (eg "0f"). */
3604 save_in
= input_line_pointer
;
3605 input_line_pointer
= *str
;
3606 if (expression (&exp
) == absolute_section
3607 && exp
.X_op
== O_big
3608 && exp
.X_add_number
< 0)
3610 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
3612 if (gen_to_words (words
, 5, (long) 15) == 0)
3614 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
3616 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
3618 if (words
[j
] != fp_values
[i
][j
])
3622 if (j
== MAX_LITTLENUMS
)
3624 *str
= input_line_pointer
;
3625 input_line_pointer
= save_in
;
3632 *str
= input_line_pointer
;
3633 input_line_pointer
= save_in
;
3637 /* Return true if anything in the expression is a bignum. */
3640 walk_no_bignums (sp
)
3643 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
3646 if (symbol_get_value_expression (sp
)->X_add_symbol
)
3648 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
3649 || (symbol_get_value_expression (sp
)->X_op_symbol
3650 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
3657 my_get_expression (ep
, str
)
3664 save_in
= input_line_pointer
;
3665 input_line_pointer
= *str
;
3666 seg
= expression (ep
);
3669 if (seg
!= absolute_section
3670 && seg
!= text_section
3671 && seg
!= data_section
3672 && seg
!= bss_section
3673 && seg
!= undefined_section
)
3675 inst
.error
= _("bad_segment");
3676 *str
= input_line_pointer
;
3677 input_line_pointer
= save_in
;
3682 /* Get rid of any bignums now, so that we don't generate an error for which
3683 we can't establish a line number later on. Big numbers are never valid
3684 in instructions, which is where this routine is always called. */
3685 if (ep
->X_op
== O_big
3686 || (ep
->X_add_symbol
3687 && (walk_no_bignums (ep
->X_add_symbol
)
3689 && walk_no_bignums (ep
->X_op_symbol
)))))
3691 inst
.error
= _("Invalid constant");
3692 *str
= input_line_pointer
;
3693 input_line_pointer
= save_in
;
3697 *str
= input_line_pointer
;
3698 input_line_pointer
= save_in
;
3702 /* UNRESTRICT should be one if <shift> <register> is permitted for this
3706 decode_shift (str
, unrestrict
)
3710 const struct asm_shift_name
* shift
;
3714 skip_whitespace (* str
);
3716 for (p
= * str
; ISALPHA (* p
); p
++)
3721 inst
.error
= _("Shift expression expected");
3727 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
3732 inst
.error
= _("Shift expression expected");
3736 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
3738 if (shift
->properties
->index
== SHIFT_RRX
)
3741 inst
.instruction
|= shift
->properties
->bit_field
;
3745 skip_whitespace (p
);
3747 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
3749 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
3753 else if (! is_immediate_prefix (* p
))
3755 inst
.error
= (unrestrict
3756 ? _("shift requires register or #expression")
3757 : _("shift requires #expression"));
3765 if (my_get_expression (& inst
.reloc
.exp
, & p
))
3768 /* Validate some simple #expressions. */
3769 if (inst
.reloc
.exp
.X_op
== O_constant
)
3771 unsigned num
= inst
.reloc
.exp
.X_add_number
;
3773 /* Reject operations greater than 32. */
3775 /* Reject a shift of 0 unless the mode allows it. */
3776 || (num
== 0 && shift
->properties
->allows_0
== 0)
3777 /* Reject a shift of 32 unless the mode allows it. */
3778 || (num
== 32 && shift
->properties
->allows_32
== 0)
3781 /* As a special case we allow a shift of zero for
3782 modes that do not support it to be recoded as an
3783 logical shift left of zero (ie nothing). We warn
3784 about this though. */
3787 as_warn (_("Shift of 0 ignored."));
3788 shift
= & shift_names
[0];
3789 assert (shift
->properties
->index
== SHIFT_LSL
);
3793 inst
.error
= _("Invalid immediate shift");
3798 /* Shifts of 32 are encoded as 0, for those shifts that
3803 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
3807 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
3808 inst
.reloc
.pc_rel
= 0;
3809 inst
.instruction
|= shift
->properties
->bit_field
;
3816 /* Do those data_ops which can take a negative immediate constant
3817 by altering the instuction. A bit of a hack really.
3821 by inverting the second operand, and
3824 by negating the second operand. */
3827 negate_data_op (instruction
, value
)
3828 unsigned long * instruction
;
3829 unsigned long value
;
3832 unsigned long negated
, inverted
;
3834 negated
= validate_immediate (-value
);
3835 inverted
= validate_immediate (~value
);
3837 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
3840 /* First negates. */
3841 case OPCODE_SUB
: /* ADD <-> SUB */
3842 new_inst
= OPCODE_ADD
;
3847 new_inst
= OPCODE_SUB
;
3851 case OPCODE_CMP
: /* CMP <-> CMN */
3852 new_inst
= OPCODE_CMN
;
3857 new_inst
= OPCODE_CMP
;
3861 /* Now Inverted ops. */
3862 case OPCODE_MOV
: /* MOV <-> MVN */
3863 new_inst
= OPCODE_MVN
;
3868 new_inst
= OPCODE_MOV
;
3872 case OPCODE_AND
: /* AND <-> BIC */
3873 new_inst
= OPCODE_BIC
;
3878 new_inst
= OPCODE_AND
;
3882 case OPCODE_ADC
: /* ADC <-> SBC */
3883 new_inst
= OPCODE_SBC
;
3888 new_inst
= OPCODE_ADC
;
3892 /* We cannot do anything. */
3897 if (value
== (unsigned) FAIL
)
3900 *instruction
&= OPCODE_MASK
;
3901 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
3912 skip_whitespace (* str
);
3914 if (reg_required_here (str
, 0) != FAIL
)
3916 if (skip_past_comma (str
) == SUCCESS
)
3917 /* Shift operation on register. */
3918 return decode_shift (str
, NO_SHIFT_RESTRICT
);
3924 /* Immediate expression. */
3925 if (is_immediate_prefix (**str
))
3930 if (my_get_expression (&inst
.reloc
.exp
, str
))
3933 if (inst
.reloc
.exp
.X_add_symbol
)
3935 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
3936 inst
.reloc
.pc_rel
= 0;
3940 if (skip_past_comma (str
) == SUCCESS
)
3942 /* #x, y -- ie explicit rotation by Y. */
3943 if (my_get_expression (&expr
, str
))
3946 if (expr
.X_op
!= O_constant
)
3948 inst
.error
= _("Constant expression expected");
3952 /* Rotate must be a multiple of 2. */
3953 if (((unsigned) expr
.X_add_number
) > 30
3954 || (expr
.X_add_number
& 1) != 0
3955 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
3957 inst
.error
= _("Invalid constant");
3960 inst
.instruction
|= INST_IMMEDIATE
;
3961 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
3962 inst
.instruction
|= expr
.X_add_number
<< 7;
3966 /* Implicit rotation, select a suitable one. */
3967 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
3971 /* Can't be done. Perhaps the code reads something like
3972 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
3973 if ((value
= negate_data_op (&inst
.instruction
,
3974 inst
.reloc
.exp
.X_add_number
))
3977 inst
.error
= _("Invalid constant");
3982 inst
.instruction
|= value
;
3985 inst
.instruction
|= INST_IMMEDIATE
;
3990 inst
.error
= _("Register or shift expression expected");
3999 skip_whitespace (* str
);
4001 if (fp_reg_required_here (str
, 0) != FAIL
)
4005 /* Immediate expression. */
4006 if (*((*str
)++) == '#')
4012 skip_whitespace (* str
);
4014 /* First try and match exact strings, this is to guarantee
4015 that some formats will work even for cross assembly. */
4017 for (i
= 0; fp_const
[i
]; i
++)
4019 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
4023 *str
+= strlen (fp_const
[i
]);
4024 if (is_end_of_line
[(unsigned char) **str
])
4026 inst
.instruction
|= i
+ 8;
4033 /* Just because we didn't get a match doesn't mean that the
4034 constant isn't valid, just that it is in a format that we
4035 don't automatically recognize. Try parsing it with
4036 the standard expression routines. */
4037 if ((i
= my_get_float_expression (str
)) >= 0)
4039 inst
.instruction
|= i
+ 8;
4043 inst
.error
= _("Invalid floating point immediate expression");
4047 _("Floating point register or immediate expression expected");
4053 do_arit (str
, flags
)
4055 unsigned long flags
;
4057 skip_whitespace (str
);
4059 if (reg_required_here (&str
, 12) == FAIL
4060 || skip_past_comma (&str
) == FAIL
4061 || reg_required_here (&str
, 16) == FAIL
4062 || skip_past_comma (&str
) == FAIL
4063 || data_op2 (&str
) == FAIL
)
4066 inst
.error
= BAD_ARGS
;
4070 inst
.instruction
|= flags
;
4078 unsigned long flags
;
4080 skip_whitespace (str
);
4082 if (reg_required_here (&str
, 12) == FAIL
4083 || skip_past_comma (&str
) == FAIL
4084 || my_get_expression (&inst
.reloc
.exp
, &str
))
4087 inst
.error
= BAD_ARGS
;
4091 if (flags
& 0x00400000)
4093 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4094 into a relative address of the form:
4095 add rd, pc, #low(label-.-8)"
4096 add rd, rd, #high(label-.-8)" */
4097 /* Frag hacking will turn this into a sub instruction if the offset turns
4098 out to be negative. */
4099 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
4100 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
4101 inst
.reloc
.pc_rel
= 1;
4102 inst
.instruction
|= flags
& ~0x00400000;
4103 inst
.size
= INSN_SIZE
* 2;
4107 /* This is a pseudo-op of the form "adr rd, label" to be converted
4108 into a relative address of the form "add rd, pc, #label-.-8". */
4109 /* Frag hacking will turn this into a sub instruction if the offset turns
4110 out to be negative. */
4111 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4112 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
4113 inst
.reloc
.pc_rel
= 1;
4114 inst
.instruction
|= flags
;
4123 unsigned long flags
;
4125 skip_whitespace (str
);
4127 if (reg_required_here (&str
, 16) == FAIL
)
4130 inst
.error
= BAD_ARGS
;
4134 if (skip_past_comma (&str
) == FAIL
4135 || data_op2 (&str
) == FAIL
)
4138 inst
.error
= BAD_ARGS
;
4142 inst
.instruction
|= flags
;
4143 if ((flags
& 0x0000f000) == 0)
4144 inst
.instruction
|= CONDS_BIT
;
4153 unsigned long flags
;
4155 skip_whitespace (str
);
4157 if (reg_required_here (&str
, 12) == FAIL
)
4160 inst
.error
= BAD_ARGS
;
4164 if (skip_past_comma (&str
) == FAIL
4165 || data_op2 (&str
) == FAIL
)
4168 inst
.error
= BAD_ARGS
;
4172 inst
.instruction
|= flags
;
4178 ldst_extend (str
, hwse
)
4189 if (my_get_expression (& inst
.reloc
.exp
, str
))
4192 if (inst
.reloc
.exp
.X_op
== O_constant
)
4194 int value
= inst
.reloc
.exp
.X_add_number
;
4196 if ((hwse
&& (value
< -255 || value
> 255))
4197 || (value
< -4095 || value
> 4095))
4199 inst
.error
= _("address offset too large");
4209 /* Halfword and signextension instructions have the
4210 immediate value split across bits 11..8 and bits 3..0. */
4212 inst
.instruction
|= (add
| HWOFFSET_IMM
4213 | ((value
>> 4) << 8) | (value
& 0xF));
4215 inst
.instruction
|= add
| value
;
4221 inst
.instruction
|= HWOFFSET_IMM
;
4222 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
4225 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4226 inst
.reloc
.pc_rel
= 0;
4239 if (reg_required_here (str
, 0) == FAIL
)
4243 inst
.instruction
|= add
;
4246 inst
.instruction
|= add
| OFFSET_REG
;
4247 if (skip_past_comma (str
) == SUCCESS
)
4248 return decode_shift (str
, SHIFT_RESTRICT
);
4256 do_ldst (str
, flags
)
4258 unsigned long flags
;
4265 /* This is not ideal, but it is the simplest way of dealing with the
4266 ARM7T halfword instructions (since they use a different
4267 encoding, but the same mnemonic): */
4268 halfword
= (flags
& 0x80000000) != 0;
4271 /* This is actually a load/store of a halfword, or a
4272 signed-extension load. */
4273 if ((cpu_variant
& ARM_EXT_HALFWORD
) == 0)
4276 = _("Processor does not support halfwords or signed bytes");
4280 inst
.instruction
= ((inst
.instruction
& COND_MASK
)
4281 | (flags
& ~COND_MASK
));
4286 skip_whitespace (str
);
4288 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
4291 inst
.error
= BAD_ARGS
;
4295 if (skip_past_comma (& str
) == FAIL
)
4297 inst
.error
= _("Address expected");
4307 skip_whitespace (str
);
4309 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4312 /* Conflicts can occur on stores as well as loads. */
4313 conflict_reg
= (conflict_reg
== reg
);
4315 skip_whitespace (str
);
4321 if (skip_past_comma (&str
) == SUCCESS
)
4323 /* [Rn],... (post inc) */
4324 if (ldst_extend (&str
, halfword
) == FAIL
)
4328 if (flags
& TRANS_BIT
)
4329 as_warn (_("Rn and Rd must be different in %s"),
4330 ((inst
.instruction
& LOAD_BIT
)
4331 ? "LDRT" : "STRT"));
4333 as_warn (_("%s register same as write-back base"),
4334 ((inst
.instruction
& LOAD_BIT
)
4335 ? _("destination") : _("source")));
4342 inst
.instruction
|= HWOFFSET_IMM
;
4344 skip_whitespace (str
);
4349 as_warn (_("%s register same as write-back base"),
4350 ((inst
.instruction
& LOAD_BIT
)
4351 ? _("destination") : _("source")));
4353 inst
.instruction
|= WRITE_BACK
;
4357 if (flags
& TRANS_BIT
)
4360 as_warn (_("Rn and Rd must be different in %s"),
4361 ((inst
.instruction
& LOAD_BIT
)
4362 ? "LDRT" : "STRT"));
4371 if (skip_past_comma (&str
) == FAIL
)
4373 inst
.error
= _("pre-indexed expression expected");
4378 if (ldst_extend (&str
, halfword
) == FAIL
)
4381 skip_whitespace (str
);
4385 inst
.error
= _("missing ]");
4389 skip_whitespace (str
);
4394 as_warn (_("%s register same as write-back base"),
4395 ((inst
.instruction
& LOAD_BIT
)
4396 ? _("destination") : _("source")));
4398 inst
.instruction
|= WRITE_BACK
;
4402 else if (*str
== '=')
4404 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4407 skip_whitespace (str
);
4409 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4412 if (inst
.reloc
.exp
.X_op
!= O_constant
4413 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4415 inst
.error
= _("Constant expression expected");
4419 if (inst
.reloc
.exp
.X_op
== O_constant
)
4421 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
4425 /* This can be done with a mov instruction. */
4426 inst
.instruction
&= LITERAL_MASK
;
4427 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
4428 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
4433 value
= validate_immediate (~ inst
.reloc
.exp
.X_add_number
);
4437 /* This can be done with a mvn instruction. */
4438 inst
.instruction
&= LITERAL_MASK
;
4439 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MVN
<< DATA_OP_SHIFT
);
4440 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
4446 /* Insert into literal pool. */
4447 if (add_to_lit_pool () == FAIL
)
4450 inst
.error
= _("literal pool insertion failed");
4454 /* Change the instruction exp to point to the pool. */
4457 inst
.instruction
|= HWOFFSET_IMM
;
4458 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
4461 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
4463 inst
.reloc
.pc_rel
= 1;
4464 inst
.instruction
|= (REG_PC
<< 16);
4469 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4474 inst
.instruction
|= HWOFFSET_IMM
;
4475 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
4478 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4480 /* PC rel adjust. */
4481 inst
.reloc
.exp
.X_add_number
-= 8;
4483 inst
.reloc
.pc_rel
= 1;
4484 inst
.instruction
|= (REG_PC
<< 16);
4488 if (pre_inc
&& (flags
& TRANS_BIT
))
4489 inst
.error
= _("Pre-increment instruction with translate");
4491 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
4500 char * str
= * strp
;
4504 /* We come back here if we get ranges concatenated by '+' or '|'. */
4519 skip_whitespace (str
);
4521 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
4530 inst
.error
= _("Bad range in register list");
4534 for (i
= cur_reg
+ 1; i
< reg
; i
++)
4536 if (range
& (1 << i
))
4538 (_("Warning: Duplicated register (r%d) in register list"),
4546 if (range
& (1 << reg
))
4547 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
4549 else if (reg
<= cur_reg
)
4550 as_tsktsk (_("Warning: Register range not in ascending order"));
4555 while (skip_past_comma (&str
) != FAIL
4556 || (in_range
= 1, *str
++ == '-'));
4558 skip_whitespace (str
);
4562 inst
.error
= _("Missing `}'");
4570 if (my_get_expression (&expr
, &str
))
4573 if (expr
.X_op
== O_constant
)
4575 if (expr
.X_add_number
4576 != (expr
.X_add_number
& 0x0000ffff))
4578 inst
.error
= _("invalid register mask");
4582 if ((range
& expr
.X_add_number
) != 0)
4584 int regno
= range
& expr
.X_add_number
;
4587 regno
= (1 << regno
) - 1;
4589 (_("Warning: Duplicated register (r%d) in register list"),
4593 range
|= expr
.X_add_number
;
4597 if (inst
.reloc
.type
!= 0)
4599 inst
.error
= _("expression too complex");
4603 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
4604 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
4605 inst
.reloc
.pc_rel
= 0;
4609 skip_whitespace (str
);
4611 if (*str
== '|' || *str
== '+')
4617 while (another_range
);
4624 do_ldmstm (str
, flags
)
4626 unsigned long flags
;
4631 skip_whitespace (str
);
4633 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
4636 if (base_reg
== REG_PC
)
4638 inst
.error
= _("r15 not allowed as base register");
4642 skip_whitespace (str
);
4646 flags
|= WRITE_BACK
;
4650 if (skip_past_comma (&str
) == FAIL
4651 || (range
= reg_list (&str
)) == FAIL
)
4654 inst
.error
= BAD_ARGS
;
4661 flags
|= LDM_TYPE_2_OR_3
;
4664 inst
.instruction
|= flags
| range
;
4672 unsigned long flags
;
4674 skip_whitespace (str
);
4676 /* Allow optional leading '#'. */
4677 if (is_immediate_prefix (*str
))
4680 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4683 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4684 inst
.reloc
.pc_rel
= 0;
4685 inst
.instruction
|= flags
;
4693 do_swap (str
, flags
)
4695 unsigned long flags
;
4699 skip_whitespace (str
);
4701 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
4706 inst
.error
= _("r15 not allowed in swap");
4710 if (skip_past_comma (&str
) == FAIL
4711 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
4714 inst
.error
= BAD_ARGS
;
4720 inst
.error
= _("r15 not allowed in swap");
4724 if (skip_past_comma (&str
) == FAIL
4727 inst
.error
= BAD_ARGS
;
4731 skip_whitespace (str
);
4733 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4738 inst
.error
= BAD_PC
;
4742 skip_whitespace (str
);
4746 inst
.error
= _("missing ]");
4750 inst
.instruction
|= flags
;
4756 do_branch (str
, flags
)
4758 unsigned long flags ATTRIBUTE_UNUSED
;
4760 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4767 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
4768 required for the instruction. */
4770 /* arm_parse_reloc () works on input_line_pointer.
4771 We actually want to parse the operands to the branch instruction
4772 passed in 'str'. Save the input pointer and restore it later. */
4773 save_in
= input_line_pointer
;
4774 input_line_pointer
= str
;
4775 if (inst
.reloc
.exp
.X_op
== O_symbol
4777 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
4779 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
4780 inst
.reloc
.pc_rel
= 0;
4781 /* Modify str to point to after parsed operands, otherwise
4782 end_of_line() will complain about the (PLT) left in str. */
4783 str
= input_line_pointer
;
4787 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
4788 inst
.reloc
.pc_rel
= 1;
4790 input_line_pointer
= save_in
;
4793 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
4794 inst
.reloc
.pc_rel
= 1;
4795 #endif /* OBJ_ELF */
4804 unsigned long flags ATTRIBUTE_UNUSED
;
4808 skip_whitespace (str
);
4810 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
4812 inst
.error
= BAD_ARGS
;
4816 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
4818 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
4826 unsigned long flags ATTRIBUTE_UNUSED
;
4828 /* Co-processor data operation.
4829 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
4830 skip_whitespace (str
);
4832 if (co_proc_number (&str
) == FAIL
)
4835 inst
.error
= BAD_ARGS
;
4839 if (skip_past_comma (&str
) == FAIL
4840 || cp_opc_expr (&str
, 20,4) == FAIL
)
4843 inst
.error
= BAD_ARGS
;
4847 if (skip_past_comma (&str
) == FAIL
4848 || cp_reg_required_here (&str
, 12) == FAIL
)
4851 inst
.error
= BAD_ARGS
;
4855 if (skip_past_comma (&str
) == FAIL
4856 || cp_reg_required_here (&str
, 16) == FAIL
)
4859 inst
.error
= BAD_ARGS
;
4863 if (skip_past_comma (&str
) == FAIL
4864 || cp_reg_required_here (&str
, 0) == FAIL
)
4867 inst
.error
= BAD_ARGS
;
4871 if (skip_past_comma (&str
) == SUCCESS
)
4873 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
4876 inst
.error
= BAD_ARGS
;
4886 do_lstc (str
, flags
)
4888 unsigned long flags
;
4890 /* Co-processor register load/store.
4891 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
4893 skip_whitespace (str
);
4895 if (co_proc_number (&str
) == FAIL
)
4898 inst
.error
= BAD_ARGS
;
4902 if (skip_past_comma (&str
) == FAIL
4903 || cp_reg_required_here (&str
, 12) == FAIL
)
4906 inst
.error
= BAD_ARGS
;
4910 if (skip_past_comma (&str
) == FAIL
4911 || cp_address_required_here (&str
) == FAIL
)
4914 inst
.error
= BAD_ARGS
;
4918 inst
.instruction
|= flags
;
4924 do_co_reg (str
, flags
)
4926 unsigned long flags
;
4928 /* Co-processor register transfer.
4929 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
4931 skip_whitespace (str
);
4933 if (co_proc_number (&str
) == FAIL
)
4936 inst
.error
= BAD_ARGS
;
4940 if (skip_past_comma (&str
) == FAIL
4941 || cp_opc_expr (&str
, 21, 3) == FAIL
)
4944 inst
.error
= BAD_ARGS
;
4948 if (skip_past_comma (&str
) == FAIL
4949 || reg_required_here (&str
, 12) == FAIL
)
4952 inst
.error
= BAD_ARGS
;
4956 if (skip_past_comma (&str
) == FAIL
4957 || cp_reg_required_here (&str
, 16) == FAIL
)
4960 inst
.error
= BAD_ARGS
;
4964 if (skip_past_comma (&str
) == FAIL
4965 || cp_reg_required_here (&str
, 0) == FAIL
)
4968 inst
.error
= BAD_ARGS
;
4972 if (skip_past_comma (&str
) == SUCCESS
)
4974 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
4977 inst
.error
= BAD_ARGS
;
4983 inst
.error
= BAD_COND
;
4991 do_fp_ctrl (str
, flags
)
4993 unsigned long flags ATTRIBUTE_UNUSED
;
4995 /* FP control registers.
4996 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
4998 skip_whitespace (str
);
5000 if (reg_required_here (&str
, 12) == FAIL
)
5003 inst
.error
= BAD_ARGS
;
5012 do_fp_ldst (str
, flags
)
5014 unsigned long flags ATTRIBUTE_UNUSED
;
5016 skip_whitespace (str
);
5018 switch (inst
.suffix
)
5023 inst
.instruction
|= CP_T_X
;
5026 inst
.instruction
|= CP_T_Y
;
5029 inst
.instruction
|= CP_T_X
| CP_T_Y
;
5035 if (fp_reg_required_here (&str
, 12) == FAIL
)
5038 inst
.error
= BAD_ARGS
;
5042 if (skip_past_comma (&str
) == FAIL
5043 || cp_address_required_here (&str
) == FAIL
)
5046 inst
.error
= BAD_ARGS
;
5054 do_fp_ldmstm (str
, flags
)
5056 unsigned long flags
;
5060 skip_whitespace (str
);
5062 if (fp_reg_required_here (&str
, 12) == FAIL
)
5065 inst
.error
= BAD_ARGS
;
5069 /* Get Number of registers to transfer. */
5070 if (skip_past_comma (&str
) == FAIL
5071 || my_get_expression (&inst
.reloc
.exp
, &str
))
5074 inst
.error
= _("constant expression expected");
5078 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5080 inst
.error
= _("Constant value required for number of registers");
5084 num_regs
= inst
.reloc
.exp
.X_add_number
;
5086 if (num_regs
< 1 || num_regs
> 4)
5088 inst
.error
= _("number of registers must be in the range [1:4]");
5095 inst
.instruction
|= CP_T_X
;
5098 inst
.instruction
|= CP_T_Y
;
5101 inst
.instruction
|= CP_T_Y
| CP_T_X
;
5115 /* The instruction specified "ea" or "fd", so we can only accept
5116 [Rn]{!}. The instruction does not really support stacking or
5117 unstacking, so we have to emulate these by setting appropriate
5118 bits and offsets. */
5119 if (skip_past_comma (&str
) == FAIL
5123 inst
.error
= BAD_ARGS
;
5128 skip_whitespace (str
);
5130 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5133 skip_whitespace (str
);
5137 inst
.error
= BAD_ARGS
;
5149 _("R15 not allowed as base register with write-back");
5156 if (flags
& CP_T_Pre
)
5158 /* Pre-decrement. */
5159 offset
= 3 * num_regs
;
5165 /* Post-increment. */
5169 offset
= 3 * num_regs
;
5173 /* No write-back, so convert this into a standard pre-increment
5174 instruction -- aesthetically more pleasing. */
5175 flags
= CP_T_Pre
| CP_T_UD
;
5180 inst
.instruction
|= flags
| offset
;
5182 else if (skip_past_comma (&str
) == FAIL
5183 || cp_address_required_here (&str
) == FAIL
)
5186 inst
.error
= BAD_ARGS
;
5194 do_fp_dyadic (str
, flags
)
5196 unsigned long flags
;
5198 skip_whitespace (str
);
5200 switch (inst
.suffix
)
5205 inst
.instruction
|= 0x00000080;
5208 inst
.instruction
|= 0x00080000;
5214 if (fp_reg_required_here (&str
, 12) == FAIL
)
5217 inst
.error
= BAD_ARGS
;
5221 if (skip_past_comma (&str
) == FAIL
5222 || fp_reg_required_here (&str
, 16) == FAIL
)
5225 inst
.error
= BAD_ARGS
;
5229 if (skip_past_comma (&str
) == FAIL
5230 || fp_op2 (&str
) == FAIL
)
5233 inst
.error
= BAD_ARGS
;
5237 inst
.instruction
|= flags
;
5243 do_fp_monadic (str
, flags
)
5245 unsigned long flags
;
5247 skip_whitespace (str
);
5249 switch (inst
.suffix
)
5254 inst
.instruction
|= 0x00000080;
5257 inst
.instruction
|= 0x00080000;
5263 if (fp_reg_required_here (&str
, 12) == FAIL
)
5266 inst
.error
= BAD_ARGS
;
5270 if (skip_past_comma (&str
) == FAIL
5271 || fp_op2 (&str
) == FAIL
)
5274 inst
.error
= BAD_ARGS
;
5278 inst
.instruction
|= flags
;
5284 do_fp_cmp (str
, flags
)
5286 unsigned long flags
;
5288 skip_whitespace (str
);
5290 if (fp_reg_required_here (&str
, 16) == FAIL
)
5293 inst
.error
= BAD_ARGS
;
5297 if (skip_past_comma (&str
) == FAIL
5298 || fp_op2 (&str
) == FAIL
)
5301 inst
.error
= BAD_ARGS
;
5305 inst
.instruction
|= flags
;
5311 do_fp_from_reg (str
, flags
)
5313 unsigned long flags
;
5315 skip_whitespace (str
);
5317 switch (inst
.suffix
)
5322 inst
.instruction
|= 0x00000080;
5325 inst
.instruction
|= 0x00080000;
5331 if (fp_reg_required_here (&str
, 16) == FAIL
)
5334 inst
.error
= BAD_ARGS
;
5338 if (skip_past_comma (&str
) == FAIL
5339 || reg_required_here (&str
, 12) == FAIL
)
5342 inst
.error
= BAD_ARGS
;
5346 inst
.instruction
|= flags
;
5352 do_fp_to_reg (str
, flags
)
5354 unsigned long flags
;
5356 skip_whitespace (str
);
5358 if (reg_required_here (&str
, 12) == FAIL
)
5361 if (skip_past_comma (&str
) == FAIL
5362 || fp_reg_required_here (&str
, 0) == FAIL
)
5365 inst
.error
= BAD_ARGS
;
5369 inst
.instruction
|= flags
;
5374 /* Thumb specific routines. */
5376 /* Parse and validate that a register is of the right form, this saves
5377 repeated checking of this information in many similar cases.
5378 Unlike the 32-bit case we do not insert the register into the opcode
5379 here, since the position is often unknown until the full instruction
5383 thumb_reg (strp
, hi_lo
)
5389 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
5397 inst
.error
= _("lo register required");
5405 inst
.error
= _("hi register required");
5417 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
5421 thumb_add_sub (str
, subtract
)
5425 int Rd
, Rs
, Rn
= FAIL
;
5427 skip_whitespace (str
);
5429 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
5430 || skip_past_comma (&str
) == FAIL
)
5433 inst
.error
= BAD_ARGS
;
5437 if (is_immediate_prefix (*str
))
5441 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5446 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5449 if (skip_past_comma (&str
) == FAIL
)
5451 /* Two operand format, shuffle the registers
5452 and pretend there are 3. */
5456 else if (is_immediate_prefix (*str
))
5459 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5462 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5466 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5467 for the latter case, EXPR contains the immediate that was found. */
5470 /* All register format. */
5471 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
5475 inst
.error
= _("dest and source1 must be the same register");
5479 /* Can't do this for SUB. */
5482 inst
.error
= _("subtract valid only on lo regs");
5486 inst
.instruction
= (T_OPCODE_ADD_HI
5487 | (Rd
> 7 ? THUMB_H1
: 0)
5488 | (Rn
> 7 ? THUMB_H2
: 0));
5489 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
5493 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
5494 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
5499 /* Immediate expression, now things start to get nasty. */
5501 /* First deal with HI regs, only very restricted cases allowed:
5502 Adjusting SP, and using PC or SP to get an address. */
5503 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
5504 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
5506 inst
.error
= _("invalid Hi register with immediate");
5510 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5512 /* Value isn't known yet, all we can do is store all the fragments
5513 we know about in the instruction and let the reloc hacking
5515 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
5516 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
5520 int offset
= inst
.reloc
.exp
.X_add_number
;
5530 /* Quick check, in case offset is MIN_INT. */
5533 inst
.error
= _("immediate value out of range");
5542 if (offset
& ~0x1fc)
5544 inst
.error
= _("invalid immediate value for stack adjust");
5547 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5548 inst
.instruction
|= offset
>> 2;
5550 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
5553 || (offset
& ~0x3fc))
5555 inst
.error
= _("invalid immediate for address calculation");
5558 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
5560 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
5566 inst
.error
= _("immediate value out of range");
5569 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5570 inst
.instruction
|= (Rd
<< 8) | offset
;
5576 inst
.error
= _("immediate value out of range");
5579 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5580 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
5589 thumb_shift (str
, shift
)
5593 int Rd
, Rs
, Rn
= FAIL
;
5595 skip_whitespace (str
);
5597 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5598 || skip_past_comma (&str
) == FAIL
)
5601 inst
.error
= BAD_ARGS
;
5605 if (is_immediate_prefix (*str
))
5607 /* Two operand immediate format, set Rs to Rd. */
5610 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5615 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5618 if (skip_past_comma (&str
) == FAIL
)
5620 /* Two operand format, shuffle the registers
5621 and pretend there are 3. */
5625 else if (is_immediate_prefix (*str
))
5628 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5631 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5635 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5636 for the latter case, EXPR contains the immediate that was found. */
5642 inst
.error
= _("source1 and dest must be same register");
5648 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
5649 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
5650 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
5653 inst
.instruction
|= Rd
| (Rn
<< 3);
5659 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
5660 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
5661 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
5664 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5666 /* Value isn't known yet, create a dummy reloc and let reloc
5667 hacking fix it up. */
5668 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
5672 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
5674 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
5676 inst
.error
= _("Invalid immediate for shift");
5680 /* Shifts of zero are handled by converting to LSL. */
5681 if (shift_value
== 0)
5682 inst
.instruction
= T_OPCODE_LSL_I
;
5684 /* Shifts of 32 are encoded as a shift of zero. */
5685 if (shift_value
== 32)
5688 inst
.instruction
|= shift_value
<< 6;
5691 inst
.instruction
|= Rd
| (Rs
<< 3);
5698 thumb_mov_compare (str
, move
)
5704 skip_whitespace (str
);
5706 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
5707 || skip_past_comma (&str
) == FAIL
)
5710 inst
.error
= BAD_ARGS
;
5714 if (is_immediate_prefix (*str
))
5717 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5720 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5725 if (Rs
< 8 && Rd
< 8)
5727 if (move
== THUMB_MOVE
)
5728 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
5729 since a MOV instruction produces unpredictable results. */
5730 inst
.instruction
= T_OPCODE_ADD_I3
;
5732 inst
.instruction
= T_OPCODE_CMP_LR
;
5733 inst
.instruction
|= Rd
| (Rs
<< 3);
5737 if (move
== THUMB_MOVE
)
5738 inst
.instruction
= T_OPCODE_MOV_HR
;
5740 inst
.instruction
= T_OPCODE_CMP_HR
;
5743 inst
.instruction
|= THUMB_H1
;
5746 inst
.instruction
|= THUMB_H2
;
5748 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
5755 inst
.error
= _("only lo regs allowed with immediate");
5759 if (move
== THUMB_MOVE
)
5760 inst
.instruction
= T_OPCODE_MOV_I8
;
5762 inst
.instruction
= T_OPCODE_CMP_I8
;
5764 inst
.instruction
|= Rd
<< 8;
5766 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5767 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
5770 unsigned value
= inst
.reloc
.exp
.X_add_number
;
5774 inst
.error
= _("invalid immediate");
5778 inst
.instruction
|= value
;
5786 thumb_load_store (str
, load_store
, size
)
5791 int Rd
, Rb
, Ro
= FAIL
;
5793 skip_whitespace (str
);
5795 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5796 || skip_past_comma (&str
) == FAIL
)
5799 inst
.error
= BAD_ARGS
;
5806 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5809 if (skip_past_comma (&str
) != FAIL
)
5811 if (is_immediate_prefix (*str
))
5814 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5817 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5822 inst
.reloc
.exp
.X_op
= O_constant
;
5823 inst
.reloc
.exp
.X_add_number
= 0;
5828 inst
.error
= _("expected ']'");
5833 else if (*str
== '=')
5835 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5838 skip_whitespace (str
);
5840 if (my_get_expression (& inst
.reloc
.exp
, & str
))
5845 if ( inst
.reloc
.exp
.X_op
!= O_constant
5846 && inst
.reloc
.exp
.X_op
!= O_symbol
)
5848 inst
.error
= "Constant expression expected";
5852 if (inst
.reloc
.exp
.X_op
== O_constant
5853 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
5855 /* This can be done with a mov instruction. */
5857 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
5858 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
5862 /* Insert into literal pool. */
5863 if (add_to_lit_pool () == FAIL
)
5866 inst
.error
= "literal pool insertion failed";
5870 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
5871 inst
.reloc
.pc_rel
= 1;
5872 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
5873 /* Adjust ARM pipeline offset to Thumb. */
5874 inst
.reloc
.exp
.X_add_number
+= 4;
5880 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5883 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
5884 inst
.reloc
.pc_rel
= 1;
5885 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
5886 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
5891 if (Rb
== REG_PC
|| Rb
== REG_SP
)
5893 if (size
!= THUMB_WORD
)
5895 inst
.error
= _("byte or halfword not valid for base register");
5898 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
5900 inst
.error
= _("R15 based store not allowed");
5903 else if (Ro
!= FAIL
)
5905 inst
.error
= _("Invalid base register for register offset");
5910 inst
.instruction
= T_OPCODE_LDR_PC
;
5911 else if (load_store
== THUMB_LOAD
)
5912 inst
.instruction
= T_OPCODE_LDR_SP
;
5914 inst
.instruction
= T_OPCODE_STR_SP
;
5916 inst
.instruction
|= Rd
<< 8;
5917 if (inst
.reloc
.exp
.X_op
== O_constant
)
5919 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
5921 if (offset
& ~0x3fc)
5923 inst
.error
= _("invalid offset");
5927 inst
.instruction
|= offset
>> 2;
5930 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
5934 inst
.error
= _("invalid base register in load/store");
5937 else if (Ro
== FAIL
)
5939 /* Immediate offset. */
5940 if (size
== THUMB_WORD
)
5941 inst
.instruction
= (load_store
== THUMB_LOAD
5942 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
5943 else if (size
== THUMB_HALFWORD
)
5944 inst
.instruction
= (load_store
== THUMB_LOAD
5945 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
5947 inst
.instruction
= (load_store
== THUMB_LOAD
5948 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
5950 inst
.instruction
|= Rd
| (Rb
<< 3);
5952 if (inst
.reloc
.exp
.X_op
== O_constant
)
5954 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
5956 if (offset
& ~(0x1f << size
))
5958 inst
.error
= _("Invalid offset");
5961 inst
.instruction
|= (offset
>> size
) << 6;
5964 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
5968 /* Register offset. */
5969 if (size
== THUMB_WORD
)
5970 inst
.instruction
= (load_store
== THUMB_LOAD
5971 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
5972 else if (size
== THUMB_HALFWORD
)
5973 inst
.instruction
= (load_store
== THUMB_LOAD
5974 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
5976 inst
.instruction
= (load_store
== THUMB_LOAD
5977 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
5979 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
5994 /* Handle the Format 4 instructions that do not have equivalents in other
5995 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
6004 skip_whitespace (str
);
6006 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6007 || skip_past_comma (&str
) == FAIL
6008 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6010 inst
.error
= BAD_ARGS
;
6014 if (skip_past_comma (&str
) != FAIL
)
6016 /* Three operand format not allowed for TST, CMN, NEG and MVN.
6017 (It isn't allowed for CMP either, but that isn't handled by this
6019 if (inst
.instruction
== T_OPCODE_TST
6020 || inst
.instruction
== T_OPCODE_CMN
6021 || inst
.instruction
== T_OPCODE_NEG
6022 || inst
.instruction
== T_OPCODE_MVN
)
6024 inst
.error
= BAD_ARGS
;
6028 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6033 inst
.error
= _("dest and source1 must be the same register");
6039 if (inst
.instruction
== T_OPCODE_MUL
6041 as_tsktsk (_("Rs and Rd must be different in MUL"));
6043 inst
.instruction
|= Rd
| (Rs
<< 3);
6051 thumb_add_sub (str
, 0);
6058 thumb_shift (str
, THUMB_ASR
);
6065 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6067 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
6068 inst
.reloc
.pc_rel
= 1;
6076 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6078 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
6079 inst
.reloc
.pc_rel
= 1;
6083 /* Find the real, Thumb encoded start of a Thumb function. */
6086 find_real_start (symbolP
)
6090 const char * name
= S_GET_NAME (symbolP
);
6091 symbolS
* new_target
;
6093 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
6094 #define STUB_NAME ".real_start_of"
6099 /* Names that start with '.' are local labels, not function entry points.
6100 The compiler may generate BL instructions to these labels because it
6101 needs to perform a branch to a far away location. */
6105 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
6106 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
6108 new_target
= symbol_find (real_start
);
6110 if (new_target
== NULL
)
6112 as_warn ("Failed to find real start of function: %s\n", name
);
6113 new_target
= symbolP
;
6125 if (my_get_expression (& inst
.reloc
.exp
, & str
))
6128 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
6129 inst
.reloc
.pc_rel
= 1;
6132 /* If the destination of the branch is a defined symbol which does not have
6133 the THUMB_FUNC attribute, then we must be calling a function which has
6134 the (interfacearm) attribute. We look for the Thumb entry point to that
6135 function and change the branch to refer to that function instead. */
6136 if ( inst
.reloc
.exp
.X_op
== O_symbol
6137 && inst
.reloc
.exp
.X_add_symbol
!= NULL
6138 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
6139 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
6140 inst
.reloc
.exp
.X_add_symbol
=
6141 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
6150 skip_whitespace (str
);
6152 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6155 /* This sets THUMB_H2 from the top bit of reg. */
6156 inst
.instruction
|= reg
<< 3;
6158 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
6159 should cause the alignment to be checked once it is known. This is
6160 because BX PC only works if the instruction is word aligned. */
6169 thumb_mov_compare (str
, THUMB_COMPARE
);
6179 skip_whitespace (str
);
6181 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6185 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
6189 if (skip_past_comma (&str
) == FAIL
6190 || (range
= reg_list (&str
)) == FAIL
)
6193 inst
.error
= BAD_ARGS
;
6197 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6199 /* This really doesn't seem worth it. */
6200 inst
.reloc
.type
= BFD_RELOC_NONE
;
6201 inst
.error
= _("Expression too complex");
6207 inst
.error
= _("only lo-regs valid in load/store multiple");
6211 inst
.instruction
|= (Rb
<< 8) | range
;
6219 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
6226 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
6233 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
6242 skip_whitespace (str
);
6244 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6245 || skip_past_comma (&str
) == FAIL
6247 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6248 || skip_past_comma (&str
) == FAIL
6249 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6253 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
6257 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
6265 thumb_shift (str
, THUMB_LSL
);
6272 thumb_shift (str
, THUMB_LSR
);
6279 thumb_mov_compare (str
, THUMB_MOVE
);
6288 skip_whitespace (str
);
6290 if ((range
= reg_list (&str
)) == FAIL
)
6293 inst
.error
= BAD_ARGS
;
6297 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6299 /* This really doesn't seem worth it. */
6300 inst
.reloc
.type
= BFD_RELOC_NONE
;
6301 inst
.error
= _("Expression too complex");
6307 if ((inst
.instruction
== T_OPCODE_PUSH
6308 && (range
& ~0xff) == 1 << REG_LR
)
6309 || (inst
.instruction
== T_OPCODE_POP
6310 && (range
& ~0xff) == 1 << REG_PC
))
6312 inst
.instruction
|= THUMB_PP_PC_LR
;
6317 inst
.error
= _("invalid register list to push/pop instruction");
6322 inst
.instruction
|= range
;
6330 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
6337 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
6344 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
6351 thumb_add_sub (str
, 1);
6358 skip_whitespace (str
);
6360 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6363 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
6374 /* This is a pseudo-op of the form "adr rd, label" to be converted
6375 into a relative address of the form "add rd, pc, #label-.-4". */
6376 skip_whitespace (str
);
6378 /* Store Rd in temporary location inside instruction. */
6379 if ((reg
= reg_required_here (&str
, 4)) == FAIL
6380 || (reg
> 7) /* For Thumb reg must be r0..r7. */
6381 || skip_past_comma (&str
) == FAIL
6382 || my_get_expression (&inst
.reloc
.exp
, &str
))
6385 inst
.error
= BAD_ARGS
;
6389 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
6390 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
6391 inst
.reloc
.pc_rel
= 1;
6392 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
6401 int len
= strlen (reg_table
[entry
].name
) + 2;
6402 char * buf
= (char *) xmalloc (len
);
6403 char * buf2
= (char *) xmalloc (len
);
6406 #ifdef REGISTER_PREFIX
6407 buf
[i
++] = REGISTER_PREFIX
;
6410 strcpy (buf
+ i
, reg_table
[entry
].name
);
6412 for (i
= 0; buf
[i
]; i
++)
6413 buf2
[i
] = TOUPPER (buf
[i
]);
6417 hash_insert (arm_reg_hsh
, buf
, (PTR
) & reg_table
[entry
]);
6418 hash_insert (arm_reg_hsh
, buf2
, (PTR
) & reg_table
[entry
]);
6422 insert_reg_alias (str
, regnum
)
6426 struct reg_entry
*new =
6427 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
6428 char *name
= xmalloc (strlen (str
) + 1);
6432 new->number
= regnum
;
6434 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
6438 set_constant_flonums ()
6442 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
6443 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
6453 if ( (arm_ops_hsh
= hash_new ()) == NULL
6454 || (arm_tops_hsh
= hash_new ()) == NULL
6455 || (arm_cond_hsh
= hash_new ()) == NULL
6456 || (arm_shift_hsh
= hash_new ()) == NULL
6457 || (arm_reg_hsh
= hash_new ()) == NULL
6458 || (arm_psr_hsh
= hash_new ()) == NULL
)
6459 as_fatal (_("Virtual memory exhausted"));
6461 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
6462 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
6463 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
6464 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
6465 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
6466 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
6467 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
6468 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
6469 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
6470 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
6472 for (i
= 0; reg_table
[i
].name
; i
++)
6475 set_constant_flonums ();
6477 #if defined OBJ_COFF || defined OBJ_ELF
6479 unsigned int flags
= 0;
6481 /* Set the flags in the private structure. */
6482 if (uses_apcs_26
) flags
|= F_APCS26
;
6483 if (support_interwork
) flags
|= F_INTERWORK
;
6484 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
6485 if (pic_code
) flags
|= F_PIC
;
6486 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
6488 bfd_set_private_flags (stdoutput
, flags
);
6490 /* We have run out flags in the COFF header to encode the
6491 status of ATPCS support, so instead we create a dummy,
6492 empty, debug section called .arm.atpcs. */
6497 sec
= bfd_make_section (stdoutput
, ".arm.atpcs");
6501 bfd_set_section_flags
6502 (stdoutput
, sec
, SEC_READONLY
| SEC_DEBUGGING
/* | SEC_HAS_CONTENTS */);
6503 bfd_set_section_size (stdoutput
, sec
, 0);
6504 bfd_set_section_contents (stdoutput
, sec
, NULL
, 0, 0);
6510 /* Record the CPU type as well. */
6511 switch (cpu_variant
& ARM_CPU_MASK
)
6514 mach
= bfd_mach_arm_2
;
6517 case ARM_3
: /* Also ARM_250. */
6518 mach
= bfd_mach_arm_2a
;
6522 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined. */
6523 mach
= bfd_mach_arm_4
;
6526 case ARM_7
: /* Also ARM_6. */
6527 mach
= bfd_mach_arm_3
;
6531 /* Catch special cases. */
6532 if (cpu_variant
& ARM_EXT_XSCALE
)
6533 mach
= bfd_mach_arm_XScale
;
6534 else if (cpu_variant
& ARM_EXT_V5E
)
6535 mach
= bfd_mach_arm_5TE
;
6536 else if (cpu_variant
& ARM_EXT_V5
)
6538 if (cpu_variant
& ARM_EXT_THUMB
)
6539 mach
= bfd_mach_arm_5T
;
6541 mach
= bfd_mach_arm_5
;
6543 else if (cpu_variant
& ARM_EXT_HALFWORD
)
6545 if (cpu_variant
& ARM_EXT_THUMB
)
6546 mach
= bfd_mach_arm_4T
;
6548 mach
= bfd_mach_arm_4
;
6550 else if (cpu_variant
& ARM_EXT_LONGMUL
)
6551 mach
= bfd_mach_arm_3M
;
6553 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
6556 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
6557 for use in the a.out file, and stores them in the array pointed to by buf.
6558 This knows about the endian-ness of the target machine and does
6559 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
6560 2 (short) and 4 (long) Floating numbers are put out as a series of
6561 LITTLENUMS (shorts, here at least). */
6564 md_number_to_chars (buf
, val
, n
)
6569 if (target_big_endian
)
6570 number_to_chars_bigendian (buf
, val
, n
);
6572 number_to_chars_littleendian (buf
, val
, n
);
6576 md_chars_to_number (buf
, n
)
6581 unsigned char * where
= (unsigned char *) buf
;
6583 if (target_big_endian
)
6588 result
|= (*where
++ & 255);
6596 result
|= (where
[n
] & 255);
6603 /* Turn a string in input_line_pointer into a floating point constant
6604 of type TYPE, and store the appropriate bytes in *LITP. The number
6605 of LITTLENUMS emitted is stored in *SIZEP. An error message is
6606 returned, or NULL on OK.
6608 Note that fp constants aren't represent in the normal way on the ARM.
6609 In big endian mode, things are as expected. However, in little endian
6610 mode fp constants are big-endian word-wise, and little-endian byte-wise
6611 within the words. For example, (double) 1.1 in big endian mode is
6612 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
6613 the byte sequence 99 99 f1 3f 9a 99 99 99.
6615 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
6618 md_atof (type
, litP
, sizeP
)
6624 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6656 return _("Bad call to MD_ATOF()");
6659 t
= atof_ieee (input_line_pointer
, type
, words
);
6661 input_line_pointer
= t
;
6664 if (target_big_endian
)
6666 for (i
= 0; i
< prec
; i
++)
6668 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
6674 /* For a 4 byte float the order of elements in `words' is 1 0. For an
6675 8 byte float the order is 1 0 3 2. */
6676 for (i
= 0; i
< prec
; i
+= 2)
6678 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
6679 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
6687 /* The knowledge of the PC's pipeline offset is built into the insns
6691 md_pcrel_from (fixP
)
6695 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
6696 && fixP
->fx_subsy
== NULL
)
6699 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
6701 /* PC relative addressing on the Thumb is slightly odd
6702 as the bottom two bits of the PC are forced to zero
6703 for the calculation. */
6704 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
6708 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
6709 so we un-adjust here to compensate for the accomodation. */
6710 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
6712 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
6716 /* Round up a section size to the appropriate boundary. */
6719 md_section_align (segment
, size
)
6720 segT segment ATTRIBUTE_UNUSED
;
6726 /* Round all sects to multiple of 4. */
6727 return (size
+ 3) & ~3;
6731 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
6732 Otherwise we have no need to default values of symbols. */
6735 md_undefined_symbol (name
)
6736 char * name ATTRIBUTE_UNUSED
;
6739 if (name
[0] == '_' && name
[1] == 'G'
6740 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
6744 if (symbol_find (name
))
6745 as_bad ("GOT already in the symbol table");
6747 GOT_symbol
= symbol_new (name
, undefined_section
,
6748 (valueT
) 0, & zero_address_frag
);
6758 /* arm_reg_parse () := if it looks like a register, return its token and
6759 advance the pointer. */
6763 register char ** ccp
;
6765 char * start
= * ccp
;
6768 struct reg_entry
* reg
;
6770 #ifdef REGISTER_PREFIX
6771 if (*start
!= REGISTER_PREFIX
)
6776 #ifdef OPTIONAL_REGISTER_PREFIX
6777 if (*p
== OPTIONAL_REGISTER_PREFIX
)
6781 if (!ISALPHA (*p
) || !is_name_beginner (*p
))
6785 while (ISALPHA (c
) || ISDIGIT (c
) || c
== '_')
6789 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
6802 md_apply_fix3 (fixP
, val
, seg
)
6807 offsetT value
= * val
;
6809 unsigned int newimm
;
6812 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
6813 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
6815 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
6817 /* Note whether this will delete the relocation. */
6819 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
6820 doesn't work fully.) */
6821 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
6824 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
6828 /* If this symbol is in a different section then we need to leave it for
6829 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
6830 so we have to undo it's effects here. */
6833 if (fixP
->fx_addsy
!= NULL
6834 && S_IS_DEFINED (fixP
->fx_addsy
)
6835 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
6838 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
6839 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
6843 value
+= md_pcrel_from (fixP
);
6847 /* Remember value for emit_reloc. */
6848 fixP
->fx_addnumber
= value
;
6850 switch (fixP
->fx_r_type
)
6852 case BFD_RELOC_ARM_IMMEDIATE
:
6853 newimm
= validate_immediate (value
);
6854 temp
= md_chars_to_number (buf
, INSN_SIZE
);
6856 /* If the instruction will fail, see if we can fix things up by
6857 changing the opcode. */
6858 if (newimm
== (unsigned int) FAIL
6859 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
6861 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6862 _("invalid constant (%lx) after fixup"),
6863 (unsigned long) value
);
6867 newimm
|= (temp
& 0xfffff000);
6868 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
6871 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
6873 unsigned int highpart
= 0;
6874 unsigned int newinsn
= 0xe1a00000; /* nop. */
6875 newimm
= validate_immediate (value
);
6876 temp
= md_chars_to_number (buf
, INSN_SIZE
);
6878 /* If the instruction will fail, see if we can fix things up by
6879 changing the opcode. */
6880 if (newimm
== (unsigned int) FAIL
6881 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
6883 /* No ? OK - try using two ADD instructions to generate
6885 newimm
= validate_immediate_twopart (value
, & highpart
);
6887 /* Yes - then make sure that the second instruction is
6889 if (newimm
!= (unsigned int) FAIL
)
6891 /* Still No ? Try using a negated value. */
6892 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
6893 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
6894 /* Otherwise - give up. */
6897 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6898 _("Unable to compute ADRL instructions for PC offset of 0x%lx"),
6903 /* Replace the first operand in the 2nd instruction (which
6904 is the PC) with the destination register. We have
6905 already added in the PC in the first instruction and we
6906 do not want to do it again. */
6907 newinsn
&= ~ 0xf0000;
6908 newinsn
|= ((newinsn
& 0x0f000) << 4);
6911 newimm
|= (temp
& 0xfffff000);
6912 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
6914 highpart
|= (newinsn
& 0xfffff000);
6915 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
6919 case BFD_RELOC_ARM_OFFSET_IMM
:
6925 if (validate_offset_imm (value
, 0) == FAIL
)
6927 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6928 _("bad immediate value for offset (%ld)"),
6933 newval
= md_chars_to_number (buf
, INSN_SIZE
);
6934 newval
&= 0xff7ff000;
6935 newval
|= value
| (sign
? INDEX_UP
: 0);
6936 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6939 case BFD_RELOC_ARM_OFFSET_IMM8
:
6940 case BFD_RELOC_ARM_HWLITERAL
:
6946 if (validate_offset_imm (value
, 1) == FAIL
)
6948 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
6949 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6950 _("invalid literal constant: pool needs to be closer"));
6952 as_bad (_("bad immediate value for half-word offset (%ld)"),
6957 newval
= md_chars_to_number (buf
, INSN_SIZE
);
6958 newval
&= 0xff7ff0f0;
6959 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
6960 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6963 case BFD_RELOC_ARM_LITERAL
:
6969 if (validate_offset_imm (value
, 0) == FAIL
)
6971 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6972 _("invalid literal constant: pool needs to be closer"));
6976 newval
= md_chars_to_number (buf
, INSN_SIZE
);
6977 newval
&= 0xff7ff000;
6978 newval
|= value
| (sign
? INDEX_UP
: 0);
6979 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6982 case BFD_RELOC_ARM_SHIFT_IMM
:
6983 newval
= md_chars_to_number (buf
, INSN_SIZE
);
6984 if (((unsigned long) value
) > 32
6986 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
6988 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6989 _("shift expression is too large"));
6994 /* Shifts of zero must be done as lsl. */
6996 else if (value
== 32)
6998 newval
&= 0xfffff07f;
6999 newval
|= (value
& 0x1f) << 7;
7000 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7003 case BFD_RELOC_ARM_SWI
:
7004 if (arm_data
->thumb_mode
)
7006 if (((unsigned long) value
) > 0xff)
7007 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7008 _("Invalid swi expression"));
7009 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
7011 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7015 if (((unsigned long) value
) > 0x00ffffff)
7016 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7017 _("Invalid swi expression"));
7018 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
7020 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7024 case BFD_RELOC_ARM_MULTI
:
7025 if (((unsigned long) value
) > 0xffff)
7026 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7027 _("Invalid expression in load/store multiple"));
7028 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
7029 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7032 case BFD_RELOC_ARM_PCREL_BRANCH
:
7033 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7035 /* Sign-extend a 24-bit number. */
7036 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
7040 value
= fixP
->fx_offset
;
7043 /* We are going to store value (shifted right by two) in the
7044 instruction, in a 24 bit, signed field. Thus we need to check
7045 that none of the top 8 bits of the shifted value (top 7 bits of
7046 the unshifted, unsigned value) are set, or that they are all set. */
7047 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
7048 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
7051 /* Normally we would be stuck at this point, since we cannot store
7052 the absolute address that is the destination of the branch in the
7053 24 bits of the branch instruction. If however, we happen to know
7054 that the destination of the branch is in the same section as the
7055 branch instruciton itself, then we can compute the relocation for
7056 ourselves and not have to bother the linker with it.
7058 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
7059 because I have not worked out how to do this for OBJ_COFF or
7062 && fixP
->fx_addsy
!= NULL
7063 && S_IS_DEFINED (fixP
->fx_addsy
)
7064 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
7066 /* Get pc relative value to go into the branch. */
7069 /* Permit a backward branch provided that enough bits
7070 are set. Allow a forwards branch, provided that
7071 enough bits are clear. */
7072 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
7073 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
7077 if (! fixP
->fx_done
)
7079 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7080 _("gas can't handle same-section branch dest >= 0x04000000"));
7084 value
+= SEXT24 (newval
);
7086 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
7087 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
7088 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7089 _("out of range branch"));
7091 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
7092 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7095 case BFD_RELOC_ARM_PCREL_BLX
:
7098 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7102 value
= fixP
->fx_offset
;
7104 hbit
= (value
>> 1) & 1;
7105 value
= (value
>> 2) & 0x00ffffff;
7106 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
7107 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
7108 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7112 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
7113 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7115 addressT diff
= (newval
& 0xff) << 1;
7120 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
7121 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7122 _("Branch out of range"));
7123 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
7125 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7128 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
7129 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7131 addressT diff
= (newval
& 0x7ff) << 1;
7136 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
7137 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7138 _("Branch out of range"));
7139 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
7141 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7144 case BFD_RELOC_THUMB_PCREL_BLX
:
7145 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
7150 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7151 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
7152 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
7153 if (diff
& 0x400000)
7156 value
= fixP
->fx_offset
;
7159 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
7160 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7161 _("Branch with link out of range"));
7163 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
7164 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
7165 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
)
7166 /* Remove bit zero of the adjusted offset. Bit zero can only be
7167 set if the upper insn is at a half-word boundary, since the
7168 destination address, an ARM instruction, must always be on a
7169 word boundary. The semantics of the BLX (1) instruction, however,
7170 are that bit zero in the offset must always be zero, and the
7171 corresponding bit one in the target address will be set from bit
7172 one of the source address. */
7174 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7175 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
7180 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7181 md_number_to_chars (buf
, value
, 1);
7183 else if (!target_oabi
)
7185 value
= fixP
->fx_offset
;
7186 md_number_to_chars (buf
, value
, 1);
7192 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7193 md_number_to_chars (buf
, value
, 2);
7195 else if (!target_oabi
)
7197 value
= fixP
->fx_offset
;
7198 md_number_to_chars (buf
, value
, 2);
7204 case BFD_RELOC_ARM_GOT32
:
7205 case BFD_RELOC_ARM_GOTOFF
:
7206 md_number_to_chars (buf
, 0, 4);
7212 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7213 md_number_to_chars (buf
, value
, 4);
7215 else if (!target_oabi
)
7217 value
= fixP
->fx_offset
;
7218 md_number_to_chars (buf
, value
, 4);
7224 case BFD_RELOC_ARM_PLT32
:
7225 /* It appears the instruction is fully prepared at this point. */
7229 case BFD_RELOC_ARM_GOTPC
:
7230 md_number_to_chars (buf
, value
, 4);
7233 case BFD_RELOC_ARM_CP_OFF_IMM
:
7235 if (value
< -1023 || value
> 1023 || (value
& 3))
7236 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7237 _("Illegal value for co-processor offset"));
7240 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
7241 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
7242 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7245 case BFD_RELOC_ARM_THUMB_OFFSET
:
7246 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7247 /* Exactly what ranges, and where the offset is inserted depends
7248 on the type of instruction, we can establish this from the
7250 switch (newval
>> 12)
7252 case 4: /* PC load. */
7253 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
7254 forced to zero for these loads, so we will need to round
7255 up the offset if the instruction address is not word
7256 aligned (since the final address produced must be, and
7257 we can only describe word-aligned immediate offsets). */
7259 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
7260 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7261 _("Invalid offset, target not word aligned (0x%08X)"),
7262 (unsigned int) (fixP
->fx_frag
->fr_address
7263 + fixP
->fx_where
+ value
));
7265 if ((value
+ 2) & ~0x3fe)
7266 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7267 _("Invalid offset, value too big (0x%08lX)"), value
);
7269 /* Round up, since pc will be rounded down. */
7270 newval
|= (value
+ 2) >> 2;
7273 case 9: /* SP load/store. */
7275 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7276 _("Invalid offset, value too big (0x%08lX)"), value
);
7277 newval
|= value
>> 2;
7280 case 6: /* Word load/store. */
7282 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7283 _("Invalid offset, value too big (0x%08lX)"), value
);
7284 newval
|= value
<< 4; /* 6 - 2. */
7287 case 7: /* Byte load/store. */
7289 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7290 _("Invalid offset, value too big (0x%08lX)"), value
);
7291 newval
|= value
<< 6;
7294 case 8: /* Halfword load/store. */
7296 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7297 _("Invalid offset, value too big (0x%08lX)"), value
);
7298 newval
|= value
<< 5; /* 6 - 1. */
7302 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7303 "Unable to process relocation for thumb opcode: %lx",
7304 (unsigned long) newval
);
7307 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7310 case BFD_RELOC_ARM_THUMB_ADD
:
7311 /* This is a complicated relocation, since we use it for all of
7312 the following immediate relocations:
7316 9bit ADD/SUB SP word-aligned
7317 10bit ADD PC/SP word-aligned
7319 The type of instruction being processed is encoded in the
7326 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7328 int rd
= (newval
>> 4) & 0xf;
7329 int rs
= newval
& 0xf;
7330 int subtract
= newval
& 0x8000;
7335 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7336 _("Invalid immediate for stack address calculation"));
7337 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
7338 newval
|= value
>> 2;
7340 else if (rs
== REG_PC
|| rs
== REG_SP
)
7344 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7345 _("Invalid immediate for address calculation (value = 0x%08lX)"),
7346 (unsigned long) value
);
7347 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
7349 newval
|= value
>> 2;
7354 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7355 _("Invalid 8bit immediate"));
7356 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
7357 newval
|= (rd
<< 8) | value
;
7362 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7363 _("Invalid 3bit immediate"));
7364 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
7365 newval
|= rd
| (rs
<< 3) | (value
<< 6);
7368 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7371 case BFD_RELOC_ARM_THUMB_IMM
:
7372 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7373 switch (newval
>> 11)
7375 case 0x04: /* 8bit immediate MOV. */
7376 case 0x05: /* 8bit immediate CMP. */
7377 if (value
< 0 || value
> 255)
7378 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7379 _("Invalid immediate: %ld is too large"),
7387 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7390 case BFD_RELOC_ARM_THUMB_SHIFT
:
7391 /* 5bit shift value (0..31). */
7392 if (value
< 0 || value
> 31)
7393 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7394 _("Illegal Thumb shift value: %ld"), (long) value
);
7395 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
7396 newval
|= value
<< 6;
7397 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7400 case BFD_RELOC_VTABLE_INHERIT
:
7401 case BFD_RELOC_VTABLE_ENTRY
:
7405 case BFD_RELOC_NONE
:
7407 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7408 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
7414 /* Translate internal representation of relocation info to BFD target
7418 tc_gen_reloc (section
, fixp
)
7419 asection
* section ATTRIBUTE_UNUSED
;
7423 bfd_reloc_code_real_type code
;
7425 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
7427 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
7428 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7429 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
7431 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
7433 if (fixp
->fx_pcrel
== 0)
7434 reloc
->addend
= fixp
->fx_offset
;
7436 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
7438 reloc
->addend
= fixp
->fx_offset
;
7441 switch (fixp
->fx_r_type
)
7446 code
= BFD_RELOC_8_PCREL
;
7453 code
= BFD_RELOC_16_PCREL
;
7460 code
= BFD_RELOC_32_PCREL
;
7464 case BFD_RELOC_ARM_PCREL_BRANCH
:
7465 case BFD_RELOC_ARM_PCREL_BLX
:
7467 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
7468 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
7469 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
7470 case BFD_RELOC_THUMB_PCREL_BLX
:
7471 case BFD_RELOC_VTABLE_ENTRY
:
7472 case BFD_RELOC_VTABLE_INHERIT
:
7473 code
= fixp
->fx_r_type
;
7476 case BFD_RELOC_ARM_LITERAL
:
7477 case BFD_RELOC_ARM_HWLITERAL
:
7478 /* If this is called then the a literal has been referenced across
7479 a section boundary - possibly due to an implicit dump. */
7480 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7481 _("Literal referenced across section boundary (Implicit dump?)"));
7485 case BFD_RELOC_ARM_GOT32
:
7486 case BFD_RELOC_ARM_GOTOFF
:
7487 case BFD_RELOC_ARM_PLT32
:
7488 code
= fixp
->fx_r_type
;
7492 case BFD_RELOC_ARM_IMMEDIATE
:
7493 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7494 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
7498 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
7499 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7500 _("ADRL used for a symbol not defined in the same file"));
7503 case BFD_RELOC_ARM_OFFSET_IMM
:
7504 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7505 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
7513 switch (fixp
->fx_r_type
)
7515 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
7516 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
7517 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
7518 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
7519 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
7520 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
7521 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
7522 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
7523 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
7524 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
7525 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
7526 default: type
= _("<unknown>"); break;
7528 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7529 _("Cannot represent %s relocation in this object file format"),
7536 if (code
== BFD_RELOC_32_PCREL
7538 && fixp
->fx_addsy
== GOT_symbol
)
7540 code
= BFD_RELOC_ARM_GOTPC
;
7541 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
7545 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
7547 if (reloc
->howto
== NULL
)
7549 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7550 _("Can not represent %s relocation in this object file format"),
7551 bfd_get_reloc_code_name (code
));
7555 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
7556 vtable entry to be used in the relocation's section offset. */
7557 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7558 reloc
->address
= fixp
->fx_offset
;
7564 md_estimate_size_before_relax (fragP
, segtype
)
7565 fragS
* fragP ATTRIBUTE_UNUSED
;
7566 segT segtype ATTRIBUTE_UNUSED
;
7568 as_fatal (_("md_estimate_size_before_relax\n"));
7573 output_inst
PARAMS ((void))
7579 as_bad (inst
.error
);
7583 to
= frag_more (inst
.size
);
7585 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
7587 assert (inst
.size
== (2 * THUMB_SIZE
));
7588 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
7589 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
7591 else if (inst
.size
> INSN_SIZE
)
7593 assert (inst
.size
== (2 * INSN_SIZE
));
7594 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
7595 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
7598 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
7600 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
7601 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
7602 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
7606 dwarf2_emit_insn (inst
.size
);
7619 /* Align the instruction.
7620 This may not be the right thing to do but ... */
7624 listing_prev_line (); /* Defined in listing.h. */
7626 /* Align the previous label if needed. */
7627 if (last_label_seen
!= NULL
)
7629 symbol_set_frag (last_label_seen
, frag_now
);
7630 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
7631 S_SET_SEGMENT (last_label_seen
, now_seg
);
7634 memset (&inst
, '\0', sizeof (inst
));
7635 inst
.reloc
.type
= BFD_RELOC_NONE
;
7637 skip_whitespace (str
);
7639 /* Scan up to the end of the op-code, which must end in white space or
7641 for (start
= p
= str
; *p
!= '\0'; p
++)
7647 as_bad (_("No operator -- statement `%s'\n"), str
);
7653 CONST
struct thumb_opcode
* opcode
;
7657 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
7662 /* Check that this instruction is supported for this CPU. */
7663 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
7665 as_bad (_("selected processor does not support this opcode"));
7669 inst
.instruction
= opcode
->value
;
7670 inst
.size
= opcode
->size
;
7671 (*opcode
->parms
) (p
);
7678 CONST
struct asm_opcode
* opcode
;
7679 unsigned long cond_code
;
7681 inst
.size
= INSN_SIZE
;
7682 /* P now points to the end of the opcode, probably white space, but we
7683 have to break the opcode up in case it contains condionals and flags;
7684 keep trying with progressively smaller basic instructions until one
7685 matches, or we run out of opcode. */
7686 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
7688 for (; q
!= str
; q
--)
7693 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
7696 if (opcode
&& opcode
->template)
7698 unsigned long flag_bits
= 0;
7701 /* Check that this instruction is supported for this CPU. */
7702 if ((opcode
->variants
& cpu_variant
) == 0)
7705 inst
.instruction
= opcode
->value
;
7706 if (q
== p
) /* Just a simple opcode. */
7708 if (opcode
->comp_suffix
)
7710 if (*opcode
->comp_suffix
!= '\0')
7711 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
7712 str
, opcode
->comp_suffix
);
7714 /* Not a conditional instruction. */
7715 (*opcode
->parms
) (q
, 0);
7719 /* A conditional instruction with default condition. */
7720 inst
.instruction
|= COND_ALWAYS
;
7721 (*opcode
->parms
) (q
, 0);
7727 /* Not just a simple opcode. Check if extra is a
7732 CONST
struct asm_cond
*cond
;
7736 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
7740 if (cond
->value
== 0xf0000000)
7742 _("Warning: Use of the 'nv' conditional is deprecated\n"));
7744 cond_code
= cond
->value
;
7748 cond_code
= COND_ALWAYS
;
7751 cond_code
= COND_ALWAYS
;
7753 /* Apply the conditional, or complain it's not allowed. */
7754 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
7756 /* Instruction isn't conditional. */
7757 if (cond_code
!= COND_ALWAYS
)
7759 as_bad (_("Opcode `%s' is unconditional\n"), str
);
7764 /* Instruction is conditional: set the condition into it. */
7765 inst
.instruction
|= cond_code
;
7767 /* If there is a compulsory suffix, it should come here
7768 before any optional flags. */
7769 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
7771 CONST
char *s
= opcode
->comp_suffix
;
7783 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
7784 str
, opcode
->comp_suffix
);
7791 /* The remainder, if any should now be flags for the instruction;
7792 Scan these checking each one found with the opcode. */
7796 CONST
struct asm_flg
*flag
= opcode
->flags
;
7805 for (flagno
= 0; flag
[flagno
].template; flagno
++)
7807 if (streq (r
, flag
[flagno
].template))
7809 flag_bits
|= flag
[flagno
].set_bits
;
7815 if (! flag
[flagno
].template)
7822 (*opcode
->parms
) (p
, flag_bits
);
7832 /* It wasn't an instruction, but it might be a register alias of the form
7835 skip_whitespace (q
);
7840 if (*q
&& !strncmp (q
, ".req ", 4))
7846 #ifdef IGNORE_OPCODE_CASE
7847 str
= original_case_string
;
7852 skip_whitespace (q
);
7854 for (r
= q
; *r
!= '\0'; r
++)
7864 regnum
= arm_reg_parse (& q
);
7867 reg
= arm_reg_parse (& str
);
7872 insert_reg_alias (str
, regnum
);
7874 as_warn (_("register '%s' does not exist\n"), q
);
7876 else if (regnum
!= FAIL
)
7879 as_warn (_("ignoring redefinition of register alias '%s'"),
7882 /* Do not warn about redefinitions to the same alias. */
7885 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
7889 as_warn (_("ignoring incomplete .req pseuso op"));
7896 as_bad (_("bad instruction `%s'"), start
);
7900 Invocation line includes a switch not recognized by the base assembler.
7901 See if it's a processor-specific option. These are:
7902 Cpu variants, the arm part is optional:
7903 -m[arm]1 Currently not supported.
7904 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
7905 -m[arm]3 Arm 3 processor
7906 -m[arm]6[xx], Arm 6 processors
7907 -m[arm]7[xx][t][[d]m] Arm 7 processors
7908 -m[arm]8[10] Arm 8 processors
7909 -m[arm]9[20][tdmi] Arm 9 processors
7910 -mstrongarm[110[0]] StrongARM processors
7911 -mxscale XScale processors
7912 -m[arm]v[2345[t[e]]] Arm architectures
7913 -mall All (except the ARM1)
7915 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
7916 -mfpe-old (No float load/store multiples)
7917 -mno-fpu Disable all floating point instructions
7918 Run-time endian selection:
7920 -EL little endian cpu
7921 ARM Procedure Calling Standard:
7922 -mapcs-32 32 bit APCS
7923 -mapcs-26 26 bit APCS
7924 -mapcs-float Pass floats in float regs
7925 -mapcs-reentrant Position independent code
7926 -mthumb-interwork Code supports Arm/Thumb interworking
7927 -matpcs ARM/Thumb Procedure Call Standard
7928 -moabi Old ELF ABI */
7930 CONST
char * md_shortopts
= "m:k";
7932 struct option md_longopts
[] =
7934 #ifdef ARM_BI_ENDIAN
7935 #define OPTION_EB (OPTION_MD_BASE + 0)
7936 {"EB", no_argument
, NULL
, OPTION_EB
},
7937 #define OPTION_EL (OPTION_MD_BASE + 1)
7938 {"EL", no_argument
, NULL
, OPTION_EL
},
7940 #define OPTION_OABI (OPTION_MD_BASE +2)
7941 {"oabi", no_argument
, NULL
, OPTION_OABI
},
7944 {NULL
, no_argument
, NULL
, 0}
7947 size_t md_longopts_size
= sizeof (md_longopts
);
7950 md_parse_option (c
, arg
)
7958 #ifdef ARM_BI_ENDIAN
7960 target_big_endian
= 1;
7963 target_big_endian
= 0;
7971 if (streq (str
, "fpa10"))
7972 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
7973 else if (streq (str
, "fpa11"))
7974 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
7975 else if (streq (str
, "fpe-old"))
7976 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
7982 if (streq (str
, "no-fpu"))
7983 cpu_variant
&= ~FPU_ALL
;
7988 if (streq (str
, "oabi"))
7994 /* Limit assembler to generating only Thumb instructions: */
7995 if (streq (str
, "thumb"))
7997 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_EXT_THUMB
;
7998 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
8001 else if (streq (str
, "thumb-interwork"))
8003 if ((cpu_variant
& ARM_EXT_THUMB
) == 0)
8004 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
8005 #if defined OBJ_COFF || defined OBJ_ELF
8006 support_interwork
= true;
8014 if (streq (str
, "all"))
8016 cpu_variant
= ARM_ALL
| FPU_ALL
;
8019 #if defined OBJ_COFF || defined OBJ_ELF
8020 if (! strncmp (str
, "apcs-", 5))
8022 /* GCC passes on all command line options starting "-mapcs-..."
8023 to us, so we must parse them here. */
8027 if (streq (str
, "32"))
8029 uses_apcs_26
= false;
8032 else if (streq (str
, "26"))
8034 uses_apcs_26
= true;
8037 else if (streq (str
, "frame"))
8039 /* Stack frames are being generated - does not affect
8043 else if (streq (str
, "stack-check"))
8045 /* Stack checking is being performed - does not affect
8046 linkage, but does require that the functions
8047 __rt_stkovf_split_small and __rt_stkovf_split_big be
8048 present in the final link. */
8052 else if (streq (str
, "float"))
8054 /* Floating point arguments are being passed in the floating
8055 point registers. This does affect linking, since this
8056 version of the APCS is incompatible with the version that
8057 passes floating points in the integer registers. */
8059 uses_apcs_float
= true;
8062 else if (streq (str
, "reentrant"))
8064 /* Reentrant code has been generated. This does affect
8065 linking, since there is no point in linking reentrant/
8066 position independent code with absolute position code. */
8071 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
8075 if (! strcmp (str
, "atpcs"))
8081 /* Strip off optional "arm". */
8082 if (! strncmp (str
, "arm", 3))
8088 if (streq (str
, "1"))
8089 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
8095 if (streq (str
, "2"))
8096 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
8097 else if (streq (str
, "250"))
8098 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
8104 if (streq (str
, "3"))
8105 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
8111 switch (strtol (str
, NULL
, 10))
8118 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
8126 /* Eat the processor name. */
8127 switch (strtol (str
, & str
, 10))
8140 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
8146 cpu_variant
|= ARM_ARCH_V4T
;
8150 cpu_variant
|= ARM_EXT_LONGMUL
;
8153 case 'f': /* fe => fp enabled cpu. */
8159 case 'c': /* Left over from 710c processor name. */
8160 case 'd': /* Debug. */
8161 case 'i': /* Embedded ICE. */
8162 /* Included for completeness in ARM processor naming. */
8172 if (streq (str
, "8") || streq (str
, "810"))
8173 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8174 | ARM_8
| ARM_ARCH_V4
;
8180 if (streq (str
, "9"))
8181 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8182 | ARM_9
| ARM_ARCH_V4T
;
8183 else if (streq (str
, "920"))
8184 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8185 | ARM_9
| ARM_ARCH_V4
;
8186 else if (streq (str
, "920t"))
8187 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8188 | ARM_9
| ARM_ARCH_V4T
;
8189 else if (streq (str
, "9tdmi"))
8190 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8191 | ARM_9
| ARM_ARCH_V4T
;
8197 if (streq (str
, "strongarm")
8198 || streq (str
, "strongarm110")
8199 || streq (str
, "strongarm1100"))
8200 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8201 | ARM_8
| ARM_ARCH_V4
;
8207 if (streq (str
, "xscale"))
8208 cpu_variant
= ARM_9
| ARM_ARCH_XSCALE
;
8214 /* Select variant based on architecture rather than
8222 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
8225 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
8228 as_bad (_("Invalid architecture variant -m%s"), arg
);
8234 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
8238 case 'm': cpu_variant
|= ARM_EXT_LONGMUL
; break;
8241 as_bad (_("Invalid architecture variant -m%s"), arg
);
8247 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCH_V4
;
8251 case 't': cpu_variant
|= ARM_EXT_THUMB
; break;
8254 as_bad (_("Invalid architecture variant -m%s"), arg
);
8260 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V5
;
8263 case 't': cpu_variant
|= ARM_EXT_THUMB
; break;
8264 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
8267 as_bad (_("Invalid architecture variant -m%s"), arg
);
8273 as_bad (_("Invalid architecture variant -m%s"), arg
);
8280 as_bad (_("Invalid processor variant -m%s"), arg
);
8286 #if defined OBJ_ELF || defined OBJ_COFF
8304 ARM Specific Assembler Options:\n\
8305 -m[arm][<processor name>] select processor variant\n\
8306 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
8307 -mthumb only allow Thumb instructions\n\
8308 -mthumb-interwork mark the assembled code as supporting interworking\n\
8309 -mall allow any instruction\n\
8310 -mfpa10, -mfpa11 select floating point architecture\n\
8311 -mfpe-old don't allow floating-point multiple instructions\n\
8312 -mno-fpu don't allow any floating-point instructions.\n\
8313 -k generate PIC code.\n"));
8314 #if defined OBJ_COFF || defined OBJ_ELF
8316 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
8317 -matpcs use ARM/Thumb Procedure Calling Standard\n\
8318 -mapcs-float floating point args are passed in FP regs\n\
8319 -mapcs-reentrant the code is position independent/reentrant\n"));
8323 -moabi support the old ELF ABI\n"));
8325 #ifdef ARM_BI_ENDIAN
8327 -EB assemble code for a big endian cpu\n\
8328 -EL assemble code for a little endian cpu\n"));
8332 /* We need to be able to fix up arbitrary expressions in some statements.
8333 This is so that we can handle symbols that are an arbitrary distance from
8334 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
8335 which returns part of an address in a form which will be valid for
8336 a data instruction. We do this by pushing the expression into a symbol
8337 in the expr_section, and creating a fix for that. */
8340 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
8349 arm_fix_data
* arm_data
;
8357 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
8361 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
8366 /* Mark whether the fix is to a THUMB instruction, or an ARM
8368 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
8369 new_fix
->tc_fix_data
= (PTR
) arm_data
;
8370 arm_data
->thumb_mode
= thumb_mode
;
8375 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
8378 cons_fix_new_arm (frag
, where
, size
, exp
)
8384 bfd_reloc_code_real_type type
;
8388 FIXME: @@ Should look at CPU word size. */
8395 type
= BFD_RELOC_16
;
8399 type
= BFD_RELOC_32
;
8402 type
= BFD_RELOC_64
;
8406 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
8409 /* A good place to do this, although this was probably not intended
8410 for this kind of use. We need to dump the literal pool before
8411 references are made to a null symbol pointer. */
8416 if (current_poolP
== NULL
)
8419 /* Put it at the end of text section. */
8420 subseg_set (text_section
, 0);
8422 listing_prev_line ();
8426 arm_start_line_hook ()
8428 last_label_seen
= NULL
;
8432 arm_frob_label (sym
)
8435 last_label_seen
= sym
;
8437 ARM_SET_THUMB (sym
, thumb_mode
);
8439 #if defined OBJ_COFF || defined OBJ_ELF
8440 ARM_SET_INTERWORK (sym
, support_interwork
);
8443 /* Note - do not allow local symbols (.Lxxx) to be labeled
8444 as Thumb functions. This is because these labels, whilst
8445 they exist inside Thumb code, are not the entry points for
8446 possible ARM->Thumb calls. Also, these labels can be used
8447 as part of a computed goto or switch statement. eg gcc
8448 can generate code that looks like this:
8460 The first instruction loads the address of the jump table.
8461 The second instruction converts a table index into a byte offset.
8462 The third instruction gets the jump address out of the table.
8463 The fourth instruction performs the jump.
8465 If the address stored at .Laaa is that of a symbol which has the
8466 Thumb_Func bit set, then the linker will arrange for this address
8467 to have the bottom bit set, which in turn would mean that the
8468 address computation performed by the third instruction would end
8469 up with the bottom bit set. Since the ARM is capable of unaligned
8470 word loads, the instruction would then load the incorrect address
8471 out of the jump table, and chaos would ensue. */
8472 if (label_is_thumb_function_name
8473 && (S_GET_NAME (sym
)[0] != '.' || S_GET_NAME (sym
)[1] != 'L')
8474 && (bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
8476 /* When the address of a Thumb function is taken the bottom
8477 bit of that address should be set. This will allow
8478 interworking between Arm and Thumb functions to work
8481 THUMB_SET_FUNC (sym
, 1);
8483 label_is_thumb_function_name
= false;
8487 /* Adjust the symbol table. This marks Thumb symbols as distinct from
8491 arm_adjust_symtab ()
8496 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
8498 if (ARM_IS_THUMB (sym
))
8500 if (THUMB_IS_FUNC (sym
))
8502 /* Mark the symbol as a Thumb function. */
8503 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
8504 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
8505 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
8507 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
8508 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
8510 as_bad (_("%s: unexpected function type: %d"),
8511 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
8513 else switch (S_GET_STORAGE_CLASS (sym
))
8516 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
8519 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
8522 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
8530 if (ARM_IS_INTERWORK (sym
))
8531 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
8538 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
8540 if (ARM_IS_THUMB (sym
))
8542 elf_symbol_type
* elf_sym
;
8544 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
8545 bind
= ELF_ST_BIND (elf_sym
);
8547 /* If it's a .thumb_func, declare it as so,
8548 otherwise tag label as .code 16. */
8549 if (THUMB_IS_FUNC (sym
))
8550 elf_sym
->internal_elf_sym
.st_info
=
8551 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
8553 elf_sym
->internal_elf_sym
.st_info
=
8554 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
8563 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
8565 *input_line_pointer
= '/';
8566 input_line_pointer
+= 5;
8567 *input_line_pointer
= 0;
8575 arm_canonicalize_symbol_name (name
)
8580 if (thumb_mode
&& (len
= strlen (name
)) > 5
8581 && streq (name
+ len
- 5, "/data"))
8582 *(name
+ len
- 5) = 0;
8588 arm_validate_fix (fixP
)
8591 /* If the destination of the branch is a defined symbol which does not have
8592 the THUMB_FUNC attribute, then we must be calling a function which has
8593 the (interfacearm) attribute. We look for the Thumb entry point to that
8594 function and change the branch to refer to that function instead. */
8595 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
8596 && fixP
->fx_addsy
!= NULL
8597 && S_IS_DEFINED (fixP
->fx_addsy
)
8598 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
8600 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
8608 /* This is a little hack to help the gas/arm/adrl.s test. It prevents
8609 local labels from being added to the output symbol table when they
8610 are used with the ADRL pseudo op. The ADRL relocation should always
8611 be resolved before the binbary is emitted, so it is safe to say that
8612 it is adjustable. */
8615 arm_fix_adjustable (fixP
)
8618 if (fixP
->fx_r_type
== BFD_RELOC_ARM_ADRL_IMMEDIATE
)
8624 /* Relocations against Thumb function names must be left unadjusted,
8625 so that the linker can use this information to correctly set the
8626 bottom bit of their addresses. The MIPS version of this function
8627 also prevents relocations that are mips-16 specific, but I do not
8628 know why it does this.
8631 There is one other problem that ought to be addressed here, but
8632 which currently is not: Taking the address of a label (rather
8633 than a function) and then later jumping to that address. Such
8634 addresses also ought to have their bottom bit set (assuming that
8635 they reside in Thumb code), but at the moment they will not. */
8638 arm_fix_adjustable (fixP
)
8641 if (fixP
->fx_addsy
== NULL
)
8644 /* Prevent all adjustments to global symbols. */
8645 if (S_IS_EXTERN (fixP
->fx_addsy
))
8648 if (S_IS_WEAK (fixP
->fx_addsy
))
8651 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
8652 && fixP
->fx_subsy
== NULL
)
8655 /* We need the symbol name for the VTABLE entries. */
8656 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
8657 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
8664 elf32_arm_target_format ()
8666 if (target_big_endian
)
8669 return "elf32-bigarm-oabi";
8671 return "elf32-bigarm";
8676 return "elf32-littlearm-oabi";
8678 return "elf32-littlearm";
8683 armelf_frob_symbol (symp
, puntp
)
8687 elf_frob_symbol (symp
, puntp
);
8691 arm_force_relocation (fixp
)
8694 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
8695 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
8696 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
8697 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
8698 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
8699 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
8705 static bfd_reloc_code_real_type
8715 bfd_reloc_code_real_type reloc
;
8719 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
8720 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
8721 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
8722 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
8723 branch instructions generated by GCC for PLT relocs. */
8724 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
8725 { NULL
, 0, BFD_RELOC_UNUSED
}
8729 for (i
= 0, ip
= input_line_pointer
;
8730 i
< sizeof (id
) && (ISALNUM (*ip
) || ISPUNCT (*ip
));
8732 id
[i
] = TOLOWER (*ip
);
8734 for (i
= 0; reloc_map
[i
].str
; i
++)
8735 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
8738 input_line_pointer
+= reloc_map
[i
].len
;
8740 return reloc_map
[i
].reloc
;
8744 s_arm_elf_cons (nbytes
)
8749 #ifdef md_flush_pending_output
8750 md_flush_pending_output ();
8753 if (is_it_end_of_statement ())
8755 demand_empty_rest_of_line ();
8759 #ifdef md_cons_align
8760 md_cons_align (nbytes
);
8765 bfd_reloc_code_real_type reloc
;
8769 if (exp
.X_op
== O_symbol
8770 && * input_line_pointer
== '('
8771 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
8773 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
8774 int size
= bfd_get_reloc_size (howto
);
8777 as_bad ("%s relocations do not fit in %d bytes",
8778 howto
->name
, nbytes
);
8781 register char *p
= frag_more ((int) nbytes
);
8782 int offset
= nbytes
- size
;
8784 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
8789 emit_expr (&exp
, (unsigned int) nbytes
);
8791 while (*input_line_pointer
++ == ',');
8793 /* Put terminator back into stream. */
8794 input_line_pointer
--;
8795 demand_empty_rest_of_line ();
8798 #endif /* OBJ_ELF */
8800 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
8801 of an rs_align_code fragment. */
8804 arm_handle_align (fragP
)
8807 static char const arm_noop
[4] = { 0x00, 0x00, 0xa0, 0xe1 };
8808 static char const thumb_noop
[2] = { 0xc0, 0x46 };
8809 static char const arm_bigend_noop
[4] = { 0xe1, 0xa0, 0x00, 0x00 };
8810 static char const thumb_bigend_noop
[2] = { 0x46, 0xc0 };
8812 int bytes
, fix
, noop_size
;
8816 if (fragP
->fr_type
!= rs_align_code
)
8819 bytes
= fragP
->fr_next
->fr_address
- fragP
->fr_address
- fragP
->fr_fix
;
8820 p
= fragP
->fr_literal
+ fragP
->fr_fix
;
8823 if (bytes
> MAX_MEM_FOR_RS_ALIGN_CODE
)
8824 bytes
&= MAX_MEM_FOR_RS_ALIGN_CODE
;
8826 if (fragP
->tc_frag_data
)
8828 if (target_big_endian
)
8829 noop
= thumb_bigend_noop
;
8832 noop_size
= sizeof (thumb_noop
);
8836 if (target_big_endian
)
8837 noop
= arm_bigend_noop
;
8840 noop_size
= sizeof (arm_noop
);
8843 if (bytes
& (noop_size
- 1))
8845 fix
= bytes
& (noop_size
- 1);
8851 while (bytes
>= noop_size
)
8853 memcpy (p
, noop
, noop_size
);
8859 fragP
->fr_fix
+= fix
;
8860 fragP
->fr_var
= noop_size
;
8863 /* Called from md_do_align. Used to create an alignment
8864 frag in a code section. */
8867 arm_frag_align_code (n
, max
)
8873 /* We assume that there will never be a requirment
8874 to support alignments greater than 32 bytes. */
8875 if (max
> MAX_MEM_FOR_RS_ALIGN_CODE
)
8876 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
8878 p
= frag_var (rs_align_code
,
8879 MAX_MEM_FOR_RS_ALIGN_CODE
,
8881 (relax_substateT
) max
,
8889 /* Perform target specific initialisation of a frag. */
8892 arm_init_frag (fragP
)
8895 /* Record whether this frag is in an ARM or a THUMB area. */
8896 fragP
->tc_frag_data
= thumb_mode
;