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 */
55 #define ARM_EXT_V5E 0x00000200 /* "El Segundo" */
57 /* Architectures are the sum of the base and extensions. */
58 #define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
59 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
60 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
61 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
63 /* Some useful combinations: */
64 #define ARM_ANY 0x00ffffff
65 #define ARM_2UP (ARM_ANY - ARM_1)
66 #define ARM_ALL ARM_2UP /* Not arm1 only */
67 #define ARM_3UP 0x00fffffc
68 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
70 #define FPU_CORE 0x80000000
71 #define FPU_FPA10 0x40000000
72 #define FPU_FPA11 0x40000000
75 /* Some useful combinations */
76 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
77 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
82 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
84 #define CPU_DEFAULT ARM_ALL
89 #define FPU_DEFAULT FPU_ALL
92 #define streq(a, b) (strcmp (a, b) == 0)
93 #define skip_whitespace(str) while (* (str) == ' ') ++ (str)
95 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
96 static int target_oabi
= 0;
98 #if defined OBJ_COFF || defined OBJ_ELF
99 /* Flags stored in private area of BFD structure */
100 static boolean uses_apcs_26
= false;
101 static boolean support_interwork
= false;
102 static boolean uses_apcs_float
= false;
103 static boolean pic_code
= false;
106 /* This array holds the chars that always start a comment. If the
107 pre-processor is disabled, these aren't very useful. */
108 CONST
char comment_chars
[] = "@";
110 /* This array holds the chars that only start a comment at the beginning of
111 a line. If the line seems to have the form '# 123 filename'
112 .line and .file directives will appear in the pre-processed output. */
113 /* Note that input_file.c hand checks for '#' at the beginning of the
114 first line of the input file. This is because the compiler outputs
115 #NO_APP at the beginning of its output. */
116 /* Also note that comments like this one will always work. */
117 CONST
char line_comment_chars
[] = "#";
120 CONST
char line_separator_chars
[] = ";";
122 CONST
char line_separator_chars
[] = "";
125 /* Chars that can be used to separate mant
126 from exp in floating point numbers. */
127 CONST
char EXP_CHARS
[] = "eE";
129 /* Chars that mean this number is a floating point constant */
133 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
135 /* Prefix characters that indicate the start of an immediate
137 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
140 symbolS
* GOT_symbol
; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
143 CONST
int md_reloc_size
= 8; /* Size of relocation record */
145 static int thumb_mode
= 0; /* 0: assemble for ARM, 1: assemble for Thumb,
146 2: assemble for Thumb even though target cpu
147 does not support thumb instructions. */
148 typedef struct arm_fix
156 unsigned long instruction
;
161 bfd_reloc_code_real_type type
;
171 CONST
char * template;
175 static CONST
struct asm_shift shift
[] =
191 #define NO_SHIFT_RESTRICT 1
192 #define SHIFT_RESTRICT 0
194 #define NUM_FLOAT_VALS 8
196 CONST
char * fp_const
[] =
198 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
201 /* Number of littlenums required to hold an extended precision number. */
202 #define MAX_LITTLENUMS 6
204 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
214 #define CP_T_X 0x00008000
215 #define CP_T_Y 0x00400000
216 #define CP_T_Pre 0x01000000
217 #define CP_T_UD 0x00800000
218 #define CP_T_WB 0x00200000
220 #define CONDS_BIT (0x00100000)
221 #define LOAD_BIT (0x00100000)
222 #define TRANS_BIT (0x00200000)
226 CONST
char * template;
230 /* This is to save a hash look-up in the common case. */
231 #define COND_ALWAYS 0xe0000000
233 static CONST
struct asm_cond conds
[] =
237 {"cs", 0x20000000}, {"hs", 0x20000000},
238 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
253 /* Warning: If the top bit of the set_bits is set, then the standard
254 instruction bitmask is ignored, and the new bitmask is taken from
258 CONST
char * template; /* Basic flag string */
259 unsigned long set_bits
; /* Bits to set */
262 static CONST
struct asm_flg s_flag
[] =
268 static CONST
struct asm_flg ldr_flags
[] =
272 {"bt", 0x00400000 | TRANS_BIT
},
279 static CONST
struct asm_flg str_flags
[] =
283 {"bt", 0x00400000 | TRANS_BIT
},
288 static CONST
struct asm_flg byte_flag
[] =
294 static CONST
struct asm_flg cmp_flags
[] =
301 static CONST
struct asm_flg ldm_flags
[] =
314 static CONST
struct asm_flg stm_flags
[] =
327 static CONST
struct asm_flg lfm_flags
[] =
334 static CONST
struct asm_flg sfm_flags
[] =
341 static CONST
struct asm_flg round_flags
[] =
349 /* The implementation of the FIX instruction is broken on some assemblers,
350 in that it accepts a precision specifier as well as a rounding specifier,
351 despite the fact that this is meaningless. To be more compatible, we
352 accept it as well, though of course it does not set any bits. */
353 static CONST
struct asm_flg fix_flags
[] =
370 static CONST
struct asm_flg except_flag
[] =
376 static CONST
struct asm_flg cplong_flag
[] =
384 CONST
char * template;
389 #define SPSR_BIT (1 << 22) /* The bit that distnguishes CPSR and SPSR. */
390 #define PSR_SHIFT 16 /* How many bits to shift the PSR_xxx bits up by. */
392 #define PSR_c (1 << 0)
393 #define PSR_x (1 << 1)
394 #define PSR_s (1 << 2)
395 #define PSR_f (1 << 3)
397 static CONST
struct asm_psr psrs
[] =
399 {"CPSR", true, PSR_c
| PSR_f
},
400 {"CPSR_all", true, PSR_c
| PSR_f
},
401 {"SPSR", false, PSR_c
| PSR_f
},
402 {"SPSR_all", false, PSR_c
| PSR_f
},
403 {"CPSR_flg", true, PSR_f
},
404 {"CPSR_f", true, PSR_f
},
405 {"SPSR_flg", false, PSR_f
},
406 {"SPSR_f", false, PSR_f
},
407 {"CPSR_c", true, PSR_c
},
408 {"CPSR_ctl", true, PSR_c
},
409 {"SPSR_c", false, PSR_c
},
410 {"SPSR_ctl", false, PSR_c
},
411 {"CPSR_x", true, PSR_x
},
412 {"CPSR_s", true, PSR_s
},
413 {"SPSR_x", false, PSR_x
},
414 {"SPSR_s", false, PSR_s
},
415 /* For backwards compatability with older toolchain we also
416 support lower case versions of some of these flags. */
417 {"cpsr", true, PSR_c
| PSR_f
},
418 {"cpsr_all", true, PSR_c
| PSR_f
},
419 {"spsr", false, PSR_c
| PSR_f
},
420 {"spsr_all", false, PSR_c
| PSR_f
},
421 {"cpsr_flg", true, PSR_f
},
422 {"cpsr_f", true, PSR_f
},
423 {"spsr_flg", false, PSR_f
},
424 {"spsr_f", false, PSR_f
},
425 {"cpsr_c", true, PSR_c
},
426 {"cpsr_ctl", true, PSR_c
},
427 {"spsr_c", false, PSR_c
},
428 {"spsr_ctl", false, PSR_c
}
431 /* Functions called by parser. */
432 /* ARM instructions */
433 static void do_arit
PARAMS ((char *, unsigned long));
434 static void do_cmp
PARAMS ((char *, unsigned long));
435 static void do_mov
PARAMS ((char *, unsigned long));
436 static void do_ldst
PARAMS ((char *, unsigned long));
437 static void do_ldmstm
PARAMS ((char *, unsigned long));
438 static void do_branch
PARAMS ((char *, unsigned long));
439 static void do_swi
PARAMS ((char *, unsigned long));
440 /* Pseudo Op codes */
441 static void do_adr
PARAMS ((char *, unsigned long));
442 static void do_adrl
PARAMS ((char *, unsigned long));
443 static void do_nop
PARAMS ((char *, unsigned long));
445 static void do_mul
PARAMS ((char *, unsigned long));
446 static void do_mla
PARAMS ((char *, unsigned long));
448 static void do_swap
PARAMS ((char *, unsigned long));
450 static void do_msr
PARAMS ((char *, unsigned long));
451 static void do_mrs
PARAMS ((char *, unsigned long));
453 static void do_mull
PARAMS ((char *, unsigned long));
455 static void do_bx
PARAMS ((char *, unsigned long));
458 /* Coprocessor Instructions */
459 static void do_cdp
PARAMS ((char *, unsigned long));
460 static void do_lstc
PARAMS ((char *, unsigned long));
461 static void do_co_reg
PARAMS ((char *, unsigned long));
462 static void do_fp_ctrl
PARAMS ((char *, unsigned long));
463 static void do_fp_ldst
PARAMS ((char *, unsigned long));
464 static void do_fp_ldmstm
PARAMS ((char *, unsigned long));
465 static void do_fp_dyadic
PARAMS ((char *, unsigned long));
466 static void do_fp_monadic
PARAMS ((char *, unsigned long));
467 static void do_fp_cmp
PARAMS ((char *, unsigned long));
468 static void do_fp_from_reg
PARAMS ((char *, unsigned long));
469 static void do_fp_to_reg
PARAMS ((char *, unsigned long));
471 static void fix_new_arm
PARAMS ((fragS
*, int, short, expressionS
*, int, int));
472 static int arm_reg_parse
PARAMS ((char **));
473 static CONST
struct asm_psr
* arm_psr_parse
PARAMS ((char **));
474 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
, valueT
, fragS
*));
475 static int add_to_lit_pool
PARAMS ((void));
476 static unsigned validate_immediate
PARAMS ((unsigned));
477 static unsigned validate_immediate_twopart
PARAMS ((unsigned int, unsigned int *));
478 static int validate_offset_imm
PARAMS ((unsigned int, int));
479 static void opcode_select
PARAMS ((int));
480 static void end_of_line
PARAMS ((char *));
481 static int reg_required_here
PARAMS ((char **, int));
482 static int psr_required_here
PARAMS ((char **));
483 static int co_proc_number
PARAMS ((char **));
484 static int cp_opc_expr
PARAMS ((char **, int, int));
485 static int cp_reg_required_here
PARAMS ((char **, int));
486 static int fp_reg_required_here
PARAMS ((char **, int));
487 static int cp_address_offset
PARAMS ((char **));
488 static int cp_address_required_here
PARAMS ((char **));
489 static int my_get_float_expression
PARAMS ((char **));
490 static int skip_past_comma
PARAMS ((char **));
491 static int walk_no_bignums
PARAMS ((symbolS
*));
492 static int negate_data_op
PARAMS ((unsigned long *, unsigned long));
493 static int data_op2
PARAMS ((char **));
494 static int fp_op2
PARAMS ((char **));
495 static long reg_list
PARAMS ((char **));
496 static void thumb_load_store
PARAMS ((char *, int, int));
497 static int decode_shift
PARAMS ((char **, int));
498 static int ldst_extend
PARAMS ((char **, int));
499 static void thumb_add_sub
PARAMS ((char *, int));
500 static void insert_reg
PARAMS ((int));
501 static void thumb_shift
PARAMS ((char *, int));
502 static void thumb_mov_compare
PARAMS ((char *, int));
503 static void set_constant_flonums
PARAMS ((void));
504 static valueT md_chars_to_number
PARAMS ((char *, int));
505 static void insert_reg_alias
PARAMS ((char *, int));
506 static void output_inst
PARAMS ((void));
508 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
511 /* ARM instructions take 4bytes in the object file, Thumb instructions
515 /* LONGEST_INST is the longest basic instruction name without conditions or
516 flags. ARM7M has 4 of length 5. */
518 #define LONGEST_INST 5
523 CONST
char * template; /* Basic string to match */
524 unsigned long value
; /* Basic instruction code */
526 /* Compulsory suffix that must follow conds. If "", then the
527 instruction is not conditional and must have no suffix. */
528 CONST
char * comp_suffix
;
530 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
531 unsigned long variants
; /* Which CPU variants this exists for */
532 /* Function to call to parse args */
533 void (* parms
) PARAMS ((char *, unsigned long));
536 static CONST
struct asm_opcode insns
[] =
538 /* ARM Instructions */
539 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
540 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
541 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
542 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
543 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
544 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
545 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
546 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
547 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
548 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
549 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
550 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
551 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
552 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
553 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
554 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
555 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
556 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
557 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
558 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
559 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
561 {"bl", 0x0b000000, NULL
, NULL
, ARM_ANY
, do_branch
},
562 {"b", 0x0a000000, NULL
, NULL
, ARM_ANY
, do_branch
},
564 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
565 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
569 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
570 {"adrl", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adrl
},
571 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
573 /* ARM 2 multiplies */
574 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
575 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
577 /* ARM 3 - swp instructions */
578 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
580 /* ARM 6 Coprocessor instructions */
581 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
582 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
583 /* ScottB: our code uses 0x0128f000 for msr.
584 NickC: but this is wrong because the bits 16 through 19 are
585 handled by the PSR_xxx defines above. */
587 /* ARM 7M long multiplies - need signed/unsigned flags! */
588 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
589 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
590 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
591 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
593 /* ARM THUMB interworking */
594 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
596 /* Floating point instructions */
597 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
598 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
599 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
600 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
601 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
602 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
603 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
604 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
605 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
606 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
607 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
608 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
609 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
610 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
611 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
612 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
613 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
614 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
615 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
616 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
617 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
618 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
619 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
620 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
621 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
622 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
623 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
624 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
625 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
626 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
627 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
628 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
629 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
630 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
631 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
632 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
633 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
634 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
635 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
636 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
637 be an optional suffix, but part of the instruction. To be compatible,
639 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
640 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
641 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
642 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
644 /* Generic copressor instructions. */
645 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
646 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
647 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
648 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
649 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
652 /* Defines for various bits that we will want to toggle. */
653 #define INST_IMMEDIATE 0x02000000
654 #define OFFSET_REG 0x02000000
655 #define HWOFFSET_IMM 0x00400000
656 #define SHIFT_BY_REG 0x00000010
657 #define PRE_INDEX 0x01000000
658 #define INDEX_UP 0x00800000
659 #define WRITE_BACK 0x00200000
660 #define LDM_TYPE_2_OR_3 0x00400000
662 #define LITERAL_MASK 0xf000f000
663 #define COND_MASK 0xf0000000
664 #define OPCODE_MASK 0xfe1fffff
665 #define DATA_OP_SHIFT 21
667 /* Codes to distinguish the arithmetic instructions. */
678 #define OPCODE_CMP 10
679 #define OPCODE_CMN 11
680 #define OPCODE_ORR 12
681 #define OPCODE_MOV 13
682 #define OPCODE_BIC 14
683 #define OPCODE_MVN 15
685 static void do_t_nop
PARAMS ((char *));
686 static void do_t_arit
PARAMS ((char *));
687 static void do_t_add
PARAMS ((char *));
688 static void do_t_asr
PARAMS ((char *));
689 static void do_t_branch9
PARAMS ((char *));
690 static void do_t_branch12
PARAMS ((char *));
691 static void do_t_branch23
PARAMS ((char *));
692 static void do_t_bx
PARAMS ((char *));
693 static void do_t_compare
PARAMS ((char *));
694 static void do_t_ldmstm
PARAMS ((char *));
695 static void do_t_ldr
PARAMS ((char *));
696 static void do_t_ldrb
PARAMS ((char *));
697 static void do_t_ldrh
PARAMS ((char *));
698 static void do_t_lds
PARAMS ((char *));
699 static void do_t_lsl
PARAMS ((char *));
700 static void do_t_lsr
PARAMS ((char *));
701 static void do_t_mov
PARAMS ((char *));
702 static void do_t_push_pop
PARAMS ((char *));
703 static void do_t_str
PARAMS ((char *));
704 static void do_t_strb
PARAMS ((char *));
705 static void do_t_strh
PARAMS ((char *));
706 static void do_t_sub
PARAMS ((char *));
707 static void do_t_swi
PARAMS ((char *));
708 static void do_t_adr
PARAMS ((char *));
710 #define T_OPCODE_MUL 0x4340
711 #define T_OPCODE_TST 0x4200
712 #define T_OPCODE_CMN 0x42c0
713 #define T_OPCODE_NEG 0x4240
714 #define T_OPCODE_MVN 0x43c0
716 #define T_OPCODE_ADD_R3 0x1800
717 #define T_OPCODE_SUB_R3 0x1a00
718 #define T_OPCODE_ADD_HI 0x4400
719 #define T_OPCODE_ADD_ST 0xb000
720 #define T_OPCODE_SUB_ST 0xb080
721 #define T_OPCODE_ADD_SP 0xa800
722 #define T_OPCODE_ADD_PC 0xa000
723 #define T_OPCODE_ADD_I8 0x3000
724 #define T_OPCODE_SUB_I8 0x3800
725 #define T_OPCODE_ADD_I3 0x1c00
726 #define T_OPCODE_SUB_I3 0x1e00
728 #define T_OPCODE_ASR_R 0x4100
729 #define T_OPCODE_LSL_R 0x4080
730 #define T_OPCODE_LSR_R 0x40c0
731 #define T_OPCODE_ASR_I 0x1000
732 #define T_OPCODE_LSL_I 0x0000
733 #define T_OPCODE_LSR_I 0x0800
735 #define T_OPCODE_MOV_I8 0x2000
736 #define T_OPCODE_CMP_I8 0x2800
737 #define T_OPCODE_CMP_LR 0x4280
738 #define T_OPCODE_MOV_HR 0x4600
739 #define T_OPCODE_CMP_HR 0x4500
741 #define T_OPCODE_LDR_PC 0x4800
742 #define T_OPCODE_LDR_SP 0x9800
743 #define T_OPCODE_STR_SP 0x9000
744 #define T_OPCODE_LDR_IW 0x6800
745 #define T_OPCODE_STR_IW 0x6000
746 #define T_OPCODE_LDR_IH 0x8800
747 #define T_OPCODE_STR_IH 0x8000
748 #define T_OPCODE_LDR_IB 0x7800
749 #define T_OPCODE_STR_IB 0x7000
750 #define T_OPCODE_LDR_RW 0x5800
751 #define T_OPCODE_STR_RW 0x5000
752 #define T_OPCODE_LDR_RH 0x5a00
753 #define T_OPCODE_STR_RH 0x5200
754 #define T_OPCODE_LDR_RB 0x5c00
755 #define T_OPCODE_STR_RB 0x5400
757 #define T_OPCODE_PUSH 0xb400
758 #define T_OPCODE_POP 0xbc00
760 #define T_OPCODE_BRANCH 0xe7fe
762 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
764 #define THUMB_SIZE 2 /* Size of thumb instruction. */
765 #define THUMB_REG_LO 0x1
766 #define THUMB_REG_HI 0x2
767 #define THUMB_REG_ANY 0x3
769 #define THUMB_H1 0x0080
770 #define THUMB_H2 0x0040
777 #define THUMB_COMPARE 1
780 #define THUMB_STORE 1
782 #define THUMB_PP_PC_LR 0x0100
784 /* These three are used for immediate shifts, do not alter. */
786 #define THUMB_HALFWORD 1
791 CONST
char * template; /* Basic string to match */
792 unsigned long value
; /* Basic instruction code */
794 unsigned long variants
; /* Which CPU variants this exists for */
795 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
798 static CONST
struct thumb_opcode tinsns
[] =
800 {"adc", 0x4140, 2, ARM_THUMB
, do_t_arit
},
801 {"add", 0x0000, 2, ARM_THUMB
, do_t_add
},
802 {"and", 0x4000, 2, ARM_THUMB
, do_t_arit
},
803 {"asr", 0x0000, 2, ARM_THUMB
, do_t_asr
},
804 {"b", T_OPCODE_BRANCH
, 2, ARM_THUMB
, do_t_branch12
},
805 {"beq", 0xd0fe, 2, ARM_THUMB
, do_t_branch9
},
806 {"bne", 0xd1fe, 2, ARM_THUMB
, do_t_branch9
},
807 {"bcs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
808 {"bhs", 0xd2fe, 2, ARM_THUMB
, do_t_branch9
},
809 {"bcc", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
810 {"bul", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
811 {"blo", 0xd3fe, 2, ARM_THUMB
, do_t_branch9
},
812 {"bmi", 0xd4fe, 2, ARM_THUMB
, do_t_branch9
},
813 {"bpl", 0xd5fe, 2, ARM_THUMB
, do_t_branch9
},
814 {"bvs", 0xd6fe, 2, ARM_THUMB
, do_t_branch9
},
815 {"bvc", 0xd7fe, 2, ARM_THUMB
, do_t_branch9
},
816 {"bhi", 0xd8fe, 2, ARM_THUMB
, do_t_branch9
},
817 {"bls", 0xd9fe, 2, ARM_THUMB
, do_t_branch9
},
818 {"bge", 0xdafe, 2, ARM_THUMB
, do_t_branch9
},
819 {"blt", 0xdbfe, 2, ARM_THUMB
, do_t_branch9
},
820 {"bgt", 0xdcfe, 2, ARM_THUMB
, do_t_branch9
},
821 {"ble", 0xddfe, 2, ARM_THUMB
, do_t_branch9
},
822 {"bal", 0xdefe, 2, ARM_THUMB
, do_t_branch9
},
823 {"bic", 0x4380, 2, ARM_THUMB
, do_t_arit
},
824 {"bl", 0xf7fffffe, 4, ARM_THUMB
, do_t_branch23
},
825 {"bx", 0x4700, 2, ARM_THUMB
, do_t_bx
},
826 {"cmn", T_OPCODE_CMN
, 2, ARM_THUMB
, do_t_arit
},
827 {"cmp", 0x0000, 2, ARM_THUMB
, do_t_compare
},
828 {"eor", 0x4040, 2, ARM_THUMB
, do_t_arit
},
829 {"ldmia", 0xc800, 2, ARM_THUMB
, do_t_ldmstm
},
830 {"ldr", 0x0000, 2, ARM_THUMB
, do_t_ldr
},
831 {"ldrb", 0x0000, 2, ARM_THUMB
, do_t_ldrb
},
832 {"ldrh", 0x0000, 2, ARM_THUMB
, do_t_ldrh
},
833 {"ldrsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
834 {"ldrsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
835 {"ldsb", 0x5600, 2, ARM_THUMB
, do_t_lds
},
836 {"ldsh", 0x5e00, 2, ARM_THUMB
, do_t_lds
},
837 {"lsl", 0x0000, 2, ARM_THUMB
, do_t_lsl
},
838 {"lsr", 0x0000, 2, ARM_THUMB
, do_t_lsr
},
839 {"mov", 0x0000, 2, ARM_THUMB
, do_t_mov
},
840 {"mul", T_OPCODE_MUL
, 2, ARM_THUMB
, do_t_arit
},
841 {"mvn", T_OPCODE_MVN
, 2, ARM_THUMB
, do_t_arit
},
842 {"neg", T_OPCODE_NEG
, 2, ARM_THUMB
, do_t_arit
},
843 {"orr", 0x4300, 2, ARM_THUMB
, do_t_arit
},
844 {"pop", 0xbc00, 2, ARM_THUMB
, do_t_push_pop
},
845 {"push", 0xb400, 2, ARM_THUMB
, do_t_push_pop
},
846 {"ror", 0x41c0, 2, ARM_THUMB
, do_t_arit
},
847 {"sbc", 0x4180, 2, ARM_THUMB
, do_t_arit
},
848 {"stmia", 0xc000, 2, ARM_THUMB
, do_t_ldmstm
},
849 {"str", 0x0000, 2, ARM_THUMB
, do_t_str
},
850 {"strb", 0x0000, 2, ARM_THUMB
, do_t_strb
},
851 {"strh", 0x0000, 2, ARM_THUMB
, do_t_strh
},
852 {"swi", 0xdf00, 2, ARM_THUMB
, do_t_swi
},
853 {"sub", 0x0000, 2, ARM_THUMB
, do_t_sub
},
854 {"tst", T_OPCODE_TST
, 2, ARM_THUMB
, do_t_arit
},
856 {"adr", 0x0000, 2, ARM_THUMB
, do_t_adr
},
857 {"nop", 0x46C0, 2, ARM_THUMB
, do_t_nop
}, /* mov r8,r8 */
866 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
867 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
868 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
874 /* These are the standard names. Users can add aliases with .req */
875 static CONST
struct reg_entry reg_table
[] =
877 /* Processor Register Numbers. */
878 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
879 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
880 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
881 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
882 /* APCS conventions. */
883 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
884 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
885 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
886 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
887 /* ATPCS additions to APCS conventions. */
888 {"wr", 7}, {"v8", 11},
890 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
891 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
892 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
893 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
894 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
895 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
896 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
897 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
898 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
899 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
900 /* ATPCS additions to float register names. */
901 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
902 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
903 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
904 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
905 /* FIXME: At some point we need to add VFP register names. */
906 /* Array terminator. */
910 #define BAD_ARGS _("Bad arguments to instruction")
911 #define BAD_PC _("r15 not allowed here")
912 #define BAD_FLAGS _("Instruction should not have flags")
913 #define BAD_COND _("Instruction is not conditional")
915 static struct hash_control
* arm_ops_hsh
= NULL
;
916 static struct hash_control
* arm_tops_hsh
= NULL
;
917 static struct hash_control
* arm_cond_hsh
= NULL
;
918 static struct hash_control
* arm_shift_hsh
= NULL
;
919 static struct hash_control
* arm_reg_hsh
= NULL
;
920 static struct hash_control
* arm_psr_hsh
= NULL
;
922 /* This table describes all the machine specific pseudo-ops the assembler
923 has to support. The fields are:
924 pseudo-op name without dot
925 function to call to execute this pseudo-op
926 Integer arg to pass to the function. */
928 static void s_req
PARAMS ((int));
929 static void s_align
PARAMS ((int));
930 static void s_bss
PARAMS ((int));
931 static void s_even
PARAMS ((int));
932 static void s_ltorg
PARAMS ((int));
933 static void s_arm
PARAMS ((int));
934 static void s_thumb
PARAMS ((int));
935 static void s_code
PARAMS ((int));
936 static void s_force_thumb
PARAMS ((int));
937 static void s_thumb_func
PARAMS ((int));
938 static void s_thumb_set
PARAMS ((int));
939 static void arm_s_text
PARAMS ((int));
940 static void arm_s_data
PARAMS ((int));
942 static void arm_s_section
PARAMS ((int));
943 static void s_arm_elf_cons
PARAMS ((int));
946 static int my_get_expression
PARAMS ((expressionS
*, char **));
948 CONST pseudo_typeS md_pseudo_table
[] =
950 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
952 { "align", s_align
, 0 },
954 { "thumb", s_thumb
, 0 },
955 { "code", s_code
, 0 },
956 { "force_thumb", s_force_thumb
, 0 },
957 { "thumb_func", s_thumb_func
, 0 },
958 { "thumb_set", s_thumb_set
, 0 },
959 { "even", s_even
, 0 },
960 { "ltorg", s_ltorg
, 0 },
961 { "pool", s_ltorg
, 0 },
962 /* Allow for the effect of section changes. */
963 { "text", arm_s_text
, 0 },
964 { "data", arm_s_data
, 0 },
966 { "section", arm_s_section
, 0 },
967 { "section.s", arm_s_section
, 0 },
968 { "sect", arm_s_section
, 0 },
969 { "sect.s", arm_s_section
, 0 },
970 { "word", s_arm_elf_cons
, 4 },
971 { "long", s_arm_elf_cons
, 4 },
975 { "extend", float_cons
, 'x' },
976 { "ldouble", float_cons
, 'x' },
977 { "packed", float_cons
, 'p' },
981 /* Stuff needed to resolve the label ambiguity
991 symbolS
* last_label_seen
;
992 static int label_is_thumb_function_name
= false;
996 #define MAX_LITERAL_POOL_SIZE 1024
998 typedef struct literalS
1000 struct expressionS exp
;
1001 struct arm_it
* inst
;
1004 literalT literals
[MAX_LITERAL_POOL_SIZE
];
1005 int next_literal_pool_place
= 0; /* Next free entry in the pool */
1006 int lit_pool_num
= 1; /* Next literal pool number */
1007 symbolS
* current_poolP
= NULL
;
1014 if (current_poolP
== NULL
)
1015 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
1016 (valueT
) 0, &zero_address_frag
);
1018 /* Check if this literal value is already in the pool: */
1019 while (lit_count
< next_literal_pool_place
)
1021 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
1022 && inst
.reloc
.exp
.X_op
== O_constant
1023 && literals
[lit_count
].exp
.X_add_number
1024 == inst
.reloc
.exp
.X_add_number
1025 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
1030 if (lit_count
== next_literal_pool_place
) /* new entry */
1032 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
1034 inst
.error
= _("Literal Pool Overflow");
1038 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1039 lit_count
= next_literal_pool_place
++;
1042 inst
.reloc
.exp
.X_op
= O_symbol
;
1043 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1044 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1049 /* Can't use symbol_new here, so have to create a symbol and then at
1050 a later date assign it a value. Thats what these functions do. */
1052 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1054 CONST
char * name
; /* It is copied, the caller can modify */
1055 segT segment
; /* Segment identifier (SEG_<something>) */
1056 valueT valu
; /* Symbol value */
1057 fragS
* frag
; /* Associated fragment */
1059 unsigned int name_length
;
1060 char * preserved_copy_of_name
;
1062 name_length
= strlen (name
) + 1; /* +1 for \0 */
1063 obstack_grow (¬es
, name
, name_length
);
1064 preserved_copy_of_name
= obstack_finish (¬es
);
1065 #ifdef STRIP_UNDERSCORE
1066 if (preserved_copy_of_name
[0] == '_')
1067 preserved_copy_of_name
++;
1070 #ifdef tc_canonicalize_symbol_name
1071 preserved_copy_of_name
=
1072 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1075 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1077 S_SET_SEGMENT (symbolP
, segment
);
1078 S_SET_VALUE (symbolP
, valu
);
1079 symbol_clear_list_pointers(symbolP
);
1081 symbol_set_frag (symbolP
, frag
);
1083 /* Link to end of symbol chain. */
1085 extern int symbol_table_frozen
;
1086 if (symbol_table_frozen
)
1090 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1092 obj_symbol_new_hook (symbolP
);
1094 #ifdef tc_symbol_new_hook
1095 tc_symbol_new_hook (symbolP
);
1099 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1100 #endif /* DEBUG_SYMS */
1103 /* Check that an immediate is valid, and if so,
1104 convert it to the right format. */
1106 validate_immediate (val
)
1112 #define rotate_left(v, n) (v << n | v >> (32 - n))
1114 for (i
= 0; i
< 32; i
+= 2)
1115 if ((a
= rotate_left (val
, i
)) <= 0xff)
1116 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1121 /* Check to see if an immediate can be computed as two seperate immediate
1122 values, added together. We already know that this value cannot be
1123 computed by just one ARM instruction. */
1125 validate_immediate_twopart (val
, highpart
)
1127 unsigned int * highpart
;
1132 for (i
= 0; i
< 32; i
+= 2)
1133 if (((a
= rotate_left (val
, i
)) & 0xff) != 0)
1139 * highpart
= (a
>> 8) | ((i
+ 24) << 7);
1141 else if (a
& 0xff0000)
1146 * highpart
= (a
>> 16) | ((i
+ 16) << 7);
1150 assert (a
& 0xff000000);
1152 * highpart
= (a
>> 24) | ((i
+ 8) << 7);
1155 return (a
& 0xff) | (i
<< 7);
1162 validate_offset_imm (val
, hwse
)
1166 if ((hwse
&& val
> 255) || val
> 4095)
1174 int a ATTRIBUTE_UNUSED
;
1176 as_bad (_("Invalid syntax for .req directive."));
1181 int ignore ATTRIBUTE_UNUSED
;
1183 /* We don't support putting frags in the BSS segment, we fake it by
1184 marking in_bss, then looking at s_skip for clues?.. */
1185 subseg_set (bss_section
, 0);
1186 demand_empty_rest_of_line ();
1191 int ignore ATTRIBUTE_UNUSED
;
1193 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1194 frag_align (1, 0, 0);
1196 record_alignment (now_seg
, 1);
1198 demand_empty_rest_of_line ();
1203 int ignored ATTRIBUTE_UNUSED
;
1208 if (current_poolP
== NULL
)
1211 /* Align pool as you have word accesses */
1212 /* Only make a frag if we have to ... */
1214 frag_align (2, 0, 0);
1216 record_alignment (now_seg
, 2);
1218 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1220 symbol_locate (current_poolP
, sym_name
, now_seg
,
1221 (valueT
) frag_now_fix (), frag_now
);
1222 symbol_table_insert (current_poolP
);
1224 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1226 #if defined OBJ_COFF || defined OBJ_ELF
1227 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1230 while (lit_count
< next_literal_pool_place
)
1231 /* First output the expression in the instruction to the pool. */
1232 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1234 next_literal_pool_place
= 0;
1235 current_poolP
= NULL
;
1239 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1240 int unused ATTRIBUTE_UNUSED
;
1243 register long temp_fill
;
1244 long max_alignment
= 15;
1246 temp
= get_absolute_expression ();
1247 if (temp
> max_alignment
)
1248 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1251 as_bad (_("Alignment negative. 0 assumed."));
1255 if (*input_line_pointer
== ',')
1257 input_line_pointer
++;
1258 temp_fill
= get_absolute_expression ();
1266 /* Only make a frag if we HAVE to. . . */
1267 if (temp
&& !need_pass_2
)
1268 frag_align (temp
, (int) temp_fill
, 0);
1269 demand_empty_rest_of_line ();
1271 record_alignment (now_seg
, temp
);
1275 s_force_thumb (ignore
)
1276 int ignore ATTRIBUTE_UNUSED
;
1278 /* If we are not already in thumb mode go into it, EVEN if
1279 the target processor does not support thumb instructions.
1280 This is used by gcc/config/arm/lib1funcs.asm for example
1281 to compile interworking support functions even if the
1282 target processor should not support interworking. */
1288 record_alignment (now_seg
, 1);
1291 demand_empty_rest_of_line ();
1295 s_thumb_func (ignore
)
1296 int ignore ATTRIBUTE_UNUSED
;
1298 /* The following label is the name/address of the start of a Thumb function.
1299 We need to know this for the interworking support. */
1301 label_is_thumb_function_name
= true;
1303 demand_empty_rest_of_line ();
1306 /* Perform a .set directive, but also mark the alias as
1307 being a thumb function. */
1313 /* XXX the following is a duplicate of the code for s_set() in read.c
1314 We cannot just call that code as we need to get at the symbol that
1316 register char * name
;
1317 register char delim
;
1318 register char * end_name
;
1319 register symbolS
* symbolP
;
1322 * Especial apologies for the random logic:
1323 * this just grew, and could be parsed much more simply!
1326 name
= input_line_pointer
;
1327 delim
= get_symbol_end ();
1328 end_name
= input_line_pointer
;
1333 if (*input_line_pointer
!= ',')
1336 as_bad (_("Expected comma after name \"%s\""), name
);
1338 ignore_rest_of_line ();
1342 input_line_pointer
++;
1345 if (name
[0] == '.' && name
[1] == '\0')
1347 /* XXX - this should not happen to .thumb_set */
1351 if ((symbolP
= symbol_find (name
)) == NULL
1352 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1355 /* When doing symbol listings, play games with dummy fragments living
1356 outside the normal fragment chain to record the file and line info
1358 if (listing
& LISTING_SYMBOLS
)
1360 extern struct list_info_struct
* listing_tail
;
1361 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1362 memset (dummy_frag
, 0, sizeof(fragS
));
1363 dummy_frag
->fr_type
= rs_fill
;
1364 dummy_frag
->line
= listing_tail
;
1365 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1366 dummy_frag
->fr_symbol
= symbolP
;
1370 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1373 /* "set" symbols are local unless otherwise specified. */
1374 SF_SET_LOCAL (symbolP
);
1375 #endif /* OBJ_COFF */
1376 } /* make a new symbol */
1378 symbol_table_insert (symbolP
);
1383 && S_IS_DEFINED (symbolP
)
1384 && S_GET_SEGMENT (symbolP
) != reg_section
)
1385 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1387 pseudo_set (symbolP
);
1389 demand_empty_rest_of_line ();
1391 /* XXX Now we come to the Thumb specific bit of code. */
1393 THUMB_SET_FUNC (symbolP
, 1);
1394 ARM_SET_THUMB (symbolP
, 1);
1395 #if defined OBJ_ELF || defined OBJ_COFF
1396 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1400 /* If we change section we must dump the literal pool first. */
1405 if (now_seg
!= text_section
)
1409 obj_elf_text (ignore
);
1419 if (flag_readonly_data_in_text
)
1421 if (now_seg
!= text_section
)
1424 else if (now_seg
!= data_section
)
1428 obj_elf_data (ignore
);
1436 arm_s_section (ignore
)
1441 obj_elf_section (ignore
);
1446 opcode_select (width
)
1454 if (! (cpu_variant
& ARM_THUMB
))
1455 as_bad (_("selected processor does not support THUMB opcodes"));
1457 /* No need to force the alignment, since we will have been
1458 coming from ARM mode, which is word-aligned. */
1459 record_alignment (now_seg
, 1);
1466 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1467 as_bad (_("selected processor does not support ARM opcodes"));
1470 frag_align (2, 0, 0);
1471 record_alignment (now_seg
, 1);
1476 as_bad (_("invalid instruction size selected (%d)"), width
);
1482 int ignore ATTRIBUTE_UNUSED
;
1485 demand_empty_rest_of_line ();
1490 int ignore ATTRIBUTE_UNUSED
;
1493 demand_empty_rest_of_line ();
1498 int unused ATTRIBUTE_UNUSED
;
1502 temp
= get_absolute_expression ();
1507 opcode_select (temp
);
1511 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1519 skip_whitespace (str
);
1522 inst
.error
= _("Garbage following instruction");
1526 skip_past_comma (str
)
1532 while ((c
= *p
) == ' ' || c
== ',')
1535 if (c
== ',' && comma
++)
1543 return comma
? SUCCESS
: FAIL
;
1546 /* A standard register must be given at this point.
1547 Shift is the place to put it in inst.instruction.
1548 Restores input start point on err.
1549 Returns the reg#, or FAIL. */
1551 reg_required_here (str
, shift
)
1555 static char buff
[128]; /* XXX */
1557 char * start
= *str
;
1559 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1562 inst
.instruction
|= reg
<< shift
;
1566 /* Restore the start point, we may have got a reg of the wrong class. */
1569 /* In the few cases where we might be able to accept something else
1570 this error can be overridden. */
1571 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1577 static CONST
struct asm_psr
*
1579 register char ** ccp
;
1581 char * start
= * ccp
;
1584 CONST
struct asm_psr
* psr
;
1588 /* Skip to the end of the next word in the input stream. */
1593 while (isalpha (c
) || c
== '_');
1595 /* Terminate the word. */
1598 /* Now locate the word in the psr hash table. */
1599 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
1601 /* Restore the input stream. */
1604 /* If we found a valid match, advance the
1605 stream pointer past the end of the word. */
1611 /* Parse the input looking for a PSR flag. */
1613 psr_required_here (str
)
1616 char * start
= *str
;
1617 CONST
struct asm_psr
* psr
;
1619 psr
= arm_psr_parse (str
);
1623 /* If this is the SPSR that is being modified, set the R bit. */
1625 inst
.instruction
|= SPSR_BIT
;
1627 /* Set the psr flags in the MSR instruction. */
1628 inst
.instruction
|= psr
->field
<< PSR_SHIFT
;
1633 /* In the few cases where we might be able to accept
1634 something else this error can be overridden. */
1635 inst
.error
= _("flag for {c}psr instruction expected");
1637 /* Restore the start point. */
1643 co_proc_number (str
)
1646 int processor
, pchar
;
1648 skip_whitespace (* str
);
1650 /* The data sheet seems to imply that just a number on its own is valid
1651 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1653 if (**str
== 'p' || **str
== 'P')
1657 if (pchar
>= '0' && pchar
<= '9')
1659 processor
= pchar
- '0';
1660 if (**str
>= '0' && **str
<= '9')
1662 processor
= processor
* 10 + *(*str
)++ - '0';
1665 inst
.error
= _("Illegal co-processor number");
1672 inst
.error
= _("Bad or missing co-processor number");
1676 inst
.instruction
|= processor
<< 8;
1681 cp_opc_expr (str
, where
, length
)
1688 skip_whitespace (* str
);
1690 memset (&expr
, '\0', sizeof (expr
));
1692 if (my_get_expression (&expr
, str
))
1694 if (expr
.X_op
!= O_constant
)
1696 inst
.error
= _("bad or missing expression");
1700 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1702 inst
.error
= _("immediate co-processor expression too large");
1706 inst
.instruction
|= expr
.X_add_number
<< where
;
1711 cp_reg_required_here (str
, where
)
1716 char * start
= *str
;
1718 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1721 inst
.instruction
|= reg
<< where
;
1725 /* In the few cases where we might be able to accept something else
1726 this error can be overridden. */
1727 inst
.error
= _("Co-processor register expected");
1729 /* Restore the start point. */
1735 fp_reg_required_here (str
, where
)
1740 char * start
= *str
;
1742 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1745 inst
.instruction
|= reg
<< where
;
1749 /* In the few cases where we might be able to accept something else
1750 this error can be overridden. */
1751 inst
.error
= _("Floating point register expected");
1753 /* Restore the start point. */
1759 cp_address_offset (str
)
1764 skip_whitespace (* str
);
1766 if (! is_immediate_prefix (**str
))
1768 inst
.error
= _("immediate expression expected");
1774 if (my_get_expression (& inst
.reloc
.exp
, str
))
1777 if (inst
.reloc
.exp
.X_op
== O_constant
)
1779 offset
= inst
.reloc
.exp
.X_add_number
;
1783 inst
.error
= _("co-processor address must be word aligned");
1787 if (offset
> 1023 || offset
< -1023)
1789 inst
.error
= _("offset too large");
1794 inst
.instruction
|= INDEX_UP
;
1798 inst
.instruction
|= offset
>> 2;
1801 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1807 cp_address_required_here (str
)
1819 skip_whitespace (p
);
1821 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1824 skip_whitespace (p
);
1830 if (skip_past_comma (& p
) == SUCCESS
)
1833 write_back
= WRITE_BACK
;
1837 inst
.error
= _("pc may not be used in post-increment");
1841 if (cp_address_offset (& p
) == FAIL
)
1845 pre_inc
= PRE_INDEX
| INDEX_UP
;
1849 /* '['Rn, #expr']'[!] */
1851 if (skip_past_comma (& p
) == FAIL
)
1853 inst
.error
= _("pre-indexed expression expected");
1857 pre_inc
= PRE_INDEX
;
1859 if (cp_address_offset (& p
) == FAIL
)
1862 skip_whitespace (p
);
1866 inst
.error
= _("missing ]");
1870 skip_whitespace (p
);
1876 inst
.error
= _("pc may not be used with write-back");
1881 write_back
= WRITE_BACK
;
1887 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1890 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1891 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1892 inst
.reloc
.pc_rel
= 1;
1893 inst
.instruction
|= (REG_PC
<< 16);
1894 pre_inc
= PRE_INDEX
;
1897 inst
.instruction
|= write_back
| pre_inc
;
1905 unsigned long flags
;
1907 /* Do nothing really. */
1908 inst
.instruction
|= flags
; /* This is pointless. */
1916 unsigned long flags
;
1920 /* Only one syntax. */
1921 skip_whitespace (str
);
1923 if (reg_required_here (&str
, 12) == FAIL
)
1925 inst
.error
= BAD_ARGS
;
1929 if (skip_past_comma (&str
) == FAIL
)
1931 inst
.error
= _("comma expected after register name");
1935 skip_whitespace (str
);
1937 if ( strcmp (str
, "CPSR") == 0
1938 || strcmp (str
, "SPSR") == 0
1939 /* Lower case versions for backwards compatability. */
1940 || strcmp (str
, "cpsr") == 0
1941 || strcmp (str
, "spsr") == 0)
1943 /* This is for backwards compatability with older toolchains. */
1944 else if (strcmp (str
, "cpsr_all") == 0
1945 || strcmp (str
, "spsr_all") == 0)
1949 inst
.error
= _("{C|S}PSR expected");
1953 if (* str
== 's' || * str
== 'S')
1954 inst
.instruction
|= SPSR_BIT
;
1957 inst
.instruction
|= flags
;
1961 /* Two possible forms:
1962 "{C|S}PSR_<field>, Rm",
1963 "{C|S}PSR_f, #expression". */
1967 unsigned long flags
;
1969 skip_whitespace (str
);
1971 if (psr_required_here (& str
) == FAIL
)
1974 if (skip_past_comma (& str
) == FAIL
)
1976 inst
.error
= _("comma missing after psr flags");
1980 skip_whitespace (str
);
1982 if (reg_required_here (& str
, 0) != FAIL
)
1985 inst
.instruction
|= flags
;
1990 if (! is_immediate_prefix (* str
))
1992 inst
.error
= _("only a register or immediate value can follow a psr flag");
1999 if (my_get_expression (& inst
.reloc
.exp
, & str
))
2001 inst
.error
= _("only a register or immediate value can follow a psr flag");
2005 if (inst
.instruction
& ((PSR_c
| PSR_x
| PSR_s
) << PSR_SHIFT
))
2007 inst
.error
= _("can only set flag field with immediate value");
2011 flags
|= INST_IMMEDIATE
;
2013 if (inst
.reloc
.exp
.X_add_symbol
)
2015 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2016 inst
.reloc
.pc_rel
= 0;
2020 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2022 if (value
== (unsigned) FAIL
)
2024 inst
.error
= _("Invalid constant");
2028 inst
.instruction
|= value
;
2032 inst
.instruction
|= flags
;
2036 /* Long Multiply Parser
2037 UMULL RdLo, RdHi, Rm, Rs
2038 SMULL RdLo, RdHi, Rm, Rs
2039 UMLAL RdLo, RdHi, Rm, Rs
2040 SMLAL RdLo, RdHi, Rm, Rs
2043 do_mull (str
, flags
)
2045 unsigned long flags
;
2047 int rdlo
, rdhi
, rm
, rs
;
2049 /* Only one format "rdlo, rdhi, rm, rs" */
2050 skip_whitespace (str
);
2052 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
2054 inst
.error
= BAD_ARGS
;
2058 if (skip_past_comma (&str
) == FAIL
2059 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
2061 inst
.error
= BAD_ARGS
;
2065 if (skip_past_comma (&str
) == FAIL
2066 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2068 inst
.error
= BAD_ARGS
;
2072 /* rdhi, rdlo and rm must all be different */
2073 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
2074 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2076 if (skip_past_comma (&str
) == FAIL
2077 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
2079 inst
.error
= BAD_ARGS
;
2083 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
2085 inst
.error
= BAD_PC
;
2089 inst
.instruction
|= flags
;
2097 unsigned long flags
;
2101 /* Only one format "rd, rm, rs" */
2102 skip_whitespace (str
);
2104 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2106 inst
.error
= BAD_ARGS
;
2112 inst
.error
= BAD_PC
;
2116 if (skip_past_comma (&str
) == FAIL
2117 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2119 inst
.error
= BAD_ARGS
;
2125 inst
.error
= BAD_PC
;
2130 as_tsktsk (_("rd and rm should be different in mul"));
2132 if (skip_past_comma (&str
) == FAIL
2133 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2135 inst
.error
= BAD_ARGS
;
2141 inst
.error
= BAD_PC
;
2145 inst
.instruction
|= flags
;
2153 unsigned long flags
;
2157 /* Only one format "rd, rm, rs, rn" */
2158 skip_whitespace (str
);
2160 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2162 inst
.error
= BAD_ARGS
;
2168 inst
.error
= BAD_PC
;
2172 if (skip_past_comma (&str
) == FAIL
2173 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2175 inst
.error
= BAD_ARGS
;
2181 inst
.error
= BAD_PC
;
2186 as_tsktsk (_("rd and rm should be different in mla"));
2188 if (skip_past_comma (&str
) == FAIL
2189 || (rd
= reg_required_here (&str
, 8)) == FAIL
2190 || skip_past_comma (&str
) == FAIL
2191 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2193 inst
.error
= BAD_ARGS
;
2197 if (rd
== REG_PC
|| rm
== REG_PC
)
2199 inst
.error
= BAD_PC
;
2203 inst
.instruction
|= flags
;
2208 /* Returns the index into fp_values of a floating point number, or -1 if
2209 not in the table. */
2211 my_get_float_expression (str
)
2214 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2220 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2221 /* Look for a raw floating point number */
2222 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2223 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2225 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2227 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2229 if (words
[j
] != fp_values
[i
][j
])
2233 if (j
== MAX_LITTLENUMS
)
2241 /* Try and parse a more complex expression, this will probably fail
2242 unless the code uses a floating point prefix (eg "0f") */
2243 save_in
= input_line_pointer
;
2244 input_line_pointer
= *str
;
2245 if (expression (&exp
) == absolute_section
2246 && exp
.X_op
== O_big
2247 && exp
.X_add_number
< 0)
2249 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2251 if (gen_to_words (words
, 5, (long)15) == 0)
2253 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2255 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2257 if (words
[j
] != fp_values
[i
][j
])
2261 if (j
== MAX_LITTLENUMS
)
2263 *str
= input_line_pointer
;
2264 input_line_pointer
= save_in
;
2271 *str
= input_line_pointer
;
2272 input_line_pointer
= save_in
;
2276 /* Return true if anything in the expression is a bignum */
2278 walk_no_bignums (sp
)
2281 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2284 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2286 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2287 || (symbol_get_value_expression (sp
)->X_op_symbol
2288 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2295 my_get_expression (ep
, str
)
2302 save_in
= input_line_pointer
;
2303 input_line_pointer
= *str
;
2304 seg
= expression (ep
);
2307 if (seg
!= absolute_section
2308 && seg
!= text_section
2309 && seg
!= data_section
2310 && seg
!= bss_section
2311 && seg
!= undefined_section
)
2313 inst
.error
= _("bad_segment");
2314 *str
= input_line_pointer
;
2315 input_line_pointer
= save_in
;
2320 /* Get rid of any bignums now, so that we don't generate an error for which
2321 we can't establish a line number later on. Big numbers are never valid
2322 in instructions, which is where this routine is always called. */
2323 if (ep
->X_op
== O_big
2324 || (ep
->X_add_symbol
2325 && (walk_no_bignums (ep
->X_add_symbol
)
2327 && walk_no_bignums (ep
->X_op_symbol
)))))
2329 inst
.error
= _("Invalid constant");
2330 *str
= input_line_pointer
;
2331 input_line_pointer
= save_in
;
2335 *str
= input_line_pointer
;
2336 input_line_pointer
= save_in
;
2340 /* unrestrict should be one if <shift> <register> is permitted for this
2344 decode_shift (str
, unrestrict
)
2348 struct asm_shift
* shft
;
2352 skip_whitespace (* str
);
2354 for (p
= *str
; isalpha (*p
); p
++)
2359 inst
.error
= _("Shift expression expected");
2365 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2369 if (!strncmp (*str
, "rrx", 3)
2370 || !strncmp (*str
, "RRX", 3))
2373 inst
.instruction
|= shft
->value
;
2377 skip_whitespace (p
);
2379 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2381 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2385 else if (is_immediate_prefix (* p
))
2389 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2392 /* Validate some simple #expressions */
2393 if (inst
.reloc
.exp
.X_op
== O_constant
)
2395 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2397 /* Reject operations greater than 32, or lsl #32 */
2398 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2400 inst
.error
= _("Invalid immediate shift");
2404 /* Shifts of zero should be converted to lsl (which is zero)*/
2411 /* Shifts of 32 are encoded as 0, for those shifts that
2416 inst
.instruction
|= (num
<< 7) | shft
->value
;
2421 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2422 inst
.reloc
.pc_rel
= 0;
2423 inst
.instruction
|= shft
->value
;
2429 inst
.error
= unrestrict
? _("shift requires register or #expression")
2430 : _("shift requires #expression");
2436 inst
.error
= _("Shift expression expected");
2440 /* Do those data_ops which can take a negative immediate constant */
2441 /* by altering the instuction. A bit of a hack really */
2445 by inverting the second operand, and
2448 by negating the second operand.
2451 negate_data_op (instruction
, value
)
2452 unsigned long * instruction
;
2453 unsigned long value
;
2456 unsigned long negated
, inverted
;
2458 negated
= validate_immediate (-value
);
2459 inverted
= validate_immediate (~value
);
2461 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2465 case OPCODE_SUB
: /* ADD <-> SUB */
2466 new_inst
= OPCODE_ADD
;
2471 new_inst
= OPCODE_SUB
;
2475 case OPCODE_CMP
: /* CMP <-> CMN */
2476 new_inst
= OPCODE_CMN
;
2481 new_inst
= OPCODE_CMP
;
2485 /* Now Inverted ops */
2486 case OPCODE_MOV
: /* MOV <-> MVN */
2487 new_inst
= OPCODE_MVN
;
2492 new_inst
= OPCODE_MOV
;
2496 case OPCODE_AND
: /* AND <-> BIC */
2497 new_inst
= OPCODE_BIC
;
2502 new_inst
= OPCODE_AND
;
2506 case OPCODE_ADC
: /* ADC <-> SBC */
2507 new_inst
= OPCODE_SBC
;
2512 new_inst
= OPCODE_ADC
;
2516 /* We cannot do anything */
2521 if (value
== (unsigned) FAIL
)
2524 *instruction
&= OPCODE_MASK
;
2525 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2536 skip_whitespace (* str
);
2538 if (reg_required_here (str
, 0) != FAIL
)
2540 if (skip_past_comma (str
) == SUCCESS
)
2541 /* Shift operation on register. */
2542 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2548 /* Immediate expression */
2549 if (is_immediate_prefix (**str
))
2554 if (my_get_expression (&inst
.reloc
.exp
, str
))
2557 if (inst
.reloc
.exp
.X_add_symbol
)
2559 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2560 inst
.reloc
.pc_rel
= 0;
2564 if (skip_past_comma (str
) == SUCCESS
)
2566 /* #x, y -- ie explicit rotation by Y */
2567 if (my_get_expression (&expr
, str
))
2570 if (expr
.X_op
!= O_constant
)
2572 inst
.error
= _("Constant expression expected");
2576 /* Rotate must be a multiple of 2 */
2577 if (((unsigned) expr
.X_add_number
) > 30
2578 || (expr
.X_add_number
& 1) != 0
2579 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2581 inst
.error
= _("Invalid constant");
2584 inst
.instruction
|= INST_IMMEDIATE
;
2585 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2586 inst
.instruction
|= expr
.X_add_number
<< 7;
2590 /* Implicit rotation, select a suitable one */
2591 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2595 /* Can't be done, perhaps the code reads something like
2596 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2597 if ((value
= negate_data_op (&inst
.instruction
,
2598 inst
.reloc
.exp
.X_add_number
))
2601 inst
.error
= _("Invalid constant");
2606 inst
.instruction
|= value
;
2609 inst
.instruction
|= INST_IMMEDIATE
;
2614 inst
.error
= _("Register or shift expression expected");
2623 skip_whitespace (* str
);
2625 if (fp_reg_required_here (str
, 0) != FAIL
)
2629 /* Immediate expression */
2630 if (*((*str
)++) == '#')
2636 skip_whitespace (* str
);
2638 /* First try and match exact strings, this is to guarantee that
2639 some formats will work even for cross assembly */
2641 for (i
= 0; fp_const
[i
]; i
++)
2643 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2647 *str
+= strlen (fp_const
[i
]);
2648 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2650 inst
.instruction
|= i
+ 8;
2657 /* Just because we didn't get a match doesn't mean that the
2658 constant isn't valid, just that it is in a format that we
2659 don't automatically recognize. Try parsing it with
2660 the standard expression routines. */
2661 if ((i
= my_get_float_expression (str
)) >= 0)
2663 inst
.instruction
|= i
+ 8;
2667 inst
.error
= _("Invalid floating point immediate expression");
2670 inst
.error
= _("Floating point register or immediate expression expected");
2676 do_arit (str
, flags
)
2678 unsigned long flags
;
2680 skip_whitespace (str
);
2682 if (reg_required_here (&str
, 12) == FAIL
2683 || skip_past_comma (&str
) == FAIL
2684 || reg_required_here (&str
, 16) == FAIL
2685 || skip_past_comma (&str
) == FAIL
2686 || data_op2 (&str
) == FAIL
)
2689 inst
.error
= BAD_ARGS
;
2693 inst
.instruction
|= flags
;
2701 unsigned long flags
;
2703 /* This is a pseudo-op of the form "adr rd, label" to be converted
2704 into a relative address of the form "add rd, pc, #label-.-8". */
2705 skip_whitespace (str
);
2707 if (reg_required_here (&str
, 12) == FAIL
2708 || skip_past_comma (&str
) == FAIL
2709 || my_get_expression (&inst
.reloc
.exp
, &str
))
2712 inst
.error
= BAD_ARGS
;
2716 /* Frag hacking will turn this into a sub instruction if the offset turns
2717 out to be negative. */
2718 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2719 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust. */
2720 inst
.reloc
.pc_rel
= 1;
2721 inst
.instruction
|= flags
;
2727 do_adrl (str
, flags
)
2729 unsigned long flags
;
2731 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2732 into a relative address of the form:
2733 add rd, pc, #low(label-.-8)"
2734 add rd, rd, #high(label-.-8)" */
2736 skip_whitespace (str
);
2738 if (reg_required_here (& str
, 12) == FAIL
2739 || skip_past_comma (& str
) == FAIL
2740 || my_get_expression (& inst
.reloc
.exp
, & str
))
2743 inst
.error
= BAD_ARGS
;
2749 /* Frag hacking will turn this into a sub instruction if the offset turns
2750 out to be negative. */
2751 inst
.reloc
.type
= BFD_RELOC_ARM_ADRL_IMMEDIATE
;
2752 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2753 inst
.reloc
.pc_rel
= 1;
2754 inst
.instruction
|= flags
;
2755 inst
.size
= INSN_SIZE
* 2;
2763 unsigned long flags
;
2765 skip_whitespace (str
);
2767 if (reg_required_here (&str
, 16) == FAIL
)
2770 inst
.error
= BAD_ARGS
;
2774 if (skip_past_comma (&str
) == FAIL
2775 || data_op2 (&str
) == FAIL
)
2778 inst
.error
= BAD_ARGS
;
2782 inst
.instruction
|= flags
;
2783 if ((flags
& 0x0000f000) == 0)
2784 inst
.instruction
|= CONDS_BIT
;
2793 unsigned long flags
;
2795 skip_whitespace (str
);
2797 if (reg_required_here (&str
, 12) == FAIL
)
2800 inst
.error
= BAD_ARGS
;
2804 if (skip_past_comma (&str
) == FAIL
2805 || data_op2 (&str
) == FAIL
)
2808 inst
.error
= BAD_ARGS
;
2812 inst
.instruction
|= flags
;
2818 ldst_extend (str
, hwse
)
2829 if (my_get_expression (& inst
.reloc
.exp
, str
))
2832 if (inst
.reloc
.exp
.X_op
== O_constant
)
2834 int value
= inst
.reloc
.exp
.X_add_number
;
2836 if ((hwse
&& (value
< -255 || value
> 255))
2837 || (value
< -4095 || value
> 4095))
2839 inst
.error
= _("address offset too large");
2849 /* Halfword and signextension instructions have the
2850 immediate value split across bits 11..8 and bits 3..0 */
2852 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2854 inst
.instruction
|= add
| value
;
2860 inst
.instruction
|= HWOFFSET_IMM
;
2861 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2864 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2865 inst
.reloc
.pc_rel
= 0;
2870 add
= 0; /* and fall through */
2872 (*str
)++; /* and fall through */
2874 if (reg_required_here (str
, 0) == FAIL
)
2878 inst
.instruction
|= add
;
2881 inst
.instruction
|= add
| OFFSET_REG
;
2882 if (skip_past_comma (str
) == SUCCESS
)
2883 return decode_shift (str
, SHIFT_RESTRICT
);
2891 do_ldst (str
, flags
)
2893 unsigned long flags
;
2900 /* This is not ideal, but it is the simplest way of dealing with the
2901 ARM7T halfword instructions (since they use a different
2902 encoding, but the same mnemonic): */
2903 halfword
= (flags
& 0x80000000) != 0;
2906 /* This is actually a load/store of a halfword, or a
2907 signed-extension load */
2908 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2911 = _("Processor does not support halfwords or signed bytes");
2915 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2916 | (flags
& ~COND_MASK
);
2921 skip_whitespace (str
);
2923 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2926 inst
.error
= BAD_ARGS
;
2930 if (skip_past_comma (& str
) == FAIL
)
2932 inst
.error
= _("Address expected");
2942 skip_whitespace (str
);
2944 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2947 /* Conflicts can occur on stores as well as loads. */
2948 conflict_reg
= (conflict_reg
== reg
);
2950 skip_whitespace (str
);
2956 if (skip_past_comma (&str
) == SUCCESS
)
2958 /* [Rn],... (post inc) */
2959 if (ldst_extend (&str
, halfword
) == FAIL
)
2962 as_warn (_("%s register same as write-back base"),
2963 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2969 inst
.instruction
|= HWOFFSET_IMM
;
2971 skip_whitespace (str
);
2976 as_warn (_("%s register same as write-back base"),
2977 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
2979 inst
.instruction
|= WRITE_BACK
;
2983 if (! (flags
& TRANS_BIT
))
2990 if (skip_past_comma (&str
) == FAIL
)
2992 inst
.error
= _("pre-indexed expression expected");
2997 if (ldst_extend (&str
, halfword
) == FAIL
)
3000 skip_whitespace (str
);
3004 inst
.error
= _("missing ]");
3008 skip_whitespace (str
);
3013 as_warn (_("%s register same as write-back base"),
3014 (inst
.instruction
& LOAD_BIT
) ? _("destination") : _("source") );
3016 inst
.instruction
|= WRITE_BACK
;
3020 else if (*str
== '=')
3022 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
3025 skip_whitespace (str
);
3027 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3030 if (inst
.reloc
.exp
.X_op
!= O_constant
3031 && inst
.reloc
.exp
.X_op
!= O_symbol
)
3033 inst
.error
= _("Constant expression expected");
3037 if (inst
.reloc
.exp
.X_op
== O_constant
3038 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
3040 /* This can be done with a mov instruction */
3041 inst
.instruction
&= LITERAL_MASK
;
3042 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
3043 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
3049 /* Insert into literal pool */
3050 if (add_to_lit_pool () == FAIL
)
3053 inst
.error
= _("literal pool insertion failed");
3057 /* Change the instruction exp to point to the pool */
3060 inst
.instruction
|= HWOFFSET_IMM
;
3061 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
3064 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
3065 inst
.reloc
.pc_rel
= 1;
3066 inst
.instruction
|= (REG_PC
<< 16);
3072 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3077 inst
.instruction
|= HWOFFSET_IMM
;
3078 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
3081 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
3083 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
3085 inst
.reloc
.pc_rel
= 1;
3086 inst
.instruction
|= (REG_PC
<< 16);
3090 if (pre_inc
&& (flags
& TRANS_BIT
))
3091 inst
.error
= _("Pre-increment instruction with translate");
3093 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
3106 /* We come back here if we get ranges concatenated by '+' or '|' */
3121 skip_whitespace (str
);
3123 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
3132 inst
.error
= _("Bad range in register list");
3136 for (i
= cur_reg
+ 1; i
< reg
; i
++)
3138 if (range
& (1 << i
))
3140 (_("Warning: Duplicated register (r%d) in register list"),
3148 if (range
& (1 << reg
))
3149 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3151 else if (reg
<= cur_reg
)
3152 as_tsktsk (_("Warning: Register range not in ascending order"));
3156 } while (skip_past_comma (&str
) != FAIL
3157 || (in_range
= 1, *str
++ == '-'));
3159 skip_whitespace (str
);
3163 inst
.error
= _("Missing `}'");
3171 if (my_get_expression (&expr
, &str
))
3174 if (expr
.X_op
== O_constant
)
3176 if (expr
.X_add_number
3177 != (expr
.X_add_number
& 0x0000ffff))
3179 inst
.error
= _("invalid register mask");
3183 if ((range
& expr
.X_add_number
) != 0)
3185 int regno
= range
& expr
.X_add_number
;
3188 regno
= (1 << regno
) - 1;
3190 (_("Warning: Duplicated register (r%d) in register list"),
3194 range
|= expr
.X_add_number
;
3198 if (inst
.reloc
.type
!= 0)
3200 inst
.error
= _("expression too complex");
3204 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3205 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3206 inst
.reloc
.pc_rel
= 0;
3210 skip_whitespace (str
);
3212 if (*str
== '|' || *str
== '+')
3217 } while (another_range
);
3224 do_ldmstm (str
, flags
)
3226 unsigned long flags
;
3231 skip_whitespace (str
);
3233 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3236 if (base_reg
== REG_PC
)
3238 inst
.error
= _("r15 not allowed as base register");
3242 skip_whitespace (str
);
3246 flags
|= WRITE_BACK
;
3250 if (skip_past_comma (&str
) == FAIL
3251 || (range
= reg_list (&str
)) == FAIL
)
3254 inst
.error
= BAD_ARGS
;
3261 flags
|= LDM_TYPE_2_OR_3
;
3264 inst
.instruction
|= flags
| range
;
3272 unsigned long flags
;
3274 skip_whitespace (str
);
3276 /* Allow optional leading '#'. */
3277 if (is_immediate_prefix (*str
))
3280 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3283 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3284 inst
.reloc
.pc_rel
= 0;
3285 inst
.instruction
|= flags
;
3293 do_swap (str
, flags
)
3295 unsigned long flags
;
3299 skip_whitespace (str
);
3301 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3306 inst
.error
= _("r15 not allowed in swap");
3310 if (skip_past_comma (&str
) == FAIL
3311 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3314 inst
.error
= BAD_ARGS
;
3320 inst
.error
= _("r15 not allowed in swap");
3324 if (skip_past_comma (&str
) == FAIL
3327 inst
.error
= BAD_ARGS
;
3331 skip_whitespace (str
);
3333 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3338 inst
.error
= BAD_PC
;
3342 skip_whitespace (str
);
3346 inst
.error
= _("missing ]");
3350 inst
.instruction
|= flags
;
3356 do_branch (str
, flags
)
3358 unsigned long flags ATTRIBUTE_UNUSED
;
3360 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3367 /* ScottB: February 5, 1998 */
3368 /* Check to see of PLT32 reloc required for the instruction. */
3370 /* arm_parse_reloc() works on input_line_pointer.
3371 We actually want to parse the operands to the branch instruction
3372 passed in 'str'. Save the input pointer and restore it later. */
3373 save_in
= input_line_pointer
;
3374 input_line_pointer
= str
;
3375 if (inst
.reloc
.exp
.X_op
== O_symbol
3377 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3379 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3380 inst
.reloc
.pc_rel
= 0;
3381 /* Modify str to point to after parsed operands, otherwise
3382 end_of_line() will complain about the (PLT) left in str. */
3383 str
= input_line_pointer
;
3387 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3388 inst
.reloc
.pc_rel
= 1;
3390 input_line_pointer
= save_in
;
3393 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3394 inst
.reloc
.pc_rel
= 1;
3395 #endif /* OBJ_ELF */
3404 unsigned long flags ATTRIBUTE_UNUSED
;
3408 skip_whitespace (str
);
3410 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3412 inst
.error
= BAD_ARGS
;
3417 inst
.error
= BAD_PC
;
3425 unsigned long flags ATTRIBUTE_UNUSED
;
3427 /* Co-processor data operation.
3428 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3429 skip_whitespace (str
);
3431 if (co_proc_number (&str
) == FAIL
)
3434 inst
.error
= BAD_ARGS
;
3438 if (skip_past_comma (&str
) == FAIL
3439 || cp_opc_expr (&str
, 20,4) == FAIL
)
3442 inst
.error
= BAD_ARGS
;
3446 if (skip_past_comma (&str
) == FAIL
3447 || cp_reg_required_here (&str
, 12) == FAIL
)
3450 inst
.error
= BAD_ARGS
;
3454 if (skip_past_comma (&str
) == FAIL
3455 || cp_reg_required_here (&str
, 16) == FAIL
)
3458 inst
.error
= BAD_ARGS
;
3462 if (skip_past_comma (&str
) == FAIL
3463 || cp_reg_required_here (&str
, 0) == FAIL
)
3466 inst
.error
= BAD_ARGS
;
3470 if (skip_past_comma (&str
) == SUCCESS
)
3472 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3475 inst
.error
= BAD_ARGS
;
3485 do_lstc (str
, flags
)
3487 unsigned long flags
;
3489 /* Co-processor register load/store.
3490 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3492 skip_whitespace (str
);
3494 if (co_proc_number (&str
) == FAIL
)
3497 inst
.error
= BAD_ARGS
;
3501 if (skip_past_comma (&str
) == FAIL
3502 || cp_reg_required_here (&str
, 12) == FAIL
)
3505 inst
.error
= BAD_ARGS
;
3509 if (skip_past_comma (&str
) == FAIL
3510 || cp_address_required_here (&str
) == FAIL
)
3513 inst
.error
= BAD_ARGS
;
3517 inst
.instruction
|= flags
;
3523 do_co_reg (str
, flags
)
3525 unsigned long flags
;
3527 /* Co-processor register transfer.
3528 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3530 skip_whitespace (str
);
3532 if (co_proc_number (&str
) == FAIL
)
3535 inst
.error
= BAD_ARGS
;
3539 if (skip_past_comma (&str
) == FAIL
3540 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3543 inst
.error
= BAD_ARGS
;
3547 if (skip_past_comma (&str
) == FAIL
3548 || reg_required_here (&str
, 12) == FAIL
)
3551 inst
.error
= BAD_ARGS
;
3555 if (skip_past_comma (&str
) == FAIL
3556 || cp_reg_required_here (&str
, 16) == FAIL
)
3559 inst
.error
= BAD_ARGS
;
3563 if (skip_past_comma (&str
) == FAIL
3564 || cp_reg_required_here (&str
, 0) == FAIL
)
3567 inst
.error
= BAD_ARGS
;
3571 if (skip_past_comma (&str
) == SUCCESS
)
3573 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3576 inst
.error
= BAD_ARGS
;
3582 inst
.error
= BAD_COND
;
3590 do_fp_ctrl (str
, flags
)
3592 unsigned long flags ATTRIBUTE_UNUSED
;
3594 /* FP control registers.
3595 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3597 skip_whitespace (str
);
3599 if (reg_required_here (&str
, 12) == FAIL
)
3602 inst
.error
= BAD_ARGS
;
3611 do_fp_ldst (str
, flags
)
3613 unsigned long flags ATTRIBUTE_UNUSED
;
3615 skip_whitespace (str
);
3617 switch (inst
.suffix
)
3622 inst
.instruction
|= CP_T_X
;
3625 inst
.instruction
|= CP_T_Y
;
3628 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3634 if (fp_reg_required_here (&str
, 12) == FAIL
)
3637 inst
.error
= BAD_ARGS
;
3641 if (skip_past_comma (&str
) == FAIL
3642 || cp_address_required_here (&str
) == FAIL
)
3645 inst
.error
= BAD_ARGS
;
3653 do_fp_ldmstm (str
, flags
)
3655 unsigned long flags
;
3659 skip_whitespace (str
);
3661 if (fp_reg_required_here (&str
, 12) == FAIL
)
3664 inst
.error
= BAD_ARGS
;
3668 /* Get Number of registers to transfer */
3669 if (skip_past_comma (&str
) == FAIL
3670 || my_get_expression (&inst
.reloc
.exp
, &str
))
3673 inst
.error
= _("constant expression expected");
3677 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3679 inst
.error
= _("Constant value required for number of registers");
3683 num_regs
= inst
.reloc
.exp
.X_add_number
;
3685 if (num_regs
< 1 || num_regs
> 4)
3687 inst
.error
= _("number of registers must be in the range [1:4]");
3694 inst
.instruction
|= CP_T_X
;
3697 inst
.instruction
|= CP_T_Y
;
3700 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3714 /* The instruction specified "ea" or "fd", so we can only accept
3715 [Rn]{!}. The instruction does not really support stacking or
3716 unstacking, so we have to emulate these by setting appropriate
3717 bits and offsets. */
3718 if (skip_past_comma (&str
) == FAIL
3722 inst
.error
= BAD_ARGS
;
3727 skip_whitespace (str
);
3729 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3732 skip_whitespace (str
);
3736 inst
.error
= BAD_ARGS
;
3747 inst
.error
= _("R15 not allowed as base register with write-back");
3754 if (flags
& CP_T_Pre
)
3757 offset
= 3 * num_regs
;
3763 /* Post-increment */
3767 offset
= 3 * num_regs
;
3771 /* No write-back, so convert this into a standard pre-increment
3772 instruction -- aesthetically more pleasing. */
3773 flags
= CP_T_Pre
| CP_T_UD
;
3778 inst
.instruction
|= flags
| offset
;
3780 else if (skip_past_comma (&str
) == FAIL
3781 || cp_address_required_here (&str
) == FAIL
)
3784 inst
.error
= BAD_ARGS
;
3792 do_fp_dyadic (str
, flags
)
3794 unsigned long flags
;
3796 skip_whitespace (str
);
3798 switch (inst
.suffix
)
3803 inst
.instruction
|= 0x00000080;
3806 inst
.instruction
|= 0x00080000;
3812 if (fp_reg_required_here (&str
, 12) == FAIL
)
3815 inst
.error
= BAD_ARGS
;
3819 if (skip_past_comma (&str
) == FAIL
3820 || fp_reg_required_here (&str
, 16) == FAIL
)
3823 inst
.error
= BAD_ARGS
;
3827 if (skip_past_comma (&str
) == FAIL
3828 || fp_op2 (&str
) == FAIL
)
3831 inst
.error
= BAD_ARGS
;
3835 inst
.instruction
|= flags
;
3841 do_fp_monadic (str
, flags
)
3843 unsigned long flags
;
3845 skip_whitespace (str
);
3847 switch (inst
.suffix
)
3852 inst
.instruction
|= 0x00000080;
3855 inst
.instruction
|= 0x00080000;
3861 if (fp_reg_required_here (&str
, 12) == FAIL
)
3864 inst
.error
= BAD_ARGS
;
3868 if (skip_past_comma (&str
) == FAIL
3869 || fp_op2 (&str
) == FAIL
)
3872 inst
.error
= BAD_ARGS
;
3876 inst
.instruction
|= flags
;
3882 do_fp_cmp (str
, flags
)
3884 unsigned long flags
;
3886 skip_whitespace (str
);
3888 if (fp_reg_required_here (&str
, 16) == FAIL
)
3891 inst
.error
= BAD_ARGS
;
3895 if (skip_past_comma (&str
) == FAIL
3896 || fp_op2 (&str
) == FAIL
)
3899 inst
.error
= BAD_ARGS
;
3903 inst
.instruction
|= flags
;
3909 do_fp_from_reg (str
, flags
)
3911 unsigned long flags
;
3913 skip_whitespace (str
);
3915 switch (inst
.suffix
)
3920 inst
.instruction
|= 0x00000080;
3923 inst
.instruction
|= 0x00080000;
3929 if (fp_reg_required_here (&str
, 16) == FAIL
)
3932 inst
.error
= BAD_ARGS
;
3936 if (skip_past_comma (&str
) == FAIL
3937 || reg_required_here (&str
, 12) == FAIL
)
3940 inst
.error
= BAD_ARGS
;
3944 inst
.instruction
|= flags
;
3950 do_fp_to_reg (str
, flags
)
3952 unsigned long flags
;
3954 skip_whitespace (str
);
3956 if (reg_required_here (&str
, 12) == FAIL
)
3959 if (skip_past_comma (&str
) == FAIL
3960 || fp_reg_required_here (&str
, 0) == FAIL
)
3963 inst
.error
= BAD_ARGS
;
3967 inst
.instruction
|= flags
;
3972 /* Thumb specific routines */
3974 /* Parse and validate that a register is of the right form, this saves
3975 repeated checking of this information in many similar cases.
3976 Unlike the 32-bit case we do not insert the register into the opcode
3977 here, since the position is often unknown until the full instruction
3980 thumb_reg (strp
, hi_lo
)
3986 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3994 inst
.error
= _("lo register required");
4002 inst
.error
= _("hi register required");
4014 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4017 thumb_add_sub (str
, subtract
)
4021 int Rd
, Rs
, Rn
= FAIL
;
4023 skip_whitespace (str
);
4025 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4026 || skip_past_comma (&str
) == FAIL
)
4029 inst
.error
= BAD_ARGS
;
4033 if (is_immediate_prefix (*str
))
4037 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4042 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4045 if (skip_past_comma (&str
) == FAIL
)
4047 /* Two operand format, shuffle the registers and pretend there
4052 else if (is_immediate_prefix (*str
))
4055 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4058 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4062 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4063 for the latter case, EXPR contains the immediate that was found. */
4066 /* All register format. */
4067 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
4071 inst
.error
= _("dest and source1 must be the same register");
4075 /* Can't do this for SUB */
4078 inst
.error
= _("subtract valid only on lo regs");
4082 inst
.instruction
= (T_OPCODE_ADD_HI
4083 | (Rd
> 7 ? THUMB_H1
: 0)
4084 | (Rn
> 7 ? THUMB_H2
: 0));
4085 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
4089 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
4090 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
4095 /* Immediate expression, now things start to get nasty. */
4097 /* First deal with HI regs, only very restricted cases allowed:
4098 Adjusting SP, and using PC or SP to get an address. */
4099 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
4100 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
4102 inst
.error
= _("invalid Hi register with immediate");
4106 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4108 /* Value isn't known yet, all we can do is store all the fragments
4109 we know about in the instruction and let the reloc hacking
4111 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
4112 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4116 int offset
= inst
.reloc
.exp
.X_add_number
;
4126 /* Quick check, in case offset is MIN_INT */
4129 inst
.error
= _("immediate value out of range");
4138 if (offset
& ~0x1fc)
4140 inst
.error
= _("invalid immediate value for stack adjust");
4143 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4144 inst
.instruction
|= offset
>> 2;
4146 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4149 || (offset
& ~0x3fc))
4151 inst
.error
= _("invalid immediate for address calculation");
4154 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4156 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4162 inst
.error
= _("immediate value out of range");
4165 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4166 inst
.instruction
|= (Rd
<< 8) | offset
;
4172 inst
.error
= _("immediate value out of range");
4175 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4176 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4185 thumb_shift (str
, shift
)
4189 int Rd
, Rs
, Rn
= FAIL
;
4191 skip_whitespace (str
);
4193 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4194 || skip_past_comma (&str
) == FAIL
)
4197 inst
.error
= BAD_ARGS
;
4201 if (is_immediate_prefix (*str
))
4203 /* Two operand immediate format, set Rs to Rd. */
4206 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4211 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4214 if (skip_past_comma (&str
) == FAIL
)
4216 /* Two operand format, shuffle the registers and pretend there
4221 else if (is_immediate_prefix (*str
))
4224 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4227 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4231 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4232 for the latter case, EXPR contains the immediate that was found. */
4238 inst
.error
= _("source1 and dest must be same register");
4244 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4245 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4246 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4249 inst
.instruction
|= Rd
| (Rn
<< 3);
4255 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4256 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4257 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4260 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4262 /* Value isn't known yet, create a dummy reloc and let reloc
4263 hacking fix it up */
4265 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4269 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4271 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4273 inst
.error
= _("Invalid immediate for shift");
4277 /* Shifts of zero are handled by converting to LSL */
4278 if (shift_value
== 0)
4279 inst
.instruction
= T_OPCODE_LSL_I
;
4281 /* Shifts of 32 are encoded as a shift of zero */
4282 if (shift_value
== 32)
4285 inst
.instruction
|= shift_value
<< 6;
4288 inst
.instruction
|= Rd
| (Rs
<< 3);
4295 thumb_mov_compare (str
, move
)
4301 skip_whitespace (str
);
4303 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4304 || skip_past_comma (&str
) == FAIL
)
4307 inst
.error
= BAD_ARGS
;
4311 if (is_immediate_prefix (*str
))
4314 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4317 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4322 if (Rs
< 8 && Rd
< 8)
4324 if (move
== THUMB_MOVE
)
4325 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4326 since a MOV instruction produces unpredictable results */
4327 inst
.instruction
= T_OPCODE_ADD_I3
;
4329 inst
.instruction
= T_OPCODE_CMP_LR
;
4330 inst
.instruction
|= Rd
| (Rs
<< 3);
4334 if (move
== THUMB_MOVE
)
4335 inst
.instruction
= T_OPCODE_MOV_HR
;
4337 inst
.instruction
= T_OPCODE_CMP_HR
;
4340 inst
.instruction
|= THUMB_H1
;
4343 inst
.instruction
|= THUMB_H2
;
4345 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4352 inst
.error
= _("only lo regs allowed with immediate");
4356 if (move
== THUMB_MOVE
)
4357 inst
.instruction
= T_OPCODE_MOV_I8
;
4359 inst
.instruction
= T_OPCODE_CMP_I8
;
4361 inst
.instruction
|= Rd
<< 8;
4363 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4364 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4367 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4371 inst
.error
= _("invalid immediate");
4375 inst
.instruction
|= value
;
4383 thumb_load_store (str
, load_store
, size
)
4388 int Rd
, Rb
, Ro
= FAIL
;
4390 skip_whitespace (str
);
4392 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4393 || skip_past_comma (&str
) == FAIL
)
4396 inst
.error
= BAD_ARGS
;
4403 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4406 if (skip_past_comma (&str
) != FAIL
)
4408 if (is_immediate_prefix (*str
))
4411 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4414 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4419 inst
.reloc
.exp
.X_op
= O_constant
;
4420 inst
.reloc
.exp
.X_add_number
= 0;
4425 inst
.error
= _("expected ']'");
4430 else if (*str
== '=')
4432 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4435 skip_whitespace (str
);
4437 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4442 if ( inst
.reloc
.exp
.X_op
!= O_constant
4443 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4445 inst
.error
= "Constant expression expected";
4449 if (inst
.reloc
.exp
.X_op
== O_constant
4450 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4452 /* This can be done with a mov instruction */
4454 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4455 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4459 /* Insert into literal pool */
4460 if (add_to_lit_pool () == FAIL
)
4463 inst
.error
= "literal pool insertion failed";
4467 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4468 inst
.reloc
.pc_rel
= 1;
4469 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4470 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4476 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4479 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4480 inst
.reloc
.pc_rel
= 1;
4481 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4482 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4487 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4489 if (size
!= THUMB_WORD
)
4491 inst
.error
= _("byte or halfword not valid for base register");
4494 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4496 inst
.error
= _("R15 based store not allowed");
4499 else if (Ro
!= FAIL
)
4501 inst
.error
= _("Invalid base register for register offset");
4506 inst
.instruction
= T_OPCODE_LDR_PC
;
4507 else if (load_store
== THUMB_LOAD
)
4508 inst
.instruction
= T_OPCODE_LDR_SP
;
4510 inst
.instruction
= T_OPCODE_STR_SP
;
4512 inst
.instruction
|= Rd
<< 8;
4513 if (inst
.reloc
.exp
.X_op
== O_constant
)
4515 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4517 if (offset
& ~0x3fc)
4519 inst
.error
= _("invalid offset");
4523 inst
.instruction
|= offset
>> 2;
4526 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4530 inst
.error
= _("invalid base register in load/store");
4533 else if (Ro
== FAIL
)
4535 /* Immediate offset */
4536 if (size
== THUMB_WORD
)
4537 inst
.instruction
= (load_store
== THUMB_LOAD
4538 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4539 else if (size
== THUMB_HALFWORD
)
4540 inst
.instruction
= (load_store
== THUMB_LOAD
4541 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4543 inst
.instruction
= (load_store
== THUMB_LOAD
4544 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4546 inst
.instruction
|= Rd
| (Rb
<< 3);
4548 if (inst
.reloc
.exp
.X_op
== O_constant
)
4550 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4552 if (offset
& ~(0x1f << size
))
4554 inst
.error
= _("Invalid offset");
4557 inst
.instruction
|= (offset
>> size
) << 6;
4560 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4564 /* Register offset */
4565 if (size
== THUMB_WORD
)
4566 inst
.instruction
= (load_store
== THUMB_LOAD
4567 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4568 else if (size
== THUMB_HALFWORD
)
4569 inst
.instruction
= (load_store
== THUMB_LOAD
4570 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4572 inst
.instruction
= (load_store
== THUMB_LOAD
4573 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4575 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4590 /* Handle the Format 4 instructions that do not have equivalents in other
4591 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4599 skip_whitespace (str
);
4601 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4602 || skip_past_comma (&str
) == FAIL
4603 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4605 inst
.error
= BAD_ARGS
;
4609 if (skip_past_comma (&str
) != FAIL
)
4611 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4612 (It isn't allowed for CMP either, but that isn't handled by this
4614 if (inst
.instruction
== T_OPCODE_TST
4615 || inst
.instruction
== T_OPCODE_CMN
4616 || inst
.instruction
== T_OPCODE_NEG
4617 || inst
.instruction
== T_OPCODE_MVN
)
4619 inst
.error
= BAD_ARGS
;
4623 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4628 inst
.error
= _("dest and source1 one must be the same register");
4634 if (inst
.instruction
== T_OPCODE_MUL
4636 as_tsktsk (_("Rs and Rd must be different in MUL"));
4638 inst
.instruction
|= Rd
| (Rs
<< 3);
4646 thumb_add_sub (str
, 0);
4653 thumb_shift (str
, THUMB_ASR
);
4660 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4662 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4663 inst
.reloc
.pc_rel
= 1;
4671 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4673 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4674 inst
.reloc
.pc_rel
= 1;
4678 /* Find the real, Thumb encoded start of a Thumb function. */
4681 find_real_start (symbolP
)
4685 const char * name
= S_GET_NAME (symbolP
);
4686 symbolS
* new_target
;
4688 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4689 #define STUB_NAME ".real_start_of"
4694 /* Names that start with '.' are local labels, not function entry points.
4695 The compiler may generate BL instructions to these labels because it
4696 needs to perform a branch to a far away location. */
4700 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4701 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4703 new_target
= symbol_find (real_start
);
4705 if (new_target
== NULL
)
4707 as_warn ("Failed to find real start of function: %s\n", name
);
4708 new_target
= symbolP
;
4721 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4724 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4725 inst
.reloc
.pc_rel
= 1;
4728 /* If the destination of the branch is a defined symbol which does not have
4729 the THUMB_FUNC attribute, then we must be calling a function which has
4730 the (interfacearm) attribute. We look for the Thumb entry point to that
4731 function and change the branch to refer to that function instead. */
4732 if ( inst
.reloc
.exp
.X_op
== O_symbol
4733 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4734 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4735 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4736 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4745 skip_whitespace (str
);
4747 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4750 /* This sets THUMB_H2 from the top bit of reg. */
4751 inst
.instruction
|= reg
<< 3;
4753 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4754 should cause the alignment to be checked once it is known. This is
4755 because BX PC only works if the instruction is word aligned. */
4764 thumb_mov_compare (str
, THUMB_COMPARE
);
4774 skip_whitespace (str
);
4776 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4780 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4784 if (skip_past_comma (&str
) == FAIL
4785 || (range
= reg_list (&str
)) == FAIL
)
4788 inst
.error
= BAD_ARGS
;
4792 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4794 /* This really doesn't seem worth it. */
4795 inst
.reloc
.type
= BFD_RELOC_NONE
;
4796 inst
.error
= _("Expression too complex");
4802 inst
.error
= _("only lo-regs valid in load/store multiple");
4806 inst
.instruction
|= (Rb
<< 8) | range
;
4814 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4821 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4828 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4837 skip_whitespace (str
);
4839 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4840 || skip_past_comma (&str
) == FAIL
4842 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4843 || skip_past_comma (&str
) == FAIL
4844 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4848 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4852 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4860 thumb_shift (str
, THUMB_LSL
);
4867 thumb_shift (str
, THUMB_LSR
);
4874 thumb_mov_compare (str
, THUMB_MOVE
);
4883 skip_whitespace (str
);
4885 if ((range
= reg_list (&str
)) == FAIL
)
4888 inst
.error
= BAD_ARGS
;
4892 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4894 /* This really doesn't seem worth it. */
4895 inst
.reloc
.type
= BFD_RELOC_NONE
;
4896 inst
.error
= _("Expression too complex");
4902 if ((inst
.instruction
== T_OPCODE_PUSH
4903 && (range
& ~0xff) == 1 << REG_LR
)
4904 || (inst
.instruction
== T_OPCODE_POP
4905 && (range
& ~0xff) == 1 << REG_PC
))
4907 inst
.instruction
|= THUMB_PP_PC_LR
;
4912 inst
.error
= _("invalid register list to push/pop instruction");
4917 inst
.instruction
|= range
;
4925 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4932 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4939 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4946 thumb_add_sub (str
, 1);
4953 skip_whitespace (str
);
4955 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4958 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4969 /* This is a pseudo-op of the form "adr rd, label" to be converted
4970 into a relative address of the form "add rd, pc, #label-.-4". */
4971 skip_whitespace (str
);
4973 /* Store Rd in temporary location inside instruction. */
4974 if ((reg
= reg_required_here (&str
, 4)) == FAIL
4975 || (reg
> 7) /* For Thumb reg must be r0..r7. */
4976 || skip_past_comma (&str
) == FAIL
4977 || my_get_expression (&inst
.reloc
.exp
, &str
))
4980 inst
.error
= BAD_ARGS
;
4984 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4985 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust. */
4986 inst
.reloc
.pc_rel
= 1;
4987 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction. */
4996 int len
= strlen (reg_table
[entry
].name
) + 2;
4997 char * buf
= (char *) xmalloc (len
);
4998 char * buf2
= (char *) xmalloc (len
);
5001 #ifdef REGISTER_PREFIX
5002 buf
[i
++] = REGISTER_PREFIX
;
5005 strcpy (buf
+ i
, reg_table
[entry
].name
);
5007 for (i
= 0; buf
[i
]; i
++)
5008 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
5012 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
5013 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
5017 insert_reg_alias (str
, regnum
)
5021 struct reg_entry
*new =
5022 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
5023 char *name
= xmalloc (strlen (str
) + 1);
5027 new->number
= regnum
;
5029 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
5033 set_constant_flonums ()
5037 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
5038 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
5048 if ( (arm_ops_hsh
= hash_new ()) == NULL
5049 || (arm_tops_hsh
= hash_new ()) == NULL
5050 || (arm_cond_hsh
= hash_new ()) == NULL
5051 || (arm_shift_hsh
= hash_new ()) == NULL
5052 || (arm_reg_hsh
= hash_new ()) == NULL
5053 || (arm_psr_hsh
= hash_new ()) == NULL
)
5054 as_fatal (_("Virtual memory exhausted"));
5056 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
5057 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
5058 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
5059 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
5060 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
5061 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
5062 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
5063 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
5064 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
5065 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
5067 for (i
= 0; reg_table
[i
].name
; i
++)
5070 set_constant_flonums ();
5072 #if defined OBJ_COFF || defined OBJ_ELF
5074 unsigned int flags
= 0;
5076 /* Set the flags in the private structure. */
5077 if (uses_apcs_26
) flags
|= F_APCS26
;
5078 if (support_interwork
) flags
|= F_INTERWORK
;
5079 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
5080 if (pic_code
) flags
|= F_PIC
;
5081 if ((cpu_variant
& FPU_ALL
) == FPU_NONE
) flags
|= F_SOFT_FLOAT
;
5083 bfd_set_private_flags (stdoutput
, flags
);
5087 /* Record the CPU type as well. */
5088 switch (cpu_variant
& ARM_CPU_MASK
)
5091 mach
= bfd_mach_arm_2
;
5094 case ARM_3
: /* Also ARM_250. */
5095 mach
= bfd_mach_arm_2a
;
5099 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined. */
5100 mach
= bfd_mach_arm_4
;
5103 case ARM_7
: /* Also ARM_6. */
5104 mach
= bfd_mach_arm_3
;
5108 /* Catch special cases. */
5109 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
5111 if (cpu_variant
& (ARM_EXT_V5
& ARM_THUMB
))
5112 mach
= bfd_mach_arm_5T
;
5113 else if (cpu_variant
& ARM_EXT_V5
)
5114 mach
= bfd_mach_arm_5
;
5115 else if (cpu_variant
& ARM_THUMB
)
5116 mach
= bfd_mach_arm_4T
;
5117 else if ((cpu_variant
& ARM_ARCH_V4
) == ARM_ARCH_V4
)
5118 mach
= bfd_mach_arm_4
;
5119 else if (cpu_variant
& ARM_LONGMUL
)
5120 mach
= bfd_mach_arm_3M
;
5123 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
5126 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5127 for use in the a.out file, and stores them in the array pointed to by buf.
5128 This knows about the endian-ness of the target machine and does
5129 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5130 2 (short) and 4 (long) Floating numbers are put out as a series of
5131 LITTLENUMS (shorts, here at least). */
5133 md_number_to_chars (buf
, val
, n
)
5138 if (target_big_endian
)
5139 number_to_chars_bigendian (buf
, val
, n
);
5141 number_to_chars_littleendian (buf
, val
, n
);
5145 md_chars_to_number (buf
, n
)
5150 unsigned char * where
= (unsigned char *) buf
;
5152 if (target_big_endian
)
5157 result
|= (*where
++ & 255);
5165 result
|= (where
[n
] & 255);
5172 /* Turn a string in input_line_pointer into a floating point constant
5173 of type TYPE, and store the appropriate bytes in *litP. The number
5174 of LITTLENUMS emitted is stored in *sizeP . An error message is
5175 returned, or NULL on OK.
5177 Note that fp constants aren't represent in the normal way on the ARM.
5178 In big endian mode, things are as expected. However, in little endian
5179 mode fp constants are big-endian word-wise, and little-endian byte-wise
5180 within the words. For example, (double) 1.1 in big endian mode is
5181 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5182 the byte sequence 99 99 f1 3f 9a 99 99 99.
5184 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5187 md_atof (type
, litP
, sizeP
)
5193 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5225 return _("Bad call to MD_ATOF()");
5228 t
= atof_ieee (input_line_pointer
, type
, words
);
5230 input_line_pointer
= t
;
5233 if (target_big_endian
)
5235 for (i
= 0; i
< prec
; i
++)
5237 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5243 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5244 8 byte float the order is 1 0 3 2. */
5245 for (i
= 0; i
< prec
; i
+= 2)
5247 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5248 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5256 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5258 md_pcrel_from (fixP
)
5262 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5263 && fixP
->fx_subsy
== NULL
)
5266 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5268 /* PC relative addressing on the Thumb is slightly odd
5269 as the bottom two bits of the PC are forced to zero
5270 for the calculation. */
5271 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5275 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5276 so we un-adjust here to compensate for the accomodation. */
5277 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
+ 8;
5279 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5283 /* Round up a section size to the appropriate boundary. */
5285 md_section_align (segment
, size
)
5286 segT segment ATTRIBUTE_UNUSED
;
5292 /* Round all sects to multiple of 4 */
5293 return (size
+ 3) & ~3;
5297 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5298 we have no need to default values of symbols. */
5302 md_undefined_symbol (name
)
5303 char * name ATTRIBUTE_UNUSED
;
5306 if (name
[0] == '_' && name
[1] == 'G'
5307 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5311 if (symbol_find (name
))
5312 as_bad ("GOT already in the symbol table");
5314 GOT_symbol
= symbol_new (name
, undefined_section
,
5315 (valueT
)0, & zero_address_frag
);
5325 /* arm_reg_parse () := if it looks like a register, return its token and
5326 advance the pointer. */
5330 register char ** ccp
;
5332 char * start
= * ccp
;
5335 struct reg_entry
* reg
;
5337 #ifdef REGISTER_PREFIX
5338 if (*start
!= REGISTER_PREFIX
)
5343 #ifdef OPTIONAL_REGISTER_PREFIX
5344 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5348 if (!isalpha (*p
) || !is_name_beginner (*p
))
5352 while (isalpha (c
) || isdigit (c
) || c
== '_')
5356 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5369 md_apply_fix3 (fixP
, val
, seg
)
5374 offsetT value
= * val
;
5376 unsigned int newimm
;
5379 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5380 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5382 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5384 /* Note whether this will delete the relocation. */
5385 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5386 if ((fixP
->fx_addsy
== 0 || symbol_constant_p (fixP
->fx_addsy
))
5389 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5393 /* If this symbol is in a different section then we need to leave it for
5394 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5395 so we have to undo it's effects here. */
5398 if (fixP
->fx_addsy
!= NULL
5399 && S_IS_DEFINED (fixP
->fx_addsy
)
5400 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5403 && (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
5407 value
+= md_pcrel_from (fixP
);
5411 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc. */
5413 switch (fixP
->fx_r_type
)
5415 case BFD_RELOC_ARM_IMMEDIATE
:
5416 newimm
= validate_immediate (value
);
5417 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5419 /* If the instruction will fail, see if we can fix things up by
5420 changing the opcode. */
5421 if (newimm
== (unsigned int) FAIL
5422 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5424 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5425 _("invalid constant (%lx) after fixup"),
5426 (unsigned long) value
);
5430 newimm
|= (temp
& 0xfffff000);
5431 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5434 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
5436 unsigned int highpart
= 0;
5437 unsigned int newinsn
= 0xe1a00000; /* nop */
5438 newimm
= validate_immediate (value
);
5439 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5441 /* If the instruction will fail, see if we can fix things up by
5442 changing the opcode. */
5443 if (newimm
== (unsigned int) FAIL
5444 && (newimm
= negate_data_op (& temp
, value
)) == (unsigned int) FAIL
)
5446 /* No ? OK - try using two ADD instructions to generate the value. */
5447 newimm
= validate_immediate_twopart (value
, & highpart
);
5449 /* Yes - then make sure that the second instruction is also an add. */
5450 if (newimm
!= (unsigned int) FAIL
)
5452 /* Still No ? Try using a negated value. */
5453 else if (validate_immediate_twopart (- value
, & highpart
) != (unsigned int) FAIL
)
5454 temp
= newinsn
= (temp
& OPCODE_MASK
) | OPCODE_SUB
<< DATA_OP_SHIFT
;
5455 /* Otherwise - give up. */
5458 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5459 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value
);
5463 /* Replace the first operand in the 2nd instruction (which is the PC)
5464 with the destination register. We have already added in the PC in the
5465 first instruction and we do not want to do it again. */
5466 newinsn
&= ~ 0xf0000;
5467 newinsn
|= ((newinsn
& 0x0f000) << 4);
5470 newimm
|= (temp
& 0xfffff000);
5471 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5473 highpart
|= (newinsn
& 0xfffff000);
5474 md_number_to_chars (buf
+ INSN_SIZE
, (valueT
) highpart
, INSN_SIZE
);
5478 case BFD_RELOC_ARM_OFFSET_IMM
:
5484 if (validate_offset_imm (value
, 0) == FAIL
)
5486 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5487 _("bad immediate value for offset (%ld)"), (long) value
);
5491 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5492 newval
&= 0xff7ff000;
5493 newval
|= value
| (sign
? INDEX_UP
: 0);
5494 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5497 case BFD_RELOC_ARM_OFFSET_IMM8
:
5498 case BFD_RELOC_ARM_HWLITERAL
:
5504 if (validate_offset_imm (value
, 1) == FAIL
)
5506 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5507 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5508 _("invalid literal constant: pool needs to be closer"));
5510 as_bad (_("bad immediate value for half-word offset (%ld)"),
5515 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5516 newval
&= 0xff7ff0f0;
5517 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5518 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5521 case BFD_RELOC_ARM_LITERAL
:
5527 if (validate_offset_imm (value
, 0) == FAIL
)
5529 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5530 _("invalid literal constant: pool needs to be closer"));
5534 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5535 newval
&= 0xff7ff000;
5536 newval
|= value
| (sign
? INDEX_UP
: 0);
5537 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5540 case BFD_RELOC_ARM_SHIFT_IMM
:
5541 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5542 if (((unsigned long) value
) > 32
5544 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5546 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5547 _("shift expression is too large"));
5552 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5553 else if (value
== 32)
5555 newval
&= 0xfffff07f;
5556 newval
|= (value
& 0x1f) << 7;
5557 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5560 case BFD_RELOC_ARM_SWI
:
5561 if (arm_data
->thumb_mode
)
5563 if (((unsigned long) value
) > 0xff)
5564 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5565 _("Invalid swi expression"));
5566 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5568 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5572 if (((unsigned long) value
) > 0x00ffffff)
5573 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5574 _("Invalid swi expression"));
5575 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5577 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5581 case BFD_RELOC_ARM_MULTI
:
5582 if (((unsigned long) value
) > 0xffff)
5583 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5584 _("Invalid expression in load/store multiple"));
5585 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5586 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5589 case BFD_RELOC_ARM_PCREL_BRANCH
:
5590 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5592 /* Sign-extend a 24-bit number. */
5593 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5597 value
= fixP
->fx_offset
;
5600 /* We are going to store value (shifted right by two) in the
5601 instruction, in a 24 bit, signed field. Thus we need to check
5602 that none of the top 8 bits of the shifted value (top 7 bits of
5603 the unshifted, unsigned value) are set, or that they are all set. */
5604 if ((value
& 0xfe000000UL
) != 0
5605 && ((value
& 0xfe000000UL
) != 0xfe000000UL
))
5608 /* Normally we would be stuck at this point, since we cannot store
5609 the absolute address that is the destination of the branch in the
5610 24 bits of the branch instruction. If however, we happen to know
5611 that the destination of the branch is in the same section as the
5612 branch instruciton itself, then we can compute the relocation for
5613 ourselves and not have to bother the linker with it.
5615 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5616 because I have not worked out how to do this for OBJ_COFF or
5619 && fixP
->fx_addsy
!= NULL
5620 && S_IS_DEFINED (fixP
->fx_addsy
)
5621 && S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
5623 /* Get pc relative value to go into the branch. */
5626 /* Permit a backward branch provided that enough bits are set.
5627 Allow a forwards branch, provided that enough bits are clear. */
5628 if ((value
& 0xfe000000UL
) == 0xfe000000UL
5629 || (value
& 0xfe000000UL
) == 0)
5633 if (! fixP
->fx_done
)
5635 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5636 _("gas can't handle same-section branch dest >= 0x04000000"));
5640 value
+= SEXT24 (newval
);
5642 if ((value
& 0xff000000UL
) != 0
5643 && ((value
& 0xff000000UL
) != 0xff000000UL
))
5644 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5645 _("out of range branch"));
5647 newval
= (value
& 0x00ffffff) | (newval
& 0xff000000);
5648 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5652 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5653 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5655 addressT diff
= (newval
& 0xff) << 1;
5660 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5661 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5662 _("Branch out of range"));
5663 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5665 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5668 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5669 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5671 addressT diff
= (newval
& 0x7ff) << 1;
5676 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5677 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5678 _("Branch out of range"));
5679 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5681 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5684 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5689 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5690 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5691 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5692 if (diff
& 0x400000)
5695 value
= fixP
->fx_offset
;
5698 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5699 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5700 _("Branch with link out of range"));
5702 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5703 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5704 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5705 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5710 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5711 md_number_to_chars (buf
, value
, 1);
5713 else if (!target_oabi
)
5715 value
= fixP
->fx_offset
;
5716 md_number_to_chars (buf
, value
, 1);
5722 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5723 md_number_to_chars (buf
, value
, 2);
5725 else if (!target_oabi
)
5727 value
= fixP
->fx_offset
;
5728 md_number_to_chars (buf
, value
, 2);
5734 case BFD_RELOC_ARM_GOT32
:
5735 case BFD_RELOC_ARM_GOTOFF
:
5736 md_number_to_chars (buf
, 0, 4);
5742 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5743 md_number_to_chars (buf
, value
, 4);
5745 else if (!target_oabi
)
5747 value
= fixP
->fx_offset
;
5748 md_number_to_chars (buf
, value
, 4);
5754 case BFD_RELOC_ARM_PLT32
:
5755 /* It appears the instruction is fully prepared at this point. */
5759 case BFD_RELOC_ARM_GOTPC
:
5760 md_number_to_chars (buf
, value
, 4);
5763 case BFD_RELOC_ARM_CP_OFF_IMM
:
5765 if (value
< -1023 || value
> 1023 || (value
& 3))
5766 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5767 _("Illegal value for co-processor offset"));
5770 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5771 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5772 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5775 case BFD_RELOC_ARM_THUMB_OFFSET
:
5776 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5777 /* Exactly what ranges, and where the offset is inserted depends on
5778 the type of instruction, we can establish this from the top 4 bits */
5779 switch (newval
>> 12)
5781 case 4: /* PC load */
5782 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5783 forced to zero for these loads, so we will need to round
5784 up the offset if the instruction address is not word
5785 aligned (since the final address produced must be, and
5786 we can only describe word-aligned immediate offsets). */
5788 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5789 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5790 _("Invalid offset, target not word aligned (0x%08X)"),
5791 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5793 if ((value
+ 2) & ~0x3fe)
5794 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5795 _("Invalid offset, value too big (0x%08X)"), value
);
5797 /* Round up, since pc will be rounded down. */
5798 newval
|= (value
+ 2) >> 2;
5801 case 9: /* SP load/store */
5803 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5804 _("Invalid offset, value too big (0x%08X)"), value
);
5805 newval
|= value
>> 2;
5808 case 6: /* Word load/store */
5810 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5811 _("Invalid offset, value too big (0x%08X)"), value
);
5812 newval
|= value
<< 4; /* 6 - 2 */
5815 case 7: /* Byte load/store */
5817 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5818 _("Invalid offset, value too big (0x%08X)"), value
);
5819 newval
|= value
<< 6;
5822 case 8: /* Halfword load/store */
5824 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5825 _("Invalid offset, value too big (0x%08X)"), value
);
5826 newval
|= value
<< 5; /* 6 - 1 */
5830 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5831 "Unable to process relocation for thumb opcode: %lx",
5832 (unsigned long) newval
);
5835 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5838 case BFD_RELOC_ARM_THUMB_ADD
:
5839 /* This is a complicated relocation, since we use it for all of
5840 the following immediate relocations:
5843 9bit ADD/SUB SP word-aligned
5844 10bit ADD PC/SP word-aligned
5846 The type of instruction being processed is encoded in the
5852 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5854 int rd
= (newval
>> 4) & 0xf;
5855 int rs
= newval
& 0xf;
5856 int subtract
= newval
& 0x8000;
5861 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5862 _("Invalid immediate for stack address calculation"));
5863 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5864 newval
|= value
>> 2;
5866 else if (rs
== REG_PC
|| rs
== REG_SP
)
5870 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5871 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5872 (unsigned long) value
);
5873 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5875 newval
|= value
>> 2;
5880 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5881 _("Invalid 8bit immediate"));
5882 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5883 newval
|= (rd
<< 8) | value
;
5888 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5889 _("Invalid 3bit immediate"));
5890 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5891 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5894 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5897 case BFD_RELOC_ARM_THUMB_IMM
:
5898 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5899 switch (newval
>> 11)
5901 case 0x04: /* 8bit immediate MOV */
5902 case 0x05: /* 8bit immediate CMP */
5903 if (value
< 0 || value
> 255)
5904 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5905 _("Invalid immediate: %ld is too large"),
5913 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5916 case BFD_RELOC_ARM_THUMB_SHIFT
:
5917 /* 5bit shift value (0..31) */
5918 if (value
< 0 || value
> 31)
5919 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5920 _("Illegal Thumb shift value: %ld"), (long) value
);
5921 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5922 newval
|= value
<< 6;
5923 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5926 case BFD_RELOC_VTABLE_INHERIT
:
5927 case BFD_RELOC_VTABLE_ENTRY
:
5931 case BFD_RELOC_NONE
:
5933 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5934 _("Bad relocation fixup type (%d)"), fixP
->fx_r_type
);
5940 /* Translate internal representation of relocation info to BFD target
5943 tc_gen_reloc (section
, fixp
)
5944 asection
* section ATTRIBUTE_UNUSED
;
5948 bfd_reloc_code_real_type code
;
5950 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5952 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5953 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5954 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5956 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5958 if (fixp
->fx_pcrel
== 0)
5959 reloc
->addend
= fixp
->fx_offset
;
5961 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5963 reloc
->addend
= fixp
->fx_offset
;
5966 switch (fixp
->fx_r_type
)
5971 code
= BFD_RELOC_8_PCREL
;
5978 code
= BFD_RELOC_16_PCREL
;
5985 code
= BFD_RELOC_32_PCREL
;
5989 case BFD_RELOC_ARM_PCREL_BRANCH
:
5991 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5992 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5993 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5994 case BFD_RELOC_VTABLE_ENTRY
:
5995 case BFD_RELOC_VTABLE_INHERIT
:
5996 code
= fixp
->fx_r_type
;
5999 case BFD_RELOC_ARM_LITERAL
:
6000 case BFD_RELOC_ARM_HWLITERAL
:
6001 /* If this is called then the a literal has been referenced across
6002 a section boundary - possibly due to an implicit dump */
6003 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6004 _("Literal referenced across section boundary (Implicit dump?)"));
6008 case BFD_RELOC_ARM_GOT32
:
6009 case BFD_RELOC_ARM_GOTOFF
:
6010 case BFD_RELOC_ARM_PLT32
:
6011 code
= fixp
->fx_r_type
;
6015 case BFD_RELOC_ARM_IMMEDIATE
:
6016 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6017 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6021 case BFD_RELOC_ARM_ADRL_IMMEDIATE
:
6022 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6023 _("ADRL used for a symbol not defined in the same file"),
6027 case BFD_RELOC_ARM_OFFSET_IMM
:
6028 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6029 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6036 switch (fixp
->fx_r_type
)
6038 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
6039 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
6040 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
6041 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
6042 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
6043 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
6044 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
6045 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
6046 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
6047 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
6048 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
6049 default: type
= _("<unknown>"); break;
6051 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6052 _("Can not represent %s relocation in this object file format (%d)"),
6053 type
, fixp
->fx_pcrel
);
6059 if (code
== BFD_RELOC_32_PCREL
6061 && fixp
->fx_addsy
== GOT_symbol
)
6063 code
= BFD_RELOC_ARM_GOTPC
;
6064 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
6068 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
6070 if (reloc
->howto
== NULL
)
6072 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
6073 _("Can not represent %s relocation in this object file format"),
6074 bfd_get_reloc_code_name (code
));
6078 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6079 vtable entry to be used in the relocation's section offset. */
6080 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6081 reloc
->address
= fixp
->fx_offset
;
6087 md_estimate_size_before_relax (fragP
, segtype
)
6088 fragS
* fragP ATTRIBUTE_UNUSED
;
6089 segT segtype ATTRIBUTE_UNUSED
;
6091 as_fatal (_("md_estimate_size_before_relax\n"));
6096 output_inst
PARAMS ((void))
6102 as_bad (inst
.error
);
6106 to
= frag_more (inst
.size
);
6108 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
6110 assert (inst
.size
== (2 * THUMB_SIZE
));
6111 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
6112 md_number_to_chars (to
+ THUMB_SIZE
, inst
.instruction
, THUMB_SIZE
);
6114 else if (inst
.size
> INSN_SIZE
)
6116 assert (inst
.size
== (2 * INSN_SIZE
));
6117 md_number_to_chars (to
, inst
.instruction
, INSN_SIZE
);
6118 md_number_to_chars (to
+ INSN_SIZE
, inst
.instruction
, INSN_SIZE
);
6121 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
6123 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
6124 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
6125 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
6140 /* Align the instruction.
6141 This may not be the right thing to do but ... */
6142 /* arm_align (2, 0); */
6143 listing_prev_line (); /* Defined in listing.h */
6145 /* Align the previous label if needed. */
6146 if (last_label_seen
!= NULL
)
6148 symbol_set_frag (last_label_seen
, frag_now
);
6149 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
6150 S_SET_SEGMENT (last_label_seen
, now_seg
);
6153 memset (&inst
, '\0', sizeof (inst
));
6154 inst
.reloc
.type
= BFD_RELOC_NONE
;
6156 skip_whitespace (str
);
6158 /* Scan up to the end of the op-code, which must end in white space or
6160 for (start
= p
= str
; *p
!= '\0'; p
++)
6166 as_bad (_("No operator -- statement `%s'\n"), str
);
6172 CONST
struct thumb_opcode
* opcode
;
6176 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
6181 /* Check that this instruction is supported for this CPU. */
6182 if (thumb_mode
== 1 && (opcode
->variants
& cpu_variant
) == 0)
6184 as_bad (_("selected processor does not support this opcode"));
6188 inst
.instruction
= opcode
->value
;
6189 inst
.size
= opcode
->size
;
6190 (*opcode
->parms
)(p
);
6197 CONST
struct asm_opcode
* opcode
;
6198 unsigned long cond_code
;
6200 inst
.size
= INSN_SIZE
;
6201 /* p now points to the end of the opcode, probably white space, but we
6202 have to break the opcode up in case it contains condionals and flags;
6203 keep trying with progressively smaller basic instructions until one
6204 matches, or we run out of opcode. */
6205 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
6206 for (; q
!= str
; q
--)
6210 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
6213 if (opcode
&& opcode
->template)
6215 unsigned long flag_bits
= 0;
6218 /* Check that this instruction is supported for this CPU. */
6219 if ((opcode
->variants
& cpu_variant
) == 0)
6222 inst
.instruction
= opcode
->value
;
6223 if (q
== p
) /* Just a simple opcode. */
6225 if (opcode
->comp_suffix
)
6227 if (*opcode
->comp_suffix
!= '\0')
6228 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6229 str
, opcode
->comp_suffix
);
6231 /* Not a conditional instruction. */
6232 (*opcode
->parms
)(q
, 0);
6236 /* A conditional instruction with default condition. */
6237 inst
.instruction
|= COND_ALWAYS
;
6238 (*opcode
->parms
)(q
, 0);
6244 /* Not just a simple opcode. Check if extra is a conditional. */
6248 CONST
struct asm_cond
*cond
;
6252 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6256 if (cond
->value
== 0xf0000000)
6258 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6260 cond_code
= cond
->value
;
6264 cond_code
= COND_ALWAYS
;
6267 cond_code
= COND_ALWAYS
;
6269 /* Apply the conditional, or complain it's not allowed. */
6270 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
== '\0')
6272 /* Instruction isn't conditional */
6273 if (cond_code
!= COND_ALWAYS
)
6275 as_bad (_("Opcode `%s' is unconditional\n"), str
);
6280 /* Instruction is conditional: set the condition into it. */
6281 inst
.instruction
|= cond_code
;
6284 /* If there is a compulsory suffix, it should come here, before
6285 any optional flags. */
6286 if (opcode
->comp_suffix
&& *opcode
->comp_suffix
!= '\0')
6288 CONST
char *s
= opcode
->comp_suffix
;
6300 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6301 opcode
->comp_suffix
);
6308 /* The remainder, if any should now be flags for the instruction;
6309 Scan these checking each one found with the opcode. */
6313 CONST
struct asm_flg
*flag
= opcode
->flags
;
6322 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6324 if (streq (r
, flag
[flagno
].template))
6326 flag_bits
|= flag
[flagno
].set_bits
;
6332 if (! flag
[flagno
].template)
6339 (*opcode
->parms
) (p
, flag_bits
);
6349 /* It wasn't an instruction, but it might be a register alias of the form
6352 skip_whitespace (q
);
6357 if (*q
&& !strncmp (q
, ".req ", 4))
6360 char * copy_of_str
= str
;
6364 skip_whitespace (q
);
6366 for (r
= q
; *r
!= '\0'; r
++)
6376 regnum
= arm_reg_parse (& q
);
6379 reg
= arm_reg_parse (& str
);
6384 insert_reg_alias (str
, regnum
);
6386 as_warn (_("register '%s' does not exist\n"), q
);
6388 else if (regnum
!= FAIL
)
6391 as_warn (_("ignoring redefinition of register alias '%s'"),
6394 /* Do not warn about redefinitions to the same alias. */
6397 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6401 as_warn (_("ignoring incomplete .req pseuso op"));
6408 as_bad (_("bad instruction `%s'"), start
);
6413 * Invocation line includes a switch not recognized by the base assembler.
6414 * See if it's a processor-specific option. These are:
6415 * Cpu variants, the arm part is optional:
6416 * -m[arm]1 Currently not supported.
6417 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6418 * -m[arm]3 Arm 3 processor
6419 * -m[arm]6[xx], Arm 6 processors
6420 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6421 * -m[arm]8[10] Arm 8 processors
6422 * -m[arm]9[20][tdmi] Arm 9 processors
6423 * -mstrongarm[110[0]] StrongARM processors
6424 * -m[arm]v[2345[t]] Arm architectures
6425 * -mall All (except the ARM1)
6427 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6428 * -mfpe-old (No float load/store multiples)
6429 * -mno-fpu Disable all floating point instructions
6430 * Run-time endian selection:
6431 * -EB big endian cpu
6432 * -EL little endian cpu
6433 * ARM Procedure Calling Standard:
6434 * -mapcs-32 32 bit APCS
6435 * -mapcs-26 26 bit APCS
6436 * -mapcs-float Pass floats in float regs
6437 * -mapcs-reentrant Position independent code
6438 * -mthumb-interwork Code supports Arm/Thumb interworking
6439 * -moabi Old ELF ABI
6442 CONST
char * md_shortopts
= "m:k";
6443 struct option md_longopts
[] =
6445 #ifdef ARM_BI_ENDIAN
6446 #define OPTION_EB (OPTION_MD_BASE + 0)
6447 {"EB", no_argument
, NULL
, OPTION_EB
},
6448 #define OPTION_EL (OPTION_MD_BASE + 1)
6449 {"EL", no_argument
, NULL
, OPTION_EL
},
6451 #define OPTION_OABI (OPTION_MD_BASE +2)
6452 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6455 {NULL
, no_argument
, NULL
, 0}
6457 size_t md_longopts_size
= sizeof (md_longopts
);
6460 md_parse_option (c
, arg
)
6468 #ifdef ARM_BI_ENDIAN
6470 target_big_endian
= 1;
6473 target_big_endian
= 0;
6481 if (streq (str
, "fpa10"))
6482 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6483 else if (streq (str
, "fpa11"))
6484 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6485 else if (streq (str
, "fpe-old"))
6486 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6492 if (streq (str
, "no-fpu"))
6493 cpu_variant
&= ~FPU_ALL
;
6498 if (streq (str
, "oabi"))
6504 /* Limit assembler to generating only Thumb instructions: */
6505 if (streq (str
, "thumb"))
6507 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6508 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6511 else if (streq (str
, "thumb-interwork"))
6513 if ((cpu_variant
& ARM_THUMB
) == 0)
6514 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4T
;
6515 #if defined OBJ_COFF || defined OBJ_ELF
6516 support_interwork
= true;
6524 if (streq (str
, "all"))
6526 cpu_variant
= ARM_ALL
| FPU_ALL
;
6529 #if defined OBJ_COFF || defined OBJ_ELF
6530 if (! strncmp (str
, "apcs-", 5))
6532 /* GCC passes on all command line options starting "-mapcs-..."
6533 to us, so we must parse them here. */
6537 if (streq (str
, "32"))
6539 uses_apcs_26
= false;
6542 else if (streq (str
, "26"))
6544 uses_apcs_26
= true;
6547 else if (streq (str
, "frame"))
6549 /* Stack frames are being generated - does not affect
6553 else if (streq (str
, "stack-check"))
6555 /* Stack checking is being performed - does not affect
6556 linkage, but does require that the functions
6557 __rt_stkovf_split_small and __rt_stkovf_split_big be
6558 present in the final link. */
6562 else if (streq (str
, "float"))
6564 /* Floating point arguments are being passed in the floating
6565 point registers. This does affect linking, since this
6566 version of the APCS is incompatible with the version that
6567 passes floating points in the integer registers. */
6569 uses_apcs_float
= true;
6572 else if (streq (str
, "reentrant"))
6574 /* Reentrant code has been generated. This does affect
6575 linking, since there is no point in linking reentrant/
6576 position independent code with absolute position code. */
6581 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6585 /* Strip off optional "arm" */
6586 if (! strncmp (str
, "arm", 3))
6592 if (streq (str
, "1"))
6593 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6599 if (streq (str
, "2"))
6600 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6601 else if (streq (str
, "250"))
6602 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6608 if (streq (str
, "3"))
6609 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6615 switch (strtol (str
, NULL
, 10))
6622 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6630 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6643 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6649 cpu_variant
|= (ARM_THUMB
| ARM_ARCH_V4
);
6653 cpu_variant
|= ARM_LONGMUL
;
6656 case 'f': /* fe => fp enabled cpu. */
6662 case 'c': /* Left over from 710c processor name. */
6663 case 'd': /* Debug */
6664 case 'i': /* Embedded ICE */
6665 /* Included for completeness in ARM processor naming. */
6675 if (streq (str
, "8") || streq (str
, "810"))
6676 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6677 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6683 if (streq (str
, "9"))
6684 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6685 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6686 else if (streq (str
, "920"))
6687 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6688 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
;
6689 else if (streq (str
, "920t"))
6690 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6691 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6692 else if (streq (str
, "9tdmi"))
6693 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6694 | ARM_9
| ARM_ARCH_V4
| ARM_LONGMUL
| ARM_THUMB
;
6701 if (streq (str
, "strongarm")
6702 || streq (str
, "strongarm110")
6703 || streq (str
, "strongarm1100"))
6704 cpu_variant
= (cpu_variant
& ~ARM_ANY
)
6705 | ARM_8
| ARM_ARCH_V4
| ARM_LONGMUL
;
6711 /* Select variant based on architecture rather than processor. */
6718 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6721 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6724 as_bad (_("Invalid architecture variant -m%s"), arg
);
6730 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6734 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6737 as_bad (_("Invalid architecture variant -m%s"), arg
);
6743 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V4
;
6747 case 't': cpu_variant
|= ARM_THUMB
; break;
6750 as_bad (_("Invalid architecture variant -m%s"), arg
);
6756 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCH_V5
;
6759 case 't': cpu_variant
|= ARM_THUMB
; break;
6760 case 'e': cpu_variant
|= ARM_EXT_V5E
; break;
6763 as_bad (_("Invalid architecture variant -m%s"), arg
);
6769 as_bad (_("Invalid architecture variant -m%s"), arg
);
6776 as_bad (_("Invalid processor variant -m%s"), arg
);
6782 #if defined OBJ_ELF || defined OBJ_COFF
6800 ARM Specific Assembler Options:\n\
6801 -m[arm][<processor name>] select processor variant\n\
6802 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
6803 -mthumb only allow Thumb instructions\n\
6804 -mthumb-interwork mark the assembled code as supporting interworking\n\
6805 -mall allow any instruction\n\
6806 -mfpa10, -mfpa11 select floating point architecture\n\
6807 -mfpe-old don't allow floating-point multiple instructions\n\
6808 -mno-fpu don't allow any floating-point instructions.\n\
6809 -k generate PIC code.\n"));
6810 #if defined OBJ_COFF || defined OBJ_ELF
6812 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
6813 -mapcs-float floating point args are passed in FP regs\n\
6814 -mapcs-reentrant the code is position independent/reentrant\n"));
6818 -moabi support the old ELF ABI\n"));
6820 #ifdef ARM_BI_ENDIAN
6822 -EB assemble code for a big endian cpu\n\
6823 -EL assemble code for a little endian cpu\n"));
6827 /* We need to be able to fix up arbitrary expressions in some statements.
6828 This is so that we can handle symbols that are an arbitrary distance from
6829 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6830 which returns part of an address in a form which will be valid for
6831 a data instruction. We do this by pushing the expression into a symbol
6832 in the expr_section, and creating a fix for that. */
6835 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6844 arm_fix_data
* arm_data
;
6852 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6856 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6861 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6862 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6863 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6864 arm_data
->thumb_mode
= thumb_mode
;
6870 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6872 cons_fix_new_arm (frag
, where
, size
, exp
)
6878 bfd_reloc_code_real_type type
;
6882 FIXME: @@ Should look at CPU word size. */
6889 type
= BFD_RELOC_16
;
6893 type
= BFD_RELOC_32
;
6896 type
= BFD_RELOC_64
;
6900 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6903 /* A good place to do this, although this was probably not intended
6904 for this kind of use. We need to dump the literal pool before
6905 references are made to a null symbol pointer. */
6909 if (current_poolP
== NULL
)
6912 subseg_set (text_section
, 0); /* Put it at the end of text section. */
6914 listing_prev_line ();
6918 arm_start_line_hook ()
6920 last_label_seen
= NULL
;
6924 arm_frob_label (sym
)
6927 last_label_seen
= sym
;
6929 ARM_SET_THUMB (sym
, thumb_mode
);
6931 #if defined OBJ_COFF || defined OBJ_ELF
6932 ARM_SET_INTERWORK (sym
, support_interwork
);
6935 if (label_is_thumb_function_name
)
6937 /* When the address of a Thumb function is taken the bottom
6938 bit of that address should be set. This will allow
6939 interworking between Arm and Thumb functions to work
6942 THUMB_SET_FUNC (sym
, 1);
6944 label_is_thumb_function_name
= false;
6948 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6952 arm_adjust_symtab ()
6957 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6959 if (ARM_IS_THUMB (sym
))
6961 if (THUMB_IS_FUNC (sym
))
6963 /* Mark the symbol as a Thumb function. */
6964 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6965 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6966 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6968 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6969 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6971 as_bad (_("%s: unexpected function type: %d"),
6972 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6974 else switch (S_GET_STORAGE_CLASS (sym
))
6977 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6980 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6983 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6985 default: /* do nothing */
6990 if (ARM_IS_INTERWORK (sym
))
6991 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
6998 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
7000 if (ARM_IS_THUMB (sym
))
7002 elf_symbol_type
* elf_sym
;
7004 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
7005 bind
= ELF_ST_BIND (elf_sym
);
7007 /* If it's a .thumb_func, declare it as so,
7008 otherwise tag label as .code 16. */
7009 if (THUMB_IS_FUNC (sym
))
7010 elf_sym
->internal_elf_sym
.st_info
=
7011 ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
7013 elf_sym
->internal_elf_sym
.st_info
=
7014 ELF_ST_INFO (bind
, STT_ARM_16BIT
);
7023 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
7025 *input_line_pointer
= '/';
7026 input_line_pointer
+= 5;
7027 *input_line_pointer
= 0;
7035 arm_canonicalize_symbol_name (name
)
7040 if (thumb_mode
&& (len
= strlen (name
)) > 5
7041 && streq (name
+ len
- 5, "/data"))
7042 *(name
+ len
- 5) = 0;
7048 arm_validate_fix (fixP
)
7051 /* If the destination of the branch is a defined symbol which does not have
7052 the THUMB_FUNC attribute, then we must be calling a function which has
7053 the (interfacearm) attribute. We look for the Thumb entry point to that
7054 function and change the branch to refer to that function instead. */
7055 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
7056 && fixP
->fx_addsy
!= NULL
7057 && S_IS_DEFINED (fixP
->fx_addsy
)
7058 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
7060 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
7068 /* Relocations against Thumb function names must be left unadjusted,
7069 so that the linker can use this information to correctly set the
7070 bottom bit of their addresses. The MIPS version of this function
7071 also prevents relocations that are mips-16 specific, but I do not
7072 know why it does this.
7075 There is one other problem that ought to be addressed here, but
7076 which currently is not: Taking the address of a label (rather
7077 than a function) and then later jumping to that address. Such
7078 addresses also ought to have their bottom bit set (assuming that
7079 they reside in Thumb code), but at the moment they will not. */
7082 arm_fix_adjustable (fixP
)
7085 if (fixP
->fx_addsy
== NULL
)
7088 /* Prevent all adjustments to global symbols. */
7089 if (S_IS_EXTERN (fixP
->fx_addsy
))
7092 if (S_IS_WEAK (fixP
->fx_addsy
))
7095 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
7096 && fixP
->fx_subsy
== NULL
)
7099 /* We need the symbol name for the VTABLE entries */
7100 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7101 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
7108 elf32_arm_target_format ()
7110 if (target_big_endian
)
7112 return "elf32-bigarm-oabi";
7114 return "elf32-bigarm";
7117 return "elf32-littlearm-oabi";
7119 return "elf32-littlearm";
7123 armelf_frob_symbol (symp
, puntp
)
7127 elf_frob_symbol (symp
, puntp
);
7131 arm_force_relocation (fixp
)
7134 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
7135 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
7136 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
7137 || fixp
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
)
7143 static bfd_reloc_code_real_type
7153 bfd_reloc_code_real_type reloc
;
7157 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7158 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
7159 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
7160 /* ScottB: Jan 30, 1998 */
7161 /* Added support for parsing "var(PLT)" branch instructions */
7162 /* generated by GCC for PLT relocs */
7163 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
7164 { NULL
, 0, BFD_RELOC_UNUSED
}
7168 for (i
= 0, ip
= input_line_pointer
;
7169 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
7171 id
[i
] = tolower (*ip
);
7173 for (i
= 0; reloc_map
[i
].str
; i
++)
7174 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
7177 input_line_pointer
+= reloc_map
[i
].len
;
7179 return reloc_map
[i
].reloc
;
7183 s_arm_elf_cons (nbytes
)
7188 #ifdef md_flush_pending_output
7189 md_flush_pending_output ();
7192 if (is_it_end_of_statement ())
7194 demand_empty_rest_of_line ();
7198 #ifdef md_cons_align
7199 md_cons_align (nbytes
);
7204 bfd_reloc_code_real_type reloc
;
7208 if (exp
.X_op
== O_symbol
7209 && * input_line_pointer
== '('
7210 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
7212 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
7213 int size
= bfd_get_reloc_size (howto
);
7216 as_bad ("%s relocations do not fit in %d bytes",
7217 howto
->name
, nbytes
);
7220 register char * p
= frag_more ((int) nbytes
);
7221 int offset
= nbytes
- size
;
7223 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
7228 emit_expr (& exp
, (unsigned int) nbytes
);
7230 while (*input_line_pointer
++ == ',');
7232 input_line_pointer
--; /* Put terminator back into stream. */
7233 demand_empty_rest_of_line ();
7236 #endif /* OBJ_ELF */