1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000 Free Software Foundation, Inc.
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
39 /* Types of processor to assemble for. */
40 #define ARM_1 0x00000001
41 #define ARM_2 0x00000002
42 #define ARM_3 0x00000004
44 #define ARM_6 0x00000008
45 #define ARM_7 ARM_6 /* same core instruction set */
46 #define ARM_8 ARM_6 /* same core instruction set */
47 #define ARM_9 ARM_6 /* same core instruction set */
48 #define ARM_CPU_MASK 0x0000000f
50 /* The following bitmasks control CPU extensions (ARM7 onwards): */
51 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
52 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
53 #define ARM_THUMB 0x00000040 /* allow BX instruction */
54 #define ARM_EXT_V5 0x00000080 /* allow CLZ etc */
56 /* Architectures are the sum of the base and extensions. */
57 #define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
58 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
59 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
60 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
62 /* Some useful combinations: */
63 #define ARM_ANY 0x00ffffff
64 #define ARM_2UP (ARM_ANY - ARM_1)
65 #define ARM_ALL ARM_2UP /* Not arm1 only */
66 #define ARM_3UP 0x00fffffc
67 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
69 #define FPU_CORE 0x80000000
70 #define FPU_FPA10 0x40000000
71 #define FPU_FPA11 0x40000000
74 /* Some useful combinations */
75 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
76 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
81 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
83 #define CPU_DEFAULT ARM_ALL
88 #define FPU_DEFAULT FPU_ALL
91 #define streq(a, b) (strcmp (a, b) == 0)
92 #define skip_whitespace(str) while (* (str) == ' ') ++ (str)
94 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
95 static int target_oabi
= 0;
97 #if defined OBJ_COFF || defined OBJ_ELF
98 /* Flags stored in private area of BFD structure */
99 static boolean uses_apcs_26
= false;
100 static boolean support_interwork
= false;
101 static boolean uses_apcs_float
= false;
102 static boolean pic_code
= false;
105 /* This array holds the chars that always start a comment. If the
106 pre-processor is disabled, these aren't very useful. */
107 CONST
char comment_chars
[] = "@";
109 /* This array holds the chars that only start a comment at the beginning of
110 a line. If the line seems to have the form '# 123 filename'
111 .line and .file directives will appear in the pre-processed output. */
112 /* Note that input_file.c hand checks for '#' at the beginning of the
113 first line of the input file. This is because the compiler outputs
114 #NO_APP at the beginning of its output. */
115 /* Also note that comments like this one will always work. */
116 CONST
char line_comment_chars
[] = "#";
118 CONST
char line_separator_chars
[] = ";";
120 /* Chars that can be used to separate mant
121 from exp in floating point numbers. */
122 CONST
char EXP_CHARS
[] = "eE";
124 /* Chars that mean this number is a floating point constant */
128 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
130 /* Prefix characters that indicate the start of an immediate
132 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
135 symbolS
* GOT_symbol
; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
138 CONST
int md_reloc_size
= 8; /* Size of relocation record */
140 static int thumb_mode
= 0; /* 0: assemble for ARM, 1: assemble for Thumb,
141 2: assemble for Thumb even though target cpu
142 does not support thumb instructions. */
143 typedef struct arm_fix
151 unsigned long instruction
;
156 bfd_reloc_code_real_type type
;
166 CONST
char * template;
170 static CONST
struct asm_shift shift
[] =
186 #define NO_SHIFT_RESTRICT 1
187 #define SHIFT_RESTRICT 0
189 #define NUM_FLOAT_VALS 8
191 CONST
char * fp_const
[] =
193 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
196 /* Number of littlenums required to hold an extended precision number. */
197 #define MAX_LITTLENUMS 6
199 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
209 #define CP_T_X 0x00008000
210 #define CP_T_Y 0x00400000
211 #define CP_T_Pre 0x01000000
212 #define CP_T_UD 0x00800000
213 #define CP_T_WB 0x00200000
215 #define CONDS_BIT (0x00100000)
216 #define LOAD_BIT (0x00100000)
217 #define TRANS_BIT (0x00200000)
221 CONST
char * template;
225 /* This is to save a hash look-up in the common case. */
226 #define COND_ALWAYS 0xe0000000
228 static CONST
struct asm_cond conds
[] =
232 {"cs", 0x20000000}, {"hs", 0x20000000},
233 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
248 /* Warning: If the top bit of the set_bits is set, then the standard
249 instruction bitmask is ignored, and the new bitmask is taken from
253 CONST
char * template; /* Basic flag string */
254 unsigned long set_bits
; /* Bits to set */
257 static CONST
struct asm_flg s_flag
[] =
263 static CONST
struct asm_flg ldr_flags
[] =
267 {"bt", 0x00400000 | TRANS_BIT
},
274 static CONST
struct asm_flg str_flags
[] =
278 {"bt", 0x00400000 | TRANS_BIT
},
283 static CONST
struct asm_flg byte_flag
[] =
289 static CONST
struct asm_flg cmp_flags
[] =
296 static CONST
struct asm_flg ldm_flags
[] =
309 static CONST
struct asm_flg stm_flags
[] =
322 static CONST
struct asm_flg lfm_flags
[] =
329 static CONST
struct asm_flg sfm_flags
[] =
336 static CONST
struct asm_flg round_flags
[] =
344 /* The implementation of the FIX instruction is broken on some assemblers,
345 in that it accepts a precision specifier as well as a rounding specifier,
346 despite the fact that this is meaningless. To be more compatible, we
347 accept it as well, though of course it does not set any bits. */
348 static CONST
struct asm_flg fix_flags
[] =
365 static CONST
struct asm_flg except_flag
[] =
371 static CONST
struct asm_flg cplong_flag
[] =
379 CONST
char * template;
384 #define SPSR_BIT (1 << 22) /* The bit that distnguishes CPSR and SPSR. */
385 #define PSR_SHIFT 16 /* How many bits to shift the PSR_xxx bits up by. */
387 #define PSR_c (1 << 0)
388 #define PSR_x (1 << 1)
389 #define PSR_s (1 << 2)
390 #define PSR_f (1 << 3)
392 static CONST
struct asm_psr psrs
[] =
394 {"CPSR", true, PSR_c
| PSR_f
},
395 {"CPSR_all", true, PSR_c
| PSR_f
},
396 {"SPSR", false, PSR_c
| PSR_f
},
397 {"SPSR_all", false, PSR_c
| PSR_f
},
398 {"CPSR_flg", true, PSR_f
},
399 {"CPSR_f", true, PSR_f
},
400 {"SPSR_flg", false, PSR_f
},
401 {"SPSR_f", false, PSR_f
},
402 {"CPSR_c", true, PSR_c
},
403 {"CPSR_ctl", true, PSR_c
},
404 {"SPSR_c", false, PSR_c
},
405 {"SPSR_ctl", false, PSR_c
},
406 {"CPSR_x", true, PSR_x
},
407 {"CPSR_s", true, PSR_s
},
408 {"SPSR_x", false, PSR_x
},
409 {"SPSR_s", false, PSR_s
},
410 /* For backwards compatability with older toolchain we also
411 support lower case versions of some of these flags. */
412 {"cpsr", true, PSR_c
| PSR_f
},
413 {"cpsr_all", true, PSR_c
| PSR_f
},
414 {"spsr", false, PSR_c
| PSR_f
},
415 {"spsr_all", false, PSR_c
| PSR_f
},
416 {"cpsr_flg", true, PSR_f
},
417 {"cpsr_f", true, PSR_f
},
418 {"spsr_flg", false, PSR_f
},
419 {"spsr_f", false, PSR_f
},
420 {"cpsr_c", true, PSR_c
},
421 {"cpsr_ctl", true, PSR_c
},
422 {"spsr_c", false, PSR_c
},
423 {"spsr_ctl", false, PSR_c
}
426 /* Functions called by parser. */
427 /* ARM instructions */
428 static void do_arit
PARAMS ((char *, unsigned long));
429 static void do_cmp
PARAMS ((char *, unsigned long));
430 static void do_mov
PARAMS ((char *, unsigned long));
431 static void do_ldst
PARAMS ((char *, unsigned long));
432 static void do_ldmstm
PARAMS ((char *, unsigned long));
433 static void do_branch
PARAMS ((char *, unsigned long));
434 static void do_swi
PARAMS ((char *, unsigned long));
435 /* Pseudo Op codes */
436 static void do_adr
PARAMS ((char *, unsigned long));
437 static void do_adrl
PARAMS ((char *, unsigned long));
438 static void do_nop
PARAMS ((char *, unsigned long));
440 static void do_mul
PARAMS ((char *, unsigned long));
441 static void do_mla
PARAMS ((char *, unsigned long));
443 static void do_swap
PARAMS ((char *, unsigned long));
445 static void do_msr
PARAMS ((char *, unsigned long));
446 static void do_mrs
PARAMS ((char *, unsigned long));
448 static void do_mull
PARAMS ((char *, unsigned long));
450 static void do_bx
PARAMS ((char *, unsigned long));
453 /* Coprocessor Instructions */
454 static void do_cdp
PARAMS ((char *, unsigned long));
455 static void do_lstc
PARAMS ((char *, unsigned long));
456 static void do_co_reg
PARAMS ((char *, unsigned long));
457 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
458 static void do_fp_ldst
PARAMS ((char *, unsigned long));
459 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
460 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
461 static void do_fp_monadic
PARAMS ((char *, unsigned long));
462 static void do_fp_cmp
PARAMS ((char *, unsigned long));
463 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
464 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
466 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
467 static int arm_reg_parse
PARAMS ((char **));
468 static CONST
struct asm_psr
* arm_psr_parse
PARAMS ((char **));
469 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
470 static int add_to_lit_pool
PARAMS ((void));
471 static unsigned validate_immediate
PARAMS ((unsigned));
472 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
473 static int validate_offset_imm
PARAMS ((unsigned int, int));
474 static void opcode_select
PARAMS ((int));
475 static void end_of_line
PARAMS ((char *));
476 static int reg_required_here
PARAMS ((char **, int));
477 static int psr_required_here
PARAMS ((char **));
478 static int co_proc_number
PARAMS ((char **));
479 static int cp_opc_expr
PARAMS ((char **, int, int));
480 static int cp_reg_required_here
PARAMS ((char **, int));
481 static int fp_reg_required_here
PARAMS ((char **, int));
482 static int cp_address_offset
PARAMS ((char **));
483 static int cp_address_required_here
PARAMS ((char **));
484 static int my_get_float_expression
PARAMS ((char **));
485 static int skip_past_comma
PARAMS ((char **));
486 static int walk_no_bignums
PARAMS ((symbolS
*));
487 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
488 static int data_op2
PARAMS ((char **));
489 static int fp_op2
PARAMS ((char **));
490 static long reg_list
PARAMS ((char **));
491 static void thumb_load_store
PARAMS ((char *, int, int));
492 static int decode_shift
PARAMS ((char **, int));
493 static int ldst_extend
PARAMS ((char **, int));
494 static void thumb_add_sub
PARAMS ((char *, int));
495 static void insert_reg
PARAMS ((int));
496 static void thumb_shift
PARAMS ((char *, int));
497 static void thumb_mov_compare
PARAMS ((char *, int));
498 static void set_constant_flonums
PARAMS ((void));
499 static valueT md_chars_to_number
PARAMS ((char *, int));
500 static void insert_reg_alias
PARAMS ((char *, int));
501 static void output_inst
PARAMS ((void));
503 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
506 /* ARM instructions take 4bytes in the object file, Thumb instructions
510 /* LONGEST_INST is the longest basic instruction name without conditions or
511 flags. ARM7M has 4 of length 5. */
513 #define LONGEST_INST 5
518 CONST
char * template; /* Basic string to match */
519 unsigned long value
; /* Basic instruction code */
521 /* Compulsory suffix that must follow conds. If "", then the
522 instruction is not conditional and must have no suffix. */
523 CONST
char * comp_suffix
;
525 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
526 unsigned long variants
; /* Which CPU variants this exists for */
527 /* Function to call to parse args */
528 void (* parms
) PARAMS ((char *, unsigned long));
531 static CONST
struct asm_opcode insns
[] =
533 /* ARM Instructions */
534 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
535 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
536 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
537 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
538 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
539 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
540 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
541 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
542 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
543 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
544 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
545 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
546 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
547 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
548 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
549 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
550 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
551 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
552 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
553 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
554 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
556 {"bl", 0x0b000000, NULL
, NULL
, ARM_ANY
, do_branch
},
557 {"b", 0x0a000000, NULL
, NULL
, ARM_ANY
, do_branch
},
559 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
560 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
564 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
565 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
566 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
568 /* ARM 2 multiplies */
569 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
570 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
572 /* ARM 3 - swp instructions */
573 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
575 /* ARM 6 Coprocessor instructions */
576 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
577 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
578 /* ScottB: our code uses 0x0128f000 for msr.
579 NickC: but this is wrong because the bits 16 through 19 are
580 handled by the PSR_xxx defines above. */
582 /* ARM 7M long multiplies - need signed/unsigned flags! */
583 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
584 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
585 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
586 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
588 /* ARM THUMB interworking */
589 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
591 /* Floating point instructions */
592 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
593 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
594 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
595 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
596 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
597 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
598 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
599 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
600 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
601 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
602 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
603 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
604 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
605 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
606 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
607 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
608 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
609 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
610 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
611 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
612 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
613 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
614 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
615 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
616 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
617 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
618 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
619 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
620 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
621 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
622 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
623 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
624 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
625 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
626 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
627 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
628 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
629 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
630 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
631 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
632 be an optional suffix, but part of the instruction. To be compatible,
634 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
635 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
636 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
637 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
639 /* Generic copressor instructions. */
640 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
641 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
642 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
643 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
644 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
647 /* Defines for various bits that we will want to toggle. */
648 #define INST_IMMEDIATE 0x02000000
649 #define OFFSET_REG 0x02000000
650 #define HWOFFSET_IMM 0x00400000
651 #define SHIFT_BY_REG 0x00000010
652 #define PRE_INDEX 0x01000000
653 #define INDEX_UP 0x00800000
654 #define WRITE_BACK 0x00200000
655 #define LDM_TYPE_2_OR_3 0x00400000
657 #define LITERAL_MASK 0xf000f000
658 #define COND_MASK 0xf0000000
659 #define OPCODE_MASK 0xfe1fffff
660 #define DATA_OP_SHIFT 21
662 /* Codes to distinguish the arithmetic instructions. */
673 #define OPCODE_CMP 10
674 #define OPCODE_CMN 11
675 #define OPCODE_ORR 12
676 #define OPCODE_MOV 13
677 #define OPCODE_BIC 14
678 #define OPCODE_MVN 15
680 static void do_t_nop
PARAMS ((char *));
681 static void do_t_arit
PARAMS ((char *));
682 static void do_t_add
PARAMS ((char *));
683 static void do_t_asr
PARAMS ((char *));
684 static void do_t_branch9
PARAMS ((char *));
685 static void do_t_branch12
PARAMS ((char *));
686 static void do_t_branch23
PARAMS ((char *));
687 static void do_t_bx
PARAMS ((char *));
688 static void do_t_compare
PARAMS ((char *));
689 static void do_t_ldmstm
PARAMS ((char *));
690 static void do_t_ldr
PARAMS ((char *));
691 static void do_t_ldrb
PARAMS ((char *));
692 static void do_t_ldrh
PARAMS ((char *));
693 static void do_t_lds
PARAMS ((char *));
694 static void do_t_lsl
PARAMS ((char *));
695 static void do_t_lsr
PARAMS ((char *));
696 static void do_t_mov
PARAMS ((char *));
697 static void do_t_push_pop
PARAMS ((char *));
698 static void do_t_str
PARAMS ((char *));
699 static void do_t_strb
PARAMS ((char *));
700 static void do_t_strh
PARAMS ((char *));
701 static void do_t_sub
PARAMS ((char *));
702 static void do_t_swi
PARAMS ((char *));
703 static void do_t_adr
PARAMS ((char *));
705 #define T_OPCODE_MUL 0x4340
706 #define T_OPCODE_TST 0x4200
707 #define T_OPCODE_CMN 0x42c0
708 #define T_OPCODE_NEG 0x4240
709 #define T_OPCODE_MVN 0x43c0
711 #define T_OPCODE_ADD_R3 0x1800
712 #define T_OPCODE_SUB_R3 0x1a00
713 #define T_OPCODE_ADD_HI 0x4400
714 #define T_OPCODE_ADD_ST 0xb000
715 #define T_OPCODE_SUB_ST 0xb080
716 #define T_OPCODE_ADD_SP 0xa800
717 #define T_OPCODE_ADD_PC 0xa000
718 #define T_OPCODE_ADD_I8 0x3000
719 #define T_OPCODE_SUB_I8 0x3800
720 #define T_OPCODE_ADD_I3 0x1c00
721 #define T_OPCODE_SUB_I3 0x1e00
723 #define T_OPCODE_ASR_R 0x4100
724 #define T_OPCODE_LSL_R 0x4080
725 #define T_OPCODE_LSR_R 0x40c0
726 #define T_OPCODE_ASR_I 0x1000
727 #define T_OPCODE_LSL_I 0x0000
728 #define T_OPCODE_LSR_I 0x0800
730 #define T_OPCODE_MOV_I8 0x2000
731 #define T_OPCODE_CMP_I8 0x2800
732 #define T_OPCODE_CMP_LR 0x4280
733 #define T_OPCODE_MOV_HR 0x4600
734 #define T_OPCODE_CMP_HR 0x4500
736 #define T_OPCODE_LDR_PC 0x4800
737 #define T_OPCODE_LDR_SP 0x9800
738 #define T_OPCODE_STR_SP 0x9000
739 #define T_OPCODE_LDR_IW 0x6800
740 #define T_OPCODE_STR_IW 0x6000
741 #define T_OPCODE_LDR_IH 0x8800
742 #define T_OPCODE_STR_IH 0x8000
743 #define T_OPCODE_LDR_IB 0x7800
744 #define T_OPCODE_STR_IB 0x7000
745 #define T_OPCODE_LDR_RW 0x5800
746 #define T_OPCODE_STR_RW 0x5000
747 #define T_OPCODE_LDR_RH 0x5a00
748 #define T_OPCODE_STR_RH 0x5200
749 #define T_OPCODE_LDR_RB 0x5c00
750 #define T_OPCODE_STR_RB 0x5400
752 #define T_OPCODE_PUSH 0xb400
753 #define T_OPCODE_POP 0xbc00
755 #define T_OPCODE_BRANCH 0xe7fe
757 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
759 #define THUMB_SIZE 2 /* Size of thumb instruction. */
760 #define THUMB_REG_LO 0x1
761 #define THUMB_REG_HI 0x2
762 #define THUMB_REG_ANY 0x3
764 #define THUMB_H1 0x0080
765 #define THUMB_H2 0x0040
772 #define THUMB_COMPARE 1
775 #define THUMB_STORE 1
777 #define THUMB_PP_PC_LR 0x0100
779 /* These three are used for immediate shifts, do not alter. */
781 #define THUMB_HALFWORD 1
786 CONST
char * template; /* Basic string to match */
787 unsigned long value
; /* Basic instruction code */
789 unsigned long variants
; /* Which CPU variants this exists for */
790 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
793 static CONST
struct thumb_opcode tinsns
[] =
795 {"adc", 0x4140, 2, ARM_THUMB
, do_t_arit
},
796 {"add", 0x0000, 2, ARM_THUMB
, do_t_add
},
797 {"and", 0x4000, 2, ARM_THUMB
, do_t_arit
},
798 {"asr", 0x0000, 2, ARM_THUMB
, do_t_asr
},
799 {"b", T_OPCODE_BRANCH
, 2, ARM_THUMB
, do_t_branch12
},
800 {"beq", 0xd0fe, 2, ARM_THUMB
, do_t_branch9
},
801 {"bne", 0xd1fe, 2, ARM_THUMB
, do_t_branch9
},
802 {"bcs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
803 {"bhs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
804 {"bcc", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
805 {"bul", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
806 {"blo", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
807 {"bmi", 0xd4fe, 2, ARM_THUMB
, do_t_branch9
},
808 {"bpl", 0xd5fe, 2, ARM_THUMB
, do_t_branch9
},
809 {"bvs", 0xd6fe, 2, ARM_THUMB
, do_t_branch9
},
810 {"bvc", 0xd7fe, 2, ARM_THUMB
, do_t_branch9
},
811 {"bhi", 0xd8fe, 2, ARM_THUMB
, do_t_branch9
},
812 {"bls", 0xd9fe, 2, ARM_THUMB
, do_t_branch9
},
813 {"bge", 0xdafe, 2, ARM_THUMB
, do_t_branch9
},
814 {"blt", 0xdbfe, 2, ARM_THUMB
, do_t_branch9
},
815 {"bgt", 0xdcfe, 2, ARM_THUMB
, do_t_branch9
},
816 {"ble", 0xddfe, 2, ARM_THUMB
, do_t_branch9
},
817 {"bal", 0xdefe, 2, ARM_THUMB
, do_t_branch9
},
818 {"bic", 0x4380, 2, ARM_THUMB
, do_t_arit
},
819 {"bl", 0xf7fffffe, 4, ARM_THUMB
, do_t_branch23
},
820 {"bx", 0x4700, 2, ARM_THUMB
, do_t_bx
},
821 {"cmn", T_OPCODE_CMN
, 2, ARM_THUMB
, do_t_arit
},
822 {"cmp", 0x0000, 2, ARM_THUMB
, do_t_compare
},
823 {"eor", 0x4040, 2, ARM_THUMB
, do_t_arit
},
824 {"ldmia", 0xc800, 2, ARM_THUMB
, do_t_ldmstm
},
825 {"ldr", 0x0000, 2, ARM_THUMB
, do_t_ldr
},
826 {"ldrb", 0x0000, 2, ARM_THUMB
, do_t_ldrb
},
827 {"ldrh", 0x0000, 2, ARM_THUMB
, do_t_ldrh
},
828 {"ldrsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
829 {"ldrsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
830 {"ldsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
831 {"ldsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
832 {"lsl", 0x0000, 2, ARM_THUMB
, do_t_lsl
},
833 {"lsr", 0x0000, 2, ARM_THUMB
, do_t_lsr
},
834 {"mov", 0x0000, 2, ARM_THUMB
, do_t_mov
},
835 {"mul", T_OPCODE_MUL
, 2, ARM_THUMB
, do_t_arit
},
836 {"mvn", T_OPCODE_MVN
, 2, ARM_THUMB
, do_t_arit
},
837 {"neg", T_OPCODE_NEG
, 2, ARM_THUMB
, do_t_arit
},
838 {"orr", 0x4300, 2, ARM_THUMB
, do_t_arit
},
839 {"pop", 0xbc00, 2, ARM_THUMB
, do_t_push_pop
},
840 {"push", 0xb400, 2, ARM_THUMB
, do_t_push_pop
},
841 {"ror", 0x41c0, 2, ARM_THUMB
, do_t_arit
},
842 {"sbc", 0x4180, 2, ARM_THUMB
, do_t_arit
},
843 {"stmia", 0xc000, 2, ARM_THUMB
, do_t_ldmstm
},
844 {"str", 0x0000, 2, ARM_THUMB
, do_t_str
},
845 {"strb", 0x0000, 2, ARM_THUMB
, do_t_strb
},
846 {"strh", 0x0000, 2, ARM_THUMB
, do_t_strh
},
847 {"swi", 0xdf00, 2, ARM_THUMB
, do_t_swi
},
848 {"sub", 0x0000, 2, ARM_THUMB
, do_t_sub
},
849 {"tst", T_OPCODE_TST
, 2, ARM_THUMB
, do_t_arit
},
851 {"adr", 0x0000, 2, ARM_THUMB
, do_t_adr
},
852 {"nop", 0x46C0, 2, ARM_THUMB
, do_t_nop
}, /* mov r8,r8 */
861 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
862 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
863 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
869 /* These are the standard names. Users can add aliases with .req */
870 static CONST
struct reg_entry reg_table
[] =
872 /* Processor Register Numbers. */
873 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
874 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
875 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
876 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
877 /* APCS conventions. */
878 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
879 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
880 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
881 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
882 /* ATPCS additions to APCS conventions. */
883 {"wr", 7}, {"v8", 11},
885 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
886 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
887 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
888 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
889 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
890 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
891 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
892 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
893 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
894 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
895 /* ATPCS additions to float register names. */
896 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
897 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
898 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
899 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
900 /* FIXME: At some point we need to add VFP register names. */
901 /* Array terminator. */
905 #define BAD_ARGS _("Bad arguments to instruction")
906 #define BAD_PC _("r15 not allowed here")
907 #define BAD_FLAGS _("Instruction should not have flags")
908 #define BAD_COND _("Instruction is not conditional")
910 static struct hash_control
* arm_ops_hsh
= NULL
;
911 static struct hash_control
* arm_tops_hsh
= NULL
;
912 static struct hash_control
* arm_cond_hsh
= NULL
;
913 static struct hash_control
* arm_shift_hsh
= NULL
;
914 static struct hash_control
* arm_reg_hsh
= NULL
;
915 static struct hash_control
* arm_psr_hsh
= NULL
;
917 /* This table describes all the machine specific pseudo-ops the assembler
918 has to support. The fields are:
919 pseudo-op name without dot
920 function to call to execute this pseudo-op
921 Integer arg to pass to the function. */
923 static void s_req
PARAMS ((int));
924 static void s_align
PARAMS ((int));
925 static void s_bss
PARAMS ((int));
926 static void s_even
PARAMS ((int));
927 static void s_ltorg
PARAMS ((int));
928 static void s_arm
PARAMS ((int));
929 static void s_thumb
PARAMS ((int));
930 static void s_code
PARAMS ((int));
931 static void s_force_thumb
PARAMS ((int));
932 static void s_thumb_func
PARAMS ((int));
933 static void s_thumb_set
PARAMS ((int));
934 static void arm_s_text
PARAMS ((int));
935 static void arm_s_data
PARAMS ((int));
937 static void arm_s_section
PARAMS ((int));
938 static void s_arm_elf_cons
PARAMS ((int));
941 static int my_get_expression
PARAMS ((expressionS
*, char **));
943 CONST pseudo_typeS md_pseudo_table
[] =
945 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
947 { "align", s_align
, 0 },
949 { "thumb", s_thumb
, 0 },
950 { "code", s_code
, 0 },
951 { "force_thumb", s_force_thumb
, 0 },
952 { "thumb_func", s_thumb_func
, 0 },
953 { "thumb_set", s_thumb_set
, 0 },
954 { "even", s_even
, 0 },
955 { "ltorg", s_ltorg
, 0 },
956 { "pool", s_ltorg
, 0 },
957 /* Allow for the effect of section changes. */
958 { "text", arm_s_text
, 0 },
959 { "data", arm_s_data
, 0 },
961 { "section", arm_s_section
, 0 },
962 { "section.s", arm_s_section
, 0 },
963 { "sect", arm_s_section
, 0 },
964 { "sect.s", arm_s_section
, 0 },
965 { "word", s_arm_elf_cons
, 4 },
966 { "long", s_arm_elf_cons
, 4 },
970 { "extend", float_cons
, 'x' },
971 { "ldouble", float_cons
, 'x' },
972 { "packed", float_cons
, 'p' },
976 /* Stuff needed to resolve the label ambiguity
986 symbolS
* last_label_seen
;
987 static int label_is_thumb_function_name
= false;
991 #define MAX_LITERAL_POOL_SIZE 1024
993 typedef struct literalS
995 struct expressionS exp
;
996 struct arm_it
* inst
;
999 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1000 int next_literal_pool_place
= 0; /* Next free entry in the pool */
1001 int lit_pool_num
= 1; /* Next literal pool number */
1002 symbolS
* current_poolP
= NULL
;
1009 if (current_poolP
== NULL
)
1010 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1011 (valueT
) 0, &zero_address_frag
);
1013 /* Check if this literal value is already in the pool: */
1014 while (lit_count
< next_literal_pool_place
)
1016 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1017 && inst
.reloc
.exp
.X_op
== O_constant
1018 && literals
[lit_count
].exp
.X_add_number
1019 == inst
.reloc
.exp
.X_add_number
1020 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1025 if (lit_count
== next_literal_pool_place
) /* new entry */
1027 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1029 inst
.error
= _("Literal Pool Overflow");
1033 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1034 lit_count
= next_literal_pool_place
++;
1037 inst
.reloc
.exp
.X_op
= O_symbol
;
1038 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1039 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1044 /* Can't use symbol_new here, so have to create a symbol and then at
1045 a later date assign it a value. Thats what these functions do. */
1047 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1049 CONST
char * name
; /* It is copied, the caller can modify */
1050 segT segment
; /* Segment identifier (SEG_<something>) */
1051 valueT valu
; /* Symbol value */
1052 fragS
* frag
; /* Associated fragment */
1054 unsigned int name_length
;
1055 char * preserved_copy_of_name
;
1057 name_length
= strlen (name
) + 1; /* +1 for \0 */
1058 obstack_grow (¬es
, name
, name_length
);
1059 preserved_copy_of_name
= obstack_finish (¬es
);
1060 #ifdef STRIP_UNDERSCORE
1061 if (preserved_copy_of_name
[0] == '_')
1062 preserved_copy_of_name
++;
1065 #ifdef tc_canonicalize_symbol_name
1066 preserved_copy_of_name
=
1067 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1070 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1072 S_SET_SEGMENT (symbolP
, segment
);
1073 S_SET_VALUE (symbolP
, valu
);
1074 symbol_clear_list_pointers(symbolP
);
1076 symbol_set_frag (symbolP
, frag
);
1078 /* Link to end of symbol chain. */
1080 extern int symbol_table_frozen
;
1081 if (symbol_table_frozen
)
1085 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1087 obj_symbol_new_hook (symbolP
);
1089 #ifdef tc_symbol_new_hook
1090 tc_symbol_new_hook (symbolP
);
1094 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1095 #endif /* DEBUG_SYMS */
1098 /* Check that an immediate is valid, and if so,
1099 convert it to the right format. */
1101 validate_immediate (val
)
1107 #define rotate_left(v, n) (v << n | v >> (32 - n))
1109 for (i
= 0; i
< 32; i
+= 2)
1110 if ((a
= rotate_left (val
, i
)) <= 0xff)
1111 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1116 /* Check to see if an immediate can be computed as two seperate immediate
1117 values, added together. We already know that this value cannot be
1118 computed by just one ARM instruction. */
1120 validate_immediate_twopart (val
, highpart
)
1122 unsigned int * highpart
;
1127 for (i
= 0; i
< 32; i
+= 2)
1128 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1134 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1136 else if (a
& 0xff0000)
1141 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1145 assert (a
& 0xff000000);
1147 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1150 return (a
& 0xff) | (i
<< 7);
1157 validate_offset_imm (val
, hwse
)
1161 if ((hwse
&& val
> 255) || val
> 4095)
1169 int a ATTRIBUTE_UNUSED
;
1171 as_bad (_("Invalid syntax for .req directive."));
1176 int ignore ATTRIBUTE_UNUSED
;
1178 /* We don't support putting frags in the BSS segment, we fake it by
1179 marking in_bss, then looking at s_skip for clues?.. */
1180 subseg_set (bss_section
, 0);
1181 demand_empty_rest_of_line ();
1186 int ignore ATTRIBUTE_UNUSED
;
1188 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1189 frag_align (1, 0, 0);
1191 record_alignment (now_seg
, 1);
1193 demand_empty_rest_of_line ();
1198 int ignored ATTRIBUTE_UNUSED
;
1203 if (current_poolP
== NULL
)
1206 /* Align pool as you have word accesses */
1207 /* Only make a frag if we have to ... */
1209 frag_align (2, 0, 0);
1211 record_alignment (now_seg
, 2);
1213 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1215 symbol_locate (current_poolP
, sym_name
, now_seg
,
1216 (valueT
) frag_now_fix (), frag_now
);
1217 symbol_table_insert (current_poolP
);
1219 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1221 #if defined OBJ_COFF || defined OBJ_ELF
1222 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1225 while (lit_count
< next_literal_pool_place
)
1226 /* First output the expression in the instruction to the pool. */
1227 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1229 next_literal_pool_place
= 0;
1230 current_poolP
= NULL
;
1234 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1235 int unused ATTRIBUTE_UNUSED
;
1238 register long temp_fill
;
1239 long max_alignment
= 15;
1241 temp
= get_absolute_expression ();
1242 if (temp
> max_alignment
)
1243 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1246 as_bad (_("Alignment negative. 0 assumed."));
1250 if (*input_line_pointer
== ',')
1252 input_line_pointer
++;
1253 temp_fill
= get_absolute_expression ();
1261 /* Only make a frag if we HAVE to. . . */
1262 if (temp
&& !need_pass_2
)
1263 frag_align (temp
, (int) temp_fill
, 0);
1264 demand_empty_rest_of_line ();
1266 record_alignment (now_seg
, temp
);
1270 s_force_thumb (ignore
)
1271 int ignore ATTRIBUTE_UNUSED
;
1273 /* If we are not already in thumb mode go into it, EVEN if
1274 the target processor does not support thumb instructions.
1275 This is used by gcc/config/arm/lib1funcs.asm for example
1276 to compile interworking support functions even if the
1277 target processor should not support interworking. */
1283 record_alignment (now_seg
, 1);
1286 demand_empty_rest_of_line ();
1290 s_thumb_func (ignore
)
1291 int ignore ATTRIBUTE_UNUSED
;
1296 /* The following label is the name/address of the start of a Thumb function.
1297 We need to know this for the interworking support. */
1298 label_is_thumb_function_name
= true;
1300 demand_empty_rest_of_line ();
1303 /* Perform a .set directive, but also mark the alias as
1304 being a thumb function. */
1310 /* XXX the following is a duplicate of the code for s_set() in read.c
1311 We cannot just call that code as we need to get at the symbol that
1313 register char * name
;
1314 register char delim
;
1315 register char * end_name
;
1316 register symbolS
* symbolP
;
1319 * Especial apologies for the random logic:
1320 * this just grew, and could be parsed much more simply!
1323 name
= input_line_pointer
;
1324 delim
= get_symbol_end ();
1325 end_name
= input_line_pointer
;
1330 if (*input_line_pointer
!= ',')
1333 as_bad (_("Expected comma after name \"%s\""), name
);
1335 ignore_rest_of_line ();
1339 input_line_pointer
++;
1342 if (name
[0] == '.' && name
[1] == '\0')
1344 /* XXX - this should not happen to .thumb_set */
1348 if ((symbolP
= symbol_find (name
)) == NULL
1349 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1352 /* When doing symbol listings, play games with dummy fragments living
1353 outside the normal fragment chain to record the file and line info
1355 if (listing
& LISTING_SYMBOLS
)
1357 extern struct list_info_struct
* listing_tail
;
1358 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1359 memset (dummy_frag
, 0, sizeof(fragS
));
1360 dummy_frag
->fr_type
= rs_fill
;
1361 dummy_frag
->line
= listing_tail
;
1362 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1363 dummy_frag
->fr_symbol
= symbolP
;
1367 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1370 /* "set" symbols are local unless otherwise specified. */
1371 SF_SET_LOCAL (symbolP
);
1372 #endif /* OBJ_COFF */
1373 } /* make a new symbol */
1375 symbol_table_insert (symbolP
);
1380 && S_IS_DEFINED (symbolP
)
1381 && S_GET_SEGMENT (symbolP
) != reg_section
)
1382 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1384 pseudo_set (symbolP
);
1386 demand_empty_rest_of_line ();
1388 /* XXX Now we come to the Thumb specific bit of code. */
1390 THUMB_SET_FUNC (symbolP
, 1);
1391 ARM_SET_THUMB (symbolP
, 1);
1392 #if defined OBJ_ELF || defined OBJ_COFF
1393 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1397 /* If we change section we must dump the literal pool first. */
1402 if (now_seg
!= text_section
)
1406 obj_elf_text (ignore
);
1416 if (flag_readonly_data_in_text
)
1418 if (now_seg
!= text_section
)
1421 else if (now_seg
!= data_section
)
1425 obj_elf_data (ignore
);
1433 arm_s_section (ignore
)
1438 obj_elf_section (ignore
);
1443 opcode_select (width
)
1451 if (! (cpu_variant
& ARM_THUMB
))
1452 as_bad (_("selected processor does not support THUMB opcodes"));
1454 /* No need to force the alignment, since we will have been
1455 coming from ARM mode, which is word-aligned. */
1456 record_alignment (now_seg
, 1);
1463 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1464 as_bad (_("selected processor does not support ARM opcodes"));
1467 frag_align (2, 0, 0);
1468 record_alignment (now_seg
, 1);
1473 as_bad (_("invalid instruction size selected (%d)"), width
);
1479 int ignore ATTRIBUTE_UNUSED
;
1482 demand_empty_rest_of_line ();
1487 int ignore ATTRIBUTE_UNUSED
;
1490 demand_empty_rest_of_line ();
1495 int unused ATTRIBUTE_UNUSED
;
1499 temp
= get_absolute_expression ();
1504 opcode_select (temp
);
1508 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1516 skip_whitespace (str
);
1519 inst
.error
= _("Garbage following instruction");
1523 skip_past_comma (str
)
1529 while ((c
= *p
) == ' ' || c
== ',')
1532 if (c
== ',' && comma
++)
1540 return comma
? SUCCESS
: FAIL
;
1543 /* A standard register must be given at this point.
1544 Shift is the place to put it in inst.instruction.
1545 Restores input start point on err.
1546 Returns the reg#, or FAIL. */
1548 reg_required_here (str
, shift
)
1552 static char buff
[128]; /* XXX */
1554 char * start
= *str
;
1556 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1559 inst
.instruction
|= reg
<< shift
;
1563 /* Restore the start point, we may have got a reg of the wrong class. */
1566 /* In the few cases where we might be able to accept something else
1567 this error can be overridden. */
1568 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1574 static CONST
struct asm_psr
*
1576 register char ** ccp
;
1578 char * start
= * ccp
;
1581 CONST
struct asm_psr
* psr
;
1585 /* Skip to the end of the next word in the input stream. */
1590 while (isalpha (c
) || c
== '_');
1592 /* Terminate the word. */
1595 /* Now locate the word in the psr hash table. */
1596 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
1598 /* Restore the input stream. */
1601 /* If we found a valid match, advance the
1602 stream pointer past the end of the word. */
1608 /* Parse the input looking for a PSR flag. */
1610 psr_required_here (str
)
1613 char * start
= *str
;
1614 CONST
struct asm_psr
* psr
;
1616 psr
= arm_psr_parse (str
);
1620 /* If this is the SPSR that is being modified, set the R bit. */
1622 inst
.instruction
|= SPSR_BIT
;
1624 /* Set the psr flags in the MSR instruction. */
1625 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
1630 /* In the few cases where we might be able to accept
1631 something else this error can be overridden. */
1632 inst
.error
= _("flag for {c}psr instruction expected");
1634 /* Restore the start point. */
1640 co_proc_number (str
)
1643 int processor
, pchar
;
1645 skip_whitespace (* str
);
1647 /* The data sheet seems to imply that just a number on its own is valid
1648 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1650 if (**str
== 'p' || **str
== 'P')
1654 if (pchar
>= '0' && pchar
<= '9')
1656 processor
= pchar
- '0';
1657 if (**str
>= '0' && **str
<= '9')
1659 processor
= processor
* 10 + *(*str
)++ - '0';
1662 inst
.error
= _("Illegal co-processor number");
1669 inst
.error
= _("Bad or missing co-processor number");
1673 inst
.instruction
|= processor
<< 8;
1678 cp_opc_expr (str
, where
, length
)
1685 skip_whitespace (* str
);
1687 memset (&expr
, '\0', sizeof (expr
));
1689 if (my_get_expression (&expr
, str
))
1691 if (expr
.X_op
!= O_constant
)
1693 inst
.error
= _("bad or missing expression");
1697 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1699 inst
.error
= _("immediate co-processor expression too large");
1703 inst
.instruction
|= expr
.X_add_number
<< where
;
1708 cp_reg_required_here (str
, where
)
1713 char * start
= *str
;
1715 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1718 inst
.instruction
|= reg
<< where
;
1722 /* In the few cases where we might be able to accept something else
1723 this error can be overridden. */
1724 inst
.error
= _("Co-processor register expected");
1726 /* Restore the start point. */
1732 fp_reg_required_here (str
, where
)
1737 char * start
= *str
;
1739 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1742 inst
.instruction
|= reg
<< where
;
1746 /* In the few cases where we might be able to accept something else
1747 this error can be overridden. */
1748 inst
.error
= _("Floating point register expected");
1750 /* Restore the start point. */
1756 cp_address_offset (str
)
1761 skip_whitespace (* str
);
1763 if (! is_immediate_prefix (**str
))
1765 inst
.error
= _("immediate expression expected");
1771 if (my_get_expression (& inst
.reloc
.exp
, str
))
1774 if (inst
.reloc
.exp
.X_op
== O_constant
)
1776 offset
= inst
.reloc
.exp
.X_add_number
;
1780 inst
.error
= _("co-processor address must be word aligned");
1784 if (offset
> 1023 || offset
< -1023)
1786 inst
.error
= _("offset too large");
1791 inst
.instruction
|= INDEX_UP
;
1795 inst
.instruction
|= offset
>> 2;
1798 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1804 cp_address_required_here (str
)
1816 skip_whitespace (p
);
1818 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1821 skip_whitespace (p
);
1827 if (skip_past_comma (& p
) == SUCCESS
)
1830 write_back
= WRITE_BACK
;
1834 inst
.error
= _("pc may not be used in post-increment");
1838 if (cp_address_offset (& p
) == FAIL
)
1842 pre_inc
= PRE_INDEX
| INDEX_UP
;
1846 /* '['Rn, #expr']'[!] */
1848 if (skip_past_comma (& p
) == FAIL
)
1850 inst
.error
= _("pre-indexed expression expected");
1854 pre_inc
= PRE_INDEX
;
1856 if (cp_address_offset (& p
) == FAIL
)
1859 skip_whitespace (p
);
1863 inst
.error
= _("missing ]");
1867 skip_whitespace (p
);
1873 inst
.error
= _("pc may not be used with write-back");
1878 write_back
= WRITE_BACK
;
1884 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1887 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1888 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1889 inst
.reloc
.pc_rel
= 1;
1890 inst
.instruction
|= (REG_PC
<< 16);
1891 pre_inc
= PRE_INDEX
;
1894 inst
.instruction
|= write_back
| pre_inc
;
1902 unsigned long flags
;
1904 /* Do nothing really. */
1905 inst
.instruction
|= flags
; /* This is pointless. */
1913 unsigned long flags
;
1917 /* Only one syntax. */
1918 skip_whitespace (str
);
1920 if (reg_required_here (&str
, 12) == FAIL
)
1922 inst
.error
= BAD_ARGS
;
1926 if (skip_past_comma (&str
) == FAIL
)
1928 inst
.error
= _("comma expected after register name");
1932 skip_whitespace (str
);
1934 if ( strcmp (str
, "CPSR") == 0
1935 || strcmp (str
, "SPSR") == 0
1936 /* Lower case versions for backwards compatability. */
1937 || strcmp (str
, "cpsr") == 0
1938 || strcmp (str
, "spsr") == 0)
1940 /* This is for backwards compatability with older toolchains. */
1941 else if (strcmp (str
, "cpsr_all") == 0
1942 || strcmp (str
, "spsr_all") == 0)
1946 inst
.error
= _("{C|S}PSR expected");
1950 if (* str
== 's' || * str
== 'S')
1951 inst
.instruction
|= SPSR_BIT
;
1954 inst
.instruction
|= flags
;
1958 /* Two possible forms:
1959 "{C|S}PSR_<field>, Rm",
1960 "{C|S}PSR_f, #expression". */
1964 unsigned long flags
;
1966 skip_whitespace (str
);
1968 if (psr_required_here (& str
) == FAIL
)
1971 if (skip_past_comma (& str
) == FAIL
)
1973 inst
.error
= _("comma missing after psr flags");
1977 skip_whitespace (str
);
1979 if (reg_required_here (& str
, 0) != FAIL
)
1982 inst
.instruction
|= flags
;
1987 if (! is_immediate_prefix (* str
))
1989 inst
.error
= _("only a register or immediate value can follow a psr flag");
1996 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1998 inst
.error
= _("only a register or immediate value can follow a psr flag");
2002 if (inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2004 inst
.error
= _("can only set flag field with immediate value");
2008 flags
|= INST_IMMEDIATE
;
2010 if (inst
.reloc
.exp
.X_add_symbol
)
2012 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2013 inst
.reloc
.pc_rel
= 0;
2017 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2019 if (value
== (unsigned) FAIL
)
2021 inst
.error
= _("Invalid constant");
2025 inst
.instruction
|= value
;
2029 inst
.instruction
|= flags
;
2033 /* Long Multiply Parser
2034 UMULL RdLo, RdHi, Rm, Rs
2035 SMULL RdLo, RdHi, Rm, Rs
2036 UMLAL RdLo, RdHi, Rm, Rs
2037 SMLAL RdLo, RdHi, Rm, Rs
2040 do_mull (str
, flags
)
2042 unsigned long flags
;
2044 int rdlo
, rdhi
, rm
, rs
;
2046 /* Only one format "rdlo, rdhi, rm, rs" */
2047 skip_whitespace (str
);
2049 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2051 inst
.error
= BAD_ARGS
;
2055 if (skip_past_comma (&str
) == FAIL
2056 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2058 inst
.error
= BAD_ARGS
;
2062 if (skip_past_comma (&str
) == FAIL
2063 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2065 inst
.error
= BAD_ARGS
;
2069 /* rdhi, rdlo and rm must all be different */
2070 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2071 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2073 if (skip_past_comma (&str
) == FAIL
2074 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2076 inst
.error
= BAD_ARGS
;
2080 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2082 inst
.error
= BAD_PC
;
2086 inst
.instruction
|= flags
;
2094 unsigned long flags
;
2098 /* Only one format "rd, rm, rs" */
2099 skip_whitespace (str
);
2101 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2103 inst
.error
= BAD_ARGS
;
2109 inst
.error
= BAD_PC
;
2113 if (skip_past_comma (&str
) == FAIL
2114 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2116 inst
.error
= BAD_ARGS
;
2122 inst
.error
= BAD_PC
;
2127 as_tsktsk (_("rd and rm should be different in mul"));
2129 if (skip_past_comma (&str
) == FAIL
2130 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2132 inst
.error
= BAD_ARGS
;
2138 inst
.error
= BAD_PC
;
2142 inst
.instruction
|= flags
;
2150 unsigned long flags
;
2154 /* Only one format "rd, rm, rs, rn" */
2155 skip_whitespace (str
);
2157 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2159 inst
.error
= BAD_ARGS
;
2165 inst
.error
= BAD_PC
;
2169 if (skip_past_comma (&str
) == FAIL
2170 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2172 inst
.error
= BAD_ARGS
;
2178 inst
.error
= BAD_PC
;
2183 as_tsktsk (_("rd and rm should be different in mla"));
2185 if (skip_past_comma (&str
) == FAIL
2186 || (rd
= reg_required_here (&str
, 8)) == FAIL
2187 || skip_past_comma (&str
) == FAIL
2188 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2190 inst
.error
= BAD_ARGS
;
2194 if (rd
== REG_PC
|| rm
== REG_PC
)
2196 inst
.error
= BAD_PC
;
2200 inst
.instruction
|= flags
;
2205 /* Returns the index into fp_values of a floating point number, or -1 if
2206 not in the table. */
2208 my_get_float_expression (str
)
2211 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2217 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2218 /* Look for a raw floating point number */
2219 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2220 && is_end_of_line
[(unsigned char) *save_in
])
2222 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2224 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2226 if (words
[j
] != fp_values
[i
][j
])
2230 if (j
== MAX_LITTLENUMS
)
2238 /* Try and parse a more complex expression, this will probably fail
2239 unless the code uses a floating point prefix (eg "0f") */
2240 save_in
= input_line_pointer
;
2241 input_line_pointer
= *str
;
2242 if (expression (&exp
) == absolute_section
2243 && exp
.X_op
== O_big
2244 && exp
.X_add_number
< 0)
2246 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2248 if (gen_to_words (words
, 5, (long)15) == 0)
2250 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2252 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2254 if (words
[j
] != fp_values
[i
][j
])
2258 if (j
== MAX_LITTLENUMS
)
2260 *str
= input_line_pointer
;
2261 input_line_pointer
= save_in
;
2268 *str
= input_line_pointer
;
2269 input_line_pointer
= save_in
;
2273 /* Return true if anything in the expression is a bignum */
2275 walk_no_bignums (sp
)
2278 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2281 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2283 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2284 || (symbol_get_value_expression (sp
)->X_op_symbol
2285 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2292 my_get_expression (ep
, str
)
2299 save_in
= input_line_pointer
;
2300 input_line_pointer
= *str
;
2301 seg
= expression (ep
);
2304 if (seg
!= absolute_section
2305 && seg
!= text_section
2306 && seg
!= data_section
2307 && seg
!= bss_section
2308 && seg
!= undefined_section
)
2310 inst
.error
= _("bad_segment");
2311 *str
= input_line_pointer
;
2312 input_line_pointer
= save_in
;
2317 /* Get rid of any bignums now, so that we don't generate an error for which
2318 we can't establish a line number later on. Big numbers are never valid
2319 in instructions, which is where this routine is always called. */
2320 if (ep
->X_op
== O_big
2321 || (ep
->X_add_symbol
2322 && (walk_no_bignums (ep
->X_add_symbol
)
2324 && walk_no_bignums (ep
->X_op_symbol
)))))
2326 inst
.error
= _("Invalid constant");
2327 *str
= input_line_pointer
;
2328 input_line_pointer
= save_in
;
2332 *str
= input_line_pointer
;
2333 input_line_pointer
= save_in
;
2337 /* unrestrict should be one if <shift> <register> is permitted for this
2341 decode_shift (str
, unrestrict
)
2345 struct asm_shift
* shft
;
2349 skip_whitespace (* str
);
2351 for (p
= *str
; isalpha (*p
); p
++)
2356 inst
.error
= _("Shift expression expected");
2362 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2366 if (!strncmp (*str
, "rrx", 3)
2367 || !strncmp (*str
, "RRX", 3))
2370 inst
.instruction
|= shft
->value
;
2374 skip_whitespace (p
);
2376 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2378 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2382 else if (is_immediate_prefix (* p
))
2386 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2389 /* Validate some simple #expressions */
2390 if (inst
.reloc
.exp
.X_op
== O_constant
)
2392 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2394 /* Reject operations greater than 32, or lsl #32 */
2395 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2397 inst
.error
= _("Invalid immediate shift");
2401 /* Shifts of zero should be converted to lsl (which is zero)*/
2408 /* Shifts of 32 are encoded as 0, for those shifts that
2413 inst
.instruction
|= (num
<< 7) | shft
->value
;
2418 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2419 inst
.reloc
.pc_rel
= 0;
2420 inst
.instruction
|= shft
->value
;
2426 inst
.error
= unrestrict
? _("shift requires register or #expression")
2427 : _("shift requires #expression");
2433 inst
.error
= _("Shift expression expected");
2437 /* Do those data_ops which can take a negative immediate constant */
2438 /* by altering the instuction. A bit of a hack really */
2442 by inverting the second operand, and
2445 by negating the second operand.
2448 negate_data_op (instruction
, value
)
2449 unsigned long * instruction
;
2450 unsigned long value
;
2453 unsigned long negated
, inverted
;
2455 negated
= validate_immediate (-value
);
2456 inverted
= validate_immediate (~value
);
2458 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2462 case OPCODE_SUB
: /* ADD <-> SUB */
2463 new_inst
= OPCODE_ADD
;
2468 new_inst
= OPCODE_SUB
;
2472 case OPCODE_CMP
: /* CMP <-> CMN */
2473 new_inst
= OPCODE_CMN
;
2478 new_inst
= OPCODE_CMP
;
2482 /* Now Inverted ops */
2483 case OPCODE_MOV
: /* MOV <-> MVN */
2484 new_inst
= OPCODE_MVN
;
2489 new_inst
= OPCODE_MOV
;
2493 case OPCODE_AND
: /* AND <-> BIC */
2494 new_inst
= OPCODE_BIC
;
2499 new_inst
= OPCODE_AND
;
2503 case OPCODE_ADC
: /* ADC <-> SBC */
2504 new_inst
= OPCODE_SBC
;
2509 new_inst
= OPCODE_ADC
;
2513 /* We cannot do anything */
2518 if (value
== (unsigned) FAIL
)
2521 *instruction
&= OPCODE_MASK
;
2522 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2533 skip_whitespace (* str
);
2535 if (reg_required_here (str
, 0) != FAIL
)
2537 if (skip_past_comma (str
) == SUCCESS
)
2538 /* Shift operation on register. */
2539 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2545 /* Immediate expression */
2546 if (is_immediate_prefix (**str
))
2551 if (my_get_expression (&inst
.reloc
.exp
, str
))
2554 if (inst
.reloc
.exp
.X_add_symbol
)
2556 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2557 inst
.reloc
.pc_rel
= 0;
2561 if (skip_past_comma (str
) == SUCCESS
)
2563 /* #x, y -- ie explicit rotation by Y */
2564 if (my_get_expression (&expr
, str
))
2567 if (expr
.X_op
!= O_constant
)
2569 inst
.error
= _("Constant expression expected");
2573 /* Rotate must be a multiple of 2 */
2574 if (((unsigned) expr
.X_add_number
) > 30
2575 || (expr
.X_add_number
& 1) != 0
2576 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2578 inst
.error
= _("Invalid constant");
2581 inst
.instruction
|= INST_IMMEDIATE
;
2582 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2583 inst
.instruction
|= expr
.X_add_number
<< 7;
2587 /* Implicit rotation, select a suitable one */
2588 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2592 /* Can't be done, perhaps the code reads something like
2593 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2594 if ((value
= negate_data_op (&inst
.instruction
,
2595 inst
.reloc
.exp
.X_add_number
))
2598 inst
.error
= _("Invalid constant");
2603 inst
.instruction
|= value
;
2606 inst
.instruction
|= INST_IMMEDIATE
;
2611 inst
.error
= _("Register or shift expression expected");
2620 skip_whitespace (* str
);
2622 if (fp_reg_required_here (str
, 0) != FAIL
)
2626 /* Immediate expression */
2627 if (*((*str
)++) == '#')
2633 skip_whitespace (* str
);
2635 /* First try and match exact strings, this is to guarantee that
2636 some formats will work even for cross assembly */
2638 for (i
= 0; fp_const
[i
]; i
++)
2640 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2644 *str
+= strlen (fp_const
[i
]);
2645 if (is_end_of_line
[(unsigned char) **str
])
2647 inst
.instruction
|= i
+ 8;
2654 /* Just because we didn't get a match doesn't mean that the
2655 constant isn't valid, just that it is in a format that we
2656 don't automatically recognize. Try parsing it with
2657 the standard expression routines. */
2658 if ((i
= my_get_float_expression (str
)) >= 0)
2660 inst
.instruction
|= i
+ 8;
2664 inst
.error
= _("Invalid floating point immediate expression");
2667 inst
.error
= _("Floating point register or immediate expression expected");
2673 do_arit (str
, flags
)
2675 unsigned long flags
;
2677 skip_whitespace (str
);
2679 if (reg_required_here (&str
, 12) == FAIL
2680 || skip_past_comma (&str
) == FAIL
2681 || reg_required_here (&str
, 16) == FAIL
2682 || skip_past_comma (&str
) == FAIL
2683 || data_op2 (&str
) == FAIL
)
2686 inst
.error
= BAD_ARGS
;
2690 inst
.instruction
|= flags
;
2698 unsigned long flags
;
2700 /* This is a pseudo-op of the form "adr rd, label" to be converted
2701 into a relative address of the form "add rd, pc, #label-.-8". */
2702 skip_whitespace (str
);
2704 if (reg_required_here (&str
, 12) == FAIL
2705 || skip_past_comma (&str
) == FAIL
2706 || my_get_expression (&inst
.reloc
.exp
, &str
))
2709 inst
.error
= BAD_ARGS
;
2713 /* Frag hacking will turn this into a sub instruction if the offset turns
2714 out to be negative. */
2715 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2716 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
2717 inst
.reloc
.pc_rel
= 1;
2718 inst
.instruction
|= flags
;
2724 do_adrl (str
, flags
)
2726 unsigned long flags
;
2728 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2729 into a relative address of the form:
2730 add rd, pc, #low(label-.-8)"
2731 add rd, rd, #high(label-.-8)" */
2733 skip_whitespace (str
);
2735 if (reg_required_here (& str
, 12) == FAIL
2736 || skip_past_comma (& str
) == FAIL
2737 || my_get_expression (& inst
.reloc
.exp
, & str
))
2740 inst
.error
= BAD_ARGS
;
2746 /* Frag hacking will turn this into a sub instruction if the offset turns
2747 out to be negative. */
2748 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2749 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2750 inst
.reloc
.pc_rel
= 1;
2751 inst
.instruction
|= flags
;
2752 inst
.size
= INSN_SIZE
* 2;
2760 unsigned long flags
;
2762 skip_whitespace (str
);
2764 if (reg_required_here (&str
, 16) == FAIL
)
2767 inst
.error
= BAD_ARGS
;
2771 if (skip_past_comma (&str
) == FAIL
2772 || data_op2 (&str
) == FAIL
)
2775 inst
.error
= BAD_ARGS
;
2779 inst
.instruction
|= flags
;
2780 if ((flags
& 0x0000f000) == 0)
2781 inst
.instruction
|= CONDS_BIT
;
2790 unsigned long flags
;
2792 skip_whitespace (str
);
2794 if (reg_required_here (&str
, 12) == FAIL
)
2797 inst
.error
= BAD_ARGS
;
2801 if (skip_past_comma (&str
) == FAIL
2802 || data_op2 (&str
) == FAIL
)
2805 inst
.error
= BAD_ARGS
;
2809 inst
.instruction
|= flags
;
2815 ldst_extend (str
, hwse
)
2826 if (my_get_expression (& inst
.reloc
.exp
, str
))
2829 if (inst
.reloc
.exp
.X_op
== O_constant
)
2831 int value
= inst
.reloc
.exp
.X_add_number
;
2833 if ((hwse
&& (value
< -255 || value
> 255))
2834 || (value
< -4095 || value
> 4095))
2836 inst
.error
= _("address offset too large");
2846 /* Halfword and signextension instructions have the
2847 immediate value split across bits 11..8 and bits 3..0 */
2849 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2851 inst
.instruction
|= add
| value
;
2857 inst
.instruction
|= HWOFFSET_IMM
;
2858 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2861 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2862 inst
.reloc
.pc_rel
= 0;
2867 add
= 0; /* and fall through */
2869 (*str
)++; /* and fall through */
2871 if (reg_required_here (str
, 0) == FAIL
)
2875 inst
.instruction
|= add
;
2878 inst
.instruction
|= add
| OFFSET_REG
;
2879 if (skip_past_comma (str
) == SUCCESS
)
2880 return decode_shift (str
, SHIFT_RESTRICT
);
2888 do_ldst (str
, flags
)
2890 unsigned long flags
;
2897 /* This is not ideal, but it is the simplest way of dealing with the
2898 ARM7T halfword instructions (since they use a different
2899 encoding, but the same mnemonic): */
2900 halfword
= (flags
& 0x80000000) != 0;
2903 /* This is actually a load/store of a halfword, or a
2904 signed-extension load */
2905 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2908 = _("Processor does not support halfwords or signed bytes");
2912 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2913 | (flags
& ~COND_MASK
);
2918 skip_whitespace (str
);
2920 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2923 inst
.error
= BAD_ARGS
;
2927 if (skip_past_comma (& str
) == FAIL
)
2929 inst
.error
= _("Address expected");
2939 skip_whitespace (str
);
2941 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2944 /* Conflicts can occur on stores as well as loads. */
2945 conflict_reg
= (conflict_reg
== reg
);
2947 skip_whitespace (str
);
2953 if (skip_past_comma (&str
) == SUCCESS
)
2955 /* [Rn],... (post inc) */
2956 if (ldst_extend (&str
, halfword
) == FAIL
)
2959 as_warn (_("%s register same as write-back base"),
2960 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2966 inst
.instruction
|= HWOFFSET_IMM
;
2968 skip_whitespace (str
);
2973 as_warn (_("%s register same as write-back base"),
2974 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2976 inst
.instruction
|= WRITE_BACK
;
2980 if (! (flags
& TRANS_BIT
))
2987 if (skip_past_comma (&str
) == FAIL
)
2989 inst
.error
= _("pre-indexed expression expected");
2994 if (ldst_extend (&str
, halfword
) == FAIL
)
2997 skip_whitespace (str
);
3001 inst
.error
= _("missing ]");
3005 skip_whitespace (str
);
3010 as_warn (_("%s register same as write-back base"),
3011 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
3013 inst
.instruction
|= WRITE_BACK
;
3017 else if (*str
== '=')
3019 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
3022 skip_whitespace (str
);
3024 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3027 if (inst
.reloc
.exp
.X_op
!= O_constant
3028 && inst
.reloc
.exp
.X_op
!= O_symbol
)
3030 inst
.error
= _("Constant expression expected");
3034 if (inst
.reloc
.exp
.X_op
== O_constant
3035 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
3037 /* This can be done with a mov instruction */
3038 inst
.instruction
&= LITERAL_MASK
;
3039 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
3040 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
3046 /* Insert into literal pool */
3047 if (add_to_lit_pool () == FAIL
)
3050 inst
.error
= _("literal pool insertion failed");
3054 /* Change the instruction exp to point to the pool */
3057 inst
.instruction
|= HWOFFSET_IMM
;
3058 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
3061 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
3062 inst
.reloc
.pc_rel
= 1;
3063 inst
.instruction
|= (REG_PC
<< 16);
3069 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3074 inst
.instruction
|= HWOFFSET_IMM
;
3075 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3078 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3080 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
3082 inst
.reloc
.pc_rel
= 1;
3083 inst
.instruction
|= (REG_PC
<< 16);
3087 if (pre_inc
&& (flags
& TRANS_BIT
))
3088 inst
.error
= _("Pre-increment instruction with translate");
3090 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3103 /* We come back here if we get ranges concatenated by '+' or '|' */
3118 skip_whitespace (str
);
3120 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3129 inst
.error
= _("Bad range in register list");
3133 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3135 if (range
& (1 << i
))
3137 (_("Warning: Duplicated register (r%d) in register list"),
3145 if (range
& (1 << reg
))
3146 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3148 else if (reg
<= cur_reg
)
3149 as_tsktsk (_("Warning: Register range not in ascending order"));
3153 } while (skip_past_comma (&str
) != FAIL
3154 || (in_range
= 1, *str
++ == '-'));
3156 skip_whitespace (str
);
3160 inst
.error
= _("Missing `}'");
3168 if (my_get_expression (&expr
, &str
))
3171 if (expr
.X_op
== O_constant
)
3173 if (expr
.X_add_number
3174 != (expr
.X_add_number
& 0x0000ffff))
3176 inst
.error
= _("invalid register mask");
3180 if ((range
& expr
.X_add_number
) != 0)
3182 int regno
= range
& expr
.X_add_number
;
3185 regno
= (1 << regno
) - 1;
3187 (_("Warning: Duplicated register (r%d) in register list"),
3191 range
|= expr
.X_add_number
;
3195 if (inst
.reloc
.type
!= 0)
3197 inst
.error
= _("expression too complex");
3201 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3202 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3203 inst
.reloc
.pc_rel
= 0;
3207 skip_whitespace (str
);
3209 if (*str
== '|' || *str
== '+')
3214 } while (another_range
);
3221 do_ldmstm (str
, flags
)
3223 unsigned long flags
;
3228 skip_whitespace (str
);
3230 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3233 if (base_reg
== REG_PC
)
3235 inst
.error
= _("r15 not allowed as base register");
3239 skip_whitespace (str
);
3243 flags
|= WRITE_BACK
;
3247 if (skip_past_comma (&str
) == FAIL
3248 || (range
= reg_list (&str
)) == FAIL
)
3251 inst
.error
= BAD_ARGS
;
3258 flags
|= LDM_TYPE_2_OR_3
;
3261 inst
.instruction
|= flags
| range
;
3269 unsigned long flags
;
3271 skip_whitespace (str
);
3273 /* Allow optional leading '#'. */
3274 if (is_immediate_prefix (*str
))
3277 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3280 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3281 inst
.reloc
.pc_rel
= 0;
3282 inst
.instruction
|= flags
;
3290 do_swap (str
, flags
)
3292 unsigned long flags
;
3296 skip_whitespace (str
);
3298 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3303 inst
.error
= _("r15 not allowed in swap");
3307 if (skip_past_comma (&str
) == FAIL
3308 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3311 inst
.error
= BAD_ARGS
;
3317 inst
.error
= _("r15 not allowed in swap");
3321 if (skip_past_comma (&str
) == FAIL
3324 inst
.error
= BAD_ARGS
;
3328 skip_whitespace (str
);
3330 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3335 inst
.error
= BAD_PC
;
3339 skip_whitespace (str
);
3343 inst
.error
= _("missing ]");
3347 inst
.instruction
|= flags
;
3353 do_branch (str
, flags
)
3355 unsigned long flags ATTRIBUTE_UNUSED
;
3357 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3364 /* ScottB: February 5, 1998 */
3365 /* Check to see of PLT32 reloc required for the instruction. */
3367 /* arm_parse_reloc() works on input_line_pointer.
3368 We actually want to parse the operands to the branch instruction
3369 passed in 'str'. Save the input pointer and restore it later. */
3370 save_in
= input_line_pointer
;
3371 input_line_pointer
= str
;
3372 if (inst
.reloc
.exp
.X_op
== O_symbol
3374 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3376 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3377 inst
.reloc
.pc_rel
= 0;
3378 /* Modify str to point to after parsed operands, otherwise
3379 end_of_line() will complain about the (PLT) left in str. */
3380 str
= input_line_pointer
;
3384 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3385 inst
.reloc
.pc_rel
= 1;
3387 input_line_pointer
= save_in
;
3390 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3391 inst
.reloc
.pc_rel
= 1;
3392 #endif /* OBJ_ELF */
3401 unsigned long flags ATTRIBUTE_UNUSED
;
3405 skip_whitespace (str
);
3407 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3409 inst
.error
= BAD_ARGS
;
3414 inst
.error
= BAD_PC
;
3422 unsigned long flags ATTRIBUTE_UNUSED
;
3424 /* Co-processor data operation.
3425 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3426 skip_whitespace (str
);
3428 if (co_proc_number (&str
) == FAIL
)
3431 inst
.error
= BAD_ARGS
;
3435 if (skip_past_comma (&str
) == FAIL
3436 || cp_opc_expr (&str
, 20,4) == FAIL
)
3439 inst
.error
= BAD_ARGS
;
3443 if (skip_past_comma (&str
) == FAIL
3444 || cp_reg_required_here (&str
, 12) == FAIL
)
3447 inst
.error
= BAD_ARGS
;
3451 if (skip_past_comma (&str
) == FAIL
3452 || cp_reg_required_here (&str
, 16) == FAIL
)
3455 inst
.error
= BAD_ARGS
;
3459 if (skip_past_comma (&str
) == FAIL
3460 || cp_reg_required_here (&str
, 0) == FAIL
)
3463 inst
.error
= BAD_ARGS
;
3467 if (skip_past_comma (&str
) == SUCCESS
)
3469 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3472 inst
.error
= BAD_ARGS
;
3482 do_lstc (str
, flags
)
3484 unsigned long flags
;
3486 /* Co-processor register load/store.
3487 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3489 skip_whitespace (str
);
3491 if (co_proc_number (&str
) == FAIL
)
3494 inst
.error
= BAD_ARGS
;
3498 if (skip_past_comma (&str
) == FAIL
3499 || cp_reg_required_here (&str
, 12) == FAIL
)
3502 inst
.error
= BAD_ARGS
;
3506 if (skip_past_comma (&str
) == FAIL
3507 || cp_address_required_here (&str
) == FAIL
)
3510 inst
.error
= BAD_ARGS
;
3514 inst
.instruction
|= flags
;
3520 do_co_reg (str
, flags
)
3522 unsigned long flags
;
3524 /* Co-processor register transfer.
3525 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3527 skip_whitespace (str
);
3529 if (co_proc_number (&str
) == FAIL
)
3532 inst
.error
= BAD_ARGS
;
3536 if (skip_past_comma (&str
) == FAIL
3537 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3540 inst
.error
= BAD_ARGS
;
3544 if (skip_past_comma (&str
) == FAIL
3545 || reg_required_here (&str
, 12) == FAIL
)
3548 inst
.error
= BAD_ARGS
;
3552 if (skip_past_comma (&str
) == FAIL
3553 || cp_reg_required_here (&str
, 16) == FAIL
)
3556 inst
.error
= BAD_ARGS
;
3560 if (skip_past_comma (&str
) == FAIL
3561 || cp_reg_required_here (&str
, 0) == FAIL
)
3564 inst
.error
= BAD_ARGS
;
3568 if (skip_past_comma (&str
) == SUCCESS
)
3570 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3573 inst
.error
= BAD_ARGS
;
3579 inst
.error
= BAD_COND
;
3587 do_fp_ctrl (str
, flags
)
3589 unsigned long flags ATTRIBUTE_UNUSED
;
3591 /* FP control registers.
3592 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3594 skip_whitespace (str
);
3596 if (reg_required_here (&str
, 12) == FAIL
)
3599 inst
.error
= BAD_ARGS
;
3608 do_fp_ldst (str
, flags
)
3610 unsigned long flags ATTRIBUTE_UNUSED
;
3612 skip_whitespace (str
);
3614 switch (inst
.suffix
)
3619 inst
.instruction
|= CP_T_X
;
3622 inst
.instruction
|= CP_T_Y
;
3625 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3631 if (fp_reg_required_here (&str
, 12) == FAIL
)
3634 inst
.error
= BAD_ARGS
;
3638 if (skip_past_comma (&str
) == FAIL
3639 || cp_address_required_here (&str
) == FAIL
)
3642 inst
.error
= BAD_ARGS
;
3650 do_fp_ldmstm (str
, flags
)
3652 unsigned long flags
;
3656 skip_whitespace (str
);
3658 if (fp_reg_required_here (&str
, 12) == FAIL
)
3661 inst
.error
= BAD_ARGS
;
3665 /* Get Number of registers to transfer */
3666 if (skip_past_comma (&str
) == FAIL
3667 || my_get_expression (&inst
.reloc
.exp
, &str
))
3670 inst
.error
= _("constant expression expected");
3674 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3676 inst
.error
= _("Constant value required for number of registers");
3680 num_regs
= inst
.reloc
.exp
.X_add_number
;
3682 if (num_regs
< 1 || num_regs
> 4)
3684 inst
.error
= _("number of registers must be in the range [1:4]");
3691 inst
.instruction
|= CP_T_X
;
3694 inst
.instruction
|= CP_T_Y
;
3697 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3711 /* The instruction specified "ea" or "fd", so we can only accept
3712 [Rn]{!}. The instruction does not really support stacking or
3713 unstacking, so we have to emulate these by setting appropriate
3714 bits and offsets. */
3715 if (skip_past_comma (&str
) == FAIL
3719 inst
.error
= BAD_ARGS
;
3724 skip_whitespace (str
);
3726 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3729 skip_whitespace (str
);
3733 inst
.error
= BAD_ARGS
;
3744 inst
.error
= _("R15 not allowed as base register with write-back");
3751 if (flags
& CP_T_Pre
)
3754 offset
= 3 * num_regs
;
3760 /* Post-increment */
3764 offset
= 3 * num_regs
;
3768 /* No write-back, so convert this into a standard pre-increment
3769 instruction -- aesthetically more pleasing. */
3770 flags
= CP_T_Pre
| CP_T_UD
;
3775 inst
.instruction
|= flags
| offset
;
3777 else if (skip_past_comma (&str
) == FAIL
3778 || cp_address_required_here (&str
) == FAIL
)
3781 inst
.error
= BAD_ARGS
;
3789 do_fp_dyadic (str
, flags
)
3791 unsigned long flags
;
3793 skip_whitespace (str
);
3795 switch (inst
.suffix
)
3800 inst
.instruction
|= 0x00000080;
3803 inst
.instruction
|= 0x00080000;
3809 if (fp_reg_required_here (&str
, 12) == FAIL
)
3812 inst
.error
= BAD_ARGS
;
3816 if (skip_past_comma (&str
) == FAIL
3817 || fp_reg_required_here (&str
, 16) == FAIL
)
3820 inst
.error
= BAD_ARGS
;
3824 if (skip_past_comma (&str
) == FAIL
3825 || fp_op2 (&str
) == FAIL
)
3828 inst
.error
= BAD_ARGS
;
3832 inst
.instruction
|= flags
;
3838 do_fp_monadic (str
, flags
)
3840 unsigned long flags
;
3842 skip_whitespace (str
);
3844 switch (inst
.suffix
)
3849 inst
.instruction
|= 0x00000080;
3852 inst
.instruction
|= 0x00080000;
3858 if (fp_reg_required_here (&str
, 12) == FAIL
)
3861 inst
.error
= BAD_ARGS
;
3865 if (skip_past_comma (&str
) == FAIL
3866 || fp_op2 (&str
) == FAIL
)
3869 inst
.error
= BAD_ARGS
;
3873 inst
.instruction
|= flags
;
3879 do_fp_cmp (str
, flags
)
3881 unsigned long flags
;
3883 skip_whitespace (str
);
3885 if (fp_reg_required_here (&str
, 16) == FAIL
)
3888 inst
.error
= BAD_ARGS
;
3892 if (skip_past_comma (&str
) == FAIL
3893 || fp_op2 (&str
) == FAIL
)
3896 inst
.error
= BAD_ARGS
;
3900 inst
.instruction
|= flags
;
3906 do_fp_from_reg (str
, flags
)
3908 unsigned long flags
;
3910 skip_whitespace (str
);
3912 switch (inst
.suffix
)
3917 inst
.instruction
|= 0x00000080;
3920 inst
.instruction
|= 0x00080000;
3926 if (fp_reg_required_here (&str
, 16) == FAIL
)
3929 inst
.error
= BAD_ARGS
;
3933 if (skip_past_comma (&str
) == FAIL
3934 || reg_required_here (&str
, 12) == FAIL
)
3937 inst
.error
= BAD_ARGS
;
3941 inst
.instruction
|= flags
;
3947 do_fp_to_reg (str
, flags
)
3949 unsigned long flags
;
3951 skip_whitespace (str
);
3953 if (reg_required_here (&str
, 12) == FAIL
)
3956 if (skip_past_comma (&str
) == FAIL
3957 || fp_reg_required_here (&str
, 0) == FAIL
)
3960 inst
.error
= BAD_ARGS
;
3964 inst
.instruction
|= flags
;
3969 /* Thumb specific routines */
3971 /* Parse and validate that a register is of the right form, this saves
3972 repeated checking of this information in many similar cases.
3973 Unlike the 32-bit case we do not insert the register into the opcode
3974 here, since the position is often unknown until the full instruction
3977 thumb_reg (strp
, hi_lo
)
3983 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3991 inst
.error
= _("lo register required");
3999 inst
.error
= _("hi register required");
4011 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4014 thumb_add_sub (str
, subtract
)
4018 int Rd
, Rs
, Rn
= FAIL
;
4020 skip_whitespace (str
);
4022 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4023 || skip_past_comma (&str
) == FAIL
)
4026 inst
.error
= BAD_ARGS
;
4030 if (is_immediate_prefix (*str
))
4034 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4039 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4042 if (skip_past_comma (&str
) == FAIL
)
4044 /* Two operand format, shuffle the registers and pretend there
4049 else if (is_immediate_prefix (*str
))
4052 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4055 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4059 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4060 for the latter case, EXPR contains the immediate that was found. */
4063 /* All register format. */
4064 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
4068 inst
.error
= _("dest and source1 must be the same register");
4072 /* Can't do this for SUB */
4075 inst
.error
= _("subtract valid only on lo regs");
4079 inst
.instruction
= (T_OPCODE_ADD_HI
4080 | (Rd
> 7 ? THUMB_H1
: 0)
4081 | (Rn
> 7 ? THUMB_H2
: 0));
4082 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4086 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4087 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4092 /* Immediate expression, now things start to get nasty. */
4094 /* First deal with HI regs, only very restricted cases allowed:
4095 Adjusting SP, and using PC or SP to get an address. */
4096 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4097 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4099 inst
.error
= _("invalid Hi register with immediate");
4103 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4105 /* Value isn't known yet, all we can do is store all the fragments
4106 we know about in the instruction and let the reloc hacking
4108 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4109 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4113 int offset
= inst
.reloc
.exp
.X_add_number
;
4123 /* Quick check, in case offset is MIN_INT */
4126 inst
.error
= _("immediate value out of range");
4135 if (offset
& ~0x1fc)
4137 inst
.error
= _("invalid immediate value for stack adjust");
4140 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4141 inst
.instruction
|= offset
>> 2;
4143 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4146 || (offset
& ~0x3fc))
4148 inst
.error
= _("invalid immediate for address calculation");
4151 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4153 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4159 inst
.error
= _("immediate value out of range");
4162 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4163 inst
.instruction
|= (Rd
<< 8) | offset
;
4169 inst
.error
= _("immediate value out of range");
4172 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4173 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4182 thumb_shift (str
, shift
)
4186 int Rd
, Rs
, Rn
= FAIL
;
4188 skip_whitespace (str
);
4190 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4191 || skip_past_comma (&str
) == FAIL
)
4194 inst
.error
= BAD_ARGS
;
4198 if (is_immediate_prefix (*str
))
4200 /* Two operand immediate format, set Rs to Rd. */
4203 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4208 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4211 if (skip_past_comma (&str
) == FAIL
)
4213 /* Two operand format, shuffle the registers and pretend there
4218 else if (is_immediate_prefix (*str
))
4221 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4224 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4228 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4229 for the latter case, EXPR contains the immediate that was found. */
4235 inst
.error
= _("source1 and dest must be same register");
4241 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4242 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4243 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4246 inst
.instruction
|= Rd
| (Rn
<< 3);
4252 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4253 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4254 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4257 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4259 /* Value isn't known yet, create a dummy reloc and let reloc
4260 hacking fix it up */
4262 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4266 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4268 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4270 inst
.error
= _("Invalid immediate for shift");
4274 /* Shifts of zero are handled by converting to LSL */
4275 if (shift_value
== 0)
4276 inst
.instruction
= T_OPCODE_LSL_I
;
4278 /* Shifts of 32 are encoded as a shift of zero */
4279 if (shift_value
== 32)
4282 inst
.instruction
|= shift_value
<< 6;
4285 inst
.instruction
|= Rd
| (Rs
<< 3);
4292 thumb_mov_compare (str
, move
)
4298 skip_whitespace (str
);
4300 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4301 || skip_past_comma (&str
) == FAIL
)
4304 inst
.error
= BAD_ARGS
;
4308 if (is_immediate_prefix (*str
))
4311 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4314 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4319 if (Rs
< 8 && Rd
< 8)
4321 if (move
== THUMB_MOVE
)
4322 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4323 since a MOV instruction produces unpredictable results */
4324 inst
.instruction
= T_OPCODE_ADD_I3
;
4326 inst
.instruction
= T_OPCODE_CMP_LR
;
4327 inst
.instruction
|= Rd
| (Rs
<< 3);
4331 if (move
== THUMB_MOVE
)
4332 inst
.instruction
= T_OPCODE_MOV_HR
;
4334 inst
.instruction
= T_OPCODE_CMP_HR
;
4337 inst
.instruction
|= THUMB_H1
;
4340 inst
.instruction
|= THUMB_H2
;
4342 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4349 inst
.error
= _("only lo regs allowed with immediate");
4353 if (move
== THUMB_MOVE
)
4354 inst
.instruction
= T_OPCODE_MOV_I8
;
4356 inst
.instruction
= T_OPCODE_CMP_I8
;
4358 inst
.instruction
|= Rd
<< 8;
4360 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4361 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4364 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4368 inst
.error
= _("invalid immediate");
4372 inst
.instruction
|= value
;
4380 thumb_load_store (str
, load_store
, size
)
4385 int Rd
, Rb
, Ro
= FAIL
;
4387 skip_whitespace (str
);
4389 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4390 || skip_past_comma (&str
) == FAIL
)
4393 inst
.error
= BAD_ARGS
;
4400 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4403 if (skip_past_comma (&str
) != FAIL
)
4405 if (is_immediate_prefix (*str
))
4408 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4411 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4416 inst
.reloc
.exp
.X_op
= O_constant
;
4417 inst
.reloc
.exp
.X_add_number
= 0;
4422 inst
.error
= _("expected ']'");
4427 else if (*str
== '=')
4429 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4432 skip_whitespace (str
);
4434 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4439 if ( inst
.reloc
.exp
.X_op
!= O_constant
4440 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4442 inst
.error
= "Constant expression expected";
4446 if (inst
.reloc
.exp
.X_op
== O_constant
4447 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4449 /* This can be done with a mov instruction */
4451 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4452 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4456 /* Insert into literal pool */
4457 if (add_to_lit_pool () == FAIL
)
4460 inst
.error
= "literal pool insertion failed";
4464 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4465 inst
.reloc
.pc_rel
= 1;
4466 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4467 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4473 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4476 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4477 inst
.reloc
.pc_rel
= 1;
4478 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4479 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4484 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4486 if (size
!= THUMB_WORD
)
4488 inst
.error
= _("byte or halfword not valid for base register");
4491 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4493 inst
.error
= _("R15 based store not allowed");
4496 else if (Ro
!= FAIL
)
4498 inst
.error
= _("Invalid base register for register offset");
4503 inst
.instruction
= T_OPCODE_LDR_PC
;
4504 else if (load_store
== THUMB_LOAD
)
4505 inst
.instruction
= T_OPCODE_LDR_SP
;
4507 inst
.instruction
= T_OPCODE_STR_SP
;
4509 inst
.instruction
|= Rd
<< 8;
4510 if (inst
.reloc
.exp
.X_op
== O_constant
)
4512 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4514 if (offset
& ~0x3fc)
4516 inst
.error
= _("invalid offset");
4520 inst
.instruction
|= offset
>> 2;
4523 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4527 inst
.error
= _("invalid base register in load/store");
4530 else if (Ro
== FAIL
)
4532 /* Immediate offset */
4533 if (size
== THUMB_WORD
)
4534 inst
.instruction
= (load_store
== THUMB_LOAD
4535 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4536 else if (size
== THUMB_HALFWORD
)
4537 inst
.instruction
= (load_store
== THUMB_LOAD
4538 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4540 inst
.instruction
= (load_store
== THUMB_LOAD
4541 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4543 inst
.instruction
|= Rd
| (Rb
<< 3);
4545 if (inst
.reloc
.exp
.X_op
== O_constant
)
4547 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4549 if (offset
& ~(0x1f << size
))
4551 inst
.error
= _("Invalid offset");
4554 inst
.instruction
|= (offset
>> size
) << 6;
4557 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4561 /* Register offset */
4562 if (size
== THUMB_WORD
)
4563 inst
.instruction
= (load_store
== THUMB_LOAD
4564 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4565 else if (size
== THUMB_HALFWORD
)
4566 inst
.instruction
= (load_store
== THUMB_LOAD
4567 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4569 inst
.instruction
= (load_store
== THUMB_LOAD
4570 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4572 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4587 /* Handle the Format 4 instructions that do not have equivalents in other
4588 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4596 skip_whitespace (str
);
4598 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4599 || skip_past_comma (&str
) == FAIL
4600 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4602 inst
.error
= BAD_ARGS
;
4606 if (skip_past_comma (&str
) != FAIL
)
4608 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4609 (It isn't allowed for CMP either, but that isn't handled by this
4611 if (inst
.instruction
== T_OPCODE_TST
4612 || inst
.instruction
== T_OPCODE_CMN
4613 || inst
.instruction
== T_OPCODE_NEG
4614 || inst
.instruction
== T_OPCODE_MVN
)
4616 inst
.error
= BAD_ARGS
;
4620 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4625 inst
.error
= _("dest and source1 one must be the same register");
4631 if (inst
.instruction
== T_OPCODE_MUL
4633 as_tsktsk (_("Rs and Rd must be different in MUL"));
4635 inst
.instruction
|= Rd
| (Rs
<< 3);
4643 thumb_add_sub (str
, 0);
4650 thumb_shift (str
, THUMB_ASR
);
4657 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4659 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4660 inst
.reloc
.pc_rel
= 1;
4668 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4670 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4671 inst
.reloc
.pc_rel
= 1;
4675 /* Find the real, Thumb encoded start of a Thumb function. */
4678 find_real_start (symbolP
)
4682 const char * name
= S_GET_NAME (symbolP
);
4683 symbolS
* new_target
;
4685 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4686 #define STUB_NAME ".real_start_of"
4691 /* Names that start with '.' are local labels, not function entry points.
4692 The compiler may generate BL instructions to these labels because it
4693 needs to perform a branch to a far away location. */
4697 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4698 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4700 new_target
= symbol_find (real_start
);
4702 if (new_target
== NULL
)
4704 as_warn ("Failed to find real start of function: %s\n", name
);
4705 new_target
= symbolP
;
4718 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4721 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4722 inst
.reloc
.pc_rel
= 1;
4725 /* If the destination of the branch is a defined symbol which does not have
4726 the THUMB_FUNC attribute, then we must be calling a function which has
4727 the (interfacearm) attribute. We look for the Thumb entry point to that
4728 function and change the branch to refer to that function instead. */
4729 if ( inst
.reloc
.exp
.X_op
== O_symbol
4730 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4731 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4732 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4733 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4742 skip_whitespace (str
);
4744 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4747 /* This sets THUMB_H2 from the top bit of reg. */
4748 inst
.instruction
|= reg
<< 3;
4750 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4751 should cause the alignment to be checked once it is known. This is
4752 because BX PC only works if the instruction is word aligned. */
4761 thumb_mov_compare (str
, THUMB_COMPARE
);
4771 skip_whitespace (str
);
4773 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4777 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4781 if (skip_past_comma (&str
) == FAIL
4782 || (range
= reg_list (&str
)) == FAIL
)
4785 inst
.error
= BAD_ARGS
;
4789 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4791 /* This really doesn't seem worth it. */
4792 inst
.reloc
.type
= BFD_RELOC_NONE
;
4793 inst
.error
= _("Expression too complex");
4799 inst
.error
= _("only lo-regs valid in load/store multiple");
4803 inst
.instruction
|= (Rb
<< 8) | range
;
4811 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4818 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4825 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4834 skip_whitespace (str
);
4836 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4837 || skip_past_comma (&str
) == FAIL
4839 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4840 || skip_past_comma (&str
) == FAIL
4841 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4845 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4849 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4857 thumb_shift (str
, THUMB_LSL
);
4864 thumb_shift (str
, THUMB_LSR
);
4871 thumb_mov_compare (str
, THUMB_MOVE
);
4880 skip_whitespace (str
);
4882 if ((range
= reg_list (&str
)) == FAIL
)
4885 inst
.error
= BAD_ARGS
;
4889 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4891 /* This really doesn't seem worth it. */
4892 inst
.reloc
.type
= BFD_RELOC_NONE
;
4893 inst
.error
= _("Expression too complex");
4899 if ((inst
.instruction
== T_OPCODE_PUSH
4900 && (range
& ~0xff) == 1 << REG_LR
)
4901 || (inst
.instruction
== T_OPCODE_POP
4902 && (range
& ~0xff) == 1 << REG_PC
))
4904 inst
.instruction
|= THUMB_PP_PC_LR
;
4909 inst
.error
= _("invalid register list to push/pop instruction");
4914 inst
.instruction
|= range
;
4922 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4929 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4936 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4943 thumb_add_sub (str
, 1);
4950 skip_whitespace (str
);
4952 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4955 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4966 /* This is a pseudo-op of the form "adr rd, label" to be converted
4967 into a relative address of the form "add rd, pc, #label-.-4". */
4968 skip_whitespace (str
);
4970 /* Store Rd in temporary location inside instruction. */
4971 if ((reg
= reg_required_here (&str
, 4)) == FAIL
4972 || (reg
> 7) /* For Thumb reg must be r0..r7. */
4973 || skip_past_comma (&str
) == FAIL
4974 || my_get_expression (&inst
.reloc
.exp
, &str
))
4977 inst
.error
= BAD_ARGS
;
4981 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4982 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
4983 inst
.reloc
.pc_rel
= 1;
4984 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
4993 int len
= strlen (reg_table
[entry
].name
) + 2;
4994 char * buf
= (char *) xmalloc (len
);
4995 char * buf2
= (char *) xmalloc (len
);
4998 #ifdef REGISTER_PREFIX
4999 buf
[i
++] = REGISTER_PREFIX
;
5002 strcpy (buf
+ i
, reg_table
[entry
].name
);
5004 for (i
= 0; buf
[i
]; i
++)
5005 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
5009 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
5010 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
5014 insert_reg_alias (str
, regnum
)
5018 struct reg_entry
*new =
5019 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
5020 char *name
= xmalloc (strlen (str
) + 1);
5024 new->number
= regnum
;
5026 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
5030 set_constant_flonums ()
5034 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
5035 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
5045 if ( (arm_ops_hsh
= hash_new ()) == NULL
5046 || (arm_tops_hsh
= hash_new ()) == NULL
5047 || (arm_cond_hsh
= hash_new ()) == NULL
5048 || (arm_shift_hsh
= hash_new ()) == NULL
5049 || (arm_reg_hsh
= hash_new ()) == NULL
5050 || (arm_psr_hsh
= hash_new ()) == NULL
)
5051 as_fatal (_("Virtual memory exhausted"));
5053 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
5054 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
5055 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
5056 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
5057 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
5058 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
5059 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
5060 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
5061 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
5062 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
5064 for (i
= 0; reg_table
[i
].name
; i
++)
5067 set_constant_flonums ();
5069 #if defined OBJ_COFF || defined OBJ_ELF
5071 unsigned int flags
= 0;
5073 /* Set the flags in the private structure. */
5074 if (uses_apcs_26
) flags
|= F_APCS26
;
5075 if (support_interwork
) flags
|= F_INTERWORK
;
5076 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
5077 if (pic_code
) flags
|= F_PIC
;
5078 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
5080 bfd_set_private_flags (stdoutput
, flags
);
5084 /* Record the CPU type as well. */
5085 switch (cpu_variant
& ARM_CPU_MASK
)
5088 mach
= bfd_mach_arm_2
;
5091 case ARM_3
: /* Also ARM_250. */
5092 mach
= bfd_mach_arm_2a
;
5096 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined. */
5097 mach
= bfd_mach_arm_4
;
5100 case ARM_7
: /* Also ARM_6. */
5101 mach
= bfd_mach_arm_3
;
5105 /* Catch special cases. */
5106 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5108 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5109 mach
= bfd_mach_arm_5T
;
5110 else if (cpu_variant
& ARM_EXT_V5
)
5111 mach
= bfd_mach_arm_5
;
5112 else if (cpu_variant
& ARM_THUMB
)
5113 mach
= bfd_mach_arm_4T
;
5114 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5115 mach
= bfd_mach_arm_4
;
5116 else if (cpu_variant
& ARM_LONGMUL
)
5117 mach
= bfd_mach_arm_3M
;
5120 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5123 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5124 for use in the a.out file, and stores them in the array pointed to by buf.
5125 This knows about the endian-ness of the target machine and does
5126 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5127 2 (short) and 4 (long) Floating numbers are put out as a series of
5128 LITTLENUMS (shorts, here at least). */
5130 md_number_to_chars (buf
, val
, n
)
5135 if (target_big_endian
)
5136 number_to_chars_bigendian (buf
, val
, n
);
5138 number_to_chars_littleendian (buf
, val
, n
);
5142 md_chars_to_number (buf
, n
)
5147 unsigned char * where
= (unsigned char *) buf
;
5149 if (target_big_endian
)
5154 result
|= (*where
++ & 255);
5162 result
|= (where
[n
] & 255);
5169 /* Turn a string in input_line_pointer into a floating point constant
5170 of type TYPE, and store the appropriate bytes in *litP. The number
5171 of LITTLENUMS emitted is stored in *sizeP . An error message is
5172 returned, or NULL on OK.
5174 Note that fp constants aren't represent in the normal way on the ARM.
5175 In big endian mode, things are as expected. However, in little endian
5176 mode fp constants are big-endian word-wise, and little-endian byte-wise
5177 within the words. For example, (double) 1.1 in big endian mode is
5178 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5179 the byte sequence 99 99 f1 3f 9a 99 99 99.
5181 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5184 md_atof (type
, litP
, sizeP
)
5190 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5222 return _("Bad call to MD_ATOF()");
5225 t
= atof_ieee (input_line_pointer
, type
, words
);
5227 input_line_pointer
= t
;
5230 if (target_big_endian
)
5232 for (i
= 0; i
< prec
; i
++)
5234 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5240 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5241 8 byte float the order is 1 0 3 2. */
5242 for (i
= 0; i
< prec
; i
+= 2)
5244 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5245 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5253 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5255 md_pcrel_from (fixP
)
5259 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5260 && fixP
->fx_subsy
== NULL
)
5263 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5265 /* PC relative addressing on the Thumb is slightly odd
5266 as the bottom two bits of the PC are forced to zero
5267 for the calculation. */
5268 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5272 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5273 so we un-adjust here to compensate for the accomodation. */
5274 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
5276 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5280 /* Round up a section size to the appropriate boundary. */
5282 md_section_align (segment
, size
)
5283 segT segment ATTRIBUTE_UNUSED
;
5289 /* Round all sects to multiple of 4 */
5290 return (size
+ 3) & ~3;
5294 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5295 we have no need to default values of symbols. */
5299 md_undefined_symbol (name
)
5300 char * name ATTRIBUTE_UNUSED
;
5303 if (name
[0] == '_' && name
[1] == 'G'
5304 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5308 if (symbol_find (name
))
5309 as_bad ("GOT already in the symbol table");
5311 GOT_symbol
= symbol_new (name
, undefined_section
,
5312 (valueT
)0, & zero_address_frag
);
5322 /* arm_reg_parse () := if it looks like a register, return its token and
5323 advance the pointer. */
5327 register char ** ccp
;
5329 char * start
= * ccp
;
5332 struct reg_entry
* reg
;
5334 #ifdef REGISTER_PREFIX
5335 if (*start
!= REGISTER_PREFIX
)
5340 #ifdef OPTIONAL_REGISTER_PREFIX
5341 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5345 if (!isalpha (*p
) || !is_name_beginner (*p
))
5349 while (isalpha (c
) || isdigit (c
) || c
== '_')
5353 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5366 md_apply_fix3 (fixP
, val
, seg
)
5371 offsetT value
= * val
;
5373 unsigned int newimm
;
5376 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5377 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5379 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5381 /* Note whether this will delete the relocation. */
5382 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5383 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5386 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5390 /* If this symbol is in a different section then we need to leave it for
5391 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5392 so we have to undo it's effects here. */
5395 if (fixP
->fx_addsy
!= NULL
5396 && S_IS_DEFINED (fixP
->fx_addsy
)
5397 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5400 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5401 || fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
5405 value
+= md_pcrel_from (fixP
);
5409 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc. */
5411 switch (fixP
->fx_r_type
)
5413 case BFD_RELOC_ARM_IMMEDIATE
:
5414 newimm
= validate_immediate (value
);
5415 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5417 /* If the instruction will fail, see if we can fix things up by
5418 changing the opcode. */
5419 if (newimm
== (unsigned int) FAIL
5420 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5422 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5423 _("invalid constant (%lx) after fixup"),
5424 (unsigned long) value
);
5428 newimm
|= (temp
& 0xfffff000);
5429 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5432 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5434 unsigned int highpart
= 0;
5435 unsigned int newinsn
= 0xe1a00000; /* nop */
5436 newimm
= validate_immediate (value
);
5437 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5439 /* If the instruction will fail, see if we can fix things up by
5440 changing the opcode. */
5441 if (newimm
== (unsigned int) FAIL
5442 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5444 /* No ? OK - try using two ADD instructions to generate the value. */
5445 newimm
= validate_immediate_twopart (value
, & highpart
);
5447 /* Yes - then make sure that the second instruction is also an add. */
5448 if (newimm
!= (unsigned int) FAIL
)
5450 /* Still No ? Try using a negated value. */
5451 else if (validate_immediate_twopart (- value
, & highpart
) != (unsigned int) FAIL
)
5452 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5453 /* Otherwise - give up. */
5456 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5457 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value
);
5461 /* Replace the first operand in the 2nd instruction (which is the PC)
5462 with the destination register. We have already added in the PC in the
5463 first instruction and we do not want to do it again. */
5464 newinsn
&= ~ 0xf0000;
5465 newinsn
|= ((newinsn
& 0x0f000) << 4);
5468 newimm
|= (temp
& 0xfffff000);
5469 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5471 highpart
|= (newinsn
& 0xfffff000);
5472 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5476 case BFD_RELOC_ARM_OFFSET_IMM
:
5482 if (validate_offset_imm (value
, 0) == FAIL
)
5484 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5485 _("bad immediate value for offset (%ld)"), (long) value
);
5489 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5490 newval
&= 0xff7ff000;
5491 newval
|= value
| (sign
? INDEX_UP
: 0);
5492 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5495 case BFD_RELOC_ARM_OFFSET_IMM8
:
5496 case BFD_RELOC_ARM_HWLITERAL
:
5502 if (validate_offset_imm (value
, 1) == FAIL
)
5504 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5505 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5506 _("invalid literal constant: pool needs to be closer"));
5508 as_bad (_("bad immediate value for half-word offset (%ld)"),
5513 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5514 newval
&= 0xff7ff0f0;
5515 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5516 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5519 case BFD_RELOC_ARM_LITERAL
:
5525 if (validate_offset_imm (value
, 0) == FAIL
)
5527 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5528 _("invalid literal constant: pool needs to be closer"));
5532 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5533 newval
&= 0xff7ff000;
5534 newval
|= value
| (sign
? INDEX_UP
: 0);
5535 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5538 case BFD_RELOC_ARM_SHIFT_IMM
:
5539 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5540 if (((unsigned long) value
) > 32
5542 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5544 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5545 _("shift expression is too large"));
5550 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5551 else if (value
== 32)
5553 newval
&= 0xfffff07f;
5554 newval
|= (value
& 0x1f) << 7;
5555 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5558 case BFD_RELOC_ARM_SWI
:
5559 if (arm_data
->thumb_mode
)
5561 if (((unsigned long) value
) > 0xff)
5562 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5563 _("Invalid swi expression"));
5564 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5566 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5570 if (((unsigned long) value
) > 0x00ffffff)
5571 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5572 _("Invalid swi expression"));
5573 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5575 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5579 case BFD_RELOC_ARM_MULTI
:
5580 if (((unsigned long) value
) > 0xffff)
5581 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5582 _("Invalid expression in load/store multiple"));
5583 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5584 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5587 case BFD_RELOC_ARM_PCREL_BRANCH
:
5588 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5590 /* Sign-extend a 24-bit number. */
5591 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5595 value
= fixP
->fx_offset
;
5598 /* We are going to store value (shifted right by two) in the
5599 instruction, in a 24 bit, signed field. Thus we need to check
5600 that none of the top 8 bits of the shifted value (top 7 bits of
5601 the unshifted, unsigned value) are set, or that they are all set. */
5602 if ((value
& ~ ((offsetT
) 0x1ffffff)) != 0
5603 && ((value
& ~ ((offsetT
) 0x1ffffff)) != ~ ((offsetT
) 0x1ffffff)))
5606 /* Normally we would be stuck at this point, since we cannot store
5607 the absolute address that is the destination of the branch in the
5608 24 bits of the branch instruction. If however, we happen to know
5609 that the destination of the branch is in the same section as the
5610 branch instruciton itself, then we can compute the relocation for
5611 ourselves and not have to bother the linker with it.
5613 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5614 because I have not worked out how to do this for OBJ_COFF or
5617 && fixP
->fx_addsy
!= NULL
5618 && S_IS_DEFINED (fixP
->fx_addsy
)
5619 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
5621 /* Get pc relative value to go into the branch. */
5624 /* Permit a backward branch provided that enough bits are set.
5625 Allow a forwards branch, provided that enough bits are clear. */
5626 if ((value
& ~ ((offsetT
) 0x1ffffff)) == ~ ((offsetT
) 0x1ffffff)
5627 || (value
& ~ ((offsetT
) 0x1ffffff)) == 0)
5631 if (! fixP
->fx_done
)
5633 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5634 _("gas can't handle same-section branch dest >= 0x04000000"));
5638 value
+= SEXT24 (newval
);
5640 if ((value
& ~ ((offsetT
) 0xffffff)) != 0
5641 && ((value
& ~ ((offsetT
) 0xffffff)) != ~ ((offsetT
) 0xffffff)))
5642 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5643 _("out of range branch"));
5645 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
5646 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5649 case BFD_RELOC_ARM_PCREL_BLX
:
5652 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5656 value
= fixP
->fx_offset
;
5658 hbit
= (value
>> 1) & 1;
5659 value
= (value
>> 2) & 0x00ffffff;
5660 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5661 newval
= value
| (newval
& 0xfe000000) | (hbit
<< 24);
5662 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5666 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5667 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5669 addressT diff
= (newval
& 0xff) << 1;
5674 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5675 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5676 _("Branch out of range"));
5677 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5679 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5682 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5683 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5685 addressT diff
= (newval
& 0x7ff) << 1;
5690 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5691 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5692 _("Branch out of range"));
5693 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5695 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5698 case BFD_RELOC_THUMB_PCREL_BLX
:
5699 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5704 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5705 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5706 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5707 if (diff
& 0x400000)
5710 value
= fixP
->fx_offset
;
5713 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5714 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5715 _("Branch with link out of range"));
5717 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5718 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5719 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5720 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5725 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5726 md_number_to_chars (buf
, value
, 1);
5728 else if (!target_oabi
)
5730 value
= fixP
->fx_offset
;
5731 md_number_to_chars (buf
, value
, 1);
5737 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5738 md_number_to_chars (buf
, value
, 2);
5740 else if (!target_oabi
)
5742 value
= fixP
->fx_offset
;
5743 md_number_to_chars (buf
, value
, 2);
5749 case BFD_RELOC_ARM_GOT32
:
5750 case BFD_RELOC_ARM_GOTOFF
:
5751 md_number_to_chars (buf
, 0, 4);
5757 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5758 md_number_to_chars (buf
, value
, 4);
5760 else if (!target_oabi
)
5762 value
= fixP
->fx_offset
;
5763 md_number_to_chars (buf
, value
, 4);
5769 case BFD_RELOC_ARM_PLT32
:
5770 /* It appears the instruction is fully prepared at this point. */
5774 case BFD_RELOC_ARM_GOTPC
:
5775 md_number_to_chars (buf
, value
, 4);
5778 case BFD_RELOC_ARM_CP_OFF_IMM
:
5780 if (value
< -1023 || value
> 1023 || (value
& 3))
5781 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5782 _("Illegal value for co-processor offset"));
5785 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5786 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5787 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5790 case BFD_RELOC_ARM_THUMB_OFFSET
:
5791 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5792 /* Exactly what ranges, and where the offset is inserted depends on
5793 the type of instruction, we can establish this from the top 4 bits */
5794 switch (newval
>> 12)
5796 case 4: /* PC load */
5797 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5798 forced to zero for these loads, so we will need to round
5799 up the offset if the instruction address is not word
5800 aligned (since the final address produced must be, and
5801 we can only describe word-aligned immediate offsets). */
5803 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5804 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5805 _("Invalid offset, target not word aligned (0x%08X)"),
5806 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5808 if ((value
+ 2) & ~0x3fe)
5809 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5810 _("Invalid offset, value too big (0x%08X)"), value
);
5812 /* Round up, since pc will be rounded down. */
5813 newval
|= (value
+ 2) >> 2;
5816 case 9: /* SP load/store */
5818 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5819 _("Invalid offset, value too big (0x%08X)"), value
);
5820 newval
|= value
>> 2;
5823 case 6: /* Word load/store */
5825 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5826 _("Invalid offset, value too big (0x%08X)"), value
);
5827 newval
|= value
<< 4; /* 6 - 2 */
5830 case 7: /* Byte load/store */
5832 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5833 _("Invalid offset, value too big (0x%08X)"), value
);
5834 newval
|= value
<< 6;
5837 case 8: /* Halfword load/store */
5839 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5840 _("Invalid offset, value too big (0x%08X)"), value
);
5841 newval
|= value
<< 5; /* 6 - 1 */
5845 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5846 "Unable to process relocation for thumb opcode: %lx",
5847 (unsigned long) newval
);
5850 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5853 case BFD_RELOC_ARM_THUMB_ADD
:
5854 /* This is a complicated relocation, since we use it for all of
5855 the following immediate relocations:
5858 9bit ADD/SUB SP word-aligned
5859 10bit ADD PC/SP word-aligned
5861 The type of instruction being processed is encoded in the
5867 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5869 int rd
= (newval
>> 4) & 0xf;
5870 int rs
= newval
& 0xf;
5871 int subtract
= newval
& 0x8000;
5876 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5877 _("Invalid immediate for stack address calculation"));
5878 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5879 newval
|= value
>> 2;
5881 else if (rs
== REG_PC
|| rs
== REG_SP
)
5885 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5886 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5887 (unsigned long) value
);
5888 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5890 newval
|= value
>> 2;
5895 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5896 _("Invalid 8bit immediate"));
5897 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5898 newval
|= (rd
<< 8) | value
;
5903 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5904 _("Invalid 3bit immediate"));
5905 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5906 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5909 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5912 case BFD_RELOC_ARM_THUMB_IMM
:
5913 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5914 switch (newval
>> 11)
5916 case 0x04: /* 8bit immediate MOV */
5917 case 0x05: /* 8bit immediate CMP */
5918 if (value
< 0 || value
> 255)
5919 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5920 _("Invalid immediate: %ld is too large"),
5928 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5931 case BFD_RELOC_ARM_THUMB_SHIFT
:
5932 /* 5bit shift value (0..31) */
5933 if (value
< 0 || value
> 31)
5934 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5935 _("Illegal Thumb shift value: %ld"), (long) value
);
5936 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5937 newval
|= value
<< 6;
5938 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5941 case BFD_RELOC_VTABLE_INHERIT
:
5942 case BFD_RELOC_VTABLE_ENTRY
:
5946 case BFD_RELOC_NONE
:
5948 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5949 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5955 /* Translate internal representation of relocation info to BFD target
5958 tc_gen_reloc (section
, fixp
)
5959 asection
* section ATTRIBUTE_UNUSED
;
5963 bfd_reloc_code_real_type code
;
5965 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5967 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5968 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5969 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5971 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5973 if (fixp
->fx_pcrel
== 0)
5974 reloc
->addend
= fixp
->fx_offset
;
5976 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5978 reloc
->addend
= fixp
->fx_offset
;
5981 switch (fixp
->fx_r_type
)
5986 code
= BFD_RELOC_8_PCREL
;
5993 code
= BFD_RELOC_16_PCREL
;
6000 code
= BFD_RELOC_32_PCREL
;
6004 case BFD_RELOC_ARM_PCREL_BRANCH
:
6005 case BFD_RELOC_ARM_PCREL_BLX
:
6007 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
6008 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
6009 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
6010 case BFD_RELOC_THUMB_PCREL_BLX
:
6011 case BFD_RELOC_VTABLE_ENTRY
:
6012 case BFD_RELOC_VTABLE_INHERIT
:
6013 code
= fixp
->fx_r_type
;
6016 case BFD_RELOC_ARM_LITERAL
:
6017 case BFD_RELOC_ARM_HWLITERAL
:
6018 /* If this is called then the a literal has been referenced across
6019 a section boundary - possibly due to an implicit dump */
6020 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6021 _("Literal referenced across section boundary (Implicit dump?)"));
6025 case BFD_RELOC_ARM_GOT32
:
6026 case BFD_RELOC_ARM_GOTOFF
:
6027 case BFD_RELOC_ARM_PLT32
:
6028 code
= fixp
->fx_r_type
;
6032 case BFD_RELOC_ARM_IMMEDIATE
:
6033 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6034 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6038 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
6039 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6040 _("ADRL used for a symbol not defined in the same file"),
6044 case BFD_RELOC_ARM_OFFSET_IMM
:
6045 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6046 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6053 switch (fixp
->fx_r_type
)
6055 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
6056 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
6057 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
6058 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
6059 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
6060 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
6061 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
6062 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
6063 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
6064 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
6065 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
6066 default: type
= _("<unknown>"); break;
6068 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6069 _("Can not represent %s relocation in this object file format (%d)"),
6070 type
, fixp
->fx_pcrel
);
6076 if (code
== BFD_RELOC_32_PCREL
6078 && fixp
->fx_addsy
== GOT_symbol
)
6080 code
= BFD_RELOC_ARM_GOTPC
;
6081 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6085 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6087 if (reloc
->howto
== NULL
)
6089 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6090 _("Can not represent %s relocation in this object file format"),
6091 bfd_get_reloc_code_name (code
));
6095 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6096 vtable entry to be used in the relocation's section offset. */
6097 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6098 reloc
->address
= fixp
->fx_offset
;
6104 md_estimate_size_before_relax (fragP
, segtype
)
6105 fragS
* fragP ATTRIBUTE_UNUSED
;
6106 segT segtype ATTRIBUTE_UNUSED
;
6108 as_fatal (_("md_estimate_size_before_relax\n"));
6113 output_inst
PARAMS ((void))
6119 as_bad (inst
.error
);
6123 to
= frag_more (inst
.size
);
6125 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6127 assert (inst
.size
== (2 * THUMB_SIZE
));
6128 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6129 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6131 else if (inst
.size
> INSN_SIZE
)
6133 assert (inst
.size
== (2 * INSN_SIZE
));
6134 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6135 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6138 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6140 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6141 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6142 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6157 /* Align the instruction.
6158 This may not be the right thing to do but ... */
6159 /* arm_align (2, 0); */
6160 listing_prev_line (); /* Defined in listing.h */
6162 /* Align the previous label if needed. */
6163 if (last_label_seen
!= NULL
)
6165 symbol_set_frag (last_label_seen
, frag_now
);
6166 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6167 S_SET_SEGMENT (last_label_seen
, now_seg
);
6170 memset (&inst
, '\0', sizeof (inst
));
6171 inst
.reloc
.type
= BFD_RELOC_NONE
;
6173 skip_whitespace (str
);
6175 /* Scan up to the end of the op-code, which must end in white space or
6177 for (start
= p
= str
; *p
!= '\0'; p
++)
6183 as_bad (_("No operator -- statement `%s'\n"), str
);
6189 CONST
struct thumb_opcode
* opcode
;
6193 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6198 /* Check that this instruction is supported for this CPU. */
6199 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
6201 as_bad (_("selected processor does not support this opcode"));
6205 inst
.instruction
= opcode
->value
;
6206 inst
.size
= opcode
->size
;
6207 (*opcode
->parms
)(p
);
6214 CONST
struct asm_opcode
* opcode
;
6215 unsigned long cond_code
;
6217 inst
.size
= INSN_SIZE
;
6218 /* p now points to the end of the opcode, probably white space, but we
6219 have to break the opcode up in case it contains condionals and flags;
6220 keep trying with progressively smaller basic instructions until one
6221 matches, or we run out of opcode. */
6222 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6224 for (; q
!= str
; q
--)
6229 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6232 if (opcode
&& opcode
->template)
6234 unsigned long flag_bits
= 0;
6237 /* Check that this instruction is supported for this CPU. */
6238 if ((opcode
->variants
& cpu_variant
) == 0)
6241 inst
.instruction
= opcode
->value
;
6242 if (q
== p
) /* Just a simple opcode. */
6244 if (opcode
->comp_suffix
)
6246 if (*opcode
->comp_suffix
!= '\0')
6247 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6248 str
, opcode
->comp_suffix
);
6250 /* Not a conditional instruction. */
6251 (*opcode
->parms
)(q
, 0);
6255 /* A conditional instruction with default condition. */
6256 inst
.instruction
|= COND_ALWAYS
;
6257 (*opcode
->parms
)(q
, 0);
6263 /* Not just a simple opcode. Check if extra is a conditional. */
6267 CONST
struct asm_cond
*cond
;
6271 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6275 if (cond
->value
== 0xf0000000)
6277 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6279 cond_code
= cond
->value
;
6283 cond_code
= COND_ALWAYS
;
6286 cond_code
= COND_ALWAYS
;
6288 /* Apply the conditional, or complain it's not allowed. */
6289 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
6291 /* Instruction isn't conditional */
6292 if (cond_code
!= COND_ALWAYS
)
6294 as_bad (_("Opcode `%s' is unconditional\n"), str
);
6299 /* Instruction is conditional: set the condition into it. */
6300 inst
.instruction
|= cond_code
;
6303 /* If there is a compulsory suffix, it should come here, before
6304 any optional flags. */
6305 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
6307 CONST
char *s
= opcode
->comp_suffix
;
6319 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6320 opcode
->comp_suffix
);
6327 /* The remainder, if any should now be flags for the instruction;
6328 Scan these checking each one found with the opcode. */
6332 CONST
struct asm_flg
*flag
= opcode
->flags
;
6341 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6343 if (streq (r
, flag
[flagno
].template))
6345 flag_bits
|= flag
[flagno
].set_bits
;
6351 if (! flag
[flagno
].template)
6358 (*opcode
->parms
) (p
, flag_bits
);
6368 /* It wasn't an instruction, but it might be a register alias of the form
6371 skip_whitespace (q
);
6376 if (*q
&& !strncmp (q
, ".req ", 4))
6379 char * copy_of_str
= str
;
6383 skip_whitespace (q
);
6385 for (r
= q
; *r
!= '\0'; r
++)
6395 regnum
= arm_reg_parse (& q
);
6398 reg
= arm_reg_parse (& str
);
6403 insert_reg_alias (str
, regnum
);
6405 as_warn (_("register '%s' does not exist\n"), q
);
6407 else if (regnum
!= FAIL
)
6410 as_warn (_("ignoring redefinition of register alias '%s'"),
6413 /* Do not warn about redefinitions to the same alias. */
6416 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6420 as_warn (_("ignoring incomplete .req pseuso op"));
6427 as_bad (_("bad instruction `%s'"), start
);
6432 * Invocation line includes a switch not recognized by the base assembler.
6433 * See if it's a processor-specific option. These are:
6434 * Cpu variants, the arm part is optional:
6435 * -m[arm]1 Currently not supported.
6436 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6437 * -m[arm]3 Arm 3 processor
6438 * -m[arm]6[xx], Arm 6 processors
6439 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6440 * -m[arm]8[10] Arm 8 processors
6441 * -m[arm]9[20][tdmi] Arm 9 processors
6442 * -mstrongarm[110[0]] StrongARM processors
6443 * -m[arm]v[2345[t]] Arm architectures
6444 * -mall All (except the ARM1)
6446 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6447 * -mfpe-old (No float load/store multiples)
6448 * -mno-fpu Disable all floating point instructions
6449 * Run-time endian selection:
6450 * -EB big endian cpu
6451 * -EL little endian cpu
6452 * ARM Procedure Calling Standard:
6453 * -mapcs-32 32 bit APCS
6454 * -mapcs-26 26 bit APCS
6455 * -mapcs-float Pass floats in float regs
6456 * -mapcs-reentrant Position independent code
6457 * -mthumb-interwork Code supports Arm/Thumb interworking
6458 * -moabi Old ELF ABI
6461 CONST
char * md_shortopts
= "m:k";
6462 struct option md_longopts
[] =
6464 #ifdef ARM_BI_ENDIAN
6465 #define OPTION_EB (OPTION_MD_BASE + 0)
6466 {"EB", no_argument
, NULL
, OPTION_EB
},
6467 #define OPTION_EL (OPTION_MD_BASE + 1)
6468 {"EL", no_argument
, NULL
, OPTION_EL
},
6470 #define OPTION_OABI (OPTION_MD_BASE +2)
6471 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6474 {NULL
, no_argument
, NULL
, 0}
6476 size_t md_longopts_size
= sizeof (md_longopts
);
6479 md_parse_option (c
, arg
)
6487 #ifdef ARM_BI_ENDIAN
6489 target_big_endian
= 1;
6492 target_big_endian
= 0;
6500 if (streq (str
, "fpa10"))
6501 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6502 else if (streq (str
, "fpa11"))
6503 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6504 else if (streq (str
, "fpe-old"))
6505 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6511 if (streq (str
, "no-fpu"))
6512 cpu_variant
&= ~FPU_ALL
;
6517 if (streq (str
, "oabi"))
6523 /* Limit assembler to generating only Thumb instructions: */
6524 if (streq (str
, "thumb"))
6526 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6527 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6530 else if (streq (str
, "thumb-interwork"))
6532 if ((cpu_variant
& ARM_THUMB
) == 0)
6533 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
6534 #if defined OBJ_COFF || defined OBJ_ELF
6535 support_interwork
= true;
6543 if (streq (str
, "all"))
6545 cpu_variant
= ARM_ALL
| FPU_ALL
;
6548 #if defined OBJ_COFF || defined OBJ_ELF
6549 if (! strncmp (str
, "apcs-", 5))
6551 /* GCC passes on all command line options starting "-mapcs-..."
6552 to us, so we must parse them here. */
6556 if (streq (str
, "32"))
6558 uses_apcs_26
= false;
6561 else if (streq (str
, "26"))
6563 uses_apcs_26
= true;
6566 else if (streq (str
, "frame"))
6568 /* Stack frames are being generated - does not affect
6572 else if (streq (str
, "stack-check"))
6574 /* Stack checking is being performed - does not affect
6575 linkage, but does require that the functions
6576 __rt_stkovf_split_small and __rt_stkovf_split_big be
6577 present in the final link. */
6581 else if (streq (str
, "float"))
6583 /* Floating point arguments are being passed in the floating
6584 point registers. This does affect linking, since this
6585 version of the APCS is incompatible with the version that
6586 passes floating points in the integer registers. */
6588 uses_apcs_float
= true;
6591 else if (streq (str
, "reentrant"))
6593 /* Reentrant code has been generated. This does affect
6594 linking, since there is no point in linking reentrant/
6595 position independent code with absolute position code. */
6600 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6604 /* Strip off optional "arm" */
6605 if (! strncmp (str
, "arm", 3))
6611 if (streq (str
, "1"))
6612 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6618 if (streq (str
, "2"))
6619 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6620 else if (streq (str
, "250"))
6621 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6627 if (streq (str
, "3"))
6628 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6634 switch (strtol (str
, NULL
, 10))
6641 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6649 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6662 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6668 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6672 cpu_variant
|= ARM_LONGMUL
;
6675 case 'f': /* fe => fp enabled cpu. */
6681 case 'c': /* Left over from 710c processor name. */
6682 case 'd': /* Debug */
6683 case 'i': /* Embedded ICE */
6684 /* Included for completeness in ARM processor naming. */
6694 if (streq (str
, "8") || streq (str
, "810"))
6695 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6696 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6702 if (streq (str
, "9"))
6703 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6704 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6705 else if (streq (str
, "920"))
6706 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6707 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6708 else if (streq (str
, "920t"))
6709 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6710 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6711 else if (streq (str
, "9tdmi"))
6712 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6713 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6720 if (streq (str
, "strongarm")
6721 || streq (str
, "strongarm110")
6722 || streq (str
, "strongarm1100"))
6723 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6724 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6730 /* Select variant based on architecture rather than processor. */
6737 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6740 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6743 as_bad (_("Invalid architecture variant -m%s"), arg
);
6749 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6753 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6756 as_bad (_("Invalid architecture variant -m%s"), arg
);
6762 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
6766 case 't': cpu_variant
|= ARM_THUMB
; break;
6769 as_bad (_("Invalid architecture variant -m%s"), arg
);
6775 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
6778 case 't': cpu_variant
|= ARM_THUMB
; break;
6781 as_bad (_("Invalid architecture variant -m%s"), arg
);
6787 as_bad (_("Invalid architecture variant -m%s"), arg
);
6794 as_bad (_("Invalid processor variant -m%s"), arg
);
6800 #if defined OBJ_ELF || defined OBJ_COFF
6818 ARM Specific Assembler Options:\n\
6819 -m[arm][<processor name>] select processor variant\n\
6820 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
6821 -mthumb only allow Thumb instructions\n\
6822 -mthumb-interwork mark the assembled code as supporting interworking\n\
6823 -mall allow any instruction\n\
6824 -mfpa10, -mfpa11 select floating point architecture\n\
6825 -mfpe-old don't allow floating-point multiple instructions\n\
6826 -mno-fpu don't allow any floating-point instructions.\n\
6827 -k generate PIC code.\n"));
6828 #if defined OBJ_COFF || defined OBJ_ELF
6830 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
6831 -mapcs-float floating point args are passed in FP regs\n\
6832 -mapcs-reentrant the code is position independent/reentrant\n"));
6836 -moabi support the old ELF ABI\n"));
6838 #ifdef ARM_BI_ENDIAN
6840 -EB assemble code for a big endian cpu\n\
6841 -EL assemble code for a little endian cpu\n"));
6845 /* We need to be able to fix up arbitrary expressions in some statements.
6846 This is so that we can handle symbols that are an arbitrary distance from
6847 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6848 which returns part of an address in a form which will be valid for
6849 a data instruction. We do this by pushing the expression into a symbol
6850 in the expr_section, and creating a fix for that. */
6853 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6862 arm_fix_data
* arm_data
;
6870 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6874 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6879 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6880 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6881 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6882 arm_data
->thumb_mode
= thumb_mode
;
6888 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6890 cons_fix_new_arm (frag
, where
, size
, exp
)
6896 bfd_reloc_code_real_type type
;
6900 FIXME: @@ Should look at CPU word size. */
6907 type
= BFD_RELOC_16
;
6911 type
= BFD_RELOC_32
;
6914 type
= BFD_RELOC_64
;
6918 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6921 /* A good place to do this, although this was probably not intended
6922 for this kind of use. We need to dump the literal pool before
6923 references are made to a null symbol pointer. */
6927 if (current_poolP
== NULL
)
6930 subseg_set (text_section
, 0); /* Put it at the end of text section. */
6932 listing_prev_line ();
6936 arm_start_line_hook ()
6938 last_label_seen
= NULL
;
6942 arm_frob_label (sym
)
6945 last_label_seen
= sym
;
6947 ARM_SET_THUMB (sym
, thumb_mode
);
6949 #if defined OBJ_COFF || defined OBJ_ELF
6950 ARM_SET_INTERWORK (sym
, support_interwork
);
6953 if (label_is_thumb_function_name
)
6955 /* When the address of a Thumb function is taken the bottom
6956 bit of that address should be set. This will allow
6957 interworking between Arm and Thumb functions to work
6960 THUMB_SET_FUNC (sym
, 1);
6962 label_is_thumb_function_name
= false;
6966 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6970 arm_adjust_symtab ()
6975 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6977 if (ARM_IS_THUMB (sym
))
6979 if (THUMB_IS_FUNC (sym
))
6981 /* Mark the symbol as a Thumb function. */
6982 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6983 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6984 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6986 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6987 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6989 as_bad (_("%s: unexpected function type: %d"),
6990 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6992 else switch (S_GET_STORAGE_CLASS (sym
))
6995 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6998 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
7001 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
7003 default: /* do nothing */
7008 if (ARM_IS_INTERWORK (sym
))
7009 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
7016 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7018 if (ARM_IS_THUMB (sym
))
7020 elf_symbol_type
* elf_sym
;
7022 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
7023 bind
= ELF_ST_BIND (elf_sym
);
7025 /* If it's a .thumb_func, declare it as so,
7026 otherwise tag label as .code 16. */
7027 if (THUMB_IS_FUNC (sym
))
7028 elf_sym
->internal_elf_sym
.st_info
=
7029 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
7031 elf_sym
->internal_elf_sym
.st_info
=
7032 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
7041 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
7043 *input_line_pointer
= '/';
7044 input_line_pointer
+= 5;
7045 *input_line_pointer
= 0;
7053 arm_canonicalize_symbol_name (name
)
7058 if (thumb_mode
&& (len
= strlen (name
)) > 5
7059 && streq (name
+ len
- 5, "/data"))
7060 *(name
+ len
- 5) = 0;
7066 arm_validate_fix (fixP
)
7069 /* If the destination of the branch is a defined symbol which does not have
7070 the THUMB_FUNC attribute, then we must be calling a function which has
7071 the (interfacearm) attribute. We look for the Thumb entry point to that
7072 function and change the branch to refer to that function instead. */
7073 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
7074 && fixP
->fx_addsy
!= NULL
7075 && S_IS_DEFINED (fixP
->fx_addsy
)
7076 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
7078 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
7086 /* Relocations against Thumb function names must be left unadjusted,
7087 so that the linker can use this information to correctly set the
7088 bottom bit of their addresses. The MIPS version of this function
7089 also prevents relocations that are mips-16 specific, but I do not
7090 know why it does this.
7093 There is one other problem that ought to be addressed here, but
7094 which currently is not: Taking the address of a label (rather
7095 than a function) and then later jumping to that address. Such
7096 addresses also ought to have their bottom bit set (assuming that
7097 they reside in Thumb code), but at the moment they will not. */
7100 arm_fix_adjustable (fixP
)
7103 if (fixP
->fx_addsy
== NULL
)
7106 /* Prevent all adjustments to global symbols. */
7107 if (S_IS_EXTERN (fixP
->fx_addsy
))
7110 if (S_IS_WEAK (fixP
->fx_addsy
))
7113 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
7114 && fixP
->fx_subsy
== NULL
)
7117 /* We need the symbol name for the VTABLE entries */
7118 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7119 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7126 elf32_arm_target_format ()
7128 if (target_big_endian
)
7130 return "elf32-bigarm-oabi";
7132 return "elf32-bigarm";
7135 return "elf32-littlearm-oabi";
7137 return "elf32-littlearm";
7141 armelf_frob_symbol (symp
, puntp
)
7145 elf_frob_symbol (symp
, puntp
);
7149 arm_force_relocation (fixp
)
7152 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7153 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7154 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7155 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BLX
7156 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BLX
7157 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7163 static bfd_reloc_code_real_type
7173 bfd_reloc_code_real_type reloc
;
7177 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7178 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7179 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7180 /* ScottB: Jan 30, 1998 */
7181 /* Added support for parsing "var(PLT)" branch instructions */
7182 /* generated by GCC for PLT relocs */
7183 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7184 { NULL
, 0, BFD_RELOC_UNUSED
}
7188 for (i
= 0, ip
= input_line_pointer
;
7189 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7191 id
[i
] = tolower (*ip
);
7193 for (i
= 0; reloc_map
[i
].str
; i
++)
7194 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7197 input_line_pointer
+= reloc_map
[i
].len
;
7199 return reloc_map
[i
].reloc
;
7203 s_arm_elf_cons (nbytes
)
7208 #ifdef md_flush_pending_output
7209 md_flush_pending_output ();
7212 if (is_it_end_of_statement ())
7214 demand_empty_rest_of_line ();
7218 #ifdef md_cons_align
7219 md_cons_align (nbytes
);
7224 bfd_reloc_code_real_type reloc
;
7228 if (exp
.X_op
== O_symbol
7229 && * input_line_pointer
== '('
7230 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
7232 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7233 int size
= bfd_get_reloc_size (howto
);
7236 as_bad ("%s relocations do not fit in %d bytes",
7237 howto
->name
, nbytes
);
7240 register char * p
= frag_more ((int) nbytes
);
7241 int offset
= nbytes
- size
;
7243 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7248 emit_expr (& exp
, (unsigned int) nbytes
);
7250 while (*input_line_pointer
++ == ',');
7252 input_line_pointer
--; /* Put terminator back into stream. */
7253 demand_empty_rest_of_line ();
7256 #endif /* OBJ_ELF */