1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999 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 */
55 #define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
57 /* Some useful combinations: */
58 #define ARM_ANY 0x00ffffff
59 #define ARM_2UP 0x00fffffe
60 #define ARM_ALL ARM_2UP /* Not arm1 only */
61 #define ARM_3UP 0x00fffffc
62 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
64 #define FPU_CORE 0x80000000
65 #define FPU_FPA10 0x40000000
66 #define FPU_FPA11 0x40000000
69 /* Some useful combinations */
70 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
71 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
76 #define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB)
78 #define CPU_DEFAULT ARM_ALL
83 #define FPU_DEFAULT FPU_ALL
86 #define streq(a,b) (strcmp (a, b) == 0)
88 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
89 static int target_oabi
= 0;
91 #if defined OBJ_COFF || defined OBJ_ELF
92 /* Flags stored in private area of BFD structure */
93 static boolean uses_apcs_26
= false;
94 static boolean support_interwork
= false;
95 static boolean uses_apcs_float
= false;
96 static boolean pic_code
= false;
99 /* This array holds the chars that always start a comment. If the
100 pre-processor is disabled, these aren't very useful */
101 CONST
char comment_chars
[] = "@";
103 /* This array holds the chars that only start a comment at the beginning of
104 a line. If the line seems to have the form '# 123 filename'
105 .line and .file directives will appear in the pre-processed output */
106 /* Note that input_file.c hand checks for '#' at the beginning of the
107 first line of the input file. This is because the compiler outputs
108 #NO_APP at the beginning of its output. */
109 /* Also note that comments like this one will always work. */
110 CONST
char line_comment_chars
[] = "#";
113 CONST
char line_separator_chars
[] = ";";
115 CONST
char line_separator_chars
[] = "";
118 /* Chars that can be used to separate mant from exp in floating point nums */
119 CONST
char EXP_CHARS
[] = "eE";
121 /* Chars that mean this number is a floating point constant */
125 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
127 /* Prefix characters that indicate the start of an immediate
129 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
132 symbolS
* GOT_symbol
; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
135 CONST
int md_reloc_size
= 8; /* Size of relocation record */
137 static int thumb_mode
= 0; /* non-zero if assembling thumb instructions */
139 typedef struct arm_fix
147 unsigned long instruction
;
152 bfd_reloc_code_real_type type
;
162 CONST
char * template;
166 static CONST
struct asm_shift shift
[] =
182 #define NO_SHIFT_RESTRICT 1
183 #define SHIFT_RESTRICT 0
185 #define NUM_FLOAT_VALS 8
187 CONST
char * fp_const
[] =
189 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
192 /* Number of littlenums required to hold an extended precision number */
193 #define MAX_LITTLENUMS 6
195 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
205 #define CP_T_X 0x00008000
206 #define CP_T_Y 0x00400000
207 #define CP_T_Pre 0x01000000
208 #define CP_T_UD 0x00800000
209 #define CP_T_WB 0x00200000
211 #define CONDS_BIT (0x00100000)
212 #define LOAD_BIT (0x00100000)
213 #define TRANS_BIT (0x00200000)
217 CONST
char * template;
221 /* This is to save a hash look-up in the common case */
222 #define COND_ALWAYS 0xe0000000
224 static CONST
struct asm_cond conds
[] =
228 {"cs", 0x20000000}, {"hs", 0x20000000},
229 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
244 /* Warning: If the top bit of the set_bits is set, then the standard
245 instruction bitmask is ignored, and the new bitmask is taken from
249 CONST
char * template; /* Basic flag string */
250 unsigned long set_bits
; /* Bits to set */
253 static CONST
struct asm_flg s_flag
[] =
259 static CONST
struct asm_flg ldr_flags
[] =
263 {"bt", 0x00400000 | TRANS_BIT
},
270 static CONST
struct asm_flg str_flags
[] =
274 {"bt", 0x00400000 | TRANS_BIT
},
279 static CONST
struct asm_flg byte_flag
[] =
285 static CONST
struct asm_flg cmp_flags
[] =
292 static CONST
struct asm_flg ldm_flags
[] =
305 static CONST
struct asm_flg stm_flags
[] =
318 static CONST
struct asm_flg lfm_flags
[] =
325 static CONST
struct asm_flg sfm_flags
[] =
332 static CONST
struct asm_flg round_flags
[] =
340 /* The implementation of the FIX instruction is broken on some assemblers,
341 in that it accepts a precision specifier as well as a rounding specifier,
342 despite the fact that this is meaningless. To be more compatible, we
343 accept it as well, though of course it does not set any bits. */
344 static CONST
struct asm_flg fix_flags
[] =
361 static CONST
struct asm_flg except_flag
[] =
367 static CONST
struct asm_flg cplong_flag
[] =
375 CONST
char * template;
376 unsigned long number
;
379 #define PSR_FIELD_MASK 0x000f0000
381 #define PSR_FLAGS 0x00080000
382 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
383 #define PSR_ALL 0x00090000
392 static CONST
struct asm_psr psrs
[] =
396 {"cpsr_all", CPSR_ALL
},
398 {"spsr_all", SPSR_ALL
},
401 {"cpsr_flg", CPSR_FLG
},
402 {"spsr_flg", SPSR_FLG
},
405 {"cpsr_c", CPSR_CTL
},
406 {"cpsr_ctl", CPSR_CTL
},
407 {"spsr_c", SPSR_CTL
},
408 {"spsr_ctl", SPSR_CTL
}
411 /* Functions called by parser */
412 /* ARM instructions */
413 static void do_arit
PARAMS ((char *operands
, unsigned long flags
));
414 static void do_cmp
PARAMS ((char *operands
, unsigned long flags
));
415 static void do_mov
PARAMS ((char *operands
, unsigned long flags
));
416 static void do_ldst
PARAMS ((char *operands
, unsigned long flags
));
417 static void do_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
418 static void do_branch
PARAMS ((char *operands
, unsigned long flags
));
419 static void do_swi
PARAMS ((char *operands
, unsigned long flags
));
420 /* Pseudo Op codes */
421 static void do_adr
PARAMS ((char *operands
, unsigned long flags
));
422 static void do_nop
PARAMS ((char *operands
, unsigned long flags
));
424 static void do_mul
PARAMS ((char *operands
, unsigned long flags
));
425 static void do_mla
PARAMS ((char *operands
, unsigned long flags
));
427 static void do_swap
PARAMS ((char *operands
, unsigned long flags
));
429 static void do_msr
PARAMS ((char *operands
, unsigned long flags
));
430 static void do_mrs
PARAMS ((char *operands
, unsigned long flags
));
432 static void do_mull
PARAMS ((char *operands
, unsigned long flags
));
434 static void do_bx
PARAMS ((char *operands
, unsigned long flags
));
436 /* Coprocessor Instructions */
437 static void do_cdp
PARAMS ((char *operands
, unsigned long flags
));
438 static void do_lstc
PARAMS ((char *operands
, unsigned long flags
));
439 static void do_co_reg
PARAMS ((char *operands
, unsigned long flags
));
440 static void do_fp_ctrl
PARAMS ((char *operands
, unsigned long flags
));
441 static void do_fp_ldst
PARAMS ((char *operands
, unsigned long flags
));
442 static void do_fp_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
443 static void do_fp_dyadic
PARAMS ((char *operands
, unsigned long flags
));
444 static void do_fp_monadic
PARAMS ((char *operands
, unsigned long flags
));
445 static void do_fp_cmp
PARAMS ((char *operands
, unsigned long flags
));
446 static void do_fp_from_reg
PARAMS ((char *operands
, unsigned long flags
));
447 static void do_fp_to_reg
PARAMS ((char *operands
, unsigned long flags
));
449 static void fix_new_arm
PARAMS ((fragS
*frag
, int where
,
450 short int size
, expressionS
*exp
,
451 int pc_rel
, int reloc
));
452 static int arm_reg_parse
PARAMS ((char **ccp
));
453 static int arm_psr_parse
PARAMS ((char **ccp
));
454 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
,
456 static int add_to_lit_pool
PARAMS ((void));
457 static unsigned validate_immediate
PARAMS ((unsigned));
458 static int validate_offset_imm
PARAMS ((int, int));
459 static void opcode_select
PARAMS ((int));
460 static void end_of_line
PARAMS ((char *));
461 static int reg_required_here
PARAMS ((char **, int));
462 static int psr_required_here
PARAMS ((char **, int, int));
463 static int co_proc_number
PARAMS ((char **));
464 static int cp_opc_expr
PARAMS ((char **, int, int));
465 static int cp_reg_required_here
PARAMS ((char **, int));
466 static int fp_reg_required_here
PARAMS ((char **, int));
467 static int cp_address_offset
PARAMS ((char **));
468 static int cp_address_required_here
PARAMS ((char **));
469 static int my_get_float_expression
PARAMS ((char **));
470 static int skip_past_comma
PARAMS ((char **));
471 static int walk_no_bignums
PARAMS ((symbolS
*));
472 static int negate_data_op
PARAMS ((unsigned long *,
474 static int data_op2
PARAMS ((char **));
475 static int fp_op2
PARAMS ((char **));
476 static long reg_list
PARAMS ((char **));
477 static void thumb_load_store
PARAMS ((char *, int, int));
478 static int decode_shift
PARAMS ((char **, int));
479 static int ldst_extend
PARAMS ((char **, int));
480 static void thumb_add_sub
PARAMS ((char *, int));
481 static void insert_reg
PARAMS ((int));
482 static void thumb_shift
PARAMS ((char *, int));
483 static void thumb_mov_compare
PARAMS ((char *, int));
484 static void set_constant_flonums
PARAMS ((void));
485 static valueT md_chars_to_number
PARAMS ((char *, int));
486 static void insert_reg_alias
PARAMS ((char *, int));
487 static void output_inst
PARAMS ((char *));
489 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
492 /* ARM instructions take 4bytes in the object file, Thumb instructions
496 /* LONGEST_INST is the longest basic instruction name without conditions or
498 * ARM7M has 4 of length 5
501 #define LONGEST_INST 5
505 CONST
char * template; /* Basic string to match */
506 unsigned long value
; /* Basic instruction code */
507 CONST
char * comp_suffix
; /* Compulsory suffix that must follow conds */
508 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
509 unsigned long variants
; /* Which CPU variants this exists for */
510 /* Function to call to parse args */
511 void (* parms
) PARAMS ((char *, unsigned long));
514 static CONST
struct asm_opcode insns
[] =
516 /* ARM Instructions */
517 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
518 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
519 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
520 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
521 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
522 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
523 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
524 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
525 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
526 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
527 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
528 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
529 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
530 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
531 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
532 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
533 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
534 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
535 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
536 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
537 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
538 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
539 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
542 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
543 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
545 /* ARM 2 multiplies */
546 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
547 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
549 /* ARM 3 - swp instructions */
550 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
552 /* ARM 6 Coprocessor instructions */
553 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
554 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
555 /* ScottB: our code uses 0x0128f000 for msr.
556 NickC: but this is wrong because the bits 16 and 19 are handled
557 by the PSR_xxx defines above. */
559 /* ARM 7M long multiplies - need signed/unsigned flags! */
560 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
561 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
562 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
563 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
565 /* ARM THUMB interworking */
566 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
568 /* Floating point instructions */
569 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
570 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
571 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
572 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
573 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
574 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
575 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
576 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
577 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
578 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
579 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
580 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
581 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
582 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
583 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
584 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
585 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
586 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
587 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
588 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
589 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
590 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
591 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
592 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
593 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
594 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
595 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
596 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
597 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
598 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
599 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
600 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
601 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
602 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
603 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
604 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
605 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
606 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
607 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
608 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
609 be an optional suffix, but part of the instruction. To be compatible,
611 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
612 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
613 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
614 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
616 /* Generic copressor instructions */
617 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
618 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
619 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
620 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
621 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
624 /* defines for various bits that we will want to toggle */
626 #define INST_IMMEDIATE 0x02000000
627 #define OFFSET_REG 0x02000000
628 #define HWOFFSET_IMM 0x00400000
629 #define SHIFT_BY_REG 0x00000010
630 #define PRE_INDEX 0x01000000
631 #define INDEX_UP 0x00800000
632 #define WRITE_BACK 0x00200000
633 #define MULTI_SET_PSR 0x00400000
635 #define LITERAL_MASK 0xf000f000
636 #define COND_MASK 0xf0000000
637 #define OPCODE_MASK 0xfe1fffff
638 #define DATA_OP_SHIFT 21
640 /* Codes to distinguish the arithmetic instructions */
652 #define OPCODE_CMP 10
653 #define OPCODE_CMN 11
654 #define OPCODE_ORR 12
655 #define OPCODE_MOV 13
656 #define OPCODE_BIC 14
657 #define OPCODE_MVN 15
659 static void do_t_nop
PARAMS ((char *operands
));
660 static void do_t_arit
PARAMS ((char *operands
));
661 static void do_t_add
PARAMS ((char *operands
));
662 static void do_t_asr
PARAMS ((char *operands
));
663 static void do_t_branch9
PARAMS ((char *operands
));
664 static void do_t_branch12
PARAMS ((char *operands
));
665 static void do_t_branch23
PARAMS ((char *operands
));
666 static void do_t_bx
PARAMS ((char *operands
));
667 static void do_t_compare
PARAMS ((char *operands
));
668 static void do_t_ldmstm
PARAMS ((char *operands
));
669 static void do_t_ldr
PARAMS ((char *operands
));
670 static void do_t_ldrb
PARAMS ((char *operands
));
671 static void do_t_ldrh
PARAMS ((char *operands
));
672 static void do_t_lds
PARAMS ((char *operands
));
673 static void do_t_lsl
PARAMS ((char *operands
));
674 static void do_t_lsr
PARAMS ((char *operands
));
675 static void do_t_mov
PARAMS ((char *operands
));
676 static void do_t_push_pop
PARAMS ((char *operands
));
677 static void do_t_str
PARAMS ((char *operands
));
678 static void do_t_strb
PARAMS ((char *operands
));
679 static void do_t_strh
PARAMS ((char *operands
));
680 static void do_t_sub
PARAMS ((char *operands
));
681 static void do_t_swi
PARAMS ((char *operands
));
682 static void do_t_adr
PARAMS ((char *operands
));
684 #define T_OPCODE_MUL 0x4340
685 #define T_OPCODE_TST 0x4200
686 #define T_OPCODE_CMN 0x42c0
687 #define T_OPCODE_NEG 0x4240
688 #define T_OPCODE_MVN 0x43c0
690 #define T_OPCODE_ADD_R3 0x1800
691 #define T_OPCODE_SUB_R3 0x1a00
692 #define T_OPCODE_ADD_HI 0x4400
693 #define T_OPCODE_ADD_ST 0xb000
694 #define T_OPCODE_SUB_ST 0xb080
695 #define T_OPCODE_ADD_SP 0xa800
696 #define T_OPCODE_ADD_PC 0xa000
697 #define T_OPCODE_ADD_I8 0x3000
698 #define T_OPCODE_SUB_I8 0x3800
699 #define T_OPCODE_ADD_I3 0x1c00
700 #define T_OPCODE_SUB_I3 0x1e00
702 #define T_OPCODE_ASR_R 0x4100
703 #define T_OPCODE_LSL_R 0x4080
704 #define T_OPCODE_LSR_R 0x40c0
705 #define T_OPCODE_ASR_I 0x1000
706 #define T_OPCODE_LSL_I 0x0000
707 #define T_OPCODE_LSR_I 0x0800
709 #define T_OPCODE_MOV_I8 0x2000
710 #define T_OPCODE_CMP_I8 0x2800
711 #define T_OPCODE_CMP_LR 0x4280
712 #define T_OPCODE_MOV_HR 0x4600
713 #define T_OPCODE_CMP_HR 0x4500
715 #define T_OPCODE_LDR_PC 0x4800
716 #define T_OPCODE_LDR_SP 0x9800
717 #define T_OPCODE_STR_SP 0x9000
718 #define T_OPCODE_LDR_IW 0x6800
719 #define T_OPCODE_STR_IW 0x6000
720 #define T_OPCODE_LDR_IH 0x8800
721 #define T_OPCODE_STR_IH 0x8000
722 #define T_OPCODE_LDR_IB 0x7800
723 #define T_OPCODE_STR_IB 0x7000
724 #define T_OPCODE_LDR_RW 0x5800
725 #define T_OPCODE_STR_RW 0x5000
726 #define T_OPCODE_LDR_RH 0x5a00
727 #define T_OPCODE_STR_RH 0x5200
728 #define T_OPCODE_LDR_RB 0x5c00
729 #define T_OPCODE_STR_RB 0x5400
731 #define T_OPCODE_PUSH 0xb400
732 #define T_OPCODE_POP 0xbc00
734 #define T_OPCODE_BRANCH 0xe7fe
736 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
738 #define THUMB_SIZE 2 /* Size of thumb instruction */
739 #define THUMB_REG_LO 0x1
740 #define THUMB_REG_HI 0x2
741 #define THUMB_REG_ANY 0x3
743 #define THUMB_H1 0x0080
744 #define THUMB_H2 0x0040
751 #define THUMB_COMPARE 1
754 #define THUMB_STORE 1
756 #define THUMB_PP_PC_LR 0x0100
758 /* These three are used for immediate shifts, do not alter */
760 #define THUMB_HALFWORD 1
765 CONST
char * template; /* Basic string to match */
766 unsigned long value
; /* Basic instruction code */
768 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
771 static CONST
struct thumb_opcode tinsns
[] =
773 {"adc", 0x4140, 2, do_t_arit
},
774 {"add", 0x0000, 2, do_t_add
},
775 {"and", 0x4000, 2, do_t_arit
},
776 {"asr", 0x0000, 2, do_t_asr
},
777 {"b", T_OPCODE_BRANCH
, 2, do_t_branch12
},
778 {"beq", 0xd0fe, 2, do_t_branch9
},
779 {"bne", 0xd1fe, 2, do_t_branch9
},
780 {"bcs", 0xd2fe, 2, do_t_branch9
},
781 {"bhs", 0xd2fe, 2, do_t_branch9
},
782 {"bcc", 0xd3fe, 2, do_t_branch9
},
783 {"bul", 0xd3fe, 2, do_t_branch9
},
784 {"blo", 0xd3fe, 2, do_t_branch9
},
785 {"bmi", 0xd4fe, 2, do_t_branch9
},
786 {"bpl", 0xd5fe, 2, do_t_branch9
},
787 {"bvs", 0xd6fe, 2, do_t_branch9
},
788 {"bvc", 0xd7fe, 2, do_t_branch9
},
789 {"bhi", 0xd8fe, 2, do_t_branch9
},
790 {"bls", 0xd9fe, 2, do_t_branch9
},
791 {"bge", 0xdafe, 2, do_t_branch9
},
792 {"blt", 0xdbfe, 2, do_t_branch9
},
793 {"bgt", 0xdcfe, 2, do_t_branch9
},
794 {"ble", 0xddfe, 2, do_t_branch9
},
795 {"bic", 0x4380, 2, do_t_arit
},
796 {"bl", 0xf7fffffe, 4, do_t_branch23
},
797 {"bx", 0x4700, 2, do_t_bx
},
798 {"cmn", T_OPCODE_CMN
, 2, do_t_arit
},
799 {"cmp", 0x0000, 2, do_t_compare
},
800 {"eor", 0x4040, 2, do_t_arit
},
801 {"ldmia", 0xc800, 2, do_t_ldmstm
},
802 {"ldr", 0x0000, 2, do_t_ldr
},
803 {"ldrb", 0x0000, 2, do_t_ldrb
},
804 {"ldrh", 0x0000, 2, do_t_ldrh
},
805 {"ldrsb", 0x5600, 2, do_t_lds
},
806 {"ldrsh", 0x5e00, 2, do_t_lds
},
807 {"ldsb", 0x5600, 2, do_t_lds
},
808 {"ldsh", 0x5e00, 2, do_t_lds
},
809 {"lsl", 0x0000, 2, do_t_lsl
},
810 {"lsr", 0x0000, 2, do_t_lsr
},
811 {"mov", 0x0000, 2, do_t_mov
},
812 {"mul", T_OPCODE_MUL
, 2, do_t_arit
},
813 {"mvn", T_OPCODE_MVN
, 2, do_t_arit
},
814 {"neg", T_OPCODE_NEG
, 2, do_t_arit
},
815 {"orr", 0x4300, 2, do_t_arit
},
816 {"pop", 0xbc00, 2, do_t_push_pop
},
817 {"push", 0xb400, 2, do_t_push_pop
},
818 {"ror", 0x41c0, 2, do_t_arit
},
819 {"sbc", 0x4180, 2, do_t_arit
},
820 {"stmia", 0xc000, 2, do_t_ldmstm
},
821 {"str", 0x0000, 2, do_t_str
},
822 {"strb", 0x0000, 2, do_t_strb
},
823 {"strh", 0x0000, 2, do_t_strh
},
824 {"swi", 0xdf00, 2, do_t_swi
},
825 {"sub", 0x0000, 2, do_t_sub
},
826 {"tst", T_OPCODE_TST
, 2, do_t_arit
},
828 {"adr", 0x0000, 2, do_t_adr
},
829 {"nop", 0x46C0, 2, do_t_nop
}, /* mov r8,r8 */
838 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
839 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
840 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
846 /* These are the standard names; Users can add aliases with .req */
847 static CONST
struct reg_entry reg_table
[] =
849 /* Processor Register Numbers */
850 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
851 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
852 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
853 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
854 /* APCS conventions */
855 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
856 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
857 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
858 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
860 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
861 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
862 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
863 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
864 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
865 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
866 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
867 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
868 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
869 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
873 #define bad_args _("Bad arguments to instruction");
874 #define bad_pc _("r15 not allowed here");
876 static struct hash_control
* arm_ops_hsh
= NULL
;
877 static struct hash_control
* arm_tops_hsh
= NULL
;
878 static struct hash_control
* arm_cond_hsh
= NULL
;
879 static struct hash_control
* arm_shift_hsh
= NULL
;
880 static struct hash_control
* arm_reg_hsh
= NULL
;
881 static struct hash_control
* arm_psr_hsh
= NULL
;
883 /* This table describes all the machine specific pseudo-ops the assembler
884 has to support. The fields are:
885 pseudo-op name without dot
886 function to call to execute this pseudo-op
887 Integer arg to pass to the function
890 static void s_req
PARAMS ((int));
891 static void s_align
PARAMS ((int));
892 static void s_bss
PARAMS ((int));
893 static void s_even
PARAMS ((int));
894 static void s_ltorg
PARAMS ((int));
895 static void s_arm
PARAMS ((int));
896 static void s_thumb
PARAMS ((int));
897 static void s_code
PARAMS ((int));
898 static void s_force_thumb
PARAMS ((int));
899 static void s_thumb_func
PARAMS ((int));
901 static void s_arm_elf_cons
PARAMS ((int));
904 static int my_get_expression
PARAMS ((expressionS
*, char **));
906 CONST pseudo_typeS md_pseudo_table
[] =
908 {"req", s_req
, 0}, /* Never called becasue '.req' does not start line */
910 {"align", s_align
, 0},
912 {"thumb", s_thumb
, 0},
914 {"force_thumb", s_force_thumb
, 0},
915 {"thumb_func", s_thumb_func
, 0},
917 {"ltorg", s_ltorg
, 0},
918 {"pool", s_ltorg
, 0},
920 {"word", s_arm_elf_cons
, 4},
921 {"long", s_arm_elf_cons
, 4},
925 {"extend", float_cons
, 'x'},
926 {"ldouble", float_cons
, 'x'},
927 {"packed", float_cons
, 'p'},
931 /* Stuff needed to resolve the label ambiguity
941 symbolS
* last_label_seen
;
942 static int label_is_thumb_function_name
= false;
946 #define MAX_LITERAL_POOL_SIZE 1024
948 typedef struct literalS
950 struct expressionS exp
;
951 struct arm_it
* inst
;
954 literalT literals
[MAX_LITERAL_POOL_SIZE
];
955 int next_literal_pool_place
= 0; /* Next free entry in the pool */
956 int lit_pool_num
= 1; /* Next literal pool number */
957 symbolS
* current_poolP
= NULL
;
964 if (current_poolP
== NULL
)
965 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
966 (valueT
) 0, &zero_address_frag
);
968 /* Check if this literal value is already in the pool: */
969 while (lit_count
< next_literal_pool_place
)
971 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
972 && inst
.reloc
.exp
.X_op
== O_constant
973 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
974 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
979 if (lit_count
== next_literal_pool_place
) /* new entry */
981 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
983 inst
.error
= _("Literal Pool Overflow");
987 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
988 lit_count
= next_literal_pool_place
++;
991 inst
.reloc
.exp
.X_op
= O_symbol
;
992 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
993 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
998 /* Can't use symbol_new here, so have to create a symbol and then at
999 a later date assign it a value. Thats what these functions do. */
1001 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1003 CONST
char * name
; /* It is copied, the caller can modify */
1004 segT segment
; /* Segment identifier (SEG_<something>) */
1005 valueT valu
; /* Symbol value */
1006 fragS
* frag
; /* Associated fragment */
1008 unsigned int name_length
;
1009 char * preserved_copy_of_name
;
1011 name_length
= strlen (name
) + 1; /* +1 for \0 */
1012 obstack_grow (¬es
, name
, name_length
);
1013 preserved_copy_of_name
= obstack_finish (¬es
);
1014 #ifdef STRIP_UNDERSCORE
1015 if (preserved_copy_of_name
[0] == '_')
1016 preserved_copy_of_name
++;
1019 #ifdef tc_canonicalize_symbol_name
1020 preserved_copy_of_name
=
1021 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1024 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1026 S_SET_SEGMENT (symbolP
, segment
);
1027 S_SET_VALUE (symbolP
, valu
);
1028 symbol_clear_list_pointers(symbolP
);
1030 symbol_set_frag (symbolP
, frag
);
1032 /* Link to end of symbol chain. */
1034 extern int symbol_table_frozen
;
1035 if (symbol_table_frozen
)
1039 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1041 obj_symbol_new_hook (symbolP
);
1043 #ifdef tc_symbol_new_hook
1044 tc_symbol_new_hook (symbolP
);
1048 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1049 #endif /* DEBUG_SYMS */
1052 /* Check that an immediate is valid, and if so, convert it to the right format. */
1055 validate_immediate (val
)
1061 #define rotate_left(v, n) (v << n | v >> (32 - n))
1063 for (i
= 0; i
< 32; i
+= 2)
1064 if ((a
= rotate_left (val
, i
)) <= 0xff)
1065 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1071 validate_offset_imm (val
, hwse
)
1075 if ((hwse
&& (val
< -255 || val
> 255))
1076 || (val
< -4095 || val
> 4095))
1086 as_bad (_("Invalid syntax for .req directive."));
1093 /* We don't support putting frags in the BSS segment, we fake it by
1094 marking in_bss, then looking at s_skip for clues?.. */
1095 subseg_set (bss_section
, 0);
1096 demand_empty_rest_of_line ();
1103 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1104 frag_align (1, 0, 0);
1106 record_alignment (now_seg
, 1);
1108 demand_empty_rest_of_line ();
1118 if (current_poolP
== NULL
)
1122 as_tsktsk (_("Nothing to put in the pool\n"));
1126 /* Align pool as you have word accesses */
1127 /* Only make a frag if we have to ... */
1129 frag_align (2, 0, 0);
1131 record_alignment (now_seg
, 2);
1134 as_tsktsk (_("Inserting implicit pool at change of section"));
1136 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1138 symbol_locate (current_poolP
, sym_name
, now_seg
,
1139 (valueT
) frag_now_fix (), frag_now
);
1140 symbol_table_insert (current_poolP
);
1142 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1144 #if defined OBJ_COFF || defined OBJ_ELF
1145 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1148 while (lit_count
< next_literal_pool_place
)
1149 /* First output the expression in the instruction to the pool */
1150 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1152 next_literal_pool_place
= 0;
1153 current_poolP
= NULL
;
1157 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1161 register long temp_fill
;
1162 long max_alignment
= 15;
1164 temp
= get_absolute_expression ();
1165 if (temp
> max_alignment
)
1166 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1169 as_bad (_("Alignment negative. 0 assumed."));
1173 if (*input_line_pointer
== ',')
1175 input_line_pointer
++;
1176 temp_fill
= get_absolute_expression ();
1184 /* Only make a frag if we HAVE to. . . */
1185 if (temp
&& !need_pass_2
)
1186 frag_align (temp
, (int) temp_fill
, 0);
1187 demand_empty_rest_of_line ();
1189 record_alignment (now_seg
, temp
);
1193 s_force_thumb (ignore
)
1196 /* If we are not already in thumb mode go into it, EVEN if
1197 the target processor does not support thumb instructions.
1198 This is used by gcc/config/arm/lib1funcs.asm for example
1199 to compile interworking support functions even if the
1200 target processor should not support interworking. */
1206 record_alignment (now_seg
, 1);
1209 demand_empty_rest_of_line ();
1213 s_thumb_func (ignore
)
1216 /* The following label is the name/address of the start of a Thumb function.
1217 We need to know this for the interworking support. */
1219 label_is_thumb_function_name
= true;
1221 demand_empty_rest_of_line ();
1225 opcode_select (width
)
1233 if (! (cpu_variant
& ARM_THUMB
))
1234 as_bad (_("selected processor does not support THUMB opcodes"));
1236 /* No need to force the alignment, since we will have been
1237 coming from ARM mode, which is word-aligned. */
1238 record_alignment (now_seg
, 1);
1245 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1246 as_bad (_("selected processor does not support ARM opcodes"));
1249 frag_align (2, 0, 0);
1250 record_alignment (now_seg
, 1);
1255 as_bad (_("invalid instruction size selected (%d)"), width
);
1264 demand_empty_rest_of_line ();
1272 demand_empty_rest_of_line ();
1281 temp
= get_absolute_expression ();
1286 opcode_select (temp
);
1290 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1302 inst
.error
= _("Garbage following instruction");
1306 skip_past_comma (str
)
1312 while ((c
= *p
) == ' ' || c
== ',')
1315 if (c
== ',' && comma
++)
1323 return comma
? SUCCESS
: FAIL
;
1326 /* A standard register must be given at this point. Shift is the place to
1327 put it in the instruction. */
1330 reg_required_here (str
, shift
)
1334 static char buff
[128]; /* XXX */
1336 char * start
= *str
;
1338 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1341 inst
.instruction
|= reg
<< shift
;
1345 /* Restore the start point, we may have got a reg of the wrong class. */
1348 /* In the few cases where we might be able to accept something else
1349 this error can be overridden */
1350 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1357 psr_required_here (str
, cpsr
, spsr
)
1363 char * start
= *str
;
1364 psr
= arm_psr_parse (str
);
1366 if (psr
== cpsr
|| psr
== spsr
)
1369 inst
.instruction
|= 1 << 22;
1374 /* In the few cases where we might be able to accept something else
1375 this error can be overridden */
1376 inst
.error
= _("<psr(f)> expected");
1378 /* Restore the start point. */
1384 co_proc_number (str
)
1387 int processor
, pchar
;
1389 while (**str
== ' ')
1392 /* The data sheet seems to imply that just a number on its own is valid
1393 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1395 if (**str
== 'p' || **str
== 'P')
1399 if (pchar
>= '0' && pchar
<= '9')
1401 processor
= pchar
- '0';
1402 if (**str
>= '0' && **str
<= '9')
1404 processor
= processor
* 10 + *(*str
)++ - '0';
1407 inst
.error
= _("Illegal co-processor number");
1414 inst
.error
= _("Bad or missing co-processor number");
1418 inst
.instruction
|= processor
<< 8;
1423 cp_opc_expr (str
, where
, length
)
1430 while (**str
== ' ')
1433 memset (&expr
, '\0', sizeof (expr
));
1435 if (my_get_expression (&expr
, str
))
1437 if (expr
.X_op
!= O_constant
)
1439 inst
.error
= _("bad or missing expression");
1443 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1445 inst
.error
= _("immediate co-processor expression too large");
1449 inst
.instruction
|= expr
.X_add_number
<< where
;
1454 cp_reg_required_here (str
, where
)
1459 char * start
= *str
;
1461 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1464 inst
.instruction
|= reg
<< where
;
1468 /* In the few cases where we might be able to accept something else
1469 this error can be overridden */
1470 inst
.error
= _("Co-processor register expected");
1472 /* Restore the start point */
1478 fp_reg_required_here (str
, where
)
1483 char * start
= *str
;
1485 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1488 inst
.instruction
|= reg
<< where
;
1492 /* In the few cases where we might be able to accept something else
1493 this error can be overridden */
1494 inst
.error
= _("Floating point register expected");
1496 /* Restore the start point */
1502 cp_address_offset (str
)
1507 while (**str
== ' ')
1510 if (! is_immediate_prefix (**str
))
1512 inst
.error
= _("immediate expression expected");
1518 if (my_get_expression (& inst
.reloc
.exp
, str
))
1521 if (inst
.reloc
.exp
.X_op
== O_constant
)
1523 offset
= inst
.reloc
.exp
.X_add_number
;
1527 inst
.error
= _("co-processor address must be word aligned");
1531 if (offset
> 1023 || offset
< -1023)
1533 inst
.error
= _("offset too large");
1538 inst
.instruction
|= INDEX_UP
;
1542 inst
.instruction
|= offset
>> 2;
1545 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1551 cp_address_required_here (str
)
1566 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1576 if (skip_past_comma (& p
) == SUCCESS
)
1579 write_back
= WRITE_BACK
;
1583 inst
.error
= _("pc may not be used in post-increment");
1587 if (cp_address_offset (& p
) == FAIL
)
1591 pre_inc
= PRE_INDEX
| INDEX_UP
;
1595 /* '['Rn, #expr']'[!] */
1597 if (skip_past_comma (& p
) == FAIL
)
1599 inst
.error
= _("pre-indexed expression expected");
1603 pre_inc
= PRE_INDEX
;
1605 if (cp_address_offset (& p
) == FAIL
)
1613 inst
.error
= _("missing ]");
1624 inst
.error
= _("pc may not be used with write-back");
1629 write_back
= WRITE_BACK
;
1635 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1638 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1639 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1640 inst
.reloc
.pc_rel
= 1;
1641 inst
.instruction
|= (REG_PC
<< 16);
1642 pre_inc
= PRE_INDEX
;
1645 inst
.instruction
|= write_back
| pre_inc
;
1653 unsigned long flags
;
1655 /* Do nothing really */
1656 inst
.instruction
|= flags
; /* This is pointless */
1664 unsigned long flags
;
1666 /* Only one syntax */
1670 if (reg_required_here (&str
, 12) == FAIL
)
1672 inst
.error
= bad_args
;
1676 if (skip_past_comma (&str
) == FAIL
1677 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1679 inst
.error
= _("<psr> expected");
1683 inst
.instruction
|= flags
;
1688 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1692 unsigned long flags
;
1699 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1701 inst
.instruction
|= PSR_ALL
;
1703 /* Sytax should be "<psr>, Rm" */
1704 if (skip_past_comma (&str
) == FAIL
1705 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1707 inst
.error
= bad_args
;
1713 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1714 inst
.instruction
|= PSR_FLAGS
;
1715 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1716 inst
.instruction
|= PSR_CONTROL
;
1719 inst
.error
= bad_args
;
1723 if (skip_past_comma (&str
) == FAIL
)
1725 inst
.error
= bad_args
;
1729 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1731 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1733 /* Immediate expression */
1734 else if (is_immediate_prefix (* str
))
1739 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1741 inst
.error
= _("Register or shift expression expected");
1745 if (inst
.reloc
.exp
.X_add_symbol
)
1747 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1748 inst
.reloc
.pc_rel
= 0;
1752 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1755 inst
.error
= _("Invalid constant");
1759 inst
.instruction
|= value
;
1762 flags
|= INST_IMMEDIATE
;
1766 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1772 inst
.instruction
|= flags
;
1777 /* Long Multiply Parser
1778 UMULL RdLo, RdHi, Rm, Rs
1779 SMULL RdLo, RdHi, Rm, Rs
1780 UMLAL RdLo, RdHi, Rm, Rs
1781 SMLAL RdLo, RdHi, Rm, Rs
1784 do_mull (str
, flags
)
1786 unsigned long flags
;
1788 int rdlo
, rdhi
, rm
, rs
;
1790 /* only one format "rdlo, rdhi, rm, rs" */
1794 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1796 inst
.error
= bad_args
;
1800 if (skip_past_comma (&str
) == FAIL
1801 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1803 inst
.error
= bad_args
;
1807 if (skip_past_comma (&str
) == FAIL
1808 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1810 inst
.error
= bad_args
;
1814 /* rdhi, rdlo and rm must all be different */
1815 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1816 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1818 if (skip_past_comma (&str
) == FAIL
1819 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1821 inst
.error
= bad_args
;
1825 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1827 inst
.error
= bad_pc
;
1831 inst
.instruction
|= flags
;
1839 unsigned long flags
;
1843 /* only one format "rd, rm, rs" */
1847 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1849 inst
.error
= bad_args
;
1855 inst
.error
= bad_pc
;
1859 if (skip_past_comma (&str
) == FAIL
1860 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1862 inst
.error
= bad_args
;
1868 inst
.error
= bad_pc
;
1873 as_tsktsk (_("rd and rm should be different in mul"));
1875 if (skip_past_comma (&str
) == FAIL
1876 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
1878 inst
.error
= bad_args
;
1884 inst
.error
= bad_pc
;
1888 inst
.instruction
|= flags
;
1896 unsigned long flags
;
1900 /* only one format "rd, rm, rs, rn" */
1904 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1906 inst
.error
= bad_args
;
1912 inst
.error
= bad_pc
;
1916 if (skip_past_comma (&str
) == FAIL
1917 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1919 inst
.error
= bad_args
;
1925 inst
.error
= bad_pc
;
1930 as_tsktsk (_("rd and rm should be different in mla"));
1932 if (skip_past_comma (&str
) == FAIL
1933 || (rd
= reg_required_here (&str
, 8)) == FAIL
1934 || skip_past_comma (&str
) == FAIL
1935 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
1937 inst
.error
= bad_args
;
1941 if (rd
== REG_PC
|| rm
== REG_PC
)
1943 inst
.error
= bad_pc
;
1947 inst
.instruction
|= flags
;
1952 /* Returns the index into fp_values of a floating point number, or -1 if
1953 not in the table. */
1955 my_get_float_expression (str
)
1958 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1964 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
1965 /* Look for a raw floating point number */
1966 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
1967 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
1969 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
1971 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
1973 if (words
[j
] != fp_values
[i
][j
])
1977 if (j
== MAX_LITTLENUMS
)
1985 /* Try and parse a more complex expression, this will probably fail
1986 unless the code uses a floating point prefix (eg "0f") */
1987 save_in
= input_line_pointer
;
1988 input_line_pointer
= *str
;
1989 if (expression (&exp
) == absolute_section
1990 && exp
.X_op
== O_big
1991 && exp
.X_add_number
< 0)
1993 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
1995 if (gen_to_words (words
, 5, (long)15) == 0)
1997 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
1999 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2001 if (words
[j
] != fp_values
[i
][j
])
2005 if (j
== MAX_LITTLENUMS
)
2007 *str
= input_line_pointer
;
2008 input_line_pointer
= save_in
;
2015 *str
= input_line_pointer
;
2016 input_line_pointer
= save_in
;
2020 /* Return true if anything in the expression is a bignum */
2022 walk_no_bignums (sp
)
2025 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2028 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2030 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2031 || (symbol_get_value_expression (sp
)->X_op_symbol
2032 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2039 my_get_expression (ep
, str
)
2046 save_in
= input_line_pointer
;
2047 input_line_pointer
= *str
;
2048 seg
= expression (ep
);
2051 if (seg
!= absolute_section
2052 && seg
!= text_section
2053 && seg
!= data_section
2054 && seg
!= bss_section
2055 && seg
!= undefined_section
)
2057 inst
.error
= _("bad_segment");
2058 *str
= input_line_pointer
;
2059 input_line_pointer
= save_in
;
2064 /* Get rid of any bignums now, so that we don't generate an error for which
2065 we can't establish a line number later on. Big numbers are never valid
2066 in instructions, which is where this routine is always called. */
2067 if (ep
->X_op
== O_big
2068 || (ep
->X_add_symbol
2069 && (walk_no_bignums (ep
->X_add_symbol
)
2071 && walk_no_bignums (ep
->X_op_symbol
)))))
2073 inst
.error
= _("Invalid constant");
2074 *str
= input_line_pointer
;
2075 input_line_pointer
= save_in
;
2079 *str
= input_line_pointer
;
2080 input_line_pointer
= save_in
;
2084 /* unrestrict should be one if <shift> <register> is permitted for this
2088 decode_shift (str
, unrestrict
)
2092 struct asm_shift
* shft
;
2096 while (**str
== ' ')
2099 for (p
= *str
; isalpha (*p
); p
++)
2104 inst
.error
= _("Shift expression expected");
2110 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2114 if (!strncmp (*str
, "rrx", 3)
2115 || !strncmp (*str
, "RRX", 3))
2118 inst
.instruction
|= shft
->value
;
2125 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2127 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2131 else if (is_immediate_prefix (* p
))
2135 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2138 /* Validate some simple #expressions */
2139 if (inst
.reloc
.exp
.X_op
== O_constant
)
2141 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2143 /* Reject operations greater than 32, or lsl #32 */
2144 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2146 inst
.error
= _("Invalid immediate shift");
2150 /* Shifts of zero should be converted to lsl (which is zero)*/
2157 /* Shifts of 32 are encoded as 0, for those shifts that
2162 inst
.instruction
|= (num
<< 7) | shft
->value
;
2167 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2168 inst
.reloc
.pc_rel
= 0;
2169 inst
.instruction
|= shft
->value
;
2175 inst
.error
= unrestrict
? _("shift requires register or #expression")
2176 : _("shift requires #expression");
2182 inst
.error
= _("Shift expression expected");
2186 /* Do those data_ops which can take a negative immediate constant */
2187 /* by altering the instuction. A bit of a hack really */
2191 by inverting the second operand, and
2194 by negating the second operand.
2197 negate_data_op (instruction
, value
)
2198 unsigned long * instruction
;
2199 unsigned long value
;
2202 unsigned long negated
, inverted
;
2204 negated
= validate_immediate (-value
);
2205 inverted
= validate_immediate (~value
);
2207 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2211 case OPCODE_SUB
: /* ADD <-> SUB */
2212 new_inst
= OPCODE_ADD
;
2217 new_inst
= OPCODE_SUB
;
2221 case OPCODE_CMP
: /* CMP <-> CMN */
2222 new_inst
= OPCODE_CMN
;
2227 new_inst
= OPCODE_CMP
;
2231 /* Now Inverted ops */
2232 case OPCODE_MOV
: /* MOV <-> MVN */
2233 new_inst
= OPCODE_MVN
;
2238 new_inst
= OPCODE_MOV
;
2242 case OPCODE_AND
: /* AND <-> BIC */
2243 new_inst
= OPCODE_BIC
;
2248 new_inst
= OPCODE_AND
;
2252 case OPCODE_ADC
: /* ADC <-> SBC */
2253 new_inst
= OPCODE_SBC
;
2258 new_inst
= OPCODE_ADC
;
2262 /* We cannot do anything */
2270 *instruction
&= OPCODE_MASK
;
2271 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2282 while (**str
== ' ')
2285 if (reg_required_here (str
, 0) != FAIL
)
2287 if (skip_past_comma (str
) == SUCCESS
)
2289 /* Shift operation on register */
2290 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2296 /* Immediate expression */
2297 if (is_immediate_prefix (**str
))
2301 if (my_get_expression (&inst
.reloc
.exp
, str
))
2304 if (inst
.reloc
.exp
.X_add_symbol
)
2306 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2307 inst
.reloc
.pc_rel
= 0;
2311 if (skip_past_comma (str
) == SUCCESS
)
2313 /* #x, y -- ie explicit rotation by Y */
2314 if (my_get_expression (&expr
, str
))
2317 if (expr
.X_op
!= O_constant
)
2319 inst
.error
= _("Constant expression expected");
2323 /* Rotate must be a multiple of 2 */
2324 if (((unsigned) expr
.X_add_number
) > 30
2325 || (expr
.X_add_number
& 1) != 0
2326 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2328 inst
.error
= _("Invalid constant");
2331 inst
.instruction
|= INST_IMMEDIATE
;
2332 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2333 inst
.instruction
|= expr
.X_add_number
<< 7;
2337 /* Implicit rotation, select a suitable one */
2338 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2342 /* Can't be done, perhaps the code reads something like
2343 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2344 if ((value
= negate_data_op (&inst
.instruction
,
2345 inst
.reloc
.exp
.X_add_number
))
2348 inst
.error
= _("Invalid constant");
2353 inst
.instruction
|= value
;
2356 inst
.instruction
|= INST_IMMEDIATE
;
2361 inst
.error
= _("Register or shift expression expected");
2370 while (**str
== ' ')
2373 if (fp_reg_required_here (str
, 0) != FAIL
)
2377 /* Immediate expression */
2378 if (*((*str
)++) == '#')
2383 while (**str
== ' ')
2386 /* First try and match exact strings, this is to guarantee that
2387 some formats will work even for cross assembly */
2389 for (i
= 0; fp_const
[i
]; i
++)
2391 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2395 *str
+= strlen (fp_const
[i
]);
2396 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2398 inst
.instruction
|= i
+ 8;
2405 /* Just because we didn't get a match doesn't mean that the
2406 constant isn't valid, just that it is in a format that we
2407 don't automatically recognize. Try parsing it with
2408 the standard expression routines. */
2409 if ((i
= my_get_float_expression (str
)) >= 0)
2411 inst
.instruction
|= i
+ 8;
2415 inst
.error
= _("Invalid floating point immediate expression");
2418 inst
.error
= _("Floating point register or immediate expression expected");
2424 do_arit (str
, flags
)
2426 unsigned long flags
;
2431 if (reg_required_here (&str
, 12) == FAIL
2432 || skip_past_comma (&str
) == FAIL
2433 || reg_required_here (&str
, 16) == FAIL
2434 || skip_past_comma (&str
) == FAIL
2435 || data_op2 (&str
) == FAIL
)
2438 inst
.error
= bad_args
;
2442 inst
.instruction
|= flags
;
2450 unsigned long flags
;
2452 /* This is a pseudo-op of the form "adr rd, label" to be converted
2453 into a relative address of the form "add rd, pc, #label-.-8" */
2458 if (reg_required_here (&str
, 12) == FAIL
2459 || skip_past_comma (&str
) == FAIL
2460 || my_get_expression (&inst
.reloc
.exp
, &str
))
2463 inst
.error
= bad_args
;
2466 /* Frag hacking will turn this into a sub instruction if the offset turns
2467 out to be negative. */
2468 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2469 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2470 inst
.reloc
.pc_rel
= 1;
2471 inst
.instruction
|= flags
;
2479 unsigned long flags
;
2484 if (reg_required_here (&str
, 16) == FAIL
)
2487 inst
.error
= bad_args
;
2491 if (skip_past_comma (&str
) == FAIL
2492 || data_op2 (&str
) == FAIL
)
2495 inst
.error
= bad_args
;
2499 inst
.instruction
|= flags
;
2500 if ((flags
& 0x0000f000) == 0)
2501 inst
.instruction
|= CONDS_BIT
;
2510 unsigned long flags
;
2515 if (reg_required_here (&str
, 12) == FAIL
)
2518 inst
.error
= bad_args
;
2522 if (skip_past_comma (&str
) == FAIL
2523 || data_op2 (&str
) == FAIL
)
2526 inst
.error
= bad_args
;
2530 inst
.instruction
|= flags
;
2536 ldst_extend (str
, hwse
)
2547 if (my_get_expression (& inst
.reloc
.exp
, str
))
2550 if (inst
.reloc
.exp
.X_op
== O_constant
)
2552 int value
= inst
.reloc
.exp
.X_add_number
;
2554 if ((hwse
&& (value
< -255 || value
> 255))
2555 || (value
< -4095 || value
> 4095))
2557 inst
.error
= _("address offset too large");
2567 /* Halfword and signextension instructions have the
2568 immediate value split across bits 11..8 and bits 3..0 */
2570 inst
.instruction
|= add
| HWOFFSET_IMM
| (value
>> 4) << 8 | value
& 0xF;
2572 inst
.instruction
|= add
| value
;
2578 inst
.instruction
|= HWOFFSET_IMM
;
2579 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2582 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2583 inst
.reloc
.pc_rel
= 0;
2588 add
= 0; /* and fall through */
2590 (*str
)++; /* and fall through */
2592 if (reg_required_here (str
, 0) == FAIL
)
2596 inst
.instruction
|= add
;
2599 inst
.instruction
|= add
| OFFSET_REG
;
2600 if (skip_past_comma (str
) == SUCCESS
)
2601 return decode_shift (str
, SHIFT_RESTRICT
);
2609 do_ldst (str
, flags
)
2611 unsigned long flags
;
2618 /* This is not ideal, but it is the simplest way of dealing with the
2619 ARM7T halfword instructions (since they use a different
2620 encoding, but the same mnemonic): */
2621 if (halfword
= ((flags
& 0x80000000) != 0))
2623 /* This is actually a load/store of a halfword, or a
2624 signed-extension load */
2625 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2628 = _("Processor does not support halfwords or signed bytes");
2632 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2633 | (flags
& ~COND_MASK
);
2641 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2644 inst
.error
= bad_args
;
2648 if (skip_past_comma (& str
) == FAIL
)
2650 inst
.error
= _("Address expected");
2662 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2665 conflict_reg
= (((conflict_reg
== reg
)
2666 && (inst
.instruction
& LOAD_BIT
))
2675 if (skip_past_comma (&str
) == SUCCESS
)
2677 /* [Rn],... (post inc) */
2678 if (ldst_extend (&str
, halfword
) == FAIL
)
2681 as_warn (_("destination register same as write-back base\n"));
2687 inst
.instruction
|= HWOFFSET_IMM
;
2695 as_warn (_("destination register same as write-back base\n"));
2697 inst
.instruction
|= WRITE_BACK
;
2701 if (! (flags
& TRANS_BIT
))
2708 if (skip_past_comma (&str
) == FAIL
)
2710 inst
.error
= _("pre-indexed expression expected");
2715 if (ldst_extend (&str
, halfword
) == FAIL
)
2723 inst
.error
= _("missing ]");
2733 as_tsktsk (_("destination register same as write-back base\n"));
2735 inst
.instruction
|= WRITE_BACK
;
2739 else if (*str
== '=')
2741 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2747 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2750 if (inst
.reloc
.exp
.X_op
!= O_constant
2751 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2753 inst
.error
= _("Constant expression expected");
2757 if (inst
.reloc
.exp
.X_op
== O_constant
2758 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2760 /* This can be done with a mov instruction */
2761 inst
.instruction
&= LITERAL_MASK
;
2762 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2763 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2769 /* Insert into literal pool */
2770 if (add_to_lit_pool () == FAIL
)
2773 inst
.error
= _("literal pool insertion failed");
2777 /* Change the instruction exp to point to the pool */
2780 inst
.instruction
|= HWOFFSET_IMM
;
2781 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2784 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2785 inst
.reloc
.pc_rel
= 1;
2786 inst
.instruction
|= (REG_PC
<< 16);
2792 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2797 inst
.instruction
|= HWOFFSET_IMM
;
2798 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2801 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2802 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
2803 inst
.reloc
.pc_rel
= 1;
2804 inst
.instruction
|= (REG_PC
<< 16);
2808 if (pre_inc
&& (flags
& TRANS_BIT
))
2809 inst
.error
= _("Pre-increment instruction with translate");
2811 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
2824 /* We come back here if we get ranges concatenated by '+' or '|' */
2842 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
2851 inst
.error
= _("Bad range in register list");
2855 for (i
= cur_reg
+ 1; i
< reg
; i
++)
2857 if (range
& (1 << i
))
2859 (_("Warning: Duplicated register (r%d) in register list"),
2867 if (range
& (1 << reg
))
2868 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
2870 else if (reg
<= cur_reg
)
2871 as_tsktsk (_("Warning: Register range not in ascending order"));
2875 } while (skip_past_comma (&str
) != FAIL
2876 || (in_range
= 1, *str
++ == '-'));
2883 inst
.error
= _("Missing `}'");
2891 if (my_get_expression (&expr
, &str
))
2894 if (expr
.X_op
== O_constant
)
2896 if (expr
.X_add_number
2897 != (expr
.X_add_number
& 0x0000ffff))
2899 inst
.error
= _("invalid register mask");
2903 if ((range
& expr
.X_add_number
) != 0)
2905 int regno
= range
& expr
.X_add_number
;
2908 regno
= (1 << regno
) - 1;
2910 (_("Warning: Duplicated register (r%d) in register list"),
2914 range
|= expr
.X_add_number
;
2918 if (inst
.reloc
.type
!= 0)
2920 inst
.error
= _("expression too complex");
2924 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
2925 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
2926 inst
.reloc
.pc_rel
= 0;
2933 if (*str
== '|' || *str
== '+')
2938 } while (another_range
);
2945 do_ldmstm (str
, flags
)
2947 unsigned long flags
;
2955 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
2958 if (base_reg
== REG_PC
)
2960 inst
.error
= _("r15 not allowed as base register");
2968 flags
|= WRITE_BACK
;
2972 if (skip_past_comma (&str
) == FAIL
2973 || (range
= reg_list (&str
)) == FAIL
)
2976 inst
.error
= bad_args
;
2983 flags
|= MULTI_SET_PSR
;
2986 inst
.instruction
|= flags
| range
;
2994 unsigned long flags
;
2999 /* Allow optional leading '#'. */
3000 if (is_immediate_prefix (*str
))
3003 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3006 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3007 inst
.reloc
.pc_rel
= 0;
3008 inst
.instruction
|= flags
;
3016 do_swap (str
, flags
)
3018 unsigned long flags
;
3025 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3030 inst
.error
= _("r15 not allowed in swap");
3034 if (skip_past_comma (&str
) == FAIL
3035 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3038 inst
.error
= bad_args
;
3044 inst
.error
= _("r15 not allowed in swap");
3048 if (skip_past_comma (&str
) == FAIL
3051 inst
.error
= bad_args
;
3058 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3063 inst
.error
= bad_pc
;
3072 inst
.error
= _("missing ]");
3076 inst
.instruction
|= flags
;
3082 do_branch (str
, flags
)
3084 unsigned long flags
;
3086 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3093 /* ScottB: February 5, 1998 */
3094 /* Check to see of PLT32 reloc required for the instruction. */
3096 /* arm_parse_reloc() works on input_line_pointer.
3097 We actually want to parse the operands to the branch instruction
3098 passed in 'str'. Save the input pointer and restore it later. */
3099 save_in
= input_line_pointer
;
3100 input_line_pointer
= str
;
3101 if (inst
.reloc
.exp
.X_op
== O_symbol
3103 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3105 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3106 inst
.reloc
.pc_rel
= 0;
3107 /* Modify str to point to after parsed operands, otherwise
3108 end_of_line() will complain about the (PLT) left in str. */
3109 str
= input_line_pointer
;
3113 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3114 inst
.reloc
.pc_rel
= 1;
3116 input_line_pointer
= save_in
;
3119 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3120 inst
.reloc
.pc_rel
= 1;
3121 #endif /* OBJ_ELF */
3130 unsigned long flags
;
3137 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3141 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3150 unsigned long flags
;
3152 /* Co-processor data operation.
3153 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3157 if (co_proc_number (&str
) == FAIL
)
3160 inst
.error
= bad_args
;
3164 if (skip_past_comma (&str
) == FAIL
3165 || cp_opc_expr (&str
, 20,4) == FAIL
)
3168 inst
.error
= bad_args
;
3172 if (skip_past_comma (&str
) == FAIL
3173 || cp_reg_required_here (&str
, 12) == FAIL
)
3176 inst
.error
= bad_args
;
3180 if (skip_past_comma (&str
) == FAIL
3181 || cp_reg_required_here (&str
, 16) == FAIL
)
3184 inst
.error
= bad_args
;
3188 if (skip_past_comma (&str
) == FAIL
3189 || cp_reg_required_here (&str
, 0) == FAIL
)
3192 inst
.error
= bad_args
;
3196 if (skip_past_comma (&str
) == SUCCESS
)
3198 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3201 inst
.error
= bad_args
;
3211 do_lstc (str
, flags
)
3213 unsigned long flags
;
3215 /* Co-processor register load/store.
3216 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3221 if (co_proc_number (&str
) == FAIL
)
3224 inst
.error
= bad_args
;
3228 if (skip_past_comma (&str
) == FAIL
3229 || cp_reg_required_here (&str
, 12) == FAIL
)
3232 inst
.error
= bad_args
;
3236 if (skip_past_comma (&str
) == FAIL
3237 || cp_address_required_here (&str
) == FAIL
)
3240 inst
.error
= bad_args
;
3244 inst
.instruction
|= flags
;
3250 do_co_reg (str
, flags
)
3252 unsigned long flags
;
3254 /* Co-processor register transfer.
3255 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3260 if (co_proc_number (&str
) == FAIL
)
3263 inst
.error
= bad_args
;
3267 if (skip_past_comma (&str
) == FAIL
3268 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3271 inst
.error
= bad_args
;
3275 if (skip_past_comma (&str
) == FAIL
3276 || reg_required_here (&str
, 12) == FAIL
)
3279 inst
.error
= bad_args
;
3283 if (skip_past_comma (&str
) == FAIL
3284 || cp_reg_required_here (&str
, 16) == FAIL
)
3287 inst
.error
= bad_args
;
3291 if (skip_past_comma (&str
) == FAIL
3292 || cp_reg_required_here (&str
, 0) == FAIL
)
3295 inst
.error
= bad_args
;
3299 if (skip_past_comma (&str
) == SUCCESS
)
3301 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3304 inst
.error
= bad_args
;
3314 do_fp_ctrl (str
, flags
)
3316 unsigned long flags
;
3318 /* FP control registers.
3319 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3324 if (reg_required_here (&str
, 12) == FAIL
)
3327 inst
.error
= bad_args
;
3336 do_fp_ldst (str
, flags
)
3338 unsigned long flags
;
3343 switch (inst
.suffix
)
3348 inst
.instruction
|= CP_T_X
;
3351 inst
.instruction
|= CP_T_Y
;
3354 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3360 if (fp_reg_required_here (&str
, 12) == FAIL
)
3363 inst
.error
= bad_args
;
3367 if (skip_past_comma (&str
) == FAIL
3368 || cp_address_required_here (&str
) == FAIL
)
3371 inst
.error
= bad_args
;
3379 do_fp_ldmstm (str
, flags
)
3381 unsigned long flags
;
3388 if (fp_reg_required_here (&str
, 12) == FAIL
)
3391 inst
.error
= bad_args
;
3395 /* Get Number of registers to transfer */
3396 if (skip_past_comma (&str
) == FAIL
3397 || my_get_expression (&inst
.reloc
.exp
, &str
))
3400 inst
.error
= _("constant expression expected");
3404 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3406 inst
.error
= _("Constant value required for number of registers");
3410 num_regs
= inst
.reloc
.exp
.X_add_number
;
3412 if (num_regs
< 1 || num_regs
> 4)
3414 inst
.error
= _("number of registers must be in the range [1:4]");
3421 inst
.instruction
|= CP_T_X
;
3424 inst
.instruction
|= CP_T_Y
;
3427 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3441 /* The instruction specified "ea" or "fd", so we can only accept
3442 [Rn]{!}. The instruction does not really support stacking or
3443 unstacking, so we have to emulate these by setting appropriate
3444 bits and offsets. */
3445 if (skip_past_comma (&str
) == FAIL
3449 inst
.error
= bad_args
;
3457 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3465 inst
.error
= bad_args
;
3476 inst
.error
= _("R15 not allowed as base register with write-back");
3483 if (flags
& CP_T_Pre
)
3486 offset
= 3 * num_regs
;
3492 /* Post-increment */
3496 offset
= 3 * num_regs
;
3500 /* No write-back, so convert this into a standard pre-increment
3501 instruction -- aesthetically more pleasing. */
3502 flags
= CP_T_Pre
| CP_T_UD
;
3507 inst
.instruction
|= flags
| offset
;
3509 else if (skip_past_comma (&str
) == FAIL
3510 || cp_address_required_here (&str
) == FAIL
)
3513 inst
.error
= bad_args
;
3521 do_fp_dyadic (str
, flags
)
3523 unsigned long flags
;
3528 switch (inst
.suffix
)
3533 inst
.instruction
|= 0x00000080;
3536 inst
.instruction
|= 0x00080000;
3542 if (fp_reg_required_here (&str
, 12) == FAIL
)
3545 inst
.error
= bad_args
;
3549 if (skip_past_comma (&str
) == FAIL
3550 || fp_reg_required_here (&str
, 16) == FAIL
)
3553 inst
.error
= bad_args
;
3557 if (skip_past_comma (&str
) == FAIL
3558 || fp_op2 (&str
) == FAIL
)
3561 inst
.error
= bad_args
;
3565 inst
.instruction
|= flags
;
3571 do_fp_monadic (str
, flags
)
3573 unsigned long flags
;
3578 switch (inst
.suffix
)
3583 inst
.instruction
|= 0x00000080;
3586 inst
.instruction
|= 0x00080000;
3592 if (fp_reg_required_here (&str
, 12) == FAIL
)
3595 inst
.error
= bad_args
;
3599 if (skip_past_comma (&str
) == FAIL
3600 || fp_op2 (&str
) == FAIL
)
3603 inst
.error
= bad_args
;
3607 inst
.instruction
|= flags
;
3613 do_fp_cmp (str
, flags
)
3615 unsigned long flags
;
3620 if (fp_reg_required_here (&str
, 16) == FAIL
)
3623 inst
.error
= bad_args
;
3627 if (skip_past_comma (&str
) == FAIL
3628 || fp_op2 (&str
) == FAIL
)
3631 inst
.error
= bad_args
;
3635 inst
.instruction
|= flags
;
3641 do_fp_from_reg (str
, flags
)
3643 unsigned long flags
;
3648 switch (inst
.suffix
)
3653 inst
.instruction
|= 0x00000080;
3656 inst
.instruction
|= 0x00080000;
3662 if (fp_reg_required_here (&str
, 16) == FAIL
)
3665 inst
.error
= bad_args
;
3669 if (skip_past_comma (&str
) == FAIL
3670 || reg_required_here (&str
, 12) == FAIL
)
3673 inst
.error
= bad_args
;
3677 inst
.instruction
|= flags
;
3683 do_fp_to_reg (str
, flags
)
3685 unsigned long flags
;
3690 if (reg_required_here (&str
, 12) == FAIL
)
3693 if (skip_past_comma (&str
) == FAIL
3694 || fp_reg_required_here (&str
, 0) == FAIL
)
3697 inst
.error
= bad_args
;
3701 inst
.instruction
|= flags
;
3706 /* Thumb specific routines */
3708 /* Parse and validate that a register is of the right form, this saves
3709 repeated checking of this information in many similar cases.
3710 Unlike the 32-bit case we do not insert the register into the opcode
3711 here, since the position is often unknown until the full instruction
3714 thumb_reg (strp
, hi_lo
)
3720 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3728 inst
.error
= _("lo register required");
3736 inst
.error
= _("hi register required");
3748 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3751 thumb_add_sub (str
, subtract
)
3755 int Rd
, Rs
, Rn
= FAIL
;
3760 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3761 || skip_past_comma (&str
) == FAIL
)
3764 inst
.error
= bad_args
;
3768 if (is_immediate_prefix (*str
))
3772 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3777 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3780 if (skip_past_comma (&str
) == FAIL
)
3782 /* Two operand format, shuffle the registers and pretend there
3787 else if (is_immediate_prefix (*str
))
3790 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3793 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3797 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3798 for the latter case, EXPR contains the immediate that was found. */
3801 /* All register format. */
3802 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
3806 inst
.error
= _("dest and source1 must be the same register");
3810 /* Can't do this for SUB */
3813 inst
.error
= _("subtract valid only on lo regs");
3817 inst
.instruction
= (T_OPCODE_ADD_HI
3818 | (Rd
> 7 ? THUMB_H1
: 0)
3819 | (Rn
> 7 ? THUMB_H2
: 0));
3820 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
3824 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
3825 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
3830 /* Immediate expression, now things start to get nasty. */
3832 /* First deal with HI regs, only very restricted cases allowed:
3833 Adjusting SP, and using PC or SP to get an address. */
3834 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
3835 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
3837 inst
.error
= _("invalid Hi register with immediate");
3841 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3843 /* Value isn't known yet, all we can do is store all the fragments
3844 we know about in the instruction and let the reloc hacking
3846 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
3847 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
3851 int offset
= inst
.reloc
.exp
.X_add_number
;
3861 /* Quick check, in case offset is MIN_INT */
3864 inst
.error
= _("immediate value out of range");
3873 if (offset
& ~0x1fc)
3875 inst
.error
= _("invalid immediate value for stack adjust");
3878 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
3879 inst
.instruction
|= offset
>> 2;
3881 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
3884 || (offset
& ~0x3fc))
3886 inst
.error
= _("invalid immediate for address calculation");
3889 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
3891 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
3897 inst
.error
= _("immediate value out of range");
3900 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
3901 inst
.instruction
|= (Rd
<< 8) | offset
;
3907 inst
.error
= _("immediate value out of range");
3910 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
3911 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
3919 thumb_shift (str
, shift
)
3923 int Rd
, Rs
, Rn
= FAIL
;
3928 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
3929 || skip_past_comma (&str
) == FAIL
)
3932 inst
.error
= bad_args
;
3936 if (is_immediate_prefix (*str
))
3938 /* Two operand immediate format, set Rs to Rd. */
3941 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3946 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
3949 if (skip_past_comma (&str
) == FAIL
)
3951 /* Two operand format, shuffle the registers and pretend there
3956 else if (is_immediate_prefix (*str
))
3959 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3962 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
3966 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3967 for the latter case, EXPR contains the immediate that was found. */
3973 inst
.error
= _("source1 and dest must be same register");
3979 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
3980 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
3981 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
3984 inst
.instruction
|= Rd
| (Rn
<< 3);
3990 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
3991 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
3992 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
3995 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3997 /* Value isn't known yet, create a dummy reloc and let reloc
3998 hacking fix it up */
4000 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4004 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4006 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4008 inst
.error
= _("Invalid immediate for shift");
4012 /* Shifts of zero are handled by converting to LSL */
4013 if (shift_value
== 0)
4014 inst
.instruction
= T_OPCODE_LSL_I
;
4016 /* Shifts of 32 are encoded as a shift of zero */
4017 if (shift_value
== 32)
4020 inst
.instruction
|= shift_value
<< 6;
4023 inst
.instruction
|= Rd
| (Rs
<< 3);
4029 thumb_mov_compare (str
, move
)
4038 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4039 || skip_past_comma (&str
) == FAIL
)
4042 inst
.error
= bad_args
;
4046 if (is_immediate_prefix (*str
))
4049 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4052 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4057 if (Rs
< 8 && Rd
< 8)
4059 if (move
== THUMB_MOVE
)
4060 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4061 since a MOV instruction produces unpredictable results */
4062 inst
.instruction
= T_OPCODE_ADD_I3
;
4064 inst
.instruction
= T_OPCODE_CMP_LR
;
4065 inst
.instruction
|= Rd
| (Rs
<< 3);
4069 if (move
== THUMB_MOVE
)
4070 inst
.instruction
= T_OPCODE_MOV_HR
;
4072 inst
.instruction
= T_OPCODE_CMP_HR
;
4075 inst
.instruction
|= THUMB_H1
;
4078 inst
.instruction
|= THUMB_H2
;
4080 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4087 inst
.error
= _("only lo regs allowed with immediate");
4091 if (move
== THUMB_MOVE
)
4092 inst
.instruction
= T_OPCODE_MOV_I8
;
4094 inst
.instruction
= T_OPCODE_CMP_I8
;
4096 inst
.instruction
|= Rd
<< 8;
4098 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4099 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4102 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4106 inst
.error
= _("invalid immediate");
4110 inst
.instruction
|= value
;
4118 thumb_load_store (str
, load_store
, size
)
4123 int Rd
, Rb
, Ro
= FAIL
;
4128 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4129 || skip_past_comma (&str
) == FAIL
)
4132 inst
.error
= bad_args
;
4139 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4142 if (skip_past_comma (&str
) != FAIL
)
4144 if (is_immediate_prefix (*str
))
4147 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4150 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4155 inst
.reloc
.exp
.X_op
= O_constant
;
4156 inst
.reloc
.exp
.X_add_number
= 0;
4161 inst
.error
= _("expected ']'");
4166 else if (*str
== '=')
4168 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4174 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4179 if ( inst
.reloc
.exp
.X_op
!= O_constant
4180 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4182 inst
.error
= "Constant expression expected";
4186 if (inst
.reloc
.exp
.X_op
== O_constant
4187 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4189 /* This can be done with a mov instruction */
4191 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4192 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4196 /* Insert into literal pool */
4197 if (add_to_lit_pool () == FAIL
)
4200 inst
.error
= "literal pool insertion failed";
4204 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4205 inst
.reloc
.pc_rel
= 1;
4206 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4207 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4213 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4216 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4217 inst
.reloc
.pc_rel
= 1;
4218 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4219 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4224 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4226 if (size
!= THUMB_WORD
)
4228 inst
.error
= _("byte or halfword not valid for base register");
4231 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4233 inst
.error
= _("R15 based store not allowed");
4236 else if (Ro
!= FAIL
)
4238 inst
.error
= _("Invalid base register for register offset");
4243 inst
.instruction
= T_OPCODE_LDR_PC
;
4244 else if (load_store
== THUMB_LOAD
)
4245 inst
.instruction
= T_OPCODE_LDR_SP
;
4247 inst
.instruction
= T_OPCODE_STR_SP
;
4249 inst
.instruction
|= Rd
<< 8;
4250 if (inst
.reloc
.exp
.X_op
== O_constant
)
4252 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4254 if (offset
& ~0x3fc)
4256 inst
.error
= _("invalid offset");
4260 inst
.instruction
|= offset
>> 2;
4263 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4267 inst
.error
= _("invalid base register in load/store");
4270 else if (Ro
== FAIL
)
4272 /* Immediate offset */
4273 if (size
== THUMB_WORD
)
4274 inst
.instruction
= (load_store
== THUMB_LOAD
4275 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4276 else if (size
== THUMB_HALFWORD
)
4277 inst
.instruction
= (load_store
== THUMB_LOAD
4278 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4280 inst
.instruction
= (load_store
== THUMB_LOAD
4281 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4283 inst
.instruction
|= Rd
| (Rb
<< 3);
4285 if (inst
.reloc
.exp
.X_op
== O_constant
)
4287 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4289 if (offset
& ~(0x1f << size
))
4291 inst
.error
= _("Invalid offset");
4294 inst
.instruction
|= (offset
>> size
) << 6;
4297 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4301 /* Register offset */
4302 if (size
== THUMB_WORD
)
4303 inst
.instruction
= (load_store
== THUMB_LOAD
4304 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4305 else if (size
== THUMB_HALFWORD
)
4306 inst
.instruction
= (load_store
== THUMB_LOAD
4307 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4309 inst
.instruction
= (load_store
== THUMB_LOAD
4310 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4312 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4327 /* Handle the Format 4 instructions that do not have equivalents in other
4328 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4339 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4342 if (skip_past_comma (&str
) == FAIL
4343 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4346 inst
.error
= bad_args
;
4350 if (skip_past_comma (&str
) != FAIL
)
4352 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4353 (It isn't allowed for CMP either, but that isn't handled by this
4355 if (inst
.instruction
== T_OPCODE_TST
4356 || inst
.instruction
== T_OPCODE_CMN
4357 || inst
.instruction
== T_OPCODE_NEG
4358 || inst
.instruction
== T_OPCODE_MVN
)
4360 inst
.error
= bad_args
;
4364 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4369 inst
.error
= _("dest and source1 one must be the same register");
4375 if (inst
.instruction
== T_OPCODE_MUL
4377 as_tsktsk (_("Rs and Rd must be different in MUL"));
4379 inst
.instruction
|= Rd
| (Rs
<< 3);
4387 thumb_add_sub (str
, 0);
4394 thumb_shift (str
, THUMB_ASR
);
4401 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4403 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4404 inst
.reloc
.pc_rel
= 1;
4412 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4414 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4415 inst
.reloc
.pc_rel
= 1;
4419 /* Find the real, Thumb encoded start of a Thumb function. */
4422 find_real_start (symbolP
)
4426 const char * name
= S_GET_NAME (symbolP
);
4427 symbolS
* new_target
;
4429 /* This definitonmust agree with the one in gcc/config/arm/thumb.c */
4430 #define STUB_NAME ".real_start_of"
4435 /* Names that start with '.' are local labels, not function entry points.
4436 The compiler may generate BL instructions to these labels because it
4437 needs to perform a branch to a far away location. */
4441 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4442 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4444 new_target
= symbol_find (real_start
);
4446 if (new_target
== NULL
)
4448 as_warn ("Failed to find real start of function: %s\n", name
);
4449 new_target
= symbolP
;
4462 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4464 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4465 inst
.reloc
.pc_rel
= 1;
4468 /* If the destination of the branch is a defined symbol which does not have
4469 the THUMB_FUNC attribute, then we must be calling a function which has
4470 the (interfacearm) attribute. We look for the Thumb entry point to that
4471 function and change the branch to refer to that function instead. */
4472 if ( inst
.reloc
.exp
.X_op
== O_symbol
4473 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4474 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4475 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4476 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4488 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4491 /* This sets THUMB_H2 from the top bit of reg. */
4492 inst
.instruction
|= reg
<< 3;
4494 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4495 should cause the alignment to be checked once it is known. This is
4496 because BX PC only works if the instruction is word aligned. */
4505 thumb_mov_compare (str
, THUMB_COMPARE
);
4518 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4522 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4526 if (skip_past_comma (&str
) == FAIL
4527 || (range
= reg_list (&str
)) == FAIL
)
4530 inst
.error
= bad_args
;
4534 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4536 /* This really doesn't seem worth it. */
4537 inst
.reloc
.type
= BFD_RELOC_NONE
;
4538 inst
.error
= _("Expression too complex");
4544 inst
.error
= _("only lo-regs valid in load/store multiple");
4548 inst
.instruction
|= (Rb
<< 8) | range
;
4556 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4563 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4570 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4582 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4583 || skip_past_comma (&str
) == FAIL
4585 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4586 || skip_past_comma (&str
) == FAIL
4587 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4591 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4595 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4603 thumb_shift (str
, THUMB_LSL
);
4610 thumb_shift (str
, THUMB_LSR
);
4617 thumb_mov_compare (str
, THUMB_MOVE
);
4629 if ((range
= reg_list (&str
)) == FAIL
)
4632 inst
.error
= bad_args
;
4636 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4638 /* This really doesn't seem worth it. */
4639 inst
.reloc
.type
= BFD_RELOC_NONE
;
4640 inst
.error
= _("Expression too complex");
4646 if ((inst
.instruction
== T_OPCODE_PUSH
4647 && (range
& ~0xff) == 1 << REG_LR
)
4648 || (inst
.instruction
== T_OPCODE_POP
4649 && (range
& ~0xff) == 1 << REG_PC
))
4651 inst
.instruction
|= THUMB_PP_PC_LR
;
4656 inst
.error
= _("invalid register list to push/pop instruction");
4661 inst
.instruction
|= range
;
4669 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4676 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4683 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4690 thumb_add_sub (str
, 1);
4700 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4703 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4712 /* This is a pseudo-op of the form "adr rd, label" to be converted
4713 into a relative address of the form "add rd, pc, #label-.-4" */
4717 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4718 || skip_past_comma (&str
) == FAIL
4719 || my_get_expression (&inst
.reloc
.exp
, &str
))
4722 inst
.error
= bad_args
;
4726 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4727 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4728 inst
.reloc
.pc_rel
= 1;
4729 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4737 int len
= strlen (reg_table
[entry
].name
) + 2;
4738 char * buf
= (char *) xmalloc (len
);
4739 char * buf2
= (char *) xmalloc (len
);
4742 #ifdef REGISTER_PREFIX
4743 buf
[i
++] = REGISTER_PREFIX
;
4746 strcpy (buf
+ i
, reg_table
[entry
].name
);
4748 for (i
= 0; buf
[i
]; i
++)
4749 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4753 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4754 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4758 insert_reg_alias (str
, regnum
)
4762 struct reg_entry
*new =
4763 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4764 char *name
= xmalloc (strlen (str
) + 1);
4768 new->number
= regnum
;
4770 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4774 set_constant_flonums ()
4778 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4779 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4788 if ( (arm_ops_hsh
= hash_new ()) == NULL
4789 || (arm_tops_hsh
= hash_new ()) == NULL
4790 || (arm_cond_hsh
= hash_new ()) == NULL
4791 || (arm_shift_hsh
= hash_new ()) == NULL
4792 || (arm_reg_hsh
= hash_new ()) == NULL
4793 || (arm_psr_hsh
= hash_new ()) == NULL
)
4794 as_fatal (_("Virtual memory exhausted"));
4796 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4797 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4798 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4799 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4800 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4801 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4802 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4803 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4804 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4805 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4807 for (i
= 0; reg_table
[i
].name
; i
++)
4810 set_constant_flonums ();
4812 #if defined OBJ_COFF || defined OBJ_ELF
4814 unsigned int flags
= 0;
4816 /* Set the flags in the private structure */
4817 if (uses_apcs_26
) flags
|= F_APCS26
;
4818 if (support_interwork
) flags
|= F_INTERWORK
;
4819 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
4820 if (pic_code
) flags
|= F_PIC
;
4822 bfd_set_private_flags (stdoutput
, flags
);
4829 /* Record the CPU type as well */
4830 switch (cpu_variant
& ARM_CPU_MASK
)
4833 mach
= bfd_mach_arm_2
;
4836 case ARM_3
: /* also ARM_250 */
4837 mach
= bfd_mach_arm_2a
;
4841 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
4842 mach
= bfd_mach_arm_4
;
4845 case ARM_7
: /* also ARM_6 */
4846 mach
= bfd_mach_arm_3
;
4850 /* Catch special cases */
4851 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
4853 if (cpu_variant
& ARM_THUMB
)
4854 mach
= bfd_mach_arm_4T
;
4855 else if ((cpu_variant
& ARM_ARCHv4
) == ARM_ARCHv4
)
4856 mach
= bfd_mach_arm_4
;
4857 else if (cpu_variant
& ARM_LONGMUL
)
4858 mach
= bfd_mach_arm_3M
;
4861 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
4865 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4866 for use in the a.out file, and stores them in the array pointed to by buf.
4867 This knows about the endian-ness of the target machine and does
4868 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4869 2 (short) and 4 (long) Floating numbers are put out as a series of
4870 LITTLENUMS (shorts, here at least)
4873 md_number_to_chars (buf
, val
, n
)
4878 if (target_big_endian
)
4879 number_to_chars_bigendian (buf
, val
, n
);
4881 number_to_chars_littleendian (buf
, val
, n
);
4885 md_chars_to_number (buf
, n
)
4890 unsigned char * where
= (unsigned char *) buf
;
4892 if (target_big_endian
)
4897 result
|= (*where
++ & 255);
4905 result
|= (where
[n
] & 255);
4912 /* Turn a string in input_line_pointer into a floating point constant
4913 of type TYPE, and store the appropriate bytes in *litP. The number
4914 of LITTLENUMS emitted is stored in *sizeP . An error message is
4915 returned, or NULL on OK.
4917 Note that fp constants aren't represent in the normal way on the ARM.
4918 In big endian mode, things are as expected. However, in little endian
4919 mode fp constants are big-endian word-wise, and little-endian byte-wise
4920 within the words. For example, (double) 1.1 in big endian mode is
4921 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4922 the byte sequence 99 99 f1 3f 9a 99 99 99.
4924 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
4927 md_atof (type
, litP
, sizeP
)
4933 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4965 return _("Bad call to MD_ATOF()");
4968 t
= atof_ieee (input_line_pointer
, type
, words
);
4970 input_line_pointer
= t
;
4973 if (target_big_endian
)
4975 for (i
= 0; i
< prec
; i
++)
4977 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4983 /* For a 4 byte float the order of elements in `words' is 1 0. For an
4984 8 byte float the order is 1 0 3 2. */
4985 for (i
= 0; i
< prec
; i
+= 2)
4987 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4988 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4996 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
4998 md_pcrel_from (fixP
)
5002 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5003 && fixP
->fx_subsy
== NULL
)
5006 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5008 /* PC relative addressing on the Thumb is slightly odd
5009 as the bottom two bits of the PC are forced to zero
5010 for the calculation */
5011 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5014 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5017 /* Round up a section size to the appropriate boundary. */
5019 md_section_align (segment
, size
)
5024 /* Don't align the dwarf2 debug sections */
5025 if (!strncmp (segment
->name
, ".debug", 5))
5028 /* Round all sects to multiple of 4 */
5029 return (size
+ 3) & ~3;
5032 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5033 we have no need to default values of symbols. */
5037 md_undefined_symbol (name
)
5041 if (name
[0] == '_' && name
[1] == 'G'
5042 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5046 if (symbol_find (name
))
5047 as_bad ("GOT already in the symbol table");
5049 GOT_symbol
= symbol_new (name
, undefined_section
,
5050 (valueT
)0, & zero_address_frag
);
5060 /* arm_reg_parse () := if it looks like a register, return its token and
5061 advance the pointer. */
5065 register char ** ccp
;
5067 char * start
= * ccp
;
5070 struct reg_entry
* reg
;
5072 #ifdef REGISTER_PREFIX
5073 if (*start
!= REGISTER_PREFIX
)
5078 #ifdef OPTIONAL_REGISTER_PREFIX
5079 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5083 if (!isalpha (*p
) || !is_name_beginner (*p
))
5087 while (isalpha (c
) || isdigit (c
) || c
== '_')
5091 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5105 register char ** ccp
;
5107 char * start
= * ccp
;
5110 CONST
struct asm_psr
* psr
;
5114 while (isalpha (c
) || c
== '_')
5118 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5131 md_apply_fix3 (fixP
, val
, seg
)
5136 offsetT value
= * val
;
5138 unsigned int newimm
;
5141 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5142 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5144 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5146 /* Note whether this will delete the relocation. */
5147 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5148 if ((fixP
->fx_addsy
== 0 || fixP
->fx_addsy
->sy_value
.X_op
== O_constant
)
5151 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5155 /* If this symbol is in a different section then we need to leave it for
5156 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5157 so we have to undo it's effects here. */
5160 if (fixP
->fx_addsy
!= NULL
5161 && S_IS_DEFINED (fixP
->fx_addsy
)
5162 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5165 && fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
5168 value
+= md_pcrel_from (fixP
);
5172 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc */
5174 switch (fixP
->fx_r_type
)
5176 case BFD_RELOC_ARM_IMMEDIATE
:
5177 newimm
= validate_immediate (value
);
5178 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5180 /* If the instruction will fail, see if we can fix things up by
5181 changing the opcode. */
5182 if (newimm
== (unsigned int) FAIL
5183 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5185 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5186 _("invalid constant (%x) after fixup\n"), value
);
5190 newimm
|= (temp
& 0xfffff000);
5191 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5194 case BFD_RELOC_ARM_OFFSET_IMM
:
5196 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5198 as_bad (_("bad immediate value for offset (%d)"), val
);
5204 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5205 newval
&= 0xff7ff000;
5206 newval
|= value
| (sign
? INDEX_UP
: 0);
5207 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5210 case BFD_RELOC_ARM_OFFSET_IMM8
:
5211 case BFD_RELOC_ARM_HWLITERAL
:
5213 if ((value
= validate_offset_imm (value
, 1)) == FAIL
)
5215 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5216 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5217 _("invalid literal constant: pool needs to be closer\n"));
5219 as_bad (_("bad immediate value for offset (%d)"), value
);
5226 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5227 newval
&= 0xff7ff0f0;
5228 newval
|= ((value
>> 4) << 8) | value
& 0xf | (sign
? INDEX_UP
: 0);
5229 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5232 case BFD_RELOC_ARM_LITERAL
:
5237 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5239 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5240 _("invalid literal constant: pool needs to be closer\n"));
5244 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5245 newval
&= 0xff7ff000;
5246 newval
|= value
| (sign
? INDEX_UP
: 0);
5247 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5250 case BFD_RELOC_ARM_SHIFT_IMM
:
5251 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5252 if (((unsigned long) value
) > 32
5254 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5256 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5257 _("shift expression is too large"));
5262 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5263 else if (value
== 32)
5265 newval
&= 0xfffff07f;
5266 newval
|= (value
& 0x1f) << 7;
5267 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5270 case BFD_RELOC_ARM_SWI
:
5271 if (arm_data
->thumb_mode
)
5273 if (((unsigned long) value
) > 0xff)
5274 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5275 _("Invalid swi expression"));
5276 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5278 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5282 if (((unsigned long) value
) > 0x00ffffff)
5283 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5284 _("Invalid swi expression"));
5285 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5287 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5291 case BFD_RELOC_ARM_MULTI
:
5292 if (((unsigned long) value
) > 0xffff)
5293 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5294 _("Invalid expression in load/store multiple"));
5295 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5296 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5299 case BFD_RELOC_ARM_PCREL_BRANCH
:
5300 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5304 value
= fixP
->fx_offset
;
5306 value
= (value
>> 2) & 0x00ffffff;
5307 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5308 newval
= value
| (newval
& 0xff000000);
5309 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5312 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5313 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5315 addressT diff
= (newval
& 0xff) << 1;
5320 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5321 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5322 _("Branch out of range"));
5323 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5325 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5328 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5329 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5331 addressT diff
= (newval
& 0x7ff) << 1;
5336 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5337 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5338 _("Branch out of range"));
5339 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5341 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5344 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5349 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5350 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5351 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5352 if (diff
& 0x400000)
5355 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5356 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5357 _("Branch with link out of range"));
5359 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5360 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5361 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5362 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5367 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5368 md_number_to_chars (buf
, value
, 1);
5370 else if (!target_oabi
)
5372 value
= fixP
->fx_offset
;
5373 md_number_to_chars (buf
, value
, 1);
5379 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5380 md_number_to_chars (buf
, value
, 2);
5382 else if (!target_oabi
)
5384 value
= fixP
->fx_offset
;
5385 md_number_to_chars (buf
, value
, 2);
5391 case BFD_RELOC_ARM_GOT32
:
5392 case BFD_RELOC_ARM_GOTOFF
:
5393 md_number_to_chars (buf
, 0, 4);
5399 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5400 md_number_to_chars (buf
, value
, 4);
5402 else if (!target_oabi
)
5404 value
= fixP
->fx_offset
;
5405 md_number_to_chars (buf
, value
, 4);
5411 case BFD_RELOC_ARM_PLT32
:
5412 /* It appears the instruction is fully prepared at this point. */
5416 case BFD_RELOC_ARM_GOTPC
:
5417 md_number_to_chars (buf
, value
, 4);
5420 case BFD_RELOC_ARM_CP_OFF_IMM
:
5422 if (value
< -1023 || value
> 1023 || (value
& 3))
5423 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5424 _("Illegal value for co-processor offset"));
5427 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5428 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5429 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5432 case BFD_RELOC_ARM_THUMB_OFFSET
:
5433 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5434 /* Exactly what ranges, and where the offset is inserted depends on
5435 the type of instruction, we can establish this from the top 4 bits */
5436 switch (newval
>> 12)
5438 case 4: /* PC load */
5439 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5440 forced to zero for these loads, so we will need to round
5441 up the offset if the instruction address is not word
5442 aligned (since the final address produced must be, and
5443 we can only describe word-aligned immediate offsets). */
5445 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5446 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5447 _("Invalid offset, target not word aligned (0x%08X)"),
5448 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5450 if ((value
+ 2) & ~0x3fe)
5451 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5452 _("Invalid offset"));
5454 /* Round up, since pc will be rounded down. */
5455 newval
|= (value
+ 2) >> 2;
5458 case 9: /* SP load/store */
5460 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5461 _("Invalid offset"));
5462 newval
|= value
>> 2;
5465 case 6: /* Word load/store */
5467 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5468 _("Invalid offset"));
5469 newval
|= value
<< 4; /* 6 - 2 */
5472 case 7: /* Byte load/store */
5474 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5475 _("Invalid offset"));
5476 newval
|= value
<< 6;
5479 case 8: /* Halfword load/store */
5481 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5482 _("Invalid offset"));
5483 newval
|= value
<< 5; /* 6 - 1 */
5487 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5488 "Unable to process relocation for thumb opcode: %x", newval
);
5491 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5494 case BFD_RELOC_ARM_THUMB_ADD
:
5495 /* This is a complicated relocation, since we use it for all of
5496 the following immediate relocations:
5499 9bit ADD/SUB SP word-aligned
5500 10bit ADD PC/SP word-aligned
5502 The type of instruction being processed is encoded in the
5508 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5510 int rd
= (newval
>> 4) & 0xf;
5511 int rs
= newval
& 0xf;
5512 int subtract
= newval
& 0x8000;
5517 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5518 _("Invalid immediate for stack address calculation"));
5519 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5520 newval
|= value
>> 2;
5522 else if (rs
== REG_PC
|| rs
== REG_SP
)
5526 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5527 _("Invalid immediate for address calculation (value = 0x%08X)"), value
);
5528 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5530 newval
|= value
>> 2;
5535 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5536 _("Invalid 8bit immediate"));
5537 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5538 newval
|= (rd
<< 8) | value
;
5543 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5544 _("Invalid 3bit immediate"));
5545 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5546 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5549 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5552 case BFD_RELOC_ARM_THUMB_IMM
:
5553 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5554 switch (newval
>> 11)
5556 case 0x04: /* 8bit immediate MOV */
5557 case 0x05: /* 8bit immediate CMP */
5558 if (value
< 0 || value
> 255)
5559 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5560 _("Invalid immediate: %d is too large"), value
);
5567 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5570 case BFD_RELOC_ARM_THUMB_SHIFT
:
5571 /* 5bit shift value (0..31) */
5572 if (value
< 0 || value
> 31)
5573 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5574 _("Illegal Thumb shift value: %d"), value
);
5575 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5576 newval
|= value
<< 6;
5577 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5580 case BFD_RELOC_VTABLE_INHERIT
:
5581 case BFD_RELOC_VTABLE_ENTRY
:
5585 case BFD_RELOC_NONE
:
5587 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5588 _("Bad relocation fixup type (%d)\n"), fixP
->fx_r_type
);
5594 /* Translate internal representation of relocation info to BFD target
5597 tc_gen_reloc (section
, fixp
)
5602 bfd_reloc_code_real_type code
;
5604 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5606 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5607 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5608 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5610 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5612 if (fixp
->fx_pcrel
== 0)
5613 reloc
->addend
= fixp
->fx_offset
;
5615 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5617 reloc
->addend
= fixp
->fx_offset
;
5620 switch (fixp
->fx_r_type
)
5625 code
= BFD_RELOC_8_PCREL
;
5632 code
= BFD_RELOC_16_PCREL
;
5639 code
= BFD_RELOC_32_PCREL
;
5643 case BFD_RELOC_ARM_PCREL_BRANCH
:
5645 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5646 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5647 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5648 case BFD_RELOC_VTABLE_ENTRY
:
5649 case BFD_RELOC_VTABLE_INHERIT
:
5650 code
= fixp
->fx_r_type
;
5653 case BFD_RELOC_ARM_LITERAL
:
5654 case BFD_RELOC_ARM_HWLITERAL
:
5655 /* If this is called then the a literal has been referenced across
5656 a section boundry - possibly due to an implicit dump */
5657 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5658 _("Literal referenced across section boundry (Implicit dump?)"));
5661 case BFD_RELOC_ARM_GOTPC
:
5662 assert (fixp
->fx_pcrel
!= 0);
5663 code
= fixp
->fx_r_type
;
5664 code
= BFD_RELOC_32_PCREL
;
5668 case BFD_RELOC_ARM_GOT32
:
5669 case BFD_RELOC_ARM_GOTOFF
:
5670 case BFD_RELOC_ARM_PLT32
:
5671 code
= fixp
->fx_r_type
;
5675 case BFD_RELOC_ARM_IMMEDIATE
:
5676 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5677 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5681 case BFD_RELOC_ARM_OFFSET_IMM
:
5682 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5683 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5690 switch (fixp
->fx_r_type
)
5692 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5693 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5694 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5695 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5696 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5697 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5698 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5699 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5700 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5701 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5702 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5703 default: type
= "<unknown>"; break;
5705 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5706 _("Can not represent %s relocation in this object file format (%d)"),
5707 type
, fixp
->fx_pcrel
);
5713 if (code
== BFD_RELOC_32_PCREL
5715 && fixp
->fx_addsy
== GOT_symbol
)
5716 code
= BFD_RELOC_ARM_GOTPC
;
5719 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5721 if (reloc
->howto
== NULL
)
5723 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5724 _("Can not represent %s relocation in this object file format"),
5725 bfd_get_reloc_code_name (code
));
5733 md_estimate_size_before_relax (fragP
, segtype
)
5737 as_fatal (_("md_estimate_size_before_relax\n"));
5749 as_bad (inst
.error
);
5753 to
= frag_more (inst
.size
);
5754 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
5756 assert (inst
.size
== (2 * THUMB_SIZE
));
5757 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
5758 md_number_to_chars (to
+ 2, inst
.instruction
, THUMB_SIZE
);
5761 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
5763 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5764 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
5765 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
5780 /* Align the instruction.
5781 This may not be the right thing to do but ... */
5782 /* arm_align (2, 0); */
5783 listing_prev_line (); /* Defined in listing.h */
5785 /* Align the previous label if needed. */
5786 if (last_label_seen
!= NULL
)
5788 symbol_set_frag (last_label_seen
, frag_now
);
5789 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
5790 S_SET_SEGMENT (last_label_seen
, now_seg
);
5793 memset (&inst
, '\0', sizeof (inst
));
5794 inst
.reloc
.type
= BFD_RELOC_NONE
;
5797 str
++; /* Skip leading white space */
5799 /* Scan up to the end of the op-code, which must end in white space or
5801 for (start
= p
= str
; *p
!= '\0'; p
++)
5807 as_bad (_("No operator -- statement `%s'\n"), str
);
5813 CONST
struct thumb_opcode
*opcode
;
5817 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
5821 inst
.instruction
= opcode
->value
;
5822 inst
.size
= opcode
->size
;
5823 (*opcode
->parms
)(p
);
5824 output_inst (start
);
5830 CONST
struct asm_opcode
*opcode
;
5832 inst
.size
= INSN_SIZE
;
5833 /* p now points to the end of the opcode, probably white space, but we
5834 have to break the opcode up in case it contains condionals and flags;
5835 keep trying with progressively smaller basic instructions until one
5836 matches, or we run out of opcode. */
5837 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
5838 for (; q
!= str
; q
--)
5842 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
5844 if (opcode
&& opcode
->template)
5846 unsigned long flag_bits
= 0;
5849 /* Check that this instruction is supported for this CPU */
5850 if ((opcode
->variants
& cpu_variant
) == 0)
5853 inst
.instruction
= opcode
->value
;
5854 if (q
== p
) /* Just a simple opcode */
5856 if (opcode
->comp_suffix
!= 0)
5857 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
5858 opcode
->comp_suffix
);
5861 inst
.instruction
|= COND_ALWAYS
;
5862 (*opcode
->parms
)(q
, 0);
5864 output_inst (start
);
5868 /* Now check for a conditional */
5872 CONST
struct asm_cond
*cond
;
5876 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
5880 if (cond
->value
== 0xf0000000)
5882 _("Warning: Use of the 'nv' conditional is deprecated\n"));
5884 inst
.instruction
|= cond
->value
;
5888 inst
.instruction
|= COND_ALWAYS
;
5891 inst
.instruction
|= COND_ALWAYS
;
5893 /* if there is a compulsory suffix, it should come here, before
5894 any optional flags. */
5895 if (opcode
->comp_suffix
)
5897 CONST
char *s
= opcode
->comp_suffix
;
5909 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
5910 opcode
->comp_suffix
);
5917 /* The remainder, if any should now be flags for the instruction;
5918 Scan these checking each one found with the opcode. */
5922 CONST
struct asm_flg
*flag
= opcode
->flags
;
5931 for (flagno
= 0; flag
[flagno
].template; flagno
++)
5933 if (streq (r
, flag
[flagno
].template))
5935 flag_bits
|= flag
[flagno
].set_bits
;
5941 if (! flag
[flagno
].template)
5948 (*opcode
->parms
) (p
, flag_bits
);
5949 output_inst (start
);
5958 /* It wasn't an instruction, but it might be a register alias of the form
5968 if (*q
&& !strncmp (q
, ".req ", 4))
5971 char * copy_of_str
= str
;
5978 for (r
= q
; *r
!= '\0'; r
++)
5988 regnum
= arm_reg_parse (& q
);
5991 reg
= arm_reg_parse (& str
);
5997 insert_reg_alias (str
, regnum
);
6001 as_warn (_("register '%s' does not exist\n"), q
);
6004 else if (regnum
!= FAIL
)
6007 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
6009 /* Do not warn abpout redefinitions to the same alias. */
6012 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6016 as_warn (_("ignoring incomplete .req pseuso op"));
6023 as_bad (_("bad instruction `%s'"), start
);
6028 * Invocation line includes a switch not recognized by the base assembler.
6029 * See if it's a processor-specific option. These are:
6030 * Cpu variants, the arm part is optional:
6031 * -m[arm]1 Currently not supported.
6032 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6033 * -m[arm]3 Arm 3 processor
6034 * -m[arm]6[xx], Arm 6 processors
6035 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6036 * -mstrongarm[110] Arm 8 processors
6037 * -mall All (except the ARM1)
6039 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6040 * -mfpe-old (No float load/store multiples)
6041 * -mno-fpu Disable all floating point instructions
6042 * Run-time endian selection:
6043 * -EB big endian cpu
6044 * -EL little endian cpu
6045 * ARM Procedure Calling Standard:
6046 * -mapcs-32 32 bit APCS
6047 * -mapcs-26 26 bit APCS
6048 * -mapcs-float Pass floats in float regs
6049 * -mapcs-reentrant Position independent code
6050 * -mthumb-interwork Code supports Arm/Thumb interworking
6051 * -moabi Old ELF ABI
6054 CONST
char * md_shortopts
= "m:k";
6055 struct option md_longopts
[] =
6057 #ifdef ARM_BI_ENDIAN
6058 #define OPTION_EB (OPTION_MD_BASE + 0)
6059 {"EB", no_argument
, NULL
, OPTION_EB
},
6060 #define OPTION_EL (OPTION_MD_BASE + 1)
6061 {"EL", no_argument
, NULL
, OPTION_EL
},
6063 #define OPTION_OABI (OPTION_MD_BASE +2)
6064 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6067 {NULL
, no_argument
, NULL
, 0}
6069 size_t md_longopts_size
= sizeof (md_longopts
);
6072 md_parse_option (c
, arg
)
6080 #ifdef ARM_BI_ENDIAN
6082 target_big_endian
= 1;
6085 target_big_endian
= 0;
6093 if (streq (str
, "fpa10"))
6094 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6095 else if (streq (str
, "fpa11"))
6096 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6097 else if (streq (str
, "fpe-old"))
6098 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6104 if (streq (str
, "no-fpu"))
6105 cpu_variant
&= ~FPU_ALL
;
6110 if (streq (str
, "oabi"))
6116 /* Limit assembler to generating only Thumb instructions: */
6117 if (streq (str
, "thumb"))
6119 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6120 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6123 else if (streq (str
, "thumb-interwork"))
6125 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
| ARM_ARCHv4
;
6126 #if defined OBJ_COFF || defined OBJ_ELF
6127 support_interwork
= true;
6135 if (streq (str
, "all"))
6137 cpu_variant
= ARM_ALL
| FPU_ALL
;
6140 #if defined OBJ_COFF || defined OBJ_ELF
6141 if (! strncmp (str
, "apcs-", 5))
6143 /* GCC passes on all command line options starting "-mapcs-..."
6144 to us, so we must parse them here. */
6148 if (streq (str
, "32"))
6150 uses_apcs_26
= false;
6153 else if (streq (str
, "26"))
6155 uses_apcs_26
= true;
6158 else if (streq (str
, "frame"))
6160 /* Stack frames are being generated - does not affect
6164 else if (streq (str
, "stack-check"))
6166 /* Stack checking is being performed - does not affect
6167 linkage, but does require that the functions
6168 __rt_stkovf_split_small and __rt_stkovf_split_big be
6169 present in the final link. */
6173 else if (streq (str
, "float"))
6175 /* Floating point arguments are being passed in the floating
6176 point registers. This does affect linking, since this
6177 version of the APCS is incompatible with the version that
6178 passes floating points in the integer registers. */
6180 uses_apcs_float
= true;
6183 else if (streq (str
, "reentrant"))
6185 /* Reentrant code has been generated. This does affect
6186 linking, since there is no point in linking reentrant/
6187 position independent code with absolute position code. */
6192 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6196 /* Strip off optional "arm" */
6197 if (! strncmp (str
, "arm", 3))
6203 if (streq (str
, "1"))
6204 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6210 if (streq (str
, "2"))
6211 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6212 else if (streq (str
, "250"))
6213 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6219 if (streq (str
, "3"))
6220 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6226 switch (strtol (str
, NULL
, 10))
6233 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6241 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6253 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6259 cpu_variant
|= (ARM_THUMB
| ARM_ARCHv4
);
6263 cpu_variant
|= ARM_LONGMUL
;
6266 case 'f': /* fe => fp enabled cpu. */
6272 case 'c': /* Left over from 710c processor name. */
6273 case 'd': /* Debug */
6274 case 'i': /* Embedded ICE */
6275 /* Included for completeness in ARM processor naming. */
6285 if (streq (str
, "8") || streq (str
, "810"))
6286 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCHv4
| ARM_LONGMUL
;
6292 if (streq (str
, "9"))
6293 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
;
6294 else if (streq (str
, "9tdmi"))
6295 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
| ARM_THUMB
;
6301 if (streq (str
, "strongarm")
6302 || streq (str
, "strongarm110")
6303 || streq (str
, "strongarm1100"))
6304 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCHv4
| ARM_LONGMUL
;
6310 /* Select variant based on architecture rather than processor */
6316 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6317 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6318 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6323 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6327 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6329 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6334 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCHv4
;
6338 case 't': cpu_variant
|= ARM_THUMB
; break;
6340 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6345 as_bad (_("Invalid architecture variant -m%s"), arg
);
6352 as_bad (_("Invalid processor variant -m%s"), arg
);
6375 ARM Specific Assembler Options:\n\
6376 -m[arm][<processor name>] select processor variant\n\
6377 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
6378 -mthumb only allow Thumb instructions\n\
6379 -mthumb-interwork mark the assembled code as supporting interworking\n\
6380 -mall allow any instruction\n\
6381 -mfpa10, -mfpa11 select floating point architecture\n\
6382 -mfpe-old don't allow floating-point multiple instructions\n\
6383 -mno-fpu don't allow any floating-point instructions.\n"));
6386 -k generate PIC code.\n"));
6387 #if defined OBJ_COFF || defined OBJ_ELF
6390 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6393 -mapcs-float floating point args are passed in FP regs\n"));
6396 -mapcs-reentrant the code is position independent/reentrant\n"));
6401 -moabi support the old ELF ABI\n"));
6403 #ifdef ARM_BI_ENDIAN
6406 -EB assemble code for a big endian cpu\n\
6407 -EL assemble code for a little endian cpu\n"));
6411 /* We need to be able to fix up arbitrary expressions in some statements.
6412 This is so that we can handle symbols that are an arbitrary distance from
6413 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6414 which returns part of an address in a form which will be valid for
6415 a data instruction. We do this by pushing the expression into a symbol
6416 in the expr_section, and creating a fix for that. */
6419 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6428 arm_fix_data
* arm_data
;
6436 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6440 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6445 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6446 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6447 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6448 arm_data
->thumb_mode
= thumb_mode
;
6455 * This fix_new is called by cons via TC_CONS_FIX_NEW
6457 * We check the expression to see if it is of the form
6458 * __GLOBAL_OFFSET_TABLE + ???
6459 * If it is then this is a PC relative reference to the GOT.
6466 * .word __GLOBAL_OFFSET_TABLE + (. - (L2 + 4))
6468 * In this case use a reloc type BFD_RELOC_ARM_GOTPC instead of the
6469 * normal BFD_RELOC_{16,32,64}
6473 cons_fix_new_arm (frag
, where
, size
, exp
)
6479 bfd_reloc_code_real_type type
;
6484 * @@ Should look at CPU word size.
6489 type
= BFD_RELOC_16
;
6493 type
= BFD_RELOC_32
;
6496 type
= BFD_RELOC_64
;
6500 /* Look for possible GOTPC reloc */
6503 * Look for pic assembler and 'undef symbol + expr symbol' expression
6504 * and a 32 bit size.
6507 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6510 /* A good place to do this, although this was probably not intended
6511 * for this kind of use. We need to dump the literal pool before
6512 * references are made to a null symbol pointer. */
6516 if (current_poolP
!= NULL
)
6518 subseg_set (text_section
, 0); /* Put it at the end of text section */
6520 listing_prev_line ();
6525 arm_start_line_hook ()
6527 last_label_seen
= NULL
;
6531 arm_frob_label (sym
)
6534 last_label_seen
= sym
;
6536 ARM_SET_THUMB (sym
, thumb_mode
);
6538 #if defined OBJ_COFF || defined OBJ_ELF
6539 ARM_SET_INTERWORK (sym
, support_interwork
);
6542 if (label_is_thumb_function_name
)
6544 /* When the address of a Thumb function is taken the bottom
6545 bit of that address should be set. This will allow
6546 interworking between Arm and Thumb functions to work
6549 THUMB_SET_FUNC (sym
, 1);
6551 label_is_thumb_function_name
= false;
6555 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6559 arm_adjust_symtab ()
6564 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6566 if (ARM_IS_THUMB (sym
))
6568 if (THUMB_IS_FUNC (sym
))
6570 /* Mark the symbol as a Thumb function. */
6571 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6572 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6573 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6575 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6576 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6578 as_bad (_("%s: unexpected function type: %d"),
6579 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6581 else switch (S_GET_STORAGE_CLASS (sym
))
6584 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6587 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6590 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6592 default: /* do nothing */
6597 if (ARM_IS_INTERWORK (sym
))
6598 coffsymbol(sym
->bsym
)->native
->u
.syment
.n_flags
= 0xFF;
6603 elf_symbol_type
* elf_sym
;
6606 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6608 if (ARM_IS_THUMB (sym
))
6610 if (THUMB_IS_FUNC (sym
))
6612 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6613 bind
= ELF_ST_BIND (elf_sym
);
6614 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6624 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6626 *input_line_pointer
= '/';
6627 input_line_pointer
+= 5;
6628 *input_line_pointer
= 0;
6636 arm_canonicalize_symbol_name (name
)
6641 if (thumb_mode
&& (len
= strlen (name
)) > 5
6642 && streq (name
+ len
- 5, "/data"))
6644 *(name
+ len
- 5) = 0;
6651 arm_validate_fix (fixP
)
6654 /* If the destination of the branch is a defined symbol which does not have
6655 the THUMB_FUNC attribute, then we must be calling a function which has
6656 the (interfacearm) attribute. We look for the Thumb entry point to that
6657 function and change the branch to refer to that function instead. */
6658 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6659 && fixP
->fx_addsy
!= NULL
6660 && S_IS_DEFINED (fixP
->fx_addsy
)
6661 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6663 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6671 /* Relocations against Thumb function names must be left unadjusted,
6672 so that the linker can use this information to correctly set the
6673 bottom bit of their addresses. The MIPS version of this function
6674 also prevents relocations that are mips-16 specific, but I do not
6675 know why it does this.
6678 There is one other problem that ought to be addressed here, but
6679 which currently is not: Taking the address of a label (rather
6680 than a function) and then later jumping to that address. Such
6681 addresses also ought to have their bottom bit set (assuming that
6682 they reside in Thumb code), but at the moment they will not. */
6685 arm_fix_adjustable (fixP
)
6689 if (fixP
->fx_addsy
== NULL
)
6692 /* Prevent all adjustments to global symbols. */
6693 if (S_IS_EXTERN (fixP
->fx_addsy
))
6696 if (S_IS_WEAK (fixP
->fx_addsy
))
6699 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6700 && fixP
->fx_subsy
== NULL
)
6703 /* We need the symbol name for the VTABLE entries */
6704 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6705 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6712 elf32_arm_target_format ()
6714 if (target_big_endian
)
6716 return "elf32-bigarm-oabi";
6718 return "elf32-bigarm";
6721 return "elf32-littlearm-oabi";
6723 return "elf32-littlearm";
6727 armelf_frob_symbol (symp
, puntp
)
6731 elf_frob_symbol (symp
, puntp
);
6735 arm_force_relocation (fixp
)
6738 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6739 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6740 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
6746 static bfd_reloc_code_real_type
6756 bfd_reloc_code_real_type reloc
;
6760 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
6761 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
6762 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
6763 /* ScottB: Jan 30, 1998 */
6764 /* Added support for parsing "var(PLT)" branch instructions */
6765 /* generated by GCC for PLT relocs */
6766 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
6767 NULL
, 0, BFD_RELOC_UNUSED
6771 for (i
= 0, ip
= input_line_pointer
;
6772 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
6774 id
[i
] = tolower (*ip
);
6776 for (i
= 0; reloc_map
[i
].str
; i
++)
6777 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
6780 input_line_pointer
+= reloc_map
[i
].len
;
6782 return reloc_map
[i
].reloc
;
6786 s_arm_elf_cons (nbytes
)
6791 #ifdef md_flush_pending_output
6792 md_flush_pending_output ();
6795 if (is_it_end_of_statement ())
6797 demand_empty_rest_of_line ();
6801 #ifdef md_cons_align
6802 md_cons_align (nbytes
);
6807 bfd_reloc_code_real_type reloc
;
6811 if (exp
.X_op
== O_symbol
6812 && * input_line_pointer
== '('
6813 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
6815 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
6816 int size
= bfd_get_reloc_size (howto
);
6819 as_bad ("%s relocations do not fit in %d bytes", howto
->name
, nbytes
);
6822 register char * p
= frag_more ((int) nbytes
);
6823 int offset
= nbytes
- size
;
6825 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
6830 emit_expr (& exp
, (unsigned int) nbytes
);
6832 while (*input_line_pointer
++ == ',');
6834 input_line_pointer
--; /* Put terminator back into stream. */
6835 demand_empty_rest_of_line ();
6838 #endif /* OBJ_ELF */