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));
900 static void s_thumb_set
PARAMS ((int));
901 static void arm_s_text
PARAMS ((int));
902 static void arm_s_data
PARAMS ((int));
904 static void arm_s_section
PARAMS ((int));
905 static void s_arm_elf_cons
PARAMS ((int));
908 static int my_get_expression
PARAMS ((expressionS
*, char **));
910 CONST pseudo_typeS md_pseudo_table
[] =
912 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
914 { "align", s_align
, 0 },
916 { "thumb", s_thumb
, 0 },
917 { "code", s_code
, 0 },
918 { "force_thumb", s_force_thumb
, 0 },
919 { "thumb_func", s_thumb_func
, 0 },
920 { "thumb_set", s_thumb_set
, 0 },
921 { "even", s_even
, 0 },
922 { "ltorg", s_ltorg
, 0 },
923 { "pool", s_ltorg
, 0 },
924 /* Allow for the effect of section changes. */
925 { "text", arm_s_text
, 0 },
926 { "data", arm_s_data
, 0 },
928 { "section", arm_s_section
, 0 },
929 { "section.s", arm_s_section
, 0 },
930 { "sect", arm_s_section
, 0 },
931 { "sect.s", arm_s_section
, 0 },
932 { "word", s_arm_elf_cons
, 4 },
933 { "long", s_arm_elf_cons
, 4 },
937 { "extend", float_cons
, 'x' },
938 { "ldouble", float_cons
, 'x' },
939 { "packed", float_cons
, 'p' },
943 /* Stuff needed to resolve the label ambiguity
953 symbolS
* last_label_seen
;
954 static int label_is_thumb_function_name
= false;
958 #define MAX_LITERAL_POOL_SIZE 1024
960 typedef struct literalS
962 struct expressionS exp
;
963 struct arm_it
* inst
;
966 literalT literals
[MAX_LITERAL_POOL_SIZE
];
967 int next_literal_pool_place
= 0; /* Next free entry in the pool */
968 int lit_pool_num
= 1; /* Next literal pool number */
969 symbolS
* current_poolP
= NULL
;
976 if (current_poolP
== NULL
)
977 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
978 (valueT
) 0, &zero_address_frag
);
980 /* Check if this literal value is already in the pool: */
981 while (lit_count
< next_literal_pool_place
)
983 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
984 && inst
.reloc
.exp
.X_op
== O_constant
985 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
986 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
991 if (lit_count
== next_literal_pool_place
) /* new entry */
993 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
995 inst
.error
= _("Literal Pool Overflow");
999 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1000 lit_count
= next_literal_pool_place
++;
1003 inst
.reloc
.exp
.X_op
= O_symbol
;
1004 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1005 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1010 /* Can't use symbol_new here, so have to create a symbol and then at
1011 a later date assign it a value. Thats what these functions do. */
1013 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1015 CONST
char * name
; /* It is copied, the caller can modify */
1016 segT segment
; /* Segment identifier (SEG_<something>) */
1017 valueT valu
; /* Symbol value */
1018 fragS
* frag
; /* Associated fragment */
1020 unsigned int name_length
;
1021 char * preserved_copy_of_name
;
1023 name_length
= strlen (name
) + 1; /* +1 for \0 */
1024 obstack_grow (¬es
, name
, name_length
);
1025 preserved_copy_of_name
= obstack_finish (¬es
);
1026 #ifdef STRIP_UNDERSCORE
1027 if (preserved_copy_of_name
[0] == '_')
1028 preserved_copy_of_name
++;
1031 #ifdef tc_canonicalize_symbol_name
1032 preserved_copy_of_name
=
1033 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1036 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1038 S_SET_SEGMENT (symbolP
, segment
);
1039 S_SET_VALUE (symbolP
, valu
);
1040 symbol_clear_list_pointers(symbolP
);
1042 symbol_set_frag (symbolP
, frag
);
1044 /* Link to end of symbol chain. */
1046 extern int symbol_table_frozen
;
1047 if (symbol_table_frozen
)
1051 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1053 obj_symbol_new_hook (symbolP
);
1055 #ifdef tc_symbol_new_hook
1056 tc_symbol_new_hook (symbolP
);
1060 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1061 #endif /* DEBUG_SYMS */
1064 /* Check that an immediate is valid, and if so, convert it to the right format. */
1067 validate_immediate (val
)
1073 #define rotate_left(v, n) (v << n | v >> (32 - n))
1075 for (i
= 0; i
< 32; i
+= 2)
1076 if ((a
= rotate_left (val
, i
)) <= 0xff)
1077 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1083 validate_offset_imm (val
, hwse
)
1087 if ((hwse
&& (val
< -255 || val
> 255))
1088 || (val
< -4095 || val
> 4095))
1098 as_bad (_("Invalid syntax for .req directive."));
1105 /* We don't support putting frags in the BSS segment, we fake it by
1106 marking in_bss, then looking at s_skip for clues?.. */
1107 subseg_set (bss_section
, 0);
1108 demand_empty_rest_of_line ();
1115 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1116 frag_align (1, 0, 0);
1118 record_alignment (now_seg
, 1);
1120 demand_empty_rest_of_line ();
1130 if (current_poolP
== NULL
)
1133 /* Align pool as you have word accesses */
1134 /* Only make a frag if we have to ... */
1136 frag_align (2, 0, 0);
1138 record_alignment (now_seg
, 2);
1140 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1142 symbol_locate (current_poolP
, sym_name
, now_seg
,
1143 (valueT
) frag_now_fix (), frag_now
);
1144 symbol_table_insert (current_poolP
);
1146 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1148 #if defined OBJ_COFF || defined OBJ_ELF
1149 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1152 while (lit_count
< next_literal_pool_place
)
1153 /* First output the expression in the instruction to the pool */
1154 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1156 next_literal_pool_place
= 0;
1157 current_poolP
= NULL
;
1161 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1165 register long temp_fill
;
1166 long max_alignment
= 15;
1168 temp
= get_absolute_expression ();
1169 if (temp
> max_alignment
)
1170 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1173 as_bad (_("Alignment negative. 0 assumed."));
1177 if (*input_line_pointer
== ',')
1179 input_line_pointer
++;
1180 temp_fill
= get_absolute_expression ();
1188 /* Only make a frag if we HAVE to. . . */
1189 if (temp
&& !need_pass_2
)
1190 frag_align (temp
, (int) temp_fill
, 0);
1191 demand_empty_rest_of_line ();
1193 record_alignment (now_seg
, temp
);
1197 s_force_thumb (ignore
)
1200 /* If we are not already in thumb mode go into it, EVEN if
1201 the target processor does not support thumb instructions.
1202 This is used by gcc/config/arm/lib1funcs.asm for example
1203 to compile interworking support functions even if the
1204 target processor should not support interworking. */
1210 record_alignment (now_seg
, 1);
1213 demand_empty_rest_of_line ();
1217 s_thumb_func (ignore
)
1220 /* The following label is the name/address of the start of a Thumb function.
1221 We need to know this for the interworking support. */
1223 label_is_thumb_function_name
= true;
1225 demand_empty_rest_of_line ();
1228 /* Perform a .set directive, but also mark the alias as
1229 being a thumb function. */
1235 /* XXX the following is a duplicate of the code for s_set() in read.c
1236 We cannot just call that code as we need to get at the symbol that
1238 register char * name
;
1239 register char delim
;
1240 register char * end_name
;
1241 register symbolS
* symbolP
;
1244 * Especial apologies for the random logic:
1245 * this just grew, and could be parsed much more simply!
1248 name
= input_line_pointer
;
1249 delim
= get_symbol_end ();
1250 end_name
= input_line_pointer
;
1255 if (*input_line_pointer
!= ',')
1258 as_bad (_("Expected comma after name \"%s\""), name
);
1260 ignore_rest_of_line ();
1264 input_line_pointer
++;
1267 if (name
[0] == '.' && name
[1] == '\0')
1269 /* XXX - this should not happen to .thumb_set */
1273 if ((symbolP
= symbol_find (name
)) == NULL
1274 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1277 /* When doing symbol listings, play games with dummy fragments living
1278 outside the normal fragment chain to record the file and line info
1280 if (listing
& LISTING_SYMBOLS
)
1282 extern struct list_info_struct
* listing_tail
;
1283 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1284 memset (dummy_frag
, 0, sizeof(fragS
));
1285 dummy_frag
->fr_type
= rs_fill
;
1286 dummy_frag
->line
= listing_tail
;
1287 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1288 dummy_frag
->fr_symbol
= symbolP
;
1292 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1295 /* "set" symbols are local unless otherwise specified. */
1296 SF_SET_LOCAL (symbolP
);
1297 #endif /* OBJ_COFF */
1298 } /* make a new symbol */
1300 symbol_table_insert (symbolP
);
1305 && S_IS_DEFINED (symbolP
)
1306 && S_GET_SEGMENT (symbolP
) != reg_section
)
1307 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1309 pseudo_set (symbolP
);
1311 demand_empty_rest_of_line ();
1313 /* XXX now we come to the Thumb specific bit of code. */
1315 THUMB_SET_FUNC (symbolP
, 1);
1316 ARM_SET_THUMB (symbolP
, 1);
1317 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1320 /* If we change section we must dump the literal pool first. */
1325 if (now_seg
!= text_section
)
1335 if (flag_readonly_data_in_text
)
1337 if (now_seg
!= text_section
)
1340 else if (now_seg
!= data_section
)
1348 arm_s_section (ignore
)
1353 obj_elf_section (ignore
);
1358 opcode_select (width
)
1366 if (! (cpu_variant
& ARM_THUMB
))
1367 as_bad (_("selected processor does not support THUMB opcodes"));
1369 /* No need to force the alignment, since we will have been
1370 coming from ARM mode, which is word-aligned. */
1371 record_alignment (now_seg
, 1);
1378 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1379 as_bad (_("selected processor does not support ARM opcodes"));
1382 frag_align (2, 0, 0);
1383 record_alignment (now_seg
, 1);
1388 as_bad (_("invalid instruction size selected (%d)"), width
);
1397 demand_empty_rest_of_line ();
1405 demand_empty_rest_of_line ();
1414 temp
= get_absolute_expression ();
1419 opcode_select (temp
);
1423 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1435 inst
.error
= _("Garbage following instruction");
1439 skip_past_comma (str
)
1445 while ((c
= *p
) == ' ' || c
== ',')
1448 if (c
== ',' && comma
++)
1456 return comma
? SUCCESS
: FAIL
;
1459 /* A standard register must be given at this point. Shift is the place to
1460 put it in the instruction. */
1463 reg_required_here (str
, shift
)
1467 static char buff
[128]; /* XXX */
1469 char * start
= *str
;
1471 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1474 inst
.instruction
|= reg
<< shift
;
1478 /* Restore the start point, we may have got a reg of the wrong class. */
1481 /* In the few cases where we might be able to accept something else
1482 this error can be overridden */
1483 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1490 psr_required_here (str
, cpsr
, spsr
)
1496 char * start
= *str
;
1497 psr
= arm_psr_parse (str
);
1499 if (psr
== cpsr
|| psr
== spsr
)
1502 inst
.instruction
|= 1 << 22;
1507 /* In the few cases where we might be able to accept something else
1508 this error can be overridden */
1509 inst
.error
= _("<psr(f)> expected");
1511 /* Restore the start point. */
1517 co_proc_number (str
)
1520 int processor
, pchar
;
1522 while (**str
== ' ')
1525 /* The data sheet seems to imply that just a number on its own is valid
1526 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1528 if (**str
== 'p' || **str
== 'P')
1532 if (pchar
>= '0' && pchar
<= '9')
1534 processor
= pchar
- '0';
1535 if (**str
>= '0' && **str
<= '9')
1537 processor
= processor
* 10 + *(*str
)++ - '0';
1540 inst
.error
= _("Illegal co-processor number");
1547 inst
.error
= _("Bad or missing co-processor number");
1551 inst
.instruction
|= processor
<< 8;
1556 cp_opc_expr (str
, where
, length
)
1563 while (**str
== ' ')
1566 memset (&expr
, '\0', sizeof (expr
));
1568 if (my_get_expression (&expr
, str
))
1570 if (expr
.X_op
!= O_constant
)
1572 inst
.error
= _("bad or missing expression");
1576 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1578 inst
.error
= _("immediate co-processor expression too large");
1582 inst
.instruction
|= expr
.X_add_number
<< where
;
1587 cp_reg_required_here (str
, where
)
1592 char * start
= *str
;
1594 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1597 inst
.instruction
|= reg
<< where
;
1601 /* In the few cases where we might be able to accept something else
1602 this error can be overridden */
1603 inst
.error
= _("Co-processor register expected");
1605 /* Restore the start point */
1611 fp_reg_required_here (str
, where
)
1616 char * start
= *str
;
1618 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1621 inst
.instruction
|= reg
<< where
;
1625 /* In the few cases where we might be able to accept something else
1626 this error can be overridden */
1627 inst
.error
= _("Floating point register expected");
1629 /* Restore the start point */
1635 cp_address_offset (str
)
1640 while (**str
== ' ')
1643 if (! is_immediate_prefix (**str
))
1645 inst
.error
= _("immediate expression expected");
1651 if (my_get_expression (& inst
.reloc
.exp
, str
))
1654 if (inst
.reloc
.exp
.X_op
== O_constant
)
1656 offset
= inst
.reloc
.exp
.X_add_number
;
1660 inst
.error
= _("co-processor address must be word aligned");
1664 if (offset
> 1023 || offset
< -1023)
1666 inst
.error
= _("offset too large");
1671 inst
.instruction
|= INDEX_UP
;
1675 inst
.instruction
|= offset
>> 2;
1678 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1684 cp_address_required_here (str
)
1699 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1709 if (skip_past_comma (& p
) == SUCCESS
)
1712 write_back
= WRITE_BACK
;
1716 inst
.error
= _("pc may not be used in post-increment");
1720 if (cp_address_offset (& p
) == FAIL
)
1724 pre_inc
= PRE_INDEX
| INDEX_UP
;
1728 /* '['Rn, #expr']'[!] */
1730 if (skip_past_comma (& p
) == FAIL
)
1732 inst
.error
= _("pre-indexed expression expected");
1736 pre_inc
= PRE_INDEX
;
1738 if (cp_address_offset (& p
) == FAIL
)
1746 inst
.error
= _("missing ]");
1757 inst
.error
= _("pc may not be used with write-back");
1762 write_back
= WRITE_BACK
;
1768 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1771 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1772 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1773 inst
.reloc
.pc_rel
= 1;
1774 inst
.instruction
|= (REG_PC
<< 16);
1775 pre_inc
= PRE_INDEX
;
1778 inst
.instruction
|= write_back
| pre_inc
;
1786 unsigned long flags
;
1788 /* Do nothing really */
1789 inst
.instruction
|= flags
; /* This is pointless */
1797 unsigned long flags
;
1799 /* Only one syntax */
1803 if (reg_required_here (&str
, 12) == FAIL
)
1805 inst
.error
= bad_args
;
1809 if (skip_past_comma (&str
) == FAIL
1810 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1812 inst
.error
= _("<psr> expected");
1816 inst
.instruction
|= flags
;
1821 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1825 unsigned long flags
;
1832 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1834 inst
.instruction
|= PSR_ALL
;
1836 /* Sytax should be "<psr>, Rm" */
1837 if (skip_past_comma (&str
) == FAIL
1838 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1840 inst
.error
= bad_args
;
1846 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1847 inst
.instruction
|= PSR_FLAGS
;
1848 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1849 inst
.instruction
|= PSR_CONTROL
;
1852 inst
.error
= bad_args
;
1856 if (skip_past_comma (&str
) == FAIL
)
1858 inst
.error
= bad_args
;
1862 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1864 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1866 /* Immediate expression */
1867 else if (is_immediate_prefix (* str
))
1872 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1874 inst
.error
= _("Register or shift expression expected");
1878 if (inst
.reloc
.exp
.X_add_symbol
)
1880 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1881 inst
.reloc
.pc_rel
= 0;
1885 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1888 inst
.error
= _("Invalid constant");
1892 inst
.instruction
|= value
;
1895 flags
|= INST_IMMEDIATE
;
1899 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1905 inst
.instruction
|= flags
;
1910 /* Long Multiply Parser
1911 UMULL RdLo, RdHi, Rm, Rs
1912 SMULL RdLo, RdHi, Rm, Rs
1913 UMLAL RdLo, RdHi, Rm, Rs
1914 SMLAL RdLo, RdHi, Rm, Rs
1917 do_mull (str
, flags
)
1919 unsigned long flags
;
1921 int rdlo
, rdhi
, rm
, rs
;
1923 /* only one format "rdlo, rdhi, rm, rs" */
1927 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1929 inst
.error
= bad_args
;
1933 if (skip_past_comma (&str
) == FAIL
1934 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1936 inst
.error
= bad_args
;
1940 if (skip_past_comma (&str
) == FAIL
1941 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1943 inst
.error
= bad_args
;
1947 /* rdhi, rdlo and rm must all be different */
1948 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1949 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1951 if (skip_past_comma (&str
) == FAIL
1952 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1954 inst
.error
= bad_args
;
1958 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1960 inst
.error
= bad_pc
;
1964 inst
.instruction
|= flags
;
1972 unsigned long flags
;
1976 /* only one format "rd, rm, rs" */
1980 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1982 inst
.error
= bad_args
;
1988 inst
.error
= bad_pc
;
1992 if (skip_past_comma (&str
) == FAIL
1993 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1995 inst
.error
= bad_args
;
2001 inst
.error
= bad_pc
;
2006 as_tsktsk (_("rd and rm should be different in mul"));
2008 if (skip_past_comma (&str
) == FAIL
2009 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2011 inst
.error
= bad_args
;
2017 inst
.error
= bad_pc
;
2021 inst
.instruction
|= flags
;
2029 unsigned long flags
;
2033 /* only one format "rd, rm, rs, rn" */
2037 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2039 inst
.error
= bad_args
;
2045 inst
.error
= bad_pc
;
2049 if (skip_past_comma (&str
) == FAIL
2050 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2052 inst
.error
= bad_args
;
2058 inst
.error
= bad_pc
;
2063 as_tsktsk (_("rd and rm should be different in mla"));
2065 if (skip_past_comma (&str
) == FAIL
2066 || (rd
= reg_required_here (&str
, 8)) == FAIL
2067 || skip_past_comma (&str
) == FAIL
2068 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2070 inst
.error
= bad_args
;
2074 if (rd
== REG_PC
|| rm
== REG_PC
)
2076 inst
.error
= bad_pc
;
2080 inst
.instruction
|= flags
;
2085 /* Returns the index into fp_values of a floating point number, or -1 if
2086 not in the table. */
2088 my_get_float_expression (str
)
2091 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2097 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2098 /* Look for a raw floating point number */
2099 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2100 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2102 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2104 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2106 if (words
[j
] != fp_values
[i
][j
])
2110 if (j
== MAX_LITTLENUMS
)
2118 /* Try and parse a more complex expression, this will probably fail
2119 unless the code uses a floating point prefix (eg "0f") */
2120 save_in
= input_line_pointer
;
2121 input_line_pointer
= *str
;
2122 if (expression (&exp
) == absolute_section
2123 && exp
.X_op
== O_big
2124 && exp
.X_add_number
< 0)
2126 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2128 if (gen_to_words (words
, 5, (long)15) == 0)
2130 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2132 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2134 if (words
[j
] != fp_values
[i
][j
])
2138 if (j
== MAX_LITTLENUMS
)
2140 *str
= input_line_pointer
;
2141 input_line_pointer
= save_in
;
2148 *str
= input_line_pointer
;
2149 input_line_pointer
= save_in
;
2153 /* Return true if anything in the expression is a bignum */
2155 walk_no_bignums (sp
)
2158 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2161 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2163 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2164 || (symbol_get_value_expression (sp
)->X_op_symbol
2165 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2172 my_get_expression (ep
, str
)
2179 save_in
= input_line_pointer
;
2180 input_line_pointer
= *str
;
2181 seg
= expression (ep
);
2184 if (seg
!= absolute_section
2185 && seg
!= text_section
2186 && seg
!= data_section
2187 && seg
!= bss_section
2188 && seg
!= undefined_section
)
2190 inst
.error
= _("bad_segment");
2191 *str
= input_line_pointer
;
2192 input_line_pointer
= save_in
;
2197 /* Get rid of any bignums now, so that we don't generate an error for which
2198 we can't establish a line number later on. Big numbers are never valid
2199 in instructions, which is where this routine is always called. */
2200 if (ep
->X_op
== O_big
2201 || (ep
->X_add_symbol
2202 && (walk_no_bignums (ep
->X_add_symbol
)
2204 && walk_no_bignums (ep
->X_op_symbol
)))))
2206 inst
.error
= _("Invalid constant");
2207 *str
= input_line_pointer
;
2208 input_line_pointer
= save_in
;
2212 *str
= input_line_pointer
;
2213 input_line_pointer
= save_in
;
2217 /* unrestrict should be one if <shift> <register> is permitted for this
2221 decode_shift (str
, unrestrict
)
2225 struct asm_shift
* shft
;
2229 while (**str
== ' ')
2232 for (p
= *str
; isalpha (*p
); p
++)
2237 inst
.error
= _("Shift expression expected");
2243 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2247 if (!strncmp (*str
, "rrx", 3)
2248 || !strncmp (*str
, "RRX", 3))
2251 inst
.instruction
|= shft
->value
;
2258 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2260 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2264 else if (is_immediate_prefix (* p
))
2268 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2271 /* Validate some simple #expressions */
2272 if (inst
.reloc
.exp
.X_op
== O_constant
)
2274 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2276 /* Reject operations greater than 32, or lsl #32 */
2277 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2279 inst
.error
= _("Invalid immediate shift");
2283 /* Shifts of zero should be converted to lsl (which is zero)*/
2290 /* Shifts of 32 are encoded as 0, for those shifts that
2295 inst
.instruction
|= (num
<< 7) | shft
->value
;
2300 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2301 inst
.reloc
.pc_rel
= 0;
2302 inst
.instruction
|= shft
->value
;
2308 inst
.error
= unrestrict
? _("shift requires register or #expression")
2309 : _("shift requires #expression");
2315 inst
.error
= _("Shift expression expected");
2319 /* Do those data_ops which can take a negative immediate constant */
2320 /* by altering the instuction. A bit of a hack really */
2324 by inverting the second operand, and
2327 by negating the second operand.
2330 negate_data_op (instruction
, value
)
2331 unsigned long * instruction
;
2332 unsigned long value
;
2335 unsigned long negated
, inverted
;
2337 negated
= validate_immediate (-value
);
2338 inverted
= validate_immediate (~value
);
2340 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2344 case OPCODE_SUB
: /* ADD <-> SUB */
2345 new_inst
= OPCODE_ADD
;
2350 new_inst
= OPCODE_SUB
;
2354 case OPCODE_CMP
: /* CMP <-> CMN */
2355 new_inst
= OPCODE_CMN
;
2360 new_inst
= OPCODE_CMP
;
2364 /* Now Inverted ops */
2365 case OPCODE_MOV
: /* MOV <-> MVN */
2366 new_inst
= OPCODE_MVN
;
2371 new_inst
= OPCODE_MOV
;
2375 case OPCODE_AND
: /* AND <-> BIC */
2376 new_inst
= OPCODE_BIC
;
2381 new_inst
= OPCODE_AND
;
2385 case OPCODE_ADC
: /* ADC <-> SBC */
2386 new_inst
= OPCODE_SBC
;
2391 new_inst
= OPCODE_ADC
;
2395 /* We cannot do anything */
2403 *instruction
&= OPCODE_MASK
;
2404 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2415 while (**str
== ' ')
2418 if (reg_required_here (str
, 0) != FAIL
)
2420 if (skip_past_comma (str
) == SUCCESS
)
2422 /* Shift operation on register */
2423 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2429 /* Immediate expression */
2430 if (is_immediate_prefix (**str
))
2434 if (my_get_expression (&inst
.reloc
.exp
, str
))
2437 if (inst
.reloc
.exp
.X_add_symbol
)
2439 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2440 inst
.reloc
.pc_rel
= 0;
2444 if (skip_past_comma (str
) == SUCCESS
)
2446 /* #x, y -- ie explicit rotation by Y */
2447 if (my_get_expression (&expr
, str
))
2450 if (expr
.X_op
!= O_constant
)
2452 inst
.error
= _("Constant expression expected");
2456 /* Rotate must be a multiple of 2 */
2457 if (((unsigned) expr
.X_add_number
) > 30
2458 || (expr
.X_add_number
& 1) != 0
2459 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2461 inst
.error
= _("Invalid constant");
2464 inst
.instruction
|= INST_IMMEDIATE
;
2465 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2466 inst
.instruction
|= expr
.X_add_number
<< 7;
2470 /* Implicit rotation, select a suitable one */
2471 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2475 /* Can't be done, perhaps the code reads something like
2476 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2477 if ((value
= negate_data_op (&inst
.instruction
,
2478 inst
.reloc
.exp
.X_add_number
))
2481 inst
.error
= _("Invalid constant");
2486 inst
.instruction
|= value
;
2489 inst
.instruction
|= INST_IMMEDIATE
;
2494 inst
.error
= _("Register or shift expression expected");
2503 while (**str
== ' ')
2506 if (fp_reg_required_here (str
, 0) != FAIL
)
2510 /* Immediate expression */
2511 if (*((*str
)++) == '#')
2516 while (**str
== ' ')
2519 /* First try and match exact strings, this is to guarantee that
2520 some formats will work even for cross assembly */
2522 for (i
= 0; fp_const
[i
]; i
++)
2524 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2528 *str
+= strlen (fp_const
[i
]);
2529 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2531 inst
.instruction
|= i
+ 8;
2538 /* Just because we didn't get a match doesn't mean that the
2539 constant isn't valid, just that it is in a format that we
2540 don't automatically recognize. Try parsing it with
2541 the standard expression routines. */
2542 if ((i
= my_get_float_expression (str
)) >= 0)
2544 inst
.instruction
|= i
+ 8;
2548 inst
.error
= _("Invalid floating point immediate expression");
2551 inst
.error
= _("Floating point register or immediate expression expected");
2557 do_arit (str
, flags
)
2559 unsigned long flags
;
2564 if (reg_required_here (&str
, 12) == FAIL
2565 || skip_past_comma (&str
) == FAIL
2566 || reg_required_here (&str
, 16) == FAIL
2567 || skip_past_comma (&str
) == FAIL
2568 || data_op2 (&str
) == FAIL
)
2571 inst
.error
= bad_args
;
2575 inst
.instruction
|= flags
;
2583 unsigned long flags
;
2585 /* This is a pseudo-op of the form "adr rd, label" to be converted
2586 into a relative address of the form "add rd, pc, #label-.-8" */
2591 if (reg_required_here (&str
, 12) == FAIL
2592 || skip_past_comma (&str
) == FAIL
2593 || my_get_expression (&inst
.reloc
.exp
, &str
))
2596 inst
.error
= bad_args
;
2599 /* Frag hacking will turn this into a sub instruction if the offset turns
2600 out to be negative. */
2601 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2602 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2603 inst
.reloc
.pc_rel
= 1;
2604 inst
.instruction
|= flags
;
2612 unsigned long flags
;
2617 if (reg_required_here (&str
, 16) == FAIL
)
2620 inst
.error
= bad_args
;
2624 if (skip_past_comma (&str
) == FAIL
2625 || data_op2 (&str
) == FAIL
)
2628 inst
.error
= bad_args
;
2632 inst
.instruction
|= flags
;
2633 if ((flags
& 0x0000f000) == 0)
2634 inst
.instruction
|= CONDS_BIT
;
2643 unsigned long flags
;
2648 if (reg_required_here (&str
, 12) == FAIL
)
2651 inst
.error
= bad_args
;
2655 if (skip_past_comma (&str
) == FAIL
2656 || data_op2 (&str
) == FAIL
)
2659 inst
.error
= bad_args
;
2663 inst
.instruction
|= flags
;
2669 ldst_extend (str
, hwse
)
2680 if (my_get_expression (& inst
.reloc
.exp
, str
))
2683 if (inst
.reloc
.exp
.X_op
== O_constant
)
2685 int value
= inst
.reloc
.exp
.X_add_number
;
2687 if ((hwse
&& (value
< -255 || value
> 255))
2688 || (value
< -4095 || value
> 4095))
2690 inst
.error
= _("address offset too large");
2700 /* Halfword and signextension instructions have the
2701 immediate value split across bits 11..8 and bits 3..0 */
2703 inst
.instruction
|= add
| HWOFFSET_IMM
| (value
>> 4) << 8 | value
& 0xF;
2705 inst
.instruction
|= add
| value
;
2711 inst
.instruction
|= HWOFFSET_IMM
;
2712 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2715 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2716 inst
.reloc
.pc_rel
= 0;
2721 add
= 0; /* and fall through */
2723 (*str
)++; /* and fall through */
2725 if (reg_required_here (str
, 0) == FAIL
)
2729 inst
.instruction
|= add
;
2732 inst
.instruction
|= add
| OFFSET_REG
;
2733 if (skip_past_comma (str
) == SUCCESS
)
2734 return decode_shift (str
, SHIFT_RESTRICT
);
2742 do_ldst (str
, flags
)
2744 unsigned long flags
;
2751 /* This is not ideal, but it is the simplest way of dealing with the
2752 ARM7T halfword instructions (since they use a different
2753 encoding, but the same mnemonic): */
2754 if (halfword
= ((flags
& 0x80000000) != 0))
2756 /* This is actually a load/store of a halfword, or a
2757 signed-extension load */
2758 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2761 = _("Processor does not support halfwords or signed bytes");
2765 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2766 | (flags
& ~COND_MASK
);
2774 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2777 inst
.error
= bad_args
;
2781 if (skip_past_comma (& str
) == FAIL
)
2783 inst
.error
= _("Address expected");
2795 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2798 conflict_reg
= (((conflict_reg
== reg
)
2799 && (inst
.instruction
& LOAD_BIT
))
2808 if (skip_past_comma (&str
) == SUCCESS
)
2810 /* [Rn],... (post inc) */
2811 if (ldst_extend (&str
, halfword
) == FAIL
)
2814 as_warn (_("destination register same as write-back base\n"));
2820 inst
.instruction
|= HWOFFSET_IMM
;
2828 as_warn (_("destination register same as write-back base\n"));
2830 inst
.instruction
|= WRITE_BACK
;
2834 if (! (flags
& TRANS_BIT
))
2841 if (skip_past_comma (&str
) == FAIL
)
2843 inst
.error
= _("pre-indexed expression expected");
2848 if (ldst_extend (&str
, halfword
) == FAIL
)
2856 inst
.error
= _("missing ]");
2866 as_tsktsk (_("destination register same as write-back base\n"));
2868 inst
.instruction
|= WRITE_BACK
;
2872 else if (*str
== '=')
2874 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2880 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2883 if (inst
.reloc
.exp
.X_op
!= O_constant
2884 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2886 inst
.error
= _("Constant expression expected");
2890 if (inst
.reloc
.exp
.X_op
== O_constant
2891 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2893 /* This can be done with a mov instruction */
2894 inst
.instruction
&= LITERAL_MASK
;
2895 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2896 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2902 /* Insert into literal pool */
2903 if (add_to_lit_pool () == FAIL
)
2906 inst
.error
= _("literal pool insertion failed");
2910 /* Change the instruction exp to point to the pool */
2913 inst
.instruction
|= HWOFFSET_IMM
;
2914 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2917 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2918 inst
.reloc
.pc_rel
= 1;
2919 inst
.instruction
|= (REG_PC
<< 16);
2925 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2930 inst
.instruction
|= HWOFFSET_IMM
;
2931 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2934 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2935 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
2936 inst
.reloc
.pc_rel
= 1;
2937 inst
.instruction
|= (REG_PC
<< 16);
2941 if (pre_inc
&& (flags
& TRANS_BIT
))
2942 inst
.error
= _("Pre-increment instruction with translate");
2944 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
2957 /* We come back here if we get ranges concatenated by '+' or '|' */
2975 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
2984 inst
.error
= _("Bad range in register list");
2988 for (i
= cur_reg
+ 1; i
< reg
; i
++)
2990 if (range
& (1 << i
))
2992 (_("Warning: Duplicated register (r%d) in register list"),
3000 if (range
& (1 << reg
))
3001 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3003 else if (reg
<= cur_reg
)
3004 as_tsktsk (_("Warning: Register range not in ascending order"));
3008 } while (skip_past_comma (&str
) != FAIL
3009 || (in_range
= 1, *str
++ == '-'));
3016 inst
.error
= _("Missing `}'");
3024 if (my_get_expression (&expr
, &str
))
3027 if (expr
.X_op
== O_constant
)
3029 if (expr
.X_add_number
3030 != (expr
.X_add_number
& 0x0000ffff))
3032 inst
.error
= _("invalid register mask");
3036 if ((range
& expr
.X_add_number
) != 0)
3038 int regno
= range
& expr
.X_add_number
;
3041 regno
= (1 << regno
) - 1;
3043 (_("Warning: Duplicated register (r%d) in register list"),
3047 range
|= expr
.X_add_number
;
3051 if (inst
.reloc
.type
!= 0)
3053 inst
.error
= _("expression too complex");
3057 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3058 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3059 inst
.reloc
.pc_rel
= 0;
3066 if (*str
== '|' || *str
== '+')
3071 } while (another_range
);
3078 do_ldmstm (str
, flags
)
3080 unsigned long flags
;
3088 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3091 if (base_reg
== REG_PC
)
3093 inst
.error
= _("r15 not allowed as base register");
3101 flags
|= WRITE_BACK
;
3105 if (skip_past_comma (&str
) == FAIL
3106 || (range
= reg_list (&str
)) == FAIL
)
3109 inst
.error
= bad_args
;
3116 flags
|= MULTI_SET_PSR
;
3119 inst
.instruction
|= flags
| range
;
3127 unsigned long flags
;
3132 /* Allow optional leading '#'. */
3133 if (is_immediate_prefix (*str
))
3136 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3139 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3140 inst
.reloc
.pc_rel
= 0;
3141 inst
.instruction
|= flags
;
3149 do_swap (str
, flags
)
3151 unsigned long flags
;
3158 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3163 inst
.error
= _("r15 not allowed in swap");
3167 if (skip_past_comma (&str
) == FAIL
3168 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3171 inst
.error
= bad_args
;
3177 inst
.error
= _("r15 not allowed in swap");
3181 if (skip_past_comma (&str
) == FAIL
3184 inst
.error
= bad_args
;
3191 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3196 inst
.error
= bad_pc
;
3205 inst
.error
= _("missing ]");
3209 inst
.instruction
|= flags
;
3215 do_branch (str
, flags
)
3217 unsigned long flags
;
3219 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3226 /* ScottB: February 5, 1998 */
3227 /* Check to see of PLT32 reloc required for the instruction. */
3229 /* arm_parse_reloc() works on input_line_pointer.
3230 We actually want to parse the operands to the branch instruction
3231 passed in 'str'. Save the input pointer and restore it later. */
3232 save_in
= input_line_pointer
;
3233 input_line_pointer
= str
;
3234 if (inst
.reloc
.exp
.X_op
== O_symbol
3236 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3238 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3239 inst
.reloc
.pc_rel
= 0;
3240 /* Modify str to point to after parsed operands, otherwise
3241 end_of_line() will complain about the (PLT) left in str. */
3242 str
= input_line_pointer
;
3246 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3247 inst
.reloc
.pc_rel
= 1;
3249 input_line_pointer
= save_in
;
3252 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3253 inst
.reloc
.pc_rel
= 1;
3254 #endif /* OBJ_ELF */
3263 unsigned long flags
;
3270 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3274 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3283 unsigned long flags
;
3285 /* Co-processor data operation.
3286 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3290 if (co_proc_number (&str
) == FAIL
)
3293 inst
.error
= bad_args
;
3297 if (skip_past_comma (&str
) == FAIL
3298 || cp_opc_expr (&str
, 20,4) == FAIL
)
3301 inst
.error
= bad_args
;
3305 if (skip_past_comma (&str
) == FAIL
3306 || cp_reg_required_here (&str
, 12) == FAIL
)
3309 inst
.error
= bad_args
;
3313 if (skip_past_comma (&str
) == FAIL
3314 || cp_reg_required_here (&str
, 16) == FAIL
)
3317 inst
.error
= bad_args
;
3321 if (skip_past_comma (&str
) == FAIL
3322 || cp_reg_required_here (&str
, 0) == FAIL
)
3325 inst
.error
= bad_args
;
3329 if (skip_past_comma (&str
) == SUCCESS
)
3331 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3334 inst
.error
= bad_args
;
3344 do_lstc (str
, flags
)
3346 unsigned long flags
;
3348 /* Co-processor register load/store.
3349 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3354 if (co_proc_number (&str
) == FAIL
)
3357 inst
.error
= bad_args
;
3361 if (skip_past_comma (&str
) == FAIL
3362 || cp_reg_required_here (&str
, 12) == FAIL
)
3365 inst
.error
= bad_args
;
3369 if (skip_past_comma (&str
) == FAIL
3370 || cp_address_required_here (&str
) == FAIL
)
3373 inst
.error
= bad_args
;
3377 inst
.instruction
|= flags
;
3383 do_co_reg (str
, flags
)
3385 unsigned long flags
;
3387 /* Co-processor register transfer.
3388 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3393 if (co_proc_number (&str
) == FAIL
)
3396 inst
.error
= bad_args
;
3400 if (skip_past_comma (&str
) == FAIL
3401 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3404 inst
.error
= bad_args
;
3408 if (skip_past_comma (&str
) == FAIL
3409 || reg_required_here (&str
, 12) == FAIL
)
3412 inst
.error
= bad_args
;
3416 if (skip_past_comma (&str
) == FAIL
3417 || cp_reg_required_here (&str
, 16) == FAIL
)
3420 inst
.error
= bad_args
;
3424 if (skip_past_comma (&str
) == FAIL
3425 || cp_reg_required_here (&str
, 0) == FAIL
)
3428 inst
.error
= bad_args
;
3432 if (skip_past_comma (&str
) == SUCCESS
)
3434 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3437 inst
.error
= bad_args
;
3447 do_fp_ctrl (str
, flags
)
3449 unsigned long flags
;
3451 /* FP control registers.
3452 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3457 if (reg_required_here (&str
, 12) == FAIL
)
3460 inst
.error
= bad_args
;
3469 do_fp_ldst (str
, flags
)
3471 unsigned long flags
;
3476 switch (inst
.suffix
)
3481 inst
.instruction
|= CP_T_X
;
3484 inst
.instruction
|= CP_T_Y
;
3487 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3493 if (fp_reg_required_here (&str
, 12) == FAIL
)
3496 inst
.error
= bad_args
;
3500 if (skip_past_comma (&str
) == FAIL
3501 || cp_address_required_here (&str
) == FAIL
)
3504 inst
.error
= bad_args
;
3512 do_fp_ldmstm (str
, flags
)
3514 unsigned long flags
;
3521 if (fp_reg_required_here (&str
, 12) == FAIL
)
3524 inst
.error
= bad_args
;
3528 /* Get Number of registers to transfer */
3529 if (skip_past_comma (&str
) == FAIL
3530 || my_get_expression (&inst
.reloc
.exp
, &str
))
3533 inst
.error
= _("constant expression expected");
3537 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3539 inst
.error
= _("Constant value required for number of registers");
3543 num_regs
= inst
.reloc
.exp
.X_add_number
;
3545 if (num_regs
< 1 || num_regs
> 4)
3547 inst
.error
= _("number of registers must be in the range [1:4]");
3554 inst
.instruction
|= CP_T_X
;
3557 inst
.instruction
|= CP_T_Y
;
3560 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3574 /* The instruction specified "ea" or "fd", so we can only accept
3575 [Rn]{!}. The instruction does not really support stacking or
3576 unstacking, so we have to emulate these by setting appropriate
3577 bits and offsets. */
3578 if (skip_past_comma (&str
) == FAIL
3582 inst
.error
= bad_args
;
3590 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3598 inst
.error
= bad_args
;
3609 inst
.error
= _("R15 not allowed as base register with write-back");
3616 if (flags
& CP_T_Pre
)
3619 offset
= 3 * num_regs
;
3625 /* Post-increment */
3629 offset
= 3 * num_regs
;
3633 /* No write-back, so convert this into a standard pre-increment
3634 instruction -- aesthetically more pleasing. */
3635 flags
= CP_T_Pre
| CP_T_UD
;
3640 inst
.instruction
|= flags
| offset
;
3642 else if (skip_past_comma (&str
) == FAIL
3643 || cp_address_required_here (&str
) == FAIL
)
3646 inst
.error
= bad_args
;
3654 do_fp_dyadic (str
, flags
)
3656 unsigned long flags
;
3661 switch (inst
.suffix
)
3666 inst
.instruction
|= 0x00000080;
3669 inst
.instruction
|= 0x00080000;
3675 if (fp_reg_required_here (&str
, 12) == FAIL
)
3678 inst
.error
= bad_args
;
3682 if (skip_past_comma (&str
) == FAIL
3683 || fp_reg_required_here (&str
, 16) == FAIL
)
3686 inst
.error
= bad_args
;
3690 if (skip_past_comma (&str
) == FAIL
3691 || fp_op2 (&str
) == FAIL
)
3694 inst
.error
= bad_args
;
3698 inst
.instruction
|= flags
;
3704 do_fp_monadic (str
, flags
)
3706 unsigned long flags
;
3711 switch (inst
.suffix
)
3716 inst
.instruction
|= 0x00000080;
3719 inst
.instruction
|= 0x00080000;
3725 if (fp_reg_required_here (&str
, 12) == FAIL
)
3728 inst
.error
= bad_args
;
3732 if (skip_past_comma (&str
) == FAIL
3733 || fp_op2 (&str
) == FAIL
)
3736 inst
.error
= bad_args
;
3740 inst
.instruction
|= flags
;
3746 do_fp_cmp (str
, flags
)
3748 unsigned long flags
;
3753 if (fp_reg_required_here (&str
, 16) == FAIL
)
3756 inst
.error
= bad_args
;
3760 if (skip_past_comma (&str
) == FAIL
3761 || fp_op2 (&str
) == FAIL
)
3764 inst
.error
= bad_args
;
3768 inst
.instruction
|= flags
;
3774 do_fp_from_reg (str
, flags
)
3776 unsigned long flags
;
3781 switch (inst
.suffix
)
3786 inst
.instruction
|= 0x00000080;
3789 inst
.instruction
|= 0x00080000;
3795 if (fp_reg_required_here (&str
, 16) == FAIL
)
3798 inst
.error
= bad_args
;
3802 if (skip_past_comma (&str
) == FAIL
3803 || reg_required_here (&str
, 12) == FAIL
)
3806 inst
.error
= bad_args
;
3810 inst
.instruction
|= flags
;
3816 do_fp_to_reg (str
, flags
)
3818 unsigned long flags
;
3823 if (reg_required_here (&str
, 12) == FAIL
)
3826 if (skip_past_comma (&str
) == FAIL
3827 || fp_reg_required_here (&str
, 0) == FAIL
)
3830 inst
.error
= bad_args
;
3834 inst
.instruction
|= flags
;
3839 /* Thumb specific routines */
3841 /* Parse and validate that a register is of the right form, this saves
3842 repeated checking of this information in many similar cases.
3843 Unlike the 32-bit case we do not insert the register into the opcode
3844 here, since the position is often unknown until the full instruction
3847 thumb_reg (strp
, hi_lo
)
3853 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3861 inst
.error
= _("lo register required");
3869 inst
.error
= _("hi register required");
3881 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3884 thumb_add_sub (str
, subtract
)
3888 int Rd
, Rs
, Rn
= FAIL
;
3893 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3894 || skip_past_comma (&str
) == FAIL
)
3897 inst
.error
= bad_args
;
3901 if (is_immediate_prefix (*str
))
3905 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3910 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3913 if (skip_past_comma (&str
) == FAIL
)
3915 /* Two operand format, shuffle the registers and pretend there
3920 else if (is_immediate_prefix (*str
))
3923 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3926 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3930 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3931 for the latter case, EXPR contains the immediate that was found. */
3934 /* All register format. */
3935 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
3939 inst
.error
= _("dest and source1 must be the same register");
3943 /* Can't do this for SUB */
3946 inst
.error
= _("subtract valid only on lo regs");
3950 inst
.instruction
= (T_OPCODE_ADD_HI
3951 | (Rd
> 7 ? THUMB_H1
: 0)
3952 | (Rn
> 7 ? THUMB_H2
: 0));
3953 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
3957 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
3958 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
3963 /* Immediate expression, now things start to get nasty. */
3965 /* First deal with HI regs, only very restricted cases allowed:
3966 Adjusting SP, and using PC or SP to get an address. */
3967 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
3968 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
3970 inst
.error
= _("invalid Hi register with immediate");
3974 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3976 /* Value isn't known yet, all we can do is store all the fragments
3977 we know about in the instruction and let the reloc hacking
3979 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
3980 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
3984 int offset
= inst
.reloc
.exp
.X_add_number
;
3994 /* Quick check, in case offset is MIN_INT */
3997 inst
.error
= _("immediate value out of range");
4006 if (offset
& ~0x1fc)
4008 inst
.error
= _("invalid immediate value for stack adjust");
4011 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4012 inst
.instruction
|= offset
>> 2;
4014 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4017 || (offset
& ~0x3fc))
4019 inst
.error
= _("invalid immediate for address calculation");
4022 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4024 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4030 inst
.error
= _("immediate value out of range");
4033 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4034 inst
.instruction
|= (Rd
<< 8) | offset
;
4040 inst
.error
= _("immediate value out of range");
4043 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4044 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4052 thumb_shift (str
, shift
)
4056 int Rd
, Rs
, Rn
= FAIL
;
4061 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4062 || skip_past_comma (&str
) == FAIL
)
4065 inst
.error
= bad_args
;
4069 if (is_immediate_prefix (*str
))
4071 /* Two operand immediate format, set Rs to Rd. */
4074 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4079 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4082 if (skip_past_comma (&str
) == FAIL
)
4084 /* Two operand format, shuffle the registers and pretend there
4089 else if (is_immediate_prefix (*str
))
4092 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4095 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4099 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4100 for the latter case, EXPR contains the immediate that was found. */
4106 inst
.error
= _("source1 and dest must be same register");
4112 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4113 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4114 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4117 inst
.instruction
|= Rd
| (Rn
<< 3);
4123 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4124 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4125 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4128 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4130 /* Value isn't known yet, create a dummy reloc and let reloc
4131 hacking fix it up */
4133 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4137 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4139 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4141 inst
.error
= _("Invalid immediate for shift");
4145 /* Shifts of zero are handled by converting to LSL */
4146 if (shift_value
== 0)
4147 inst
.instruction
= T_OPCODE_LSL_I
;
4149 /* Shifts of 32 are encoded as a shift of zero */
4150 if (shift_value
== 32)
4153 inst
.instruction
|= shift_value
<< 6;
4156 inst
.instruction
|= Rd
| (Rs
<< 3);
4162 thumb_mov_compare (str
, move
)
4171 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4172 || skip_past_comma (&str
) == FAIL
)
4175 inst
.error
= bad_args
;
4179 if (is_immediate_prefix (*str
))
4182 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4185 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4190 if (Rs
< 8 && Rd
< 8)
4192 if (move
== THUMB_MOVE
)
4193 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4194 since a MOV instruction produces unpredictable results */
4195 inst
.instruction
= T_OPCODE_ADD_I3
;
4197 inst
.instruction
= T_OPCODE_CMP_LR
;
4198 inst
.instruction
|= Rd
| (Rs
<< 3);
4202 if (move
== THUMB_MOVE
)
4203 inst
.instruction
= T_OPCODE_MOV_HR
;
4205 inst
.instruction
= T_OPCODE_CMP_HR
;
4208 inst
.instruction
|= THUMB_H1
;
4211 inst
.instruction
|= THUMB_H2
;
4213 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4220 inst
.error
= _("only lo regs allowed with immediate");
4224 if (move
== THUMB_MOVE
)
4225 inst
.instruction
= T_OPCODE_MOV_I8
;
4227 inst
.instruction
= T_OPCODE_CMP_I8
;
4229 inst
.instruction
|= Rd
<< 8;
4231 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4232 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4235 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4239 inst
.error
= _("invalid immediate");
4243 inst
.instruction
|= value
;
4251 thumb_load_store (str
, load_store
, size
)
4256 int Rd
, Rb
, Ro
= FAIL
;
4261 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4262 || skip_past_comma (&str
) == FAIL
)
4265 inst
.error
= bad_args
;
4272 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4275 if (skip_past_comma (&str
) != FAIL
)
4277 if (is_immediate_prefix (*str
))
4280 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4283 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4288 inst
.reloc
.exp
.X_op
= O_constant
;
4289 inst
.reloc
.exp
.X_add_number
= 0;
4294 inst
.error
= _("expected ']'");
4299 else if (*str
== '=')
4301 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4307 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4312 if ( inst
.reloc
.exp
.X_op
!= O_constant
4313 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4315 inst
.error
= "Constant expression expected";
4319 if (inst
.reloc
.exp
.X_op
== O_constant
4320 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4322 /* This can be done with a mov instruction */
4324 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4325 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4329 /* Insert into literal pool */
4330 if (add_to_lit_pool () == FAIL
)
4333 inst
.error
= "literal pool insertion failed";
4337 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4338 inst
.reloc
.pc_rel
= 1;
4339 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4340 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4346 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4349 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4350 inst
.reloc
.pc_rel
= 1;
4351 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4352 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4357 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4359 if (size
!= THUMB_WORD
)
4361 inst
.error
= _("byte or halfword not valid for base register");
4364 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4366 inst
.error
= _("R15 based store not allowed");
4369 else if (Ro
!= FAIL
)
4371 inst
.error
= _("Invalid base register for register offset");
4376 inst
.instruction
= T_OPCODE_LDR_PC
;
4377 else if (load_store
== THUMB_LOAD
)
4378 inst
.instruction
= T_OPCODE_LDR_SP
;
4380 inst
.instruction
= T_OPCODE_STR_SP
;
4382 inst
.instruction
|= Rd
<< 8;
4383 if (inst
.reloc
.exp
.X_op
== O_constant
)
4385 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4387 if (offset
& ~0x3fc)
4389 inst
.error
= _("invalid offset");
4393 inst
.instruction
|= offset
>> 2;
4396 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4400 inst
.error
= _("invalid base register in load/store");
4403 else if (Ro
== FAIL
)
4405 /* Immediate offset */
4406 if (size
== THUMB_WORD
)
4407 inst
.instruction
= (load_store
== THUMB_LOAD
4408 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4409 else if (size
== THUMB_HALFWORD
)
4410 inst
.instruction
= (load_store
== THUMB_LOAD
4411 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4413 inst
.instruction
= (load_store
== THUMB_LOAD
4414 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4416 inst
.instruction
|= Rd
| (Rb
<< 3);
4418 if (inst
.reloc
.exp
.X_op
== O_constant
)
4420 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4422 if (offset
& ~(0x1f << size
))
4424 inst
.error
= _("Invalid offset");
4427 inst
.instruction
|= (offset
>> size
) << 6;
4430 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4434 /* Register offset */
4435 if (size
== THUMB_WORD
)
4436 inst
.instruction
= (load_store
== THUMB_LOAD
4437 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4438 else if (size
== THUMB_HALFWORD
)
4439 inst
.instruction
= (load_store
== THUMB_LOAD
4440 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4442 inst
.instruction
= (load_store
== THUMB_LOAD
4443 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4445 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4460 /* Handle the Format 4 instructions that do not have equivalents in other
4461 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4472 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4475 if (skip_past_comma (&str
) == FAIL
4476 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4479 inst
.error
= bad_args
;
4483 if (skip_past_comma (&str
) != FAIL
)
4485 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4486 (It isn't allowed for CMP either, but that isn't handled by this
4488 if (inst
.instruction
== T_OPCODE_TST
4489 || inst
.instruction
== T_OPCODE_CMN
4490 || inst
.instruction
== T_OPCODE_NEG
4491 || inst
.instruction
== T_OPCODE_MVN
)
4493 inst
.error
= bad_args
;
4497 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4502 inst
.error
= _("dest and source1 one must be the same register");
4508 if (inst
.instruction
== T_OPCODE_MUL
4510 as_tsktsk (_("Rs and Rd must be different in MUL"));
4512 inst
.instruction
|= Rd
| (Rs
<< 3);
4520 thumb_add_sub (str
, 0);
4527 thumb_shift (str
, THUMB_ASR
);
4534 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4536 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4537 inst
.reloc
.pc_rel
= 1;
4545 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4547 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4548 inst
.reloc
.pc_rel
= 1;
4552 /* Find the real, Thumb encoded start of a Thumb function. */
4555 find_real_start (symbolP
)
4559 const char * name
= S_GET_NAME (symbolP
);
4560 symbolS
* new_target
;
4562 /* This definitonmust agree with the one in gcc/config/arm/thumb.c */
4563 #define STUB_NAME ".real_start_of"
4568 /* Names that start with '.' are local labels, not function entry points.
4569 The compiler may generate BL instructions to these labels because it
4570 needs to perform a branch to a far away location. */
4574 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4575 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4577 new_target
= symbol_find (real_start
);
4579 if (new_target
== NULL
)
4581 as_warn ("Failed to find real start of function: %s\n", name
);
4582 new_target
= symbolP
;
4595 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4597 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4598 inst
.reloc
.pc_rel
= 1;
4601 /* If the destination of the branch is a defined symbol which does not have
4602 the THUMB_FUNC attribute, then we must be calling a function which has
4603 the (interfacearm) attribute. We look for the Thumb entry point to that
4604 function and change the branch to refer to that function instead. */
4605 if ( inst
.reloc
.exp
.X_op
== O_symbol
4606 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4607 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4608 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4609 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4621 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4624 /* This sets THUMB_H2 from the top bit of reg. */
4625 inst
.instruction
|= reg
<< 3;
4627 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4628 should cause the alignment to be checked once it is known. This is
4629 because BX PC only works if the instruction is word aligned. */
4638 thumb_mov_compare (str
, THUMB_COMPARE
);
4651 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4655 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4659 if (skip_past_comma (&str
) == FAIL
4660 || (range
= reg_list (&str
)) == FAIL
)
4663 inst
.error
= bad_args
;
4667 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4669 /* This really doesn't seem worth it. */
4670 inst
.reloc
.type
= BFD_RELOC_NONE
;
4671 inst
.error
= _("Expression too complex");
4677 inst
.error
= _("only lo-regs valid in load/store multiple");
4681 inst
.instruction
|= (Rb
<< 8) | range
;
4689 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4696 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4703 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4715 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4716 || skip_past_comma (&str
) == FAIL
4718 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4719 || skip_past_comma (&str
) == FAIL
4720 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4724 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4728 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4736 thumb_shift (str
, THUMB_LSL
);
4743 thumb_shift (str
, THUMB_LSR
);
4750 thumb_mov_compare (str
, THUMB_MOVE
);
4762 if ((range
= reg_list (&str
)) == FAIL
)
4765 inst
.error
= bad_args
;
4769 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4771 /* This really doesn't seem worth it. */
4772 inst
.reloc
.type
= BFD_RELOC_NONE
;
4773 inst
.error
= _("Expression too complex");
4779 if ((inst
.instruction
== T_OPCODE_PUSH
4780 && (range
& ~0xff) == 1 << REG_LR
)
4781 || (inst
.instruction
== T_OPCODE_POP
4782 && (range
& ~0xff) == 1 << REG_PC
))
4784 inst
.instruction
|= THUMB_PP_PC_LR
;
4789 inst
.error
= _("invalid register list to push/pop instruction");
4794 inst
.instruction
|= range
;
4802 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4809 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4816 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4823 thumb_add_sub (str
, 1);
4833 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4836 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4845 /* This is a pseudo-op of the form "adr rd, label" to be converted
4846 into a relative address of the form "add rd, pc, #label-.-4" */
4850 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4851 || skip_past_comma (&str
) == FAIL
4852 || my_get_expression (&inst
.reloc
.exp
, &str
))
4855 inst
.error
= bad_args
;
4859 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4860 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4861 inst
.reloc
.pc_rel
= 1;
4862 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4870 int len
= strlen (reg_table
[entry
].name
) + 2;
4871 char * buf
= (char *) xmalloc (len
);
4872 char * buf2
= (char *) xmalloc (len
);
4875 #ifdef REGISTER_PREFIX
4876 buf
[i
++] = REGISTER_PREFIX
;
4879 strcpy (buf
+ i
, reg_table
[entry
].name
);
4881 for (i
= 0; buf
[i
]; i
++)
4882 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4886 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4887 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4891 insert_reg_alias (str
, regnum
)
4895 struct reg_entry
*new =
4896 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4897 char *name
= xmalloc (strlen (str
) + 1);
4901 new->number
= regnum
;
4903 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4907 set_constant_flonums ()
4911 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4912 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4921 if ( (arm_ops_hsh
= hash_new ()) == NULL
4922 || (arm_tops_hsh
= hash_new ()) == NULL
4923 || (arm_cond_hsh
= hash_new ()) == NULL
4924 || (arm_shift_hsh
= hash_new ()) == NULL
4925 || (arm_reg_hsh
= hash_new ()) == NULL
4926 || (arm_psr_hsh
= hash_new ()) == NULL
)
4927 as_fatal (_("Virtual memory exhausted"));
4929 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4930 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4931 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4932 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4933 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4934 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4935 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4936 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4937 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4938 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4940 for (i
= 0; reg_table
[i
].name
; i
++)
4943 set_constant_flonums ();
4945 #if defined OBJ_COFF || defined OBJ_ELF
4947 unsigned int flags
= 0;
4949 /* Set the flags in the private structure */
4950 if (uses_apcs_26
) flags
|= F_APCS26
;
4951 if (support_interwork
) flags
|= F_INTERWORK
;
4952 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
4953 if (pic_code
) flags
|= F_PIC
;
4955 bfd_set_private_flags (stdoutput
, flags
);
4962 /* Record the CPU type as well */
4963 switch (cpu_variant
& ARM_CPU_MASK
)
4966 mach
= bfd_mach_arm_2
;
4969 case ARM_3
: /* also ARM_250 */
4970 mach
= bfd_mach_arm_2a
;
4974 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
4975 mach
= bfd_mach_arm_4
;
4978 case ARM_7
: /* also ARM_6 */
4979 mach
= bfd_mach_arm_3
;
4983 /* Catch special cases */
4984 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
4986 if (cpu_variant
& ARM_THUMB
)
4987 mach
= bfd_mach_arm_4T
;
4988 else if ((cpu_variant
& ARM_ARCHv4
) == ARM_ARCHv4
)
4989 mach
= bfd_mach_arm_4
;
4990 else if (cpu_variant
& ARM_LONGMUL
)
4991 mach
= bfd_mach_arm_3M
;
4994 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
4998 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4999 for use in the a.out file, and stores them in the array pointed to by buf.
5000 This knows about the endian-ness of the target machine and does
5001 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5002 2 (short) and 4 (long) Floating numbers are put out as a series of
5003 LITTLENUMS (shorts, here at least)
5006 md_number_to_chars (buf
, val
, n
)
5011 if (target_big_endian
)
5012 number_to_chars_bigendian (buf
, val
, n
);
5014 number_to_chars_littleendian (buf
, val
, n
);
5018 md_chars_to_number (buf
, n
)
5023 unsigned char * where
= (unsigned char *) buf
;
5025 if (target_big_endian
)
5030 result
|= (*where
++ & 255);
5038 result
|= (where
[n
] & 255);
5045 /* Turn a string in input_line_pointer into a floating point constant
5046 of type TYPE, and store the appropriate bytes in *litP. The number
5047 of LITTLENUMS emitted is stored in *sizeP . An error message is
5048 returned, or NULL on OK.
5050 Note that fp constants aren't represent in the normal way on the ARM.
5051 In big endian mode, things are as expected. However, in little endian
5052 mode fp constants are big-endian word-wise, and little-endian byte-wise
5053 within the words. For example, (double) 1.1 in big endian mode is
5054 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5055 the byte sequence 99 99 f1 3f 9a 99 99 99.
5057 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5060 md_atof (type
, litP
, sizeP
)
5066 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5098 return _("Bad call to MD_ATOF()");
5101 t
= atof_ieee (input_line_pointer
, type
, words
);
5103 input_line_pointer
= t
;
5106 if (target_big_endian
)
5108 for (i
= 0; i
< prec
; i
++)
5110 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5116 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5117 8 byte float the order is 1 0 3 2. */
5118 for (i
= 0; i
< prec
; i
+= 2)
5120 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5121 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5129 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5131 md_pcrel_from (fixP
)
5135 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5136 && fixP
->fx_subsy
== NULL
)
5139 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5141 /* PC relative addressing on the Thumb is slightly odd
5142 as the bottom two bits of the PC are forced to zero
5143 for the calculation */
5144 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5147 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5150 /* Round up a section size to the appropriate boundary. */
5152 md_section_align (segment
, size
)
5157 /* Don't align the dwarf2 debug sections */
5158 if (!strncmp (segment
->name
, ".debug", 5))
5161 /* Round all sects to multiple of 4 */
5162 return (size
+ 3) & ~3;
5165 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5166 we have no need to default values of symbols. */
5170 md_undefined_symbol (name
)
5174 if (name
[0] == '_' && name
[1] == 'G'
5175 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5179 if (symbol_find (name
))
5180 as_bad ("GOT already in the symbol table");
5182 GOT_symbol
= symbol_new (name
, undefined_section
,
5183 (valueT
)0, & zero_address_frag
);
5193 /* arm_reg_parse () := if it looks like a register, return its token and
5194 advance the pointer. */
5198 register char ** ccp
;
5200 char * start
= * ccp
;
5203 struct reg_entry
* reg
;
5205 #ifdef REGISTER_PREFIX
5206 if (*start
!= REGISTER_PREFIX
)
5211 #ifdef OPTIONAL_REGISTER_PREFIX
5212 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5216 if (!isalpha (*p
) || !is_name_beginner (*p
))
5220 while (isalpha (c
) || isdigit (c
) || c
== '_')
5224 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5238 register char ** ccp
;
5240 char * start
= * ccp
;
5243 CONST
struct asm_psr
* psr
;
5247 while (isalpha (c
) || c
== '_')
5251 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5264 md_apply_fix3 (fixP
, val
, seg
)
5269 offsetT value
= * val
;
5271 unsigned int newimm
;
5274 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5275 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5277 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5279 /* Note whether this will delete the relocation. */
5280 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5281 if ((fixP
->fx_addsy
== 0 || fixP
->fx_addsy
->sy_value
.X_op
== O_constant
)
5284 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5288 /* If this symbol is in a different section then we need to leave it for
5289 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5290 so we have to undo it's effects here. */
5293 if (fixP
->fx_addsy
!= NULL
5294 && S_IS_DEFINED (fixP
->fx_addsy
)
5295 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5298 && fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
5301 value
+= md_pcrel_from (fixP
);
5305 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc */
5307 switch (fixP
->fx_r_type
)
5309 case BFD_RELOC_ARM_IMMEDIATE
:
5310 newimm
= validate_immediate (value
);
5311 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5313 /* If the instruction will fail, see if we can fix things up by
5314 changing the opcode. */
5315 if (newimm
== (unsigned int) FAIL
5316 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5318 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5319 _("invalid constant (%x) after fixup\n"), value
);
5323 newimm
|= (temp
& 0xfffff000);
5324 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5327 case BFD_RELOC_ARM_OFFSET_IMM
:
5329 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5331 as_bad (_("bad immediate value for offset (%d)"), val
);
5337 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5338 newval
&= 0xff7ff000;
5339 newval
|= value
| (sign
? INDEX_UP
: 0);
5340 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5343 case BFD_RELOC_ARM_OFFSET_IMM8
:
5344 case BFD_RELOC_ARM_HWLITERAL
:
5346 if ((value
= validate_offset_imm (value
, 1)) == FAIL
)
5348 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5349 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5350 _("invalid literal constant: pool needs to be closer\n"));
5352 as_bad (_("bad immediate value for offset (%d)"), value
);
5359 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5360 newval
&= 0xff7ff0f0;
5361 newval
|= ((value
>> 4) << 8) | value
& 0xf | (sign
? INDEX_UP
: 0);
5362 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5365 case BFD_RELOC_ARM_LITERAL
:
5370 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5372 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5373 _("invalid literal constant: pool needs to be closer\n"));
5377 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5378 newval
&= 0xff7ff000;
5379 newval
|= value
| (sign
? INDEX_UP
: 0);
5380 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5383 case BFD_RELOC_ARM_SHIFT_IMM
:
5384 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5385 if (((unsigned long) value
) > 32
5387 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5389 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5390 _("shift expression is too large"));
5395 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5396 else if (value
== 32)
5398 newval
&= 0xfffff07f;
5399 newval
|= (value
& 0x1f) << 7;
5400 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5403 case BFD_RELOC_ARM_SWI
:
5404 if (arm_data
->thumb_mode
)
5406 if (((unsigned long) value
) > 0xff)
5407 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5408 _("Invalid swi expression"));
5409 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5411 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5415 if (((unsigned long) value
) > 0x00ffffff)
5416 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5417 _("Invalid swi expression"));
5418 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5420 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5424 case BFD_RELOC_ARM_MULTI
:
5425 if (((unsigned long) value
) > 0xffff)
5426 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5427 _("Invalid expression in load/store multiple"));
5428 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5429 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5432 case BFD_RELOC_ARM_PCREL_BRANCH
:
5433 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5437 value
= fixP
->fx_offset
;
5439 value
= (value
>> 2) & 0x00ffffff;
5440 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5441 newval
= value
| (newval
& 0xff000000);
5442 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5445 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5446 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5448 addressT diff
= (newval
& 0xff) << 1;
5453 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5454 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5455 _("Branch out of range"));
5456 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5458 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5461 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5462 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5464 addressT diff
= (newval
& 0x7ff) << 1;
5469 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5470 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5471 _("Branch out of range"));
5472 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5474 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5477 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5482 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5483 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5484 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5485 if (diff
& 0x400000)
5488 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5489 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5490 _("Branch with link out of range"));
5492 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5493 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5494 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5495 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5500 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5501 md_number_to_chars (buf
, value
, 1);
5503 else if (!target_oabi
)
5505 value
= fixP
->fx_offset
;
5506 md_number_to_chars (buf
, value
, 1);
5512 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5513 md_number_to_chars (buf
, value
, 2);
5515 else if (!target_oabi
)
5517 value
= fixP
->fx_offset
;
5518 md_number_to_chars (buf
, value
, 2);
5524 case BFD_RELOC_ARM_GOT32
:
5525 case BFD_RELOC_ARM_GOTOFF
:
5526 md_number_to_chars (buf
, 0, 4);
5532 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5533 md_number_to_chars (buf
, value
, 4);
5535 else if (!target_oabi
)
5537 value
= fixP
->fx_offset
;
5538 md_number_to_chars (buf
, value
, 4);
5544 case BFD_RELOC_ARM_PLT32
:
5545 /* It appears the instruction is fully prepared at this point. */
5549 case BFD_RELOC_ARM_GOTPC
:
5550 md_number_to_chars (buf
, value
, 4);
5553 case BFD_RELOC_ARM_CP_OFF_IMM
:
5555 if (value
< -1023 || value
> 1023 || (value
& 3))
5556 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5557 _("Illegal value for co-processor offset"));
5560 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5561 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5562 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5565 case BFD_RELOC_ARM_THUMB_OFFSET
:
5566 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5567 /* Exactly what ranges, and where the offset is inserted depends on
5568 the type of instruction, we can establish this from the top 4 bits */
5569 switch (newval
>> 12)
5571 case 4: /* PC load */
5572 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5573 forced to zero for these loads, so we will need to round
5574 up the offset if the instruction address is not word
5575 aligned (since the final address produced must be, and
5576 we can only describe word-aligned immediate offsets). */
5578 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5579 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5580 _("Invalid offset, target not word aligned (0x%08X)"),
5581 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5583 if ((value
+ 2) & ~0x3fe)
5584 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5585 _("Invalid offset"));
5587 /* Round up, since pc will be rounded down. */
5588 newval
|= (value
+ 2) >> 2;
5591 case 9: /* SP load/store */
5593 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5594 _("Invalid offset"));
5595 newval
|= value
>> 2;
5598 case 6: /* Word load/store */
5600 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5601 _("Invalid offset"));
5602 newval
|= value
<< 4; /* 6 - 2 */
5605 case 7: /* Byte load/store */
5607 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5608 _("Invalid offset"));
5609 newval
|= value
<< 6;
5612 case 8: /* Halfword load/store */
5614 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5615 _("Invalid offset"));
5616 newval
|= value
<< 5; /* 6 - 1 */
5620 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5621 "Unable to process relocation for thumb opcode: %x", newval
);
5624 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5627 case BFD_RELOC_ARM_THUMB_ADD
:
5628 /* This is a complicated relocation, since we use it for all of
5629 the following immediate relocations:
5632 9bit ADD/SUB SP word-aligned
5633 10bit ADD PC/SP word-aligned
5635 The type of instruction being processed is encoded in the
5641 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5643 int rd
= (newval
>> 4) & 0xf;
5644 int rs
= newval
& 0xf;
5645 int subtract
= newval
& 0x8000;
5650 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5651 _("Invalid immediate for stack address calculation"));
5652 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5653 newval
|= value
>> 2;
5655 else if (rs
== REG_PC
|| rs
== REG_SP
)
5659 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5660 _("Invalid immediate for address calculation (value = 0x%08X)"), value
);
5661 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5663 newval
|= value
>> 2;
5668 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5669 _("Invalid 8bit immediate"));
5670 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5671 newval
|= (rd
<< 8) | value
;
5676 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5677 _("Invalid 3bit immediate"));
5678 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5679 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5682 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5685 case BFD_RELOC_ARM_THUMB_IMM
:
5686 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5687 switch (newval
>> 11)
5689 case 0x04: /* 8bit immediate MOV */
5690 case 0x05: /* 8bit immediate CMP */
5691 if (value
< 0 || value
> 255)
5692 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5693 _("Invalid immediate: %d is too large"), value
);
5700 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5703 case BFD_RELOC_ARM_THUMB_SHIFT
:
5704 /* 5bit shift value (0..31) */
5705 if (value
< 0 || value
> 31)
5706 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5707 _("Illegal Thumb shift value: %d"), value
);
5708 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5709 newval
|= value
<< 6;
5710 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5713 case BFD_RELOC_VTABLE_INHERIT
:
5714 case BFD_RELOC_VTABLE_ENTRY
:
5718 case BFD_RELOC_NONE
:
5720 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5721 _("Bad relocation fixup type (%d)\n"), fixP
->fx_r_type
);
5727 /* Translate internal representation of relocation info to BFD target
5730 tc_gen_reloc (section
, fixp
)
5735 bfd_reloc_code_real_type code
;
5737 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5739 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5740 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5741 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5743 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5745 if (fixp
->fx_pcrel
== 0)
5746 reloc
->addend
= fixp
->fx_offset
;
5748 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5750 reloc
->addend
= fixp
->fx_offset
;
5753 switch (fixp
->fx_r_type
)
5758 code
= BFD_RELOC_8_PCREL
;
5765 code
= BFD_RELOC_16_PCREL
;
5772 code
= BFD_RELOC_32_PCREL
;
5776 case BFD_RELOC_ARM_PCREL_BRANCH
:
5778 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5779 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5780 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5781 case BFD_RELOC_VTABLE_ENTRY
:
5782 case BFD_RELOC_VTABLE_INHERIT
:
5783 code
= fixp
->fx_r_type
;
5786 case BFD_RELOC_ARM_LITERAL
:
5787 case BFD_RELOC_ARM_HWLITERAL
:
5788 /* If this is called then the a literal has been referenced across
5789 a section boundry - possibly due to an implicit dump */
5790 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5791 _("Literal referenced across section boundry (Implicit dump?)"));
5794 case BFD_RELOC_ARM_GOTPC
:
5795 assert (fixp
->fx_pcrel
!= 0);
5796 code
= fixp
->fx_r_type
;
5797 code
= BFD_RELOC_32_PCREL
;
5801 case BFD_RELOC_ARM_GOT32
:
5802 case BFD_RELOC_ARM_GOTOFF
:
5803 case BFD_RELOC_ARM_PLT32
:
5804 code
= fixp
->fx_r_type
;
5808 case BFD_RELOC_ARM_IMMEDIATE
:
5809 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5810 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5814 case BFD_RELOC_ARM_OFFSET_IMM
:
5815 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5816 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5823 switch (fixp
->fx_r_type
)
5825 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5826 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5827 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5828 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5829 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5830 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5831 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5832 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5833 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5834 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5835 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5836 default: type
= "<unknown>"; break;
5838 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5839 _("Can not represent %s relocation in this object file format (%d)"),
5840 type
, fixp
->fx_pcrel
);
5846 if (code
== BFD_RELOC_32_PCREL
5848 && fixp
->fx_addsy
== GOT_symbol
)
5850 code
= BFD_RELOC_ARM_GOTPC
;
5851 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5855 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5857 if (reloc
->howto
== NULL
)
5859 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5860 _("Can not represent %s relocation in this object file format"),
5861 bfd_get_reloc_code_name (code
));
5869 md_estimate_size_before_relax (fragP
, segtype
)
5873 as_fatal (_("md_estimate_size_before_relax\n"));
5885 as_bad (inst
.error
);
5889 to
= frag_more (inst
.size
);
5890 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
5892 assert (inst
.size
== (2 * THUMB_SIZE
));
5893 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
5894 md_number_to_chars (to
+ 2, inst
.instruction
, THUMB_SIZE
);
5897 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
5899 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5900 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
5901 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
5916 /* Align the instruction.
5917 This may not be the right thing to do but ... */
5918 /* arm_align (2, 0); */
5919 listing_prev_line (); /* Defined in listing.h */
5921 /* Align the previous label if needed. */
5922 if (last_label_seen
!= NULL
)
5924 symbol_set_frag (last_label_seen
, frag_now
);
5925 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
5926 S_SET_SEGMENT (last_label_seen
, now_seg
);
5929 memset (&inst
, '\0', sizeof (inst
));
5930 inst
.reloc
.type
= BFD_RELOC_NONE
;
5933 str
++; /* Skip leading white space */
5935 /* Scan up to the end of the op-code, which must end in white space or
5937 for (start
= p
= str
; *p
!= '\0'; p
++)
5943 as_bad (_("No operator -- statement `%s'\n"), str
);
5949 CONST
struct thumb_opcode
*opcode
;
5953 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
5957 inst
.instruction
= opcode
->value
;
5958 inst
.size
= opcode
->size
;
5959 (*opcode
->parms
)(p
);
5960 output_inst (start
);
5966 CONST
struct asm_opcode
*opcode
;
5968 inst
.size
= INSN_SIZE
;
5969 /* p now points to the end of the opcode, probably white space, but we
5970 have to break the opcode up in case it contains condionals and flags;
5971 keep trying with progressively smaller basic instructions until one
5972 matches, or we run out of opcode. */
5973 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
5974 for (; q
!= str
; q
--)
5978 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
5980 if (opcode
&& opcode
->template)
5982 unsigned long flag_bits
= 0;
5985 /* Check that this instruction is supported for this CPU */
5986 if ((opcode
->variants
& cpu_variant
) == 0)
5989 inst
.instruction
= opcode
->value
;
5990 if (q
== p
) /* Just a simple opcode */
5992 if (opcode
->comp_suffix
!= 0)
5993 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
5994 opcode
->comp_suffix
);
5997 inst
.instruction
|= COND_ALWAYS
;
5998 (*opcode
->parms
)(q
, 0);
6000 output_inst (start
);
6004 /* Now check for a conditional */
6008 CONST
struct asm_cond
*cond
;
6012 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6016 if (cond
->value
== 0xf0000000)
6018 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6020 inst
.instruction
|= cond
->value
;
6024 inst
.instruction
|= COND_ALWAYS
;
6027 inst
.instruction
|= COND_ALWAYS
;
6029 /* if there is a compulsory suffix, it should come here, before
6030 any optional flags. */
6031 if (opcode
->comp_suffix
)
6033 CONST
char *s
= opcode
->comp_suffix
;
6045 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6046 opcode
->comp_suffix
);
6053 /* The remainder, if any should now be flags for the instruction;
6054 Scan these checking each one found with the opcode. */
6058 CONST
struct asm_flg
*flag
= opcode
->flags
;
6067 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6069 if (streq (r
, flag
[flagno
].template))
6071 flag_bits
|= flag
[flagno
].set_bits
;
6077 if (! flag
[flagno
].template)
6084 (*opcode
->parms
) (p
, flag_bits
);
6085 output_inst (start
);
6094 /* It wasn't an instruction, but it might be a register alias of the form
6104 if (*q
&& !strncmp (q
, ".req ", 4))
6107 char * copy_of_str
= str
;
6114 for (r
= q
; *r
!= '\0'; r
++)
6124 regnum
= arm_reg_parse (& q
);
6127 reg
= arm_reg_parse (& str
);
6133 insert_reg_alias (str
, regnum
);
6137 as_warn (_("register '%s' does not exist\n"), q
);
6140 else if (regnum
!= FAIL
)
6143 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
6145 /* Do not warn abpout redefinitions to the same alias. */
6148 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6152 as_warn (_("ignoring incomplete .req pseuso op"));
6159 as_bad (_("bad instruction `%s'"), start
);
6164 * Invocation line includes a switch not recognized by the base assembler.
6165 * See if it's a processor-specific option. These are:
6166 * Cpu variants, the arm part is optional:
6167 * -m[arm]1 Currently not supported.
6168 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6169 * -m[arm]3 Arm 3 processor
6170 * -m[arm]6[xx], Arm 6 processors
6171 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6172 * -m8[10] Arm 8 processors
6173 * -m9[20][tdmi] Arm 9 processors
6174 * -mstrongarm[110[0]] StrongARM processors
6175 * -mall All (except the ARM1)
6177 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6178 * -mfpe-old (No float load/store multiples)
6179 * -mno-fpu Disable all floating point instructions
6180 * Run-time endian selection:
6181 * -EB big endian cpu
6182 * -EL little endian cpu
6183 * ARM Procedure Calling Standard:
6184 * -mapcs-32 32 bit APCS
6185 * -mapcs-26 26 bit APCS
6186 * -mapcs-float Pass floats in float regs
6187 * -mapcs-reentrant Position independent code
6188 * -mthumb-interwork Code supports Arm/Thumb interworking
6189 * -moabi Old ELF ABI
6192 CONST
char * md_shortopts
= "m:k";
6193 struct option md_longopts
[] =
6195 #ifdef ARM_BI_ENDIAN
6196 #define OPTION_EB (OPTION_MD_BASE + 0)
6197 {"EB", no_argument
, NULL
, OPTION_EB
},
6198 #define OPTION_EL (OPTION_MD_BASE + 1)
6199 {"EL", no_argument
, NULL
, OPTION_EL
},
6201 #define OPTION_OABI (OPTION_MD_BASE +2)
6202 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6205 {NULL
, no_argument
, NULL
, 0}
6207 size_t md_longopts_size
= sizeof (md_longopts
);
6210 md_parse_option (c
, arg
)
6218 #ifdef ARM_BI_ENDIAN
6220 target_big_endian
= 1;
6223 target_big_endian
= 0;
6231 if (streq (str
, "fpa10"))
6232 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6233 else if (streq (str
, "fpa11"))
6234 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6235 else if (streq (str
, "fpe-old"))
6236 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6242 if (streq (str
, "no-fpu"))
6243 cpu_variant
&= ~FPU_ALL
;
6248 if (streq (str
, "oabi"))
6254 /* Limit assembler to generating only Thumb instructions: */
6255 if (streq (str
, "thumb"))
6257 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6258 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6261 else if (streq (str
, "thumb-interwork"))
6263 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
| ARM_ARCHv4
;
6264 #if defined OBJ_COFF || defined OBJ_ELF
6265 support_interwork
= true;
6273 if (streq (str
, "all"))
6275 cpu_variant
= ARM_ALL
| FPU_ALL
;
6278 #if defined OBJ_COFF || defined OBJ_ELF
6279 if (! strncmp (str
, "apcs-", 5))
6281 /* GCC passes on all command line options starting "-mapcs-..."
6282 to us, so we must parse them here. */
6286 if (streq (str
, "32"))
6288 uses_apcs_26
= false;
6291 else if (streq (str
, "26"))
6293 uses_apcs_26
= true;
6296 else if (streq (str
, "frame"))
6298 /* Stack frames are being generated - does not affect
6302 else if (streq (str
, "stack-check"))
6304 /* Stack checking is being performed - does not affect
6305 linkage, but does require that the functions
6306 __rt_stkovf_split_small and __rt_stkovf_split_big be
6307 present in the final link. */
6311 else if (streq (str
, "float"))
6313 /* Floating point arguments are being passed in the floating
6314 point registers. This does affect linking, since this
6315 version of the APCS is incompatible with the version that
6316 passes floating points in the integer registers. */
6318 uses_apcs_float
= true;
6321 else if (streq (str
, "reentrant"))
6323 /* Reentrant code has been generated. This does affect
6324 linking, since there is no point in linking reentrant/
6325 position independent code with absolute position code. */
6330 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6334 /* Strip off optional "arm" */
6335 if (! strncmp (str
, "arm", 3))
6341 if (streq (str
, "1"))
6342 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6348 if (streq (str
, "2"))
6349 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6350 else if (streq (str
, "250"))
6351 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6357 if (streq (str
, "3"))
6358 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6364 switch (strtol (str
, NULL
, 10))
6371 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6379 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6391 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6397 cpu_variant
|= (ARM_THUMB
| ARM_ARCHv4
);
6401 cpu_variant
|= ARM_LONGMUL
;
6404 case 'f': /* fe => fp enabled cpu. */
6410 case 'c': /* Left over from 710c processor name. */
6411 case 'd': /* Debug */
6412 case 'i': /* Embedded ICE */
6413 /* Included for completeness in ARM processor naming. */
6423 if (streq (str
, "8") || streq (str
, "810"))
6424 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCHv4
| ARM_LONGMUL
;
6430 if (streq (str
, "9"))
6431 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
| ARM_THUMB
;
6432 else if (streq (str
, "920"))
6433 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
;
6434 else if (streq (str
, "920t"))
6435 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
| ARM_THUMB
;
6436 else if (streq (str
, "9tdmi"))
6437 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
| ARM_THUMB
;
6443 if (streq (str
, "strongarm")
6444 || streq (str
, "strongarm110")
6445 || streq (str
, "strongarm1100"))
6446 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCHv4
| ARM_LONGMUL
;
6452 /* Select variant based on architecture rather than processor */
6458 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6459 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6460 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6465 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6469 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6471 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6476 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCHv4
;
6480 case 't': cpu_variant
|= ARM_THUMB
; break;
6482 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6487 as_bad (_("Invalid architecture variant -m%s"), arg
);
6494 as_bad (_("Invalid processor variant -m%s"), arg
);
6517 ARM Specific Assembler Options:\n\
6518 -m[arm][<processor name>] select processor variant\n\
6519 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
6520 -mthumb only allow Thumb instructions\n\
6521 -mthumb-interwork mark the assembled code as supporting interworking\n\
6522 -mall allow any instruction\n\
6523 -mfpa10, -mfpa11 select floating point architecture\n\
6524 -mfpe-old don't allow floating-point multiple instructions\n\
6525 -mno-fpu don't allow any floating-point instructions.\n"));
6528 -k generate PIC code.\n"));
6529 #if defined OBJ_COFF || defined OBJ_ELF
6532 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6535 -mapcs-float floating point args are passed in FP regs\n"));
6538 -mapcs-reentrant the code is position independent/reentrant\n"));
6543 -moabi support the old ELF ABI\n"));
6545 #ifdef ARM_BI_ENDIAN
6548 -EB assemble code for a big endian cpu\n\
6549 -EL assemble code for a little endian cpu\n"));
6553 /* We need to be able to fix up arbitrary expressions in some statements.
6554 This is so that we can handle symbols that are an arbitrary distance from
6555 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6556 which returns part of an address in a form which will be valid for
6557 a data instruction. We do this by pushing the expression into a symbol
6558 in the expr_section, and creating a fix for that. */
6561 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6570 arm_fix_data
* arm_data
;
6578 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6582 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6587 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6588 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6589 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6590 arm_data
->thumb_mode
= thumb_mode
;
6597 * This fix_new is called by cons via TC_CONS_FIX_NEW
6599 * We check the expression to see if it is of the form
6600 * __GLOBAL_OFFSET_TABLE + ???
6601 * If it is then this is a PC relative reference to the GOT.
6608 * .word __GLOBAL_OFFSET_TABLE + (. - (L2 + 4))
6610 * In this case use a reloc type BFD_RELOC_ARM_GOTPC instead of the
6611 * normal BFD_RELOC_{16,32,64}
6615 cons_fix_new_arm (frag
, where
, size
, exp
)
6621 bfd_reloc_code_real_type type
;
6626 * @@ Should look at CPU word size.
6631 type
= BFD_RELOC_16
;
6635 type
= BFD_RELOC_32
;
6638 type
= BFD_RELOC_64
;
6642 /* Look for possible GOTPC reloc */
6645 * Look for pic assembler and 'undef symbol + expr symbol' expression
6646 * and a 32 bit size.
6649 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6652 /* A good place to do this, although this was probably not intended
6653 * for this kind of use. We need to dump the literal pool before
6654 * references are made to a null symbol pointer. */
6658 if (current_poolP
!= NULL
)
6660 subseg_set (text_section
, 0); /* Put it at the end of text section */
6662 listing_prev_line ();
6667 arm_start_line_hook ()
6669 last_label_seen
= NULL
;
6673 arm_frob_label (sym
)
6676 last_label_seen
= sym
;
6678 ARM_SET_THUMB (sym
, thumb_mode
);
6680 #if defined OBJ_COFF || defined OBJ_ELF
6681 ARM_SET_INTERWORK (sym
, support_interwork
);
6684 if (label_is_thumb_function_name
)
6686 /* When the address of a Thumb function is taken the bottom
6687 bit of that address should be set. This will allow
6688 interworking between Arm and Thumb functions to work
6691 THUMB_SET_FUNC (sym
, 1);
6693 label_is_thumb_function_name
= false;
6697 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6701 arm_adjust_symtab ()
6706 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6708 if (ARM_IS_THUMB (sym
))
6710 if (THUMB_IS_FUNC (sym
))
6712 /* Mark the symbol as a Thumb function. */
6713 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6714 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6715 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6717 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6718 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6720 as_bad (_("%s: unexpected function type: %d"),
6721 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6723 else switch (S_GET_STORAGE_CLASS (sym
))
6726 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6729 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6732 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6734 default: /* do nothing */
6739 if (ARM_IS_INTERWORK (sym
))
6740 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
6745 elf_symbol_type
* elf_sym
;
6748 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6750 if (ARM_IS_THUMB (sym
))
6752 if (THUMB_IS_FUNC (sym
))
6754 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6755 bind
= ELF_ST_BIND (elf_sym
);
6756 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6766 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6768 *input_line_pointer
= '/';
6769 input_line_pointer
+= 5;
6770 *input_line_pointer
= 0;
6778 arm_canonicalize_symbol_name (name
)
6783 if (thumb_mode
&& (len
= strlen (name
)) > 5
6784 && streq (name
+ len
- 5, "/data"))
6786 *(name
+ len
- 5) = 0;
6793 arm_validate_fix (fixP
)
6796 /* If the destination of the branch is a defined symbol which does not have
6797 the THUMB_FUNC attribute, then we must be calling a function which has
6798 the (interfacearm) attribute. We look for the Thumb entry point to that
6799 function and change the branch to refer to that function instead. */
6800 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6801 && fixP
->fx_addsy
!= NULL
6802 && S_IS_DEFINED (fixP
->fx_addsy
)
6803 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6805 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6813 /* Relocations against Thumb function names must be left unadjusted,
6814 so that the linker can use this information to correctly set the
6815 bottom bit of their addresses. The MIPS version of this function
6816 also prevents relocations that are mips-16 specific, but I do not
6817 know why it does this.
6820 There is one other problem that ought to be addressed here, but
6821 which currently is not: Taking the address of a label (rather
6822 than a function) and then later jumping to that address. Such
6823 addresses also ought to have their bottom bit set (assuming that
6824 they reside in Thumb code), but at the moment they will not. */
6827 arm_fix_adjustable (fixP
)
6831 if (fixP
->fx_addsy
== NULL
)
6834 /* Prevent all adjustments to global symbols. */
6835 if (S_IS_EXTERN (fixP
->fx_addsy
))
6838 if (S_IS_WEAK (fixP
->fx_addsy
))
6841 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6842 && fixP
->fx_subsy
== NULL
)
6845 /* We need the symbol name for the VTABLE entries */
6846 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6847 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6854 elf32_arm_target_format ()
6856 if (target_big_endian
)
6858 return "elf32-bigarm-oabi";
6860 return "elf32-bigarm";
6863 return "elf32-littlearm-oabi";
6865 return "elf32-littlearm";
6869 armelf_frob_symbol (symp
, puntp
)
6873 elf_frob_symbol (symp
, puntp
);
6877 arm_force_relocation (fixp
)
6880 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6881 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6882 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
6888 static bfd_reloc_code_real_type
6898 bfd_reloc_code_real_type reloc
;
6902 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
6903 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
6904 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
6905 /* ScottB: Jan 30, 1998 */
6906 /* Added support for parsing "var(PLT)" branch instructions */
6907 /* generated by GCC for PLT relocs */
6908 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
6909 NULL
, 0, BFD_RELOC_UNUSED
6913 for (i
= 0, ip
= input_line_pointer
;
6914 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
6916 id
[i
] = tolower (*ip
);
6918 for (i
= 0; reloc_map
[i
].str
; i
++)
6919 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
6922 input_line_pointer
+= reloc_map
[i
].len
;
6924 return reloc_map
[i
].reloc
;
6928 s_arm_elf_cons (nbytes
)
6933 #ifdef md_flush_pending_output
6934 md_flush_pending_output ();
6937 if (is_it_end_of_statement ())
6939 demand_empty_rest_of_line ();
6943 #ifdef md_cons_align
6944 md_cons_align (nbytes
);
6949 bfd_reloc_code_real_type reloc
;
6953 if (exp
.X_op
== O_symbol
6954 && * input_line_pointer
== '('
6955 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
6957 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
6958 int size
= bfd_get_reloc_size (howto
);
6961 as_bad ("%s relocations do not fit in %d bytes", howto
->name
, nbytes
);
6964 register char * p
= frag_more ((int) nbytes
);
6965 int offset
= nbytes
- size
;
6967 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
6972 emit_expr (& exp
, (unsigned int) nbytes
);
6974 while (*input_line_pointer
++ == ',');
6976 input_line_pointer
--; /* Put terminator back into stream. */
6977 demand_empty_rest_of_line ();
6980 #endif /* OBJ_ELF */