1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
39 /* Types of processor to assemble for. */
40 #define ARM_1 0x00000001
41 #define ARM_2 0x00000002
42 #define ARM_3 0x00000004
44 #define ARM_6 0x00000008
45 #define ARM_7 ARM_6 /* same core instruction set */
46 #define ARM_8 ARM_6 /* same core instruction set */
47 #define ARM_9 ARM_6 /* same core instruction set */
48 #define ARM_CPU_MASK 0x0000000f
50 /* The following bitmasks control CPU extensions (ARM7 onwards): */
51 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
52 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
53 #define ARM_THUMB 0x00000040 /* allow BX instruction */
55 #define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
57 /* Some useful combinations: */
58 #define ARM_ANY 0x00ffffff
59 #define ARM_2UP 0x00fffffe
60 #define ARM_ALL ARM_2UP /* Not arm1 only */
61 #define ARM_3UP 0x00fffffc
62 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
64 #define FPU_CORE 0x80000000
65 #define FPU_FPA10 0x40000000
66 #define FPU_FPA11 0x40000000
69 /* Some useful combinations */
70 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
71 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
76 #define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB)
78 #define CPU_DEFAULT ARM_ALL
83 #define FPU_DEFAULT FPU_ALL
86 #define streq(a,b) (strcmp (a, b) == 0)
88 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
89 static int target_oabi
= 0;
91 #if defined OBJ_COFF || defined OBJ_ELF
92 /* Flags stored in private area of BFD structure */
93 static boolean uses_apcs_26
= false;
94 static boolean support_interwork
= false;
95 static boolean uses_apcs_float
= false;
96 static boolean pic_code
= false;
99 /* This array holds the chars that always start a comment. If the
100 pre-processor is disabled, these aren't very useful */
101 CONST
char comment_chars
[] = "@";
103 /* This array holds the chars that only start a comment at the beginning of
104 a line. If the line seems to have the form '# 123 filename'
105 .line and .file directives will appear in the pre-processed output */
106 /* Note that input_file.c hand checks for '#' at the beginning of the
107 first line of the input file. This is because the compiler outputs
108 #NO_APP at the beginning of its output. */
109 /* Also note that comments like this one will always work. */
110 CONST
char line_comment_chars
[] = "#";
113 CONST
char line_separator_chars
[] = ";";
115 CONST
char line_separator_chars
[] = "";
118 /* Chars that can be used to separate mant from exp in floating point nums */
119 CONST
char EXP_CHARS
[] = "eE";
121 /* Chars that mean this number is a floating point constant */
125 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
127 /* Prefix characters that indicate the start of an immediate
129 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
132 symbolS
* GOT_symbol
; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
135 CONST
int md_reloc_size
= 8; /* Size of relocation record */
137 static int thumb_mode
= 0; /* non-zero if assembling thumb instructions */
139 typedef struct arm_fix
147 unsigned long instruction
;
152 bfd_reloc_code_real_type type
;
162 CONST
char * template;
166 static CONST
struct asm_shift shift
[] =
182 #define NO_SHIFT_RESTRICT 1
183 #define SHIFT_RESTRICT 0
185 #define NUM_FLOAT_VALS 8
187 CONST
char * fp_const
[] =
189 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
192 /* Number of littlenums required to hold an extended precision number */
193 #define MAX_LITTLENUMS 6
195 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
205 #define CP_T_X 0x00008000
206 #define CP_T_Y 0x00400000
207 #define CP_T_Pre 0x01000000
208 #define CP_T_UD 0x00800000
209 #define CP_T_WB 0x00200000
211 #define CONDS_BIT (0x00100000)
212 #define LOAD_BIT (0x00100000)
213 #define TRANS_BIT (0x00200000)
217 CONST
char * template;
221 /* This is to save a hash look-up in the common case */
222 #define COND_ALWAYS 0xe0000000
224 static CONST
struct asm_cond conds
[] =
228 {"cs", 0x20000000}, {"hs", 0x20000000},
229 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
244 /* Warning: If the top bit of the set_bits is set, then the standard
245 instruction bitmask is ignored, and the new bitmask is taken from
249 CONST
char * template; /* Basic flag string */
250 unsigned long set_bits
; /* Bits to set */
253 static CONST
struct asm_flg s_flag
[] =
259 static CONST
struct asm_flg ldr_flags
[] =
263 {"bt", 0x00400000 | TRANS_BIT
},
270 static CONST
struct asm_flg str_flags
[] =
274 {"bt", 0x00400000 | TRANS_BIT
},
279 static CONST
struct asm_flg byte_flag
[] =
285 static CONST
struct asm_flg cmp_flags
[] =
292 static CONST
struct asm_flg ldm_flags
[] =
305 static CONST
struct asm_flg stm_flags
[] =
318 static CONST
struct asm_flg lfm_flags
[] =
325 static CONST
struct asm_flg sfm_flags
[] =
332 static CONST
struct asm_flg round_flags
[] =
340 /* The implementation of the FIX instruction is broken on some assemblers,
341 in that it accepts a precision specifier as well as a rounding specifier,
342 despite the fact that this is meaningless. To be more compatible, we
343 accept it as well, though of course it does not set any bits. */
344 static CONST
struct asm_flg fix_flags
[] =
361 static CONST
struct asm_flg except_flag
[] =
367 static CONST
struct asm_flg cplong_flag
[] =
375 CONST
char * template;
376 unsigned long number
;
379 #define PSR_FIELD_MASK 0x000f0000
381 #define PSR_FLAGS 0x00080000
382 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
383 #define PSR_ALL 0x00090000
392 static CONST
struct asm_psr psrs
[] =
396 {"cpsr_all", CPSR_ALL
},
398 {"spsr_all", SPSR_ALL
},
401 {"cpsr_flg", CPSR_FLG
},
402 {"spsr_flg", SPSR_FLG
},
405 {"cpsr_c", CPSR_CTL
},
406 {"cpsr_ctl", CPSR_CTL
},
407 {"spsr_c", SPSR_CTL
},
408 {"spsr_ctl", SPSR_CTL
}
411 /* Functions called by parser */
412 /* ARM instructions */
413 static void do_arit
PARAMS ((char *operands
, unsigned long flags
));
414 static void do_cmp
PARAMS ((char *operands
, unsigned long flags
));
415 static void do_mov
PARAMS ((char *operands
, unsigned long flags
));
416 static void do_ldst
PARAMS ((char *operands
, unsigned long flags
));
417 static void do_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
418 static void do_branch
PARAMS ((char *operands
, unsigned long flags
));
419 static void do_swi
PARAMS ((char *operands
, unsigned long flags
));
420 /* Pseudo Op codes */
421 static void do_adr
PARAMS ((char *operands
, unsigned long flags
));
422 static void do_nop
PARAMS ((char *operands
, unsigned long flags
));
424 static void do_mul
PARAMS ((char *operands
, unsigned long flags
));
425 static void do_mla
PARAMS ((char *operands
, unsigned long flags
));
427 static void do_swap
PARAMS ((char *operands
, unsigned long flags
));
429 static void do_msr
PARAMS ((char *operands
, unsigned long flags
));
430 static void do_mrs
PARAMS ((char *operands
, unsigned long flags
));
432 static void do_mull
PARAMS ((char *operands
, unsigned long flags
));
434 static void do_bx
PARAMS ((char *operands
, unsigned long flags
));
436 /* Coprocessor Instructions */
437 static void do_cdp
PARAMS ((char *operands
, unsigned long flags
));
438 static void do_lstc
PARAMS ((char *operands
, unsigned long flags
));
439 static void do_co_reg
PARAMS ((char *operands
, unsigned long flags
));
440 static void do_fp_ctrl
PARAMS ((char *operands
, unsigned long flags
));
441 static void do_fp_ldst
PARAMS ((char *operands
, unsigned long flags
));
442 static void do_fp_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
443 static void do_fp_dyadic
PARAMS ((char *operands
, unsigned long flags
));
444 static void do_fp_monadic
PARAMS ((char *operands
, unsigned long flags
));
445 static void do_fp_cmp
PARAMS ((char *operands
, unsigned long flags
));
446 static void do_fp_from_reg
PARAMS ((char *operands
, unsigned long flags
));
447 static void do_fp_to_reg
PARAMS ((char *operands
, unsigned long flags
));
449 static void fix_new_arm
PARAMS ((fragS
*frag
, int where
,
450 short int size
, expressionS
*exp
,
451 int pc_rel
, int reloc
));
452 static int arm_reg_parse
PARAMS ((char **ccp
));
453 static int arm_psr_parse
PARAMS ((char **ccp
));
454 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
,
456 static int add_to_lit_pool
PARAMS ((void));
457 static unsigned validate_immediate
PARAMS ((unsigned));
458 static int validate_offset_imm
PARAMS ((int, int));
459 static void opcode_select
PARAMS ((int));
460 static void end_of_line
PARAMS ((char *));
461 static int reg_required_here
PARAMS ((char **, int));
462 static int psr_required_here
PARAMS ((char **, int, int));
463 static int co_proc_number
PARAMS ((char **));
464 static int cp_opc_expr
PARAMS ((char **, int, int));
465 static int cp_reg_required_here
PARAMS ((char **, int));
466 static int fp_reg_required_here
PARAMS ((char **, int));
467 static int cp_address_offset
PARAMS ((char **));
468 static int cp_address_required_here
PARAMS ((char **));
469 static int my_get_float_expression
PARAMS ((char **));
470 static int skip_past_comma
PARAMS ((char **));
471 static int walk_no_bignums
PARAMS ((symbolS
*));
472 static int negate_data_op
PARAMS ((unsigned long *,
474 static int data_op2
PARAMS ((char **));
475 static int fp_op2
PARAMS ((char **));
476 static long reg_list
PARAMS ((char **));
477 static void thumb_load_store
PARAMS ((char *, int, int));
478 static int decode_shift
PARAMS ((char **, int));
479 static int ldst_extend
PARAMS ((char **, int));
480 static void thumb_add_sub
PARAMS ((char *, int));
481 static void insert_reg
PARAMS ((int));
482 static void thumb_shift
PARAMS ((char *, int));
483 static void thumb_mov_compare
PARAMS ((char *, int));
484 static void set_constant_flonums
PARAMS ((void));
485 static valueT md_chars_to_number
PARAMS ((char *, int));
486 static void insert_reg_alias
PARAMS ((char *, int));
487 static void output_inst
PARAMS ((char *));
489 static bfd_reloc_code_real_type arm_parse_reloc
PARAMS ((void));
492 /* ARM instructions take 4bytes in the object file, Thumb instructions
496 /* LONGEST_INST is the longest basic instruction name without conditions or
498 * ARM7M has 4 of length 5
501 #define LONGEST_INST 5
505 CONST
char * template; /* Basic string to match */
506 unsigned long value
; /* Basic instruction code */
507 CONST
char * comp_suffix
; /* Compulsory suffix that must follow conds */
508 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
509 unsigned long variants
; /* Which CPU variants this exists for */
510 /* Function to call to parse args */
511 void (* parms
) PARAMS ((char *, unsigned long));
514 static CONST
struct asm_opcode insns
[] =
516 /* ARM Instructions */
517 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
518 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
519 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
520 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
521 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
522 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
523 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
524 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
525 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
526 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
527 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
528 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
529 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
530 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
531 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
532 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
533 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
534 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
535 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
536 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
537 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
538 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
539 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
542 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
543 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
545 /* ARM 2 multiplies */
546 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
547 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
549 /* ARM 3 - swp instructions */
550 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
552 /* ARM 6 Coprocessor instructions */
553 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
554 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
555 /* ScottB: our code uses 0x0128f000 for msr.
556 NickC: but this is wrong because the bits 16 and 19 are handled
557 by the PSR_xxx defines above. */
559 /* ARM 7M long multiplies - need signed/unsigned flags! */
560 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
561 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
562 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
563 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
565 /* ARM THUMB interworking */
566 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
568 /* Floating point instructions */
569 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
570 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
571 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
572 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
573 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
574 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
575 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
576 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
577 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
578 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
579 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
580 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
581 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
582 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
583 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
584 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
585 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
586 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
587 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
588 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
589 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
590 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
591 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
592 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
593 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
594 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
595 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
596 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
597 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
598 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
599 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
600 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
601 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
602 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
603 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
604 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
605 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
606 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
607 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
608 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
609 be an optional suffix, but part of the instruction. To be compatible,
611 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
612 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
613 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
614 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
616 /* Generic copressor instructions */
617 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
618 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
619 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
620 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
621 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
624 /* defines for various bits that we will want to toggle */
626 #define INST_IMMEDIATE 0x02000000
627 #define OFFSET_REG 0x02000000
628 #define HWOFFSET_IMM 0x00400000
629 #define SHIFT_BY_REG 0x00000010
630 #define PRE_INDEX 0x01000000
631 #define INDEX_UP 0x00800000
632 #define WRITE_BACK 0x00200000
633 #define MULTI_SET_PSR 0x00400000
635 #define LITERAL_MASK 0xf000f000
636 #define COND_MASK 0xf0000000
637 #define OPCODE_MASK 0xfe1fffff
638 #define DATA_OP_SHIFT 21
640 /* Codes to distinguish the arithmetic instructions */
652 #define OPCODE_CMP 10
653 #define OPCODE_CMN 11
654 #define OPCODE_ORR 12
655 #define OPCODE_MOV 13
656 #define OPCODE_BIC 14
657 #define OPCODE_MVN 15
659 static void do_t_nop
PARAMS ((char *operands
));
660 static void do_t_arit
PARAMS ((char *operands
));
661 static void do_t_add
PARAMS ((char *operands
));
662 static void do_t_asr
PARAMS ((char *operands
));
663 static void do_t_branch9
PARAMS ((char *operands
));
664 static void do_t_branch12
PARAMS ((char *operands
));
665 static void do_t_branch23
PARAMS ((char *operands
));
666 static void do_t_bx
PARAMS ((char *operands
));
667 static void do_t_compare
PARAMS ((char *operands
));
668 static void do_t_ldmstm
PARAMS ((char *operands
));
669 static void do_t_ldr
PARAMS ((char *operands
));
670 static void do_t_ldrb
PARAMS ((char *operands
));
671 static void do_t_ldrh
PARAMS ((char *operands
));
672 static void do_t_lds
PARAMS ((char *operands
));
673 static void do_t_lsl
PARAMS ((char *operands
));
674 static void do_t_lsr
PARAMS ((char *operands
));
675 static void do_t_mov
PARAMS ((char *operands
));
676 static void do_t_push_pop
PARAMS ((char *operands
));
677 static void do_t_str
PARAMS ((char *operands
));
678 static void do_t_strb
PARAMS ((char *operands
));
679 static void do_t_strh
PARAMS ((char *operands
));
680 static void do_t_sub
PARAMS ((char *operands
));
681 static void do_t_swi
PARAMS ((char *operands
));
682 static void do_t_adr
PARAMS ((char *operands
));
684 #define T_OPCODE_MUL 0x4340
685 #define T_OPCODE_TST 0x4200
686 #define T_OPCODE_CMN 0x42c0
687 #define T_OPCODE_NEG 0x4240
688 #define T_OPCODE_MVN 0x43c0
690 #define T_OPCODE_ADD_R3 0x1800
691 #define T_OPCODE_SUB_R3 0x1a00
692 #define T_OPCODE_ADD_HI 0x4400
693 #define T_OPCODE_ADD_ST 0xb000
694 #define T_OPCODE_SUB_ST 0xb080
695 #define T_OPCODE_ADD_SP 0xa800
696 #define T_OPCODE_ADD_PC 0xa000
697 #define T_OPCODE_ADD_I8 0x3000
698 #define T_OPCODE_SUB_I8 0x3800
699 #define T_OPCODE_ADD_I3 0x1c00
700 #define T_OPCODE_SUB_I3 0x1e00
702 #define T_OPCODE_ASR_R 0x4100
703 #define T_OPCODE_LSL_R 0x4080
704 #define T_OPCODE_LSR_R 0x40c0
705 #define T_OPCODE_ASR_I 0x1000
706 #define T_OPCODE_LSL_I 0x0000
707 #define T_OPCODE_LSR_I 0x0800
709 #define T_OPCODE_MOV_I8 0x2000
710 #define T_OPCODE_CMP_I8 0x2800
711 #define T_OPCODE_CMP_LR 0x4280
712 #define T_OPCODE_MOV_HR 0x4600
713 #define T_OPCODE_CMP_HR 0x4500
715 #define T_OPCODE_LDR_PC 0x4800
716 #define T_OPCODE_LDR_SP 0x9800
717 #define T_OPCODE_STR_SP 0x9000
718 #define T_OPCODE_LDR_IW 0x6800
719 #define T_OPCODE_STR_IW 0x6000
720 #define T_OPCODE_LDR_IH 0x8800
721 #define T_OPCODE_STR_IH 0x8000
722 #define T_OPCODE_LDR_IB 0x7800
723 #define T_OPCODE_STR_IB 0x7000
724 #define T_OPCODE_LDR_RW 0x5800
725 #define T_OPCODE_STR_RW 0x5000
726 #define T_OPCODE_LDR_RH 0x5a00
727 #define T_OPCODE_STR_RH 0x5200
728 #define T_OPCODE_LDR_RB 0x5c00
729 #define T_OPCODE_STR_RB 0x5400
731 #define T_OPCODE_PUSH 0xb400
732 #define T_OPCODE_POP 0xbc00
734 #define T_OPCODE_BRANCH 0xe7fe
736 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
738 #define THUMB_SIZE 2 /* Size of thumb instruction */
739 #define THUMB_REG_LO 0x1
740 #define THUMB_REG_HI 0x2
741 #define THUMB_REG_ANY 0x3
743 #define THUMB_H1 0x0080
744 #define THUMB_H2 0x0040
751 #define THUMB_COMPARE 1
754 #define THUMB_STORE 1
756 #define THUMB_PP_PC_LR 0x0100
758 /* These three are used for immediate shifts, do not alter */
760 #define THUMB_HALFWORD 1
765 CONST
char * template; /* Basic string to match */
766 unsigned long value
; /* Basic instruction code */
768 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
771 static CONST
struct thumb_opcode tinsns
[] =
773 {"adc", 0x4140, 2, do_t_arit
},
774 {"add", 0x0000, 2, do_t_add
},
775 {"and", 0x4000, 2, do_t_arit
},
776 {"asr", 0x0000, 2, do_t_asr
},
777 {"b", T_OPCODE_BRANCH
, 2, do_t_branch12
},
778 {"beq", 0xd0fe, 2, do_t_branch9
},
779 {"bne", 0xd1fe, 2, do_t_branch9
},
780 {"bcs", 0xd2fe, 2, do_t_branch9
},
781 {"bhs", 0xd2fe, 2, do_t_branch9
},
782 {"bcc", 0xd3fe, 2, do_t_branch9
},
783 {"bul", 0xd3fe, 2, do_t_branch9
},
784 {"blo", 0xd3fe, 2, do_t_branch9
},
785 {"bmi", 0xd4fe, 2, do_t_branch9
},
786 {"bpl", 0xd5fe, 2, do_t_branch9
},
787 {"bvs", 0xd6fe, 2, do_t_branch9
},
788 {"bvc", 0xd7fe, 2, do_t_branch9
},
789 {"bhi", 0xd8fe, 2, do_t_branch9
},
790 {"bls", 0xd9fe, 2, do_t_branch9
},
791 {"bge", 0xdafe, 2, do_t_branch9
},
792 {"blt", 0xdbfe, 2, do_t_branch9
},
793 {"bgt", 0xdcfe, 2, do_t_branch9
},
794 {"ble", 0xddfe, 2, do_t_branch9
},
795 {"bic", 0x4380, 2, do_t_arit
},
796 {"bl", 0xf7fffffe, 4, do_t_branch23
},
797 {"bx", 0x4700, 2, do_t_bx
},
798 {"cmn", T_OPCODE_CMN
, 2, do_t_arit
},
799 {"cmp", 0x0000, 2, do_t_compare
},
800 {"eor", 0x4040, 2, do_t_arit
},
801 {"ldmia", 0xc800, 2, do_t_ldmstm
},
802 {"ldr", 0x0000, 2, do_t_ldr
},
803 {"ldrb", 0x0000, 2, do_t_ldrb
},
804 {"ldrh", 0x0000, 2, do_t_ldrh
},
805 {"ldrsb", 0x5600, 2, do_t_lds
},
806 {"ldrsh", 0x5e00, 2, do_t_lds
},
807 {"ldsb", 0x5600, 2, do_t_lds
},
808 {"ldsh", 0x5e00, 2, do_t_lds
},
809 {"lsl", 0x0000, 2, do_t_lsl
},
810 {"lsr", 0x0000, 2, do_t_lsr
},
811 {"mov", 0x0000, 2, do_t_mov
},
812 {"mul", T_OPCODE_MUL
, 2, do_t_arit
},
813 {"mvn", T_OPCODE_MVN
, 2, do_t_arit
},
814 {"neg", T_OPCODE_NEG
, 2, do_t_arit
},
815 {"orr", 0x4300, 2, do_t_arit
},
816 {"pop", 0xbc00, 2, do_t_push_pop
},
817 {"push", 0xb400, 2, do_t_push_pop
},
818 {"ror", 0x41c0, 2, do_t_arit
},
819 {"sbc", 0x4180, 2, do_t_arit
},
820 {"stmia", 0xc000, 2, do_t_ldmstm
},
821 {"str", 0x0000, 2, do_t_str
},
822 {"strb", 0x0000, 2, do_t_strb
},
823 {"strh", 0x0000, 2, do_t_strh
},
824 {"swi", 0xdf00, 2, do_t_swi
},
825 {"sub", 0x0000, 2, do_t_sub
},
826 {"tst", T_OPCODE_TST
, 2, do_t_arit
},
828 {"adr", 0x0000, 2, do_t_adr
},
829 {"nop", 0x46C0, 2, do_t_nop
}, /* mov r8,r8 */
838 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
839 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
840 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
846 /* These are the standard names; Users can add aliases with .req */
847 static CONST
struct reg_entry reg_table
[] =
849 /* Processor Register Numbers */
850 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
851 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
852 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
853 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
854 /* APCS conventions */
855 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
856 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
857 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
858 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
860 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
861 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
862 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
863 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
864 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
865 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
866 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
867 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
868 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
869 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
873 #define bad_args _("Bad arguments to instruction");
874 #define bad_pc _("r15 not allowed here");
876 static struct hash_control
* arm_ops_hsh
= NULL
;
877 static struct hash_control
* arm_tops_hsh
= NULL
;
878 static struct hash_control
* arm_cond_hsh
= NULL
;
879 static struct hash_control
* arm_shift_hsh
= NULL
;
880 static struct hash_control
* arm_reg_hsh
= NULL
;
881 static struct hash_control
* arm_psr_hsh
= NULL
;
883 /* This table describes all the machine specific pseudo-ops the assembler
884 has to support. The fields are:
885 pseudo-op name without dot
886 function to call to execute this pseudo-op
887 Integer arg to pass to the function
890 static void s_req
PARAMS ((int));
891 static void s_align
PARAMS ((int));
892 static void s_bss
PARAMS ((int));
893 static void s_even
PARAMS ((int));
894 static void s_ltorg
PARAMS ((int));
895 static void s_arm
PARAMS ((int));
896 static void s_thumb
PARAMS ((int));
897 static void s_code
PARAMS ((int));
898 static void s_force_thumb
PARAMS ((int));
899 static void s_thumb_func
PARAMS ((int));
900 static void s_thumb_set
PARAMS ((int));
901 static void arm_s_text
PARAMS ((int));
902 static void arm_s_data
PARAMS ((int));
904 static void arm_s_section
PARAMS ((int));
905 static void s_arm_elf_cons
PARAMS ((int));
908 static int my_get_expression
PARAMS ((expressionS
*, char **));
910 CONST pseudo_typeS md_pseudo_table
[] =
912 { "req", s_req
, 0 }, /* Never called becasue '.req' does not start line */
914 { "align", s_align
, 0 },
916 { "thumb", s_thumb
, 0 },
917 { "code", s_code
, 0 },
918 { "force_thumb", s_force_thumb
, 0 },
919 { "thumb_func", s_thumb_func
, 0 },
920 { "thumb_set", s_thumb_set
, 0 },
921 { "even", s_even
, 0 },
922 { "ltorg", s_ltorg
, 0 },
923 { "pool", s_ltorg
, 0 },
924 /* Allow for the effect of section changes. */
925 { "text", arm_s_text
, 0 },
926 { "data", arm_s_data
, 0 },
928 { "section", arm_s_section
, 0 },
929 { "section.s", arm_s_section
, 0 },
930 { "sect", arm_s_section
, 0 },
931 { "sect.s", arm_s_section
, 0 },
932 { "word", s_arm_elf_cons
, 4 },
933 { "long", s_arm_elf_cons
, 4 },
937 { "extend", float_cons
, 'x' },
938 { "ldouble", float_cons
, 'x' },
939 { "packed", float_cons
, 'p' },
943 /* Stuff needed to resolve the label ambiguity
953 symbolS
* last_label_seen
;
954 static int label_is_thumb_function_name
= false;
958 #define MAX_LITERAL_POOL_SIZE 1024
960 typedef struct literalS
962 struct expressionS exp
;
963 struct arm_it
* inst
;
966 literalT literals
[MAX_LITERAL_POOL_SIZE
];
967 int next_literal_pool_place
= 0; /* Next free entry in the pool */
968 int lit_pool_num
= 1; /* Next literal pool number */
969 symbolS
* current_poolP
= NULL
;
976 if (current_poolP
== NULL
)
977 current_poolP
= symbol_create (FAKE_LABEL_NAME
, undefined_section
,
978 (valueT
) 0, &zero_address_frag
);
980 /* Check if this literal value is already in the pool: */
981 while (lit_count
< next_literal_pool_place
)
983 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
984 && inst
.reloc
.exp
.X_op
== O_constant
985 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
986 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
991 if (lit_count
== next_literal_pool_place
) /* new entry */
993 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
995 inst
.error
= _("Literal Pool Overflow");
999 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
1000 lit_count
= next_literal_pool_place
++;
1003 inst
.reloc
.exp
.X_op
= O_symbol
;
1004 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
1005 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
1010 /* Can't use symbol_new here, so have to create a symbol and then at
1011 a later date assign it a value. Thats what these functions do. */
1013 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
1015 CONST
char * name
; /* It is copied, the caller can modify */
1016 segT segment
; /* Segment identifier (SEG_<something>) */
1017 valueT valu
; /* Symbol value */
1018 fragS
* frag
; /* Associated fragment */
1020 unsigned int name_length
;
1021 char * preserved_copy_of_name
;
1023 name_length
= strlen (name
) + 1; /* +1 for \0 */
1024 obstack_grow (¬es
, name
, name_length
);
1025 preserved_copy_of_name
= obstack_finish (¬es
);
1026 #ifdef STRIP_UNDERSCORE
1027 if (preserved_copy_of_name
[0] == '_')
1028 preserved_copy_of_name
++;
1031 #ifdef tc_canonicalize_symbol_name
1032 preserved_copy_of_name
=
1033 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1036 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1038 S_SET_SEGMENT (symbolP
, segment
);
1039 S_SET_VALUE (symbolP
, valu
);
1040 symbol_clear_list_pointers(symbolP
);
1042 symbol_set_frag (symbolP
, frag
);
1044 /* Link to end of symbol chain. */
1046 extern int symbol_table_frozen
;
1047 if (symbol_table_frozen
)
1051 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1053 obj_symbol_new_hook (symbolP
);
1055 #ifdef tc_symbol_new_hook
1056 tc_symbol_new_hook (symbolP
);
1060 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1061 #endif /* DEBUG_SYMS */
1064 /* Check that an immediate is valid, and if so, convert it to the right format. */
1067 validate_immediate (val
)
1073 #define rotate_left(v, n) (v << n | v >> (32 - n))
1075 for (i
= 0; i
< 32; i
+= 2)
1076 if ((a
= rotate_left (val
, i
)) <= 0xff)
1077 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1083 validate_offset_imm (val
, hwse
)
1087 if ((hwse
&& (val
< -255 || val
> 255))
1088 || (val
< -4095 || val
> 4095))
1098 as_bad (_("Invalid syntax for .req directive."));
1105 /* We don't support putting frags in the BSS segment, we fake it by
1106 marking in_bss, then looking at s_skip for clues?.. */
1107 subseg_set (bss_section
, 0);
1108 demand_empty_rest_of_line ();
1115 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1116 frag_align (1, 0, 0);
1118 record_alignment (now_seg
, 1);
1120 demand_empty_rest_of_line ();
1130 if (current_poolP
== NULL
)
1133 /* Align pool as you have word accesses */
1134 /* Only make a frag if we have to ... */
1136 frag_align (2, 0, 0);
1138 record_alignment (now_seg
, 2);
1140 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1142 symbol_locate (current_poolP
, sym_name
, now_seg
,
1143 (valueT
) frag_now_fix (), frag_now
);
1144 symbol_table_insert (current_poolP
);
1146 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1148 #if defined OBJ_COFF || defined OBJ_ELF
1149 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1152 while (lit_count
< next_literal_pool_place
)
1153 /* First output the expression in the instruction to the pool */
1154 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1156 next_literal_pool_place
= 0;
1157 current_poolP
= NULL
;
1161 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1165 register long temp_fill
;
1166 long max_alignment
= 15;
1168 temp
= get_absolute_expression ();
1169 if (temp
> max_alignment
)
1170 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1173 as_bad (_("Alignment negative. 0 assumed."));
1177 if (*input_line_pointer
== ',')
1179 input_line_pointer
++;
1180 temp_fill
= get_absolute_expression ();
1188 /* Only make a frag if we HAVE to. . . */
1189 if (temp
&& !need_pass_2
)
1190 frag_align (temp
, (int) temp_fill
, 0);
1191 demand_empty_rest_of_line ();
1193 record_alignment (now_seg
, temp
);
1197 s_force_thumb (ignore
)
1200 /* If we are not already in thumb mode go into it, EVEN if
1201 the target processor does not support thumb instructions.
1202 This is used by gcc/config/arm/lib1funcs.asm for example
1203 to compile interworking support functions even if the
1204 target processor should not support interworking. */
1210 record_alignment (now_seg
, 1);
1213 demand_empty_rest_of_line ();
1217 s_thumb_func (ignore
)
1220 /* The following label is the name/address of the start of a Thumb function.
1221 We need to know this for the interworking support. */
1223 label_is_thumb_function_name
= true;
1225 demand_empty_rest_of_line ();
1228 /* Perform a .set directive, but also mark the alias as
1229 being a thumb function. */
1235 /* XXX the following is a duplicate of the code for s_set() in read.c
1236 We cannot just call that code as we need to get at the symbol that
1238 register char * name
;
1239 register char delim
;
1240 register char * end_name
;
1241 register symbolS
* symbolP
;
1244 * Especial apologies for the random logic:
1245 * this just grew, and could be parsed much more simply!
1248 name
= input_line_pointer
;
1249 delim
= get_symbol_end ();
1250 end_name
= input_line_pointer
;
1255 if (*input_line_pointer
!= ',')
1258 as_bad (_("Expected comma after name \"%s\""), name
);
1260 ignore_rest_of_line ();
1264 input_line_pointer
++;
1267 if (name
[0] == '.' && name
[1] == '\0')
1269 /* XXX - this should not happen to .thumb_set */
1273 if ((symbolP
= symbol_find (name
)) == NULL
1274 && (symbolP
= md_undefined_symbol (name
)) == NULL
)
1277 /* When doing symbol listings, play games with dummy fragments living
1278 outside the normal fragment chain to record the file and line info
1280 if (listing
& LISTING_SYMBOLS
)
1282 extern struct list_info_struct
* listing_tail
;
1283 fragS
* dummy_frag
= (fragS
*) xmalloc (sizeof(fragS
));
1284 memset (dummy_frag
, 0, sizeof(fragS
));
1285 dummy_frag
->fr_type
= rs_fill
;
1286 dummy_frag
->line
= listing_tail
;
1287 symbolP
= symbol_new (name
, undefined_section
, 0, dummy_frag
);
1288 dummy_frag
->fr_symbol
= symbolP
;
1292 symbolP
= symbol_new (name
, undefined_section
, 0, &zero_address_frag
);
1295 /* "set" symbols are local unless otherwise specified. */
1296 SF_SET_LOCAL (symbolP
);
1297 #endif /* OBJ_COFF */
1298 } /* make a new symbol */
1300 symbol_table_insert (symbolP
);
1305 && S_IS_DEFINED (symbolP
)
1306 && S_GET_SEGMENT (symbolP
) != reg_section
)
1307 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP
));
1309 pseudo_set (symbolP
);
1311 demand_empty_rest_of_line ();
1313 /* XXX now we come to the Thumb specific bit of code. */
1315 THUMB_SET_FUNC (symbolP
, 1);
1316 ARM_SET_THUMB (symbolP
, 1);
1317 ARM_SET_INTERWORK (symbolP
, support_interwork
);
1320 /* If we change section we must dump the literal pool first. */
1325 if (now_seg
!= text_section
)
1335 if (flag_readonly_data_in_text
)
1337 if (now_seg
!= text_section
)
1340 else if (now_seg
!= data_section
)
1348 arm_s_section (ignore
)
1353 obj_elf_section (ignore
);
1358 opcode_select (width
)
1366 if (! (cpu_variant
& ARM_THUMB
))
1367 as_bad (_("selected processor does not support THUMB opcodes"));
1369 /* No need to force the alignment, since we will have been
1370 coming from ARM mode, which is word-aligned. */
1371 record_alignment (now_seg
, 1);
1378 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1379 as_bad (_("selected processor does not support ARM opcodes"));
1382 frag_align (2, 0, 0);
1383 record_alignment (now_seg
, 1);
1388 as_bad (_("invalid instruction size selected (%d)"), width
);
1397 demand_empty_rest_of_line ();
1405 demand_empty_rest_of_line ();
1414 temp
= get_absolute_expression ();
1419 opcode_select (temp
);
1423 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1435 inst
.error
= _("Garbage following instruction");
1439 skip_past_comma (str
)
1445 while ((c
= *p
) == ' ' || c
== ',')
1448 if (c
== ',' && comma
++)
1456 return comma
? SUCCESS
: FAIL
;
1459 /* A standard register must be given at this point. Shift is the place to
1460 put it in the instruction. */
1463 reg_required_here (str
, shift
)
1467 static char buff
[128]; /* XXX */
1469 char * start
= *str
;
1471 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1474 inst
.instruction
|= reg
<< shift
;
1478 /* Restore the start point, we may have got a reg of the wrong class. */
1481 /* In the few cases where we might be able to accept something else
1482 this error can be overridden */
1483 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1490 psr_required_here (str
, cpsr
, spsr
)
1496 char * start
= *str
;
1497 psr
= arm_psr_parse (str
);
1499 if (psr
== cpsr
|| psr
== spsr
)
1502 inst
.instruction
|= 1 << 22;
1507 /* In the few cases where we might be able to accept something else
1508 this error can be overridden */
1509 inst
.error
= _("<psr(f)> expected");
1511 /* Restore the start point. */
1517 co_proc_number (str
)
1520 int processor
, pchar
;
1522 while (**str
== ' ')
1525 /* The data sheet seems to imply that just a number on its own is valid
1526 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1528 if (**str
== 'p' || **str
== 'P')
1532 if (pchar
>= '0' && pchar
<= '9')
1534 processor
= pchar
- '0';
1535 if (**str
>= '0' && **str
<= '9')
1537 processor
= processor
* 10 + *(*str
)++ - '0';
1540 inst
.error
= _("Illegal co-processor number");
1547 inst
.error
= _("Bad or missing co-processor number");
1551 inst
.instruction
|= processor
<< 8;
1556 cp_opc_expr (str
, where
, length
)
1563 while (**str
== ' ')
1566 memset (&expr
, '\0', sizeof (expr
));
1568 if (my_get_expression (&expr
, str
))
1570 if (expr
.X_op
!= O_constant
)
1572 inst
.error
= _("bad or missing expression");
1576 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1578 inst
.error
= _("immediate co-processor expression too large");
1582 inst
.instruction
|= expr
.X_add_number
<< where
;
1587 cp_reg_required_here (str
, where
)
1592 char * start
= *str
;
1594 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1597 inst
.instruction
|= reg
<< where
;
1601 /* In the few cases where we might be able to accept something else
1602 this error can be overridden */
1603 inst
.error
= _("Co-processor register expected");
1605 /* Restore the start point */
1611 fp_reg_required_here (str
, where
)
1616 char * start
= *str
;
1618 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1621 inst
.instruction
|= reg
<< where
;
1625 /* In the few cases where we might be able to accept something else
1626 this error can be overridden */
1627 inst
.error
= _("Floating point register expected");
1629 /* Restore the start point */
1635 cp_address_offset (str
)
1640 while (**str
== ' ')
1643 if (! is_immediate_prefix (**str
))
1645 inst
.error
= _("immediate expression expected");
1651 if (my_get_expression (& inst
.reloc
.exp
, str
))
1654 if (inst
.reloc
.exp
.X_op
== O_constant
)
1656 offset
= inst
.reloc
.exp
.X_add_number
;
1660 inst
.error
= _("co-processor address must be word aligned");
1664 if (offset
> 1023 || offset
< -1023)
1666 inst
.error
= _("offset too large");
1671 inst
.instruction
|= INDEX_UP
;
1675 inst
.instruction
|= offset
>> 2;
1678 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1684 cp_address_required_here (str
)
1699 if ((reg
= reg_required_here (& p
, 16)) == FAIL
)
1709 if (skip_past_comma (& p
) == SUCCESS
)
1712 write_back
= WRITE_BACK
;
1716 inst
.error
= _("pc may not be used in post-increment");
1720 if (cp_address_offset (& p
) == FAIL
)
1724 pre_inc
= PRE_INDEX
| INDEX_UP
;
1728 /* '['Rn, #expr']'[!] */
1730 if (skip_past_comma (& p
) == FAIL
)
1732 inst
.error
= _("pre-indexed expression expected");
1736 pre_inc
= PRE_INDEX
;
1738 if (cp_address_offset (& p
) == FAIL
)
1746 inst
.error
= _("missing ]");
1757 inst
.error
= _("pc may not be used with write-back");
1762 write_back
= WRITE_BACK
;
1768 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1771 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1772 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1773 inst
.reloc
.pc_rel
= 1;
1774 inst
.instruction
|= (REG_PC
<< 16);
1775 pre_inc
= PRE_INDEX
;
1778 inst
.instruction
|= write_back
| pre_inc
;
1786 unsigned long flags
;
1788 /* Do nothing really */
1789 inst
.instruction
|= flags
; /* This is pointless */
1797 unsigned long flags
;
1799 /* Only one syntax */
1803 if (reg_required_here (&str
, 12) == FAIL
)
1805 inst
.error
= bad_args
;
1809 if (skip_past_comma (&str
) == FAIL
1810 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1812 inst
.error
= _("<psr> expected");
1816 inst
.instruction
|= flags
;
1821 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1825 unsigned long flags
;
1832 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1834 inst
.instruction
|= PSR_ALL
;
1836 /* Sytax should be "<psr>, Rm" */
1837 if (skip_past_comma (&str
) == FAIL
1838 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1840 inst
.error
= bad_args
;
1846 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1847 inst
.instruction
|= PSR_FLAGS
;
1848 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1849 inst
.instruction
|= PSR_CONTROL
;
1852 inst
.error
= bad_args
;
1856 if (skip_past_comma (&str
) == FAIL
)
1858 inst
.error
= bad_args
;
1862 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1864 if ((reg
= reg_required_here (& str
, 0)) != FAIL
)
1866 /* Immediate expression */
1867 else if (is_immediate_prefix (* str
))
1872 if (my_get_expression (& inst
.reloc
.exp
, & str
))
1874 inst
.error
= _("Register or shift expression expected");
1878 if (inst
.reloc
.exp
.X_add_symbol
)
1880 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1881 inst
.reloc
.pc_rel
= 0;
1885 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1888 inst
.error
= _("Invalid constant");
1892 inst
.instruction
|= value
;
1895 flags
|= INST_IMMEDIATE
;
1899 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1905 inst
.instruction
|= flags
;
1910 /* Long Multiply Parser
1911 UMULL RdLo, RdHi, Rm, Rs
1912 SMULL RdLo, RdHi, Rm, Rs
1913 UMLAL RdLo, RdHi, Rm, Rs
1914 SMLAL RdLo, RdHi, Rm, Rs
1917 do_mull (str
, flags
)
1919 unsigned long flags
;
1921 int rdlo
, rdhi
, rm
, rs
;
1923 /* only one format "rdlo, rdhi, rm, rs" */
1927 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1929 inst
.error
= bad_args
;
1933 if (skip_past_comma (&str
) == FAIL
1934 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1936 inst
.error
= bad_args
;
1940 if (skip_past_comma (&str
) == FAIL
1941 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1943 inst
.error
= bad_args
;
1947 /* rdhi, rdlo and rm must all be different */
1948 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1949 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1951 if (skip_past_comma (&str
) == FAIL
1952 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1954 inst
.error
= bad_args
;
1958 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1960 inst
.error
= bad_pc
;
1964 inst
.instruction
|= flags
;
1972 unsigned long flags
;
1976 /* only one format "rd, rm, rs" */
1980 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1982 inst
.error
= bad_args
;
1988 inst
.error
= bad_pc
;
1992 if (skip_past_comma (&str
) == FAIL
1993 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1995 inst
.error
= bad_args
;
2001 inst
.error
= bad_pc
;
2006 as_tsktsk (_("rd and rm should be different in mul"));
2008 if (skip_past_comma (&str
) == FAIL
2009 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
2011 inst
.error
= bad_args
;
2017 inst
.error
= bad_pc
;
2021 inst
.instruction
|= flags
;
2029 unsigned long flags
;
2033 /* only one format "rd, rm, rs, rn" */
2037 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
2039 inst
.error
= bad_args
;
2045 inst
.error
= bad_pc
;
2049 if (skip_past_comma (&str
) == FAIL
2050 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
2052 inst
.error
= bad_args
;
2058 inst
.error
= bad_pc
;
2063 as_tsktsk (_("rd and rm should be different in mla"));
2065 if (skip_past_comma (&str
) == FAIL
2066 || (rd
= reg_required_here (&str
, 8)) == FAIL
2067 || skip_past_comma (&str
) == FAIL
2068 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
2070 inst
.error
= bad_args
;
2074 if (rd
== REG_PC
|| rm
== REG_PC
)
2076 inst
.error
= bad_pc
;
2080 inst
.instruction
|= flags
;
2085 /* Returns the index into fp_values of a floating point number, or -1 if
2086 not in the table. */
2088 my_get_float_expression (str
)
2091 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
2097 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
2098 /* Look for a raw floating point number */
2099 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
2100 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
2102 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2104 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2106 if (words
[j
] != fp_values
[i
][j
])
2110 if (j
== MAX_LITTLENUMS
)
2118 /* Try and parse a more complex expression, this will probably fail
2119 unless the code uses a floating point prefix (eg "0f") */
2120 save_in
= input_line_pointer
;
2121 input_line_pointer
= *str
;
2122 if (expression (&exp
) == absolute_section
2123 && exp
.X_op
== O_big
2124 && exp
.X_add_number
< 0)
2126 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2128 if (gen_to_words (words
, 5, (long)15) == 0)
2130 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2132 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2134 if (words
[j
] != fp_values
[i
][j
])
2138 if (j
== MAX_LITTLENUMS
)
2140 *str
= input_line_pointer
;
2141 input_line_pointer
= save_in
;
2148 *str
= input_line_pointer
;
2149 input_line_pointer
= save_in
;
2153 /* Return true if anything in the expression is a bignum */
2155 walk_no_bignums (sp
)
2158 if (symbol_get_value_expression (sp
)->X_op
== O_big
)
2161 if (symbol_get_value_expression (sp
)->X_add_symbol
)
2163 return (walk_no_bignums (symbol_get_value_expression (sp
)->X_add_symbol
)
2164 || (symbol_get_value_expression (sp
)->X_op_symbol
2165 && walk_no_bignums (symbol_get_value_expression (sp
)->X_op_symbol
)));
2172 my_get_expression (ep
, str
)
2179 save_in
= input_line_pointer
;
2180 input_line_pointer
= *str
;
2181 seg
= expression (ep
);
2184 if (seg
!= absolute_section
2185 && seg
!= text_section
2186 && seg
!= data_section
2187 && seg
!= bss_section
2188 && seg
!= undefined_section
)
2190 inst
.error
= _("bad_segment");
2191 *str
= input_line_pointer
;
2192 input_line_pointer
= save_in
;
2197 /* Get rid of any bignums now, so that we don't generate an error for which
2198 we can't establish a line number later on. Big numbers are never valid
2199 in instructions, which is where this routine is always called. */
2200 if (ep
->X_op
== O_big
2201 || (ep
->X_add_symbol
2202 && (walk_no_bignums (ep
->X_add_symbol
)
2204 && walk_no_bignums (ep
->X_op_symbol
)))))
2206 inst
.error
= _("Invalid constant");
2207 *str
= input_line_pointer
;
2208 input_line_pointer
= save_in
;
2212 *str
= input_line_pointer
;
2213 input_line_pointer
= save_in
;
2217 /* unrestrict should be one if <shift> <register> is permitted for this
2221 decode_shift (str
, unrestrict
)
2225 struct asm_shift
* shft
;
2229 while (**str
== ' ')
2232 for (p
= *str
; isalpha (*p
); p
++)
2237 inst
.error
= _("Shift expression expected");
2243 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2247 if (!strncmp (*str
, "rrx", 3)
2248 || !strncmp (*str
, "RRX", 3))
2251 inst
.instruction
|= shft
->value
;
2258 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2260 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2264 else if (is_immediate_prefix (* p
))
2268 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2271 /* Validate some simple #expressions */
2272 if (inst
.reloc
.exp
.X_op
== O_constant
)
2274 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2276 /* Reject operations greater than 32, or lsl #32 */
2277 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2279 inst
.error
= _("Invalid immediate shift");
2283 /* Shifts of zero should be converted to lsl (which is zero)*/
2290 /* Shifts of 32 are encoded as 0, for those shifts that
2295 inst
.instruction
|= (num
<< 7) | shft
->value
;
2300 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2301 inst
.reloc
.pc_rel
= 0;
2302 inst
.instruction
|= shft
->value
;
2308 inst
.error
= unrestrict
? _("shift requires register or #expression")
2309 : _("shift requires #expression");
2315 inst
.error
= _("Shift expression expected");
2319 /* Do those data_ops which can take a negative immediate constant */
2320 /* by altering the instuction. A bit of a hack really */
2324 by inverting the second operand, and
2327 by negating the second operand.
2330 negate_data_op (instruction
, value
)
2331 unsigned long * instruction
;
2332 unsigned long value
;
2335 unsigned long negated
, inverted
;
2337 negated
= validate_immediate (-value
);
2338 inverted
= validate_immediate (~value
);
2340 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2344 case OPCODE_SUB
: /* ADD <-> SUB */
2345 new_inst
= OPCODE_ADD
;
2350 new_inst
= OPCODE_SUB
;
2354 case OPCODE_CMP
: /* CMP <-> CMN */
2355 new_inst
= OPCODE_CMN
;
2360 new_inst
= OPCODE_CMP
;
2364 /* Now Inverted ops */
2365 case OPCODE_MOV
: /* MOV <-> MVN */
2366 new_inst
= OPCODE_MVN
;
2371 new_inst
= OPCODE_MOV
;
2375 case OPCODE_AND
: /* AND <-> BIC */
2376 new_inst
= OPCODE_BIC
;
2381 new_inst
= OPCODE_AND
;
2385 case OPCODE_ADC
: /* ADC <-> SBC */
2386 new_inst
= OPCODE_SBC
;
2391 new_inst
= OPCODE_ADC
;
2395 /* We cannot do anything */
2403 *instruction
&= OPCODE_MASK
;
2404 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2415 while (**str
== ' ')
2418 if (reg_required_here (str
, 0) != FAIL
)
2420 if (skip_past_comma (str
) == SUCCESS
)
2422 /* Shift operation on register */
2423 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2429 /* Immediate expression */
2430 if (is_immediate_prefix (**str
))
2434 if (my_get_expression (&inst
.reloc
.exp
, str
))
2437 if (inst
.reloc
.exp
.X_add_symbol
)
2439 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2440 inst
.reloc
.pc_rel
= 0;
2444 if (skip_past_comma (str
) == SUCCESS
)
2446 /* #x, y -- ie explicit rotation by Y */
2447 if (my_get_expression (&expr
, str
))
2450 if (expr
.X_op
!= O_constant
)
2452 inst
.error
= _("Constant expression expected");
2456 /* Rotate must be a multiple of 2 */
2457 if (((unsigned) expr
.X_add_number
) > 30
2458 || (expr
.X_add_number
& 1) != 0
2459 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2461 inst
.error
= _("Invalid constant");
2464 inst
.instruction
|= INST_IMMEDIATE
;
2465 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2466 inst
.instruction
|= expr
.X_add_number
<< 7;
2470 /* Implicit rotation, select a suitable one */
2471 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2475 /* Can't be done, perhaps the code reads something like
2476 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2477 if ((value
= negate_data_op (&inst
.instruction
,
2478 inst
.reloc
.exp
.X_add_number
))
2481 inst
.error
= _("Invalid constant");
2486 inst
.instruction
|= value
;
2489 inst
.instruction
|= INST_IMMEDIATE
;
2494 inst
.error
= _("Register or shift expression expected");
2503 while (**str
== ' ')
2506 if (fp_reg_required_here (str
, 0) != FAIL
)
2510 /* Immediate expression */
2511 if (*((*str
)++) == '#')
2516 while (**str
== ' ')
2519 /* First try and match exact strings, this is to guarantee that
2520 some formats will work even for cross assembly */
2522 for (i
= 0; fp_const
[i
]; i
++)
2524 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2528 *str
+= strlen (fp_const
[i
]);
2529 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2531 inst
.instruction
|= i
+ 8;
2538 /* Just because we didn't get a match doesn't mean that the
2539 constant isn't valid, just that it is in a format that we
2540 don't automatically recognize. Try parsing it with
2541 the standard expression routines. */
2542 if ((i
= my_get_float_expression (str
)) >= 0)
2544 inst
.instruction
|= i
+ 8;
2548 inst
.error
= _("Invalid floating point immediate expression");
2551 inst
.error
= _("Floating point register or immediate expression expected");
2557 do_arit (str
, flags
)
2559 unsigned long flags
;
2564 if (reg_required_here (&str
, 12) == FAIL
2565 || skip_past_comma (&str
) == FAIL
2566 || reg_required_here (&str
, 16) == FAIL
2567 || skip_past_comma (&str
) == FAIL
2568 || data_op2 (&str
) == FAIL
)
2571 inst
.error
= bad_args
;
2575 inst
.instruction
|= flags
;
2583 unsigned long flags
;
2585 /* This is a pseudo-op of the form "adr rd, label" to be converted
2586 into a relative address of the form "add rd, pc, #label-.-8" */
2591 if (reg_required_here (&str
, 12) == FAIL
2592 || skip_past_comma (&str
) == FAIL
2593 || my_get_expression (&inst
.reloc
.exp
, &str
))
2596 inst
.error
= bad_args
;
2599 /* Frag hacking will turn this into a sub instruction if the offset turns
2600 out to be negative. */
2601 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2602 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2603 inst
.reloc
.pc_rel
= 1;
2604 inst
.instruction
|= flags
;
2612 unsigned long flags
;
2617 if (reg_required_here (&str
, 16) == FAIL
)
2620 inst
.error
= bad_args
;
2624 if (skip_past_comma (&str
) == FAIL
2625 || data_op2 (&str
) == FAIL
)
2628 inst
.error
= bad_args
;
2632 inst
.instruction
|= flags
;
2633 if ((flags
& 0x0000f000) == 0)
2634 inst
.instruction
|= CONDS_BIT
;
2643 unsigned long flags
;
2648 if (reg_required_here (&str
, 12) == FAIL
)
2651 inst
.error
= bad_args
;
2655 if (skip_past_comma (&str
) == FAIL
2656 || data_op2 (&str
) == FAIL
)
2659 inst
.error
= bad_args
;
2663 inst
.instruction
|= flags
;
2669 ldst_extend (str
, hwse
)
2680 if (my_get_expression (& inst
.reloc
.exp
, str
))
2683 if (inst
.reloc
.exp
.X_op
== O_constant
)
2685 int value
= inst
.reloc
.exp
.X_add_number
;
2687 if ((hwse
&& (value
< -255 || value
> 255))
2688 || (value
< -4095 || value
> 4095))
2690 inst
.error
= _("address offset too large");
2700 /* Halfword and signextension instructions have the
2701 immediate value split across bits 11..8 and bits 3..0 */
2703 inst
.instruction
|= add
| HWOFFSET_IMM
| ((value
>> 4) << 8) | (value
& 0xF);
2705 inst
.instruction
|= add
| value
;
2711 inst
.instruction
|= HWOFFSET_IMM
;
2712 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2715 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2716 inst
.reloc
.pc_rel
= 0;
2721 add
= 0; /* and fall through */
2723 (*str
)++; /* and fall through */
2725 if (reg_required_here (str
, 0) == FAIL
)
2729 inst
.instruction
|= add
;
2732 inst
.instruction
|= add
| OFFSET_REG
;
2733 if (skip_past_comma (str
) == SUCCESS
)
2734 return decode_shift (str
, SHIFT_RESTRICT
);
2742 do_ldst (str
, flags
)
2744 unsigned long flags
;
2751 /* This is not ideal, but it is the simplest way of dealing with the
2752 ARM7T halfword instructions (since they use a different
2753 encoding, but the same mnemonic): */
2754 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 || symbol_constant_p (fixP
->fx_addsy
))
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 (%lx) after fixup\n"),
5321 (unsigned long) value
);
5325 newimm
|= (temp
& 0xfffff000);
5326 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5329 case BFD_RELOC_ARM_OFFSET_IMM
:
5331 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5333 as_bad (_("bad immediate value for offset (%ld)"), (long) value
);
5339 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5340 newval
&= 0xff7ff000;
5341 newval
|= value
| (sign
? INDEX_UP
: 0);
5342 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5345 case BFD_RELOC_ARM_OFFSET_IMM8
:
5346 case BFD_RELOC_ARM_HWLITERAL
:
5348 if ((value
= validate_offset_imm (value
, 1)) == FAIL
)
5350 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5351 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5352 _("invalid literal constant: pool needs to be closer\n"));
5354 as_bad (_("bad immediate value for offset (%ld)"), (long) value
);
5361 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5362 newval
&= 0xff7ff0f0;
5363 newval
|= ((value
>> 4) << 8) | (value
& 0xf) | (sign
? INDEX_UP
: 0);
5364 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5367 case BFD_RELOC_ARM_LITERAL
:
5372 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5374 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5375 _("invalid literal constant: pool needs to be closer\n"));
5379 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5380 newval
&= 0xff7ff000;
5381 newval
|= value
| (sign
? INDEX_UP
: 0);
5382 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5385 case BFD_RELOC_ARM_SHIFT_IMM
:
5386 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5387 if (((unsigned long) value
) > 32
5389 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5391 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5392 _("shift expression is too large"));
5397 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5398 else if (value
== 32)
5400 newval
&= 0xfffff07f;
5401 newval
|= (value
& 0x1f) << 7;
5402 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5405 case BFD_RELOC_ARM_SWI
:
5406 if (arm_data
->thumb_mode
)
5408 if (((unsigned long) value
) > 0xff)
5409 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5410 _("Invalid swi expression"));
5411 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5413 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5417 if (((unsigned long) value
) > 0x00ffffff)
5418 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5419 _("Invalid swi expression"));
5420 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5422 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5426 case BFD_RELOC_ARM_MULTI
:
5427 if (((unsigned long) value
) > 0xffff)
5428 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5429 _("Invalid expression in load/store multiple"));
5430 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5431 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5434 case BFD_RELOC_ARM_PCREL_BRANCH
:
5435 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5439 value
= fixP
->fx_offset
;
5441 value
= (value
>> 2) & 0x00ffffff;
5442 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5443 newval
= value
| (newval
& 0xff000000);
5444 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5447 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5448 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5450 addressT diff
= (newval
& 0xff) << 1;
5455 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5456 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5457 _("Branch out of range"));
5458 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5460 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5463 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5464 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5466 addressT diff
= (newval
& 0x7ff) << 1;
5471 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5472 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5473 _("Branch out of range"));
5474 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5476 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5479 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5484 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5485 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5486 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5487 if (diff
& 0x400000)
5490 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5491 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5492 _("Branch with link out of range"));
5494 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5495 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5496 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5497 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5502 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5503 md_number_to_chars (buf
, value
, 1);
5505 else if (!target_oabi
)
5507 value
= fixP
->fx_offset
;
5508 md_number_to_chars (buf
, value
, 1);
5514 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5515 md_number_to_chars (buf
, value
, 2);
5517 else if (!target_oabi
)
5519 value
= fixP
->fx_offset
;
5520 md_number_to_chars (buf
, value
, 2);
5526 case BFD_RELOC_ARM_GOT32
:
5527 case BFD_RELOC_ARM_GOTOFF
:
5528 md_number_to_chars (buf
, 0, 4);
5534 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5535 md_number_to_chars (buf
, value
, 4);
5537 else if (!target_oabi
)
5539 value
= fixP
->fx_offset
;
5540 md_number_to_chars (buf
, value
, 4);
5546 case BFD_RELOC_ARM_PLT32
:
5547 /* It appears the instruction is fully prepared at this point. */
5551 case BFD_RELOC_ARM_GOTPC
:
5552 md_number_to_chars (buf
, value
, 4);
5555 case BFD_RELOC_ARM_CP_OFF_IMM
:
5557 if (value
< -1023 || value
> 1023 || (value
& 3))
5558 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5559 _("Illegal value for co-processor offset"));
5562 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5563 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5564 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5567 case BFD_RELOC_ARM_THUMB_OFFSET
:
5568 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5569 /* Exactly what ranges, and where the offset is inserted depends on
5570 the type of instruction, we can establish this from the top 4 bits */
5571 switch (newval
>> 12)
5573 case 4: /* PC load */
5574 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5575 forced to zero for these loads, so we will need to round
5576 up the offset if the instruction address is not word
5577 aligned (since the final address produced must be, and
5578 we can only describe word-aligned immediate offsets). */
5580 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5581 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5582 _("Invalid offset, target not word aligned (0x%08X)"),
5583 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5585 if ((value
+ 2) & ~0x3fe)
5586 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5587 _("Invalid offset"));
5589 /* Round up, since pc will be rounded down. */
5590 newval
|= (value
+ 2) >> 2;
5593 case 9: /* SP load/store */
5595 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5596 _("Invalid offset"));
5597 newval
|= value
>> 2;
5600 case 6: /* Word load/store */
5602 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5603 _("Invalid offset"));
5604 newval
|= value
<< 4; /* 6 - 2 */
5607 case 7: /* Byte load/store */
5609 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5610 _("Invalid offset"));
5611 newval
|= value
<< 6;
5614 case 8: /* Halfword load/store */
5616 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5617 _("Invalid offset"));
5618 newval
|= value
<< 5; /* 6 - 1 */
5622 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5623 "Unable to process relocation for thumb opcode: %lx",
5624 (unsigned long) newval
);
5627 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5630 case BFD_RELOC_ARM_THUMB_ADD
:
5631 /* This is a complicated relocation, since we use it for all of
5632 the following immediate relocations:
5635 9bit ADD/SUB SP word-aligned
5636 10bit ADD PC/SP word-aligned
5638 The type of instruction being processed is encoded in the
5644 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5646 int rd
= (newval
>> 4) & 0xf;
5647 int rs
= newval
& 0xf;
5648 int subtract
= newval
& 0x8000;
5653 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5654 _("Invalid immediate for stack address calculation"));
5655 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5656 newval
|= value
>> 2;
5658 else if (rs
== REG_PC
|| rs
== REG_SP
)
5662 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5663 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5664 (unsigned long) value
);
5665 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5667 newval
|= value
>> 2;
5672 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5673 _("Invalid 8bit immediate"));
5674 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5675 newval
|= (rd
<< 8) | value
;
5680 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5681 _("Invalid 3bit immediate"));
5682 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5683 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5686 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5689 case BFD_RELOC_ARM_THUMB_IMM
:
5690 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5691 switch (newval
>> 11)
5693 case 0x04: /* 8bit immediate MOV */
5694 case 0x05: /* 8bit immediate CMP */
5695 if (value
< 0 || value
> 255)
5696 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5697 _("Invalid immediate: %ld is too large"),
5705 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5708 case BFD_RELOC_ARM_THUMB_SHIFT
:
5709 /* 5bit shift value (0..31) */
5710 if (value
< 0 || value
> 31)
5711 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5712 _("Illegal Thumb shift value: %ld"), (long) value
);
5713 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5714 newval
|= value
<< 6;
5715 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5718 case BFD_RELOC_VTABLE_INHERIT
:
5719 case BFD_RELOC_VTABLE_ENTRY
:
5723 case BFD_RELOC_NONE
:
5725 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5726 _("Bad relocation fixup type (%d)\n"), fixP
->fx_r_type
);
5732 /* Translate internal representation of relocation info to BFD target
5735 tc_gen_reloc (section
, fixp
)
5740 bfd_reloc_code_real_type code
;
5742 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5744 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
5745 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
5746 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5748 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5750 if (fixp
->fx_pcrel
== 0)
5751 reloc
->addend
= fixp
->fx_offset
;
5753 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5755 reloc
->addend
= fixp
->fx_offset
;
5758 switch (fixp
->fx_r_type
)
5763 code
= BFD_RELOC_8_PCREL
;
5770 code
= BFD_RELOC_16_PCREL
;
5777 code
= BFD_RELOC_32_PCREL
;
5781 case BFD_RELOC_ARM_PCREL_BRANCH
:
5783 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5784 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5785 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5786 case BFD_RELOC_VTABLE_ENTRY
:
5787 case BFD_RELOC_VTABLE_INHERIT
:
5788 code
= fixp
->fx_r_type
;
5791 case BFD_RELOC_ARM_LITERAL
:
5792 case BFD_RELOC_ARM_HWLITERAL
:
5793 /* If this is called then the a literal has been referenced across
5794 a section boundry - possibly due to an implicit dump */
5795 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5796 _("Literal referenced across section boundry (Implicit dump?)"));
5799 case BFD_RELOC_ARM_GOTPC
:
5800 assert (fixp
->fx_pcrel
!= 0);
5801 code
= fixp
->fx_r_type
;
5802 code
= BFD_RELOC_32_PCREL
;
5806 case BFD_RELOC_ARM_GOT32
:
5807 case BFD_RELOC_ARM_GOTOFF
:
5808 case BFD_RELOC_ARM_PLT32
:
5809 code
= fixp
->fx_r_type
;
5813 case BFD_RELOC_ARM_IMMEDIATE
:
5814 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5815 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5819 case BFD_RELOC_ARM_OFFSET_IMM
:
5820 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5821 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5828 switch (fixp
->fx_r_type
)
5830 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5831 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5832 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5833 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5834 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5835 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5836 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5837 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5838 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5839 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5840 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5841 default: type
= "<unknown>"; break;
5843 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5844 _("Can not represent %s relocation in this object file format (%d)"),
5845 type
, fixp
->fx_pcrel
);
5851 if (code
== BFD_RELOC_32_PCREL
5853 && fixp
->fx_addsy
== GOT_symbol
)
5855 code
= BFD_RELOC_ARM_GOTPC
;
5856 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5860 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5862 if (reloc
->howto
== NULL
)
5864 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5865 _("Can not represent %s relocation in this object file format"),
5866 bfd_get_reloc_code_name (code
));
5874 md_estimate_size_before_relax (fragP
, segtype
)
5878 as_fatal (_("md_estimate_size_before_relax\n"));
5890 as_bad (inst
.error
);
5894 to
= frag_more (inst
.size
);
5895 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
5897 assert (inst
.size
== (2 * THUMB_SIZE
));
5898 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
5899 md_number_to_chars (to
+ 2, inst
.instruction
, THUMB_SIZE
);
5902 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
5904 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5905 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
5906 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
5921 /* Align the instruction.
5922 This may not be the right thing to do but ... */
5923 /* arm_align (2, 0); */
5924 listing_prev_line (); /* Defined in listing.h */
5926 /* Align the previous label if needed. */
5927 if (last_label_seen
!= NULL
)
5929 symbol_set_frag (last_label_seen
, frag_now
);
5930 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
5931 S_SET_SEGMENT (last_label_seen
, now_seg
);
5934 memset (&inst
, '\0', sizeof (inst
));
5935 inst
.reloc
.type
= BFD_RELOC_NONE
;
5938 str
++; /* Skip leading white space */
5940 /* Scan up to the end of the op-code, which must end in white space or
5942 for (start
= p
= str
; *p
!= '\0'; p
++)
5948 as_bad (_("No operator -- statement `%s'\n"), str
);
5954 CONST
struct thumb_opcode
*opcode
;
5958 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
5962 inst
.instruction
= opcode
->value
;
5963 inst
.size
= opcode
->size
;
5964 (*opcode
->parms
)(p
);
5965 output_inst (start
);
5971 CONST
struct asm_opcode
*opcode
;
5973 inst
.size
= INSN_SIZE
;
5974 /* p now points to the end of the opcode, probably white space, but we
5975 have to break the opcode up in case it contains condionals and flags;
5976 keep trying with progressively smaller basic instructions until one
5977 matches, or we run out of opcode. */
5978 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
5979 for (; q
!= str
; q
--)
5983 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
5985 if (opcode
&& opcode
->template)
5987 unsigned long flag_bits
= 0;
5990 /* Check that this instruction is supported for this CPU */
5991 if ((opcode
->variants
& cpu_variant
) == 0)
5994 inst
.instruction
= opcode
->value
;
5995 if (q
== p
) /* Just a simple opcode */
5997 if (opcode
->comp_suffix
!= 0)
5998 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
5999 opcode
->comp_suffix
);
6002 inst
.instruction
|= COND_ALWAYS
;
6003 (*opcode
->parms
)(q
, 0);
6005 output_inst (start
);
6009 /* Now check for a conditional */
6013 CONST
struct asm_cond
*cond
;
6017 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
6021 if (cond
->value
== 0xf0000000)
6023 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6025 inst
.instruction
|= cond
->value
;
6029 inst
.instruction
|= COND_ALWAYS
;
6032 inst
.instruction
|= COND_ALWAYS
;
6034 /* if there is a compulsory suffix, it should come here, before
6035 any optional flags. */
6036 if (opcode
->comp_suffix
)
6038 CONST
char *s
= opcode
->comp_suffix
;
6050 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
6051 opcode
->comp_suffix
);
6058 /* The remainder, if any should now be flags for the instruction;
6059 Scan these checking each one found with the opcode. */
6063 CONST
struct asm_flg
*flag
= opcode
->flags
;
6072 for (flagno
= 0; flag
[flagno
].template; flagno
++)
6074 if (streq (r
, flag
[flagno
].template))
6076 flag_bits
|= flag
[flagno
].set_bits
;
6082 if (! flag
[flagno
].template)
6089 (*opcode
->parms
) (p
, flag_bits
);
6090 output_inst (start
);
6099 /* It wasn't an instruction, but it might be a register alias of the form
6109 if (*q
&& !strncmp (q
, ".req ", 4))
6112 char * copy_of_str
= str
;
6119 for (r
= q
; *r
!= '\0'; r
++)
6129 regnum
= arm_reg_parse (& q
);
6132 reg
= arm_reg_parse (& str
);
6138 insert_reg_alias (str
, regnum
);
6142 as_warn (_("register '%s' does not exist\n"), q
);
6145 else if (regnum
!= FAIL
)
6148 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
6150 /* Do not warn abpout redefinitions to the same alias. */
6153 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6157 as_warn (_("ignoring incomplete .req pseuso op"));
6164 as_bad (_("bad instruction `%s'"), start
);
6169 * Invocation line includes a switch not recognized by the base assembler.
6170 * See if it's a processor-specific option. These are:
6171 * Cpu variants, the arm part is optional:
6172 * -m[arm]1 Currently not supported.
6173 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6174 * -m[arm]3 Arm 3 processor
6175 * -m[arm]6[xx], Arm 6 processors
6176 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6177 * -m8[10] Arm 8 processors
6178 * -m9[20][tdmi] Arm 9 processors
6179 * -mstrongarm[110[0]] StrongARM processors
6180 * -mall All (except the ARM1)
6182 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6183 * -mfpe-old (No float load/store multiples)
6184 * -mno-fpu Disable all floating point instructions
6185 * Run-time endian selection:
6186 * -EB big endian cpu
6187 * -EL little endian cpu
6188 * ARM Procedure Calling Standard:
6189 * -mapcs-32 32 bit APCS
6190 * -mapcs-26 26 bit APCS
6191 * -mapcs-float Pass floats in float regs
6192 * -mapcs-reentrant Position independent code
6193 * -mthumb-interwork Code supports Arm/Thumb interworking
6194 * -moabi Old ELF ABI
6197 CONST
char * md_shortopts
= "m:k";
6198 struct option md_longopts
[] =
6200 #ifdef ARM_BI_ENDIAN
6201 #define OPTION_EB (OPTION_MD_BASE + 0)
6202 {"EB", no_argument
, NULL
, OPTION_EB
},
6203 #define OPTION_EL (OPTION_MD_BASE + 1)
6204 {"EL", no_argument
, NULL
, OPTION_EL
},
6206 #define OPTION_OABI (OPTION_MD_BASE +2)
6207 {"oabi", no_argument
, NULL
, OPTION_OABI
},
6210 {NULL
, no_argument
, NULL
, 0}
6212 size_t md_longopts_size
= sizeof (md_longopts
);
6215 md_parse_option (c
, arg
)
6223 #ifdef ARM_BI_ENDIAN
6225 target_big_endian
= 1;
6228 target_big_endian
= 0;
6236 if (streq (str
, "fpa10"))
6237 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
6238 else if (streq (str
, "fpa11"))
6239 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
6240 else if (streq (str
, "fpe-old"))
6241 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
6247 if (streq (str
, "no-fpu"))
6248 cpu_variant
&= ~FPU_ALL
;
6253 if (streq (str
, "oabi"))
6259 /* Limit assembler to generating only Thumb instructions: */
6260 if (streq (str
, "thumb"))
6262 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6263 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6266 else if (streq (str
, "thumb-interwork"))
6268 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
| ARM_ARCHv4
;
6269 #if defined OBJ_COFF || defined OBJ_ELF
6270 support_interwork
= true;
6278 if (streq (str
, "all"))
6280 cpu_variant
= ARM_ALL
| FPU_ALL
;
6283 #if defined OBJ_COFF || defined OBJ_ELF
6284 if (! strncmp (str
, "apcs-", 5))
6286 /* GCC passes on all command line options starting "-mapcs-..."
6287 to us, so we must parse them here. */
6291 if (streq (str
, "32"))
6293 uses_apcs_26
= false;
6296 else if (streq (str
, "26"))
6298 uses_apcs_26
= true;
6301 else if (streq (str
, "frame"))
6303 /* Stack frames are being generated - does not affect
6307 else if (streq (str
, "stack-check"))
6309 /* Stack checking is being performed - does not affect
6310 linkage, but does require that the functions
6311 __rt_stkovf_split_small and __rt_stkovf_split_big be
6312 present in the final link. */
6316 else if (streq (str
, "float"))
6318 /* Floating point arguments are being passed in the floating
6319 point registers. This does affect linking, since this
6320 version of the APCS is incompatible with the version that
6321 passes floating points in the integer registers. */
6323 uses_apcs_float
= true;
6326 else if (streq (str
, "reentrant"))
6328 /* Reentrant code has been generated. This does affect
6329 linking, since there is no point in linking reentrant/
6330 position independent code with absolute position code. */
6335 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6339 /* Strip off optional "arm" */
6340 if (! strncmp (str
, "arm", 3))
6346 if (streq (str
, "1"))
6347 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6353 if (streq (str
, "2"))
6354 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6355 else if (streq (str
, "250"))
6356 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6362 if (streq (str
, "3"))
6363 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6369 switch (strtol (str
, NULL
, 10))
6376 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6384 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6396 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6402 cpu_variant
|= (ARM_THUMB
| ARM_ARCHv4
);
6406 cpu_variant
|= ARM_LONGMUL
;
6409 case 'f': /* fe => fp enabled cpu. */
6415 case 'c': /* Left over from 710c processor name. */
6416 case 'd': /* Debug */
6417 case 'i': /* Embedded ICE */
6418 /* Included for completeness in ARM processor naming. */
6428 if (streq (str
, "8") || streq (str
, "810"))
6429 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCHv4
| ARM_LONGMUL
;
6435 if (streq (str
, "9"))
6436 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
| ARM_THUMB
;
6437 else if (streq (str
, "920"))
6438 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
;
6439 else if (streq (str
, "920t"))
6440 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
| ARM_THUMB
;
6441 else if (streq (str
, "9tdmi"))
6442 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_9
| ARM_ARCHv4
| ARM_LONGMUL
| ARM_THUMB
;
6448 if (streq (str
, "strongarm")
6449 || streq (str
, "strongarm110")
6450 || streq (str
, "strongarm1100"))
6451 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_8
| ARM_ARCHv4
| ARM_LONGMUL
;
6457 /* Select variant based on architecture rather than processor */
6463 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6464 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6465 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6470 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6474 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6476 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6481 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCHv4
;
6485 case 't': cpu_variant
|= ARM_THUMB
; break;
6487 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6492 as_bad (_("Invalid architecture variant -m%s"), arg
);
6499 as_bad (_("Invalid processor variant -m%s"), arg
);
6522 ARM Specific Assembler Options:\n\
6523 -m[arm][<processor name>] select processor variant\n\
6524 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
6525 -mthumb only allow Thumb instructions\n\
6526 -mthumb-interwork mark the assembled code as supporting interworking\n\
6527 -mall allow any instruction\n\
6528 -mfpa10, -mfpa11 select floating point architecture\n\
6529 -mfpe-old don't allow floating-point multiple instructions\n\
6530 -mno-fpu don't allow any floating-point instructions.\n"));
6533 -k generate PIC code.\n"));
6534 #if defined OBJ_COFF || defined OBJ_ELF
6537 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6540 -mapcs-float floating point args are passed in FP regs\n"));
6543 -mapcs-reentrant the code is position independent/reentrant\n"));
6548 -moabi support the old ELF ABI\n"));
6550 #ifdef ARM_BI_ENDIAN
6553 -EB assemble code for a big endian cpu\n\
6554 -EL assemble code for a little endian cpu\n"));
6558 /* We need to be able to fix up arbitrary expressions in some statements.
6559 This is so that we can handle symbols that are an arbitrary distance from
6560 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6561 which returns part of an address in a form which will be valid for
6562 a data instruction. We do this by pushing the expression into a symbol
6563 in the expr_section, and creating a fix for that. */
6566 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6575 arm_fix_data
* arm_data
;
6583 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6587 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6592 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6593 arm_data
= (arm_fix_data
*) obstack_alloc (& notes
, sizeof (arm_fix_data
));
6594 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6595 arm_data
->thumb_mode
= thumb_mode
;
6602 * This fix_new is called by cons via TC_CONS_FIX_NEW
6604 * We check the expression to see if it is of the form
6605 * __GLOBAL_OFFSET_TABLE + ???
6606 * If it is then this is a PC relative reference to the GOT.
6613 * .word __GLOBAL_OFFSET_TABLE + (. - (L2 + 4))
6615 * In this case use a reloc type BFD_RELOC_ARM_GOTPC instead of the
6616 * normal BFD_RELOC_{16,32,64}
6620 cons_fix_new_arm (frag
, where
, size
, exp
)
6626 bfd_reloc_code_real_type type
;
6631 * @@ Should look at CPU word size.
6636 type
= BFD_RELOC_16
;
6640 type
= BFD_RELOC_32
;
6643 type
= BFD_RELOC_64
;
6647 /* Look for possible GOTPC reloc */
6650 * Look for pic assembler and 'undef symbol + expr symbol' expression
6651 * and a 32 bit size.
6654 fix_new_exp (frag
, where
, (int) size
, exp
, pcrel
, type
);
6657 /* A good place to do this, although this was probably not intended
6658 * for this kind of use. We need to dump the literal pool before
6659 * references are made to a null symbol pointer. */
6663 if (current_poolP
!= NULL
)
6665 subseg_set (text_section
, 0); /* Put it at the end of text section */
6667 listing_prev_line ();
6672 arm_start_line_hook ()
6674 last_label_seen
= NULL
;
6678 arm_frob_label (sym
)
6681 last_label_seen
= sym
;
6683 ARM_SET_THUMB (sym
, thumb_mode
);
6685 #if defined OBJ_COFF || defined OBJ_ELF
6686 ARM_SET_INTERWORK (sym
, support_interwork
);
6689 if (label_is_thumb_function_name
)
6691 /* When the address of a Thumb function is taken the bottom
6692 bit of that address should be set. This will allow
6693 interworking between Arm and Thumb functions to work
6696 THUMB_SET_FUNC (sym
, 1);
6698 label_is_thumb_function_name
= false;
6702 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6706 arm_adjust_symtab ()
6711 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6713 if (ARM_IS_THUMB (sym
))
6715 if (THUMB_IS_FUNC (sym
))
6717 /* Mark the symbol as a Thumb function. */
6718 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6719 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6720 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6722 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6723 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6725 as_bad (_("%s: unexpected function type: %d"),
6726 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6728 else switch (S_GET_STORAGE_CLASS (sym
))
6731 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6734 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6737 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6739 default: /* do nothing */
6744 if (ARM_IS_INTERWORK (sym
))
6745 coffsymbol (symbol_get_bfdsym (sym
))->native
->u
.syment
.n_flags
= 0xFF;
6750 elf_symbol_type
* elf_sym
;
6753 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6755 if (ARM_IS_THUMB (sym
))
6757 if (THUMB_IS_FUNC (sym
))
6759 elf_sym
= elf_symbol (symbol_get_bfdsym (sym
));
6760 bind
= ELF_ST_BIND (elf_sym
);
6761 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6771 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6773 *input_line_pointer
= '/';
6774 input_line_pointer
+= 5;
6775 *input_line_pointer
= 0;
6783 arm_canonicalize_symbol_name (name
)
6788 if (thumb_mode
&& (len
= strlen (name
)) > 5
6789 && streq (name
+ len
- 5, "/data"))
6791 *(name
+ len
- 5) = 0;
6798 arm_validate_fix (fixP
)
6801 /* If the destination of the branch is a defined symbol which does not have
6802 the THUMB_FUNC attribute, then we must be calling a function which has
6803 the (interfacearm) attribute. We look for the Thumb entry point to that
6804 function and change the branch to refer to that function instead. */
6805 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6806 && fixP
->fx_addsy
!= NULL
6807 && S_IS_DEFINED (fixP
->fx_addsy
)
6808 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6810 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6818 /* Relocations against Thumb function names must be left unadjusted,
6819 so that the linker can use this information to correctly set the
6820 bottom bit of their addresses. The MIPS version of this function
6821 also prevents relocations that are mips-16 specific, but I do not
6822 know why it does this.
6825 There is one other problem that ought to be addressed here, but
6826 which currently is not: Taking the address of a label (rather
6827 than a function) and then later jumping to that address. Such
6828 addresses also ought to have their bottom bit set (assuming that
6829 they reside in Thumb code), but at the moment they will not. */
6832 arm_fix_adjustable (fixP
)
6836 if (fixP
->fx_addsy
== NULL
)
6839 /* Prevent all adjustments to global symbols. */
6840 if (S_IS_EXTERN (fixP
->fx_addsy
))
6843 if (S_IS_WEAK (fixP
->fx_addsy
))
6846 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6847 && fixP
->fx_subsy
== NULL
)
6850 /* We need the symbol name for the VTABLE entries */
6851 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6852 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6859 elf32_arm_target_format ()
6861 if (target_big_endian
)
6863 return "elf32-bigarm-oabi";
6865 return "elf32-bigarm";
6868 return "elf32-littlearm-oabi";
6870 return "elf32-littlearm";
6874 armelf_frob_symbol (symp
, puntp
)
6878 elf_frob_symbol (symp
, puntp
);
6882 arm_force_relocation (fixp
)
6885 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6886 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6887 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
6893 static bfd_reloc_code_real_type
6903 bfd_reloc_code_real_type reloc
;
6907 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
6908 MAP ("(got)", BFD_RELOC_ARM_GOT32
),
6909 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF
),
6910 /* ScottB: Jan 30, 1998 */
6911 /* Added support for parsing "var(PLT)" branch instructions */
6912 /* generated by GCC for PLT relocs */
6913 MAP ("(plt)", BFD_RELOC_ARM_PLT32
),
6914 NULL
, 0, BFD_RELOC_UNUSED
6918 for (i
= 0, ip
= input_line_pointer
;
6919 i
< sizeof (id
) && (isalnum (*ip
) || ispunct (*ip
));
6921 id
[i
] = tolower (*ip
);
6923 for (i
= 0; reloc_map
[i
].str
; i
++)
6924 if (strncmp (id
, reloc_map
[i
].str
, reloc_map
[i
].len
) == 0)
6927 input_line_pointer
+= reloc_map
[i
].len
;
6929 return reloc_map
[i
].reloc
;
6933 s_arm_elf_cons (nbytes
)
6938 #ifdef md_flush_pending_output
6939 md_flush_pending_output ();
6942 if (is_it_end_of_statement ())
6944 demand_empty_rest_of_line ();
6948 #ifdef md_cons_align
6949 md_cons_align (nbytes
);
6954 bfd_reloc_code_real_type reloc
;
6958 if (exp
.X_op
== O_symbol
6959 && * input_line_pointer
== '('
6960 && (reloc
= arm_parse_reloc()) != BFD_RELOC_UNUSED
)
6962 reloc_howto_type
* howto
= bfd_reloc_type_lookup (stdoutput
, reloc
);
6963 int size
= bfd_get_reloc_size (howto
);
6966 as_bad ("%s relocations do not fit in %d bytes", howto
->name
, nbytes
);
6969 register char * p
= frag_more ((int) nbytes
);
6970 int offset
= nbytes
- size
;
6972 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
+ offset
, size
,
6977 emit_expr (& exp
, (unsigned int) nbytes
);
6979 while (*input_line_pointer
++ == ',');
6981 input_line_pointer
--; /* Put terminator back into stream. */
6982 demand_empty_rest_of_line ();
6985 #endif /* OBJ_ELF */