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
34 #include "struc-symbol.h"
40 /* Types of processor to assemble for. */
41 #define ARM_1 0x00000001
42 #define ARM_2 0x00000002
43 #define ARM_3 0x00000004
45 #define ARM_6 0x00000008
46 #define ARM_7 ARM_6 /* same core instruction set */
47 #define ARM_8 ARM_6 /* same core instruction set */
48 #define ARM_9 ARM_6 /* same core instruction set */
49 #define ARM_CPU_MASK 0x0000000f
51 /* The following bitmasks control CPU extensions (ARM7 onwards): */
52 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
53 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
54 #define ARM_THUMB 0x00000040 /* allow BX instruction */
56 #define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
58 /* Some useful combinations: */
59 #define ARM_ANY 0x00ffffff
60 #define ARM_2UP 0x00fffffe
61 #define ARM_ALL ARM_2UP /* Not arm1 only */
62 #define ARM_3UP 0x00fffffc
63 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
65 #define FPU_CORE 0x80000000
66 #define FPU_FPA10 0x40000000
67 #define FPU_FPA11 0x40000000
70 /* Some useful combinations */
71 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
72 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
77 #define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB)
79 #define CPU_DEFAULT ARM_ALL
84 #define FPU_DEFAULT FPU_ALL
87 #define streq(a,b) (strcmp (a, b) == 0)
89 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
90 static int target_oabi
= 0;
92 #if defined OBJ_COFF || defined OBJ_ELF
93 /* Flags stored in private area of BFD structure */
94 static boolean uses_apcs_26
= false;
95 static boolean support_interwork
= false;
96 static boolean uses_apcs_float
= false;
97 static boolean pic_code
= false;
100 /* This array holds the chars that always start a comment. If the
101 pre-processor is disabled, these aren't very useful */
102 CONST
char comment_chars
[] = "@";
104 /* This array holds the chars that only start a comment at the beginning of
105 a line. If the line seems to have the form '# 123 filename'
106 .line and .file directives will appear in the pre-processed output */
107 /* Note that input_file.c hand checks for '#' at the beginning of the
108 first line of the input file. This is because the compiler outputs
109 #NO_APP at the beginning of its output. */
110 /* Also note that comments like this one will always work. */
111 CONST
char line_comment_chars
[] = "#";
114 CONST
char line_separator_chars
[] = ";";
116 CONST
char line_separator_chars
[] = "";
119 /* Chars that can be used to separate mant from exp in floating point nums */
120 CONST
char EXP_CHARS
[] = "eE";
122 /* Chars that mean this number is a floating point constant */
126 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
128 /* Prefix characters that indicate the start of an immediate
130 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
133 symbolS
* GOT_symbol
; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
136 CONST
int md_reloc_size
= 8; /* Size of relocation record */
138 static int thumb_mode
= 0; /* non-zero if assembling thumb instructions */
140 typedef struct arm_fix
148 unsigned long instruction
;
153 bfd_reloc_code_real_type type
;
163 CONST
char * template;
167 static CONST
struct asm_shift shift
[] =
183 #define NO_SHIFT_RESTRICT 1
184 #define SHIFT_RESTRICT 0
186 #define NUM_FLOAT_VALS 8
188 CONST
char * fp_const
[] =
190 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
193 /* Number of littlenums required to hold an extended precision number */
194 #define MAX_LITTLENUMS 6
196 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
206 #define CP_T_X 0x00008000
207 #define CP_T_Y 0x00400000
208 #define CP_T_Pre 0x01000000
209 #define CP_T_UD 0x00800000
210 #define CP_T_WB 0x00200000
212 #define CONDS_BIT (0x00100000)
213 #define LOAD_BIT (0x00100000)
214 #define TRANS_BIT (0x00200000)
218 CONST
char * template;
222 /* This is to save a hash look-up in the common case */
223 #define COND_ALWAYS 0xe0000000
225 static CONST
struct asm_cond conds
[] =
229 {"cs", 0x20000000}, {"hs", 0x20000000},
230 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
245 /* Warning: If the top bit of the set_bits is set, then the standard
246 instruction bitmask is ignored, and the new bitmask is taken from
250 CONST
char * template; /* Basic flag string */
251 unsigned long set_bits
; /* Bits to set */
254 static CONST
struct asm_flg s_flag
[] =
260 static CONST
struct asm_flg ldr_flags
[] =
264 {"bt", 0x00400000 | TRANS_BIT
},
271 static CONST
struct asm_flg str_flags
[] =
275 {"bt", 0x00400000 | TRANS_BIT
},
280 static CONST
struct asm_flg byte_flag
[] =
286 static CONST
struct asm_flg cmp_flags
[] =
293 static CONST
struct asm_flg ldm_flags
[] =
306 static CONST
struct asm_flg stm_flags
[] =
319 static CONST
struct asm_flg lfm_flags
[] =
326 static CONST
struct asm_flg sfm_flags
[] =
333 static CONST
struct asm_flg round_flags
[] =
341 /* The implementation of the FIX instruction is broken on some assemblers,
342 in that it accepts a precision specifier as well as a rounding specifier,
343 despite the fact that this is meaningless. To be more compatible, we
344 accept it as well, though of course it does not set any bits. */
345 static CONST
struct asm_flg fix_flags
[] =
362 static CONST
struct asm_flg except_flag
[] =
368 static CONST
struct asm_flg cplong_flag
[] =
376 CONST
char * template;
377 unsigned long number
;
380 #define PSR_FIELD_MASK 0x000f0000
382 #define PSR_FLAGS 0x00080000
383 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
384 #define PSR_ALL 0x00090000
393 static CONST
struct asm_psr psrs
[] =
397 {"cpsr_all", CPSR_ALL
},
399 {"spsr_all", SPSR_ALL
},
402 {"cpsr_flg", CPSR_FLG
},
403 {"spsr_flg", SPSR_FLG
},
406 {"cpsr_c", CPSR_CTL
},
407 {"cpsr_ctl", CPSR_CTL
},
408 {"spsr_c", SPSR_CTL
},
409 {"spsr_ctl", SPSR_CTL
}
412 /* Functions called by parser */
413 /* ARM instructions */
414 static void do_arit
PARAMS ((char *operands
, unsigned long flags
));
415 static void do_cmp
PARAMS ((char *operands
, unsigned long flags
));
416 static void do_mov
PARAMS ((char *operands
, unsigned long flags
));
417 static void do_ldst
PARAMS ((char *operands
, unsigned long flags
));
418 static void do_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
419 static void do_branch
PARAMS ((char *operands
, unsigned long flags
));
420 static void do_swi
PARAMS ((char *operands
, unsigned long flags
));
421 /* Pseudo Op codes */
422 static void do_adr
PARAMS ((char *operands
, unsigned long flags
));
423 static void do_nop
PARAMS ((char *operands
, unsigned long flags
));
425 static void do_mul
PARAMS ((char *operands
, unsigned long flags
));
426 static void do_mla
PARAMS ((char *operands
, unsigned long flags
));
428 static void do_swap
PARAMS ((char *operands
, unsigned long flags
));
430 static void do_msr
PARAMS ((char *operands
, unsigned long flags
));
431 static void do_mrs
PARAMS ((char *operands
, unsigned long flags
));
433 static void do_mull
PARAMS ((char *operands
, unsigned long flags
));
435 static void do_bx
PARAMS ((char *operands
, unsigned long flags
));
437 /* Coprocessor Instructions */
438 static void do_cdp
PARAMS ((char *operands
, unsigned long flags
));
439 static void do_lstc
PARAMS ((char *operands
, unsigned long flags
));
440 static void do_co_reg
PARAMS ((char *operands
, unsigned long flags
));
441 static void do_fp_ctrl
PARAMS ((char *operands
, unsigned long flags
));
442 static void do_fp_ldst
PARAMS ((char *operands
, unsigned long flags
));
443 static void do_fp_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
444 static void do_fp_dyadic
PARAMS ((char *operands
, unsigned long flags
));
445 static void do_fp_monadic
PARAMS ((char *operands
, unsigned long flags
));
446 static void do_fp_cmp
PARAMS ((char *operands
, unsigned long flags
));
447 static void do_fp_from_reg
PARAMS ((char *operands
, unsigned long flags
));
448 static void do_fp_to_reg
PARAMS ((char *operands
, unsigned long flags
));
450 static void fix_new_arm
PARAMS ((fragS
*frag
, int where
,
451 short int size
, expressionS
*exp
,
452 int pc_rel
, int reloc
));
453 static int arm_reg_parse
PARAMS ((char **ccp
));
454 static int arm_psr_parse
PARAMS ((char **ccp
));
455 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
,
457 static int add_to_lit_pool
PARAMS ((void));
458 static unsigned validate_immediate
PARAMS ((unsigned));
459 static int validate_offset_imm
PARAMS ((int, int));
460 static void opcode_select
PARAMS ((int));
461 static void end_of_line
PARAMS ((char *));
462 static int reg_required_here
PARAMS ((char **, int));
463 static int psr_required_here
PARAMS ((char **, int, int));
464 static int co_proc_number
PARAMS ((char **));
465 static int cp_opc_expr
PARAMS ((char **, int, int));
466 static int cp_reg_required_here
PARAMS ((char **, int));
467 static int fp_reg_required_here
PARAMS ((char **, int));
468 static int cp_address_offset
PARAMS ((char **));
469 static int cp_address_required_here
PARAMS ((char **));
470 static int my_get_float_expression
PARAMS ((char **));
471 static int skip_past_comma
PARAMS ((char **));
472 static int walk_no_bignums
PARAMS ((symbolS
*));
473 static int negate_data_op
PARAMS ((unsigned long *,
475 static int data_op2
PARAMS ((char **));
476 static int fp_op2
PARAMS ((char **));
477 static long reg_list
PARAMS ((char **));
478 static void thumb_load_store
PARAMS ((char *, int, int));
479 static int decode_shift
PARAMS ((char **, int));
480 static int ldst_extend
PARAMS ((char **, int));
481 static void thumb_add_sub
PARAMS ((char *, int));
482 static void insert_reg
PARAMS ((int));
483 static void thumb_shift
PARAMS ((char *, int));
484 static void thumb_mov_compare
PARAMS ((char *, int));
485 static void set_constant_flonums
PARAMS ((void));
486 static valueT md_chars_to_number
PARAMS ((char *, int));
487 static void insert_reg_alias
PARAMS ((char *, int));
488 static void output_inst
PARAMS ((char *));
490 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
493 /* ARM instructions take 4bytes in the object file, Thumb instructions
497 /* LONGEST_INST is the longest basic instruction name without conditions or
499 * ARM7M has 4 of length 5
502 #define LONGEST_INST 5
506 CONST
char * template; /* Basic string to match */
507 unsigned long value
; /* Basic instruction code */
508 CONST
char * comp_suffix
; /* Compulsory suffix that must follow conds */
509 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
510 unsigned long variants
; /* Which CPU variants this exists for */
511 /* Function to call to parse args */
512 void (* parms
) PARAMS ((char *, unsigned long));
515 static CONST
struct asm_opcode insns
[] =
517 /* ARM Instructions */
518 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
519 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
520 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
521 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
522 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
523 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
524 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
525 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
526 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
527 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
528 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
529 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
530 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
531 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
532 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
533 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
534 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
535 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
536 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
537 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
538 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
539 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
540 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
543 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
544 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
546 /* ARM 2 multiplies */
547 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
548 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
550 /* ARM 3 - swp instructions */
551 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
553 /* ARM 6 Coprocessor instructions */
554 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
555 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
556 /* ScottB: our code uses 0x0128f000 for msr.
557 NickC: but this is wrong because the bits 16 and 19 are handled
558 by the PSR_xxx defines above. */
560 /* ARM 7M long multiplies - need signed/unsigned flags! */
561 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
562 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
563 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
564 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
566 /* ARM THUMB interworking */
567 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
569 /* Floating point instructions */
570 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
571 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
572 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
573 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
574 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
575 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
576 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
577 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
578 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
579 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
580 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
581 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
582 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
583 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
584 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
585 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
586 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
587 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
588 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
589 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
590 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
591 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
592 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
593 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
594 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
595 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
596 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
597 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
598 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
599 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
600 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
601 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
602 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
603 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
604 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
605 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
606 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
607 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
608 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
609 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
610 be an optional suffix, but part of the instruction. To be compatible,
612 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
613 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
614 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
615 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
617 /* Generic copressor instructions */
618 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
619 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
620 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
621 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
622 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
625 /* defines for various bits that we will want to toggle */
627 #define INST_IMMEDIATE 0x02000000
628 #define OFFSET_REG 0x02000000
629 #define HWOFFSET_IMM 0x00400000
630 #define SHIFT_BY_REG 0x00000010
631 #define PRE_INDEX 0x01000000
632 #define INDEX_UP 0x00800000
633 #define WRITE_BACK 0x00200000
634 #define MULTI_SET_PSR 0x00400000
636 #define LITERAL_MASK 0xf000f000
637 #define COND_MASK 0xf0000000
638 #define OPCODE_MASK 0xfe1fffff
639 #define DATA_OP_SHIFT 21
641 /* Codes to distinguish the arithmetic instructions */
653 #define OPCODE_CMP 10
654 #define OPCODE_CMN 11
655 #define OPCODE_ORR 12
656 #define OPCODE_MOV 13
657 #define OPCODE_BIC 14
658 #define OPCODE_MVN 15
660 static void do_t_nop
PARAMS ((char *operands
));
661 static void do_t_arit
PARAMS ((char *operands
));
662 static void do_t_add
PARAMS ((char *operands
));
663 static void do_t_asr
PARAMS ((char *operands
));
664 static void do_t_branch9
PARAMS ((char *operands
));
665 static void do_t_branch12
PARAMS ((char *operands
));
666 static void do_t_branch23
PARAMS ((char *operands
));
667 static void do_t_bx
PARAMS ((char *operands
));
668 static void do_t_compare
PARAMS ((char *operands
));
669 static void do_t_ldmstm
PARAMS ((char *operands
));
670 static void do_t_ldr
PARAMS ((char *operands
));
671 static void do_t_ldrb
PARAMS ((char *operands
));
672 static void do_t_ldrh
PARAMS ((char *operands
));
673 static void do_t_lds
PARAMS ((char *operands
));
674 static void do_t_lsl
PARAMS ((char *operands
));
675 static void do_t_lsr
PARAMS ((char *operands
));
676 static void do_t_mov
PARAMS ((char *operands
));
677 static void do_t_push_pop
PARAMS ((char *operands
));
678 static void do_t_str
PARAMS ((char *operands
));
679 static void do_t_strb
PARAMS ((char *operands
));
680 static void do_t_strh
PARAMS ((char *operands
));
681 static void do_t_sub
PARAMS ((char *operands
));
682 static void do_t_swi
PARAMS ((char *operands
));
683 static void do_t_adr
PARAMS ((char *operands
));
685 #define T_OPCODE_MUL 0x4340
686 #define T_OPCODE_TST 0x4200
687 #define T_OPCODE_CMN 0x42c0
688 #define T_OPCODE_NEG 0x4240
689 #define T_OPCODE_MVN 0x43c0
691 #define T_OPCODE_ADD_R3 0x1800
692 #define T_OPCODE_SUB_R3 0x1a00
693 #define T_OPCODE_ADD_HI 0x4400
694 #define T_OPCODE_ADD_ST 0xb000
695 #define T_OPCODE_SUB_ST 0xb080
696 #define T_OPCODE_ADD_SP 0xa800
697 #define T_OPCODE_ADD_PC 0xa000
698 #define T_OPCODE_ADD_I8 0x3000
699 #define T_OPCODE_SUB_I8 0x3800
700 #define T_OPCODE_ADD_I3 0x1c00
701 #define T_OPCODE_SUB_I3 0x1e00
703 #define T_OPCODE_ASR_R 0x4100
704 #define T_OPCODE_LSL_R 0x4080
705 #define T_OPCODE_LSR_R 0x40c0
706 #define T_OPCODE_ASR_I 0x1000
707 #define T_OPCODE_LSL_I 0x0000
708 #define T_OPCODE_LSR_I 0x0800
710 #define T_OPCODE_MOV_I8 0x2000
711 #define T_OPCODE_CMP_I8 0x2800
712 #define T_OPCODE_CMP_LR 0x4280
713 #define T_OPCODE_MOV_HR 0x4600
714 #define T_OPCODE_CMP_HR 0x4500
716 #define T_OPCODE_LDR_PC 0x4800
717 #define T_OPCODE_LDR_SP 0x9800
718 #define T_OPCODE_STR_SP 0x9000
719 #define T_OPCODE_LDR_IW 0x6800
720 #define T_OPCODE_STR_IW 0x6000
721 #define T_OPCODE_LDR_IH 0x8800
722 #define T_OPCODE_STR_IH 0x8000
723 #define T_OPCODE_LDR_IB 0x7800
724 #define T_OPCODE_STR_IB 0x7000
725 #define T_OPCODE_LDR_RW 0x5800
726 #define T_OPCODE_STR_RW 0x5000
727 #define T_OPCODE_LDR_RH 0x5a00
728 #define T_OPCODE_STR_RH 0x5200
729 #define T_OPCODE_LDR_RB 0x5c00
730 #define T_OPCODE_STR_RB 0x5400
732 #define T_OPCODE_PUSH 0xb400
733 #define T_OPCODE_POP 0xbc00
735 #define T_OPCODE_BRANCH 0xe7fe
737 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
739 #define THUMB_SIZE 2 /* Size of thumb instruction */
740 #define THUMB_REG_LO 0x1
741 #define THUMB_REG_HI 0x2
742 #define THUMB_REG_ANY 0x3
744 #define THUMB_H1 0x0080
745 #define THUMB_H2 0x0040
752 #define THUMB_COMPARE 1
755 #define THUMB_STORE 1
757 #define THUMB_PP_PC_LR 0x0100
759 /* These three are used for immediate shifts, do not alter */
761 #define THUMB_HALFWORD 1
766 CONST
char * template; /* Basic string to match */
767 unsigned long value
; /* Basic instruction code */
769 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
772 static CONST
struct thumb_opcode tinsns
[] =
774 {"adc", 0x4140, 2, do_t_arit
},
775 {"add", 0x0000, 2, do_t_add
},
776 {"and", 0x4000, 2, do_t_arit
},
777 {"asr", 0x0000, 2, do_t_asr
},
778 {"b", T_OPCODE_BRANCH
, 2, do_t_branch12
},
779 {"beq", 0xd0fe, 2, do_t_branch9
},
780 {"bne", 0xd1fe, 2, do_t_branch9
},
781 {"bcs", 0xd2fe, 2, do_t_branch9
},
782 {"bhs", 0xd2fe, 2, do_t_branch9
},
783 {"bcc", 0xd3fe, 2, do_t_branch9
},
784 {"bul", 0xd3fe, 2, do_t_branch9
},
785 {"blo", 0xd3fe, 2, do_t_branch9
},
786 {"bmi", 0xd4fe, 2, do_t_branch9
},
787 {"bpl", 0xd5fe, 2, do_t_branch9
},
788 {"bvs", 0xd6fe, 2, do_t_branch9
},
789 {"bvc", 0xd7fe, 2, do_t_branch9
},
790 {"bhi", 0xd8fe, 2, do_t_branch9
},
791 {"bls", 0xd9fe, 2, do_t_branch9
},
792 {"bge", 0xdafe, 2, do_t_branch9
},
793 {"blt", 0xdbfe, 2, do_t_branch9
},
794 {"bgt", 0xdcfe, 2, do_t_branch9
},
795 {"ble", 0xddfe, 2, do_t_branch9
},
796 {"bic", 0x4380, 2, do_t_arit
},
797 {"bl", 0xf7fffffe, 4, do_t_branch23
},
798 {"bx", 0x4700, 2, do_t_bx
},
799 {"cmn", T_OPCODE_CMN
, 2, do_t_arit
},
800 {"cmp", 0x0000, 2, do_t_compare
},
801 {"eor", 0x4040, 2, do_t_arit
},
802 {"ldmia", 0xc800, 2, do_t_ldmstm
},
803 {"ldr", 0x0000, 2, do_t_ldr
},
804 {"ldrb", 0x0000, 2, do_t_ldrb
},
805 {"ldrh", 0x0000, 2, do_t_ldrh
},
806 {"ldrsb", 0x5600, 2, do_t_lds
},
807 {"ldrsh", 0x5e00, 2, do_t_lds
},
808 {"ldsb", 0x5600, 2, do_t_lds
},
809 {"ldsh", 0x5e00, 2, do_t_lds
},
810 {"lsl", 0x0000, 2, do_t_lsl
},
811 {"lsr", 0x0000, 2, do_t_lsr
},
812 {"mov", 0x0000, 2, do_t_mov
},
813 {"mul", T_OPCODE_MUL
, 2, do_t_arit
},
814 {"mvn", T_OPCODE_MVN
, 2, do_t_arit
},
815 {"neg", T_OPCODE_NEG
, 2, do_t_arit
},
816 {"orr", 0x4300, 2, do_t_arit
},
817 {"pop", 0xbc00, 2, do_t_push_pop
},
818 {"push", 0xb400, 2, do_t_push_pop
},
819 {"ror", 0x41c0, 2, do_t_arit
},
820 {"sbc", 0x4180, 2, do_t_arit
},
821 {"stmia", 0xc000, 2, do_t_ldmstm
},
822 {"str", 0x0000, 2, do_t_str
},
823 {"strb", 0x0000, 2, do_t_strb
},
824 {"strh", 0x0000, 2, do_t_strh
},
825 {"swi", 0xdf00, 2, do_t_swi
},
826 {"sub", 0x0000, 2, do_t_sub
},
827 {"tst", T_OPCODE_TST
, 2, do_t_arit
},
829 {"adr", 0x0000, 2, do_t_adr
},
830 {"nop", 0x46C0, 2, do_t_nop
}, /* mov r8,r8 */
839 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
840 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
841 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
847 /* These are the standard names; Users can add aliases with .req */
848 static CONST
struct reg_entry reg_table
[] =
850 /* Processor Register Numbers */
851 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
852 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
853 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
854 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
855 /* APCS conventions */
856 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
857 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
858 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
859 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
861 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
862 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
863 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
864 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
865 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
866 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
867 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
868 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
869 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
870 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
874 #define bad_args _("Bad arguments to instruction");
875 #define bad_pc _("r15 not allowed here");
877 static struct hash_control
* arm_ops_hsh
= NULL
;
878 static struct hash_control
* arm_tops_hsh
= NULL
;
879 static struct hash_control
* arm_cond_hsh
= NULL
;
880 static struct hash_control
* arm_shift_hsh
= NULL
;
881 static struct hash_control
* arm_reg_hsh
= NULL
;
882 static struct hash_control
* arm_psr_hsh
= NULL
;
884 /* This table describes all the machine specific pseudo-ops the assembler
885 has to support. The fields are:
886 pseudo-op name without dot
887 function to call to execute this pseudo-op
888 Integer arg to pass to the function
891 static void s_req
PARAMS ((int));
892 static void s_align
PARAMS ((int));
893 static void s_bss
PARAMS ((int));
894 static void s_even
PARAMS ((int));
895 static void s_ltorg
PARAMS ((int));
896 static void s_arm
PARAMS ((int));
897 static void s_thumb
PARAMS ((int));
898 static void s_code
PARAMS ((int));
899 static void s_force_thumb
PARAMS ((int));
900 static void s_thumb_func
PARAMS ((int));
901 static void s_thumb_set
PARAMS ((int));
902 static void arm_s_text
PARAMS ((int));
903 static void arm_s_data
PARAMS ((int));
905 static void arm_s_section
PARAMS ((int));
906 static void s_arm_elf_cons
PARAMS ((int));
909 static int my_get_expression
PARAMS ((expressionS
*, char **));
911 CONST pseudo_typeS md_pseudo_table
[] =
913 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
915 { "align", s_align
, 0 },
917 { "thumb", s_thumb
, 0 },
918 { "code", s_code
, 0 },
919 { "force_thumb", s_force_thumb
, 0 },
920 { "thumb_func", s_thumb_func
, 0 },
921 { "thumb_set", s_thumb_set
, 0 },
922 { "even", s_even
, 0 },
923 { "ltorg", s_ltorg
, 0 },
924 { "pool", s_ltorg
, 0 },
925 /* Allow for the effect of section changes. */
926 { "text", arm_s_text
, 0 },
927 { "data", arm_s_data
, 0 },
929 { "section", arm_s_section
, 0 },
930 { "section.s", arm_s_section
, 0 },
931 { "sect", arm_s_section
, 0 },
932 { "sect.s", arm_s_section
, 0 },
933 { "word", s_arm_elf_cons
, 4 },
934 { "long", s_arm_elf_cons
, 4 },
938 { "extend", float_cons
, 'x' },
939 { "ldouble", float_cons
, 'x' },
940 { "packed", float_cons
, 'p' },
944 /* Stuff needed to resolve the label ambiguity
954 symbolS
* last_label_seen
;
955 static int label_is_thumb_function_name
= false;
959 #define MAX_LITERAL_POOL_SIZE 1024
961 typedef struct literalS
963 struct expressionS exp
;
964 struct arm_it
* inst
;
967 literalT literals
[MAX_LITERAL_POOL_SIZE
];
968 int next_literal_pool_place
= 0; /* Next free entry in the pool */
969 int lit_pool_num
= 1; /* Next literal pool number */
970 symbolS
* current_poolP
= NULL
;
977 if (current_poolP
== NULL
)
978 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
979 (valueT
) 0, &zero_address_frag
);
981 /* Check if this literal value is already in the pool: */
982 while (lit_count
< next_literal_pool_place
)
984 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
985 && inst
.reloc
.exp
.X_op
== O_constant
986 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
987 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
992 if (lit_count
== next_literal_pool_place
) /* new entry */
994 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
996 inst
.error
= _("Literal Pool Overflow");
1000 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1001 lit_count
= next_literal_pool_place
++;
1004 inst
.reloc
.exp
.X_op
= O_symbol
;
1005 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1006 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1011 /* Can't use symbol_new here, so have to create a symbol and then at
1012 a later date assign it a value. Thats what these functions do. */
1014 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1016 CONST
char * name
; /* It is copied, the caller can modify */
1017 segT segment
; /* Segment identifier (SEG_<something>) */
1018 valueT valu
; /* Symbol value */
1019 fragS
* frag
; /* Associated fragment */
1021 unsigned int name_length
;
1022 char * preserved_copy_of_name
;
1024 name_length
= strlen (name
) + 1; /* +1 for \0 */
1025 obstack_grow (¬es
, name
, name_length
);
1026 preserved_copy_of_name
= obstack_finish (¬es
);
1027 #ifdef STRIP_UNDERSCORE
1028 if (preserved_copy_of_name
[0] == '_')
1029 preserved_copy_of_name
++;
1032 #ifdef tc_canonicalize_symbol_name
1033 preserved_copy_of_name
=
1034 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1037 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1039 S_SET_SEGMENT (symbolP
, segment
);
1040 S_SET_VALUE (symbolP
, valu
);
1041 symbol_clear_list_pointers(symbolP
);
1043 symbol_set_frag (symbolP
, frag
);
1045 /* Link to end of symbol chain. */
1047 extern int symbol_table_frozen
;
1048 if (symbol_table_frozen
)
1052 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1054 obj_symbol_new_hook (symbolP
);
1056 #ifdef tc_symbol_new_hook
1057 tc_symbol_new_hook (symbolP
);
1061 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1062 #endif /* DEBUG_SYMS */
1065 /* Check that an immediate is valid, and if so, convert it to the right format. */
1068 validate_immediate (val
)
1074 #define rotate_left(v, n) (v << n | v >> (32 - n))
1076 for (i
= 0; i
< 32; i
+= 2)
1077 if ((a
= rotate_left (val
, i
)) <= 0xff)
1078 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1084 validate_offset_imm (val
, hwse
)
1088 if ((hwse
&& (val
< -255 || val
> 255))
1089 || (val
< -4095 || val
> 4095))
1099 as_bad (_("Invalid syntax for .req directive."));
1106 /* We don't support putting frags in the BSS segment, we fake it by
1107 marking in_bss, then looking at s_skip for clues?.. */
1108 subseg_set (bss_section
, 0);
1109 demand_empty_rest_of_line ();
1116 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1117 frag_align (1, 0, 0);
1119 record_alignment (now_seg
, 1);
1121 demand_empty_rest_of_line ();
1131 if (current_poolP
== NULL
)
1134 /* Align pool as you have word accesses */
1135 /* Only make a frag if we have to ... */
1137 frag_align (2, 0, 0);
1139 record_alignment (now_seg
, 2);
1141 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1143 symbol_locate (current_poolP
, sym_name
, now_seg
,
1144 (valueT
) frag_now_fix (), frag_now
);
1145 symbol_table_insert (current_poolP
);
1147 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1149 #if defined OBJ_COFF || defined OBJ_ELF
1150 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1153 while (lit_count
< next_literal_pool_place
)
1154 /* First output the expression in the instruction to the pool */
1155 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1157 next_literal_pool_place
= 0;
1158 current_poolP
= NULL
;
1162 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1166 register long temp_fill
;
1167 long max_alignment
= 15;
1169 temp
= get_absolute_expression ();
1170 if (temp
> max_alignment
)
1171 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1174 as_bad (_("Alignment negative. 0 assumed."));
1178 if (*input_line_pointer
== ',')
1180 input_line_pointer
++;
1181 temp_fill
= get_absolute_expression ();
1189 /* Only make a frag if we HAVE to. . . */
1190 if (temp
&& !need_pass_2
)
1191 frag_align (temp
, (int) temp_fill
, 0);
1192 demand_empty_rest_of_line ();
1194 record_alignment (now_seg
, temp
);
1198 s_force_thumb (ignore
)
1201 /* If we are not already in thumb mode go into it, EVEN if
1202 the target processor does not support thumb instructions.
1203 This is used by gcc/config/arm/lib1funcs.asm for example
1204 to compile interworking support functions even if the
1205 target processor should not support interworking. */
1211 record_alignment (now_seg
, 1);
1214 demand_empty_rest_of_line ();
1218 s_thumb_func (ignore
)
1221 /* The following label is the name/address of the start of a Thumb function.
1222 We need to know this for the interworking support. */
1224 label_is_thumb_function_name
= true;
1226 demand_empty_rest_of_line ();
1229 /* Perform a .set directive, but also mark the alias as
1230 being a thumb function. */
1236 /* XXX the following is a duplicate of the code for s_set() in read.c
1237 We cannot just call that code as we need to get at the symbol that
1239 register char * name
;
1240 register char delim
;
1241 register char * end_name
;
1242 register symbolS
* symbolP
;
1245 * Especial apologies for the random logic:
1246 * this just grew, and could be parsed much more simply!
1249 name
= input_line_pointer
;
1250 delim
= get_symbol_end ();
1251 end_name
= input_line_pointer
;
1256 if (*input_line_pointer
!= ',')
1259 as_bad (_("Expected comma after name \"%s\""), name
);
1261 ignore_rest_of_line ();
1265 input_line_pointer
++;
1268 if (name
[0] == '.' && name
[1] == '\0')
1270 /* XXX - this should not happen to .thumb_set */
1274 if ((symbolP
= symbol_find (name
)) == NULL
1275 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1278 /* When doing symbol listings, play games with dummy fragments living
1279 outside the normal fragment chain to record the file and line info
1281 if (listing
& LISTING_SYMBOLS
)
1283 extern struct list_info_struct
* listing_tail
;
1284 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1285 memset (dummy_frag
, 0, sizeof(fragS
));
1286 dummy_frag
->fr_type
= rs_fill
;
1287 dummy_frag
->line
= listing_tail
;
1288 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1289 dummy_frag
->fr_symbol
= symbolP
;
1293 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1296 /* "set" symbols are local unless otherwise specified. */
1297 SF_SET_LOCAL (symbolP
);
1298 #endif /* OBJ_COFF */
1299 } /* make a new symbol */
1301 symbol_table_insert (symbolP
);
1306 && S_IS_DEFINED (symbolP
)
1307 && S_GET_SEGMENT (symbolP
) != reg_section
)
1308 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1310 pseudo_set (symbolP
);
1312 demand_empty_rest_of_line ();
1314 /* XXX now we come to the Thumb specific bit of code. */
1316 THUMB_SET_FUNC (symbolP
, 1);
1317 ARM_SET_THUMB (symbolP
, 1);
1318 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1321 /* If we change section we must dump the literal pool first. */
1326 if (now_seg
!= text_section
)
1336 if (flag_readonly_data_in_text
)
1338 if (now_seg
!= text_section
)
1341 else if (now_seg
!= data_section
)
1349 arm_s_section (ignore
)
1354 obj_elf_section (ignore
);
1359 opcode_select (width
)
1367 if (! (cpu_variant
& ARM_THUMB
))
1368 as_bad (_("selected processor does not support THUMB opcodes"));
1370 /* No need to force the alignment, since we will have been
1371 coming from ARM mode, which is word-aligned. */
1372 record_alignment (now_seg
, 1);
1379 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1380 as_bad (_("selected processor does not support ARM opcodes"));
1383 frag_align (2, 0, 0);
1384 record_alignment (now_seg
, 1);
1389 as_bad (_("invalid instruction size selected (%d)"), width
);
1398 demand_empty_rest_of_line ();
1406 demand_empty_rest_of_line ();
1415 temp
= get_absolute_expression ();
1420 opcode_select (temp
);
1424 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1436 inst
.error
= _("Garbage following instruction");
1440 skip_past_comma (str
)
1446 while ((c
= *p
) == ' ' || c
== ',')
1449 if (c
== ',' && comma
++)
1457 return comma
? SUCCESS
: FAIL
;
1460 /* A standard register must be given at this point. Shift is the place to
1461 put it in the instruction. */
1464 reg_required_here (str
, shift
)
1468 static char buff
[128]; /* XXX */
1470 char * start
= *str
;
1472 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1475 inst
.instruction
|= reg
<< shift
;
1479 /* Restore the start point, we may have got a reg of the wrong class. */
1482 /* In the few cases where we might be able to accept something else
1483 this error can be overridden */
1484 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1491 psr_required_here (str
, cpsr
, spsr
)
1497 char * start
= *str
;
1498 psr
= arm_psr_parse (str
);
1500 if (psr
== cpsr
|| psr
== spsr
)
1503 inst
.instruction
|= 1 << 22;
1508 /* In the few cases where we might be able to accept something else
1509 this error can be overridden */
1510 inst
.error
= _("<psr(f)> expected");
1512 /* Restore the start point. */
1518 co_proc_number (str
)
1521 int processor
, pchar
;
1523 while (**str
== ' ')
1526 /* The data sheet seems to imply that just a number on its own is valid
1527 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1529 if (**str
== 'p' || **str
== 'P')
1533 if (pchar
>= '0' && pchar
<= '9')
1535 processor
= pchar
- '0';
1536 if (**str
>= '0' && **str
<= '9')
1538 processor
= processor
* 10 + *(*str
)++ - '0';
1541 inst
.error
= _("Illegal co-processor number");
1548 inst
.error
= _("Bad or missing co-processor number");
1552 inst
.instruction
|= processor
<< 8;
1557 cp_opc_expr (str
, where
, length
)
1564 while (**str
== ' ')
1567 memset (&expr
, '\0', sizeof (expr
));
1569 if (my_get_expression (&expr
, str
))
1571 if (expr
.X_op
!= O_constant
)
1573 inst
.error
= _("bad or missing expression");
1577 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1579 inst
.error
= _("immediate co-processor expression too large");
1583 inst
.instruction
|= expr
.X_add_number
<< where
;
1588 cp_reg_required_here (str
, where
)
1593 char * start
= *str
;
1595 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1598 inst
.instruction
|= reg
<< where
;
1602 /* In the few cases where we might be able to accept something else
1603 this error can be overridden */
1604 inst
.error
= _("Co-processor register expected");
1606 /* Restore the start point */
1612 fp_reg_required_here (str
, where
)
1617 char * start
= *str
;
1619 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1622 inst
.instruction
|= reg
<< where
;
1626 /* In the few cases where we might be able to accept something else
1627 this error can be overridden */
1628 inst
.error
= _("Floating point register expected");
1630 /* Restore the start point */
1636 cp_address_offset (str
)
1641 while (**str
== ' ')
1644 if (! is_immediate_prefix (**str
))
1646 inst
.error
= _("immediate expression expected");
1652 if (my_get_expression (& inst
.reloc
.exp
, str
))
1655 if (inst
.reloc
.exp
.X_op
== O_constant
)
1657 offset
= inst
.reloc
.exp
.X_add_number
;
1661 inst
.error
= _("co-processor address must be word aligned");
1665 if (offset
> 1023 || offset
< -1023)
1667 inst
.error
= _("offset too large");
1672 inst
.instruction
|= INDEX_UP
;
1676 inst
.instruction
|= offset
>> 2;
1679 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1685 cp_address_required_here (str
)
1700 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1710 if (skip_past_comma (& p
) == SUCCESS
)
1713 write_back
= WRITE_BACK
;
1717 inst
.error
= _("pc may not be used in post-increment");
1721 if (cp_address_offset (& p
) == FAIL
)
1725 pre_inc
= PRE_INDEX
| INDEX_UP
;
1729 /* '['Rn, #expr']'[!] */
1731 if (skip_past_comma (& p
) == FAIL
)
1733 inst
.error
= _("pre-indexed expression expected");
1737 pre_inc
= PRE_INDEX
;
1739 if (cp_address_offset (& p
) == FAIL
)
1747 inst
.error
= _("missing ]");
1758 inst
.error
= _("pc may not be used with write-back");
1763 write_back
= WRITE_BACK
;
1769 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1772 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1773 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1774 inst
.reloc
.pc_rel
= 1;
1775 inst
.instruction
|= (REG_PC
<< 16);
1776 pre_inc
= PRE_INDEX
;
1779 inst
.instruction
|= write_back
| pre_inc
;
1787 unsigned long flags
;
1789 /* Do nothing really */
1790 inst
.instruction
|= flags
; /* This is pointless */
1798 unsigned long flags
;
1800 /* Only one syntax */
1804 if (reg_required_here (&str
, 12) == FAIL
)
1806 inst
.error
= bad_args
;
1810 if (skip_past_comma (&str
) == FAIL
1811 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1813 inst
.error
= _("<psr> expected");
1817 inst
.instruction
|= flags
;
1822 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1826 unsigned long flags
;
1833 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1835 inst
.instruction
|= PSR_ALL
;
1837 /* Sytax should be "<psr>, Rm" */
1838 if (skip_past_comma (&str
) == FAIL
1839 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1841 inst
.error
= bad_args
;
1847 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1848 inst
.instruction
|= PSR_FLAGS
;
1849 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1850 inst
.instruction
|= PSR_CONTROL
;
1853 inst
.error
= bad_args
;
1857 if (skip_past_comma (&str
) == FAIL
)
1859 inst
.error
= bad_args
;
1863 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1865 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1867 /* Immediate expression */
1868 else if (is_immediate_prefix (* str
))
1873 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1875 inst
.error
= _("Register or shift expression expected");
1879 if (inst
.reloc
.exp
.X_add_symbol
)
1881 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1882 inst
.reloc
.pc_rel
= 0;
1886 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1889 inst
.error
= _("Invalid constant");
1893 inst
.instruction
|= value
;
1896 flags
|= INST_IMMEDIATE
;
1900 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1906 inst
.instruction
|= flags
;
1911 /* Long Multiply Parser
1912 UMULL RdLo, RdHi, Rm, Rs
1913 SMULL RdLo, RdHi, Rm, Rs
1914 UMLAL RdLo, RdHi, Rm, Rs
1915 SMLAL RdLo, RdHi, Rm, Rs
1918 do_mull (str
, flags
)
1920 unsigned long flags
;
1922 int rdlo
, rdhi
, rm
, rs
;
1924 /* only one format "rdlo, rdhi, rm, rs" */
1928 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1930 inst
.error
= bad_args
;
1934 if (skip_past_comma (&str
) == FAIL
1935 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1937 inst
.error
= bad_args
;
1941 if (skip_past_comma (&str
) == FAIL
1942 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1944 inst
.error
= bad_args
;
1948 /* rdhi, rdlo and rm must all be different */
1949 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1950 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1952 if (skip_past_comma (&str
) == FAIL
1953 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1955 inst
.error
= bad_args
;
1959 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1961 inst
.error
= bad_pc
;
1965 inst
.instruction
|= flags
;
1973 unsigned long flags
;
1977 /* only one format "rd, rm, rs" */
1981 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1983 inst
.error
= bad_args
;
1989 inst
.error
= bad_pc
;
1993 if (skip_past_comma (&str
) == FAIL
1994 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1996 inst
.error
= bad_args
;
2002 inst
.error
= bad_pc
;
2007 as_tsktsk (_("rd and rm should be different in mul"));
2009 if (skip_past_comma (&str
) == FAIL
2010 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2012 inst
.error
= bad_args
;
2018 inst
.error
= bad_pc
;
2022 inst
.instruction
|= flags
;
2030 unsigned long flags
;
2034 /* only one format "rd, rm, rs, rn" */
2038 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2040 inst
.error
= bad_args
;
2046 inst
.error
= bad_pc
;
2050 if (skip_past_comma (&str
) == FAIL
2051 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2053 inst
.error
= bad_args
;
2059 inst
.error
= bad_pc
;
2064 as_tsktsk (_("rd and rm should be different in mla"));
2066 if (skip_past_comma (&str
) == FAIL
2067 || (rd
= reg_required_here (&str
, 8)) == FAIL
2068 || skip_past_comma (&str
) == FAIL
2069 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2071 inst
.error
= bad_args
;
2075 if (rd
== REG_PC
|| rm
== REG_PC
)
2077 inst
.error
= bad_pc
;
2081 inst
.instruction
|= flags
;
2086 /* Returns the index into fp_values of a floating point number, or -1 if
2087 not in the table. */
2089 my_get_float_expression (str
)
2092 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2098 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2099 /* Look for a raw floating point number */
2100 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2101 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2103 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2105 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2107 if (words
[j
] != fp_values
[i
][j
])
2111 if (j
== MAX_LITTLENUMS
)
2119 /* Try and parse a more complex expression, this will probably fail
2120 unless the code uses a floating point prefix (eg "0f") */
2121 save_in
= input_line_pointer
;
2122 input_line_pointer
= *str
;
2123 if (expression (&exp
) == absolute_section
2124 && exp
.X_op
== O_big
2125 && exp
.X_add_number
< 0)
2127 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2129 if (gen_to_words (words
, 5, (long)15) == 0)
2131 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2133 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2135 if (words
[j
] != fp_values
[i
][j
])
2139 if (j
== MAX_LITTLENUMS
)
2141 *str
= input_line_pointer
;
2142 input_line_pointer
= save_in
;
2149 *str
= input_line_pointer
;
2150 input_line_pointer
= save_in
;
2154 /* Return true if anything in the expression is a bignum */
2156 walk_no_bignums (sp
)
2159 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2162 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2164 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2165 || (symbol_get_value_expression (sp
)->X_op_symbol
2166 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2173 my_get_expression (ep
, str
)
2180 save_in
= input_line_pointer
;
2181 input_line_pointer
= *str
;
2182 seg
= expression (ep
);
2185 if (seg
!= absolute_section
2186 && seg
!= text_section
2187 && seg
!= data_section
2188 && seg
!= bss_section
2189 && seg
!= undefined_section
)
2191 inst
.error
= _("bad_segment");
2192 *str
= input_line_pointer
;
2193 input_line_pointer
= save_in
;
2198 /* Get rid of any bignums now, so that we don't generate an error for which
2199 we can't establish a line number later on. Big numbers are never valid
2200 in instructions, which is where this routine is always called. */
2201 if (ep
->X_op
== O_big
2202 || (ep
->X_add_symbol
2203 && (walk_no_bignums (ep
->X_add_symbol
)
2205 && walk_no_bignums (ep
->X_op_symbol
)))))
2207 inst
.error
= _("Invalid constant");
2208 *str
= input_line_pointer
;
2209 input_line_pointer
= save_in
;
2213 *str
= input_line_pointer
;
2214 input_line_pointer
= save_in
;
2218 /* unrestrict should be one if <shift> <register> is permitted for this
2222 decode_shift (str
, unrestrict
)
2226 struct asm_shift
* shft
;
2230 while (**str
== ' ')
2233 for (p
= *str
; isalpha (*p
); p
++)
2238 inst
.error
= _("Shift expression expected");
2244 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2248 if (!strncmp (*str
, "rrx", 3)
2249 || !strncmp (*str
, "RRX", 3))
2252 inst
.instruction
|= shft
->value
;
2259 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2261 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2265 else if (is_immediate_prefix (* p
))
2269 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2272 /* Validate some simple #expressions */
2273 if (inst
.reloc
.exp
.X_op
== O_constant
)
2275 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2277 /* Reject operations greater than 32, or lsl #32 */
2278 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2280 inst
.error
= _("Invalid immediate shift");
2284 /* Shifts of zero should be converted to lsl (which is zero)*/
2291 /* Shifts of 32 are encoded as 0, for those shifts that
2296 inst
.instruction
|= (num
<< 7) | shft
->value
;
2301 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2302 inst
.reloc
.pc_rel
= 0;
2303 inst
.instruction
|= shft
->value
;
2309 inst
.error
= unrestrict
? _("shift requires register or #expression")
2310 : _("shift requires #expression");
2316 inst
.error
= _("Shift expression expected");
2320 /* Do those data_ops which can take a negative immediate constant */
2321 /* by altering the instuction. A bit of a hack really */
2325 by inverting the second operand, and
2328 by negating the second operand.
2331 negate_data_op (instruction
, value
)
2332 unsigned long * instruction
;
2333 unsigned long value
;
2336 unsigned long negated
, inverted
;
2338 negated
= validate_immediate (-value
);
2339 inverted
= validate_immediate (~value
);
2341 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2345 case OPCODE_SUB
: /* ADD <-> SUB */
2346 new_inst
= OPCODE_ADD
;
2351 new_inst
= OPCODE_SUB
;
2355 case OPCODE_CMP
: /* CMP <-> CMN */
2356 new_inst
= OPCODE_CMN
;
2361 new_inst
= OPCODE_CMP
;
2365 /* Now Inverted ops */
2366 case OPCODE_MOV
: /* MOV <-> MVN */
2367 new_inst
= OPCODE_MVN
;
2372 new_inst
= OPCODE_MOV
;
2376 case OPCODE_AND
: /* AND <-> BIC */
2377 new_inst
= OPCODE_BIC
;
2382 new_inst
= OPCODE_AND
;
2386 case OPCODE_ADC
: /* ADC <-> SBC */
2387 new_inst
= OPCODE_SBC
;
2392 new_inst
= OPCODE_ADC
;
2396 /* We cannot do anything */
2404 *instruction
&= OPCODE_MASK
;
2405 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2416 while (**str
== ' ')
2419 if (reg_required_here (str
, 0) != FAIL
)
2421 if (skip_past_comma (str
) == SUCCESS
)
2423 /* Shift operation on register */
2424 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2430 /* Immediate expression */
2431 if (is_immediate_prefix (**str
))
2435 if (my_get_expression (&inst
.reloc
.exp
, str
))
2438 if (inst
.reloc
.exp
.X_add_symbol
)
2440 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2441 inst
.reloc
.pc_rel
= 0;
2445 if (skip_past_comma (str
) == SUCCESS
)
2447 /* #x, y -- ie explicit rotation by Y */
2448 if (my_get_expression (&expr
, str
))
2451 if (expr
.X_op
!= O_constant
)
2453 inst
.error
= _("Constant expression expected");
2457 /* Rotate must be a multiple of 2 */
2458 if (((unsigned) expr
.X_add_number
) > 30
2459 || (expr
.X_add_number
& 1) != 0
2460 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2462 inst
.error
= _("Invalid constant");
2465 inst
.instruction
|= INST_IMMEDIATE
;
2466 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2467 inst
.instruction
|= expr
.X_add_number
<< 7;
2471 /* Implicit rotation, select a suitable one */
2472 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2476 /* Can't be done, perhaps the code reads something like
2477 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2478 if ((value
= negate_data_op (&inst
.instruction
,
2479 inst
.reloc
.exp
.X_add_number
))
2482 inst
.error
= _("Invalid constant");
2487 inst
.instruction
|= value
;
2490 inst
.instruction
|= INST_IMMEDIATE
;
2495 inst
.error
= _("Register or shift expression expected");
2504 while (**str
== ' ')
2507 if (fp_reg_required_here (str
, 0) != FAIL
)
2511 /* Immediate expression */
2512 if (*((*str
)++) == '#')
2517 while (**str
== ' ')
2520 /* First try and match exact strings, this is to guarantee that
2521 some formats will work even for cross assembly */
2523 for (i
= 0; fp_const
[i
]; i
++)
2525 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2529 *str
+= strlen (fp_const
[i
]);
2530 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2532 inst
.instruction
|= i
+ 8;
2539 /* Just because we didn't get a match doesn't mean that the
2540 constant isn't valid, just that it is in a format that we
2541 don't automatically recognize. Try parsing it with
2542 the standard expression routines. */
2543 if ((i
= my_get_float_expression (str
)) >= 0)
2545 inst
.instruction
|= i
+ 8;
2549 inst
.error
= _("Invalid floating point immediate expression");
2552 inst
.error
= _("Floating point register or immediate expression expected");
2558 do_arit (str
, flags
)
2560 unsigned long flags
;
2565 if (reg_required_here (&str
, 12) == FAIL
2566 || skip_past_comma (&str
) == FAIL
2567 || reg_required_here (&str
, 16) == FAIL
2568 || skip_past_comma (&str
) == FAIL
2569 || data_op2 (&str
) == FAIL
)
2572 inst
.error
= bad_args
;
2576 inst
.instruction
|= flags
;
2584 unsigned long flags
;
2586 /* This is a pseudo-op of the form "adr rd, label" to be converted
2587 into a relative address of the form "add rd, pc, #label-.-8" */
2592 if (reg_required_here (&str
, 12) == FAIL
2593 || skip_past_comma (&str
) == FAIL
2594 || my_get_expression (&inst
.reloc
.exp
, &str
))
2597 inst
.error
= bad_args
;
2600 /* Frag hacking will turn this into a sub instruction if the offset turns
2601 out to be negative. */
2602 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2603 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2604 inst
.reloc
.pc_rel
= 1;
2605 inst
.instruction
|= flags
;
2613 unsigned long flags
;
2618 if (reg_required_here (&str
, 16) == FAIL
)
2621 inst
.error
= bad_args
;
2625 if (skip_past_comma (&str
) == FAIL
2626 || data_op2 (&str
) == FAIL
)
2629 inst
.error
= bad_args
;
2633 inst
.instruction
|= flags
;
2634 if ((flags
& 0x0000f000) == 0)
2635 inst
.instruction
|= CONDS_BIT
;
2644 unsigned long flags
;
2649 if (reg_required_here (&str
, 12) == FAIL
)
2652 inst
.error
= bad_args
;
2656 if (skip_past_comma (&str
) == FAIL
2657 || data_op2 (&str
) == FAIL
)
2660 inst
.error
= bad_args
;
2664 inst
.instruction
|= flags
;
2670 ldst_extend (str
, hwse
)
2681 if (my_get_expression (& inst
.reloc
.exp
, str
))
2684 if (inst
.reloc
.exp
.X_op
== O_constant
)
2686 int value
= inst
.reloc
.exp
.X_add_number
;
2688 if ((hwse
&& (value
< -255 || value
> 255))
2689 || (value
< -4095 || value
> 4095))
2691 inst
.error
= _("address offset too large");
2701 /* Halfword and signextension instructions have the
2702 immediate value split across bits 11..8 and bits 3..0 */
2704 inst
.instruction
|= add
| HWOFFSET_IMM
| (value
>> 4) << 8 | value
& 0xF;
2706 inst
.instruction
|= add
| value
;
2712 inst
.instruction
|= HWOFFSET_IMM
;
2713 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2716 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2717 inst
.reloc
.pc_rel
= 0;
2722 add
= 0; /* and fall through */
2724 (*str
)++; /* and fall through */
2726 if (reg_required_here (str
, 0) == FAIL
)
2730 inst
.instruction
|= add
;
2733 inst
.instruction
|= add
| OFFSET_REG
;
2734 if (skip_past_comma (str
) == SUCCESS
)
2735 return decode_shift (str
, SHIFT_RESTRICT
);
2743 do_ldst (str
, flags
)
2745 unsigned long flags
;
2752 /* This is not ideal, but it is the simplest way of dealing with the
2753 ARM7T halfword instructions (since they use a different
2754 encoding, but the same mnemonic): */
2755 if (halfword
= ((flags
& 0x80000000) != 0))
2757 /* This is actually a load/store of a halfword, or a
2758 signed-extension load */
2759 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2762 = _("Processor does not support halfwords or signed bytes");
2766 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2767 | (flags
& ~COND_MASK
);
2775 if ((conflict_reg
= reg_required_here (& str
, 12)) == FAIL
)
2778 inst
.error
= bad_args
;
2782 if (skip_past_comma (& str
) == FAIL
)
2784 inst
.error
= _("Address expected");
2796 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2799 conflict_reg
= (((conflict_reg
== reg
)
2800 && (inst
.instruction
& LOAD_BIT
))
2809 if (skip_past_comma (&str
) == SUCCESS
)
2811 /* [Rn],... (post inc) */
2812 if (ldst_extend (&str
, halfword
) == FAIL
)
2815 as_warn (_("destination register same as write-back base\n"));
2821 inst
.instruction
|= HWOFFSET_IMM
;
2829 as_warn (_("destination register same as write-back base\n"));
2831 inst
.instruction
|= WRITE_BACK
;
2835 if (! (flags
& TRANS_BIT
))
2842 if (skip_past_comma (&str
) == FAIL
)
2844 inst
.error
= _("pre-indexed expression expected");
2849 if (ldst_extend (&str
, halfword
) == FAIL
)
2857 inst
.error
= _("missing ]");
2867 as_tsktsk (_("destination register same as write-back base\n"));
2869 inst
.instruction
|= WRITE_BACK
;
2873 else if (*str
== '=')
2875 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2881 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2884 if (inst
.reloc
.exp
.X_op
!= O_constant
2885 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2887 inst
.error
= _("Constant expression expected");
2891 if (inst
.reloc
.exp
.X_op
== O_constant
2892 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2894 /* This can be done with a mov instruction */
2895 inst
.instruction
&= LITERAL_MASK
;
2896 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2897 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2903 /* Insert into literal pool */
2904 if (add_to_lit_pool () == FAIL
)
2907 inst
.error
= _("literal pool insertion failed");
2911 /* Change the instruction exp to point to the pool */
2914 inst
.instruction
|= HWOFFSET_IMM
;
2915 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2918 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2919 inst
.reloc
.pc_rel
= 1;
2920 inst
.instruction
|= (REG_PC
<< 16);
2926 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2931 inst
.instruction
|= HWOFFSET_IMM
;
2932 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2935 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2936 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
2937 inst
.reloc
.pc_rel
= 1;
2938 inst
.instruction
|= (REG_PC
<< 16);
2942 if (pre_inc
&& (flags
& TRANS_BIT
))
2943 inst
.error
= _("Pre-increment instruction with translate");
2945 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
2958 /* We come back here if we get ranges concatenated by '+' or '|' */
2976 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
2985 inst
.error
= _("Bad range in register list");
2989 for (i
= cur_reg
+ 1; i
< reg
; i
++)
2991 if (range
& (1 << i
))
2993 (_("Warning: Duplicated register (r%d) in register list"),
3001 if (range
& (1 << reg
))
3002 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3004 else if (reg
<= cur_reg
)
3005 as_tsktsk (_("Warning: Register range not in ascending order"));
3009 } while (skip_past_comma (&str
) != FAIL
3010 || (in_range
= 1, *str
++ == '-'));
3017 inst
.error
= _("Missing `}'");
3025 if (my_get_expression (&expr
, &str
))
3028 if (expr
.X_op
== O_constant
)
3030 if (expr
.X_add_number
3031 != (expr
.X_add_number
& 0x0000ffff))
3033 inst
.error
= _("invalid register mask");
3037 if ((range
& expr
.X_add_number
) != 0)
3039 int regno
= range
& expr
.X_add_number
;
3042 regno
= (1 << regno
) - 1;
3044 (_("Warning: Duplicated register (r%d) in register list"),
3048 range
|= expr
.X_add_number
;
3052 if (inst
.reloc
.type
!= 0)
3054 inst
.error
= _("expression too complex");
3058 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
3059 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
3060 inst
.reloc
.pc_rel
= 0;
3067 if (*str
== '|' || *str
== '+')
3072 } while (another_range
);
3079 do_ldmstm (str
, flags
)
3081 unsigned long flags
;
3089 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
3092 if (base_reg
== REG_PC
)
3094 inst
.error
= _("r15 not allowed as base register");
3102 flags
|= WRITE_BACK
;
3106 if (skip_past_comma (&str
) == FAIL
3107 || (range
= reg_list (&str
)) == FAIL
)
3110 inst
.error
= bad_args
;
3117 flags
|= MULTI_SET_PSR
;
3120 inst
.instruction
|= flags
| range
;
3128 unsigned long flags
;
3133 /* Allow optional leading '#'. */
3134 if (is_immediate_prefix (*str
))
3137 if (my_get_expression (& inst
.reloc
.exp
, & str
))
3140 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3141 inst
.reloc
.pc_rel
= 0;
3142 inst
.instruction
|= flags
;
3150 do_swap (str
, flags
)
3152 unsigned long flags
;
3159 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3164 inst
.error
= _("r15 not allowed in swap");
3168 if (skip_past_comma (&str
) == FAIL
3169 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3172 inst
.error
= bad_args
;
3178 inst
.error
= _("r15 not allowed in swap");
3182 if (skip_past_comma (&str
) == FAIL
3185 inst
.error
= bad_args
;
3192 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3197 inst
.error
= bad_pc
;
3206 inst
.error
= _("missing ]");
3210 inst
.instruction
|= flags
;
3216 do_branch (str
, flags
)
3218 unsigned long flags
;
3220 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3227 /* ScottB: February 5, 1998 */
3228 /* Check to see of PLT32 reloc required for the instruction. */
3230 /* arm_parse_reloc() works on input_line_pointer.
3231 We actually want to parse the operands to the branch instruction
3232 passed in 'str'. Save the input pointer and restore it later. */
3233 save_in
= input_line_pointer
;
3234 input_line_pointer
= str
;
3235 if (inst
.reloc
.exp
.X_op
== O_symbol
3237 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32
)
3239 inst
.reloc
.type
= BFD_RELOC_ARM_PLT32
;
3240 inst
.reloc
.pc_rel
= 0;
3241 /* Modify str to point to after parsed operands, otherwise
3242 end_of_line() will complain about the (PLT) left in str. */
3243 str
= input_line_pointer
;
3247 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3248 inst
.reloc
.pc_rel
= 1;
3250 input_line_pointer
= save_in
;
3253 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3254 inst
.reloc
.pc_rel
= 1;
3255 #endif /* OBJ_ELF */
3264 unsigned long flags
;
3271 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3275 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3284 unsigned long flags
;
3286 /* Co-processor data operation.
3287 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3291 if (co_proc_number (&str
) == FAIL
)
3294 inst
.error
= bad_args
;
3298 if (skip_past_comma (&str
) == FAIL
3299 || cp_opc_expr (&str
, 20,4) == FAIL
)
3302 inst
.error
= bad_args
;
3306 if (skip_past_comma (&str
) == FAIL
3307 || cp_reg_required_here (&str
, 12) == FAIL
)
3310 inst
.error
= bad_args
;
3314 if (skip_past_comma (&str
) == FAIL
3315 || cp_reg_required_here (&str
, 16) == FAIL
)
3318 inst
.error
= bad_args
;
3322 if (skip_past_comma (&str
) == FAIL
3323 || cp_reg_required_here (&str
, 0) == FAIL
)
3326 inst
.error
= bad_args
;
3330 if (skip_past_comma (&str
) == SUCCESS
)
3332 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3335 inst
.error
= bad_args
;
3345 do_lstc (str
, flags
)
3347 unsigned long flags
;
3349 /* Co-processor register load/store.
3350 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3355 if (co_proc_number (&str
) == FAIL
)
3358 inst
.error
= bad_args
;
3362 if (skip_past_comma (&str
) == FAIL
3363 || cp_reg_required_here (&str
, 12) == FAIL
)
3366 inst
.error
= bad_args
;
3370 if (skip_past_comma (&str
) == FAIL
3371 || cp_address_required_here (&str
) == FAIL
)
3374 inst
.error
= bad_args
;
3378 inst
.instruction
|= flags
;
3384 do_co_reg (str
, flags
)
3386 unsigned long flags
;
3388 /* Co-processor register transfer.
3389 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3394 if (co_proc_number (&str
) == FAIL
)
3397 inst
.error
= bad_args
;
3401 if (skip_past_comma (&str
) == FAIL
3402 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3405 inst
.error
= bad_args
;
3409 if (skip_past_comma (&str
) == FAIL
3410 || reg_required_here (&str
, 12) == FAIL
)
3413 inst
.error
= bad_args
;
3417 if (skip_past_comma (&str
) == FAIL
3418 || cp_reg_required_here (&str
, 16) == FAIL
)
3421 inst
.error
= bad_args
;
3425 if (skip_past_comma (&str
) == FAIL
3426 || cp_reg_required_here (&str
, 0) == FAIL
)
3429 inst
.error
= bad_args
;
3433 if (skip_past_comma (&str
) == SUCCESS
)
3435 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3438 inst
.error
= bad_args
;
3448 do_fp_ctrl (str
, flags
)
3450 unsigned long flags
;
3452 /* FP control registers.
3453 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3458 if (reg_required_here (&str
, 12) == FAIL
)
3461 inst
.error
= bad_args
;
3470 do_fp_ldst (str
, flags
)
3472 unsigned long flags
;
3477 switch (inst
.suffix
)
3482 inst
.instruction
|= CP_T_X
;
3485 inst
.instruction
|= CP_T_Y
;
3488 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3494 if (fp_reg_required_here (&str
, 12) == FAIL
)
3497 inst
.error
= bad_args
;
3501 if (skip_past_comma (&str
) == FAIL
3502 || cp_address_required_here (&str
) == FAIL
)
3505 inst
.error
= bad_args
;
3513 do_fp_ldmstm (str
, flags
)
3515 unsigned long flags
;
3522 if (fp_reg_required_here (&str
, 12) == FAIL
)
3525 inst
.error
= bad_args
;
3529 /* Get Number of registers to transfer */
3530 if (skip_past_comma (&str
) == FAIL
3531 || my_get_expression (&inst
.reloc
.exp
, &str
))
3534 inst
.error
= _("constant expression expected");
3538 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3540 inst
.error
= _("Constant value required for number of registers");
3544 num_regs
= inst
.reloc
.exp
.X_add_number
;
3546 if (num_regs
< 1 || num_regs
> 4)
3548 inst
.error
= _("number of registers must be in the range [1:4]");
3555 inst
.instruction
|= CP_T_X
;
3558 inst
.instruction
|= CP_T_Y
;
3561 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3575 /* The instruction specified "ea" or "fd", so we can only accept
3576 [Rn]{!}. The instruction does not really support stacking or
3577 unstacking, so we have to emulate these by setting appropriate
3578 bits and offsets. */
3579 if (skip_past_comma (&str
) == FAIL
3583 inst
.error
= bad_args
;
3591 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3599 inst
.error
= bad_args
;
3610 inst
.error
= _("R15 not allowed as base register with write-back");
3617 if (flags
& CP_T_Pre
)
3620 offset
= 3 * num_regs
;
3626 /* Post-increment */
3630 offset
= 3 * num_regs
;
3634 /* No write-back, so convert this into a standard pre-increment
3635 instruction -- aesthetically more pleasing. */
3636 flags
= CP_T_Pre
| CP_T_UD
;
3641 inst
.instruction
|= flags
| offset
;
3643 else if (skip_past_comma (&str
) == FAIL
3644 || cp_address_required_here (&str
) == FAIL
)
3647 inst
.error
= bad_args
;
3655 do_fp_dyadic (str
, flags
)
3657 unsigned long flags
;
3662 switch (inst
.suffix
)
3667 inst
.instruction
|= 0x00000080;
3670 inst
.instruction
|= 0x00080000;
3676 if (fp_reg_required_here (&str
, 12) == FAIL
)
3679 inst
.error
= bad_args
;
3683 if (skip_past_comma (&str
) == FAIL
3684 || fp_reg_required_here (&str
, 16) == FAIL
)
3687 inst
.error
= bad_args
;
3691 if (skip_past_comma (&str
) == FAIL
3692 || fp_op2 (&str
) == FAIL
)
3695 inst
.error
= bad_args
;
3699 inst
.instruction
|= flags
;
3705 do_fp_monadic (str
, flags
)
3707 unsigned long flags
;
3712 switch (inst
.suffix
)
3717 inst
.instruction
|= 0x00000080;
3720 inst
.instruction
|= 0x00080000;
3726 if (fp_reg_required_here (&str
, 12) == FAIL
)
3729 inst
.error
= bad_args
;
3733 if (skip_past_comma (&str
) == FAIL
3734 || fp_op2 (&str
) == FAIL
)
3737 inst
.error
= bad_args
;
3741 inst
.instruction
|= flags
;
3747 do_fp_cmp (str
, flags
)
3749 unsigned long flags
;
3754 if (fp_reg_required_here (&str
, 16) == FAIL
)
3757 inst
.error
= bad_args
;
3761 if (skip_past_comma (&str
) == FAIL
3762 || fp_op2 (&str
) == FAIL
)
3765 inst
.error
= bad_args
;
3769 inst
.instruction
|= flags
;
3775 do_fp_from_reg (str
, flags
)
3777 unsigned long flags
;
3782 switch (inst
.suffix
)
3787 inst
.instruction
|= 0x00000080;
3790 inst
.instruction
|= 0x00080000;
3796 if (fp_reg_required_here (&str
, 16) == FAIL
)
3799 inst
.error
= bad_args
;
3803 if (skip_past_comma (&str
) == FAIL
3804 || reg_required_here (&str
, 12) == FAIL
)
3807 inst
.error
= bad_args
;
3811 inst
.instruction
|= flags
;
3817 do_fp_to_reg (str
, flags
)
3819 unsigned long flags
;
3824 if (reg_required_here (&str
, 12) == FAIL
)
3827 if (skip_past_comma (&str
) == FAIL
3828 || fp_reg_required_here (&str
, 0) == FAIL
)
3831 inst
.error
= bad_args
;
3835 inst
.instruction
|= flags
;
3840 /* Thumb specific routines */
3842 /* Parse and validate that a register is of the right form, this saves
3843 repeated checking of this information in many similar cases.
3844 Unlike the 32-bit case we do not insert the register into the opcode
3845 here, since the position is often unknown until the full instruction
3848 thumb_reg (strp
, hi_lo
)
3854 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3862 inst
.error
= _("lo register required");
3870 inst
.error
= _("hi register required");
3882 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3885 thumb_add_sub (str
, subtract
)
3889 int Rd
, Rs
, Rn
= FAIL
;
3894 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3895 || skip_past_comma (&str
) == FAIL
)
3898 inst
.error
= bad_args
;
3902 if (is_immediate_prefix (*str
))
3906 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3911 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3914 if (skip_past_comma (&str
) == FAIL
)
3916 /* Two operand format, shuffle the registers and pretend there
3921 else if (is_immediate_prefix (*str
))
3924 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3927 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3931 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3932 for the latter case, EXPR contains the immediate that was found. */
3935 /* All register format. */
3936 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
3940 inst
.error
= _("dest and source1 must be the same register");
3944 /* Can't do this for SUB */
3947 inst
.error
= _("subtract valid only on lo regs");
3951 inst
.instruction
= (T_OPCODE_ADD_HI
3952 | (Rd
> 7 ? THUMB_H1
: 0)
3953 | (Rn
> 7 ? THUMB_H2
: 0));
3954 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
3958 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
3959 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
3964 /* Immediate expression, now things start to get nasty. */
3966 /* First deal with HI regs, only very restricted cases allowed:
3967 Adjusting SP, and using PC or SP to get an address. */
3968 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
3969 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
3971 inst
.error
= _("invalid Hi register with immediate");
3975 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3977 /* Value isn't known yet, all we can do is store all the fragments
3978 we know about in the instruction and let the reloc hacking
3980 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
3981 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
3985 int offset
= inst
.reloc
.exp
.X_add_number
;
3995 /* Quick check, in case offset is MIN_INT */
3998 inst
.error
= _("immediate value out of range");
4007 if (offset
& ~0x1fc)
4009 inst
.error
= _("invalid immediate value for stack adjust");
4012 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
4013 inst
.instruction
|= offset
>> 2;
4015 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
4018 || (offset
& ~0x3fc))
4020 inst
.error
= _("invalid immediate for address calculation");
4023 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
4025 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
4031 inst
.error
= _("immediate value out of range");
4034 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
4035 inst
.instruction
|= (Rd
<< 8) | offset
;
4041 inst
.error
= _("immediate value out of range");
4044 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
4045 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
4053 thumb_shift (str
, shift
)
4057 int Rd
, Rs
, Rn
= FAIL
;
4062 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4063 || skip_past_comma (&str
) == FAIL
)
4066 inst
.error
= bad_args
;
4070 if (is_immediate_prefix (*str
))
4072 /* Two operand immediate format, set Rs to Rd. */
4075 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4080 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4083 if (skip_past_comma (&str
) == FAIL
)
4085 /* Two operand format, shuffle the registers and pretend there
4090 else if (is_immediate_prefix (*str
))
4093 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4096 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4100 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4101 for the latter case, EXPR contains the immediate that was found. */
4107 inst
.error
= _("source1 and dest must be same register");
4113 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
4114 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
4115 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
4118 inst
.instruction
|= Rd
| (Rn
<< 3);
4124 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
4125 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
4126 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
4129 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4131 /* Value isn't known yet, create a dummy reloc and let reloc
4132 hacking fix it up */
4134 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
4138 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
4140 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
4142 inst
.error
= _("Invalid immediate for shift");
4146 /* Shifts of zero are handled by converting to LSL */
4147 if (shift_value
== 0)
4148 inst
.instruction
= T_OPCODE_LSL_I
;
4150 /* Shifts of 32 are encoded as a shift of zero */
4151 if (shift_value
== 32)
4154 inst
.instruction
|= shift_value
<< 6;
4157 inst
.instruction
|= Rd
| (Rs
<< 3);
4163 thumb_mov_compare (str
, move
)
4172 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
4173 || skip_past_comma (&str
) == FAIL
)
4176 inst
.error
= bad_args
;
4180 if (is_immediate_prefix (*str
))
4183 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4186 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4191 if (Rs
< 8 && Rd
< 8)
4193 if (move
== THUMB_MOVE
)
4194 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4195 since a MOV instruction produces unpredictable results */
4196 inst
.instruction
= T_OPCODE_ADD_I3
;
4198 inst
.instruction
= T_OPCODE_CMP_LR
;
4199 inst
.instruction
|= Rd
| (Rs
<< 3);
4203 if (move
== THUMB_MOVE
)
4204 inst
.instruction
= T_OPCODE_MOV_HR
;
4206 inst
.instruction
= T_OPCODE_CMP_HR
;
4209 inst
.instruction
|= THUMB_H1
;
4212 inst
.instruction
|= THUMB_H2
;
4214 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4221 inst
.error
= _("only lo regs allowed with immediate");
4225 if (move
== THUMB_MOVE
)
4226 inst
.instruction
= T_OPCODE_MOV_I8
;
4228 inst
.instruction
= T_OPCODE_CMP_I8
;
4230 inst
.instruction
|= Rd
<< 8;
4232 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4233 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4236 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4240 inst
.error
= _("invalid immediate");
4244 inst
.instruction
|= value
;
4252 thumb_load_store (str
, load_store
, size
)
4257 int Rd
, Rb
, Ro
= FAIL
;
4262 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4263 || skip_past_comma (&str
) == FAIL
)
4266 inst
.error
= bad_args
;
4273 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4276 if (skip_past_comma (&str
) != FAIL
)
4278 if (is_immediate_prefix (*str
))
4281 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4284 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4289 inst
.reloc
.exp
.X_op
= O_constant
;
4290 inst
.reloc
.exp
.X_add_number
= 0;
4295 inst
.error
= _("expected ']'");
4300 else if (*str
== '=')
4302 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4308 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4313 if ( inst
.reloc
.exp
.X_op
!= O_constant
4314 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4316 inst
.error
= "Constant expression expected";
4320 if (inst
.reloc
.exp
.X_op
== O_constant
4321 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4323 /* This can be done with a mov instruction */
4325 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4326 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4330 /* Insert into literal pool */
4331 if (add_to_lit_pool () == FAIL
)
4334 inst
.error
= "literal pool insertion failed";
4338 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4339 inst
.reloc
.pc_rel
= 1;
4340 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4341 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4347 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4350 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4351 inst
.reloc
.pc_rel
= 1;
4352 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4353 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4358 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4360 if (size
!= THUMB_WORD
)
4362 inst
.error
= _("byte or halfword not valid for base register");
4365 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4367 inst
.error
= _("R15 based store not allowed");
4370 else if (Ro
!= FAIL
)
4372 inst
.error
= _("Invalid base register for register offset");
4377 inst
.instruction
= T_OPCODE_LDR_PC
;
4378 else if (load_store
== THUMB_LOAD
)
4379 inst
.instruction
= T_OPCODE_LDR_SP
;
4381 inst
.instruction
= T_OPCODE_STR_SP
;
4383 inst
.instruction
|= Rd
<< 8;
4384 if (inst
.reloc
.exp
.X_op
== O_constant
)
4386 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4388 if (offset
& ~0x3fc)
4390 inst
.error
= _("invalid offset");
4394 inst
.instruction
|= offset
>> 2;
4397 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4401 inst
.error
= _("invalid base register in load/store");
4404 else if (Ro
== FAIL
)
4406 /* Immediate offset */
4407 if (size
== THUMB_WORD
)
4408 inst
.instruction
= (load_store
== THUMB_LOAD
4409 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4410 else if (size
== THUMB_HALFWORD
)
4411 inst
.instruction
= (load_store
== THUMB_LOAD
4412 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4414 inst
.instruction
= (load_store
== THUMB_LOAD
4415 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4417 inst
.instruction
|= Rd
| (Rb
<< 3);
4419 if (inst
.reloc
.exp
.X_op
== O_constant
)
4421 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4423 if (offset
& ~(0x1f << size
))
4425 inst
.error
= _("Invalid offset");
4428 inst
.instruction
|= (offset
>> size
) << 6;
4431 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4435 /* Register offset */
4436 if (size
== THUMB_WORD
)
4437 inst
.instruction
= (load_store
== THUMB_LOAD
4438 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4439 else if (size
== THUMB_HALFWORD
)
4440 inst
.instruction
= (load_store
== THUMB_LOAD
4441 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4443 inst
.instruction
= (load_store
== THUMB_LOAD
4444 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4446 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4461 /* Handle the Format 4 instructions that do not have equivalents in other
4462 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4473 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4476 if (skip_past_comma (&str
) == FAIL
4477 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4480 inst
.error
= bad_args
;
4484 if (skip_past_comma (&str
) != FAIL
)
4486 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4487 (It isn't allowed for CMP either, but that isn't handled by this
4489 if (inst
.instruction
== T_OPCODE_TST
4490 || inst
.instruction
== T_OPCODE_CMN
4491 || inst
.instruction
== T_OPCODE_NEG
4492 || inst
.instruction
== T_OPCODE_MVN
)
4494 inst
.error
= bad_args
;
4498 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4503 inst
.error
= _("dest and source1 one must be the same register");
4509 if (inst
.instruction
== T_OPCODE_MUL
4511 as_tsktsk (_("Rs and Rd must be different in MUL"));
4513 inst
.instruction
|= Rd
| (Rs
<< 3);
4521 thumb_add_sub (str
, 0);
4528 thumb_shift (str
, THUMB_ASR
);
4535 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4537 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4538 inst
.reloc
.pc_rel
= 1;
4546 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4548 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4549 inst
.reloc
.pc_rel
= 1;
4553 /* Find the real, Thumb encoded start of a Thumb function. */
4556 find_real_start (symbolP
)
4560 const char * name
= S_GET_NAME (symbolP
);
4561 symbolS
* new_target
;
4563 /* This definitonmust agree with the one in gcc/config/arm/thumb.c */
4564 #define STUB_NAME ".real_start_of"
4569 /* Names that start with '.' are local labels, not function entry points.
4570 The compiler may generate BL instructions to these labels because it
4571 needs to perform a branch to a far away location. */
4575 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4576 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4578 new_target
= symbol_find (real_start
);
4580 if (new_target
== NULL
)
4582 as_warn ("Failed to find real start of function: %s\n", name
);
4583 new_target
= symbolP
;
4596 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4598 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4599 inst
.reloc
.pc_rel
= 1;
4602 /* If the destination of the branch is a defined symbol which does not have
4603 the THUMB_FUNC attribute, then we must be calling a function which has
4604 the (interfacearm) attribute. We look for the Thumb entry point to that
4605 function and change the branch to refer to that function instead. */
4606 if ( inst
.reloc
.exp
.X_op
== O_symbol
4607 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4608 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4609 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4610 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4622 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4625 /* This sets THUMB_H2 from the top bit of reg. */
4626 inst
.instruction
|= reg
<< 3;
4628 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4629 should cause the alignment to be checked once it is known. This is
4630 because BX PC only works if the instruction is word aligned. */
4639 thumb_mov_compare (str
, THUMB_COMPARE
);
4652 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4656 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4660 if (skip_past_comma (&str
) == FAIL
4661 || (range
= reg_list (&str
)) == FAIL
)
4664 inst
.error
= bad_args
;
4668 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4670 /* This really doesn't seem worth it. */
4671 inst
.reloc
.type
= BFD_RELOC_NONE
;
4672 inst
.error
= _("Expression too complex");
4678 inst
.error
= _("only lo-regs valid in load/store multiple");
4682 inst
.instruction
|= (Rb
<< 8) | range
;
4690 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4697 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4704 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4716 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4717 || skip_past_comma (&str
) == FAIL
4719 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4720 || skip_past_comma (&str
) == FAIL
4721 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4725 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4729 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4737 thumb_shift (str
, THUMB_LSL
);
4744 thumb_shift (str
, THUMB_LSR
);
4751 thumb_mov_compare (str
, THUMB_MOVE
);
4763 if ((range
= reg_list (&str
)) == FAIL
)
4766 inst
.error
= bad_args
;
4770 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4772 /* This really doesn't seem worth it. */
4773 inst
.reloc
.type
= BFD_RELOC_NONE
;
4774 inst
.error
= _("Expression too complex");
4780 if ((inst
.instruction
== T_OPCODE_PUSH
4781 && (range
& ~0xff) == 1 << REG_LR
)
4782 || (inst
.instruction
== T_OPCODE_POP
4783 && (range
& ~0xff) == 1 << REG_PC
))
4785 inst
.instruction
|= THUMB_PP_PC_LR
;
4790 inst
.error
= _("invalid register list to push/pop instruction");
4795 inst
.instruction
|= range
;
4803 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4810 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4817 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4824 thumb_add_sub (str
, 1);
4834 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4837 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4846 /* This is a pseudo-op of the form "adr rd, label" to be converted
4847 into a relative address of the form "add rd, pc, #label-.-4" */
4851 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4852 || skip_past_comma (&str
) == FAIL
4853 || my_get_expression (&inst
.reloc
.exp
, &str
))
4856 inst
.error
= bad_args
;
4860 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4861 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4862 inst
.reloc
.pc_rel
= 1;
4863 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4871 int len
= strlen (reg_table
[entry
].name
) + 2;
4872 char * buf
= (char *) xmalloc (len
);
4873 char * buf2
= (char *) xmalloc (len
);
4876 #ifdef REGISTER_PREFIX
4877 buf
[i
++] = REGISTER_PREFIX
;
4880 strcpy (buf
+ i
, reg_table
[entry
].name
);
4882 for (i
= 0; buf
[i
]; i
++)
4883 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4887 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4888 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4892 insert_reg_alias (str
, regnum
)
4896 struct reg_entry
*new =
4897 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4898 char *name
= xmalloc (strlen (str
) + 1);
4902 new->number
= regnum
;
4904 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4908 set_constant_flonums ()
4912 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4913 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4922 if ( (arm_ops_hsh
= hash_new ()) == NULL
4923 || (arm_tops_hsh
= hash_new ()) == NULL
4924 || (arm_cond_hsh
= hash_new ()) == NULL
4925 || (arm_shift_hsh
= hash_new ()) == NULL
4926 || (arm_reg_hsh
= hash_new ()) == NULL
4927 || (arm_psr_hsh
= hash_new ()) == NULL
)
4928 as_fatal (_("Virtual memory exhausted"));
4930 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4931 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4932 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4933 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4934 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4935 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4936 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4937 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4938 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4939 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4941 for (i
= 0; reg_table
[i
].name
; i
++)
4944 set_constant_flonums ();
4946 #if defined OBJ_COFF || defined OBJ_ELF
4948 unsigned int flags
= 0;
4950 /* Set the flags in the private structure */
4951 if (uses_apcs_26
) flags
|= F_APCS26
;
4952 if (support_interwork
) flags
|= F_INTERWORK
;
4953 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
4954 if (pic_code
) flags
|= F_PIC
;
4956 bfd_set_private_flags (stdoutput
, flags
);
4963 /* Record the CPU type as well */
4964 switch (cpu_variant
& ARM_CPU_MASK
)
4967 mach
= bfd_mach_arm_2
;
4970 case ARM_3
: /* also ARM_250 */
4971 mach
= bfd_mach_arm_2a
;
4975 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
4976 mach
= bfd_mach_arm_4
;
4979 case ARM_7
: /* also ARM_6 */
4980 mach
= bfd_mach_arm_3
;
4984 /* Catch special cases */
4985 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
4987 if (cpu_variant
& ARM_THUMB
)
4988 mach
= bfd_mach_arm_4T
;
4989 else if ((cpu_variant
& ARM_ARCHv4
) == ARM_ARCHv4
)
4990 mach
= bfd_mach_arm_4
;
4991 else if (cpu_variant
& ARM_LONGMUL
)
4992 mach
= bfd_mach_arm_3M
;
4995 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
4999 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5000 for use in the a.out file, and stores them in the array pointed to by buf.
5001 This knows about the endian-ness of the target machine and does
5002 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5003 2 (short) and 4 (long) Floating numbers are put out as a series of
5004 LITTLENUMS (shorts, here at least)
5007 md_number_to_chars (buf
, val
, n
)
5012 if (target_big_endian
)
5013 number_to_chars_bigendian (buf
, val
, n
);
5015 number_to_chars_littleendian (buf
, val
, n
);
5019 md_chars_to_number (buf
, n
)
5024 unsigned char * where
= (unsigned char *) buf
;
5026 if (target_big_endian
)
5031 result
|= (*where
++ & 255);
5039 result
|= (where
[n
] & 255);
5046 /* Turn a string in input_line_pointer into a floating point constant
5047 of type TYPE, and store the appropriate bytes in *litP. The number
5048 of LITTLENUMS emitted is stored in *sizeP . An error message is
5049 returned, or NULL on OK.
5051 Note that fp constants aren't represent in the normal way on the ARM.
5052 In big endian mode, things are as expected. However, in little endian
5053 mode fp constants are big-endian word-wise, and little-endian byte-wise
5054 within the words. For example, (double) 1.1 in big endian mode is
5055 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5056 the byte sequence 99 99 f1 3f 9a 99 99 99.
5058 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5061 md_atof (type
, litP
, sizeP
)
5067 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
5099 return _("Bad call to MD_ATOF()");
5102 t
= atof_ieee (input_line_pointer
, type
, words
);
5104 input_line_pointer
= t
;
5107 if (target_big_endian
)
5109 for (i
= 0; i
< prec
; i
++)
5111 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
5117 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5118 8 byte float the order is 1 0 3 2. */
5119 for (i
= 0; i
< prec
; i
+= 2)
5121 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
5122 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
5130 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5132 md_pcrel_from (fixP
)
5136 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
5137 && fixP
->fx_subsy
== NULL
)
5140 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
5142 /* PC relative addressing on the Thumb is slightly odd
5143 as the bottom two bits of the PC are forced to zero
5144 for the calculation */
5145 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
5148 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
5151 /* Round up a section size to the appropriate boundary. */
5153 md_section_align (segment
, size
)
5158 /* Don't align the dwarf2 debug sections */
5159 if (!strncmp (segment
->name
, ".debug", 5))
5162 /* Round all sects to multiple of 4 */
5163 return (size
+ 3) & ~3;
5166 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5167 we have no need to default values of symbols. */
5171 md_undefined_symbol (name
)
5175 if (name
[0] == '_' && name
[1] == 'G'
5176 && streq (name
, GLOBAL_OFFSET_TABLE_NAME
))
5180 if (symbol_find (name
))
5181 as_bad ("GOT already in the symbol table");
5183 GOT_symbol
= symbol_new (name
, undefined_section
,
5184 (valueT
)0, & zero_address_frag
);
5194 /* arm_reg_parse () := if it looks like a register, return its token and
5195 advance the pointer. */
5199 register char ** ccp
;
5201 char * start
= * ccp
;
5204 struct reg_entry
* reg
;
5206 #ifdef REGISTER_PREFIX
5207 if (*start
!= REGISTER_PREFIX
)
5212 #ifdef OPTIONAL_REGISTER_PREFIX
5213 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5217 if (!isalpha (*p
) || !is_name_beginner (*p
))
5221 while (isalpha (c
) || isdigit (c
) || c
== '_')
5225 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5239 register char ** ccp
;
5241 char * start
= * ccp
;
5244 CONST
struct asm_psr
* psr
;
5248 while (isalpha (c
) || c
== '_')
5252 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5265 md_apply_fix3 (fixP
, val
, seg
)
5270 offsetT value
= * val
;
5272 unsigned int newimm
;
5275 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5276 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5278 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5280 /* Note whether this will delete the relocation. */
5281 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5282 if ((fixP
->fx_addsy
== 0 || fixP
->fx_addsy
->sy_value
.X_op
== O_constant
)
5285 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5289 /* If this symbol is in a different section then we need to leave it for
5290 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5291 so we have to undo it's effects here. */
5294 if (fixP
->fx_addsy
!= NULL
5295 && S_IS_DEFINED (fixP
->fx_addsy
)
5296 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5299 && fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
5302 value
+= md_pcrel_from (fixP
);
5306 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc */
5308 switch (fixP
->fx_r_type
)
5310 case BFD_RELOC_ARM_IMMEDIATE
:
5311 newimm
= validate_immediate (value
);
5312 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5314 /* If the instruction will fail, see if we can fix things up by
5315 changing the opcode. */
5316 if (newimm
== (unsigned int) FAIL
5317 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5319 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5320 _("invalid constant (%x) after fixup\n"), value
);
5324 newimm
|= (temp
& 0xfffff000);
5325 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5328 case BFD_RELOC_ARM_OFFSET_IMM
:
5330 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5332 as_bad (_("bad immediate value for offset (%d)"), val
);
5338 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5339 newval
&= 0xff7ff000;
5340 newval
|= value
| (sign
? INDEX_UP
: 0);
5341 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5344 case BFD_RELOC_ARM_OFFSET_IMM8
:
5345 case BFD_RELOC_ARM_HWLITERAL
:
5347 if ((value
= validate_offset_imm (value
, 1)) == FAIL
)
5349 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5350 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5351 _("invalid literal constant: pool needs to be closer\n"));
5353 as_bad (_("bad immediate value for offset (%d)"), value
);
5360 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5361 newval
&= 0xff7ff0f0;
5362 newval
|= ((value
>> 4) << 8) | value
& 0xf | (sign
? INDEX_UP
: 0);
5363 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5366 case BFD_RELOC_ARM_LITERAL
:
5371 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5373 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5374 _("invalid literal constant: pool needs to be closer\n"));
5378 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5379 newval
&= 0xff7ff000;
5380 newval
|= value
| (sign
? INDEX_UP
: 0);
5381 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5384 case BFD_RELOC_ARM_SHIFT_IMM
:
5385 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5386 if (((unsigned long) value
) > 32
5388 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5390 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5391 _("shift expression is too large"));
5396 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5397 else if (value
== 32)
5399 newval
&= 0xfffff07f;
5400 newval
|= (value
& 0x1f) << 7;
5401 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5404 case BFD_RELOC_ARM_SWI
:
5405 if (arm_data
->thumb_mode
)
5407 if (((unsigned long) value
) > 0xff)
5408 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5409 _("Invalid swi expression"));
5410 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5412 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5416 if (((unsigned long) value
) > 0x00ffffff)
5417 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5418 _("Invalid swi expression"));
5419 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5421 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5425 case BFD_RELOC_ARM_MULTI
:
5426 if (((unsigned long) value
) > 0xffff)
5427 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5428 _("Invalid expression in load/store multiple"));
5429 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5430 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5433 case BFD_RELOC_ARM_PCREL_BRANCH
:
5434 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5438 value
= fixP
->fx_offset
;
5440 value
= (value
>> 2) & 0x00ffffff;
5441 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5442 newval
= value
| (newval
& 0xff000000);
5443 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5446 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5447 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5449 addressT diff
= (newval
& 0xff) << 1;
5454 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5455 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5456 _("Branch out of range"));
5457 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5459 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5462 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5463 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5465 addressT diff
= (newval
& 0x7ff) << 1;
5470 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5471 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5472 _("Branch out of range"));
5473 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5475 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5478 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5483 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5484 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5485 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5486 if (diff
& 0x400000)
5489 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5490 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5491 _("Branch with link out of range"));
5493 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5494 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5495 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5496 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5501 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5502 md_number_to_chars (buf
, value
, 1);
5504 else if (!target_oabi
)
5506 value
= fixP
->fx_offset
;
5507 md_number_to_chars (buf
, value
, 1);
5513 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5514 md_number_to_chars (buf
, value
, 2);
5516 else if (!target_oabi
)
5518 value
= fixP
->fx_offset
;
5519 md_number_to_chars (buf
, value
, 2);
5525 case BFD_RELOC_ARM_GOT32
:
5526 case BFD_RELOC_ARM_GOTOFF
:
5527 md_number_to_chars (buf
, 0, 4);
5533 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5534 md_number_to_chars (buf
, value
, 4);
5536 else if (!target_oabi
)
5538 value
= fixP
->fx_offset
;
5539 md_number_to_chars (buf
, value
, 4);
5545 case BFD_RELOC_ARM_PLT32
:
5546 /* It appears the instruction is fully prepared at this point. */
5550 case BFD_RELOC_ARM_GOTPC
:
5551 md_number_to_chars (buf
, value
, 4);
5554 case BFD_RELOC_ARM_CP_OFF_IMM
:
5556 if (value
< -1023 || value
> 1023 || (value
& 3))
5557 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5558 _("Illegal value for co-processor offset"));
5561 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5562 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5563 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5566 case BFD_RELOC_ARM_THUMB_OFFSET
:
5567 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5568 /* Exactly what ranges, and where the offset is inserted depends on
5569 the type of instruction, we can establish this from the top 4 bits */
5570 switch (newval
>> 12)
5572 case 4: /* PC load */
5573 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5574 forced to zero for these loads, so we will need to round
5575 up the offset if the instruction address is not word
5576 aligned (since the final address produced must be, and
5577 we can only describe word-aligned immediate offsets). */
5579 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5580 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5581 _("Invalid offset, target not word aligned (0x%08X)"),
5582 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5584 if ((value
+ 2) & ~0x3fe)
5585 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5586 _("Invalid offset"));
5588 /* Round up, since pc will be rounded down. */
5589 newval
|= (value
+ 2) >> 2;
5592 case 9: /* SP load/store */
5594 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5595 _("Invalid offset"));
5596 newval
|= value
>> 2;
5599 case 6: /* Word load/store */
5601 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5602 _("Invalid offset"));
5603 newval
|= value
<< 4; /* 6 - 2 */
5606 case 7: /* Byte load/store */
5608 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5609 _("Invalid offset"));
5610 newval
|= value
<< 6;
5613 case 8: /* Halfword load/store */
5615 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5616 _("Invalid offset"));
5617 newval
|= value
<< 5; /* 6 - 1 */
5621 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5622 "Unable to process relocation for thumb opcode: %x", newval
);
5625 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5628 case BFD_RELOC_ARM_THUMB_ADD
:
5629 /* This is a complicated relocation, since we use it for all of
5630 the following immediate relocations:
5633 9bit ADD/SUB SP word-aligned
5634 10bit ADD PC/SP word-aligned
5636 The type of instruction being processed is encoded in the
5642 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5644 int rd
= (newval
>> 4) & 0xf;
5645 int rs
= newval
& 0xf;
5646 int subtract
= newval
& 0x8000;
5651 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5652 _("Invalid immediate for stack address calculation"));
5653 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5654 newval
|= value
>> 2;
5656 else if (rs
== REG_PC
|| rs
== REG_SP
)
5660 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5661 _("Invalid immediate for address calculation (value = 0x%08X)"), value
);
5662 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5664 newval
|= value
>> 2;
5669 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5670 _("Invalid 8bit immediate"));
5671 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5672 newval
|= (rd
<< 8) | value
;
5677 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5678 _("Invalid 3bit immediate"));
5679 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5680 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5683 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5686 case BFD_RELOC_ARM_THUMB_IMM
:
5687 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5688 switch (newval
>> 11)
5690 case 0x04: /* 8bit immediate MOV */
5691 case 0x05: /* 8bit immediate CMP */
5692 if (value
< 0 || value
> 255)
5693 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5694 _("Invalid immediate: %d is too large"), value
);
5701 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5704 case BFD_RELOC_ARM_THUMB_SHIFT
:
5705 /* 5bit shift value (0..31) */
5706 if (value
< 0 || value
> 31)
5707 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5708 _("Illegal Thumb shift value: %d"), value
);
5709 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5710 newval
|= value
<< 6;
5711 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5714 case BFD_RELOC_VTABLE_INHERIT
:
5715 case BFD_RELOC_VTABLE_ENTRY
:
5719 case BFD_RELOC_NONE
:
5721 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5722 _("Bad relocation fixup type (%d)\n"), fixP
->fx_r_type
);
5728 /* Translate internal representation of relocation info to BFD target
5731 tc_gen_reloc (section
, fixp
)
5736 bfd_reloc_code_real_type code
;
5738 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5740 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5741 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5742 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5744 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5746 if (fixp
->fx_pcrel
== 0)
5747 reloc
->addend
= fixp
->fx_offset
;
5749 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5751 reloc
->addend
= fixp
->fx_offset
;
5754 switch (fixp
->fx_r_type
)
5759 code
= BFD_RELOC_8_PCREL
;
5766 code
= BFD_RELOC_16_PCREL
;
5773 code
= BFD_RELOC_32_PCREL
;
5777 case BFD_RELOC_ARM_PCREL_BRANCH
:
5779 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5780 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5781 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5782 case BFD_RELOC_VTABLE_ENTRY
:
5783 case BFD_RELOC_VTABLE_INHERIT
:
5784 code
= fixp
->fx_r_type
;
5787 case BFD_RELOC_ARM_LITERAL
:
5788 case BFD_RELOC_ARM_HWLITERAL
:
5789 /* If this is called then the a literal has been referenced across
5790 a section boundry - possibly due to an implicit dump */
5791 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5792 _("Literal referenced across section boundry (Implicit dump?)"));
5795 case BFD_RELOC_ARM_GOTPC
:
5796 assert (fixp
->fx_pcrel
!= 0);
5797 code
= fixp
->fx_r_type
;
5798 code
= BFD_RELOC_32_PCREL
;
5802 case BFD_RELOC_ARM_GOT32
:
5803 case BFD_RELOC_ARM_GOTOFF
:
5804 case BFD_RELOC_ARM_PLT32
:
5805 code
= fixp
->fx_r_type
;
5809 case BFD_RELOC_ARM_IMMEDIATE
:
5810 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5811 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5815 case BFD_RELOC_ARM_OFFSET_IMM
:
5816 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5817 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5824 switch (fixp
->fx_r_type
)
5826 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5827 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5828 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5829 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5830 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5831 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5832 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5833 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5834 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5835 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5836 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5837 default: type
= "<unknown>"; break;
5839 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5840 _("Can not represent %s relocation in this object file format (%d)"),
5841 type
, fixp
->fx_pcrel
);
5847 if (code
== BFD_RELOC_32_PCREL
5849 && fixp
->fx_addsy
== GOT_symbol
)
5851 code
= BFD_RELOC_ARM_GOTPC
;
5852 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5856 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5858 if (reloc
->howto
== NULL
)
5860 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5861 _("Can not represent %s relocation in this object file format"),
5862 bfd_get_reloc_code_name (code
));
5870 md_estimate_size_before_relax (fragP
, segtype
)
5874 as_fatal (_("md_estimate_size_before_relax\n"));
5886 as_bad (inst
.error
);
5890 to
= frag_more (inst
.size
);
5891 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
5893 assert (inst
.size
== (2 * THUMB_SIZE
));
5894 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
5895 md_number_to_chars (to
+ 2, inst
.instruction
, THUMB_SIZE
);
5898 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
5900 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5901 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
5902 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
5917 /* Align the instruction.
5918 This may not be the right thing to do but ... */
5919 /* arm_align (2, 0); */
5920 listing_prev_line (); /* Defined in listing.h */
5922 /* Align the previous label if needed. */
5923 if (last_label_seen
!= NULL
)
5925 symbol_set_frag (last_label_seen
, frag_now
);
5926 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
5927 S_SET_SEGMENT (last_label_seen
, now_seg
);
5930 memset (&inst
, '\0', sizeof (inst
));
5931 inst
.reloc
.type
= BFD_RELOC_NONE
;
5934 str
++; /* Skip leading white space */
5936 /* Scan up to the end of the op-code, which must end in white space or
5938 for (start
= p
= str
; *p
!= '\0'; p
++)
5944 as_bad (_("No operator -- statement `%s'\n"), str
);
5950 CONST
struct thumb_opcode
*opcode
;
5954 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
5958 inst
.instruction
= opcode
->value
;
5959 inst
.size
= opcode
->size
;
5960 (*opcode
->parms
)(p
);
5961 output_inst (start
);
5967 CONST
struct asm_opcode
*opcode
;
5969 inst
.size
= INSN_SIZE
;
5970 /* p now points to the end of the opcode, probably white space, but we
5971 have to break the opcode up in case it contains condionals and flags;
5972 keep trying with progressively smaller basic instructions until one
5973 matches, or we run out of opcode. */
5974 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
5975 for (; q
!= str
; q
--)
5979 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
5981 if (opcode
&& opcode
->template)
5983 unsigned long flag_bits
= 0;
5986 /* Check that this instruction is supported for this CPU */
5987 if ((opcode
->variants
& cpu_variant
) == 0)
5990 inst
.instruction
= opcode
->value
;
5991 if (q
== p
) /* Just a simple opcode */
5993 if (opcode
->comp_suffix
!= 0)
5994 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
5995 opcode
->comp_suffix
);
5998 inst
.instruction
|= COND_ALWAYS
;
5999 (*opcode
->parms
)(q
, 0);
6001 output_inst (start
);
6005 /* Now check for a conditional */
6009 CONST
struct asm_cond
*cond
;
6013 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6017 if (cond
->value
== 0xf0000000)
6019 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6021 inst
.instruction
|= cond
->value
;
6025 inst
.instruction
|= COND_ALWAYS
;
6028 inst
.instruction
|= COND_ALWAYS
;
6030 /* if there is a compulsory suffix, it should come here, before
6031 any optional flags. */
6032 if (opcode
->comp_suffix
)
6034 CONST
char *s
= opcode
->comp_suffix
;
6046 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6047 opcode
->comp_suffix
);
6054 /* The remainder, if any should now be flags for the instruction;
6055 Scan these checking each one found with the opcode. */
6059 CONST
struct asm_flg
*flag
= opcode
->flags
;
6068 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6070 if (streq (r
, flag
[flagno
].template))
6072 flag_bits
|= flag
[flagno
].set_bits
;
6078 if (! flag
[flagno
].template)
6085 (*opcode
->parms
) (p
, flag_bits
);
6086 output_inst (start
);
6095 /* It wasn't an instruction, but it might be a register alias of the form
6105 if (*q
&& !strncmp (q
, ".req ", 4))
6108 char * copy_of_str
= str
;
6115 for (r
= q
; *r
!= '\0'; r
++)
6125 regnum
= arm_reg_parse (& q
);
6128 reg
= arm_reg_parse (& str
);
6134 insert_reg_alias (str
, regnum
);
6138 as_warn (_("register '%s' does not exist\n"), q
);
6141 else if (regnum
!= FAIL
)
6144 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
6146 /* Do not warn abpout redefinitions to the same alias. */
6149 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6153 as_warn (_("ignoring incomplete .req pseuso op"));
6160 as_bad (_("bad instruction `%s'"), start
);
6165 * Invocation line includes a switch not recognized by the base assembler.
6166 * See if it's a processor-specific option. These are:
6167 * Cpu variants, the arm part is optional:
6168 * -m[arm]1 Currently not supported.
6169 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6170 * -m[arm]3 Arm 3 processor
6171 * -m[arm]6[xx], Arm 6 processors
6172 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6173 * -m8[10] Arm 8 processors
6174 * -m9[20][tdmi] Arm 9 processors
6175 * -mstrongarm[110[0]] StrongARM processors
6176 * -mall All (except the ARM1)
6178 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6179 * -mfpe-old (No float load/store multiples)
6180 * -mno-fpu Disable all floating point instructions
6181 * Run-time endian selection:
6182 * -EB big endian cpu
6183 * -EL little endian cpu
6184 * ARM Procedure Calling Standard:
6185 * -mapcs-32 32 bit APCS
6186 * -mapcs-26 26 bit APCS
6187 * -mapcs-float Pass floats in float regs
6188 * -mapcs-reentrant Position independent code
6189 * -mthumb-interwork Code supports Arm/Thumb interworking
6190 * -moabi Old ELF ABI
6193 CONST
char * md_shortopts
= "m:k";
6194 struct option md_longopts
[] =
6196 #ifdef ARM_BI_ENDIAN
6197 #define OPTION_EB (OPTION_MD_BASE + 0)
6198 {"EB", no_argument
, NULL
, OPTION_EB
},
6199 #define OPTION_EL (OPTION_MD_BASE + 1)
6200 {"EL", no_argument
, NULL
, OPTION_EL
},
6202 #define OPTION_OABI (OPTION_MD_BASE +2)
6203 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6206 {NULL
, no_argument
, NULL
, 0}
6208 size_t md_longopts_size
= sizeof (md_longopts
);
6211 md_parse_option (c
, arg
)
6219 #ifdef ARM_BI_ENDIAN
6221 target_big_endian
= 1;
6224 target_big_endian
= 0;
6232 if (streq (str
, "fpa10"))
6233 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6234 else if (streq (str
, "fpa11"))
6235 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6236 else if (streq (str
, "fpe-old"))
6237 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6243 if (streq (str
, "no-fpu"))
6244 cpu_variant
&= ~FPU_ALL
;
6249 if (streq (str
, "oabi"))
6255 /* Limit assembler to generating only Thumb instructions: */
6256 if (streq (str
, "thumb"))
6258 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6259 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6262 else if (streq (str
, "thumb-interwork"))
6264 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
| ARM_ARCHv4
;
6265 #if defined OBJ_COFF || defined OBJ_ELF
6266 support_interwork
= true;
6274 if (streq (str
, "all"))
6276 cpu_variant
= ARM_ALL
| FPU_ALL
;
6279 #if defined OBJ_COFF || defined OBJ_ELF
6280 if (! strncmp (str
, "apcs-", 5))
6282 /* GCC passes on all command line options starting "-mapcs-..."
6283 to us, so we must parse them here. */
6287 if (streq (str
, "32"))
6289 uses_apcs_26
= false;
6292 else if (streq (str
, "26"))
6294 uses_apcs_26
= true;
6297 else if (streq (str
, "frame"))
6299 /* Stack frames are being generated - does not affect
6303 else if (streq (str
, "stack-check"))
6305 /* Stack checking is being performed - does not affect
6306 linkage, but does require that the functions
6307 __rt_stkovf_split_small and __rt_stkovf_split_big be
6308 present in the final link. */
6312 else if (streq (str
, "float"))
6314 /* Floating point arguments are being passed in the floating
6315 point registers. This does affect linking, since this
6316 version of the APCS is incompatible with the version that
6317 passes floating points in the integer registers. */
6319 uses_apcs_float
= true;
6322 else if (streq (str
, "reentrant"))
6324 /* Reentrant code has been generated. This does affect
6325 linking, since there is no point in linking reentrant/
6326 position independent code with absolute position code. */
6331 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6335 /* Strip off optional "arm" */
6336 if (! strncmp (str
, "arm", 3))
6342 if (streq (str
, "1"))
6343 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6349 if (streq (str
, "2"))
6350 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6351 else if (streq (str
, "250"))
6352 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6358 if (streq (str
, "3"))
6359 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6365 switch (strtol (str
, NULL
, 10))
6372 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6380 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6392 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6398 cpu_variant
|= (ARM_THUMB
| ARM_ARCHv4
);
6402 cpu_variant
|= ARM_LONGMUL
;
6405 case 'f': /* fe => fp enabled cpu. */
6411 case 'c': /* Left over from 710c processor name. */
6412 case 'd': /* Debug */
6413 case 'i': /* Embedded ICE */
6414 /* Included for completeness in ARM processor naming. */
6424 if (streq (str
, "8") || streq (str
, "810"))
6425 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCHv4
| ARM_LONGMUL
;
6431 if (streq (str
, "9"))
6432 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
| ARM_THUMB
;
6433 else if (streq (str
, "920"))
6434 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
;
6435 else if (streq (str
, "920t"))
6436 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
| ARM_THUMB
;
6437 else if (streq (str
, "9tdmi"))
6438 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
| ARM_THUMB
;
6444 if (streq (str
, "strongarm")
6445 || streq (str
, "strongarm110")
6446 || streq (str
, "strongarm1100"))
6447 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCHv4
| ARM_LONGMUL
;
6453 /* Select variant based on architecture rather than processor */
6459 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6460 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6461 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6466 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6470 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6472 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6477 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCHv4
;
6481 case 't': cpu_variant
|= ARM_THUMB
; break;
6483 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6488 as_bad (_("Invalid architecture variant -m%s"), arg
);
6495 as_bad (_("Invalid processor variant -m%s"), arg
);
6518 ARM Specific Assembler Options:\n\
6519 -m[arm][<processor name>] select processor variant\n\
6520 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
6521 -mthumb only allow Thumb instructions\n\
6522 -mthumb-interwork mark the assembled code as supporting interworking\n\
6523 -mall allow any instruction\n\
6524 -mfpa10, -mfpa11 select floating point architecture\n\
6525 -mfpe-old don't allow floating-point multiple instructions\n\
6526 -mno-fpu don't allow any floating-point instructions.\n"));
6529 -k generate PIC code.\n"));
6530 #if defined OBJ_COFF || defined OBJ_ELF
6533 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6536 -mapcs-float floating point args are passed in FP regs\n"));
6539 -mapcs-reentrant the code is position independent/reentrant\n"));
6544 -moabi support the old ELF ABI\n"));
6546 #ifdef ARM_BI_ENDIAN
6549 -EB assemble code for a big endian cpu\n\
6550 -EL assemble code for a little endian cpu\n"));
6554 /* We need to be able to fix up arbitrary expressions in some statements.
6555 This is so that we can handle symbols that are an arbitrary distance from
6556 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6557 which returns part of an address in a form which will be valid for
6558 a data instruction. We do this by pushing the expression into a symbol
6559 in the expr_section, and creating a fix for that. */
6562 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6571 arm_fix_data
* arm_data
;
6579 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6583 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6588 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6589 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6590 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6591 arm_data
->thumb_mode
= thumb_mode
;
6598 * This fix_new is called by cons via TC_CONS_FIX_NEW
6600 * We check the expression to see if it is of the form
6601 * __GLOBAL_OFFSET_TABLE + ???
6602 * If it is then this is a PC relative reference to the GOT.
6609 * .word __GLOBAL_OFFSET_TABLE + (. - (L2 + 4))
6611 * In this case use a reloc type BFD_RELOC_ARM_GOTPC instead of the
6612 * normal BFD_RELOC_{16,32,64}
6616 cons_fix_new_arm (frag
, where
, size
, exp
)
6622 bfd_reloc_code_real_type type
;
6627 * @@ Should look at CPU word size.
6632 type
= BFD_RELOC_16
;
6636 type
= BFD_RELOC_32
;
6639 type
= BFD_RELOC_64
;
6643 /* Look for possible GOTPC reloc */
6646 * Look for pic assembler and 'undef symbol + expr symbol' expression
6647 * and a 32 bit size.
6650 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6653 /* A good place to do this, although this was probably not intended
6654 * for this kind of use. We need to dump the literal pool before
6655 * references are made to a null symbol pointer. */
6659 if (current_poolP
!= NULL
)
6661 subseg_set (text_section
, 0); /* Put it at the end of text section */
6663 listing_prev_line ();
6668 arm_start_line_hook ()
6670 last_label_seen
= NULL
;
6674 arm_frob_label (sym
)
6677 last_label_seen
= sym
;
6679 ARM_SET_THUMB (sym
, thumb_mode
);
6681 #if defined OBJ_COFF || defined OBJ_ELF
6682 ARM_SET_INTERWORK (sym
, support_interwork
);
6685 if (label_is_thumb_function_name
)
6687 /* When the address of a Thumb function is taken the bottom
6688 bit of that address should be set. This will allow
6689 interworking between Arm and Thumb functions to work
6692 THUMB_SET_FUNC (sym
, 1);
6694 label_is_thumb_function_name
= false;
6698 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6702 arm_adjust_symtab ()
6707 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6709 if (ARM_IS_THUMB (sym
))
6711 if (THUMB_IS_FUNC (sym
))
6713 /* Mark the symbol as a Thumb function. */
6714 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6715 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6716 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6718 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6719 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6721 as_bad (_("%s: unexpected function type: %d"),
6722 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6724 else switch (S_GET_STORAGE_CLASS (sym
))
6727 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6730 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6733 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6735 default: /* do nothing */
6740 if (ARM_IS_INTERWORK (sym
))
6741 coffsymbol (sym
->bsym
)->native
->u
.syment
.n_flags
= 0xFF;
6746 elf_symbol_type
* elf_sym
;
6749 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6751 if (ARM_IS_THUMB (sym
))
6753 if (THUMB_IS_FUNC (sym
))
6755 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6756 bind
= ELF_ST_BIND (elf_sym
);
6757 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6767 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6769 *input_line_pointer
= '/';
6770 input_line_pointer
+= 5;
6771 *input_line_pointer
= 0;
6779 arm_canonicalize_symbol_name (name
)
6784 if (thumb_mode
&& (len
= strlen (name
)) > 5
6785 && streq (name
+ len
- 5, "/data"))
6787 *(name
+ len
- 5) = 0;
6794 arm_validate_fix (fixP
)
6797 /* If the destination of the branch is a defined symbol which does not have
6798 the THUMB_FUNC attribute, then we must be calling a function which has
6799 the (interfacearm) attribute. We look for the Thumb entry point to that
6800 function and change the branch to refer to that function instead. */
6801 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6802 && fixP
->fx_addsy
!= NULL
6803 && S_IS_DEFINED (fixP
->fx_addsy
)
6804 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6806 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6814 /* Relocations against Thumb function names must be left unadjusted,
6815 so that the linker can use this information to correctly set the
6816 bottom bit of their addresses. The MIPS version of this function
6817 also prevents relocations that are mips-16 specific, but I do not
6818 know why it does this.
6821 There is one other problem that ought to be addressed here, but
6822 which currently is not: Taking the address of a label (rather
6823 than a function) and then later jumping to that address. Such
6824 addresses also ought to have their bottom bit set (assuming that
6825 they reside in Thumb code), but at the moment they will not. */
6828 arm_fix_adjustable (fixP
)
6832 if (fixP
->fx_addsy
== NULL
)
6835 /* Prevent all adjustments to global symbols. */
6836 if (S_IS_EXTERN (fixP
->fx_addsy
))
6839 if (S_IS_WEAK (fixP
->fx_addsy
))
6842 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6843 && fixP
->fx_subsy
== NULL
)
6846 /* We need the symbol name for the VTABLE entries */
6847 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6848 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6855 elf32_arm_target_format ()
6857 if (target_big_endian
)
6859 return "elf32-bigarm-oabi";
6861 return "elf32-bigarm";
6864 return "elf32-littlearm-oabi";
6866 return "elf32-littlearm";
6870 armelf_frob_symbol (symp
, puntp
)
6874 elf_frob_symbol (symp
, puntp
);
6878 arm_force_relocation (fixp
)
6881 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6882 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6883 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
6889 static bfd_reloc_code_real_type
6899 bfd_reloc_code_real_type reloc
;
6903 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
6904 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
6905 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
6906 /* ScottB: Jan 30, 1998 */
6907 /* Added support for parsing "var(PLT)" branch instructions */
6908 /* generated by GCC for PLT relocs */
6909 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
6910 NULL
, 0, BFD_RELOC_UNUSED
6914 for (i
= 0, ip
= input_line_pointer
;
6915 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
6917 id
[i
] = tolower (*ip
);
6919 for (i
= 0; reloc_map
[i
].str
; i
++)
6920 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
6923 input_line_pointer
+= reloc_map
[i
].len
;
6925 return reloc_map
[i
].reloc
;
6929 s_arm_elf_cons (nbytes
)
6934 #ifdef md_flush_pending_output
6935 md_flush_pending_output ();
6938 if (is_it_end_of_statement ())
6940 demand_empty_rest_of_line ();
6944 #ifdef md_cons_align
6945 md_cons_align (nbytes
);
6950 bfd_reloc_code_real_type reloc
;
6954 if (exp
.X_op
== O_symbol
6955 && * input_line_pointer
== '('
6956 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
6958 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
6959 int size
= bfd_get_reloc_size (howto
);
6962 as_bad ("%s relocations do not fit in %d bytes", howto
->name
, nbytes
);
6965 register char * p
= frag_more ((int) nbytes
);
6966 int offset
= nbytes
- size
;
6968 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
6973 emit_expr (& exp
, (unsigned int) nbytes
);
6975 while (*input_line_pointer
++ == ',');
6977 input_line_pointer
--; /* Put terminator back into stream. */
6978 demand_empty_rest_of_line ();
6981 #endif /* OBJ_ELF */