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_CPU_MASK 0x0000000f
48 /* The following bitmasks control CPU extensions (ARM7 onwards): */
49 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
50 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
51 #define ARM_THUMB 0x00000040 /* allow BX instruction */
53 #define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
55 /* Some useful combinations: */
56 #define ARM_ANY 0x00ffffff
57 #define ARM_2UP 0x00fffffe
58 #define ARM_ALL ARM_2UP /* Not arm1 only */
59 #define ARM_3UP 0x00fffffc
60 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
62 #define FPU_CORE 0x80000000
63 #define FPU_FPA10 0x40000000
64 #define FPU_FPA11 0x40000000
67 /* Some useful combinations */
68 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
69 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
74 #define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB)
76 #define CPU_DEFAULT ARM_ALL
81 #define FPU_DEFAULT FPU_ALL
84 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
85 static int target_oabi
= 0;
87 #if defined OBJ_COFF || defined OBJ_ELF
88 /* Flags stored in private area of BFD structure */
89 static boolean uses_apcs_26
= false;
90 static boolean support_interwork
= false;
91 static boolean uses_apcs_float
= false;
92 static boolean pic_code
= false;
95 /* This array holds the chars that always start a comment. If the
96 pre-processor is disabled, these aren't very useful */
97 CONST
char comment_chars
[] = "@";
99 /* This array holds the chars that only start a comment at the beginning of
100 a line. If the line seems to have the form '# 123 filename'
101 .line and .file directives will appear in the pre-processed output */
102 /* Note that input_file.c hand checks for '#' at the beginning of the
103 first line of the input file. This is because the compiler outputs
104 #NO_APP at the beginning of its output. */
105 /* Also note that comments like this one will always work. */
106 CONST
char line_comment_chars
[] = "#";
108 CONST
char line_separator_chars
[] = "";
110 /* Chars that can be used to separate mant from exp in floating point nums */
111 CONST
char EXP_CHARS
[] = "eE";
113 /* Chars that mean this number is a floating point constant */
117 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
119 CONST
int md_reloc_size
= 8; /* Size of relocation record */
121 static int thumb_mode
= 0; /* non-zero if assembling thumb instructions */
123 typedef struct arm_fix
131 unsigned long instruction
;
136 bfd_reloc_code_real_type type
;
146 CONST
char * template;
150 static CONST
struct asm_shift shift
[] =
166 #define NO_SHIFT_RESTRICT 1
167 #define SHIFT_RESTRICT 0
169 #define NUM_FLOAT_VALS 8
171 CONST
char * fp_const
[] =
173 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
176 /* Number of littlenums required to hold an extended precision number */
177 #define MAX_LITTLENUMS 6
179 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
189 #define CP_T_X 0x00008000
190 #define CP_T_Y 0x00400000
191 #define CP_T_Pre 0x01000000
192 #define CP_T_UD 0x00800000
193 #define CP_T_WB 0x00200000
195 #define CONDS_BIT (0x00100000)
196 #define LOAD_BIT (0x00100000)
197 #define TRANS_BIT (0x00200000)
201 CONST
char * template;
205 /* This is to save a hash look-up in the common case */
206 #define COND_ALWAYS 0xe0000000
208 static CONST
struct asm_cond conds
[] =
212 {"cs", 0x20000000}, {"hs", 0x20000000},
213 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
228 /* Warning: If the top bit of the set_bits is set, then the standard
229 instruction bitmask is ignored, and the new bitmask is taken from
233 CONST
char * template; /* Basic flag string */
234 unsigned long set_bits
; /* Bits to set */
237 static CONST
struct asm_flg s_flag
[] =
243 static CONST
struct asm_flg ldr_flags
[] =
247 {"bt", 0x00400000 | TRANS_BIT
},
254 static CONST
struct asm_flg str_flags
[] =
258 {"bt", 0x00400000 | TRANS_BIT
},
263 static CONST
struct asm_flg byte_flag
[] =
269 static CONST
struct asm_flg cmp_flags
[] =
276 static CONST
struct asm_flg ldm_flags
[] =
289 static CONST
struct asm_flg stm_flags
[] =
302 static CONST
struct asm_flg lfm_flags
[] =
309 static CONST
struct asm_flg sfm_flags
[] =
316 static CONST
struct asm_flg round_flags
[] =
324 /* The implementation of the FIX instruction is broken on some assemblers,
325 in that it accepts a precision specifier as well as a rounding specifier,
326 despite the fact that this is meaningless. To be more compatible, we
327 accept it as well, though of course it does not set any bits. */
328 static CONST
struct asm_flg fix_flags
[] =
345 static CONST
struct asm_flg except_flag
[] =
351 static CONST
struct asm_flg cplong_flag
[] =
359 CONST
char * template;
360 unsigned long number
;
363 #define PSR_FIELD_MASK 0x000f0000
365 #define PSR_FLAGS 0x00080000
366 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
367 #define PSR_ALL 0x00090000
376 static CONST
struct asm_psr psrs
[] =
380 {"cpsr_all", CPSR_ALL
},
382 {"spsr_all", SPSR_ALL
},
385 {"cpsr_flg", CPSR_FLG
},
386 {"spsr_flg", SPSR_FLG
},
389 {"cpsr_c", CPSR_CTL
},
390 {"cpsr_ctl", CPSR_CTL
},
391 {"spsr_c", SPSR_CTL
},
392 {"spsr_ctl", SPSR_CTL
}
395 /* Functions called by parser */
396 /* ARM instructions */
397 static void do_arit
PARAMS ((char *operands
, unsigned long flags
));
398 static void do_cmp
PARAMS ((char *operands
, unsigned long flags
));
399 static void do_mov
PARAMS ((char *operands
, unsigned long flags
));
400 static void do_ldst
PARAMS ((char *operands
, unsigned long flags
));
401 static void do_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
402 static void do_branch
PARAMS ((char *operands
, unsigned long flags
));
403 static void do_swi
PARAMS ((char *operands
, unsigned long flags
));
404 /* Pseudo Op codes */
405 static void do_adr
PARAMS ((char *operands
, unsigned long flags
));
406 static void do_nop
PARAMS ((char *operands
, unsigned long flags
));
408 static void do_mul
PARAMS ((char *operands
, unsigned long flags
));
409 static void do_mla
PARAMS ((char *operands
, unsigned long flags
));
411 static void do_swap
PARAMS ((char *operands
, unsigned long flags
));
413 static void do_msr
PARAMS ((char *operands
, unsigned long flags
));
414 static void do_mrs
PARAMS ((char *operands
, unsigned long flags
));
416 static void do_mull
PARAMS ((char *operands
, unsigned long flags
));
418 static void do_bx
PARAMS ((char *operands
, unsigned long flags
));
420 /* Coprocessor Instructions */
421 static void do_cdp
PARAMS ((char *operands
, unsigned long flags
));
422 static void do_lstc
PARAMS ((char *operands
, unsigned long flags
));
423 static void do_co_reg
PARAMS ((char *operands
, unsigned long flags
));
424 static void do_fp_ctrl
PARAMS ((char *operands
, unsigned long flags
));
425 static void do_fp_ldst
PARAMS ((char *operands
, unsigned long flags
));
426 static void do_fp_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
427 static void do_fp_dyadic
PARAMS ((char *operands
, unsigned long flags
));
428 static void do_fp_monadic
PARAMS ((char *operands
, unsigned long flags
));
429 static void do_fp_cmp
PARAMS ((char *operands
, unsigned long flags
));
430 static void do_fp_from_reg
PARAMS ((char *operands
, unsigned long flags
));
431 static void do_fp_to_reg
PARAMS ((char *operands
, unsigned long flags
));
433 static void fix_new_arm
PARAMS ((fragS
*frag
, int where
,
434 short int size
, expressionS
*exp
,
435 int pc_rel
, int reloc
));
436 static int arm_reg_parse
PARAMS ((char **ccp
));
437 static int arm_psr_parse
PARAMS ((char **ccp
));
438 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
,
440 static int add_to_lit_pool
PARAMS ((void));
441 static unsigned validate_immediate
PARAMS ((unsigned));
442 static int validate_offset_imm
PARAMS ((int, int));
443 static void opcode_select
PARAMS ((int));
444 static void end_of_line
PARAMS ((char *));
445 static int reg_required_here
PARAMS ((char **, int));
446 static int psr_required_here
PARAMS ((char **, int, int));
447 static int co_proc_number
PARAMS ((char **));
448 static int cp_opc_expr
PARAMS ((char **, int, int));
449 static int cp_reg_required_here
PARAMS ((char **, int));
450 static int fp_reg_required_here
PARAMS ((char **, int));
451 static int cp_address_offset
PARAMS ((char **));
452 static int cp_address_required_here
PARAMS ((char **));
453 static int my_get_float_expression
PARAMS ((char **));
454 static int skip_past_comma
PARAMS ((char **));
455 static int walk_no_bignums
PARAMS ((symbolS
*));
456 static int negate_data_op
PARAMS ((unsigned long *,
458 static int data_op2
PARAMS ((char **));
459 static int fp_op2
PARAMS ((char **));
460 static long reg_list
PARAMS ((char **));
461 static void thumb_load_store
PARAMS ((char *, int, int));
462 static int decode_shift
PARAMS ((char **, int));
463 static int ldst_extend
PARAMS ((char **, int));
464 static void thumb_add_sub
PARAMS ((char *, int));
465 static void insert_reg
PARAMS ((int));
466 static void thumb_shift
PARAMS ((char *, int));
467 static void thumb_mov_compare
PARAMS ((char *, int));
468 static void set_constant_flonums
PARAMS ((void));
469 static valueT md_chars_to_number
PARAMS ((char *, int));
470 static void insert_reg_alias
PARAMS ((char *, int));
471 static void output_inst
PARAMS ((char *));
473 /* ARM instructions take 4bytes in the object file, Thumb instructions
477 /* LONGEST_INST is the longest basic instruction name without conditions or
479 * ARM7M has 4 of length 5
482 #define LONGEST_INST 5
486 CONST
char * template; /* Basic string to match */
487 unsigned long value
; /* Basic instruction code */
488 CONST
char * comp_suffix
; /* Compulsory suffix that must follow conds */
489 CONST
struct asm_flg
* flags
; /* Bits to toggle if flag 'n' set */
490 unsigned long variants
; /* Which CPU variants this exists for */
491 /* Function to call to parse args */
492 void (* parms
) PARAMS ((char *, unsigned long));
495 static CONST
struct asm_opcode insns
[] =
497 /* ARM Instructions */
498 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
499 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
500 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
501 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
502 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
503 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
504 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
505 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
506 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
507 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
508 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
509 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
510 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
511 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
512 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
513 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
514 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
515 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
516 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
517 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
518 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
519 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
520 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
523 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
524 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
526 /* ARM 2 multiplies */
527 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
528 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
530 /* ARM 3 - swp instructions */
531 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
533 /* ARM 6 Coprocessor instructions */
534 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
535 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
537 /* ARM 7M long multiplies - need signed/unsigned flags! */
538 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
539 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
540 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
541 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
543 /* ARM THUMB interworking */
544 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
546 /* Floating point instructions */
547 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
548 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
549 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
550 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
551 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
552 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
553 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
554 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
555 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
556 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
557 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
558 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
559 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
560 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
561 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
562 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
563 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
564 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
565 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
566 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
567 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
568 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
569 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
570 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
571 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
572 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
573 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
574 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
575 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
576 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
577 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
578 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
579 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
580 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
581 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
582 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
583 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
584 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
585 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
586 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
587 be an optional suffix, but part of the instruction. To be compatible,
589 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
590 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
591 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
592 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
594 /* Generic copressor instructions */
595 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
596 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
597 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
598 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
599 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
602 /* defines for various bits that we will want to toggle */
604 #define INST_IMMEDIATE 0x02000000
605 #define OFFSET_REG 0x02000000
606 #define HWOFFSET_IMM 0x00400000
607 #define SHIFT_BY_REG 0x00000010
608 #define PRE_INDEX 0x01000000
609 #define INDEX_UP 0x00800000
610 #define WRITE_BACK 0x00200000
611 #define MULTI_SET_PSR 0x00400000
613 #define LITERAL_MASK 0xf000f000
614 #define COND_MASK 0xf0000000
615 #define OPCODE_MASK 0xfe1fffff
616 #define DATA_OP_SHIFT 21
618 /* Codes to distinguish the arithmetic instructions */
630 #define OPCODE_CMP 10
631 #define OPCODE_CMN 11
632 #define OPCODE_ORR 12
633 #define OPCODE_MOV 13
634 #define OPCODE_BIC 14
635 #define OPCODE_MVN 15
637 static void do_t_nop
PARAMS ((char *operands
));
638 static void do_t_arit
PARAMS ((char *operands
));
639 static void do_t_add
PARAMS ((char *operands
));
640 static void do_t_asr
PARAMS ((char *operands
));
641 static void do_t_branch9
PARAMS ((char *operands
));
642 static void do_t_branch12
PARAMS ((char *operands
));
643 static void do_t_branch23
PARAMS ((char *operands
));
644 static void do_t_bx
PARAMS ((char *operands
));
645 static void do_t_compare
PARAMS ((char *operands
));
646 static void do_t_ldmstm
PARAMS ((char *operands
));
647 static void do_t_ldr
PARAMS ((char *operands
));
648 static void do_t_ldrb
PARAMS ((char *operands
));
649 static void do_t_ldrh
PARAMS ((char *operands
));
650 static void do_t_lds
PARAMS ((char *operands
));
651 static void do_t_lsl
PARAMS ((char *operands
));
652 static void do_t_lsr
PARAMS ((char *operands
));
653 static void do_t_mov
PARAMS ((char *operands
));
654 static void do_t_push_pop
PARAMS ((char *operands
));
655 static void do_t_str
PARAMS ((char *operands
));
656 static void do_t_strb
PARAMS ((char *operands
));
657 static void do_t_strh
PARAMS ((char *operands
));
658 static void do_t_sub
PARAMS ((char *operands
));
659 static void do_t_swi
PARAMS ((char *operands
));
660 static void do_t_adr
PARAMS ((char *operands
));
662 #define T_OPCODE_MUL 0x4340
663 #define T_OPCODE_TST 0x4200
664 #define T_OPCODE_CMN 0x42c0
665 #define T_OPCODE_NEG 0x4240
666 #define T_OPCODE_MVN 0x43c0
668 #define T_OPCODE_ADD_R3 0x1800
669 #define T_OPCODE_SUB_R3 0x1a00
670 #define T_OPCODE_ADD_HI 0x4400
671 #define T_OPCODE_ADD_ST 0xb000
672 #define T_OPCODE_SUB_ST 0xb080
673 #define T_OPCODE_ADD_SP 0xa800
674 #define T_OPCODE_ADD_PC 0xa000
675 #define T_OPCODE_ADD_I8 0x3000
676 #define T_OPCODE_SUB_I8 0x3800
677 #define T_OPCODE_ADD_I3 0x1c00
678 #define T_OPCODE_SUB_I3 0x1e00
680 #define T_OPCODE_ASR_R 0x4100
681 #define T_OPCODE_LSL_R 0x4080
682 #define T_OPCODE_LSR_R 0x40c0
683 #define T_OPCODE_ASR_I 0x1000
684 #define T_OPCODE_LSL_I 0x0000
685 #define T_OPCODE_LSR_I 0x0800
687 #define T_OPCODE_MOV_I8 0x2000
688 #define T_OPCODE_CMP_I8 0x2800
689 #define T_OPCODE_CMP_LR 0x4280
690 #define T_OPCODE_MOV_HR 0x4600
691 #define T_OPCODE_CMP_HR 0x4500
693 #define T_OPCODE_LDR_PC 0x4800
694 #define T_OPCODE_LDR_SP 0x9800
695 #define T_OPCODE_STR_SP 0x9000
696 #define T_OPCODE_LDR_IW 0x6800
697 #define T_OPCODE_STR_IW 0x6000
698 #define T_OPCODE_LDR_IH 0x8800
699 #define T_OPCODE_STR_IH 0x8000
700 #define T_OPCODE_LDR_IB 0x7800
701 #define T_OPCODE_STR_IB 0x7000
702 #define T_OPCODE_LDR_RW 0x5800
703 #define T_OPCODE_STR_RW 0x5000
704 #define T_OPCODE_LDR_RH 0x5a00
705 #define T_OPCODE_STR_RH 0x5200
706 #define T_OPCODE_LDR_RB 0x5c00
707 #define T_OPCODE_STR_RB 0x5400
709 #define T_OPCODE_PUSH 0xb400
710 #define T_OPCODE_POP 0xbc00
712 #define T_OPCODE_BRANCH 0xe7fe
714 static int thumb_reg
PARAMS ((char ** str
, int hi_lo
));
716 #define THUMB_SIZE 2 /* Size of thumb instruction */
717 #define THUMB_REG_LO 0x1
718 #define THUMB_REG_HI 0x2
719 #define THUMB_REG_ANY 0x3
721 #define THUMB_H1 0x0080
722 #define THUMB_H2 0x0040
729 #define THUMB_COMPARE 1
732 #define THUMB_STORE 1
734 #define THUMB_PP_PC_LR 0x0100
736 /* These three are used for immediate shifts, do not alter */
738 #define THUMB_HALFWORD 1
743 CONST
char * template; /* Basic string to match */
744 unsigned long value
; /* Basic instruction code */
746 void (* parms
) PARAMS ((char *)); /* Function to call to parse args */
749 static CONST
struct thumb_opcode tinsns
[] =
751 {"adc", 0x4140, 2, do_t_arit
},
752 {"add", 0x0000, 2, do_t_add
},
753 {"and", 0x4000, 2, do_t_arit
},
754 {"asr", 0x0000, 2, do_t_asr
},
755 {"b", T_OPCODE_BRANCH
, 2, do_t_branch12
},
756 {"beq", 0xd0fe, 2, do_t_branch9
},
757 {"bne", 0xd1fe, 2, do_t_branch9
},
758 {"bcs", 0xd2fe, 2, do_t_branch9
},
759 {"bhs", 0xd2fe, 2, do_t_branch9
},
760 {"bcc", 0xd3fe, 2, do_t_branch9
},
761 {"bul", 0xd3fe, 2, do_t_branch9
},
762 {"blo", 0xd3fe, 2, do_t_branch9
},
763 {"bmi", 0xd4fe, 2, do_t_branch9
},
764 {"bpl", 0xd5fe, 2, do_t_branch9
},
765 {"bvs", 0xd6fe, 2, do_t_branch9
},
766 {"bvc", 0xd7fe, 2, do_t_branch9
},
767 {"bhi", 0xd8fe, 2, do_t_branch9
},
768 {"bls", 0xd9fe, 2, do_t_branch9
},
769 {"bge", 0xdafe, 2, do_t_branch9
},
770 {"blt", 0xdbfe, 2, do_t_branch9
},
771 {"bgt", 0xdcfe, 2, do_t_branch9
},
772 {"ble", 0xddfe, 2, do_t_branch9
},
773 {"bic", 0x4380, 2, do_t_arit
},
774 {"bl", 0xf7fffffe, 4, do_t_branch23
},
775 {"bx", 0x4700, 2, do_t_bx
},
776 {"cmn", T_OPCODE_CMN
, 2, do_t_arit
},
777 {"cmp", 0x0000, 2, do_t_compare
},
778 {"eor", 0x4040, 2, do_t_arit
},
779 {"ldmia", 0xc800, 2, do_t_ldmstm
},
780 {"ldr", 0x0000, 2, do_t_ldr
},
781 {"ldrb", 0x0000, 2, do_t_ldrb
},
782 {"ldrh", 0x0000, 2, do_t_ldrh
},
783 {"ldrsb", 0x5600, 2, do_t_lds
},
784 {"ldrsh", 0x5e00, 2, do_t_lds
},
785 {"ldsb", 0x5600, 2, do_t_lds
},
786 {"ldsh", 0x5e00, 2, do_t_lds
},
787 {"lsl", 0x0000, 2, do_t_lsl
},
788 {"lsr", 0x0000, 2, do_t_lsr
},
789 {"mov", 0x0000, 2, do_t_mov
},
790 {"mul", T_OPCODE_MUL
, 2, do_t_arit
},
791 {"mvn", T_OPCODE_MVN
, 2, do_t_arit
},
792 {"neg", T_OPCODE_NEG
, 2, do_t_arit
},
793 {"orr", 0x4300, 2, do_t_arit
},
794 {"pop", 0xbc00, 2, do_t_push_pop
},
795 {"push", 0xb400, 2, do_t_push_pop
},
796 {"ror", 0x41c0, 2, do_t_arit
},
797 {"sbc", 0x4180, 2, do_t_arit
},
798 {"stmia", 0xc000, 2, do_t_ldmstm
},
799 {"str", 0x0000, 2, do_t_str
},
800 {"strb", 0x0000, 2, do_t_strb
},
801 {"strh", 0x0000, 2, do_t_strh
},
802 {"swi", 0xdf00, 2, do_t_swi
},
803 {"sub", 0x0000, 2, do_t_sub
},
804 {"tst", T_OPCODE_TST
, 2, do_t_arit
},
806 {"adr", 0x0000, 2, do_t_adr
},
807 {"nop", 0x46C0, 2, do_t_nop
}, /* mov r8,r8 */
816 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
817 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
818 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
824 /* These are the standard names; Users can add aliases with .req */
825 static CONST
struct reg_entry reg_table
[] =
827 /* Processor Register Numbers */
828 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
829 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
830 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
831 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
832 /* APCS conventions */
833 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
834 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
835 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
836 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
838 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
839 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
840 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
841 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
842 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
843 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
844 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
845 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
846 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
847 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
851 #define bad_args _("Bad arguments to instruction");
852 #define bad_pc _("r15 not allowed here");
854 static struct hash_control
* arm_ops_hsh
= NULL
;
855 static struct hash_control
* arm_tops_hsh
= NULL
;
856 static struct hash_control
* arm_cond_hsh
= NULL
;
857 static struct hash_control
* arm_shift_hsh
= NULL
;
858 static struct hash_control
* arm_reg_hsh
= NULL
;
859 static struct hash_control
* arm_psr_hsh
= NULL
;
861 /* This table describes all the machine specific pseudo-ops the assembler
862 has to support. The fields are:
863 pseudo-op name without dot
864 function to call to execute this pseudo-op
865 Integer arg to pass to the function
868 static void s_req
PARAMS ((int));
869 static void s_align
PARAMS ((int));
870 static void s_bss
PARAMS ((int));
871 static void s_even
PARAMS ((int));
872 static void s_ltorg
PARAMS ((int));
873 static void s_arm
PARAMS ((int));
874 static void s_thumb
PARAMS ((int));
875 static void s_code
PARAMS ((int));
876 static void s_force_thumb
PARAMS ((int));
877 static void s_thumb_func
PARAMS ((int));
879 static int my_get_expression
PARAMS ((expressionS
*, char **));
881 CONST pseudo_typeS md_pseudo_table
[] =
883 {"req", s_req
, 0}, /* Never called becasue '.req' does not start line */
885 {"align", s_align
, 0},
887 {"thumb", s_thumb
, 0},
889 {"force_thumb", s_force_thumb
, 0},
890 {"thumb_func", s_thumb_func
, 0},
892 {"ltorg", s_ltorg
, 0},
893 {"pool", s_ltorg
, 0},
895 {"extend", float_cons
, 'x'},
896 {"ldouble", float_cons
, 'x'},
897 {"packed", float_cons
, 'p'},
901 /* Stuff needed to resolve the label ambiguity
911 symbolS
* last_label_seen
;
912 static int label_is_thumb_function_name
= false;
916 #define MAX_LITERAL_POOL_SIZE 1024
918 typedef struct literalS
920 struct expressionS exp
;
921 struct arm_it
* inst
;
924 literalT literals
[MAX_LITERAL_POOL_SIZE
];
925 int next_literal_pool_place
= 0; /* Next free entry in the pool */
926 int lit_pool_num
= 1; /* Next literal pool number */
927 symbolS
* current_poolP
= NULL
;
928 symbolS
* symbol_make_empty
PARAMS ((void));
935 if (current_poolP
== NULL
)
936 current_poolP
= symbol_make_empty ();
938 /* Check if this literal value is already in the pool: */
939 while (lit_count
< next_literal_pool_place
)
941 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
942 && inst
.reloc
.exp
.X_op
== O_constant
943 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
944 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
949 if (lit_count
== next_literal_pool_place
) /* new entry */
951 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
953 inst
.error
= _("Literal Pool Overflow");
957 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
958 lit_count
= next_literal_pool_place
++;
961 inst
.reloc
.exp
.X_op
= O_symbol
;
962 inst
.reloc
.exp
.X_add_number
= (lit_count
) * 4 - 8;
963 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
968 /* Can't use symbol_new here, so have to create a symbol and then at
969 a later date assign it a value. Thats what these functions do. */
971 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
973 CONST
char * name
; /* It is copied, the caller can modify */
974 segT segment
; /* Segment identifier (SEG_<something>) */
975 valueT valu
; /* Symbol value */
976 fragS
* frag
; /* Associated fragment */
978 unsigned int name_length
;
979 char * preserved_copy_of_name
;
981 name_length
= strlen (name
) + 1; /* +1 for \0 */
982 obstack_grow (¬es
, name
, name_length
);
983 preserved_copy_of_name
= obstack_finish (¬es
);
984 #ifdef STRIP_UNDERSCORE
985 if (preserved_copy_of_name
[0] == '_')
986 preserved_copy_of_name
++;
989 #ifdef tc_canonicalize_symbol_name
990 preserved_copy_of_name
=
991 tc_canonicalize_symbol_name (preserved_copy_of_name
);
994 S_SET_NAME (symbolP
, preserved_copy_of_name
);
996 S_SET_SEGMENT (symbolP
, segment
);
997 S_SET_VALUE (symbolP
, valu
);
998 symbol_clear_list_pointers(symbolP
);
1000 symbolP
->sy_frag
= frag
;
1002 /* Link to end of symbol chain. */
1004 extern int symbol_table_frozen
;
1005 if (symbol_table_frozen
)
1009 symbol_append (symbolP
, symbol_lastP
, & symbol_rootP
, & symbol_lastP
);
1011 obj_symbol_new_hook (symbolP
);
1013 #ifdef tc_symbol_new_hook
1014 tc_symbol_new_hook (symbolP
);
1018 verify_symbol_chain (symbol_rootP
, symbol_lastP
);
1019 #endif /* DEBUG_SYMS */
1023 symbol_make_empty ()
1027 symbolP
= (symbolS
*) obstack_alloc (¬es
, sizeof (symbolS
));
1029 /* symbol must be born in some fixed state. This seems as good as any. */
1030 memset (symbolP
, 0, sizeof (symbolS
));
1032 symbolP
->bsym
= bfd_make_empty_symbol (stdoutput
);
1033 assert (symbolP
->bsym
!= 0);
1034 symbolP
->bsym
->udata
.p
= (PTR
) symbolP
;
1039 /* Check that an immediate is valid, and if so, convert it to the right format. */
1042 validate_immediate (val
)
1048 #define rotate_left(v, n) (v << n | v >> (32 - n))
1050 for (i
= 0; i
< 32; i
+= 2)
1051 if ((a
= rotate_left (val
, i
)) <= 0xff)
1052 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1057 validate_offset_imm (val
, hwse
)
1061 if ((hwse
&& (val
< -255 || val
> 255))
1062 || (val
< -4095 || val
> 4095))
1072 as_bad (_("Invalid syntax for .req directive."));
1079 /* We don't support putting frags in the BSS segment, we fake it by
1080 marking in_bss, then looking at s_skip for clues?.. */
1081 subseg_set (bss_section
, 0);
1082 demand_empty_rest_of_line ();
1089 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1090 frag_align (1, 0, 0);
1092 record_alignment (now_seg
, 1);
1094 demand_empty_rest_of_line ();
1104 if (current_poolP
== NULL
)
1108 as_tsktsk (_("Nothing to put in the pool\n"));
1112 /* Align pool as you have word accesses */
1113 /* Only make a frag if we have to ... */
1115 frag_align (2, 0, 0);
1117 record_alignment (now_seg
, 2);
1120 as_tsktsk (_("Inserting implicit pool at change of section"));
1122 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1124 symbol_locate (current_poolP
, sym_name
, now_seg
,
1125 (valueT
) frag_now_fix (), frag_now
);
1126 symbol_table_insert (current_poolP
);
1128 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1130 #if defined OBJ_COFF || defined OBJ_ELF
1131 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1134 while (lit_count
< next_literal_pool_place
)
1135 /* First output the expression in the instruction to the pool */
1136 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1138 next_literal_pool_place
= 0;
1139 current_poolP
= NULL
;
1143 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1147 register long temp_fill
;
1148 long max_alignment
= 15;
1150 temp
= get_absolute_expression ();
1151 if (temp
> max_alignment
)
1152 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1155 as_bad (_("Alignment negative. 0 assumed."));
1159 if (*input_line_pointer
== ',')
1161 input_line_pointer
++;
1162 temp_fill
= get_absolute_expression ();
1170 /* Only make a frag if we HAVE to. . . */
1171 if (temp
&& !need_pass_2
)
1172 frag_align (temp
, (int) temp_fill
, 0);
1173 demand_empty_rest_of_line ();
1175 record_alignment (now_seg
, temp
);
1179 s_force_thumb (ignore
)
1182 /* If we are not already in thumb mode go into it, EVEN if
1183 the target processor does not support thumb instructions.
1184 This is used by gcc/config/arm/lib1funcs.asm for example
1185 to compile interworking support functions even if the
1186 target processor should not support interworking. */
1192 record_alignment (now_seg
, 1);
1195 demand_empty_rest_of_line ();
1199 s_thumb_func (ignore
)
1202 /* The following label is the name/address of the start of a Thumb function.
1203 We need to know this for the interworking support. */
1205 label_is_thumb_function_name
= true;
1207 demand_empty_rest_of_line ();
1211 opcode_select (width
)
1219 if (! (cpu_variant
& ARM_THUMB
))
1220 as_bad (_("selected processor does not support THUMB opcodes"));
1222 /* No need to force the alignment, since we will have been
1223 coming from ARM mode, which is word-aligned. */
1224 record_alignment (now_seg
, 1);
1231 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1232 as_bad (_("selected processor does not support ARM opcodes"));
1235 frag_align (2, 0, 0);
1236 record_alignment (now_seg
, 1);
1241 as_bad (_("invalid instruction size selected (%d)"), width
);
1250 demand_empty_rest_of_line ();
1258 demand_empty_rest_of_line ();
1267 temp
= get_absolute_expression ();
1272 opcode_select (temp
);
1276 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1288 inst
.error
= _("Garbage following instruction");
1292 skip_past_comma (str
)
1298 while ((c
= *p
) == ' ' || c
== ',')
1301 if (c
== ',' && comma
++)
1309 return comma
? SUCCESS
: FAIL
;
1312 /* A standard register must be given at this point. Shift is the place to
1313 put it in the instruction. */
1316 reg_required_here (str
, shift
)
1320 static char buff
[128]; /* XXX */
1322 char * start
= *str
;
1324 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1327 inst
.instruction
|= reg
<< shift
;
1331 /* Restore the start point, we may have got a reg of the wrong class. */
1334 /* In the few cases where we might be able to accept something else
1335 this error can be overridden */
1336 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1343 psr_required_here (str
, cpsr
, spsr
)
1349 char * start
= *str
;
1350 psr
= arm_psr_parse (str
);
1352 if (psr
== cpsr
|| psr
== spsr
)
1355 inst
.instruction
|= 1 << 22;
1360 /* In the few cases where we might be able to accept something else
1361 this error can be overridden */
1362 inst
.error
= _("<psr(f)> expected");
1364 /* Restore the start point. */
1370 co_proc_number (str
)
1373 int processor
, pchar
;
1375 while (**str
== ' ')
1378 /* The data sheet seems to imply that just a number on its own is valid
1379 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1381 if (**str
== 'p' || **str
== 'P')
1385 if (pchar
>= '0' && pchar
<= '9')
1387 processor
= pchar
- '0';
1388 if (**str
>= '0' && **str
<= '9')
1390 processor
= processor
* 10 + *(*str
)++ - '0';
1393 inst
.error
= _("Illegal co-processor number");
1400 inst
.error
= _("Bad or missing co-processor number");
1404 inst
.instruction
|= processor
<< 8;
1409 cp_opc_expr (str
, where
, length
)
1416 while (**str
== ' ')
1419 memset (&expr
, '\0', sizeof (expr
));
1421 if (my_get_expression (&expr
, str
))
1423 if (expr
.X_op
!= O_constant
)
1425 inst
.error
= _("bad or missing expression");
1429 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1431 inst
.error
= _("immediate co-processor expression too large");
1435 inst
.instruction
|= expr
.X_add_number
<< where
;
1440 cp_reg_required_here (str
, where
)
1445 char * start
= *str
;
1447 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1450 inst
.instruction
|= reg
<< where
;
1454 /* In the few cases where we might be able to accept something else
1455 this error can be overridden */
1456 inst
.error
= _("Co-processor register expected");
1458 /* Restore the start point */
1464 fp_reg_required_here (str
, where
)
1469 char * start
= *str
;
1471 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1474 inst
.instruction
|= reg
<< where
;
1478 /* In the few cases where we might be able to accept something else
1479 this error can be overridden */
1480 inst
.error
= _("Floating point register expected");
1482 /* Restore the start point */
1488 cp_address_offset (str
)
1493 while (**str
== ' ')
1498 inst
.error
= _("immediate expression expected");
1503 if (my_get_expression (&inst
.reloc
.exp
, str
))
1505 if (inst
.reloc
.exp
.X_op
== O_constant
)
1507 offset
= inst
.reloc
.exp
.X_add_number
;
1510 inst
.error
= _("co-processor address must be word aligned");
1514 if (offset
> 1023 || offset
< -1023)
1516 inst
.error
= _("offset too large");
1521 inst
.instruction
|= INDEX_UP
;
1525 inst
.instruction
|= offset
>> 2;
1528 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1534 cp_address_required_here (str
)
1549 if ((reg
= reg_required_here (&p
, 16)) == FAIL
)
1558 if (skip_past_comma (&p
) == SUCCESS
)
1561 write_back
= WRITE_BACK
;
1564 inst
.error
= _("pc may not be used in post-increment");
1568 if (cp_address_offset (&p
) == FAIL
)
1572 pre_inc
= PRE_INDEX
| INDEX_UP
;
1576 /* '['Rn, #expr']'[!] */
1578 if (skip_past_comma (&p
) == FAIL
)
1580 inst
.error
= _("pre-indexed expression expected");
1584 pre_inc
= PRE_INDEX
;
1585 if (cp_address_offset (&p
) == FAIL
)
1593 inst
.error
= _("missing ]");
1604 inst
.error
= _("pc may not be used with write-back");
1609 write_back
= WRITE_BACK
;
1615 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1618 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1619 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1620 inst
.reloc
.pc_rel
= 1;
1621 inst
.instruction
|= (REG_PC
<< 16);
1622 pre_inc
= PRE_INDEX
;
1625 inst
.instruction
|= write_back
| pre_inc
;
1633 unsigned long flags
;
1635 /* Do nothing really */
1636 inst
.instruction
|= flags
; /* This is pointless */
1644 unsigned long flags
;
1646 /* Only one syntax */
1650 if (reg_required_here (&str
, 12) == FAIL
)
1652 inst
.error
= bad_args
;
1656 if (skip_past_comma (&str
) == FAIL
1657 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1659 inst
.error
= _("<psr> expected");
1663 inst
.instruction
|= flags
;
1668 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1672 unsigned long flags
;
1679 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1681 inst
.instruction
|= PSR_ALL
;
1683 /* Sytax should be "<psr>, Rm" */
1684 if (skip_past_comma (&str
) == FAIL
1685 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1687 inst
.error
= bad_args
;
1693 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1695 inst
.instruction
|= PSR_FLAGS
;
1697 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1699 inst
.instruction
|= PSR_CONTROL
;
1703 inst
.error
= bad_args
;
1707 if (skip_past_comma (&str
) == FAIL
)
1709 inst
.error
= bad_args
;
1713 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1715 if ((reg
= reg_required_here (&str
, 0)) != FAIL
)
1717 /* Immediate expression */
1718 else if (*(str
++) == '#')
1721 if (my_get_expression (&inst
.reloc
.exp
, &str
))
1723 inst
.error
= _("Register or shift expression expected");
1727 if (inst
.reloc
.exp
.X_add_symbol
)
1729 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1730 inst
.reloc
.pc_rel
= 0;
1734 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1737 inst
.error
= _("Invalid constant");
1741 inst
.instruction
|= value
;
1744 flags
|= INST_IMMEDIATE
;
1748 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1754 inst
.instruction
|= flags
;
1759 /* Long Multiply Parser
1760 UMULL RdLo, RdHi, Rm, Rs
1761 SMULL RdLo, RdHi, Rm, Rs
1762 UMLAL RdLo, RdHi, Rm, Rs
1763 SMLAL RdLo, RdHi, Rm, Rs
1766 do_mull (str
, flags
)
1768 unsigned long flags
;
1770 int rdlo
, rdhi
, rm
, rs
;
1772 /* only one format "rdlo, rdhi, rm, rs" */
1776 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1778 inst
.error
= bad_args
;
1782 if (skip_past_comma (&str
) == FAIL
1783 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1785 inst
.error
= bad_args
;
1789 if (skip_past_comma (&str
) == FAIL
1790 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1792 inst
.error
= bad_args
;
1796 /* rdhi, rdlo and rm must all be different */
1797 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1798 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1800 if (skip_past_comma (&str
) == FAIL
1801 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1803 inst
.error
= bad_args
;
1807 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1809 inst
.error
= bad_pc
;
1813 inst
.instruction
|= flags
;
1821 unsigned long flags
;
1825 /* only one format "rd, rm, rs" */
1829 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1831 inst
.error
= bad_args
;
1837 inst
.error
= bad_pc
;
1841 if (skip_past_comma (&str
) == FAIL
1842 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1844 inst
.error
= bad_args
;
1850 inst
.error
= bad_pc
;
1855 as_tsktsk (_("rd and rm should be different in mul"));
1857 if (skip_past_comma (&str
) == FAIL
1858 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
1860 inst
.error
= bad_args
;
1866 inst
.error
= bad_pc
;
1870 inst
.instruction
|= flags
;
1878 unsigned long flags
;
1882 /* only one format "rd, rm, rs, rn" */
1886 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1888 inst
.error
= bad_args
;
1894 inst
.error
= bad_pc
;
1898 if (skip_past_comma (&str
) == FAIL
1899 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1901 inst
.error
= bad_args
;
1907 inst
.error
= bad_pc
;
1912 as_tsktsk (_("rd and rm should be different in mla"));
1914 if (skip_past_comma (&str
) == FAIL
1915 || (rd
= reg_required_here (&str
, 8)) == FAIL
1916 || skip_past_comma (&str
) == FAIL
1917 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
1919 inst
.error
= bad_args
;
1923 if (rd
== REG_PC
|| rm
== REG_PC
)
1925 inst
.error
= bad_pc
;
1929 inst
.instruction
|= flags
;
1934 /* Returns the index into fp_values of a floating point number, or -1 if
1935 not in the table. */
1937 my_get_float_expression (str
)
1940 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1946 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
1947 /* Look for a raw floating point number */
1948 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
1949 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
1951 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
1953 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
1955 if (words
[j
] != fp_values
[i
][j
])
1959 if (j
== MAX_LITTLENUMS
)
1967 /* Try and parse a more complex expression, this will probably fail
1968 unless the code uses a floating point prefix (eg "0f") */
1969 save_in
= input_line_pointer
;
1970 input_line_pointer
= *str
;
1971 if (expression (&exp
) == absolute_section
1972 && exp
.X_op
== O_big
1973 && exp
.X_add_number
< 0)
1975 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
1977 if (gen_to_words (words
, 5, (long)15) == 0)
1979 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
1981 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
1983 if (words
[j
] != fp_values
[i
][j
])
1987 if (j
== MAX_LITTLENUMS
)
1989 *str
= input_line_pointer
;
1990 input_line_pointer
= save_in
;
1997 *str
= input_line_pointer
;
1998 input_line_pointer
= save_in
;
2002 /* Return true if anything in the expression is a bignum */
2004 walk_no_bignums (sp
)
2007 if (sp
->sy_value
.X_op
== O_big
)
2010 if (sp
->sy_value
.X_add_symbol
)
2012 return (walk_no_bignums (sp
->sy_value
.X_add_symbol
)
2013 || (sp
->sy_value
.X_op_symbol
2014 && walk_no_bignums (sp
->sy_value
.X_op_symbol
)));
2021 my_get_expression (ep
, str
)
2028 save_in
= input_line_pointer
;
2029 input_line_pointer
= *str
;
2030 seg
= expression (ep
);
2033 if (seg
!= absolute_section
2034 && seg
!= text_section
2035 && seg
!= data_section
2036 && seg
!= bss_section
2037 && seg
!= undefined_section
)
2039 inst
.error
= _("bad_segment");
2040 *str
= input_line_pointer
;
2041 input_line_pointer
= save_in
;
2046 /* Get rid of any bignums now, so that we don't generate an error for which
2047 we can't establish a line number later on. Big numbers are never valid
2048 in instructions, which is where this routine is always called. */
2049 if (ep
->X_op
== O_big
2050 || (ep
->X_add_symbol
2051 && (walk_no_bignums (ep
->X_add_symbol
)
2053 && walk_no_bignums (ep
->X_op_symbol
)))))
2055 inst
.error
= _("Invalid constant");
2056 *str
= input_line_pointer
;
2057 input_line_pointer
= save_in
;
2061 *str
= input_line_pointer
;
2062 input_line_pointer
= save_in
;
2066 /* unrestrict should be one if <shift> <register> is permitted for this
2070 decode_shift (str
, unrestrict
)
2074 struct asm_shift
* shft
;
2078 while (**str
== ' ')
2081 for (p
= *str
; isalpha (*p
); p
++)
2086 inst
.error
= _("Shift expression expected");
2092 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2096 if (!strncmp (*str
, "rrx", 3)
2097 || !strncmp (*str
, "RRX", 3))
2100 inst
.instruction
|= shft
->value
;
2107 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2109 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2117 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2120 /* Validate some simple #expressions */
2121 if (inst
.reloc
.exp
.X_op
== O_constant
)
2123 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2125 /* Reject operations greater than 32, or lsl #32 */
2126 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2128 inst
.error
= _("Invalid immediate shift");
2132 /* Shifts of zero should be converted to lsl (which is zero)*/
2139 /* Shifts of 32 are encoded as 0, for those shifts that
2144 inst
.instruction
|= (num
<< 7) | shft
->value
;
2149 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2150 inst
.reloc
.pc_rel
= 0;
2151 inst
.instruction
|= shft
->value
;
2157 inst
.error
= unrestrict
? _("shift requires register or #expression")
2158 : _("shift requires #expression");
2164 inst
.error
= _("Shift expression expected");
2168 /* Do those data_ops which can take a negative immediate constant */
2169 /* by altering the instuction. A bit of a hack really */
2173 by inverting the second operand, and
2176 by negating the second operand.
2179 negate_data_op (instruction
, value
)
2180 unsigned long * instruction
;
2181 unsigned long value
;
2184 unsigned long negated
, inverted
;
2186 negated
= validate_immediate (-value
);
2187 inverted
= validate_immediate (~value
);
2189 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2193 case OPCODE_SUB
: /* ADD <-> SUB */
2194 new_inst
= OPCODE_ADD
;
2199 new_inst
= OPCODE_SUB
;
2203 case OPCODE_CMP
: /* CMP <-> CMN */
2204 new_inst
= OPCODE_CMN
;
2209 new_inst
= OPCODE_CMP
;
2213 /* Now Inverted ops */
2214 case OPCODE_MOV
: /* MOV <-> MVN */
2215 new_inst
= OPCODE_MVN
;
2220 new_inst
= OPCODE_MOV
;
2224 case OPCODE_AND
: /* AND <-> BIC */
2225 new_inst
= OPCODE_BIC
;
2230 new_inst
= OPCODE_AND
;
2234 case OPCODE_ADC
: /* ADC <-> SBC */
2235 new_inst
= OPCODE_SBC
;
2240 new_inst
= OPCODE_ADC
;
2244 /* We cannot do anything */
2252 *instruction
&= OPCODE_MASK
;
2253 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2264 while (**str
== ' ')
2267 if (reg_required_here (str
, 0) != FAIL
)
2269 if (skip_past_comma (str
) == SUCCESS
)
2271 /* Shift operation on register */
2272 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2278 /* Immediate expression */
2279 if (*((*str
)++) == '#')
2282 if (my_get_expression (&inst
.reloc
.exp
, str
))
2285 if (inst
.reloc
.exp
.X_add_symbol
)
2287 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2288 inst
.reloc
.pc_rel
= 0;
2292 if (skip_past_comma (str
) == SUCCESS
)
2294 /* #x, y -- ie explicit rotation by Y */
2295 if (my_get_expression (&expr
, str
))
2298 if (expr
.X_op
!= O_constant
)
2300 inst
.error
= _("Constant expression expected");
2304 /* Rotate must be a multiple of 2 */
2305 if (((unsigned) expr
.X_add_number
) > 30
2306 || (expr
.X_add_number
& 1) != 0
2307 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2309 inst
.error
= _("Invalid constant");
2312 inst
.instruction
|= INST_IMMEDIATE
;
2313 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2314 inst
.instruction
|= expr
.X_add_number
<< 7;
2318 /* Implicit rotation, select a suitable one */
2319 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2323 /* Can't be done, perhaps the code reads something like
2324 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2325 if ((value
= negate_data_op (&inst
.instruction
,
2326 inst
.reloc
.exp
.X_add_number
))
2329 inst
.error
= _("Invalid constant");
2334 inst
.instruction
|= value
;
2337 inst
.instruction
|= INST_IMMEDIATE
;
2341 inst
.error
= _("Register or shift expression expected");
2350 while (**str
== ' ')
2353 if (fp_reg_required_here (str
, 0) != FAIL
)
2357 /* Immediate expression */
2358 if (*((*str
)++) == '#')
2363 while (**str
== ' ')
2366 /* First try and match exact strings, this is to guarantee that
2367 some formats will work even for cross assembly */
2369 for (i
= 0; fp_const
[i
]; i
++)
2371 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2375 *str
+= strlen (fp_const
[i
]);
2376 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2378 inst
.instruction
|= i
+ 8;
2385 /* Just because we didn't get a match doesn't mean that the
2386 constant isn't valid, just that it is in a format that we
2387 don't automatically recognize. Try parsing it with
2388 the standard expression routines. */
2389 if ((i
= my_get_float_expression (str
)) >= 0)
2391 inst
.instruction
|= i
+ 8;
2395 inst
.error
= _("Invalid floating point immediate expression");
2398 inst
.error
= _("Floating point register or immediate expression expected");
2404 do_arit (str
, flags
)
2406 unsigned long flags
;
2411 if (reg_required_here (&str
, 12) == FAIL
2412 || skip_past_comma (&str
) == FAIL
2413 || reg_required_here (&str
, 16) == FAIL
2414 || skip_past_comma (&str
) == FAIL
2415 || data_op2 (&str
) == FAIL
)
2418 inst
.error
= bad_args
;
2422 inst
.instruction
|= flags
;
2430 unsigned long flags
;
2432 /* This is a pseudo-op of the form "adr rd, label" to be converted
2433 into a relative address of the form "add rd, pc, #label-.-8" */
2438 if (reg_required_here (&str
, 12) == FAIL
2439 || skip_past_comma (&str
) == FAIL
2440 || my_get_expression (&inst
.reloc
.exp
, &str
))
2443 inst
.error
= bad_args
;
2446 /* Frag hacking will turn this into a sub instruction if the offset turns
2447 out to be negative. */
2448 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2449 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2450 inst
.reloc
.pc_rel
= 1;
2451 inst
.instruction
|= flags
;
2459 unsigned long flags
;
2464 if (reg_required_here (&str
, 16) == FAIL
)
2467 inst
.error
= bad_args
;
2471 if (skip_past_comma (&str
) == FAIL
2472 || data_op2 (&str
) == FAIL
)
2475 inst
.error
= bad_args
;
2479 inst
.instruction
|= flags
;
2480 if ((flags
& 0x0000f000) == 0)
2481 inst
.instruction
|= CONDS_BIT
;
2490 unsigned long flags
;
2495 if (reg_required_here (&str
, 12) == FAIL
)
2498 inst
.error
= bad_args
;
2502 if (skip_past_comma (&str
) == FAIL
2503 || data_op2 (&str
) == FAIL
)
2506 inst
.error
= bad_args
;
2510 inst
.instruction
|= flags
;
2516 ldst_extend (str
, hwse
)
2526 if (my_get_expression (&inst
.reloc
.exp
, str
))
2529 if (inst
.reloc
.exp
.X_op
== O_constant
)
2531 int value
= inst
.reloc
.exp
.X_add_number
;
2533 if ((hwse
&& (value
< -255 || value
> 255))
2534 || (value
< -4095 || value
> 4095))
2536 inst
.error
= _("address offset too large");
2546 /* Halfword and signextension instructions have the
2547 immediate value split across bits 11..8 and bits 3..0 */
2549 inst
.instruction
|= add
| HWOFFSET_IMM
| (value
>> 4) << 8 | value
& 0xF;
2551 inst
.instruction
|= add
| value
;
2557 inst
.instruction
|= HWOFFSET_IMM
;
2558 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2561 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2562 inst
.reloc
.pc_rel
= 0;
2567 add
= 0; /* and fall through */
2569 (*str
)++; /* and fall through */
2571 if (reg_required_here (str
, 0) == FAIL
)
2575 inst
.instruction
|= add
;
2578 inst
.instruction
|= add
| OFFSET_REG
;
2579 if (skip_past_comma (str
) == SUCCESS
)
2580 return decode_shift (str
, SHIFT_RESTRICT
);
2588 do_ldst (str
, flags
)
2590 unsigned long flags
;
2597 /* This is not ideal, but it is the simplest way of dealing with the
2598 ARM7T halfword instructions (since they use a different
2599 encoding, but the same mnemonic): */
2600 if (halfword
= ((flags
& 0x80000000) != 0))
2602 /* This is actually a load/store of a halfword, or a
2603 signed-extension load */
2604 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2607 = _("Processor does not support halfwords or signed bytes");
2611 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2612 | (flags
& ~COND_MASK
);
2620 if ((conflict_reg
= reg_required_here (&str
, 12)) == FAIL
)
2623 if (skip_past_comma (&str
) == FAIL
)
2625 inst
.error
= _("Address expected");
2637 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2640 conflict_reg
= (((conflict_reg
== reg
)
2641 && (inst
.instruction
& LOAD_BIT
))
2650 if (skip_past_comma (&str
) == SUCCESS
)
2652 /* [Rn],... (post inc) */
2653 if (ldst_extend (&str
, halfword
) == FAIL
)
2656 as_warn (_("destination register same as write-back base\n"));
2662 inst
.instruction
|= HWOFFSET_IMM
;
2670 as_warn (_("destination register same as write-back base\n"));
2672 inst
.instruction
|= WRITE_BACK
;
2676 if (! (flags
& TRANS_BIT
))
2683 if (skip_past_comma (&str
) == FAIL
)
2685 inst
.error
= _("pre-indexed expression expected");
2690 if (ldst_extend (&str
, halfword
) == FAIL
)
2698 inst
.error
= _("missing ]");
2708 as_tsktsk (_("destination register same as write-back base\n"));
2710 inst
.instruction
|= WRITE_BACK
;
2714 else if (*str
== '=')
2716 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2722 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2725 if (inst
.reloc
.exp
.X_op
!= O_constant
2726 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2728 inst
.error
= _("Constant expression expected");
2732 if (inst
.reloc
.exp
.X_op
== O_constant
2733 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2735 /* This can be done with a mov instruction */
2736 inst
.instruction
&= LITERAL_MASK
;
2737 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2738 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2744 /* Insert into literal pool */
2745 if (add_to_lit_pool () == FAIL
)
2748 inst
.error
= _("literal pool insertion failed");
2752 /* Change the instruction exp to point to the pool */
2755 inst
.instruction
|= HWOFFSET_IMM
;
2756 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2759 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2760 inst
.reloc
.pc_rel
= 1;
2761 inst
.instruction
|= (REG_PC
<< 16);
2767 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2772 inst
.instruction
|= HWOFFSET_IMM
;
2773 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2776 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2777 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
2778 inst
.reloc
.pc_rel
= 1;
2779 inst
.instruction
|= (REG_PC
<< 16);
2783 if (pre_inc
&& (flags
& TRANS_BIT
))
2784 inst
.error
= _("Pre-increment instruction with translate");
2786 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
2799 /* We come back here if we get ranges concatenated by '+' or '|' */
2817 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
2826 inst
.error
= _("Bad range in register list");
2830 for (i
= cur_reg
+ 1; i
< reg
; i
++)
2832 if (range
& (1 << i
))
2834 (_("Warning: Duplicated register (r%d) in register list"),
2842 if (range
& (1 << reg
))
2843 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
2845 else if (reg
<= cur_reg
)
2846 as_tsktsk (_("Warning: Register range not in ascending order"));
2850 } while (skip_past_comma (&str
) != FAIL
2851 || (in_range
= 1, *str
++ == '-'));
2858 inst
.error
= _("Missing `}'");
2866 if (my_get_expression (&expr
, &str
))
2869 if (expr
.X_op
== O_constant
)
2871 if (expr
.X_add_number
2872 != (expr
.X_add_number
& 0x0000ffff))
2874 inst
.error
= _("invalid register mask");
2878 if ((range
& expr
.X_add_number
) != 0)
2880 int regno
= range
& expr
.X_add_number
;
2883 regno
= (1 << regno
) - 1;
2885 (_("Warning: Duplicated register (r%d) in register list"),
2889 range
|= expr
.X_add_number
;
2893 if (inst
.reloc
.type
!= 0)
2895 inst
.error
= _("expression too complex");
2899 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
2900 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
2901 inst
.reloc
.pc_rel
= 0;
2908 if (*str
== '|' || *str
== '+')
2913 } while (another_range
);
2920 do_ldmstm (str
, flags
)
2922 unsigned long flags
;
2930 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
2933 if (base_reg
== REG_PC
)
2935 inst
.error
= _("r15 not allowed as base register");
2943 flags
|= WRITE_BACK
;
2947 if (skip_past_comma (&str
) == FAIL
2948 || (range
= reg_list (&str
)) == FAIL
)
2951 inst
.error
= bad_args
;
2958 flags
|= MULTI_SET_PSR
;
2961 inst
.instruction
|= flags
| range
;
2969 unsigned long flags
;
2971 /* Allow optional leading '#'. */
2977 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2980 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
2981 inst
.reloc
.pc_rel
= 0;
2982 inst
.instruction
|= flags
;
2988 do_swap (str
, flags
)
2990 unsigned long flags
;
2997 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3002 inst
.error
= _("r15 not allowed in swap");
3006 if (skip_past_comma (&str
) == FAIL
3007 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3010 inst
.error
= bad_args
;
3016 inst
.error
= _("r15 not allowed in swap");
3020 if (skip_past_comma (&str
) == FAIL
3023 inst
.error
= bad_args
;
3030 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3035 inst
.error
= bad_pc
;
3044 inst
.error
= _("missing ]");
3048 inst
.instruction
|= flags
;
3054 do_branch (str
, flags
)
3056 unsigned long flags
;
3058 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3060 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3061 inst
.reloc
.pc_rel
= 1;
3069 unsigned long flags
;
3076 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3080 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3089 unsigned long flags
;
3091 /* Co-processor data operation.
3092 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3096 if (co_proc_number (&str
) == FAIL
)
3099 inst
.error
= bad_args
;
3103 if (skip_past_comma (&str
) == FAIL
3104 || cp_opc_expr (&str
, 20,4) == FAIL
)
3107 inst
.error
= bad_args
;
3111 if (skip_past_comma (&str
) == FAIL
3112 || cp_reg_required_here (&str
, 12) == FAIL
)
3115 inst
.error
= bad_args
;
3119 if (skip_past_comma (&str
) == FAIL
3120 || cp_reg_required_here (&str
, 16) == FAIL
)
3123 inst
.error
= bad_args
;
3127 if (skip_past_comma (&str
) == FAIL
3128 || cp_reg_required_here (&str
, 0) == FAIL
)
3131 inst
.error
= bad_args
;
3135 if (skip_past_comma (&str
) == SUCCESS
)
3137 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3140 inst
.error
= bad_args
;
3150 do_lstc (str
, flags
)
3152 unsigned long flags
;
3154 /* Co-processor register load/store.
3155 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3160 if (co_proc_number (&str
) == FAIL
)
3163 inst
.error
= bad_args
;
3167 if (skip_past_comma (&str
) == FAIL
3168 || cp_reg_required_here (&str
, 12) == FAIL
)
3171 inst
.error
= bad_args
;
3175 if (skip_past_comma (&str
) == FAIL
3176 || cp_address_required_here (&str
) == FAIL
)
3179 inst
.error
= bad_args
;
3183 inst
.instruction
|= flags
;
3189 do_co_reg (str
, flags
)
3191 unsigned long flags
;
3193 /* Co-processor register transfer.
3194 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3199 if (co_proc_number (&str
) == FAIL
)
3202 inst
.error
= bad_args
;
3206 if (skip_past_comma (&str
) == FAIL
3207 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3210 inst
.error
= bad_args
;
3214 if (skip_past_comma (&str
) == FAIL
3215 || reg_required_here (&str
, 12) == FAIL
)
3218 inst
.error
= bad_args
;
3222 if (skip_past_comma (&str
) == FAIL
3223 || cp_reg_required_here (&str
, 16) == FAIL
)
3226 inst
.error
= bad_args
;
3230 if (skip_past_comma (&str
) == FAIL
3231 || cp_reg_required_here (&str
, 0) == FAIL
)
3234 inst
.error
= bad_args
;
3238 if (skip_past_comma (&str
) == SUCCESS
)
3240 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3243 inst
.error
= bad_args
;
3253 do_fp_ctrl (str
, flags
)
3255 unsigned long flags
;
3257 /* FP control registers.
3258 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3263 if (reg_required_here (&str
, 12) == FAIL
)
3266 inst
.error
= bad_args
;
3275 do_fp_ldst (str
, flags
)
3277 unsigned long flags
;
3282 switch (inst
.suffix
)
3287 inst
.instruction
|= CP_T_X
;
3290 inst
.instruction
|= CP_T_Y
;
3293 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3299 if (fp_reg_required_here (&str
, 12) == FAIL
)
3302 inst
.error
= bad_args
;
3306 if (skip_past_comma (&str
) == FAIL
3307 || cp_address_required_here (&str
) == FAIL
)
3310 inst
.error
= bad_args
;
3318 do_fp_ldmstm (str
, flags
)
3320 unsigned long flags
;
3327 if (fp_reg_required_here (&str
, 12) == FAIL
)
3330 inst
.error
= bad_args
;
3334 /* Get Number of registers to transfer */
3335 if (skip_past_comma (&str
) == FAIL
3336 || my_get_expression (&inst
.reloc
.exp
, &str
))
3339 inst
.error
= _("constant expression expected");
3343 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3345 inst
.error
= _("Constant value required for number of registers");
3349 num_regs
= inst
.reloc
.exp
.X_add_number
;
3351 if (num_regs
< 1 || num_regs
> 4)
3353 inst
.error
= _("number of registers must be in the range [1:4]");
3360 inst
.instruction
|= CP_T_X
;
3363 inst
.instruction
|= CP_T_Y
;
3366 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3380 /* The instruction specified "ea" or "fd", so we can only accept
3381 [Rn]{!}. The instruction does not really support stacking or
3382 unstacking, so we have to emulate these by setting appropriate
3383 bits and offsets. */
3384 if (skip_past_comma (&str
) == FAIL
3388 inst
.error
= bad_args
;
3396 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3404 inst
.error
= bad_args
;
3415 inst
.error
= _("R15 not allowed as base register with write-back");
3422 if (flags
& CP_T_Pre
)
3425 offset
= 3 * num_regs
;
3431 /* Post-increment */
3435 offset
= 3 * num_regs
;
3439 /* No write-back, so convert this into a standard pre-increment
3440 instruction -- aesthetically more pleasing. */
3441 flags
= CP_T_Pre
| CP_T_UD
;
3446 inst
.instruction
|= flags
| offset
;
3448 else if (skip_past_comma (&str
) == FAIL
3449 || cp_address_required_here (&str
) == FAIL
)
3452 inst
.error
= bad_args
;
3460 do_fp_dyadic (str
, flags
)
3462 unsigned long flags
;
3467 switch (inst
.suffix
)
3472 inst
.instruction
|= 0x00000080;
3475 inst
.instruction
|= 0x00080000;
3481 if (fp_reg_required_here (&str
, 12) == FAIL
)
3484 inst
.error
= bad_args
;
3488 if (skip_past_comma (&str
) == FAIL
3489 || fp_reg_required_here (&str
, 16) == FAIL
)
3492 inst
.error
= bad_args
;
3496 if (skip_past_comma (&str
) == FAIL
3497 || fp_op2 (&str
) == FAIL
)
3500 inst
.error
= bad_args
;
3504 inst
.instruction
|= flags
;
3510 do_fp_monadic (str
, flags
)
3512 unsigned long flags
;
3517 switch (inst
.suffix
)
3522 inst
.instruction
|= 0x00000080;
3525 inst
.instruction
|= 0x00080000;
3531 if (fp_reg_required_here (&str
, 12) == FAIL
)
3534 inst
.error
= bad_args
;
3538 if (skip_past_comma (&str
) == FAIL
3539 || fp_op2 (&str
) == FAIL
)
3542 inst
.error
= bad_args
;
3546 inst
.instruction
|= flags
;
3552 do_fp_cmp (str
, flags
)
3554 unsigned long flags
;
3559 if (fp_reg_required_here (&str
, 16) == FAIL
)
3562 inst
.error
= bad_args
;
3566 if (skip_past_comma (&str
) == FAIL
3567 || fp_op2 (&str
) == FAIL
)
3570 inst
.error
= bad_args
;
3574 inst
.instruction
|= flags
;
3580 do_fp_from_reg (str
, flags
)
3582 unsigned long flags
;
3587 switch (inst
.suffix
)
3592 inst
.instruction
|= 0x00000080;
3595 inst
.instruction
|= 0x00080000;
3601 if (fp_reg_required_here (&str
, 16) == FAIL
)
3604 inst
.error
= bad_args
;
3608 if (skip_past_comma (&str
) == FAIL
3609 || reg_required_here (&str
, 12) == FAIL
)
3612 inst
.error
= bad_args
;
3616 inst
.instruction
|= flags
;
3622 do_fp_to_reg (str
, flags
)
3624 unsigned long flags
;
3629 if (reg_required_here (&str
, 12) == FAIL
)
3632 if (skip_past_comma (&str
) == FAIL
3633 || fp_reg_required_here (&str
, 0) == FAIL
)
3636 inst
.error
= bad_args
;
3640 inst
.instruction
|= flags
;
3645 /* Thumb specific routines */
3647 /* Parse and validate that a register is of the right form, this saves
3648 repeated checking of this information in many similar cases.
3649 Unlike the 32-bit case we do not insert the register into the opcode
3650 here, since the position is often unknown until the full instruction
3653 thumb_reg (strp
, hi_lo
)
3659 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3667 inst
.error
= _("lo register required");
3675 inst
.error
= _("hi register required");
3687 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3690 thumb_add_sub (str
, subtract
)
3694 int Rd
, Rs
, Rn
= FAIL
;
3699 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3700 || skip_past_comma (&str
) == FAIL
)
3703 inst
.error
= bad_args
;
3711 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3716 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3719 if (skip_past_comma (&str
) == FAIL
)
3721 /* Two operand format, shuffle the registers and pretend there
3726 else if (*str
== '#')
3729 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3732 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3736 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3737 for the latter case, EXPR contains the immediate that was found. */
3740 /* All register format. */
3741 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
3745 inst
.error
= _("dest and source1 must be the same register");
3749 /* Can't do this for SUB */
3752 inst
.error
= _("subtract valid only on lo regs");
3756 inst
.instruction
= (T_OPCODE_ADD_HI
3757 | (Rd
> 7 ? THUMB_H1
: 0)
3758 | (Rn
> 7 ? THUMB_H2
: 0));
3759 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
3763 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
3764 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
3769 /* Immediate expression, now things start to get nasty. */
3771 /* First deal with HI regs, only very restricted cases allowed:
3772 Adjusting SP, and using PC or SP to get an address. */
3773 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
3774 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
3776 inst
.error
= _("invalid Hi register with immediate");
3780 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3782 /* Value isn't known yet, all we can do is store all the fragments
3783 we know about in the instruction and let the reloc hacking
3785 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
3786 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
3790 int offset
= inst
.reloc
.exp
.X_add_number
;
3800 /* Quick check, in case offset is MIN_INT */
3803 inst
.error
= _("immediate value out of range");
3812 if (offset
& ~0x1fc)
3814 inst
.error
= _("invalid immediate value for stack adjust");
3817 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
3818 inst
.instruction
|= offset
>> 2;
3820 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
3823 || (offset
& ~0x3fc))
3825 inst
.error
= _("invalid immediate for address calculation");
3828 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
3830 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
3836 inst
.error
= _("immediate value out of range");
3839 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
3840 inst
.instruction
|= (Rd
<< 8) | offset
;
3846 inst
.error
= _("immediate value out of range");
3849 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
3850 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
3858 thumb_shift (str
, shift
)
3862 int Rd
, Rs
, Rn
= FAIL
;
3867 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
3868 || skip_past_comma (&str
) == FAIL
)
3871 inst
.error
= bad_args
;
3877 /* Two operand immediate format, set Rs to Rd. */
3880 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3885 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
3888 if (skip_past_comma (&str
) == FAIL
)
3890 /* Two operand format, shuffle the registers and pretend there
3895 else if (*str
== '#')
3898 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3901 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
3905 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3906 for the latter case, EXPR contains the immediate that was found. */
3912 inst
.error
= _("source1 and dest must be same register");
3918 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
3919 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
3920 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
3923 inst
.instruction
|= Rd
| (Rn
<< 3);
3929 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
3930 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
3931 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
3934 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3936 /* Value isn't known yet, create a dummy reloc and let reloc
3937 hacking fix it up */
3939 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
3943 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
3945 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
3947 inst
.error
= _("Invalid immediate for shift");
3951 /* Shifts of zero are handled by converting to LSL */
3952 if (shift_value
== 0)
3953 inst
.instruction
= T_OPCODE_LSL_I
;
3955 /* Shifts of 32 are encoded as a shift of zero */
3956 if (shift_value
== 32)
3959 inst
.instruction
|= shift_value
<< 6;
3962 inst
.instruction
|= Rd
| (Rs
<< 3);
3968 thumb_mov_compare (str
, move
)
3977 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3978 || skip_past_comma (&str
) == FAIL
)
3981 inst
.error
= bad_args
;
3988 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3991 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3996 if (Rs
< 8 && Rd
< 8)
3998 if (move
== THUMB_MOVE
)
3999 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4000 since a MOV instruction produces unpredictable results */
4001 inst
.instruction
= T_OPCODE_ADD_I3
;
4003 inst
.instruction
= T_OPCODE_CMP_LR
;
4004 inst
.instruction
|= Rd
| (Rs
<< 3);
4008 if (move
== THUMB_MOVE
)
4009 inst
.instruction
= T_OPCODE_MOV_HR
;
4011 inst
.instruction
= T_OPCODE_CMP_HR
;
4014 inst
.instruction
|= THUMB_H1
;
4017 inst
.instruction
|= THUMB_H2
;
4019 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4026 inst
.error
= _("only lo regs allowed with immediate");
4030 if (move
== THUMB_MOVE
)
4031 inst
.instruction
= T_OPCODE_MOV_I8
;
4033 inst
.instruction
= T_OPCODE_CMP_I8
;
4035 inst
.instruction
|= Rd
<< 8;
4037 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4038 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4041 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4045 inst
.error
= _("invalid immediate");
4049 inst
.instruction
|= value
;
4057 thumb_load_store (str
, load_store
, size
)
4062 int Rd
, Rb
, Ro
= FAIL
;
4067 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4068 || skip_past_comma (&str
) == FAIL
)
4071 inst
.error
= bad_args
;
4078 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4081 if (skip_past_comma (&str
) != FAIL
)
4086 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4089 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4094 inst
.reloc
.exp
.X_op
= O_constant
;
4095 inst
.reloc
.exp
.X_add_number
= 0;
4100 inst
.error
= _("expected ']'");
4105 else if (*str
== '=')
4107 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4113 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4118 if ( inst
.reloc
.exp
.X_op
!= O_constant
4119 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4121 inst
.error
= "Constant expression expected";
4125 if (inst
.reloc
.exp
.X_op
== O_constant
4126 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4128 /* This can be done with a mov instruction */
4130 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4131 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4135 /* Insert into literal pool */
4136 if (add_to_lit_pool () == FAIL
)
4139 inst
.error
= "literal pool insertion failed";
4143 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4144 inst
.reloc
.pc_rel
= 1;
4145 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4146 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4152 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4155 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4156 inst
.reloc
.pc_rel
= 1;
4157 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4158 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4163 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4165 if (size
!= THUMB_WORD
)
4167 inst
.error
= _("byte or halfword not valid for base register");
4170 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4172 inst
.error
= _("R15 based store not allowed");
4175 else if (Ro
!= FAIL
)
4177 inst
.error
= _("Invalid base register for register offset");
4182 inst
.instruction
= T_OPCODE_LDR_PC
;
4183 else if (load_store
== THUMB_LOAD
)
4184 inst
.instruction
= T_OPCODE_LDR_SP
;
4186 inst
.instruction
= T_OPCODE_STR_SP
;
4188 inst
.instruction
|= Rd
<< 8;
4189 if (inst
.reloc
.exp
.X_op
== O_constant
)
4191 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4193 if (offset
& ~0x3fc)
4195 inst
.error
= _("invalid offset");
4199 inst
.instruction
|= offset
>> 2;
4202 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4206 inst
.error
= _("invalid base register in load/store");
4209 else if (Ro
== FAIL
)
4211 /* Immediate offset */
4212 if (size
== THUMB_WORD
)
4213 inst
.instruction
= (load_store
== THUMB_LOAD
4214 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4215 else if (size
== THUMB_HALFWORD
)
4216 inst
.instruction
= (load_store
== THUMB_LOAD
4217 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4219 inst
.instruction
= (load_store
== THUMB_LOAD
4220 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4222 inst
.instruction
|= Rd
| (Rb
<< 3);
4224 if (inst
.reloc
.exp
.X_op
== O_constant
)
4226 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4228 if (offset
& ~(0x1f << size
))
4230 inst
.error
= _("Invalid offset");
4233 inst
.instruction
|= (offset
>> size
) << 6;
4236 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4240 /* Register offset */
4241 if (size
== THUMB_WORD
)
4242 inst
.instruction
= (load_store
== THUMB_LOAD
4243 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4244 else if (size
== THUMB_HALFWORD
)
4245 inst
.instruction
= (load_store
== THUMB_LOAD
4246 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4248 inst
.instruction
= (load_store
== THUMB_LOAD
4249 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4251 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4266 /* Handle the Format 4 instructions that do not have equivalents in other
4267 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4278 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4281 if (skip_past_comma (&str
) == FAIL
4282 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4285 inst
.error
= bad_args
;
4289 if (skip_past_comma (&str
) != FAIL
)
4291 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4292 (It isn't allowed for CMP either, but that isn't handled by this
4294 if (inst
.instruction
== T_OPCODE_TST
4295 || inst
.instruction
== T_OPCODE_CMN
4296 || inst
.instruction
== T_OPCODE_NEG
4297 || inst
.instruction
== T_OPCODE_MVN
)
4299 inst
.error
= bad_args
;
4303 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4308 inst
.error
= _("dest and source1 one must be the same register");
4314 if (inst
.instruction
== T_OPCODE_MUL
4316 as_tsktsk (_("Rs and Rd must be different in MUL"));
4318 inst
.instruction
|= Rd
| (Rs
<< 3);
4326 thumb_add_sub (str
, 0);
4333 thumb_shift (str
, THUMB_ASR
);
4340 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4342 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4343 inst
.reloc
.pc_rel
= 1;
4351 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4353 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4354 inst
.reloc
.pc_rel
= 1;
4358 /* Find the real, Thumb encoded start of a Thumb function. */
4361 find_real_start (symbolP
)
4365 const char * name
= S_GET_NAME (symbolP
);
4366 symbolS
* new_target
;
4368 /* This definitonmust agree with the one in gcc/config/arm/thumb.c */
4369 #define STUB_NAME ".real_start_of"
4374 /* Names that start with '.' are local labels, not function entry points.
4375 The compiler may generate BL instructions to these labels because it
4376 needs to perform a branch to a far away location. */
4380 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4381 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4383 new_target
= symbol_find (real_start
);
4385 if (new_target
== NULL
)
4387 as_warn ("Failed to find real start of function: %s\n", name
);
4388 new_target
= symbolP
;
4401 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4403 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4404 inst
.reloc
.pc_rel
= 1;
4407 /* If the destination of the branch is a defined symbol which does not have
4408 the THUMB_FUNC attribute, then we must be calling a function which has
4409 the (interfacearm) attribute. We look for the Thumb entry point to that
4410 function and change the branch to refer to that function instead. */
4411 if ( inst
.reloc
.exp
.X_op
== O_symbol
4412 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4413 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4414 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4415 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4427 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4430 /* This sets THUMB_H2 from the top bit of reg. */
4431 inst
.instruction
|= reg
<< 3;
4433 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4434 should cause the alignment to be checked once it is known. This is
4435 because BX PC only works if the instruction is word aligned. */
4444 thumb_mov_compare (str
, THUMB_COMPARE
);
4457 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4461 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4465 if (skip_past_comma (&str
) == FAIL
4466 || (range
= reg_list (&str
)) == FAIL
)
4469 inst
.error
= bad_args
;
4473 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4475 /* This really doesn't seem worth it. */
4476 inst
.reloc
.type
= BFD_RELOC_NONE
;
4477 inst
.error
= _("Expression too complex");
4483 inst
.error
= _("only lo-regs valid in load/store multiple");
4487 inst
.instruction
|= (Rb
<< 8) | range
;
4495 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4502 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4509 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4521 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4522 || skip_past_comma (&str
) == FAIL
4524 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4525 || skip_past_comma (&str
) == FAIL
4526 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4530 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4534 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4542 thumb_shift (str
, THUMB_LSL
);
4549 thumb_shift (str
, THUMB_LSR
);
4556 thumb_mov_compare (str
, THUMB_MOVE
);
4568 if ((range
= reg_list (&str
)) == FAIL
)
4571 inst
.error
= bad_args
;
4575 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4577 /* This really doesn't seem worth it. */
4578 inst
.reloc
.type
= BFD_RELOC_NONE
;
4579 inst
.error
= _("Expression too complex");
4585 if ((inst
.instruction
== T_OPCODE_PUSH
4586 && (range
& ~0xff) == 1 << REG_LR
)
4587 || (inst
.instruction
== T_OPCODE_POP
4588 && (range
& ~0xff) == 1 << REG_PC
))
4590 inst
.instruction
|= THUMB_PP_PC_LR
;
4595 inst
.error
= _("invalid register list to push/pop instruction");
4600 inst
.instruction
|= range
;
4608 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4615 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4622 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4629 thumb_add_sub (str
, 1);
4639 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4642 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4651 /* This is a pseudo-op of the form "adr rd, label" to be converted
4652 into a relative address of the form "add rd, pc, #label-.-4" */
4656 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4657 || skip_past_comma (&str
) == FAIL
4658 || my_get_expression (&inst
.reloc
.exp
, &str
))
4661 inst
.error
= bad_args
;
4665 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4666 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4667 inst
.reloc
.pc_rel
= 1;
4668 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4676 int len
= strlen (reg_table
[entry
].name
) + 2;
4677 char * buf
= (char *) xmalloc (len
);
4678 char * buf2
= (char *) xmalloc (len
);
4681 #ifdef REGISTER_PREFIX
4682 buf
[i
++] = REGISTER_PREFIX
;
4685 strcpy (buf
+ i
, reg_table
[entry
].name
);
4687 for (i
= 0; buf
[i
]; i
++)
4688 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4692 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4693 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4697 insert_reg_alias (str
, regnum
)
4701 struct reg_entry
*new =
4702 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4703 char *name
= xmalloc (strlen (str
) + 1);
4707 new->number
= regnum
;
4709 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4713 set_constant_flonums ()
4717 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4718 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4727 if ((arm_ops_hsh
= hash_new ()) == NULL
4728 || (arm_tops_hsh
= hash_new ()) == NULL
4729 || (arm_cond_hsh
= hash_new ()) == NULL
4730 || (arm_shift_hsh
= hash_new ()) == NULL
4731 || (arm_reg_hsh
= hash_new ()) == NULL
4732 || (arm_psr_hsh
= hash_new ()) == NULL
)
4733 as_fatal (_("Virtual memory exhausted"));
4735 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4736 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4737 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4738 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4739 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4740 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4741 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4742 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4743 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4744 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4746 for (i
= 0; reg_table
[i
].name
; i
++)
4749 set_constant_flonums ();
4751 #if defined OBJ_COFF || defined OBJ_ELF
4753 unsigned int flags
= 0;
4755 /* Set the flags in the private structure */
4756 if (uses_apcs_26
) flags
|= F_APCS26
;
4757 if (support_interwork
) flags
|= F_INTERWORK
;
4758 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
4759 if (pic_code
) flags
|= F_PIC
;
4761 bfd_set_private_flags (stdoutput
, flags
);
4768 /* Record the CPU type as well */
4769 switch (cpu_variant
& ARM_CPU_MASK
)
4772 mach
= bfd_mach_arm_2
;
4775 case ARM_3
: /* also ARM_250 */
4776 mach
= bfd_mach_arm_2a
;
4780 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
4781 mach
= bfd_mach_arm_4
;
4784 case ARM_7
: /* also ARM_6 */
4785 mach
= bfd_mach_arm_3
;
4789 /* Catch special cases */
4790 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
4792 if (cpu_variant
& ARM_THUMB
)
4793 mach
= bfd_mach_arm_4T
;
4794 else if ((cpu_variant
& ARM_ARCHv4
) == ARM_ARCHv4
)
4795 mach
= bfd_mach_arm_4
;
4796 else if (cpu_variant
& ARM_LONGMUL
)
4797 mach
= bfd_mach_arm_3M
;
4800 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
4804 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4805 for use in the a.out file, and stores them in the array pointed to by buf.
4806 This knows about the endian-ness of the target machine and does
4807 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4808 2 (short) and 4 (long) Floating numbers are put out as a series of
4809 LITTLENUMS (shorts, here at least)
4812 md_number_to_chars (buf
, val
, n
)
4817 if (target_big_endian
)
4818 number_to_chars_bigendian (buf
, val
, n
);
4820 number_to_chars_littleendian (buf
, val
, n
);
4824 md_chars_to_number (buf
, n
)
4829 unsigned char *where
= (unsigned char *) buf
;
4831 if (target_big_endian
)
4836 result
|= (*where
++ & 255);
4844 result
|= (where
[n
] & 255);
4851 /* Turn a string in input_line_pointer into a floating point constant
4852 of type TYPE, and store the appropriate bytes in *litP. The number
4853 of LITTLENUMS emitted is stored in *sizeP . An error message is
4854 returned, or NULL on OK.
4856 Note that fp constants aren't represent in the normal way on the ARM.
4857 In big endian mode, things are as expected. However, in little endian
4858 mode fp constants are big-endian word-wise, and little-endian byte-wise
4859 within the words. For example, (double) 1.1 in big endian mode is
4860 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4861 the byte sequence 99 99 f1 3f 9a 99 99 99.
4863 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
4866 md_atof (type
, litP
, sizeP
)
4872 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4904 return _("Bad call to MD_ATOF()");
4907 t
= atof_ieee (input_line_pointer
, type
, words
);
4909 input_line_pointer
= t
;
4912 if (target_big_endian
)
4914 for (i
= 0; i
< prec
; i
++)
4916 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4922 /* For a 4 byte float the order of elements in `words' is 1 0. For an
4923 8 byte float the order is 1 0 3 2. */
4924 for (i
= 0; i
< prec
; i
+= 2)
4926 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4927 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4935 /* The knowledge of the PC's pipeline offset is built into the relocs
4936 for the ELF port and into the insns themselves for the COFF port. */
4938 md_pcrel_from (fixP
)
4942 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
4943 && fixP
->fx_subsy
== NULL
)
4946 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
4948 /* PC relative addressing on the Thumb is slightly odd
4949 as the bottom two bits of the PC are forced to zero
4950 for the calculation */
4951 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
4954 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
4957 /* Round up a section size to the appropriate boundary. */
4959 md_section_align (segment
, size
)
4964 /* Don't align the dwarf2 debug sections */
4965 if (!strncmp (segment
->name
, ".debug", 5))
4968 /* Round all sects to multiple of 4 */
4969 return (size
+ 3) & ~3;
4972 /* We have no need to default values of symbols. */
4976 md_undefined_symbol (name
)
4982 /* arm_reg_parse () := if it looks like a register, return its token and
4983 advance the pointer. */
4987 register char ** ccp
;
4989 char * start
= * ccp
;
4992 struct reg_entry
* reg
;
4994 #ifdef REGISTER_PREFIX
4995 if (*start
!= REGISTER_PREFIX
)
5000 #ifdef OPTIONAL_REGISTER_PREFIX
5001 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5005 if (!isalpha (*p
) || !is_name_beginner (*p
))
5009 while (isalpha (c
) || isdigit (c
) || c
== '_')
5013 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5027 register char ** ccp
;
5029 char * start
= * ccp
;
5032 CONST
struct asm_psr
* psr
;
5036 while (isalpha (c
) || c
== '_')
5040 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5053 md_apply_fix3 (fixP
, val
, seg
)
5058 offsetT value
= * val
;
5060 unsigned int newimm
;
5063 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5064 arm_fix_data
* arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5066 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5068 /* Note whether this will delete the relocation. */
5069 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5070 if ((fixP
->fx_addsy
== 0 || fixP
->fx_addsy
->sy_value
.X_op
== O_constant
)
5073 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5077 /* If this symbol is in a different section then we need to leave it for
5078 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5079 so we have to undo it's effects here. */
5082 if (fixP
->fx_addsy
!= NULL
5083 && S_IS_DEFINED (fixP
->fx_addsy
)
5084 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5086 if (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
5089 value
+= md_pcrel_from (fixP
);
5093 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc */
5095 switch (fixP
->fx_r_type
)
5097 case BFD_RELOC_ARM_IMMEDIATE
:
5098 newimm
= validate_immediate (value
);
5099 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5101 /* If the instruction will fail, see if we can fix things up by
5102 changing the opcode. */
5103 if (newimm
== (unsigned int) FAIL
5104 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5106 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5107 _("invalid constant after fixup\n"));
5111 newimm
|= (temp
& 0xfffff000);
5112 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5115 case BFD_RELOC_ARM_OFFSET_IMM
:
5117 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5119 as_bad (_("bad immediate value for offset (%d)"), val
);
5125 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5126 newval
&= 0xff7ff000;
5127 newval
|= value
| (sign
? INDEX_UP
: 0);
5128 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5131 case BFD_RELOC_ARM_OFFSET_IMM8
:
5132 case BFD_RELOC_ARM_HWLITERAL
:
5134 if ((value
= validate_offset_imm (value
, 1)) == FAIL
)
5136 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5137 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5138 _("invalid literal constant: pool needs to be closer\n"));
5140 as_bad (_("bad immediate value for offset (%d)"), value
);
5147 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5148 newval
&= 0xff7ff0f0;
5149 newval
|= ((value
>> 4) << 8) | value
& 0xf | (sign
? INDEX_UP
: 0);
5150 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5153 case BFD_RELOC_ARM_LITERAL
:
5158 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5160 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5161 _("invalid literal constant: pool needs to be closer\n"));
5165 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5166 newval
&= 0xff7ff000;
5167 newval
|= value
| (sign
? INDEX_UP
: 0);
5168 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5171 case BFD_RELOC_ARM_SHIFT_IMM
:
5172 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5173 if (((unsigned long) value
) > 32
5175 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5177 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5178 _("shift expression is too large"));
5183 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5184 else if (value
== 32)
5186 newval
&= 0xfffff07f;
5187 newval
|= (value
& 0x1f) << 7;
5188 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5191 case BFD_RELOC_ARM_SWI
:
5192 if (arm_data
->thumb_mode
)
5194 if (((unsigned long) value
) > 0xff)
5195 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5196 _("Invalid swi expression"));
5197 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5199 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5203 if (((unsigned long) value
) > 0x00ffffff)
5204 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5205 _("Invalid swi expression"));
5206 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5208 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5212 case BFD_RELOC_ARM_MULTI
:
5213 if (((unsigned long) value
) > 0xffff)
5214 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5215 _("Invalid expression in load/store multiple"));
5216 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5217 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5220 case BFD_RELOC_ARM_PCREL_BRANCH
:
5221 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5223 newval
&= 0xff000000;
5225 value
= fixP
->fx_offset
;
5228 value
= (value
>> 2) & 0x00ffffff;
5230 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5231 newval
= value
| (newval
& 0xff000000);
5232 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5235 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5236 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5238 addressT diff
= (newval
& 0xff) << 1;
5243 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5244 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5245 _("Branch out of range"));
5246 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5248 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5251 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5252 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5254 addressT diff
= (newval
& 0x7ff) << 1;
5259 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5260 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5261 _("Branch out of range"));
5262 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5264 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5267 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5272 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5273 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5274 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5275 if (diff
& 0x400000)
5278 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5279 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5280 _("Branch with link out of range"));
5282 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5283 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5284 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5285 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5290 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5291 md_number_to_chars (buf
, value
, 1);
5293 else if (!target_oabi
)
5295 value
= fixP
->fx_offset
;
5296 md_number_to_chars (buf
, value
, 1);
5302 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5303 md_number_to_chars (buf
, value
, 2);
5305 else if (!target_oabi
)
5307 value
= fixP
->fx_offset
;
5308 md_number_to_chars (buf
, value
, 2);
5315 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5316 md_number_to_chars (buf
, value
, 4);
5318 else if (!target_oabi
)
5320 value
= fixP
->fx_offset
;
5321 md_number_to_chars (buf
, value
, 4);
5326 case BFD_RELOC_ARM_CP_OFF_IMM
:
5328 if (value
< -1023 || value
> 1023 || (value
& 3))
5329 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5330 _("Illegal value for co-processor offset"));
5333 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5334 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5335 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5338 case BFD_RELOC_ARM_THUMB_OFFSET
:
5339 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5340 /* Exactly what ranges, and where the offset is inserted depends on
5341 the type of instruction, we can establish this from the top 4 bits */
5342 switch (newval
>> 12)
5344 case 4: /* PC load */
5345 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5346 forced to zero for these loads, so we will need to round
5347 up the offset if the instruction address is not word
5348 aligned (since the final address produced must be, and
5349 we can only describe word-aligned immediate offsets). */
5351 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5352 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5353 _("Invalid offset, target not word aligned (0x%08X)"),
5354 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5356 if ((value
+ 2) & ~0x3fe)
5357 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5358 _("Invalid offset"));
5360 /* Round up, since pc will be rounded down. */
5361 newval
|= (value
+ 2) >> 2;
5364 case 9: /* SP load/store */
5366 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5367 _("Invalid offset"));
5368 newval
|= value
>> 2;
5371 case 6: /* Word load/store */
5373 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5374 _("Invalid offset"));
5375 newval
|= value
<< 4; /* 6 - 2 */
5378 case 7: /* Byte load/store */
5380 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5381 _("Invalid offset"));
5382 newval
|= value
<< 6;
5385 case 8: /* Halfword load/store */
5387 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5388 _("Invalid offset"));
5389 newval
|= value
<< 5; /* 6 - 1 */
5393 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5394 "Unable to process relocation for thumb opcode: %x", newval
);
5397 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5400 case BFD_RELOC_ARM_THUMB_ADD
:
5401 /* This is a complicated relocation, since we use it for all of
5402 the following immediate relocations:
5405 9bit ADD/SUB SP word-aligned
5406 10bit ADD PC/SP word-aligned
5408 The type of instruction being processed is encoded in the
5414 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5416 int rd
= (newval
>> 4) & 0xf;
5417 int rs
= newval
& 0xf;
5418 int subtract
= newval
& 0x8000;
5423 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5424 _("Invalid immediate for stack address calculation"));
5425 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5426 newval
|= value
>> 2;
5428 else if (rs
== REG_PC
|| rs
== REG_SP
)
5432 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5433 _("Invalid immediate for address calculation (value = 0x%08X)"), value
);
5434 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5436 newval
|= value
>> 2;
5441 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5442 _("Invalid 8bit immediate"));
5443 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5444 newval
|= (rd
<< 8) | value
;
5449 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5450 _("Invalid 3bit immediate"));
5451 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5452 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5455 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5458 case BFD_RELOC_ARM_THUMB_IMM
:
5459 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5460 switch (newval
>> 11)
5462 case 0x04: /* 8bit immediate MOV */
5463 case 0x05: /* 8bit immediate CMP */
5464 if (value
< 0 || value
> 255)
5465 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5466 _("Invalid immediate: %d is too large"), value
);
5473 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5476 case BFD_RELOC_ARM_THUMB_SHIFT
:
5477 /* 5bit shift value (0..31) */
5478 if (value
< 0 || value
> 31)
5479 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5480 _("Illegal Thumb shift value: %d"), value
);
5481 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5482 newval
|= value
<< 6;
5483 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5486 case BFD_RELOC_VTABLE_INHERIT
:
5487 case BFD_RELOC_VTABLE_ENTRY
:
5491 case BFD_RELOC_NONE
:
5493 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5494 _("Bad relocation fixup type (%d)\n"), fixP
->fx_r_type
);
5500 /* Translate internal representation of relocation info to BFD target
5503 tc_gen_reloc (section
, fixp
)
5508 bfd_reloc_code_real_type code
;
5510 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5512 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
5513 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5515 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5517 if (fixp
->fx_pcrel
== 0)
5518 reloc
->addend
= fixp
->fx_offset
;
5520 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5522 reloc
->addend
= fixp
->fx_offset
;
5525 switch (fixp
->fx_r_type
)
5530 code
= BFD_RELOC_8_PCREL
;
5537 code
= BFD_RELOC_16_PCREL
;
5544 code
= BFD_RELOC_32_PCREL
;
5548 case BFD_RELOC_ARM_PCREL_BRANCH
:
5550 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5551 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5552 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5553 case BFD_RELOC_VTABLE_ENTRY
:
5554 case BFD_RELOC_VTABLE_INHERIT
:
5555 code
= fixp
->fx_r_type
;
5558 case BFD_RELOC_ARM_LITERAL
:
5559 case BFD_RELOC_ARM_HWLITERAL
:
5560 /* If this is called then the a literal has been referenced across
5561 a section boundry - possibly due to an implicit dump */
5562 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5563 _("Literal referenced across section boundry (Implicit dump?)"));
5566 case BFD_RELOC_ARM_IMMEDIATE
:
5567 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5568 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5572 case BFD_RELOC_ARM_OFFSET_IMM
:
5573 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5574 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5581 switch (fixp
->fx_r_type
)
5583 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5584 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5585 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5586 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5587 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5588 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5589 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5590 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5591 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5592 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5593 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5594 default: type
= "<unknown>"; break;
5596 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5597 _("Can not represent %s relocation in this object file format (%d)"),
5598 type
, fixp
->fx_pcrel
);
5603 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5605 if (reloc
->howto
== NULL
)
5607 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5608 _("Can not represent %s relocation in this object file format"),
5609 bfd_get_reloc_code_name (code
));
5617 md_estimate_size_before_relax (fragP
, segtype
)
5621 as_fatal (_("md_estimate_size_before_relax\n"));
5633 as_bad (inst
.error
);
5637 to
= frag_more (inst
.size
);
5638 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
5640 assert (inst
.size
== (2 * THUMB_SIZE
));
5641 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
5642 md_number_to_chars (to
+ 2, inst
.instruction
, THUMB_SIZE
);
5645 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
5647 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5648 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
5649 inst
.size
, & inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
5664 /* Align the instruction.
5665 This may not be the right thing to do but ... */
5666 /* arm_align (2, 0); */
5667 listing_prev_line (); /* Defined in listing.h */
5669 /* Align the previous label if needed. */
5670 if (last_label_seen
!= NULL
)
5672 last_label_seen
->sy_frag
= frag_now
;
5673 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
5674 S_SET_SEGMENT (last_label_seen
, now_seg
);
5677 memset (&inst
, '\0', sizeof (inst
));
5678 inst
.reloc
.type
= BFD_RELOC_NONE
;
5681 str
++; /* Skip leading white space */
5683 /* Scan up to the end of the op-code, which must end in white space or
5685 for (start
= p
= str
; *p
!= '\0'; p
++)
5691 as_bad (_("No operator -- statement `%s'\n"), str
);
5697 CONST
struct thumb_opcode
*opcode
;
5701 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
5705 inst
.instruction
= opcode
->value
;
5706 inst
.size
= opcode
->size
;
5707 (*opcode
->parms
)(p
);
5708 output_inst (start
);
5714 CONST
struct asm_opcode
*opcode
;
5716 inst
.size
= INSN_SIZE
;
5717 /* p now points to the end of the opcode, probably white space, but we
5718 have to break the opcode up in case it contains condionals and flags;
5719 keep trying with progressively smaller basic instructions until one
5720 matches, or we run out of opcode. */
5721 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
5722 for (; q
!= str
; q
--)
5726 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
5728 if (opcode
&& opcode
->template)
5730 unsigned long flag_bits
= 0;
5733 /* Check that this instruction is supported for this CPU */
5734 if ((opcode
->variants
& cpu_variant
) == 0)
5737 inst
.instruction
= opcode
->value
;
5738 if (q
== p
) /* Just a simple opcode */
5740 if (opcode
->comp_suffix
!= 0)
5741 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
5742 opcode
->comp_suffix
);
5745 inst
.instruction
|= COND_ALWAYS
;
5746 (*opcode
->parms
)(q
, 0);
5748 output_inst (start
);
5752 /* Now check for a conditional */
5756 CONST
struct asm_cond
*cond
;
5760 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
5764 if (cond
->value
== 0xf0000000)
5766 _("Warning: Use of the 'nv' conditional is deprecated\n"));
5768 inst
.instruction
|= cond
->value
;
5772 inst
.instruction
|= COND_ALWAYS
;
5775 inst
.instruction
|= COND_ALWAYS
;
5777 /* if there is a compulsory suffix, it should come here, before
5778 any optional flags. */
5779 if (opcode
->comp_suffix
)
5781 CONST
char *s
= opcode
->comp_suffix
;
5793 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
5794 opcode
->comp_suffix
);
5801 /* The remainder, if any should now be flags for the instruction;
5802 Scan these checking each one found with the opcode. */
5806 CONST
struct asm_flg
*flag
= opcode
->flags
;
5815 for (flagno
= 0; flag
[flagno
].template; flagno
++)
5817 if (! strcmp (r
, flag
[flagno
].template))
5819 flag_bits
|= flag
[flagno
].set_bits
;
5825 if (! flag
[flagno
].template)
5832 (*opcode
->parms
) (p
, flag_bits
);
5833 output_inst (start
);
5842 /* It wasn't an instruction, but it might be a register alias of the form
5852 if (*q
&& !strncmp (q
, ".req ", 4))
5855 char * copy_of_str
= str
;
5862 for (r
= q
; *r
!= '\0'; r
++)
5872 regnum
= arm_reg_parse (& q
);
5875 reg
= arm_reg_parse (& str
);
5881 insert_reg_alias (str
, regnum
);
5885 as_warn (_("register '%s' does not exist\n"), q
);
5888 else if (regnum
!= FAIL
)
5891 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
5893 /* Do not warn abpout redefinitions to the same alias. */
5896 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
5900 as_warn (_("ignoring incomplete .req pseuso op"));
5907 as_bad (_("bad instruction `%s'"), start
);
5912 * Invocation line includes a switch not recognized by the base assembler.
5913 * See if it's a processor-specific option. These are:
5914 * Cpu variants, the arm part is optional:
5915 * -m[arm]1 Currently not supported.
5916 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
5917 * -m[arm]3 Arm 3 processor
5918 * -m[arm]6[xx], Arm 6 processors
5919 * -m[arm]7[xx][t][[d]m] Arm 7 processors
5920 * -mstrongarm[110] Arm 8 processors
5921 * -mall All (except the ARM1)
5923 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
5924 * -mfpe-old (No float load/store multiples)
5925 * -mno-fpu Disable all floating point instructions
5926 * Run-time endian selection:
5927 * -EB big endian cpu
5928 * -EL little endian cpu
5929 * ARM Procedure Calling Standard:
5930 * -mapcs-32 32 bit APCS
5931 * -mapcs-26 26 bit APCS
5932 * -mapcs-float Pass floats in float regs
5933 * -mapcs-reentrant Position independent code
5934 * -mthumb-interwork Code supports Arm/Thumb interworking
5935 * -moabi Old ELF ABI
5938 CONST
char * md_shortopts
= "m:";
5939 struct option md_longopts
[] =
5941 #ifdef ARM_BI_ENDIAN
5942 #define OPTION_EB (OPTION_MD_BASE + 0)
5943 {"EB", no_argument
, NULL
, OPTION_EB
},
5944 #define OPTION_EL (OPTION_MD_BASE + 1)
5945 {"EL", no_argument
, NULL
, OPTION_EL
},
5947 #define OPTION_OABI (OPTION_MD_BASE +2)
5948 {"oabi", no_argument
, NULL
, OPTION_OABI
},
5951 {NULL
, no_argument
, NULL
, 0}
5953 size_t md_longopts_size
= sizeof (md_longopts
);
5956 md_parse_option (c
, arg
)
5964 #ifdef ARM_BI_ENDIAN
5966 target_big_endian
= 1;
5969 target_big_endian
= 0;
5977 if (! strcmp (str
, "fpa10"))
5978 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
5979 else if (! strcmp (str
, "fpa11"))
5980 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
5981 else if (! strcmp (str
, "fpe-old"))
5982 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
5988 if (! strcmp (str
, "no-fpu"))
5989 cpu_variant
&= ~FPU_ALL
;
5994 if (!strcmp (str
, "oabi"))
6000 /* Limit assembler to generating only Thumb instructions: */
6001 if (! strcmp (str
, "thumb"))
6003 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
6004 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
6007 else if (! strcmp (str
, "thumb-interwork"))
6009 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
| ARM_ARCHv4
;
6010 #if defined OBJ_COFF || defined OBJ_ELF
6011 support_interwork
= true;
6019 if (! strcmp (str
, "all"))
6021 cpu_variant
= ARM_ALL
| FPU_ALL
;
6024 #if defined OBJ_COFF || defined OBJ_ELF
6025 if (! strncmp (str
, "apcs-", 5))
6027 /* GCC passes on all command line options starting "-mapcs-..."
6028 to us, so we must parse them here. */
6032 if (! strcmp (str
, "32"))
6034 uses_apcs_26
= false;
6037 else if (! strcmp (str
, "26"))
6039 uses_apcs_26
= true;
6042 else if (! strcmp (str
, "frame"))
6044 /* Stack frames are being generated - does not affect
6048 else if (! strcmp (str
, "stack-check"))
6050 /* Stack checking is being performed - does not affect
6051 linkage, but does require that the functions
6052 __rt_stkovf_split_small and __rt_stkovf_split_big be
6053 present in the final link. */
6057 else if (! strcmp (str
, "float"))
6059 /* Floating point arguments are being passed in the floating
6060 point registers. This does affect linking, since this
6061 version of the APCS is incompatible with the version that
6062 passes floating points in the integer registers. */
6064 uses_apcs_float
= true;
6067 else if (! strcmp (str
, "reentrant"))
6069 /* Reentrant code has been generated. This does affect
6070 linking, since there is no point in linking reentrant/
6071 position independent code with absolute position code. */
6076 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6080 /* Strip off optional "arm" */
6081 if (! strncmp (str
, "arm", 3))
6087 if (! strcmp (str
, "1"))
6088 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6094 if (! strcmp (str
, "2"))
6095 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6096 else if (! strcmp (str
, "250"))
6097 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6103 if (! strcmp (str
, "3"))
6104 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6110 if (! strcmp (str
, "strongarm") || ! strcmp (str
, "strongarm110"))
6111 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCHv4
| ARM_LONGMUL
;
6117 if (! strcmp (str
, "8"))
6118 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCHv4
| ARM_LONGMUL
;
6123 switch (strtol (str
, NULL
, 10))
6130 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6138 switch (strtol (str
, & str
, 10)) /* Eat the processor name */
6150 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6156 cpu_variant
|= (ARM_THUMB
| ARM_ARCHv4
);
6160 cpu_variant
|= ARM_LONGMUL
;
6163 case 'f': /* fe => fp enabled cpu. */
6169 case 'c': /* Unknown */
6170 case 'd': /* debug */
6171 case 'i': /* embedded ice */
6172 /* Included for completeness in ARM processor naming. */
6182 /* Select variant based on architecture rather than processor */
6188 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6189 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6190 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6195 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6199 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6201 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6206 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCHv4
;
6210 case 't': cpu_variant
|= ARM_THUMB
; break;
6212 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6217 as_bad (_("Invalid architecture variant -m%s"), arg
);
6224 as_bad (_("Invalid processor variant -m%s"), arg
);
6243 ARM Specific Assembler Options:\n\
6244 -m[arm][<processor name>] select processor variant\n\
6245 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
6246 -mthumb only allow Thumb instructions\n\
6247 -mthumb-interwork mark the assembled code as supporting interworking\n\
6248 -mall allow any instruction\n\
6249 -mfpa10, -mfpa11 select floating point architecture\n\
6250 -mfpe-old don't allow floating-point multiple instructions\n\
6251 -mno-fpu don't allow any floating-point instructions.\n"));
6252 #if defined OBJ_COFF || defined OBJ_ELF
6255 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6258 -mapcs-float floating point args are passed in FP regs\n"));
6261 -mapcs-reentrant the code is position independent/reentrant\n"));
6266 -moabi support the old ELF ABI\n"));
6268 #ifdef ARM_BI_ENDIAN
6271 -EB assemble code for a big endian cpu\n\
6272 -EL assemble code for a little endian cpu\n"));
6276 /* We need to be able to fix up arbitrary expressions in some statements.
6277 This is so that we can handle symbols that are an arbitrary distance from
6278 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6279 which returns part of an address in a form which will be valid for
6280 a data instruction. We do this by pushing the expression into a symbol
6281 in the expr_section, and creating a fix for that. */
6284 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6293 arm_fix_data
* arm_data
;
6301 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6305 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6310 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6311 arm_data
= (arm_fix_data
*) obstack_alloc (¬es
, sizeof (arm_fix_data
));
6312 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6313 arm_data
->thumb_mode
= thumb_mode
;
6318 /* A good place to do this, although this was probably not intended
6319 * for this kind of use. We need to dump the literal pool before
6320 * references are made to a null symbol pointer. */
6324 if (current_poolP
!= NULL
)
6326 subseg_set (text_section
, 0); /* Put it at the end of text section */
6328 listing_prev_line ();
6333 arm_start_line_hook ()
6335 last_label_seen
= NULL
;
6339 arm_frob_label (sym
)
6342 last_label_seen
= sym
;
6344 ARM_SET_THUMB (sym
, thumb_mode
);
6346 #if defined OBJ_COFF || defined OBJ_ELF
6347 ARM_SET_INTERWORK (sym
, support_interwork
);
6350 if (label_is_thumb_function_name
)
6352 /* When the address of a Thumb function is taken the bottom
6353 bit of that address should be set. This will allow
6354 interworking between Arm and Thumb functions to work
6357 THUMB_SET_FUNC (sym
, 1);
6359 label_is_thumb_function_name
= false;
6363 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6367 arm_adjust_symtab ()
6372 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6374 if (ARM_IS_THUMB (sym
))
6376 if (THUMB_IS_FUNC (sym
))
6378 /* Mark the symbol as a Thumb function. */
6379 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6380 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6381 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6383 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6384 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6386 as_bad (_("%s: unexpected function type: %d"),
6387 S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6389 else switch (S_GET_STORAGE_CLASS (sym
))
6392 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6395 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6398 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6400 default: /* do nothing */
6405 if (ARM_IS_INTERWORK (sym
))
6406 coffsymbol(sym
->bsym
)->native
->u
.syment
.n_flags
= 0xFF;
6411 elf_symbol_type
* elf_sym
;
6414 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6416 if (ARM_IS_THUMB (sym
))
6418 if (THUMB_IS_FUNC (sym
))
6420 elf_sym
= elf_symbol (sym
->bsym
);
6421 bind
= ELF_ST_BIND (elf_sym
);
6422 elf_sym
->internal_elf_sym
.st_info
= ELF_ST_INFO (bind
, STT_ARM_TFUNC
);
6432 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6434 *input_line_pointer
= '/';
6435 input_line_pointer
+= 5;
6436 *input_line_pointer
= 0;
6444 arm_canonicalize_symbol_name (name
)
6449 if (thumb_mode
&& (len
= strlen (name
)) > 5
6450 && ! strcmp (name
+ len
- 5, "/data"))
6452 *(name
+ len
- 5) = 0;
6459 arm_validate_fix (fixP
)
6462 /* If the destination of the branch is a defined symbol which does not have
6463 the THUMB_FUNC attribute, then we must be calling a function which has
6464 the (interfacearm) attribute. We look for the Thumb entry point to that
6465 function and change the branch to refer to that function instead. */
6466 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6467 && fixP
->fx_addsy
!= NULL
6468 && S_IS_DEFINED (fixP
->fx_addsy
)
6469 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6471 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);
6479 /* Relocations against Thumb function names must be left unadjusted,
6480 so that the linker can use this information to correctly set the
6481 bottom bit of their addresses. The MIPS version of this function
6482 also prevents relocations that are mips-16 specific, but I do not
6483 know why it does this.
6486 There is one other problem that ought to be addressed here, but
6487 which currently is not: Taking the address of a label (rather
6488 than a function) and then later jumping to that address. Such
6489 addresses also ought to have their bottom bit set (assuming that
6490 they reside in Thumb code), but at the moment they will not. */
6493 arm_fix_adjustable (fixP
)
6497 if (fixP
->fx_addsy
== NULL
)
6500 /* Prevent all adjustments to global symbols. */
6501 if (S_IS_EXTERN (fixP
->fx_addsy
))
6504 if (S_IS_WEAK (fixP
->fx_addsy
))
6507 if (THUMB_IS_FUNC (fixP
->fx_addsy
)
6508 && fixP
->fx_subsy
== NULL
)
6511 /* We need the symbol name for the VTABLE entries */
6512 if ( fixP
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6513 || fixP
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
6520 elf32_arm_target_format ()
6522 if (target_big_endian
)
6524 return "elf32-bigarm-oabi";
6526 return "elf32-bigarm";
6529 return "elf32-littlearm-oabi";
6531 return "elf32-littlearm";
6535 armelf_frob_symbol (symp
, puntp
)
6539 elf_frob_symbol (symp
, puntp
);
6543 arm_force_relocation (fixp
)
6546 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
6547 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
6548 || fixp
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
6554 #endif /* OBJ_ELF */