1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000
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
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 cplong_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_adrl
PARAMS ((char *, unsigned long));
594 static void do_nop
PARAMS ((char *, unsigned long));
596 static void do_mul
PARAMS ((char *, unsigned long));
597 static void do_mla
PARAMS ((char *, unsigned long));
599 static void do_swap
PARAMS ((char *, unsigned long));
601 static void do_msr
PARAMS ((char *, unsigned long));
602 static void do_mrs
PARAMS ((char *, unsigned long));
604 static void do_mull
PARAMS ((char *, unsigned long));
606 static void do_bx
PARAMS ((char *, unsigned long));
608 /* ARM_EXT_XScale. */
609 static void do_mia
PARAMS ((char *, unsigned long));
610 static void do_mar
PARAMS ((char *, unsigned long));
611 static void do_mra
PARAMS ((char *, unsigned long));
612 static void do_pld
PARAMS ((char *, unsigned long));
613 static void do_ldrd
PARAMS ((char *, unsigned long));
616 static void do_blx
PARAMS ((char *, unsigned long));
617 static void do_bkpt
PARAMS ((char *, unsigned long));
618 static void do_clz
PARAMS ((char *, unsigned long));
619 static void do_lstc2
PARAMS ((char *, unsigned long));
620 static void do_cdp2
PARAMS ((char *, unsigned long));
621 static void do_co_reg2
PARAMS ((char *, unsigned long));
623 static void do_t_blx
PARAMS ((char *));
624 static void do_t_bkpt
PARAMS ((char *));
627 static void do_smla
PARAMS ((char *, unsigned long));
628 static void do_smlal
PARAMS ((char *, unsigned long));
629 static void do_smul
PARAMS ((char *, unsigned long));
630 static void do_qadd
PARAMS ((char *, unsigned long));
631 static void do_co_reg2c
PARAMS ((char *, unsigned long));
633 /* Coprocessor Instructions. */
634 static void do_cdp
PARAMS ((char *, unsigned long));
635 static void do_lstc
PARAMS ((char *, unsigned long));
636 static void do_co_reg
PARAMS ((char *, unsigned long));
637 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
638 static void do_fp_ldst
PARAMS ((char *, unsigned long));
639 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
640 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
641 static void do_fp_monadic
PARAMS ((char *, unsigned long));
642 static void do_fp_cmp
PARAMS ((char *, unsigned long));
643 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
644 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
646 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
647 static int arm_reg_parse
PARAMS ((char **));
648 static CONST
struct asm_psr
* arm_psr_parse
PARAMS ((char **));
649 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
650 static int add_to_lit_pool
PARAMS ((void));
651 static unsigned validate_immediate
PARAMS ((unsigned));
652 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
653 static int validate_offset_imm
PARAMS ((unsigned int, int));
654 static void opcode_select
PARAMS ((int));
655 static void end_of_line
PARAMS ((char *));
656 static int reg_required_here
PARAMS ((char **, int));
657 static int psr_required_here
PARAMS ((char **));
658 static int co_proc_number
PARAMS ((char **));
659 static int cp_opc_expr
PARAMS ((char **, int, int));
660 static int cp_reg_required_here
PARAMS ((char **, int));
661 static int fp_reg_required_here
PARAMS ((char **, int));
662 static int cp_address_offset
PARAMS ((char **));
663 static int cp_address_required_here
PARAMS ((char **));
664 static int my_get_float_expression
PARAMS ((char **));
665 static int skip_past_comma
PARAMS ((char **));
666 static int walk_no_bignums
PARAMS ((symbolS
*));
667 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
668 static int data_op2
PARAMS ((char **));
669 static int fp_op2
PARAMS ((char **));
670 static long reg_list
PARAMS ((char **));
671 static void thumb_load_store
PARAMS ((char *, int, int));
672 static int decode_shift
PARAMS ((char **, int));
673 static int ldst_extend
PARAMS ((char **, int));
674 static void thumb_add_sub
PARAMS ((char *, int));
675 static void insert_reg
PARAMS ((int));
676 static void thumb_shift
PARAMS ((char *, int));
677 static void thumb_mov_compare
PARAMS ((char *, int));
678 static void set_constant_flonums
PARAMS ((void));
679 static valueT md_chars_to_number
PARAMS ((char *, int));
680 static void insert_reg_alias
PARAMS ((char *, int));
681 static void output_inst
PARAMS ((void));
683 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
686 /* ARM instructions take 4bytes in the object file, Thumb instructions
690 /* LONGEST_INST is the longest basic instruction name without
691 conditions or flags. ARM7M has 4 of length 5. El Segundo
692 has one basic instruction name of length 7 (SMLALxy). */
693 #define LONGEST_INST 7
697 /* Basic string to match. */
698 CONST
char * template;
700 /* Basic instruction code. */
703 /* Compulsory suffix that must follow conds. If "", then the
704 instruction is not conditional and must have no suffix. */
705 CONST
char * comp_suffix
;
707 /* Bits to toggle if flag 'n' set. */
708 CONST
struct asm_flg
* flags
;
710 /* Which CPU variants this exists for. */
711 unsigned long variants
;
713 /* Function to call to parse args. */
714 void (* parms
) PARAMS ((char *, unsigned long));
717 static CONST
struct asm_opcode insns
[] =
719 /* Intel XScale extensions to ARM V5 ISA. */
720 {"mia", 0x0e200010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
721 {"miaph", 0x0e280010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
722 {"miabb", 0x0e2c0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
723 {"miabt", 0x0e2d0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
724 {"miatb", 0x0e2e0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
725 {"miatt", 0x0e2f0010, NULL
, NULL
, ARM_EXT_XSCALE
, do_mia
},
726 {"mar", 0x0c400000, NULL
, NULL
, ARM_EXT_XSCALE
, do_mar
},
727 {"mra", 0x0c500000, NULL
, NULL
, ARM_EXT_XSCALE
, do_mra
},
728 {"pld", 0xf450f000, "", NULL
, ARM_EXT_XSCALE
, do_pld
},
729 {"ldr", 0x000000d0, NULL
, ldr_flags
, ARM_ANY
, do_ldrd
},
730 {"str", 0x000000f0, NULL
, str_flags
, ARM_ANY
, do_ldrd
},
732 /* ARM Instructions. */
733 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
734 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
735 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
736 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
737 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
738 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
739 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
740 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
741 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
742 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
743 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
744 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
745 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
746 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
747 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
748 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
749 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
750 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
751 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
752 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
753 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
755 {"bl", 0x0b000000, NULL
, NULL
, ARM_ANY
, do_branch
},
756 {"b", 0x0a000000, NULL
, NULL
, ARM_ANY
, do_branch
},
758 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
759 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
763 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
764 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
765 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
767 /* ARM 2 multiplies. */
768 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
769 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
771 /* ARM 3 - swp instructions. */
772 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
774 /* ARM 6 Coprocessor instructions. */
775 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
776 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
777 /* ScottB: our code uses 0x0128f000 for msr.
778 NickC: but this is wrong because the bits 16 through 19 are
779 handled by the PSR_xxx defines above. */
781 /* ARM 7M long multiplies - need signed/unsigned flags! */
782 {"smull", 0x00c00090, NULL
, s_flag
, ARM_EXT_LONGMUL
, do_mull
},
783 {"umull", 0x00800090, NULL
, s_flag
, ARM_EXT_LONGMUL
, do_mull
},
784 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_EXT_LONGMUL
, do_mull
},
785 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_EXT_LONGMUL
, do_mull
},
787 /* ARM THUMB interworking. */
788 {"bx", 0x012fff10, NULL
, NULL
, ARM_EXT_THUMB
, do_bx
},
790 /* Floating point instructions. */
791 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
792 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
793 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
794 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
795 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
796 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
797 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
798 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
799 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
800 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
801 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
802 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
803 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
804 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
805 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
806 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
807 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
808 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
809 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
810 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
811 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
812 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
813 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
814 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
815 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
816 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
817 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
818 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
819 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
820 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
821 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
822 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
823 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
824 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
825 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
826 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
827 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
828 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
829 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
830 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
831 be an optional suffix, but part of the instruction. To be compatible,
833 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
834 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
835 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
836 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
838 /* Generic copressor instructions. */
839 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
840 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
841 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
842 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
843 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
845 /* ARM ISA extension 5. */
846 /* Note: blx is actually 2 opcodes, so the .value is set dynamically.
847 And it's sometimes conditional and sometimes not. */
848 {"blx", 0, NULL
, NULL
, ARM_EXT_V5
, do_blx
},
849 {"clz", 0x016f0f10, NULL
, NULL
, ARM_EXT_V5
, do_clz
},
850 {"bkpt", 0xe1200070, "", NULL
, ARM_EXT_V5
, do_bkpt
},
851 {"ldc2", 0xfc100000, "", cplong_flag
, ARM_EXT_V5
, do_lstc2
},
852 {"stc2", 0xfc000000, "", cplong_flag
, ARM_EXT_V5
, do_lstc2
},
853 {"cdp2", 0xfe000000, "", NULL
, ARM_EXT_V5
, do_cdp2
},
854 {"mcr2", 0xfe000010, "", NULL
, ARM_EXT_V5
, do_co_reg2
},
855 {"mrc2", 0xfe100010, "", NULL
, ARM_EXT_V5
, do_co_reg2
},
857 /* ARM ISA extension 5E, El Segundo. */
858 {"smlabb", 0x01000080, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
859 {"smlatb", 0x010000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
860 {"smlabt", 0x010000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
861 {"smlatt", 0x010000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
863 {"smlawb", 0x01200080, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
864 {"smlawt", 0x012000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smla
},
866 {"smlalbb",0x01400080, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
867 {"smlaltb",0x014000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
868 {"smlalbt",0x014000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
869 {"smlaltt",0x014000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smlal
},
871 {"smulbb", 0x01600080, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
872 {"smultb", 0x016000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
873 {"smulbt", 0x016000c0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
874 {"smultt", 0x016000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
876 {"smulwb", 0x012000a0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
877 {"smulwt", 0x012000e0, NULL
, NULL
, ARM_EXT_V5E
, do_smul
},
879 {"qadd", 0x01000050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
880 {"qdadd", 0x01400050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
881 {"qsub", 0x01200050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
882 {"qdsub", 0x01600050, NULL
, NULL
, ARM_EXT_V5E
, do_qadd
},
884 {"mcrr", 0x0c400000, NULL
, NULL
, ARM_EXT_V5E
, do_co_reg2c
},
885 {"mrrc", 0x0c500000, NULL
, NULL
, ARM_EXT_V5E
, do_co_reg2c
},
888 /* Defines for various bits that we will want to toggle. */
889 #define INST_IMMEDIATE 0x02000000
890 #define OFFSET_REG 0x02000000
891 #define HWOFFSET_IMM 0x00400000
892 #define SHIFT_BY_REG 0x00000010
893 #define PRE_INDEX 0x01000000
894 #define INDEX_UP 0x00800000
895 #define WRITE_BACK 0x00200000
896 #define LDM_TYPE_2_OR_3 0x00400000
898 #define LITERAL_MASK 0xf000f000
899 #define COND_MASK 0xf0000000
900 #define OPCODE_MASK 0xfe1fffff
901 #define DATA_OP_SHIFT 21
903 /* Codes to distinguish the arithmetic instructions. */
914 #define OPCODE_CMP 10
915 #define OPCODE_CMN 11
916 #define OPCODE_ORR 12
917 #define OPCODE_MOV 13
918 #define OPCODE_BIC 14
919 #define OPCODE_MVN 15
921 static void do_t_nop
PARAMS ((char *));
922 static void do_t_arit
PARAMS ((char *));
923 static void do_t_add
PARAMS ((char *));
924 static void do_t_asr
PARAMS ((char *));
925 static void do_t_branch9
PARAMS ((char *));
926 static void do_t_branch12
PARAMS ((char *));
927 static void do_t_branch23
PARAMS ((char *));
928 static void do_t_bx
PARAMS ((char *));
929 static void do_t_compare
PARAMS ((char *));
930 static void do_t_ldmstm
PARAMS ((char *));
931 static void do_t_ldr
PARAMS ((char *));
932 static void do_t_ldrb
PARAMS ((char *));
933 static void do_t_ldrh
PARAMS ((char *));
934 static void do_t_lds
PARAMS ((char *));
935 static void do_t_lsl
PARAMS ((char *));
936 static void do_t_lsr
PARAMS ((char *));
937 static void do_t_mov
PARAMS ((char *));
938 static void do_t_push_pop
PARAMS ((char *));
939 static void do_t_str
PARAMS ((char *));
940 static void do_t_strb
PARAMS ((char *));
941 static void do_t_strh
PARAMS ((char *));
942 static void do_t_sub
PARAMS ((char *));
943 static void do_t_swi
PARAMS ((char *));
944 static void do_t_adr
PARAMS ((char *));
946 #define T_OPCODE_MUL 0x4340
947 #define T_OPCODE_TST 0x4200
948 #define T_OPCODE_CMN 0x42c0
949 #define T_OPCODE_NEG 0x4240
950 #define T_OPCODE_MVN 0x43c0
952 #define T_OPCODE_ADD_R3 0x1800
953 #define T_OPCODE_SUB_R3 0x1a00
954 #define T_OPCODE_ADD_HI 0x4400
955 #define T_OPCODE_ADD_ST 0xb000
956 #define T_OPCODE_SUB_ST 0xb080
957 #define T_OPCODE_ADD_SP 0xa800
958 #define T_OPCODE_ADD_PC 0xa000
959 #define T_OPCODE_ADD_I8 0x3000
960 #define T_OPCODE_SUB_I8 0x3800
961 #define T_OPCODE_ADD_I3 0x1c00
962 #define T_OPCODE_SUB_I3 0x1e00
964 #define T_OPCODE_ASR_R 0x4100
965 #define T_OPCODE_LSL_R 0x4080
966 #define T_OPCODE_LSR_R 0x40c0
967 #define T_OPCODE_ASR_I 0x1000
968 #define T_OPCODE_LSL_I 0x0000
969 #define T_OPCODE_LSR_I 0x0800
971 #define T_OPCODE_MOV_I8 0x2000
972 #define T_OPCODE_CMP_I8 0x2800
973 #define T_OPCODE_CMP_LR 0x4280
974 #define T_OPCODE_MOV_HR 0x4600
975 #define T_OPCODE_CMP_HR 0x4500
977 #define T_OPCODE_LDR_PC 0x4800
978 #define T_OPCODE_LDR_SP 0x9800
979 #define T_OPCODE_STR_SP 0x9000
980 #define T_OPCODE_LDR_IW 0x6800
981 #define T_OPCODE_STR_IW 0x6000
982 #define T_OPCODE_LDR_IH 0x8800
983 #define T_OPCODE_STR_IH 0x8000
984 #define T_OPCODE_LDR_IB 0x7800
985 #define T_OPCODE_STR_IB 0x7000
986 #define T_OPCODE_LDR_RW 0x5800
987 #define T_OPCODE_STR_RW 0x5000
988 #define T_OPCODE_LDR_RH 0x5a00
989 #define T_OPCODE_STR_RH 0x5200
990 #define T_OPCODE_LDR_RB 0x5c00
991 #define T_OPCODE_STR_RB 0x5400
993 #define T_OPCODE_PUSH 0xb400
994 #define T_OPCODE_POP 0xbc00
996 #define T_OPCODE_BRANCH 0xe7fe
998 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
1000 #define THUMB_SIZE 2 /* Size of thumb instruction. */
1001 #define THUMB_REG_LO 0x1
1002 #define THUMB_REG_HI 0x2
1003 #define THUMB_REG_ANY 0x3
1005 #define THUMB_H1 0x0080
1006 #define THUMB_H2 0x0040
1012 #define THUMB_MOVE 0
1013 #define THUMB_COMPARE 1
1015 #define THUMB_LOAD 0
1016 #define THUMB_STORE 1
1018 #define THUMB_PP_PC_LR 0x0100
1020 /* These three are used for immediate shifts, do not alter. */
1021 #define THUMB_WORD 2
1022 #define THUMB_HALFWORD 1
1023 #define THUMB_BYTE 0
1027 /* Basic string to match. */
1028 CONST
char * template;
1030 /* Basic instruction code. */
1031 unsigned long value
;
1035 /* Which CPU variants this exists for. */
1036 unsigned long variants
;
1038 /* Function to call to parse args. */
1039 void (* parms
) PARAMS ((char *));
1042 static CONST
struct thumb_opcode tinsns
[] =
1044 {"adc", 0x4140, 2, ARM_EXT_THUMB
, do_t_arit
},
1045 {"add", 0x0000, 2, ARM_EXT_THUMB
, do_t_add
},
1046 {"and", 0x4000, 2, ARM_EXT_THUMB
, do_t_arit
},
1047 {"asr", 0x0000, 2, ARM_EXT_THUMB
, do_t_asr
},
1048 {"b", T_OPCODE_BRANCH
, 2, ARM_EXT_THUMB
, do_t_branch12
},
1049 {"beq", 0xd0fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1050 {"bne", 0xd1fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1051 {"bcs", 0xd2fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1052 {"bhs", 0xd2fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1053 {"bcc", 0xd3fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1054 {"bul", 0xd3fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1055 {"blo", 0xd3fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1056 {"bmi", 0xd4fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1057 {"bpl", 0xd5fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1058 {"bvs", 0xd6fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1059 {"bvc", 0xd7fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1060 {"bhi", 0xd8fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1061 {"bls", 0xd9fe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1062 {"bge", 0xdafe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1063 {"blt", 0xdbfe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1064 {"bgt", 0xdcfe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1065 {"ble", 0xddfe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1066 {"bal", 0xdefe, 2, ARM_EXT_THUMB
, do_t_branch9
},
1067 {"bic", 0x4380, 2, ARM_EXT_THUMB
, do_t_arit
},
1068 {"bl", 0xf7fffffe, 4, ARM_EXT_THUMB
, do_t_branch23
},
1069 {"blx", 0, 0, ARM_EXT_V5
, do_t_blx
},
1070 {"bkpt", 0xbe00, 2, ARM_EXT_V5
, do_t_bkpt
},
1071 {"bx", 0x4700, 2, ARM_EXT_THUMB
, do_t_bx
},
1072 {"cmn", T_OPCODE_CMN
, 2, ARM_EXT_THUMB
, do_t_arit
},
1073 {"cmp", 0x0000, 2, ARM_EXT_THUMB
, do_t_compare
},
1074 {"eor", 0x4040, 2, ARM_EXT_THUMB
, do_t_arit
},
1075 {"ldmia", 0xc800, 2, ARM_EXT_THUMB
, do_t_ldmstm
},
1076 {"ldr", 0x0000, 2, ARM_EXT_THUMB
, do_t_ldr
},
1077 {"ldrb", 0x0000, 2, ARM_EXT_THUMB
, do_t_ldrb
},
1078 {"ldrh", 0x0000, 2, ARM_EXT_THUMB
, do_t_ldrh
},
1079 {"ldrsb", 0x5600, 2, ARM_EXT_THUMB
, do_t_lds
},
1080 {"ldrsh", 0x5e00, 2, ARM_EXT_THUMB
, do_t_lds
},
1081 {"ldsb", 0x5600, 2, ARM_EXT_THUMB
, do_t_lds
},
1082 {"ldsh", 0x5e00, 2, ARM_EXT_THUMB
, do_t_lds
},
1083 {"lsl", 0x0000, 2, ARM_EXT_THUMB
, do_t_lsl
},
1084 {"lsr", 0x0000, 2, ARM_EXT_THUMB
, do_t_lsr
},
1085 {"mov", 0x0000, 2, ARM_EXT_THUMB
, do_t_mov
},
1086 {"mul", T_OPCODE_MUL
, 2, ARM_EXT_THUMB
, do_t_arit
},
1087 {"mvn", T_OPCODE_MVN
, 2, ARM_EXT_THUMB
, do_t_arit
},
1088 {"neg", T_OPCODE_NEG
, 2, ARM_EXT_THUMB
, do_t_arit
},
1089 {"orr", 0x4300, 2, ARM_EXT_THUMB
, do_t_arit
},
1090 {"pop", 0xbc00, 2, ARM_EXT_THUMB
, do_t_push_pop
},
1091 {"push", 0xb400, 2, ARM_EXT_THUMB
, do_t_push_pop
},
1092 {"ror", 0x41c0, 2, ARM_EXT_THUMB
, do_t_arit
},
1093 {"sbc", 0x4180, 2, ARM_EXT_THUMB
, do_t_arit
},
1094 {"stmia", 0xc000, 2, ARM_EXT_THUMB
, do_t_ldmstm
},
1095 {"str", 0x0000, 2, ARM_EXT_THUMB
, do_t_str
},
1096 {"strb", 0x0000, 2, ARM_EXT_THUMB
, do_t_strb
},
1097 {"strh", 0x0000, 2, ARM_EXT_THUMB
, do_t_strh
},
1098 {"swi", 0xdf00, 2, ARM_EXT_THUMB
, do_t_swi
},
1099 {"sub", 0x0000, 2, ARM_EXT_THUMB
, do_t_sub
},
1100 {"tst", T_OPCODE_TST
, 2, ARM_EXT_THUMB
, do_t_arit
},
1102 {"adr", 0x0000, 2, ARM_EXT_THUMB
, do_t_adr
},
1103 {"nop", 0x46C0, 2, ARM_EXT_THUMB
, do_t_nop
}, /* mov r8,r8 */
1112 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
1113 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
1114 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
1120 /* These are the standard names. Users can add aliases with .req. */
1121 static CONST
struct reg_entry reg_table
[] =
1123 /* Processor Register Numbers. */
1124 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
1125 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
1126 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
1127 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
1128 /* APCS conventions. */
1129 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
1130 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
1131 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
1132 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
1133 /* ATPCS additions to APCS conventions. */
1134 {"wr", 7}, {"v8", 11},
1136 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
1137 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
1138 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
1139 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
1140 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
1141 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
1142 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
1143 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
1144 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
1145 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1146 /* ATPCS additions to float register names. */
1147 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
1148 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
1149 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
1150 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
1151 /* FIXME: At some point we need to add VFP register names. */
1152 /* Array terminator. */
1156 #define BAD_ARGS _("Bad arguments to instruction")
1157 #define BAD_PC _("r15 not allowed here")
1158 #define BAD_FLAGS _("Instruction should not have flags")
1159 #define BAD_COND _("Instruction is not conditional")
1160 #define ERR_NO_ACCUM _("acc0 expected")
1162 static struct hash_control
* arm_ops_hsh
= NULL
;
1163 static struct hash_control
* arm_tops_hsh
= NULL
;
1164 static struct hash_control
* arm_cond_hsh
= NULL
;
1165 static struct hash_control
* arm_shift_hsh
= NULL
;
1166 static struct hash_control
* arm_reg_hsh
= NULL
;
1167 static struct hash_control
* arm_psr_hsh
= NULL
;
1169 /* This table describes all the machine specific pseudo-ops the assembler
1170 has to support. The fields are:
1171 pseudo-op name without dot
1172 function to call to execute this pseudo-op
1173 Integer arg to pass to the function. */
1175 static void s_req
PARAMS ((int));
1176 static void s_align
PARAMS ((int));
1177 static void s_bss
PARAMS ((int));
1178 static void s_even
PARAMS ((int));
1179 static void s_ltorg
PARAMS ((int));
1180 static void s_arm
PARAMS ((int));
1181 static void s_thumb
PARAMS ((int));
1182 static void s_code
PARAMS ((int));
1183 static void s_force_thumb
PARAMS ((int));
1184 static void s_thumb_func
PARAMS ((int));
1185 static void s_thumb_set
PARAMS ((int));
1186 static void arm_s_text
PARAMS ((int));
1187 static void arm_s_data
PARAMS ((int));
1189 static void arm_s_section
PARAMS ((int));
1190 static void s_arm_elf_cons
PARAMS ((int));
1193 static int my_get_expression
PARAMS ((expressionS
*, char **));
1195 CONST pseudo_typeS md_pseudo_table
[] =
1197 /* Never called becasue '.req' does not start line. */
1198 { "req", s_req
, 0 },
1199 { "bss", s_bss
, 0 },
1200 { "align", s_align
, 0 },
1201 { "arm", s_arm
, 0 },
1202 { "thumb", s_thumb
, 0 },
1203 { "code", s_code
, 0 },
1204 { "force_thumb", s_force_thumb
, 0 },
1205 { "thumb_func", s_thumb_func
, 0 },
1206 { "thumb_set", s_thumb_set
, 0 },
1207 { "even", s_even
, 0 },
1208 { "ltorg", s_ltorg
, 0 },
1209 { "pool", s_ltorg
, 0 },
1210 /* Allow for the effect of section changes. */
1211 { "text", arm_s_text
, 0 },
1212 { "data", arm_s_data
, 0 },
1214 { "section", arm_s_section
, 0 },
1215 { "section.s", arm_s_section
, 0 },
1216 { "sect", arm_s_section
, 0 },
1217 { "sect.s", arm_s_section
, 0 },
1218 { "word", s_arm_elf_cons
, 4 },
1219 { "long", s_arm_elf_cons
, 4 },
1220 { "file", dwarf2_directive_file
, 0 },
1221 { "loc", dwarf2_directive_loc
, 0 },
1225 { "extend", float_cons
, 'x' },
1226 { "ldouble", float_cons
, 'x' },
1227 { "packed", float_cons
, 'p' },
1231 /* Stuff needed to resolve the label ambiguity
1241 symbolS
* last_label_seen
;
1242 static int label_is_thumb_function_name
= false;
1244 /* Literal stuff. */
1246 #define MAX_LITERAL_POOL_SIZE 1024
1248 typedef struct literalS
1250 struct expressionS exp
;
1251 struct arm_it
* inst
;
1254 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1256 /* Next free entry in the pool. */
1257 int next_literal_pool_place
= 0;
1259 /* Next literal pool number. */
1260 int lit_pool_num
= 1;
1262 symbolS
* current_poolP
= NULL
;
1269 if (current_poolP
== NULL
)
1270 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1271 (valueT
) 0, &zero_address_frag
);
1273 /* Check if this literal value is already in the pool: */
1274 while (lit_count
< next_literal_pool_place
)
1276 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1277 && inst
.reloc
.exp
.X_op
== O_constant
1278 && (literals
[lit_count
].exp
.X_add_number
1279 == inst
.reloc
.exp
.X_add_number
)
1280 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1285 if (lit_count
== next_literal_pool_place
) /* New entry. */
1287 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1289 inst
.error
= _("Literal Pool Overflow");
1293 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1294 lit_count
= next_literal_pool_place
++;
1297 inst
.reloc
.exp
.X_op
= O_symbol
;
1298 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1299 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1304 /* Can't use symbol_new here, so have to create a symbol and then at
1305 a later date assign it a value. Thats what these functions do. */
1308 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1310 CONST
char * name
; /* It is copied, the caller can modify. */
1311 segT segment
; /* Segment identifier (SEG_<something>). */
1312 valueT valu
; /* Symbol value. */
1313 fragS
* frag
; /* Associated fragment. */
1315 unsigned int name_length
;
1316 char * preserved_copy_of_name
;
1318 name_length
= strlen (name
) + 1; /* +1 for \0. */
1319 obstack_grow (¬es
, name
, name_length
);
1320 preserved_copy_of_name
= obstack_finish (¬es
);
1321 #ifdef STRIP_UNDERSCORE
1322 if (preserved_copy_of_name
[0] == '_')
1323 preserved_copy_of_name
++;
1326 #ifdef tc_canonicalize_symbol_name
1327 preserved_copy_of_name
=
1328 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1331 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1333 S_SET_SEGMENT (symbolP
, segment
);
1334 S_SET_VALUE (symbolP
, valu
);
1335 symbol_clear_list_pointers(symbolP
);
1337 symbol_set_frag (symbolP
, frag
);
1339 /* Link to end of symbol chain. */
1341 extern int symbol_table_frozen
;
1342 if (symbol_table_frozen
)
1346 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1348 obj_symbol_new_hook (symbolP
);
1350 #ifdef tc_symbol_new_hook
1351 tc_symbol_new_hook (symbolP
);
1355 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1356 #endif /* DEBUG_SYMS */
1359 /* Check that an immediate is valid.
1360 If so, convert it to the right format. */
1363 validate_immediate (val
)
1369 #define rotate_left(v, n) (v << n | v >> (32 - n))
1371 for (i
= 0; i
< 32; i
+= 2)
1372 if ((a
= rotate_left (val
, i
)) <= 0xff)
1373 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const]. */
1378 /* Check to see if an immediate can be computed as two seperate immediate
1379 values, added together. We already know that this value cannot be
1380 computed by just one ARM instruction. */
1383 validate_immediate_twopart (val
, highpart
)
1385 unsigned int * highpart
;
1390 for (i
= 0; i
< 32; i
+= 2)
1391 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1397 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1399 else if (a
& 0xff0000)
1403 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1407 assert (a
& 0xff000000);
1408 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1411 return (a
& 0xff) | (i
<< 7);
1418 validate_offset_imm (val
, hwse
)
1422 if ((hwse
&& val
> 255) || val
> 4095)
1429 int a ATTRIBUTE_UNUSED
;
1431 as_bad (_("Invalid syntax for .req directive."));
1436 int ignore ATTRIBUTE_UNUSED
;
1438 /* We don't support putting frags in the BSS segment, we fake it by
1439 marking in_bss, then looking at s_skip for clues. */
1440 subseg_set (bss_section
, 0);
1441 demand_empty_rest_of_line ();
1446 int ignore ATTRIBUTE_UNUSED
;
1448 /* Never make frag if expect extra pass. */
1450 frag_align (1, 0, 0);
1452 record_alignment (now_seg
, 1);
1454 demand_empty_rest_of_line ();
1459 int ignored ATTRIBUTE_UNUSED
;
1464 if (current_poolP
== NULL
)
1467 /* Align pool as you have word accesses.
1468 Only make a frag if we have to. */
1470 frag_align (2, 0, 0);
1472 record_alignment (now_seg
, 2);
1474 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1476 symbol_locate (current_poolP
, sym_name
, now_seg
,
1477 (valueT
) frag_now_fix (), frag_now
);
1478 symbol_table_insert (current_poolP
);
1480 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1482 #if defined OBJ_COFF || defined OBJ_ELF
1483 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1486 while (lit_count
< next_literal_pool_place
)
1487 /* First output the expression in the instruction to the pool. */
1488 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1490 next_literal_pool_place
= 0;
1491 current_poolP
= NULL
;
1494 /* Same as s_align_ptwo but align 0 => align 2. */
1498 int unused ATTRIBUTE_UNUSED
;
1501 register long temp_fill
;
1502 long max_alignment
= 15;
1504 temp
= get_absolute_expression ();
1505 if (temp
> max_alignment
)
1506 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1509 as_bad (_("Alignment negative. 0 assumed."));
1513 if (*input_line_pointer
== ',')
1515 input_line_pointer
++;
1516 temp_fill
= get_absolute_expression ();
1524 /* Only make a frag if we HAVE to. */
1525 if (temp
&& !need_pass_2
)
1526 frag_align (temp
, (int) temp_fill
, 0);
1527 demand_empty_rest_of_line ();
1529 record_alignment (now_seg
, temp
);
1533 s_force_thumb (ignore
)
1534 int ignore ATTRIBUTE_UNUSED
;
1536 /* If we are not already in thumb mode go into it, EVEN if
1537 the target processor does not support thumb instructions.
1538 This is used by gcc/config/arm/lib1funcs.asm for example
1539 to compile interworking support functions even if the
1540 target processor should not support interworking. */
1545 record_alignment (now_seg
, 1);
1548 demand_empty_rest_of_line ();
1552 s_thumb_func (ignore
)
1553 int ignore ATTRIBUTE_UNUSED
;
1558 /* The following label is the name/address of the start of a Thumb function.
1559 We need to know this for the interworking support. */
1560 label_is_thumb_function_name
= true;
1562 demand_empty_rest_of_line ();
1565 /* Perform a .set directive, but also mark the alias as
1566 being a thumb function. */
1572 /* XXX the following is a duplicate of the code for s_set() in read.c
1573 We cannot just call that code as we need to get at the symbol that
1575 register char * name
;
1576 register char delim
;
1577 register char * end_name
;
1578 register symbolS
* symbolP
;
1580 /* Especial apologies for the random logic:
1581 This just grew, and could be parsed much more simply!
1583 name
= input_line_pointer
;
1584 delim
= get_symbol_end ();
1585 end_name
= input_line_pointer
;
1590 if (*input_line_pointer
!= ',')
1593 as_bad (_("Expected comma after name \"%s\""), name
);
1595 ignore_rest_of_line ();
1599 input_line_pointer
++;
1602 if (name
[0] == '.' && name
[1] == '\0')
1604 /* XXX - this should not happen to .thumb_set. */
1608 if ((symbolP
= symbol_find (name
)) == NULL
1609 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1612 /* When doing symbol listings, play games with dummy fragments living
1613 outside the normal fragment chain to record the file and line info
1615 if (listing
& LISTING_SYMBOLS
)
1617 extern struct list_info_struct
* listing_tail
;
1618 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof (fragS
));
1620 memset (dummy_frag
, 0, sizeof (fragS
));
1621 dummy_frag
->fr_type
= rs_fill
;
1622 dummy_frag
->line
= listing_tail
;
1623 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1624 dummy_frag
->fr_symbol
= symbolP
;
1628 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1631 /* "set" symbols are local unless otherwise specified. */
1632 SF_SET_LOCAL (symbolP
);
1633 #endif /* OBJ_COFF */
1634 } /* Make a new symbol. */
1636 symbol_table_insert (symbolP
);
1641 && S_IS_DEFINED (symbolP
)
1642 && S_GET_SEGMENT (symbolP
) != reg_section
)
1643 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1645 pseudo_set (symbolP
);
1647 demand_empty_rest_of_line ();
1649 /* XXX Now we come to the Thumb specific bit of code. */
1651 THUMB_SET_FUNC (symbolP
, 1);
1652 ARM_SET_THUMB (symbolP
, 1);
1653 #if defined OBJ_ELF || defined OBJ_COFF
1654 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1658 /* If we change section we must dump the literal pool first. */
1664 if (now_seg
!= text_section
)
1668 obj_elf_text (ignore
);
1678 if (flag_readonly_data_in_text
)
1680 if (now_seg
!= text_section
)
1683 else if (now_seg
!= data_section
)
1687 obj_elf_data (ignore
);
1695 arm_s_section (ignore
)
1700 obj_elf_section (ignore
);
1705 opcode_select (width
)
1713 if (! (cpu_variant
& ARM_EXT_THUMB
))
1714 as_bad (_("selected processor does not support THUMB opcodes"));
1717 /* No need to force the alignment, since we will have been
1718 coming from ARM mode, which is word-aligned. */
1719 record_alignment (now_seg
, 1);
1726 if ((cpu_variant
& ARM_ANY
) == ARM_EXT_THUMB
)
1727 as_bad (_("selected processor does not support ARM opcodes"));
1732 frag_align (2, 0, 0);
1734 record_alignment (now_seg
, 1);
1739 as_bad (_("invalid instruction size selected (%d)"), width
);
1745 int ignore ATTRIBUTE_UNUSED
;
1748 demand_empty_rest_of_line ();
1753 int ignore ATTRIBUTE_UNUSED
;
1756 demand_empty_rest_of_line ();
1761 int unused ATTRIBUTE_UNUSED
;
1765 temp
= get_absolute_expression ();
1770 opcode_select (temp
);
1774 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1782 skip_whitespace (str
);
1785 inst
.error
= _("Garbage following instruction");
1789 skip_past_comma (str
)
1792 char * p
= * str
, c
;
1795 while ((c
= *p
) == ' ' || c
== ',')
1798 if (c
== ',' && comma
++)
1806 return comma
? SUCCESS
: FAIL
;
1809 /* A standard register must be given at this point.
1810 SHIFT is the place to put it in inst.instruction.
1811 Restores input start point on error.
1812 Returns the reg#, or FAIL. */
1815 reg_required_here (str
, shift
)
1819 static char buff
[128]; /* XXX */
1821 char * start
= * str
;
1823 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1826 inst
.instruction
|= reg
<< shift
;
1830 /* Restore the start point, we may have got a reg of the wrong class. */
1833 /* In the few cases where we might be able to accept something else
1834 this error can be overridden. */
1835 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1841 static CONST
struct asm_psr
*
1843 register char ** ccp
;
1845 char * start
= * ccp
;
1848 CONST
struct asm_psr
* psr
;
1852 /* Skip to the end of the next word in the input stream. */
1857 while (isalpha (c
) || c
== '_');
1859 /* Terminate the word. */
1862 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
1863 feature for ease of use and backwards compatibility. */
1864 if (!strncmp (start
, "cpsr", 4))
1865 strncpy (start
, "CPSR", 4);
1866 else if (!strncmp (start
, "spsr", 4))
1867 strncpy (start
, "SPSR", 4);
1869 /* Now locate the word in the psr hash table. */
1870 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
1872 /* Restore the input stream. */
1875 /* If we found a valid match, advance the
1876 stream pointer past the end of the word. */
1882 /* Parse the input looking for a PSR flag. */
1885 psr_required_here (str
)
1888 char * start
= * str
;
1889 CONST
struct asm_psr
* psr
;
1891 psr
= arm_psr_parse (str
);
1895 /* If this is the SPSR that is being modified, set the R bit. */
1897 inst
.instruction
|= SPSR_BIT
;
1899 /* Set the psr flags in the MSR instruction. */
1900 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
1905 /* In the few cases where we might be able to accept
1906 something else this error can be overridden. */
1907 inst
.error
= _("flag for {c}psr instruction expected");
1909 /* Restore the start point. */
1915 co_proc_number (str
)
1918 int processor
, pchar
;
1920 skip_whitespace (* str
);
1922 /* The data sheet seems to imply that just a number on its own is valid
1923 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1925 if (**str
== 'p' || **str
== 'P')
1929 if (pchar
>= '0' && pchar
<= '9')
1931 processor
= pchar
- '0';
1932 if (**str
>= '0' && **str
<= '9')
1934 processor
= processor
* 10 + *(*str
)++ - '0';
1937 inst
.error
= _("Illegal co-processor number");
1944 inst
.error
= _("Bad or missing co-processor number");
1948 inst
.instruction
|= processor
<< 8;
1953 cp_opc_expr (str
, where
, length
)
1960 skip_whitespace (* str
);
1962 memset (&expr
, '\0', sizeof (expr
));
1964 if (my_get_expression (&expr
, str
))
1966 if (expr
.X_op
!= O_constant
)
1968 inst
.error
= _("bad or missing expression");
1972 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1974 inst
.error
= _("immediate co-processor expression too large");
1978 inst
.instruction
|= expr
.X_add_number
<< where
;
1983 cp_reg_required_here (str
, where
)
1988 char * start
= *str
;
1990 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1993 inst
.instruction
|= reg
<< where
;
1997 /* In the few cases where we might be able to accept something else
1998 this error can be overridden. */
1999 inst
.error
= _("Co-processor register expected");
2001 /* Restore the start point. */
2007 fp_reg_required_here (str
, where
)
2012 char * start
= * str
;
2014 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
2017 inst
.instruction
|= reg
<< where
;
2021 /* In the few cases where we might be able to accept something else
2022 this error can be overridden. */
2023 inst
.error
= _("Floating point register expected");
2025 /* Restore the start point. */
2031 cp_address_offset (str
)
2036 skip_whitespace (* str
);
2038 if (! is_immediate_prefix (**str
))
2040 inst
.error
= _("immediate expression expected");
2046 if (my_get_expression (& inst
.reloc
.exp
, str
))
2049 if (inst
.reloc
.exp
.X_op
== O_constant
)
2051 offset
= inst
.reloc
.exp
.X_add_number
;
2055 inst
.error
= _("co-processor address must be word aligned");
2059 if (offset
> 1023 || offset
< -1023)
2061 inst
.error
= _("offset too large");
2066 inst
.instruction
|= INDEX_UP
;
2070 inst
.instruction
|= offset
>> 2;
2073 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2079 cp_address_required_here (str
)
2091 skip_whitespace (p
);
2093 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
2096 skip_whitespace (p
);
2102 if (skip_past_comma (& p
) == SUCCESS
)
2105 write_back
= WRITE_BACK
;
2109 inst
.error
= _("pc may not be used in post-increment");
2113 if (cp_address_offset (& p
) == FAIL
)
2117 pre_inc
= PRE_INDEX
| INDEX_UP
;
2121 /* '['Rn, #expr']'[!] */
2123 if (skip_past_comma (& p
) == FAIL
)
2125 inst
.error
= _("pre-indexed expression expected");
2129 pre_inc
= PRE_INDEX
;
2131 if (cp_address_offset (& p
) == FAIL
)
2134 skip_whitespace (p
);
2138 inst
.error
= _("missing ]");
2142 skip_whitespace (p
);
2148 inst
.error
= _("pc may not be used with write-back");
2153 write_back
= WRITE_BACK
;
2159 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2162 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
2163 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2164 inst
.reloc
.pc_rel
= 1;
2165 inst
.instruction
|= (REG_PC
<< 16);
2166 pre_inc
= PRE_INDEX
;
2169 inst
.instruction
|= write_back
| pre_inc
;
2177 unsigned long flags
;
2179 /* Do nothing really. */
2180 inst
.instruction
|= flags
; /* This is pointless. */
2188 unsigned long flags
;
2192 /* Only one syntax. */
2193 skip_whitespace (str
);
2195 if (reg_required_here (&str
, 12) == FAIL
)
2197 inst
.error
= BAD_ARGS
;
2201 if (skip_past_comma (&str
) == FAIL
)
2203 inst
.error
= _("comma expected after register name");
2207 skip_whitespace (str
);
2209 if ( strcmp (str
, "CPSR") == 0
2210 || strcmp (str
, "SPSR") == 0
2211 /* Lower case versions for backwards compatability. */
2212 || strcmp (str
, "cpsr") == 0
2213 || strcmp (str
, "spsr") == 0)
2216 /* This is for backwards compatability with older toolchains. */
2217 else if ( strcmp (str
, "cpsr_all") == 0
2218 || strcmp (str
, "spsr_all") == 0)
2222 inst
.error
= _("{C|S}PSR expected");
2226 if (* str
== 's' || * str
== 'S')
2227 inst
.instruction
|= SPSR_BIT
;
2230 inst
.instruction
|= flags
;
2234 /* Two possible forms:
2235 "{C|S}PSR_<field>, Rm",
2236 "{C|S}PSR_f, #expression". */
2241 unsigned long flags
;
2243 skip_whitespace (str
);
2245 if (psr_required_here (& str
) == FAIL
)
2248 if (skip_past_comma (& str
) == FAIL
)
2250 inst
.error
= _("comma missing after psr flags");
2254 skip_whitespace (str
);
2256 if (reg_required_here (& str
, 0) != FAIL
)
2259 inst
.instruction
|= flags
;
2264 if (! is_immediate_prefix (* str
))
2267 _("only a register or immediate value can follow a psr flag");
2274 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2277 _("only a register or immediate value can follow a psr flag");
2281 if ((cpu_variant
& ARM_EXT_V5
) != ARM_EXT_V5
2282 && inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2284 inst
.error
= _("immediate value cannot be used to set this field");
2288 flags
|= INST_IMMEDIATE
;
2290 if (inst
.reloc
.exp
.X_add_symbol
)
2292 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2293 inst
.reloc
.pc_rel
= 0;
2297 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2299 if (value
== (unsigned) FAIL
)
2301 inst
.error
= _("Invalid constant");
2305 inst
.instruction
|= value
;
2309 inst
.instruction
|= flags
;
2313 /* Long Multiply Parser
2314 UMULL RdLo, RdHi, Rm, Rs
2315 SMULL RdLo, RdHi, Rm, Rs
2316 UMLAL RdLo, RdHi, Rm, Rs
2317 SMLAL RdLo, RdHi, Rm, Rs. */
2320 do_mull (str
, flags
)
2322 unsigned long flags
;
2324 int rdlo
, rdhi
, rm
, rs
;
2326 /* Only one format "rdlo, rdhi, rm, rs". */
2327 skip_whitespace (str
);
2329 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2331 inst
.error
= BAD_ARGS
;
2335 if (skip_past_comma (&str
) == FAIL
2336 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2338 inst
.error
= BAD_ARGS
;
2342 if (skip_past_comma (&str
) == FAIL
2343 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2345 inst
.error
= BAD_ARGS
;
2349 /* rdhi, rdlo and rm must all be different. */
2350 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2351 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2353 if (skip_past_comma (&str
) == FAIL
2354 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2356 inst
.error
= BAD_ARGS
;
2360 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2362 inst
.error
= BAD_PC
;
2366 inst
.instruction
|= flags
;
2374 unsigned long flags
;
2378 /* Only one format "rd, rm, rs". */
2379 skip_whitespace (str
);
2381 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2383 inst
.error
= BAD_ARGS
;
2389 inst
.error
= BAD_PC
;
2393 if (skip_past_comma (&str
) == FAIL
2394 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2396 inst
.error
= BAD_ARGS
;
2402 inst
.error
= BAD_PC
;
2407 as_tsktsk (_("rd and rm should be different in mul"));
2409 if (skip_past_comma (&str
) == FAIL
2410 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2412 inst
.error
= BAD_ARGS
;
2418 inst
.error
= BAD_PC
;
2422 inst
.instruction
|= flags
;
2430 unsigned long flags
;
2434 /* Only one format "rd, rm, rs, rn". */
2435 skip_whitespace (str
);
2437 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2439 inst
.error
= BAD_ARGS
;
2445 inst
.error
= BAD_PC
;
2449 if (skip_past_comma (&str
) == FAIL
2450 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2452 inst
.error
= BAD_ARGS
;
2458 inst
.error
= BAD_PC
;
2463 as_tsktsk (_("rd and rm should be different in mla"));
2465 if (skip_past_comma (&str
) == FAIL
2466 || (rd
= reg_required_here (&str
, 8)) == FAIL
2467 || skip_past_comma (&str
) == FAIL
2468 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2470 inst
.error
= BAD_ARGS
;
2474 if (rd
== REG_PC
|| rm
== REG_PC
)
2476 inst
.error
= BAD_PC
;
2480 inst
.instruction
|= flags
;
2485 /* Expects *str -> the characters "acc0", possibly with leading blanks.
2486 Advances *str to the next non-alphanumeric.
2487 Returns 0, or else FAIL (in which case sets inst.error).
2489 (In a future XScale, there may be accumulators other than zero.
2490 At that time this routine and its callers can be upgraded to suit.) */
2493 accum0_required_here (str
)
2496 static char buff
[128]; /* Note the address is taken. Hence, static. */
2499 int result
= 0; /* The accum number. */
2501 skip_whitespace (p
);
2503 *str
= p
; /* Advance caller's string pointer too. */
2508 *--p
= 0; /* Aap nul into input buffer at non-alnum. */
2510 if (! ( streq (*str
, "acc0") || streq (*str
, "ACC0")))
2512 sprintf (buff
, _("acc0 expected, not '%.100s'"), *str
);
2517 *p
= c
; /* Unzap. */
2518 *str
= p
; /* Caller's string pointer to after match. */
2522 /* Expects **str -> after a comma. May be leading blanks.
2523 Advances *str, recognizing a load mode, and setting inst.instruction.
2524 Returns rn, or else FAIL (in which case may set inst.error
2525 and not advance str)
2527 Note: doesn't know Rd, so no err checks that require such knowledge. */
2530 ld_mode_required_here (string
)
2533 char * str
= * string
;
2537 skip_whitespace (str
);
2543 skip_whitespace (str
);
2545 if ((rn
= reg_required_here (& str
, 16)) == FAIL
)
2548 skip_whitespace (str
);
2554 if (skip_past_comma (& str
) == SUCCESS
)
2556 /* [Rn],... (post inc) */
2557 if (ldst_extend (& str
, 1) == FAIL
)
2562 skip_whitespace (str
);
2567 inst
.instruction
|= WRITE_BACK
;
2570 inst
.instruction
|= INDEX_UP
| HWOFFSET_IMM
;
2576 if (skip_past_comma (& str
) == FAIL
)
2578 inst
.error
= _("pre-indexed expression expected");
2584 if (ldst_extend (& str
, 1) == FAIL
)
2587 skip_whitespace (str
);
2589 if (* str
++ != ']')
2591 inst
.error
= _("missing ]");
2595 skip_whitespace (str
);
2600 inst
.instruction
|= WRITE_BACK
;
2604 else if (* str
== '=') /* ldr's "r,=label" syntax */
2605 /* We should never reach here, because <text> = <expression> is
2606 caught gas/read.c read_a_source_file() as a .set operation. */
2608 else /* PC +- 8 bit immediate offset. */
2610 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2613 inst
.instruction
|= HWOFFSET_IMM
; /* The I bit. */
2614 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2615 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust. */
2616 inst
.reloc
.pc_rel
= 1;
2617 inst
.instruction
|= (REG_PC
<< 16);
2623 inst
.instruction
|= (pre_inc
? PRE_INDEX
: 0);
2629 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
2630 SMLAxy{cond} Rd,Rm,Rs,Rn
2631 SMLAWy{cond} Rd,Rm,Rs,Rn
2632 Error if any register is R15. */
2635 do_smla (str
, flags
)
2637 unsigned long flags
;
2641 skip_whitespace (str
);
2643 if ((rd
= reg_required_here (& str
, 16)) == FAIL
2644 || skip_past_comma (& str
) == FAIL
2645 || (rm
= reg_required_here (& str
, 0)) == FAIL
2646 || skip_past_comma (& str
) == FAIL
2647 || (rs
= reg_required_here (& str
, 8)) == FAIL
2648 || skip_past_comma (& str
) == FAIL
2649 || (rn
= reg_required_here (& str
, 12)) == FAIL
)
2650 inst
.error
= BAD_ARGS
;
2652 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
|| rn
== REG_PC
)
2653 inst
.error
= BAD_PC
;
2656 inst
.error
= BAD_FLAGS
;
2662 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
2663 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
2664 Error if any register is R15.
2665 Warning if Rdlo == Rdhi. */
2668 do_smlal (str
, flags
)
2670 unsigned long flags
;
2672 int rdlo
, rdhi
, rm
, rs
;
2674 skip_whitespace (str
);
2676 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
2677 || skip_past_comma (& str
) == FAIL
2678 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
2679 || skip_past_comma (& str
) == FAIL
2680 || (rm
= reg_required_here (& str
, 0)) == FAIL
2681 || skip_past_comma (& str
) == FAIL
2682 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
2684 inst
.error
= BAD_ARGS
;
2688 if (rdlo
== REG_PC
|| rdhi
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
2690 inst
.error
= BAD_PC
;
2695 as_tsktsk (_("rdhi and rdlo must be different"));
2698 inst
.error
= BAD_FLAGS
;
2703 /* ARM V5E (El Segundo) signed-multiply (argument parse)
2704 SMULxy{cond} Rd,Rm,Rs
2705 Error if any register is R15. */
2708 do_smul (str
, flags
)
2710 unsigned long flags
;
2714 skip_whitespace (str
);
2716 if ((rd
= reg_required_here (& str
, 16)) == FAIL
2717 || skip_past_comma (& str
) == FAIL
2718 || (rm
= reg_required_here (& str
, 0)) == FAIL
2719 || skip_past_comma (& str
) == FAIL
2720 || (rs
= reg_required_here (& str
, 8)) == FAIL
)
2721 inst
.error
= BAD_ARGS
;
2723 else if (rd
== REG_PC
|| rm
== REG_PC
|| rs
== REG_PC
)
2724 inst
.error
= BAD_PC
;
2727 inst
.error
= BAD_FLAGS
;
2733 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
2734 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
2735 Error if any register is R15. */
2738 do_qadd (str
, flags
)
2740 unsigned long flags
;
2744 skip_whitespace (str
);
2746 if ((rd
= reg_required_here (& str
, 12)) == FAIL
2747 || skip_past_comma (& str
) == FAIL
2748 || (rm
= reg_required_here (& str
, 0)) == FAIL
2749 || skip_past_comma (& str
) == FAIL
2750 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
2751 inst
.error
= BAD_ARGS
;
2753 else if (rd
== REG_PC
|| rm
== REG_PC
|| rn
== REG_PC
)
2754 inst
.error
= BAD_PC
;
2757 inst
.error
= BAD_FLAGS
;
2763 /* ARM V5E (el Segundo)
2764 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2765 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2767 These are equivalent to the XScale instructions MAR and MRA,
2768 respectively, when coproc == 0, opcode == 0, and CRm == 0.
2770 Result unpredicatable if Rd or Rn is R15. */
2773 do_co_reg2c (str
, flags
)
2775 unsigned long flags
;
2779 skip_whitespace (str
);
2781 if (co_proc_number (& str
) == FAIL
)
2784 inst
.error
= BAD_ARGS
;
2788 if (skip_past_comma (& str
) == FAIL
2789 || cp_opc_expr (& str
, 4, 4) == FAIL
)
2792 inst
.error
= BAD_ARGS
;
2796 if (skip_past_comma (& str
) == FAIL
2797 || (rd
= reg_required_here (& str
, 12)) == FAIL
)
2800 inst
.error
= BAD_ARGS
;
2804 if (skip_past_comma (& str
) == FAIL
2805 || (rn
= reg_required_here (& str
, 16)) == FAIL
)
2808 inst
.error
= BAD_ARGS
;
2812 /* Unpredictable result if rd or rn is R15. */
2813 if (rd
== REG_PC
|| rn
== REG_PC
)
2815 (_("Warning: Instruction unpredictable when using r15"));
2817 if (skip_past_comma (& str
) == FAIL
2818 || cp_reg_required_here (& str
, 0) == FAIL
)
2821 inst
.error
= BAD_ARGS
;
2826 inst
.error
= BAD_COND
;
2832 /* ARM V5 count-leading-zeroes instruction (argument parse)
2833 CLZ{<cond>} <Rd>, <Rm>
2834 Condition defaults to COND_ALWAYS.
2835 Error if Rd or Rm are R15. */
2840 unsigned long flags
;
2850 skip_whitespace (str
);
2852 if (((rd
= reg_required_here (& str
, 12)) == FAIL
)
2853 || (skip_past_comma (& str
) == FAIL
)
2854 || ((rm
= reg_required_here (& str
, 0)) == FAIL
))
2855 inst
.error
= BAD_ARGS
;
2857 else if (rd
== REG_PC
|| rm
== REG_PC
)
2858 inst
.error
= BAD_PC
;
2864 /* ARM V5 (argument parse)
2865 LDC2{L} <coproc>, <CRd>, <addressing mode>
2866 STC2{L} <coproc>, <CRd>, <addressing mode>
2867 Instruction is not conditional, and has 0xf in the codition field.
2868 Otherwise, it's the same as LDC/STC. */
2871 do_lstc2 (str
, flags
)
2873 unsigned long flags
;
2876 inst
.error
= BAD_COND
;
2878 skip_whitespace (str
);
2880 if (co_proc_number (& str
) == FAIL
)
2883 inst
.error
= BAD_ARGS
;
2885 else if (skip_past_comma (& str
) == FAIL
2886 || cp_reg_required_here (& str
, 12) == FAIL
)
2889 inst
.error
= BAD_ARGS
;
2891 else if (skip_past_comma (& str
) == FAIL
2892 || cp_address_required_here (& str
) == FAIL
)
2895 inst
.error
= BAD_ARGS
;
2901 /* ARM V5 (argument parse)
2902 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
2903 Instruction is not conditional, and has 0xf in the condition field.
2904 Otherwise, it's the same as CDP. */
2907 do_cdp2 (str
, flags
)
2909 unsigned long flags
;
2911 skip_whitespace (str
);
2913 if (co_proc_number (& str
) == FAIL
)
2916 inst
.error
= BAD_ARGS
;
2920 if (skip_past_comma (& str
) == FAIL
2921 || cp_opc_expr (& str
, 20,4) == FAIL
)
2924 inst
.error
= BAD_ARGS
;
2928 if (skip_past_comma (& str
) == FAIL
2929 || cp_reg_required_here (& str
, 12) == FAIL
)
2932 inst
.error
= BAD_ARGS
;
2936 if (skip_past_comma (& str
) == FAIL
2937 || cp_reg_required_here (& str
, 16) == FAIL
)
2940 inst
.error
= BAD_ARGS
;
2944 if (skip_past_comma (& str
) == FAIL
2945 || cp_reg_required_here (& str
, 0) == FAIL
)
2948 inst
.error
= BAD_ARGS
;
2952 if (skip_past_comma (& str
) == SUCCESS
)
2954 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
2957 inst
.error
= BAD_ARGS
;
2963 inst
.error
= BAD_FLAGS
;
2968 /* ARM V5 (argument parse)
2969 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
2970 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
2971 Instruction is not conditional, and has 0xf in the condition field.
2972 Otherwise, it's the same as MCR/MRC. */
2975 do_co_reg2 (str
, flags
)
2977 unsigned long flags
;
2979 skip_whitespace (str
);
2981 if (co_proc_number (& str
) == FAIL
)
2984 inst
.error
= BAD_ARGS
;
2988 if (skip_past_comma (& str
) == FAIL
2989 || cp_opc_expr (& str
, 21, 3) == FAIL
)
2992 inst
.error
= BAD_ARGS
;
2996 if (skip_past_comma (& str
) == FAIL
2997 || reg_required_here (& str
, 12) == FAIL
)
3000 inst
.error
= BAD_ARGS
;
3004 if (skip_past_comma (& str
) == FAIL
3005 || cp_reg_required_here (& str
, 16) == FAIL
)
3008 inst
.error
= BAD_ARGS
;
3012 if (skip_past_comma (& str
) == FAIL
3013 || cp_reg_required_here (& str
, 0) == FAIL
)
3016 inst
.error
= BAD_ARGS
;
3020 if (skip_past_comma (& str
) == SUCCESS
)
3022 if (cp_opc_expr (& str
, 5, 3) == FAIL
)
3025 inst
.error
= BAD_ARGS
;
3031 inst
.error
= BAD_COND
;
3036 /* THUMB V5 breakpoint instruction (argument parse)
3044 unsigned long number
;
3046 skip_whitespace (str
);
3048 /* Allow optional leading '#'. */
3049 if (is_immediate_prefix (*str
))
3052 memset (& expr
, '\0', sizeof (expr
));
3053 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3055 inst
.error
= _("bad or missing expression");
3059 number
= expr
.X_add_number
;
3061 /* Check it fits an 8 bit unsigned. */
3062 if (number
!= (number
& 0xff))
3064 inst
.error
= _("immediate value out of range");
3068 inst
.instruction
|= number
;
3073 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3074 Expects inst.instruction is set for BLX(1).
3075 Note: this is cloned from do_branch, and the reloc changed to be a
3076 new one that can cope with setting one extra bit (the H bit). */
3079 do_branch25 (str
, flags
)
3081 unsigned long flags ATTRIBUTE_UNUSED
;
3083 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3090 /* ScottB: February 5, 1998 */
3091 /* Check to see of PLT32 reloc required for the instruction. */
3093 /* arm_parse_reloc() works on input_line_pointer.
3094 We actually want to parse the operands to the branch instruction
3095 passed in 'str'. Save the input pointer and restore it later. */
3096 save_in
= input_line_pointer
;
3097 input_line_pointer
= str
;
3099 if (inst
.reloc
.exp
.X_op
== O_symbol
3101 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3103 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3104 inst
.reloc
.pc_rel
= 0;
3105 /* Modify str to point to after parsed operands, otherwise
3106 end_of_line() will complain about the (PLT) left in str. */
3107 str
= input_line_pointer
;
3111 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3112 inst
.reloc
.pc_rel
= 1;
3115 input_line_pointer
= save_in
;
3118 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BLX
;
3119 inst
.reloc
.pc_rel
= 1;
3120 #endif /* OBJ_ELF */
3125 /* ARM V5 branch-link-exchange instruction (argument parse)
3126 BLX <target_addr> ie BLX(1)
3127 BLX{<condition>} <Rm> ie BLX(2)
3128 Unfortunately, there are two different opcodes for this mnemonic.
3129 So, the insns[].value is not used, and the code here zaps values
3130 into inst.instruction.
3131 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
3136 unsigned long flags
;
3147 skip_whitespace (mystr
);
3148 rm
= reg_required_here (& mystr
, 0);
3150 /* The above may set inst.error. Ignore his opinion. */
3155 /* Arg is a register.
3156 Use the condition code our caller put in inst.instruction.
3157 Pass ourselves off as a BX with a funny opcode. */
3158 inst
.instruction
|= 0x012fff30;
3163 /* This must be is BLX <target address>, no condition allowed. */
3164 if (inst
.instruction
!= COND_ALWAYS
)
3166 inst
.error
= BAD_COND
;
3170 inst
.instruction
= 0xfafffffe;
3172 /* Process like a B/BL, but with a different reloc.
3173 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
3174 do_branch25 (str
, flags
);
3178 /* ARM V5 Thumb BLX (argument parse)
3179 BLX <target_addr> which is BLX(1)
3180 BLX <Rm> which is BLX(2)
3181 Unfortunately, there are two different opcodes for this mnemonic.
3182 So, the tinsns[].value is not used, and the code here zaps values
3183 into inst.instruction. */
3192 skip_whitespace (mystr
);
3193 inst
.instruction
= 0x4780;
3195 /* Note that this call is to the ARM register recognizer. BLX(2)
3196 uses the ARM register space, not the Thumb one, so a call to
3197 thumb_reg() would be wrong. */
3198 rm
= reg_required_here (& mystr
, 3);
3203 /* It's BLX(2). The .instruction was zapped with rm & is final. */
3208 /* No ARM register. This must be BLX(1). Change the .instruction. */
3209 inst
.instruction
= 0xf7ffeffe;
3212 if (my_get_expression (& inst
.reloc
.exp
, & mystr
))
3215 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BLX
;
3216 inst
.reloc
.pc_rel
= 1;
3219 end_of_line (mystr
);
3222 /* ARM V5 breakpoint instruction (argument parse)
3223 BKPT <16 bit unsigned immediate>
3224 Instruction is not conditional.
3225 The bit pattern given in insns[] has the COND_ALWAYS condition,
3226 and it is an error if the caller tried to override that.
3227 Note "flags" is nonzero if a flag was supplied (which is an error). */
3230 do_bkpt (str
, flags
)
3232 unsigned long flags
;
3235 unsigned long number
;
3237 skip_whitespace (str
);
3239 /* Allow optional leading '#'. */
3240 if (is_immediate_prefix (* str
))
3243 memset (& expr
, '\0', sizeof (expr
));
3245 if (my_get_expression (& expr
, & str
) || (expr
.X_op
!= O_constant
))
3247 inst
.error
= _("bad or missing expression");
3251 number
= expr
.X_add_number
;
3253 /* Check it fits a 16 bit unsigned. */
3254 if (number
!= (number
& 0xffff))
3256 inst
.error
= _("immediate value out of range");
3260 /* Top 12 of 16 bits to bits 19:8. */
3261 inst
.instruction
|= (number
& 0xfff0) << 4;
3263 /* Bottom 4 of 16 bits to bits 3:0. */
3264 inst
.instruction
|= number
& 0xf;
3269 inst
.error
= BAD_FLAGS
;
3272 /* Xscale multiply-accumulate (argument parse)
3275 MIAxycc acc0,Rm,Rs. */
3280 unsigned long flags
;
3288 else if (accum0_required_here (& str
) == FAIL
)
3289 inst
.error
= ERR_NO_ACCUM
;
3291 else if (skip_past_comma (& str
) == FAIL
3292 || (rm
= reg_required_here (& str
, 0)) == FAIL
)
3293 inst
.error
= BAD_ARGS
;
3295 else if (skip_past_comma (& str
) == FAIL
3296 || (rs
= reg_required_here (& str
, 12)) == FAIL
)
3297 inst
.error
= BAD_ARGS
;
3299 /* inst.instruction has now been zapped with both rm and rs. */
3300 else if (rm
== REG_PC
|| rs
== REG_PC
)
3301 inst
.error
= BAD_PC
; /* Undefined result if rm or rs is R15. */
3307 /* Xscale move-accumulator-register (argument parse)
3309 MARcc acc0,RdLo,RdHi. */
3314 unsigned long flags
;
3321 else if (accum0_required_here (& str
) == FAIL
)
3322 inst
.error
= ERR_NO_ACCUM
;
3324 else if (skip_past_comma (& str
) == FAIL
3325 || (rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3326 inst
.error
= BAD_ARGS
;
3328 else if (skip_past_comma (& str
) == FAIL
3329 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3330 inst
.error
= BAD_ARGS
;
3332 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3333 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3334 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3340 /* Xscale move-register-accumulator (argument parse)
3342 MRAcc RdLo,RdHi,acc0. */
3347 unsigned long flags
;
3358 skip_whitespace (str
);
3360 if ((rdlo
= reg_required_here (& str
, 12)) == FAIL
)
3361 inst
.error
= BAD_ARGS
;
3363 else if (skip_past_comma (& str
) == FAIL
3364 || (rdhi
= reg_required_here (& str
, 16)) == FAIL
)
3365 inst
.error
= BAD_ARGS
;
3367 else if (skip_past_comma (& str
) == FAIL
3368 || accum0_required_here (& str
) == FAIL
)
3369 inst
.error
= ERR_NO_ACCUM
;
3371 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3372 else if (rdlo
== rdhi
)
3373 inst
.error
= BAD_ARGS
; /* Undefined result if 2 writes to same reg. */
3375 else if (rdlo
== REG_PC
|| rdhi
== REG_PC
)
3376 inst
.error
= BAD_PC
; /* Undefined result if rdlo or rdhi is R15. */
3381 /* Xscale: Preload-Cache
3385 Syntactically, like LDR with B=1, W=0, L=1. */
3390 unsigned long flags
;
3400 skip_whitespace (str
);
3404 inst
.error
= _("'[' expected after PLD mnemonic");
3409 skip_whitespace (str
);
3411 if ((rd
= reg_required_here (& str
, 16)) == FAIL
)
3414 skip_whitespace (str
);
3420 skip_whitespace (str
);
3422 if (skip_past_comma (& str
) == SUCCESS
)
3424 if (ldst_extend (& str
, 0) == FAIL
)
3427 else if (* str
== '!') /* [Rn]! */
3429 inst
.error
= _("writeback used in preload instruction");
3433 inst
.instruction
|= INDEX_UP
| PRE_INDEX
;
3435 else /* [Rn, ...] */
3437 if (skip_past_comma (& str
) == FAIL
)
3439 inst
.error
= _("pre-indexed expression expected");
3443 if (ldst_extend (& str
, 0) == FAIL
)
3446 skip_whitespace (str
);
3450 inst
.error
= _("missing ]");
3455 skip_whitespace (str
);
3457 if (* str
== '!') /* [Rn]! */
3459 inst
.error
= _("writeback used in preload instruction");
3463 inst
.instruction
|= PRE_INDEX
;
3469 /* Xscale load-consecutive (argument parse)
3476 do_ldrd (str
, flags
)
3478 unsigned long flags
;
3483 if (flags
!= DOUBLE_LOAD_FLAG
)
3485 /* Change instruction pattern to normal ldr/str. */
3486 if (inst
.instruction
& 0x20)
3487 inst
.instruction
= (inst
.instruction
& COND_MASK
) | 0x04000000; /* str */
3489 inst
.instruction
= (inst
.instruction
& COND_MASK
) | 0x04100000; /* ldr */
3491 /* Perform a normal load/store instruction parse. */
3492 do_ldst (str
, flags
);
3497 if ((cpu_variant
& ARM_EXT_XSCALE
) != ARM_EXT_XSCALE
)
3499 static char buff
[128];
3502 while (isspace (*str
))
3506 /* Deny all knowledge. */
3507 sprintf (buff
, _("bad instruction '%.100s'"), str
);
3512 skip_whitespace (str
);
3514 if ((rd
= reg_required_here (& str
, 12)) == FAIL
)
3516 inst
.error
= BAD_ARGS
;
3520 if (skip_past_comma (& str
) == FAIL
3521 || (rn
= ld_mode_required_here (& str
)) == FAIL
)
3524 inst
.error
= BAD_ARGS
;
3528 /* inst.instruction has now been zapped with Rd and the addressing mode. */
3529 if (rd
& 1) /* Unpredictable result if Rd is odd. */
3531 inst
.error
= _("Destination register must be even");
3535 if (rd
== REG_LR
|| rd
== 12)
3537 inst
.error
= _("r12 or r14 not allowed here");
3541 if (((rd
== rn
) || (rd
+ 1 == rn
))
3543 ((inst
.instruction
& WRITE_BACK
)
3544 || (!(inst
.instruction
& PRE_INDEX
))))
3545 as_warn (_("pre/post-indexing used when modified address register is destination"));
3550 /* Returns the index into fp_values of a floating point number,
3551 or -1 if not in the table. */
3554 my_get_float_expression (str
)
3557 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
3563 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
3565 /* Look for a raw floating point number. */
3566 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
3567 && is_end_of_line
[(unsigned char) *save_in
])
3569 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
3571 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
3573 if (words
[j
] != fp_values
[i
][j
])
3577 if (j
== MAX_LITTLENUMS
)
3585 /* Try and parse a more complex expression, this will probably fail
3586 unless the code uses a floating point prefix (eg "0f"). */
3587 save_in
= input_line_pointer
;
3588 input_line_pointer
= *str
;
3589 if (expression (&exp
) == absolute_section
3590 && exp
.X_op
== O_big
3591 && exp
.X_add_number
< 0)
3593 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
3595 if (gen_to_words (words
, 5, (long) 15) == 0)
3597 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
3599 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
3601 if (words
[j
] != fp_values
[i
][j
])
3605 if (j
== MAX_LITTLENUMS
)
3607 *str
= input_line_pointer
;
3608 input_line_pointer
= save_in
;
3615 *str
= input_line_pointer
;
3616 input_line_pointer
= save_in
;
3620 /* Return true if anything in the expression is a bignum. */
3623 walk_no_bignums (sp
)
3626 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
3629 if (symbol_get_value_expression (sp
)->X_add_symbol
)
3631 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
3632 || (symbol_get_value_expression (sp
)->X_op_symbol
3633 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
3640 my_get_expression (ep
, str
)
3647 save_in
= input_line_pointer
;
3648 input_line_pointer
= *str
;
3649 seg
= expression (ep
);
3652 if (seg
!= absolute_section
3653 && seg
!= text_section
3654 && seg
!= data_section
3655 && seg
!= bss_section
3656 && seg
!= undefined_section
)
3658 inst
.error
= _("bad_segment");
3659 *str
= input_line_pointer
;
3660 input_line_pointer
= save_in
;
3665 /* Get rid of any bignums now, so that we don't generate an error for which
3666 we can't establish a line number later on. Big numbers are never valid
3667 in instructions, which is where this routine is always called. */
3668 if (ep
->X_op
== O_big
3669 || (ep
->X_add_symbol
3670 && (walk_no_bignums (ep
->X_add_symbol
)
3672 && walk_no_bignums (ep
->X_op_symbol
)))))
3674 inst
.error
= _("Invalid constant");
3675 *str
= input_line_pointer
;
3676 input_line_pointer
= save_in
;
3680 *str
= input_line_pointer
;
3681 input_line_pointer
= save_in
;
3685 /* UNRESTRICT should be one if <shift> <register> is permitted for this
3689 decode_shift (str
, unrestrict
)
3693 const struct asm_shift_name
* shift
;
3697 skip_whitespace (* str
);
3699 for (p
= * str
; isalpha (* p
); p
++)
3704 inst
.error
= _("Shift expression expected");
3710 shift
= (const struct asm_shift_name
*) hash_find (arm_shift_hsh
, * str
);
3715 inst
.error
= _("Shift expression expected");
3719 assert (shift
->properties
->index
== shift_properties
[shift
->properties
->index
].index
);
3721 if (shift
->properties
->index
== SHIFT_RRX
)
3724 inst
.instruction
|= shift
->properties
->bit_field
;
3728 skip_whitespace (p
);
3730 if (unrestrict
&& reg_required_here (& p
, 8) != FAIL
)
3732 inst
.instruction
|= shift
->properties
->bit_field
| SHIFT_BY_REG
;
3736 else if (! is_immediate_prefix (* p
))
3738 inst
.error
= (unrestrict
3739 ? _("shift requires register or #expression")
3740 : _("shift requires #expression"));
3748 if (my_get_expression (& inst
.reloc
.exp
, & p
))
3751 /* Validate some simple #expressions. */
3752 if (inst
.reloc
.exp
.X_op
== O_constant
)
3754 unsigned num
= inst
.reloc
.exp
.X_add_number
;
3756 /* Reject operations greater than 32. */
3758 /* Reject a shift of 0 unless the mode allows it. */
3759 || (num
== 0 && shift
->properties
->allows_0
== 0)
3760 /* Reject a shift of 32 unless the mode allows it. */
3761 || (num
== 32 && shift
->properties
->allows_32
== 0)
3764 /* As a special case we allow a shift of zero for
3765 modes that do not support it to be recoded as an
3766 logical shift left of zero (ie nothing). We warn
3767 about this though. */
3770 as_warn (_("Shift of 0 ignored."));
3771 shift
= & shift_names
[0];
3772 assert (shift
->properties
->index
== SHIFT_LSL
);
3776 inst
.error
= _("Invalid immediate shift");
3781 /* Shifts of 32 are encoded as 0, for those shifts that
3786 inst
.instruction
|= (num
<< 7) | shift
->properties
->bit_field
;
3790 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
3791 inst
.reloc
.pc_rel
= 0;
3792 inst
.instruction
|= shift
->properties
->bit_field
;
3799 /* Do those data_ops which can take a negative immediate constant
3800 by altering the instuction. A bit of a hack really.
3804 by inverting the second operand, and
3807 by negating the second operand. */
3810 negate_data_op (instruction
, value
)
3811 unsigned long * instruction
;
3812 unsigned long value
;
3815 unsigned long negated
, inverted
;
3817 negated
= validate_immediate (-value
);
3818 inverted
= validate_immediate (~value
);
3820 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
3823 /* First negates. */
3824 case OPCODE_SUB
: /* ADD <-> SUB */
3825 new_inst
= OPCODE_ADD
;
3830 new_inst
= OPCODE_SUB
;
3834 case OPCODE_CMP
: /* CMP <-> CMN */
3835 new_inst
= OPCODE_CMN
;
3840 new_inst
= OPCODE_CMP
;
3844 /* Now Inverted ops. */
3845 case OPCODE_MOV
: /* MOV <-> MVN */
3846 new_inst
= OPCODE_MVN
;
3851 new_inst
= OPCODE_MOV
;
3855 case OPCODE_AND
: /* AND <-> BIC */
3856 new_inst
= OPCODE_BIC
;
3861 new_inst
= OPCODE_AND
;
3865 case OPCODE_ADC
: /* ADC <-> SBC */
3866 new_inst
= OPCODE_SBC
;
3871 new_inst
= OPCODE_ADC
;
3875 /* We cannot do anything. */
3880 if (value
== (unsigned) FAIL
)
3883 *instruction
&= OPCODE_MASK
;
3884 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
3895 skip_whitespace (* str
);
3897 if (reg_required_here (str
, 0) != FAIL
)
3899 if (skip_past_comma (str
) == SUCCESS
)
3900 /* Shift operation on register. */
3901 return decode_shift (str
, NO_SHIFT_RESTRICT
);
3907 /* Immediate expression. */
3908 if (is_immediate_prefix (**str
))
3913 if (my_get_expression (&inst
.reloc
.exp
, str
))
3916 if (inst
.reloc
.exp
.X_add_symbol
)
3918 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
3919 inst
.reloc
.pc_rel
= 0;
3923 if (skip_past_comma (str
) == SUCCESS
)
3925 /* #x, y -- ie explicit rotation by Y. */
3926 if (my_get_expression (&expr
, str
))
3929 if (expr
.X_op
!= O_constant
)
3931 inst
.error
= _("Constant expression expected");
3935 /* Rotate must be a multiple of 2. */
3936 if (((unsigned) expr
.X_add_number
) > 30
3937 || (expr
.X_add_number
& 1) != 0
3938 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
3940 inst
.error
= _("Invalid constant");
3943 inst
.instruction
|= INST_IMMEDIATE
;
3944 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
3945 inst
.instruction
|= expr
.X_add_number
<< 7;
3949 /* Implicit rotation, select a suitable one. */
3950 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
3954 /* Can't be done. Perhaps the code reads something like
3955 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
3956 if ((value
= negate_data_op (&inst
.instruction
,
3957 inst
.reloc
.exp
.X_add_number
))
3960 inst
.error
= _("Invalid constant");
3965 inst
.instruction
|= value
;
3968 inst
.instruction
|= INST_IMMEDIATE
;
3973 inst
.error
= _("Register or shift expression expected");
3982 skip_whitespace (* str
);
3984 if (fp_reg_required_here (str
, 0) != FAIL
)
3988 /* Immediate expression. */
3989 if (*((*str
)++) == '#')
3995 skip_whitespace (* str
);
3997 /* First try and match exact strings, this is to guarantee
3998 that some formats will work even for cross assembly. */
4000 for (i
= 0; fp_const
[i
]; i
++)
4002 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
4006 *str
+= strlen (fp_const
[i
]);
4007 if (is_end_of_line
[(unsigned char) **str
])
4009 inst
.instruction
|= i
+ 8;
4016 /* Just because we didn't get a match doesn't mean that the
4017 constant isn't valid, just that it is in a format that we
4018 don't automatically recognize. Try parsing it with
4019 the standard expression routines. */
4020 if ((i
= my_get_float_expression (str
)) >= 0)
4022 inst
.instruction
|= i
+ 8;
4026 inst
.error
= _("Invalid floating point immediate expression");
4030 _("Floating point register or immediate expression expected");
4036 do_arit (str
, flags
)
4038 unsigned long flags
;
4040 skip_whitespace (str
);
4042 if (reg_required_here (&str
, 12) == FAIL
4043 || skip_past_comma (&str
) == FAIL
4044 || reg_required_here (&str
, 16) == FAIL
4045 || skip_past_comma (&str
) == FAIL
4046 || data_op2 (&str
) == FAIL
)
4049 inst
.error
= BAD_ARGS
;
4053 inst
.instruction
|= flags
;
4061 unsigned long flags
;
4063 /* This is a pseudo-op of the form "adr rd, label" to be converted
4064 into a relative address of the form "add rd, pc, #label-.-8". */
4065 skip_whitespace (str
);
4067 if (reg_required_here (&str
, 12) == FAIL
4068 || skip_past_comma (&str
) == FAIL
4069 || my_get_expression (&inst
.reloc
.exp
, &str
))
4072 inst
.error
= BAD_ARGS
;
4076 /* Frag hacking will turn this into a sub instruction if the offset turns
4077 out to be negative. */
4078 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
4079 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
4080 inst
.reloc
.pc_rel
= 1;
4081 inst
.instruction
|= flags
;
4087 do_adrl (str
, flags
)
4089 unsigned long flags
;
4091 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4092 into a relative address of the form:
4093 add rd, pc, #low(label-.-8)"
4094 add rd, rd, #high(label-.-8)" */
4096 skip_whitespace (str
);
4098 if (reg_required_here (& str
, 12) == FAIL
4099 || skip_past_comma (& str
) == FAIL
4100 || my_get_expression (& inst
.reloc
.exp
, & str
))
4103 inst
.error
= BAD_ARGS
;
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_ADRL_IMMEDIATE
;
4112 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
4113 inst
.reloc
.pc_rel
= 1;
4114 inst
.instruction
|= flags
;
4115 inst
.size
= INSN_SIZE
* 2;
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
)
4327 as_warn (_("%s register same as write-back base"),
4328 ((inst
.instruction
& LOAD_BIT
)
4329 ? _("destination") : _("source")));
4335 inst
.instruction
|= HWOFFSET_IMM
;
4337 skip_whitespace (str
);
4342 as_warn (_("%s register same as write-back base"),
4343 ((inst
.instruction
& LOAD_BIT
)
4344 ? _("destination") : _("source")));
4346 inst
.instruction
|= WRITE_BACK
;
4350 if (! (flags
& TRANS_BIT
))
4357 if (skip_past_comma (&str
) == FAIL
)
4359 inst
.error
= _("pre-indexed expression expected");
4364 if (ldst_extend (&str
, halfword
) == FAIL
)
4367 skip_whitespace (str
);
4371 inst
.error
= _("missing ]");
4375 skip_whitespace (str
);
4380 as_warn (_("%s register same as write-back base"),
4381 ((inst
.instruction
& LOAD_BIT
)
4382 ? _("destination") : _("source")));
4384 inst
.instruction
|= WRITE_BACK
;
4388 else if (*str
== '=')
4390 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4393 skip_whitespace (str
);
4395 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4398 if (inst
.reloc
.exp
.X_op
!= O_constant
4399 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4401 inst
.error
= _("Constant expression expected");
4405 if (inst
.reloc
.exp
.X_op
== O_constant
4406 && (value
= validate_immediate (inst
.reloc
.exp
.X_add_number
)) != FAIL
)
4408 /* This can be done with a mov instruction. */
4409 inst
.instruction
&= LITERAL_MASK
;
4410 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
4411 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
4417 /* Insert into literal pool. */
4418 if (add_to_lit_pool () == FAIL
)
4421 inst
.error
= _("literal pool insertion failed");
4425 /* Change the instruction exp to point to the pool. */
4428 inst
.instruction
|= HWOFFSET_IMM
;
4429 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
4432 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
4433 inst
.reloc
.pc_rel
= 1;
4434 inst
.instruction
|= (REG_PC
<< 16);
4440 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4445 inst
.instruction
|= HWOFFSET_IMM
;
4446 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
4449 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
4451 /* PC rel adjust. */
4452 inst
.reloc
.exp
.X_add_number
-= 8;
4454 inst
.reloc
.pc_rel
= 1;
4455 inst
.instruction
|= (REG_PC
<< 16);
4459 if (pre_inc
&& (flags
& TRANS_BIT
))
4460 inst
.error
= _("Pre-increment instruction with translate");
4462 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
4471 char * str
= * strp
;
4475 /* We come back here if we get ranges concatenated by '+' or '|'. */
4490 skip_whitespace (str
);
4492 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
4501 inst
.error
= _("Bad range in register list");
4505 for (i
= cur_reg
+ 1; i
< reg
; i
++)
4507 if (range
& (1 << i
))
4509 (_("Warning: Duplicated register (r%d) in register list"),
4517 if (range
& (1 << reg
))
4518 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
4520 else if (reg
<= cur_reg
)
4521 as_tsktsk (_("Warning: Register range not in ascending order"));
4526 while (skip_past_comma (&str
) != FAIL
4527 || (in_range
= 1, *str
++ == '-'));
4529 skip_whitespace (str
);
4533 inst
.error
= _("Missing `}'");
4541 if (my_get_expression (&expr
, &str
))
4544 if (expr
.X_op
== O_constant
)
4546 if (expr
.X_add_number
4547 != (expr
.X_add_number
& 0x0000ffff))
4549 inst
.error
= _("invalid register mask");
4553 if ((range
& expr
.X_add_number
) != 0)
4555 int regno
= range
& expr
.X_add_number
;
4558 regno
= (1 << regno
) - 1;
4560 (_("Warning: Duplicated register (r%d) in register list"),
4564 range
|= expr
.X_add_number
;
4568 if (inst
.reloc
.type
!= 0)
4570 inst
.error
= _("expression too complex");
4574 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
4575 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
4576 inst
.reloc
.pc_rel
= 0;
4580 skip_whitespace (str
);
4582 if (*str
== '|' || *str
== '+')
4588 while (another_range
);
4595 do_ldmstm (str
, flags
)
4597 unsigned long flags
;
4602 skip_whitespace (str
);
4604 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
4607 if (base_reg
== REG_PC
)
4609 inst
.error
= _("r15 not allowed as base register");
4613 skip_whitespace (str
);
4617 flags
|= WRITE_BACK
;
4621 if (skip_past_comma (&str
) == FAIL
4622 || (range
= reg_list (&str
)) == FAIL
)
4625 inst
.error
= BAD_ARGS
;
4632 flags
|= LDM_TYPE_2_OR_3
;
4635 inst
.instruction
|= flags
| range
;
4643 unsigned long flags
;
4645 skip_whitespace (str
);
4647 /* Allow optional leading '#'. */
4648 if (is_immediate_prefix (*str
))
4651 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4654 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4655 inst
.reloc
.pc_rel
= 0;
4656 inst
.instruction
|= flags
;
4664 do_swap (str
, flags
)
4666 unsigned long flags
;
4670 skip_whitespace (str
);
4672 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
4677 inst
.error
= _("r15 not allowed in swap");
4681 if (skip_past_comma (&str
) == FAIL
4682 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
4685 inst
.error
= BAD_ARGS
;
4691 inst
.error
= _("r15 not allowed in swap");
4695 if (skip_past_comma (&str
) == FAIL
4698 inst
.error
= BAD_ARGS
;
4702 skip_whitespace (str
);
4704 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
4709 inst
.error
= BAD_PC
;
4713 skip_whitespace (str
);
4717 inst
.error
= _("missing ]");
4721 inst
.instruction
|= flags
;
4727 do_branch (str
, flags
)
4729 unsigned long flags ATTRIBUTE_UNUSED
;
4731 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4738 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
4739 required for the instruction. */
4741 /* arm_parse_reloc () works on input_line_pointer.
4742 We actually want to parse the operands to the branch instruction
4743 passed in 'str'. Save the input pointer and restore it later. */
4744 save_in
= input_line_pointer
;
4745 input_line_pointer
= str
;
4746 if (inst
.reloc
.exp
.X_op
== O_symbol
4748 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
4750 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
4751 inst
.reloc
.pc_rel
= 0;
4752 /* Modify str to point to after parsed operands, otherwise
4753 end_of_line() will complain about the (PLT) left in str. */
4754 str
= input_line_pointer
;
4758 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
4759 inst
.reloc
.pc_rel
= 1;
4761 input_line_pointer
= save_in
;
4764 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
4765 inst
.reloc
.pc_rel
= 1;
4766 #endif /* OBJ_ELF */
4775 unsigned long flags ATTRIBUTE_UNUSED
;
4779 skip_whitespace (str
);
4781 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
4783 inst
.error
= BAD_ARGS
;
4787 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
4789 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
4797 unsigned long flags ATTRIBUTE_UNUSED
;
4799 /* Co-processor data operation.
4800 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
4801 skip_whitespace (str
);
4803 if (co_proc_number (&str
) == FAIL
)
4806 inst
.error
= BAD_ARGS
;
4810 if (skip_past_comma (&str
) == FAIL
4811 || cp_opc_expr (&str
, 20,4) == FAIL
)
4814 inst
.error
= BAD_ARGS
;
4818 if (skip_past_comma (&str
) == FAIL
4819 || cp_reg_required_here (&str
, 12) == FAIL
)
4822 inst
.error
= BAD_ARGS
;
4826 if (skip_past_comma (&str
) == FAIL
4827 || cp_reg_required_here (&str
, 16) == FAIL
)
4830 inst
.error
= BAD_ARGS
;
4834 if (skip_past_comma (&str
) == FAIL
4835 || cp_reg_required_here (&str
, 0) == FAIL
)
4838 inst
.error
= BAD_ARGS
;
4842 if (skip_past_comma (&str
) == SUCCESS
)
4844 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
4847 inst
.error
= BAD_ARGS
;
4857 do_lstc (str
, flags
)
4859 unsigned long flags
;
4861 /* Co-processor register load/store.
4862 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
4864 skip_whitespace (str
);
4866 if (co_proc_number (&str
) == FAIL
)
4869 inst
.error
= BAD_ARGS
;
4873 if (skip_past_comma (&str
) == FAIL
4874 || cp_reg_required_here (&str
, 12) == FAIL
)
4877 inst
.error
= BAD_ARGS
;
4881 if (skip_past_comma (&str
) == FAIL
4882 || cp_address_required_here (&str
) == FAIL
)
4885 inst
.error
= BAD_ARGS
;
4889 inst
.instruction
|= flags
;
4895 do_co_reg (str
, flags
)
4897 unsigned long flags
;
4899 /* Co-processor register transfer.
4900 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
4902 skip_whitespace (str
);
4904 if (co_proc_number (&str
) == FAIL
)
4907 inst
.error
= BAD_ARGS
;
4911 if (skip_past_comma (&str
) == FAIL
4912 || cp_opc_expr (&str
, 21, 3) == FAIL
)
4915 inst
.error
= BAD_ARGS
;
4919 if (skip_past_comma (&str
) == FAIL
4920 || reg_required_here (&str
, 12) == FAIL
)
4923 inst
.error
= BAD_ARGS
;
4927 if (skip_past_comma (&str
) == FAIL
4928 || cp_reg_required_here (&str
, 16) == FAIL
)
4931 inst
.error
= BAD_ARGS
;
4935 if (skip_past_comma (&str
) == FAIL
4936 || cp_reg_required_here (&str
, 0) == FAIL
)
4939 inst
.error
= BAD_ARGS
;
4943 if (skip_past_comma (&str
) == SUCCESS
)
4945 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
4948 inst
.error
= BAD_ARGS
;
4954 inst
.error
= BAD_COND
;
4962 do_fp_ctrl (str
, flags
)
4964 unsigned long flags ATTRIBUTE_UNUSED
;
4966 /* FP control registers.
4967 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
4969 skip_whitespace (str
);
4971 if (reg_required_here (&str
, 12) == FAIL
)
4974 inst
.error
= BAD_ARGS
;
4983 do_fp_ldst (str
, flags
)
4985 unsigned long flags ATTRIBUTE_UNUSED
;
4987 skip_whitespace (str
);
4989 switch (inst
.suffix
)
4994 inst
.instruction
|= CP_T_X
;
4997 inst
.instruction
|= CP_T_Y
;
5000 inst
.instruction
|= CP_T_X
| CP_T_Y
;
5006 if (fp_reg_required_here (&str
, 12) == FAIL
)
5009 inst
.error
= BAD_ARGS
;
5013 if (skip_past_comma (&str
) == FAIL
5014 || cp_address_required_here (&str
) == FAIL
)
5017 inst
.error
= BAD_ARGS
;
5025 do_fp_ldmstm (str
, flags
)
5027 unsigned long flags
;
5031 skip_whitespace (str
);
5033 if (fp_reg_required_here (&str
, 12) == FAIL
)
5036 inst
.error
= BAD_ARGS
;
5040 /* Get Number of registers to transfer. */
5041 if (skip_past_comma (&str
) == FAIL
5042 || my_get_expression (&inst
.reloc
.exp
, &str
))
5045 inst
.error
= _("constant expression expected");
5049 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5051 inst
.error
= _("Constant value required for number of registers");
5055 num_regs
= inst
.reloc
.exp
.X_add_number
;
5057 if (num_regs
< 1 || num_regs
> 4)
5059 inst
.error
= _("number of registers must be in the range [1:4]");
5066 inst
.instruction
|= CP_T_X
;
5069 inst
.instruction
|= CP_T_Y
;
5072 inst
.instruction
|= CP_T_Y
| CP_T_X
;
5086 /* The instruction specified "ea" or "fd", so we can only accept
5087 [Rn]{!}. The instruction does not really support stacking or
5088 unstacking, so we have to emulate these by setting appropriate
5089 bits and offsets. */
5090 if (skip_past_comma (&str
) == FAIL
5094 inst
.error
= BAD_ARGS
;
5099 skip_whitespace (str
);
5101 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
5104 skip_whitespace (str
);
5108 inst
.error
= BAD_ARGS
;
5120 _("R15 not allowed as base register with write-back");
5127 if (flags
& CP_T_Pre
)
5129 /* Pre-decrement. */
5130 offset
= 3 * num_regs
;
5136 /* Post-increment. */
5140 offset
= 3 * num_regs
;
5144 /* No write-back, so convert this into a standard pre-increment
5145 instruction -- aesthetically more pleasing. */
5146 flags
= CP_T_Pre
| CP_T_UD
;
5151 inst
.instruction
|= flags
| offset
;
5153 else if (skip_past_comma (&str
) == FAIL
5154 || cp_address_required_here (&str
) == FAIL
)
5157 inst
.error
= BAD_ARGS
;
5165 do_fp_dyadic (str
, flags
)
5167 unsigned long flags
;
5169 skip_whitespace (str
);
5171 switch (inst
.suffix
)
5176 inst
.instruction
|= 0x00000080;
5179 inst
.instruction
|= 0x00080000;
5185 if (fp_reg_required_here (&str
, 12) == FAIL
)
5188 inst
.error
= BAD_ARGS
;
5192 if (skip_past_comma (&str
) == FAIL
5193 || fp_reg_required_here (&str
, 16) == FAIL
)
5196 inst
.error
= BAD_ARGS
;
5200 if (skip_past_comma (&str
) == FAIL
5201 || fp_op2 (&str
) == FAIL
)
5204 inst
.error
= BAD_ARGS
;
5208 inst
.instruction
|= flags
;
5214 do_fp_monadic (str
, flags
)
5216 unsigned long flags
;
5218 skip_whitespace (str
);
5220 switch (inst
.suffix
)
5225 inst
.instruction
|= 0x00000080;
5228 inst
.instruction
|= 0x00080000;
5234 if (fp_reg_required_here (&str
, 12) == FAIL
)
5237 inst
.error
= BAD_ARGS
;
5241 if (skip_past_comma (&str
) == FAIL
5242 || fp_op2 (&str
) == FAIL
)
5245 inst
.error
= BAD_ARGS
;
5249 inst
.instruction
|= flags
;
5255 do_fp_cmp (str
, flags
)
5257 unsigned long flags
;
5259 skip_whitespace (str
);
5261 if (fp_reg_required_here (&str
, 16) == FAIL
)
5264 inst
.error
= BAD_ARGS
;
5268 if (skip_past_comma (&str
) == FAIL
5269 || fp_op2 (&str
) == FAIL
)
5272 inst
.error
= BAD_ARGS
;
5276 inst
.instruction
|= flags
;
5282 do_fp_from_reg (str
, flags
)
5284 unsigned long flags
;
5286 skip_whitespace (str
);
5288 switch (inst
.suffix
)
5293 inst
.instruction
|= 0x00000080;
5296 inst
.instruction
|= 0x00080000;
5302 if (fp_reg_required_here (&str
, 16) == FAIL
)
5305 inst
.error
= BAD_ARGS
;
5309 if (skip_past_comma (&str
) == FAIL
5310 || reg_required_here (&str
, 12) == FAIL
)
5313 inst
.error
= BAD_ARGS
;
5317 inst
.instruction
|= flags
;
5323 do_fp_to_reg (str
, flags
)
5325 unsigned long flags
;
5327 skip_whitespace (str
);
5329 if (reg_required_here (&str
, 12) == FAIL
)
5332 if (skip_past_comma (&str
) == FAIL
5333 || fp_reg_required_here (&str
, 0) == FAIL
)
5336 inst
.error
= BAD_ARGS
;
5340 inst
.instruction
|= flags
;
5345 /* Thumb specific routines. */
5347 /* Parse and validate that a register is of the right form, this saves
5348 repeated checking of this information in many similar cases.
5349 Unlike the 32-bit case we do not insert the register into the opcode
5350 here, since the position is often unknown until the full instruction
5354 thumb_reg (strp
, hi_lo
)
5360 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
5368 inst
.error
= _("lo register required");
5376 inst
.error
= _("hi register required");
5388 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
5392 thumb_add_sub (str
, subtract
)
5396 int Rd
, Rs
, Rn
= FAIL
;
5398 skip_whitespace (str
);
5400 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
5401 || skip_past_comma (&str
) == FAIL
)
5404 inst
.error
= BAD_ARGS
;
5408 if (is_immediate_prefix (*str
))
5412 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5417 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5420 if (skip_past_comma (&str
) == FAIL
)
5422 /* Two operand format, shuffle the registers
5423 and pretend there are 3. */
5427 else if (is_immediate_prefix (*str
))
5430 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5433 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5437 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5438 for the latter case, EXPR contains the immediate that was found. */
5441 /* All register format. */
5442 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
5446 inst
.error
= _("dest and source1 must be the same register");
5450 /* Can't do this for SUB. */
5453 inst
.error
= _("subtract valid only on lo regs");
5457 inst
.instruction
= (T_OPCODE_ADD_HI
5458 | (Rd
> 7 ? THUMB_H1
: 0)
5459 | (Rn
> 7 ? THUMB_H2
: 0));
5460 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
5464 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
5465 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
5470 /* Immediate expression, now things start to get nasty. */
5472 /* First deal with HI regs, only very restricted cases allowed:
5473 Adjusting SP, and using PC or SP to get an address. */
5474 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
5475 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
5477 inst
.error
= _("invalid Hi register with immediate");
5481 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5483 /* Value isn't known yet, all we can do is store all the fragments
5484 we know about in the instruction and let the reloc hacking
5486 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
5487 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
5491 int offset
= inst
.reloc
.exp
.X_add_number
;
5501 /* Quick check, in case offset is MIN_INT. */
5504 inst
.error
= _("immediate value out of range");
5513 if (offset
& ~0x1fc)
5515 inst
.error
= _("invalid immediate value for stack adjust");
5518 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5519 inst
.instruction
|= offset
>> 2;
5521 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
5524 || (offset
& ~0x3fc))
5526 inst
.error
= _("invalid immediate for address calculation");
5529 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
5531 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
5537 inst
.error
= _("immediate value out of range");
5540 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5541 inst
.instruction
|= (Rd
<< 8) | offset
;
5547 inst
.error
= _("immediate value out of range");
5550 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5551 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
5560 thumb_shift (str
, shift
)
5564 int Rd
, Rs
, Rn
= FAIL
;
5566 skip_whitespace (str
);
5568 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5569 || skip_past_comma (&str
) == FAIL
)
5572 inst
.error
= BAD_ARGS
;
5576 if (is_immediate_prefix (*str
))
5578 /* Two operand immediate format, set Rs to Rd. */
5581 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5586 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5589 if (skip_past_comma (&str
) == FAIL
)
5591 /* Two operand format, shuffle the registers
5592 and pretend there are 3. */
5596 else if (is_immediate_prefix (*str
))
5599 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5602 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5606 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5607 for the latter case, EXPR contains the immediate that was found. */
5613 inst
.error
= _("source1 and dest must be same register");
5619 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
5620 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
5621 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
5624 inst
.instruction
|= Rd
| (Rn
<< 3);
5630 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
5631 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
5632 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
5635 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5637 /* Value isn't known yet, create a dummy reloc and let reloc
5638 hacking fix it up. */
5639 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
5643 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
5645 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
5647 inst
.error
= _("Invalid immediate for shift");
5651 /* Shifts of zero are handled by converting to LSL. */
5652 if (shift_value
== 0)
5653 inst
.instruction
= T_OPCODE_LSL_I
;
5655 /* Shifts of 32 are encoded as a shift of zero. */
5656 if (shift_value
== 32)
5659 inst
.instruction
|= shift_value
<< 6;
5662 inst
.instruction
|= Rd
| (Rs
<< 3);
5669 thumb_mov_compare (str
, move
)
5675 skip_whitespace (str
);
5677 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
5678 || skip_past_comma (&str
) == FAIL
)
5681 inst
.error
= BAD_ARGS
;
5685 if (is_immediate_prefix (*str
))
5688 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5691 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5696 if (Rs
< 8 && Rd
< 8)
5698 if (move
== THUMB_MOVE
)
5699 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
5700 since a MOV instruction produces unpredictable results. */
5701 inst
.instruction
= T_OPCODE_ADD_I3
;
5703 inst
.instruction
= T_OPCODE_CMP_LR
;
5704 inst
.instruction
|= Rd
| (Rs
<< 3);
5708 if (move
== THUMB_MOVE
)
5709 inst
.instruction
= T_OPCODE_MOV_HR
;
5711 inst
.instruction
= T_OPCODE_CMP_HR
;
5714 inst
.instruction
|= THUMB_H1
;
5717 inst
.instruction
|= THUMB_H2
;
5719 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
5726 inst
.error
= _("only lo regs allowed with immediate");
5730 if (move
== THUMB_MOVE
)
5731 inst
.instruction
= T_OPCODE_MOV_I8
;
5733 inst
.instruction
= T_OPCODE_CMP_I8
;
5735 inst
.instruction
|= Rd
<< 8;
5737 if (inst
.reloc
.exp
.X_op
!= O_constant
)
5738 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
5741 unsigned value
= inst
.reloc
.exp
.X_add_number
;
5745 inst
.error
= _("invalid immediate");
5749 inst
.instruction
|= value
;
5757 thumb_load_store (str
, load_store
, size
)
5762 int Rd
, Rb
, Ro
= FAIL
;
5764 skip_whitespace (str
);
5766 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5767 || skip_past_comma (&str
) == FAIL
)
5770 inst
.error
= BAD_ARGS
;
5777 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
5780 if (skip_past_comma (&str
) != FAIL
)
5782 if (is_immediate_prefix (*str
))
5785 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5788 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5793 inst
.reloc
.exp
.X_op
= O_constant
;
5794 inst
.reloc
.exp
.X_add_number
= 0;
5799 inst
.error
= _("expected ']'");
5804 else if (*str
== '=')
5806 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5809 skip_whitespace (str
);
5811 if (my_get_expression (& inst
.reloc
.exp
, & str
))
5816 if ( inst
.reloc
.exp
.X_op
!= O_constant
5817 && inst
.reloc
.exp
.X_op
!= O_symbol
)
5819 inst
.error
= "Constant expression expected";
5823 if (inst
.reloc
.exp
.X_op
== O_constant
5824 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
5826 /* This can be done with a mov instruction. */
5828 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
5829 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
5833 /* Insert into literal pool. */
5834 if (add_to_lit_pool () == FAIL
)
5837 inst
.error
= "literal pool insertion failed";
5841 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
5842 inst
.reloc
.pc_rel
= 1;
5843 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
5844 /* Adjust ARM pipeline offset to Thumb. */
5845 inst
.reloc
.exp
.X_add_number
+= 4;
5851 if (my_get_expression (&inst
.reloc
.exp
, &str
))
5854 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
5855 inst
.reloc
.pc_rel
= 1;
5856 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset. */
5857 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
5862 if (Rb
== REG_PC
|| Rb
== REG_SP
)
5864 if (size
!= THUMB_WORD
)
5866 inst
.error
= _("byte or halfword not valid for base register");
5869 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
5871 inst
.error
= _("R15 based store not allowed");
5874 else if (Ro
!= FAIL
)
5876 inst
.error
= _("Invalid base register for register offset");
5881 inst
.instruction
= T_OPCODE_LDR_PC
;
5882 else if (load_store
== THUMB_LOAD
)
5883 inst
.instruction
= T_OPCODE_LDR_SP
;
5885 inst
.instruction
= T_OPCODE_STR_SP
;
5887 inst
.instruction
|= Rd
<< 8;
5888 if (inst
.reloc
.exp
.X_op
== O_constant
)
5890 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
5892 if (offset
& ~0x3fc)
5894 inst
.error
= _("invalid offset");
5898 inst
.instruction
|= offset
>> 2;
5901 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
5905 inst
.error
= _("invalid base register in load/store");
5908 else if (Ro
== FAIL
)
5910 /* Immediate offset. */
5911 if (size
== THUMB_WORD
)
5912 inst
.instruction
= (load_store
== THUMB_LOAD
5913 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
5914 else if (size
== THUMB_HALFWORD
)
5915 inst
.instruction
= (load_store
== THUMB_LOAD
5916 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
5918 inst
.instruction
= (load_store
== THUMB_LOAD
5919 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
5921 inst
.instruction
|= Rd
| (Rb
<< 3);
5923 if (inst
.reloc
.exp
.X_op
== O_constant
)
5925 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
5927 if (offset
& ~(0x1f << size
))
5929 inst
.error
= _("Invalid offset");
5932 inst
.instruction
|= (offset
>> size
) << 6;
5935 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
5939 /* Register offset. */
5940 if (size
== THUMB_WORD
)
5941 inst
.instruction
= (load_store
== THUMB_LOAD
5942 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
5943 else if (size
== THUMB_HALFWORD
)
5944 inst
.instruction
= (load_store
== THUMB_LOAD
5945 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
5947 inst
.instruction
= (load_store
== THUMB_LOAD
5948 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
5950 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
5965 /* Handle the Format 4 instructions that do not have equivalents in other
5966 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
5975 skip_whitespace (str
);
5977 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
5978 || skip_past_comma (&str
) == FAIL
5979 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
5981 inst
.error
= BAD_ARGS
;
5985 if (skip_past_comma (&str
) != FAIL
)
5987 /* Three operand format not allowed for TST, CMN, NEG and MVN.
5988 (It isn't allowed for CMP either, but that isn't handled by this
5990 if (inst
.instruction
== T_OPCODE_TST
5991 || inst
.instruction
== T_OPCODE_CMN
5992 || inst
.instruction
== T_OPCODE_NEG
5993 || inst
.instruction
== T_OPCODE_MVN
)
5995 inst
.error
= BAD_ARGS
;
5999 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6004 inst
.error
= _("dest and source1 one must be the same register");
6010 if (inst
.instruction
== T_OPCODE_MUL
6012 as_tsktsk (_("Rs and Rd must be different in MUL"));
6014 inst
.instruction
|= Rd
| (Rs
<< 3);
6022 thumb_add_sub (str
, 0);
6029 thumb_shift (str
, THUMB_ASR
);
6036 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6038 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
6039 inst
.reloc
.pc_rel
= 1;
6047 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6049 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
6050 inst
.reloc
.pc_rel
= 1;
6054 /* Find the real, Thumb encoded start of a Thumb function. */
6057 find_real_start (symbolP
)
6061 const char * name
= S_GET_NAME (symbolP
);
6062 symbolS
* new_target
;
6064 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
6065 #define STUB_NAME ".real_start_of"
6070 /* Names that start with '.' are local labels, not function entry points.
6071 The compiler may generate BL instructions to these labels because it
6072 needs to perform a branch to a far away location. */
6076 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
6077 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
6079 new_target
= symbol_find (real_start
);
6081 if (new_target
== NULL
)
6083 as_warn ("Failed to find real start of function: %s\n", name
);
6084 new_target
= symbolP
;
6096 if (my_get_expression (& inst
.reloc
.exp
, & str
))
6099 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
6100 inst
.reloc
.pc_rel
= 1;
6103 /* If the destination of the branch is a defined symbol which does not have
6104 the THUMB_FUNC attribute, then we must be calling a function which has
6105 the (interfacearm) attribute. We look for the Thumb entry point to that
6106 function and change the branch to refer to that function instead. */
6107 if ( inst
.reloc
.exp
.X_op
== O_symbol
6108 && inst
.reloc
.exp
.X_add_symbol
!= NULL
6109 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
6110 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
6111 inst
.reloc
.exp
.X_add_symbol
=
6112 find_real_start (inst
.reloc
.exp
.X_add_symbol
);
6121 skip_whitespace (str
);
6123 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
6126 /* This sets THUMB_H2 from the top bit of reg. */
6127 inst
.instruction
|= reg
<< 3;
6129 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
6130 should cause the alignment to be checked once it is known. This is
6131 because BX PC only works if the instruction is word aligned. */
6140 thumb_mov_compare (str
, THUMB_COMPARE
);
6150 skip_whitespace (str
);
6152 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
6156 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
6160 if (skip_past_comma (&str
) == FAIL
6161 || (range
= reg_list (&str
)) == FAIL
)
6164 inst
.error
= BAD_ARGS
;
6168 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6170 /* This really doesn't seem worth it. */
6171 inst
.reloc
.type
= BFD_RELOC_NONE
;
6172 inst
.error
= _("Expression too complex");
6178 inst
.error
= _("only lo-regs valid in load/store multiple");
6182 inst
.instruction
|= (Rb
<< 8) | range
;
6190 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
6197 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
6204 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
6213 skip_whitespace (str
);
6215 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6216 || skip_past_comma (&str
) == FAIL
6218 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6219 || skip_past_comma (&str
) == FAIL
6220 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
6224 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
6228 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
6236 thumb_shift (str
, THUMB_LSL
);
6243 thumb_shift (str
, THUMB_LSR
);
6250 thumb_mov_compare (str
, THUMB_MOVE
);
6259 skip_whitespace (str
);
6261 if ((range
= reg_list (&str
)) == FAIL
)
6264 inst
.error
= BAD_ARGS
;
6268 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6270 /* This really doesn't seem worth it. */
6271 inst
.reloc
.type
= BFD_RELOC_NONE
;
6272 inst
.error
= _("Expression too complex");
6278 if ((inst
.instruction
== T_OPCODE_PUSH
6279 && (range
& ~0xff) == 1 << REG_LR
)
6280 || (inst
.instruction
== T_OPCODE_POP
6281 && (range
& ~0xff) == 1 << REG_PC
))
6283 inst
.instruction
|= THUMB_PP_PC_LR
;
6288 inst
.error
= _("invalid register list to push/pop instruction");
6293 inst
.instruction
|= range
;
6301 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
6308 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
6315 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
6322 thumb_add_sub (str
, 1);
6329 skip_whitespace (str
);
6331 if (my_get_expression (&inst
.reloc
.exp
, &str
))
6334 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
6345 /* This is a pseudo-op of the form "adr rd, label" to be converted
6346 into a relative address of the form "add rd, pc, #label-.-4". */
6347 skip_whitespace (str
);
6349 /* Store Rd in temporary location inside instruction. */
6350 if ((reg
= reg_required_here (&str
, 4)) == FAIL
6351 || (reg
> 7) /* For Thumb reg must be r0..r7. */
6352 || skip_past_comma (&str
) == FAIL
6353 || my_get_expression (&inst
.reloc
.exp
, &str
))
6356 inst
.error
= BAD_ARGS
;
6360 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
6361 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
6362 inst
.reloc
.pc_rel
= 1;
6363 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
6372 int len
= strlen (reg_table
[entry
].name
) + 2;
6373 char * buf
= (char *) xmalloc (len
);
6374 char * buf2
= (char *) xmalloc (len
);
6377 #ifdef REGISTER_PREFIX
6378 buf
[i
++] = REGISTER_PREFIX
;
6381 strcpy (buf
+ i
, reg_table
[entry
].name
);
6383 for (i
= 0; buf
[i
]; i
++)
6384 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
6388 hash_insert (arm_reg_hsh
, buf
, (PTR
) & reg_table
[entry
]);
6389 hash_insert (arm_reg_hsh
, buf2
, (PTR
) & reg_table
[entry
]);
6393 insert_reg_alias (str
, regnum
)
6397 struct reg_entry
*new =
6398 (struct reg_entry
*) xmalloc (sizeof (struct reg_entry
));
6399 char *name
= xmalloc (strlen (str
) + 1);
6403 new->number
= regnum
;
6405 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
6409 set_constant_flonums ()
6413 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
6414 if (atof_ieee ((char *) fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
6424 if ( (arm_ops_hsh
= hash_new ()) == NULL
6425 || (arm_tops_hsh
= hash_new ()) == NULL
6426 || (arm_cond_hsh
= hash_new ()) == NULL
6427 || (arm_shift_hsh
= hash_new ()) == NULL
6428 || (arm_reg_hsh
= hash_new ()) == NULL
6429 || (arm_psr_hsh
= hash_new ()) == NULL
)
6430 as_fatal (_("Virtual memory exhausted"));
6432 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
6433 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
6434 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
6435 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
6436 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
6437 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
6438 for (i
= 0; i
< sizeof (shift_names
) / sizeof (struct asm_shift_name
); i
++)
6439 hash_insert (arm_shift_hsh
, shift_names
[i
].name
, (PTR
) (shift_names
+ i
));
6440 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
6441 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
6443 for (i
= 0; reg_table
[i
].name
; i
++)
6446 set_constant_flonums ();
6448 #if defined OBJ_COFF || defined OBJ_ELF
6450 unsigned int flags
= 0;
6452 /* Set the flags in the private structure. */
6453 if (uses_apcs_26
) flags
|= F_APCS26
;
6454 if (support_interwork
) flags
|= F_INTERWORK
;
6455 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
6456 if (pic_code
) flags
|= F_PIC
;
6457 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
6459 bfd_set_private_flags (stdoutput
, flags
);
6461 /* We have run out flags in the COFF header to encode the
6462 status of ATPCS support, so instead we create a dummy,
6463 empty, debug section called .arm.atpcs. */
6468 sec
= bfd_make_section (stdoutput
, ".arm.atpcs");
6472 bfd_set_section_flags
6473 (stdoutput
, sec
, SEC_READONLY
| SEC_DEBUGGING
/* | SEC_HAS_CONTENTS */);
6474 bfd_set_section_size (stdoutput
, sec
, 0);
6475 bfd_set_section_contents (stdoutput
, sec
, NULL
, 0, 0);
6481 /* Record the CPU type as well. */
6482 switch (cpu_variant
& ARM_CPU_MASK
)
6485 mach
= bfd_mach_arm_2
;
6488 case ARM_3
: /* Also ARM_250. */
6489 mach
= bfd_mach_arm_2a
;
6493 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined. */
6494 mach
= bfd_mach_arm_4
;
6497 case ARM_7
: /* Also ARM_6. */
6498 mach
= bfd_mach_arm_3
;
6502 /* Catch special cases. */
6503 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
6505 if (cpu_variant
& ARM_EXT_XSCALE
)
6506 mach
= bfd_mach_arm_XScale
;
6507 else if (cpu_variant
& ARM_EXT_V5E
)
6508 mach
= bfd_mach_arm_5TE
;
6509 else if (cpu_variant
& ARM_EXT_V5
)
6511 if (cpu_variant
& ARM_EXT_THUMB
)
6512 mach
= bfd_mach_arm_5T
;
6514 mach
= bfd_mach_arm_5
;
6516 else if (cpu_variant
& ARM_EXT_HALFWORD
)
6518 if (cpu_variant
& ARM_EXT_THUMB
)
6519 mach
= bfd_mach_arm_4T
;
6521 mach
= bfd_mach_arm_4
;
6523 else if (cpu_variant
& ARM_EXT_LONGMUL
)
6524 mach
= bfd_mach_arm_3M
;
6527 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
6530 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
6531 for use in the a.out file, and stores them in the array pointed to by buf.
6532 This knows about the endian-ness of the target machine and does
6533 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
6534 2 (short) and 4 (long) Floating numbers are put out as a series of
6535 LITTLENUMS (shorts, here at least). */
6538 md_number_to_chars (buf
, val
, n
)
6543 if (target_big_endian
)
6544 number_to_chars_bigendian (buf
, val
, n
);
6546 number_to_chars_littleendian (buf
, val
, n
);
6550 md_chars_to_number (buf
, n
)
6555 unsigned char * where
= (unsigned char *) buf
;
6557 if (target_big_endian
)
6562 result
|= (*where
++ & 255);
6570 result
|= (where
[n
] & 255);
6577 /* Turn a string in input_line_pointer into a floating point constant
6578 of type TYPE, and store the appropriate bytes in *LITP. The number
6579 of LITTLENUMS emitted is stored in *SIZEP. An error message is
6580 returned, or NULL on OK.
6582 Note that fp constants aren't represent in the normal way on the ARM.
6583 In big endian mode, things are as expected. However, in little endian
6584 mode fp constants are big-endian word-wise, and little-endian byte-wise
6585 within the words. For example, (double) 1.1 in big endian mode is
6586 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
6587 the byte sequence 99 99 f1 3f 9a 99 99 99.
6589 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
6592 md_atof (type
, litP
, sizeP
)
6598 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
6630 return _("Bad call to MD_ATOF()");
6633 t
= atof_ieee (input_line_pointer
, type
, words
);
6635 input_line_pointer
= t
;
6638 if (target_big_endian
)
6640 for (i
= 0; i
< prec
; i
++)
6642 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
6648 /* For a 4 byte float the order of elements in `words' is 1 0. For an
6649 8 byte float the order is 1 0 3 2. */
6650 for (i
= 0; i
< prec
; i
+= 2)
6652 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
6653 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
6661 /* The knowledge of the PC's pipeline offset is built into the insns
6665 md_pcrel_from (fixP
)
6669 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
6670 && fixP
->fx_subsy
== NULL
)
6673 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
6675 /* PC relative addressing on the Thumb is slightly odd
6676 as the bottom two bits of the PC are forced to zero
6677 for the calculation. */
6678 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
6682 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
6683 so we un-adjust here to compensate for the accomodation. */
6684 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
6686 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
6690 /* Round up a section size to the appropriate boundary. */
6693 md_section_align (segment
, size
)
6694 segT segment ATTRIBUTE_UNUSED
;
6700 /* Round all sects to multiple of 4. */
6701 return (size
+ 3) & ~3;
6705 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
6706 Otherwise we have no need to default values of symbols. */
6709 md_undefined_symbol (name
)
6710 char * name ATTRIBUTE_UNUSED
;
6713 if (name
[0] == '_' && name
[1] == 'G'
6714 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
6718 if (symbol_find (name
))
6719 as_bad ("GOT already in the symbol table");
6721 GOT_symbol
= symbol_new (name
, undefined_section
,
6722 (valueT
) 0, & zero_address_frag
);
6732 /* arm_reg_parse () := if it looks like a register, return its token and
6733 advance the pointer. */
6737 register char ** ccp
;
6739 char * start
= * ccp
;
6742 struct reg_entry
* reg
;
6744 #ifdef REGISTER_PREFIX
6745 if (*start
!= REGISTER_PREFIX
)
6750 #ifdef OPTIONAL_REGISTER_PREFIX
6751 if (*p
== OPTIONAL_REGISTER_PREFIX
)
6755 if (!isalpha (*p
) || !is_name_beginner (*p
))
6759 while (isalpha (c
) || isdigit (c
) || c
== '_')
6763 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
6776 md_apply_fix3 (fixP
, val
, seg
)
6781 offsetT value
= * val
;
6783 unsigned int newimm
;
6786 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
6787 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
6789 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
6791 /* Note whether this will delete the relocation. */
6793 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
6794 doesn't work fully.) */
6795 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
6798 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
6802 /* If this symbol is in a different section then we need to leave it for
6803 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
6804 so we have to undo it's effects here. */
6807 if (fixP
->fx_addsy
!= NULL
6808 && S_IS_DEFINED (fixP
->fx_addsy
)
6809 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
6812 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
6813 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
6817 value
+= md_pcrel_from (fixP
);
6821 /* Remember value for emit_reloc. */
6822 fixP
->fx_addnumber
= value
;
6824 switch (fixP
->fx_r_type
)
6826 case BFD_RELOC_ARM_IMMEDIATE
:
6827 newimm
= validate_immediate (value
);
6828 temp
= md_chars_to_number (buf
, INSN_SIZE
);
6830 /* If the instruction will fail, see if we can fix things up by
6831 changing the opcode. */
6832 if (newimm
== (unsigned int) FAIL
6833 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
6835 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6836 _("invalid constant (%lx) after fixup"),
6837 (unsigned long) value
);
6841 newimm
|= (temp
& 0xfffff000);
6842 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
6845 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
6847 unsigned int highpart
= 0;
6848 unsigned int newinsn
= 0xe1a00000; /* nop. */
6849 newimm
= validate_immediate (value
);
6850 temp
= md_chars_to_number (buf
, INSN_SIZE
);
6852 /* If the instruction will fail, see if we can fix things up by
6853 changing the opcode. */
6854 if (newimm
== (unsigned int) FAIL
6855 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
6857 /* No ? OK - try using two ADD instructions to generate
6859 newimm
= validate_immediate_twopart (value
, & highpart
);
6861 /* Yes - then make sure that the second instruction is
6863 if (newimm
!= (unsigned int) FAIL
)
6865 /* Still No ? Try using a negated value. */
6866 else if ((newimm
= validate_immediate_twopart (- value
, & highpart
)) != (unsigned int) FAIL
)
6867 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
6868 /* Otherwise - give up. */
6871 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6872 _("Unable to compute ADRL instructions for PC offset of 0x%lx"),
6877 /* Replace the first operand in the 2nd instruction (which
6878 is the PC) with the destination register. We have
6879 already added in the PC in the first instruction and we
6880 do not want to do it again. */
6881 newinsn
&= ~ 0xf0000;
6882 newinsn
|= ((newinsn
& 0x0f000) << 4);
6885 newimm
|= (temp
& 0xfffff000);
6886 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
6888 highpart
|= (newinsn
& 0xfffff000);
6889 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
6893 case BFD_RELOC_ARM_OFFSET_IMM
:
6899 if (validate_offset_imm (value
, 0) == FAIL
)
6901 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6902 _("bad immediate value for offset (%ld)"),
6907 newval
= md_chars_to_number (buf
, INSN_SIZE
);
6908 newval
&= 0xff7ff000;
6909 newval
|= value
| (sign
? INDEX_UP
: 0);
6910 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6913 case BFD_RELOC_ARM_OFFSET_IMM8
:
6914 case BFD_RELOC_ARM_HWLITERAL
:
6920 if (validate_offset_imm (value
, 1) == FAIL
)
6922 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
6923 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6924 _("invalid literal constant: pool needs to be closer"));
6926 as_bad (_("bad immediate value for half-word offset (%ld)"),
6931 newval
= md_chars_to_number (buf
, INSN_SIZE
);
6932 newval
&= 0xff7ff0f0;
6933 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
6934 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6937 case BFD_RELOC_ARM_LITERAL
:
6943 if (validate_offset_imm (value
, 0) == FAIL
)
6945 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6946 _("invalid literal constant: pool needs to be closer"));
6950 newval
= md_chars_to_number (buf
, INSN_SIZE
);
6951 newval
&= 0xff7ff000;
6952 newval
|= value
| (sign
? INDEX_UP
: 0);
6953 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6956 case BFD_RELOC_ARM_SHIFT_IMM
:
6957 newval
= md_chars_to_number (buf
, INSN_SIZE
);
6958 if (((unsigned long) value
) > 32
6960 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
6962 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6963 _("shift expression is too large"));
6968 /* Shifts of zero must be done as lsl. */
6970 else if (value
== 32)
6972 newval
&= 0xfffff07f;
6973 newval
|= (value
& 0x1f) << 7;
6974 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6977 case BFD_RELOC_ARM_SWI
:
6978 if (arm_data
->thumb_mode
)
6980 if (((unsigned long) value
) > 0xff)
6981 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6982 _("Invalid swi expression"));
6983 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
6985 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
6989 if (((unsigned long) value
) > 0x00ffffff)
6990 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
6991 _("Invalid swi expression"));
6992 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
6994 md_number_to_chars (buf
, newval
, INSN_SIZE
);
6998 case BFD_RELOC_ARM_MULTI
:
6999 if (((unsigned long) value
) > 0xffff)
7000 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7001 _("Invalid expression in load/store multiple"));
7002 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
7003 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7006 case BFD_RELOC_ARM_PCREL_BRANCH
:
7007 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7009 /* Sign-extend a 24-bit number. */
7010 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
7014 value
= fixP
->fx_offset
;
7017 /* We are going to store value (shifted right by two) in the
7018 instruction, in a 24 bit, signed field. Thus we need to check
7019 that none of the top 8 bits of the shifted value (top 7 bits of
7020 the unshifted, unsigned value) are set, or that they are all set. */
7021 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
7022 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
7025 /* Normally we would be stuck at this point, since we cannot store
7026 the absolute address that is the destination of the branch in the
7027 24 bits of the branch instruction. If however, we happen to know
7028 that the destination of the branch is in the same section as the
7029 branch instruciton itself, then we can compute the relocation for
7030 ourselves and not have to bother the linker with it.
7032 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
7033 because I have not worked out how to do this for OBJ_COFF or
7036 && fixP
->fx_addsy
!= NULL
7037 && S_IS_DEFINED (fixP
->fx_addsy
)
7038 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
7040 /* Get pc relative value to go into the branch. */
7043 /* Permit a backward branch provided that enough bits
7044 are set. Allow a forwards branch, provided that
7045 enough bits are clear. */
7046 if ( (value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
7047 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
7051 if (! fixP
->fx_done
)
7053 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7054 _("gas can't handle same-section branch dest >= 0x04000000"));
7058 value
+= SEXT24 (newval
);
7060 if ( (value
& ~ ((offsetT
) 0xffffff)) != 0
7061 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
7062 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7063 _("out of range branch"));
7065 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
7066 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7069 case BFD_RELOC_ARM_PCREL_BLX
:
7072 newval
= md_chars_to_number (buf
, INSN_SIZE
);
7076 value
= fixP
->fx_offset
;
7078 hbit
= (value
>> 1) & 1;
7079 value
= (value
>> 2) & 0x00ffffff;
7080 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
7081 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
7082 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7086 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* Conditional branch. */
7087 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7089 addressT diff
= (newval
& 0xff) << 1;
7094 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
7095 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7096 _("Branch out of range"));
7097 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
7099 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7102 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* Unconditional branch. */
7103 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7105 addressT diff
= (newval
& 0x7ff) << 1;
7110 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
7111 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7112 _("Branch out of range"));
7113 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
7115 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7118 case BFD_RELOC_THUMB_PCREL_BLX
:
7119 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
7124 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7125 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
7126 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
7127 if (diff
& 0x400000)
7130 value
= fixP
->fx_offset
;
7133 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
7134 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7135 _("Branch with link out of range"));
7137 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
7138 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
7139 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7140 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
7145 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7146 md_number_to_chars (buf
, value
, 1);
7148 else if (!target_oabi
)
7150 value
= fixP
->fx_offset
;
7151 md_number_to_chars (buf
, value
, 1);
7157 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7158 md_number_to_chars (buf
, value
, 2);
7160 else if (!target_oabi
)
7162 value
= fixP
->fx_offset
;
7163 md_number_to_chars (buf
, value
, 2);
7169 case BFD_RELOC_ARM_GOT32
:
7170 case BFD_RELOC_ARM_GOTOFF
:
7171 md_number_to_chars (buf
, 0, 4);
7177 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
7178 md_number_to_chars (buf
, value
, 4);
7180 else if (!target_oabi
)
7182 value
= fixP
->fx_offset
;
7183 md_number_to_chars (buf
, value
, 4);
7189 case BFD_RELOC_ARM_PLT32
:
7190 /* It appears the instruction is fully prepared at this point. */
7194 case BFD_RELOC_ARM_GOTPC
:
7195 md_number_to_chars (buf
, value
, 4);
7198 case BFD_RELOC_ARM_CP_OFF_IMM
:
7200 if (value
< -1023 || value
> 1023 || (value
& 3))
7201 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7202 _("Illegal value for co-processor offset"));
7205 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
7206 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
7207 md_number_to_chars (buf
, newval
, INSN_SIZE
);
7210 case BFD_RELOC_ARM_THUMB_OFFSET
:
7211 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7212 /* Exactly what ranges, and where the offset is inserted depends
7213 on the type of instruction, we can establish this from the
7215 switch (newval
>> 12)
7217 case 4: /* PC load. */
7218 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
7219 forced to zero for these loads, so we will need to round
7220 up the offset if the instruction address is not word
7221 aligned (since the final address produced must be, and
7222 we can only describe word-aligned immediate offsets). */
7224 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
7225 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7226 _("Invalid offset, target not word aligned (0x%08X)"),
7227 (unsigned int) (fixP
->fx_frag
->fr_address
7228 + fixP
->fx_where
+ value
));
7230 if ((value
+ 2) & ~0x3fe)
7231 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7232 _("Invalid offset, value too big (0x%08lX)"), value
);
7234 /* Round up, since pc will be rounded down. */
7235 newval
|= (value
+ 2) >> 2;
7238 case 9: /* SP load/store. */
7240 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7241 _("Invalid offset, value too big (0x%08lX)"), value
);
7242 newval
|= value
>> 2;
7245 case 6: /* Word load/store. */
7247 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7248 _("Invalid offset, value too big (0x%08lX)"), value
);
7249 newval
|= value
<< 4; /* 6 - 2. */
7252 case 7: /* Byte load/store. */
7254 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7255 _("Invalid offset, value too big (0x%08lX)"), value
);
7256 newval
|= value
<< 6;
7259 case 8: /* Halfword load/store. */
7261 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7262 _("Invalid offset, value too big (0x%08lX)"), value
);
7263 newval
|= value
<< 5; /* 6 - 1. */
7267 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7268 "Unable to process relocation for thumb opcode: %lx",
7269 (unsigned long) newval
);
7272 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7275 case BFD_RELOC_ARM_THUMB_ADD
:
7276 /* This is a complicated relocation, since we use it for all of
7277 the following immediate relocations:
7281 9bit ADD/SUB SP word-aligned
7282 10bit ADD PC/SP word-aligned
7284 The type of instruction being processed is encoded in the
7291 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7293 int rd
= (newval
>> 4) & 0xf;
7294 int rs
= newval
& 0xf;
7295 int subtract
= newval
& 0x8000;
7300 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7301 _("Invalid immediate for stack address calculation"));
7302 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
7303 newval
|= value
>> 2;
7305 else if (rs
== REG_PC
|| rs
== REG_SP
)
7309 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7310 _("Invalid immediate for address calculation (value = 0x%08lX)"),
7311 (unsigned long) value
);
7312 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
7314 newval
|= value
>> 2;
7319 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7320 _("Invalid 8bit immediate"));
7321 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
7322 newval
|= (rd
<< 8) | value
;
7327 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7328 _("Invalid 3bit immediate"));
7329 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
7330 newval
|= rd
| (rs
<< 3) | (value
<< 6);
7333 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7336 case BFD_RELOC_ARM_THUMB_IMM
:
7337 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
7338 switch (newval
>> 11)
7340 case 0x04: /* 8bit immediate MOV. */
7341 case 0x05: /* 8bit immediate CMP. */
7342 if (value
< 0 || value
> 255)
7343 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7344 _("Invalid immediate: %ld is too large"),
7352 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7355 case BFD_RELOC_ARM_THUMB_SHIFT
:
7356 /* 5bit shift value (0..31). */
7357 if (value
< 0 || value
> 31)
7358 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7359 _("Illegal Thumb shift value: %ld"), (long) value
);
7360 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
7361 newval
|= value
<< 6;
7362 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
7365 case BFD_RELOC_VTABLE_INHERIT
:
7366 case BFD_RELOC_VTABLE_ENTRY
:
7370 case BFD_RELOC_NONE
:
7372 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
7373 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
7379 /* Translate internal representation of relocation info to BFD target
7383 tc_gen_reloc (section
, fixp
)
7384 asection
* section ATTRIBUTE_UNUSED
;
7388 bfd_reloc_code_real_type code
;
7390 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
7392 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
7393 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
7394 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
7396 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
7398 if (fixp
->fx_pcrel
== 0)
7399 reloc
->addend
= fixp
->fx_offset
;
7401 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
7403 reloc
->addend
= fixp
->fx_offset
;
7406 switch (fixp
->fx_r_type
)
7411 code
= BFD_RELOC_8_PCREL
;
7418 code
= BFD_RELOC_16_PCREL
;
7425 code
= BFD_RELOC_32_PCREL
;
7429 case BFD_RELOC_ARM_PCREL_BRANCH
:
7430 case BFD_RELOC_ARM_PCREL_BLX
:
7432 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
7433 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
7434 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
7435 case BFD_RELOC_THUMB_PCREL_BLX
:
7436 case BFD_RELOC_VTABLE_ENTRY
:
7437 case BFD_RELOC_VTABLE_INHERIT
:
7438 code
= fixp
->fx_r_type
;
7441 case BFD_RELOC_ARM_LITERAL
:
7442 case BFD_RELOC_ARM_HWLITERAL
:
7443 /* If this is called then the a literal has been referenced across
7444 a section boundary - possibly due to an implicit dump. */
7445 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7446 _("Literal referenced across section boundary (Implicit dump?)"));
7450 case BFD_RELOC_ARM_GOT32
:
7451 case BFD_RELOC_ARM_GOTOFF
:
7452 case BFD_RELOC_ARM_PLT32
:
7453 code
= fixp
->fx_r_type
;
7457 case BFD_RELOC_ARM_IMMEDIATE
:
7458 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7459 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
7463 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
7464 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7465 _("ADRL used for a symbol not defined in the same file"));
7468 case BFD_RELOC_ARM_OFFSET_IMM
:
7469 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7470 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
7478 switch (fixp
->fx_r_type
)
7480 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
7481 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
7482 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
7483 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
7484 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
7485 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
7486 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
7487 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
7488 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
7489 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
7490 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
7491 default: type
= _("<unknown>"); break;
7493 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7494 _("Cannot represent %s relocation in this object file format"),
7501 if (code
== BFD_RELOC_32_PCREL
7503 && fixp
->fx_addsy
== GOT_symbol
)
7505 code
= BFD_RELOC_ARM_GOTPC
;
7506 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
7510 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
7512 if (reloc
->howto
== NULL
)
7514 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
7515 _("Can not represent %s relocation in this object file format"),
7516 bfd_get_reloc_code_name (code
));
7520 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
7521 vtable entry to be used in the relocation's section offset. */
7522 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7523 reloc
->address
= fixp
->fx_offset
;
7529 md_estimate_size_before_relax (fragP
, segtype
)
7530 fragS
* fragP ATTRIBUTE_UNUSED
;
7531 segT segtype ATTRIBUTE_UNUSED
;
7533 as_fatal (_("md_estimate_size_before_relax\n"));
7538 output_inst
PARAMS ((void))
7544 as_bad (inst
.error
);
7548 to
= frag_more (inst
.size
);
7550 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
7552 assert (inst
.size
== (2 * THUMB_SIZE
));
7553 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
7554 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
7556 else if (inst
.size
> INSN_SIZE
)
7558 assert (inst
.size
== (2 * INSN_SIZE
));
7559 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
7560 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
7563 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
7565 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
7566 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
7567 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
7571 dwarf2_emit_insn (inst
.size
);
7584 /* Align the instruction.
7585 This may not be the right thing to do but ... */
7589 listing_prev_line (); /* Defined in listing.h. */
7591 /* Align the previous label if needed. */
7592 if (last_label_seen
!= NULL
)
7594 symbol_set_frag (last_label_seen
, frag_now
);
7595 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
7596 S_SET_SEGMENT (last_label_seen
, now_seg
);
7599 memset (&inst
, '\0', sizeof (inst
));
7600 inst
.reloc
.type
= BFD_RELOC_NONE
;
7602 skip_whitespace (str
);
7604 /* Scan up to the end of the op-code, which must end in white space or
7606 for (start
= p
= str
; *p
!= '\0'; p
++)
7612 as_bad (_("No operator -- statement `%s'\n"), str
);
7618 CONST
struct thumb_opcode
* opcode
;
7622 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
7627 /* Check that this instruction is supported for this CPU. */
7628 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
7630 as_bad (_("selected processor does not support this opcode"));
7634 inst
.instruction
= opcode
->value
;
7635 inst
.size
= opcode
->size
;
7636 (*opcode
->parms
) (p
);
7643 CONST
struct asm_opcode
* opcode
;
7644 unsigned long cond_code
;
7646 inst
.size
= INSN_SIZE
;
7647 /* P now points to the end of the opcode, probably white space, but we
7648 have to break the opcode up in case it contains condionals and flags;
7649 keep trying with progressively smaller basic instructions until one
7650 matches, or we run out of opcode. */
7651 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
7653 for (; q
!= str
; q
--)
7658 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
7661 if (opcode
&& opcode
->template)
7663 unsigned long flag_bits
= 0;
7666 /* Check that this instruction is supported for this CPU. */
7667 if ((opcode
->variants
& cpu_variant
) == 0)
7670 inst
.instruction
= opcode
->value
;
7671 if (q
== p
) /* Just a simple opcode. */
7673 if (opcode
->comp_suffix
)
7675 if (*opcode
->comp_suffix
!= '\0')
7676 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
7677 str
, opcode
->comp_suffix
);
7679 /* Not a conditional instruction. */
7680 (*opcode
->parms
) (q
, 0);
7684 /* A conditional instruction with default condition. */
7685 inst
.instruction
|= COND_ALWAYS
;
7686 (*opcode
->parms
) (q
, 0);
7692 /* Not just a simple opcode. Check if extra is a
7697 CONST
struct asm_cond
*cond
;
7701 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
7705 if (cond
->value
== 0xf0000000)
7707 _("Warning: Use of the 'nv' conditional is deprecated\n"));
7709 cond_code
= cond
->value
;
7713 cond_code
= COND_ALWAYS
;
7716 cond_code
= COND_ALWAYS
;
7718 /* Apply the conditional, or complain it's not allowed. */
7719 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
7721 /* Instruction isn't conditional. */
7722 if (cond_code
!= COND_ALWAYS
)
7724 as_bad (_("Opcode `%s' is unconditional\n"), str
);
7729 /* Instruction is conditional: set the condition into it. */
7730 inst
.instruction
|= cond_code
;
7732 /* If there is a compulsory suffix, it should come here
7733 before any optional flags. */
7734 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
7736 CONST
char *s
= opcode
->comp_suffix
;
7748 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
7749 str
, opcode
->comp_suffix
);
7756 /* The remainder, if any should now be flags for the instruction;
7757 Scan these checking each one found with the opcode. */
7761 CONST
struct asm_flg
*flag
= opcode
->flags
;
7770 for (flagno
= 0; flag
[flagno
].template; flagno
++)
7772 if (streq (r
, flag
[flagno
].template))
7774 flag_bits
|= flag
[flagno
].set_bits
;
7780 if (! flag
[flagno
].template)
7787 (*opcode
->parms
) (p
, flag_bits
);
7797 /* It wasn't an instruction, but it might be a register alias of the form
7800 skip_whitespace (q
);
7805 if (*q
&& !strncmp (q
, ".req ", 4))
7811 #ifdef IGNORE_OPCODE_CASE
7812 str
= original_case_string
;
7817 skip_whitespace (q
);
7819 for (r
= q
; *r
!= '\0'; r
++)
7829 regnum
= arm_reg_parse (& q
);
7832 reg
= arm_reg_parse (& str
);
7837 insert_reg_alias (str
, regnum
);
7839 as_warn (_("register '%s' does not exist\n"), q
);
7841 else if (regnum
!= FAIL
)
7844 as_warn (_("ignoring redefinition of register alias '%s'"),
7847 /* Do not warn about redefinitions to the same alias. */
7850 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
7854 as_warn (_("ignoring incomplete .req pseuso op"));
7861 as_bad (_("bad instruction `%s'"), start
);
7865 Invocation line includes a switch not recognized by the base assembler.
7866 See if it's a processor-specific option. These are:
7867 Cpu variants, the arm part is optional:
7868 -m[arm]1 Currently not supported.
7869 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
7870 -m[arm]3 Arm 3 processor
7871 -m[arm]6[xx], Arm 6 processors
7872 -m[arm]7[xx][t][[d]m] Arm 7 processors
7873 -m[arm]8[10] Arm 8 processors
7874 -m[arm]9[20][tdmi] Arm 9 processors
7875 -mstrongarm[110[0]] StrongARM processors
7876 -mxscale XScale processors
7877 -m[arm]v[2345[t[e]]] Arm architectures
7878 -mall All (except the ARM1)
7880 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
7881 -mfpe-old (No float load/store multiples)
7882 -mno-fpu Disable all floating point instructions
7883 Run-time endian selection:
7885 -EL little endian cpu
7886 ARM Procedure Calling Standard:
7887 -mapcs-32 32 bit APCS
7888 -mapcs-26 26 bit APCS
7889 -mapcs-float Pass floats in float regs
7890 -mapcs-reentrant Position independent code
7891 -mthumb-interwork Code supports Arm/Thumb interworking
7892 -matpcs ARM/Thumb Procedure Call Standard
7893 -moabi Old ELF ABI */
7895 CONST
char * md_shortopts
= "m:k";
7897 struct option md_longopts
[] =
7899 #ifdef ARM_BI_ENDIAN
7900 #define OPTION_EB (OPTION_MD_BASE + 0)
7901 {"EB", no_argument
, NULL
, OPTION_EB
},
7902 #define OPTION_EL (OPTION_MD_BASE + 1)
7903 {"EL", no_argument
, NULL
, OPTION_EL
},
7905 #define OPTION_OABI (OPTION_MD_BASE +2)
7906 {"oabi", no_argument
, NULL
, OPTION_OABI
},
7909 {NULL
, no_argument
, NULL
, 0}
7912 size_t md_longopts_size
= sizeof (md_longopts
);
7915 md_parse_option (c
, arg
)
7923 #ifdef ARM_BI_ENDIAN
7925 target_big_endian
= 1;
7928 target_big_endian
= 0;
7936 if (streq (str
, "fpa10"))
7937 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
7938 else if (streq (str
, "fpa11"))
7939 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
7940 else if (streq (str
, "fpe-old"))
7941 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
7947 if (streq (str
, "no-fpu"))
7948 cpu_variant
&= ~FPU_ALL
;
7953 if (streq (str
, "oabi"))
7959 /* Limit assembler to generating only Thumb instructions: */
7960 if (streq (str
, "thumb"))
7962 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_EXT_THUMB
;
7963 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
7966 else if (streq (str
, "thumb-interwork"))
7968 if ((cpu_variant
& ARM_EXT_THUMB
) == 0)
7969 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
7970 #if defined OBJ_COFF || defined OBJ_ELF
7971 support_interwork
= true;
7979 if (streq (str
, "all"))
7981 cpu_variant
= ARM_ALL
| FPU_ALL
;
7984 #if defined OBJ_COFF || defined OBJ_ELF
7985 if (! strncmp (str
, "apcs-", 5))
7987 /* GCC passes on all command line options starting "-mapcs-..."
7988 to us, so we must parse them here. */
7992 if (streq (str
, "32"))
7994 uses_apcs_26
= false;
7997 else if (streq (str
, "26"))
7999 uses_apcs_26
= true;
8002 else if (streq (str
, "frame"))
8004 /* Stack frames are being generated - does not affect
8008 else if (streq (str
, "stack-check"))
8010 /* Stack checking is being performed - does not affect
8011 linkage, but does require that the functions
8012 __rt_stkovf_split_small and __rt_stkovf_split_big be
8013 present in the final link. */
8017 else if (streq (str
, "float"))
8019 /* Floating point arguments are being passed in the floating
8020 point registers. This does affect linking, since this
8021 version of the APCS is incompatible with the version that
8022 passes floating points in the integer registers. */
8024 uses_apcs_float
= true;
8027 else if (streq (str
, "reentrant"))
8029 /* Reentrant code has been generated. This does affect
8030 linking, since there is no point in linking reentrant/
8031 position independent code with absolute position code. */
8036 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
8040 if (! strcmp (str
, "atpcs"))
8046 /* Strip off optional "arm". */
8047 if (! strncmp (str
, "arm", 3))
8053 if (streq (str
, "1"))
8054 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
8060 if (streq (str
, "2"))
8061 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
8062 else if (streq (str
, "250"))
8063 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
8069 if (streq (str
, "3"))
8070 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
8076 switch (strtol (str
, NULL
, 10))
8083 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
8091 /* Eat the processor name. */
8092 switch (strtol (str
, & str
, 10))
8105 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
8111 cpu_variant
|= ARM_ARCH_V4T
;
8115 cpu_variant
|= ARM_EXT_LONGMUL
;
8118 case 'f': /* fe => fp enabled cpu. */
8124 case 'c': /* Left over from 710c processor name. */
8125 case 'd': /* Debug. */
8126 case 'i': /* Embedded ICE. */
8127 /* Included for completeness in ARM processor naming. */
8137 if (streq (str
, "8") || streq (str
, "810"))
8138 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8139 | ARM_8
| ARM_ARCH_V4
;
8145 if (streq (str
, "9"))
8146 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8147 | ARM_9
| ARM_ARCH_V4T
;
8148 else if (streq (str
, "920"))
8149 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8150 | ARM_9
| ARM_ARCH_V4
;
8151 else if (streq (str
, "920t"))
8152 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8153 | ARM_9
| ARM_ARCH_V4T
;
8154 else if (streq (str
, "9tdmi"))
8155 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8156 | ARM_9
| ARM_ARCH_V4T
;
8162 if (streq (str
, "strongarm")
8163 || streq (str
, "strongarm110")
8164 || streq (str
, "strongarm1100"))
8165 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
8166 | ARM_8
| ARM_ARCH_V4
;
8172 if (streq (str
, "xscale"))
8173 cpu_variant
= ARM_9
| ARM_ARCH_XSCALE
;
8179 /* Select variant based on architecture rather than
8187 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
8190 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
8193 as_bad (_("Invalid architecture variant -m%s"), arg
);
8199 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
8203 case 'm': cpu_variant
|= ARM_EXT_LONGMUL
; break;
8206 as_bad (_("Invalid architecture variant -m%s"), arg
);
8212 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCH_V4
;
8216 case 't': cpu_variant
|= ARM_EXT_THUMB
; break;
8219 as_bad (_("Invalid architecture variant -m%s"), arg
);
8225 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCH_V5
;
8228 case 't': cpu_variant
|= ARM_EXT_THUMB
; break;
8229 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
8232 as_bad (_("Invalid architecture variant -m%s"), arg
);
8238 as_bad (_("Invalid architecture variant -m%s"), arg
);
8245 as_bad (_("Invalid processor variant -m%s"), arg
);
8251 #if defined OBJ_ELF || defined OBJ_COFF
8269 ARM Specific Assembler Options:\n\
8270 -m[arm][<processor name>] select processor variant\n\
8271 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
8272 -mthumb only allow Thumb instructions\n\
8273 -mthumb-interwork mark the assembled code as supporting interworking\n\
8274 -mall allow any instruction\n\
8275 -mfpa10, -mfpa11 select floating point architecture\n\
8276 -mfpe-old don't allow floating-point multiple instructions\n\
8277 -mno-fpu don't allow any floating-point instructions.\n\
8278 -k generate PIC code.\n"));
8279 #if defined OBJ_COFF || defined OBJ_ELF
8281 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
8282 -matpcs use ARM/Thumb Procedure Calling Standard\n\
8283 -mapcs-float floating point args are passed in FP regs\n\
8284 -mapcs-reentrant the code is position independent/reentrant\n"));
8288 -moabi support the old ELF ABI\n"));
8290 #ifdef ARM_BI_ENDIAN
8292 -EB assemble code for a big endian cpu\n\
8293 -EL assemble code for a little endian cpu\n"));
8297 /* We need to be able to fix up arbitrary expressions in some statements.
8298 This is so that we can handle symbols that are an arbitrary distance from
8299 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
8300 which returns part of an address in a form which will be valid for
8301 a data instruction. We do this by pushing the expression into a symbol
8302 in the expr_section, and creating a fix for that. */
8305 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
8314 arm_fix_data
* arm_data
;
8322 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
8326 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
8331 /* Mark whether the fix is to a THUMB instruction, or an ARM
8333 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
8334 new_fix
->tc_fix_data
= (PTR
) arm_data
;
8335 arm_data
->thumb_mode
= thumb_mode
;
8340 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
8343 cons_fix_new_arm (frag
, where
, size
, exp
)
8349 bfd_reloc_code_real_type type
;
8353 FIXME: @@ Should look at CPU word size. */
8360 type
= BFD_RELOC_16
;
8364 type
= BFD_RELOC_32
;
8367 type
= BFD_RELOC_64
;
8371 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
8374 /* A good place to do this, although this was probably not intended
8375 for this kind of use. We need to dump the literal pool before
8376 references are made to a null symbol pointer. */
8381 if (current_poolP
== NULL
)
8384 /* Put it at the end of text section. */
8385 subseg_set (text_section
, 0);
8387 listing_prev_line ();
8391 arm_start_line_hook ()
8393 last_label_seen
= NULL
;
8397 arm_frob_label (sym
)
8400 last_label_seen
= sym
;
8402 ARM_SET_THUMB (sym
, thumb_mode
);
8404 #if defined OBJ_COFF || defined OBJ_ELF
8405 ARM_SET_INTERWORK (sym
, support_interwork
);
8408 if (label_is_thumb_function_name
)
8410 /* When the address of a Thumb function is taken the bottom
8411 bit of that address should be set. This will allow
8412 interworking between Arm and Thumb functions to work
8415 THUMB_SET_FUNC (sym
, 1);
8417 label_is_thumb_function_name
= false;
8421 /* Adjust the symbol table. This marks Thumb symbols as distinct from
8425 arm_adjust_symtab ()
8430 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
8432 if (ARM_IS_THUMB (sym
))
8434 if (THUMB_IS_FUNC (sym
))
8436 /* Mark the symbol as a Thumb function. */
8437 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
8438 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
8439 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
8441 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
8442 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
8444 as_bad (_("%s: unexpected function type: %d"),
8445 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
8447 else switch (S_GET_STORAGE_CLASS (sym
))
8450 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
8453 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
8456 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
8464 if (ARM_IS_INTERWORK (sym
))
8465 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
8472 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
8474 if (ARM_IS_THUMB (sym
))
8476 elf_symbol_type
* elf_sym
;
8478 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
8479 bind
= ELF_ST_BIND (elf_sym
);
8481 /* If it's a .thumb_func, declare it as so,
8482 otherwise tag label as .code 16. */
8483 if (THUMB_IS_FUNC (sym
))
8484 elf_sym
->internal_elf_sym
.st_info
=
8485 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
8487 elf_sym
->internal_elf_sym
.st_info
=
8488 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
8497 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
8499 *input_line_pointer
= '/';
8500 input_line_pointer
+= 5;
8501 *input_line_pointer
= 0;
8509 arm_canonicalize_symbol_name (name
)
8514 if (thumb_mode
&& (len
= strlen (name
)) > 5
8515 && streq (name
+ len
- 5, "/data"))
8516 *(name
+ len
- 5) = 0;
8522 arm_validate_fix (fixP
)
8525 /* If the destination of the branch is a defined symbol which does not have
8526 the THUMB_FUNC attribute, then we must be calling a function which has
8527 the (interfacearm) attribute. We look for the Thumb entry point to that
8528 function and change the branch to refer to that function instead. */
8529 if (fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
8530 && fixP
->fx_addsy
!= NULL
8531 && S_IS_DEFINED (fixP
->fx_addsy
)
8532 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
8534 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
8542 /* Relocations against Thumb function names must be left unadjusted,
8543 so that the linker can use this information to correctly set the
8544 bottom bit of their addresses. The MIPS version of this function
8545 also prevents relocations that are mips-16 specific, but I do not
8546 know why it does this.
8549 There is one other problem that ought to be addressed here, but
8550 which currently is not: Taking the address of a label (rather
8551 than a function) and then later jumping to that address. Such
8552 addresses also ought to have their bottom bit set (assuming that
8553 they reside in Thumb code), but at the moment they will not. */
8556 arm_fix_adjustable (fixP
)
8559 if (fixP
->fx_addsy
== NULL
)
8562 /* Prevent all adjustments to global symbols. */
8563 if (S_IS_EXTERN (fixP
->fx_addsy
))
8566 if (S_IS_WEAK (fixP
->fx_addsy
))
8569 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
8570 && fixP
->fx_subsy
== NULL
)
8573 /* We need the symbol name for the VTABLE entries. */
8574 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
8575 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
8582 elf32_arm_target_format ()
8584 if (target_big_endian
)
8587 return "elf32-bigarm-oabi";
8589 return "elf32-bigarm";
8594 return "elf32-littlearm-oabi";
8596 return "elf32-littlearm";
8601 armelf_frob_symbol (symp
, puntp
)
8605 elf_frob_symbol (symp
, puntp
);
8609 arm_force_relocation (fixp
)
8612 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
8613 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
8614 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
8615 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
8616 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
8617 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
8623 static bfd_reloc_code_real_type
8633 bfd_reloc_code_real_type reloc
;
8637 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
8638 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
8639 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
8640 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
8641 branch instructions generated by GCC for PLT relocs. */
8642 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
8643 { NULL
, 0, BFD_RELOC_UNUSED
}
8647 for (i
= 0, ip
= input_line_pointer
;
8648 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
8650 id
[i
] = tolower (*ip
);
8652 for (i
= 0; reloc_map
[i
].str
; i
++)
8653 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
8656 input_line_pointer
+= reloc_map
[i
].len
;
8658 return reloc_map
[i
].reloc
;
8662 s_arm_elf_cons (nbytes
)
8667 #ifdef md_flush_pending_output
8668 md_flush_pending_output ();
8671 if (is_it_end_of_statement ())
8673 demand_empty_rest_of_line ();
8677 #ifdef md_cons_align
8678 md_cons_align (nbytes
);
8683 bfd_reloc_code_real_type reloc
;
8687 if (exp
.X_op
== O_symbol
8688 && * input_line_pointer
== '('
8689 && (reloc
= arm_parse_reloc ()) != BFD_RELOC_UNUSED
)
8691 reloc_howto_type
*howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
8692 int size
= bfd_get_reloc_size (howto
);
8695 as_bad ("%s relocations do not fit in %d bytes",
8696 howto
->name
, nbytes
);
8699 register char *p
= frag_more ((int) nbytes
);
8700 int offset
= nbytes
- size
;
8702 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
8707 emit_expr (&exp
, (unsigned int) nbytes
);
8709 while (*input_line_pointer
++ == ',');
8711 /* Put terminator back into stream. */
8712 input_line_pointer
--;
8713 demand_empty_rest_of_line ();
8716 #endif /* OBJ_ELF */