1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 1998 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 /* ??? This is currently unused. */
41 #define internalError() \
42 as_fatal (_("ARM Internal Error, line %d, %s"), __LINE__, __FILE__)
44 #define internalError() as_fatal (_("ARM Internal Error"))
47 /* Types of processor to assemble for. */
48 #define ARM_1 0x00000001
49 #define ARM_2 0x00000002
50 #define ARM_3 0x00000004
52 #define ARM_6 0x00000008
53 #define ARM_7 ARM_6 /* same core instruction set */
54 #define ARM_CPU_MASK 0x0000000f
56 /* The following bitmasks control CPU extensions (ARM7 onwards): */
57 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
58 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
59 #define ARM_THUMB 0x00000040 /* allow BX instruction */
61 #define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
63 /* Some useful combinations: */
64 #define ARM_ANY 0x00ffffff
65 #define ARM_2UP 0x00fffffe
66 #define ARM_ALL ARM_2UP /* Not arm1 only */
67 #define ARM_3UP 0x00fffffc
68 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
70 #define FPU_CORE 0x80000000
71 #define FPU_FPA10 0x40000000
72 #define FPU_FPA11 0x40000000
75 /* Some useful combinations */
76 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
77 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
82 #define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB)
84 #define CPU_DEFAULT ARM_ALL
89 #define FPU_DEFAULT FPU_ALL
92 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
94 #if defined OBJ_COFF || defined OBJ_ELF
95 /* Flags stored in private area of BFD structure */
96 static boolean uses_apcs_26
= false;
97 static boolean support_interwork
= false;
98 static boolean uses_apcs_float
= false;
99 static boolean pic_code
= false;
102 /* This array holds the chars that always start a comment. If the
103 pre-processor is disabled, these aren't very useful */
104 CONST
char comment_chars
[] = "@";
106 /* This array holds the chars that only start a comment at the beginning of
107 a line. If the line seems to have the form '# 123 filename'
108 .line and .file directives will appear in the pre-processed output */
109 /* Note that input_file.c hand checks for '#' at the beginning of the
110 first line of the input file. This is because the compiler outputs
111 #NO_APP at the beginning of its output. */
112 /* Also note that comments like this one will always work. */
113 CONST
char line_comment_chars
[] = "#";
115 CONST
char line_separator_chars
[] = "";
117 /* Chars that can be used to separate mant from exp in floating point nums */
118 CONST
char EXP_CHARS
[] = "eE";
120 /* Chars that mean this number is a floating point constant */
124 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
126 CONST
int md_reloc_size
= 8; /* Size of relocation record */
128 static int thumb_mode
= 0; /* non-zero if assembling thumb instructions */
130 typedef struct arm_fix
138 unsigned long instruction
;
143 bfd_reloc_code_real_type type
;
153 CONST
char *template;
157 static CONST
struct asm_shift shift
[] =
173 #define NO_SHIFT_RESTRICT 1
174 #define SHIFT_RESTRICT 0
176 #define NUM_FLOAT_VALS 8
178 CONST
char *fp_const
[] =
180 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
183 /* Number of littlenums required to hold an extended precision number */
184 #define MAX_LITTLENUMS 6
186 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
196 #define CP_T_X 0x00008000
197 #define CP_T_Y 0x00400000
198 #define CP_T_Pre 0x01000000
199 #define CP_T_UD 0x00800000
200 #define CP_T_WB 0x00200000
202 #define CONDS_BIT (0x00100000)
203 #define LOAD_BIT (0x00100000)
204 #define TRANS_BIT (0x00200000)
208 CONST
char *template;
212 /* This is to save a hash look-up in the common case */
213 #define COND_ALWAYS 0xe0000000
215 static CONST
struct asm_cond conds
[] =
219 {"cs", 0x20000000}, {"hs", 0x20000000},
220 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
235 /* Warning: If the top bit of the set_bits is set, then the standard
236 instruction bitmask is ignored, and the new bitmask is taken from
240 CONST
char *template; /* Basic flag string */
241 unsigned long set_bits
; /* Bits to set */
244 static CONST
struct asm_flg s_flag
[] =
250 static CONST
struct asm_flg ldr_flags
[] =
254 {"bt", 0x00400000 | TRANS_BIT
},
261 static CONST
struct asm_flg str_flags
[] =
265 {"bt", 0x00400000 | TRANS_BIT
},
270 static CONST
struct asm_flg byte_flag
[] =
276 static CONST
struct asm_flg cmp_flags
[] =
283 static CONST
struct asm_flg ldm_flags
[] =
296 static CONST
struct asm_flg stm_flags
[] =
309 static CONST
struct asm_flg lfm_flags
[] =
316 static CONST
struct asm_flg sfm_flags
[] =
323 static CONST
struct asm_flg round_flags
[] =
331 /* The implementation of the FIX instruction is broken on some assemblers,
332 in that it accepts a precision specifier as well as a rounding specifier,
333 despite the fact that this is meaningless. To be more compatible, we
334 accept it as well, though of course it does not set any bits. */
335 static CONST
struct asm_flg fix_flags
[] =
352 static CONST
struct asm_flg except_flag
[] =
358 static CONST
struct asm_flg cplong_flag
[] =
366 CONST
char *template;
367 unsigned long number
;
370 #define PSR_FIELD_MASK 0x000f0000
372 #define PSR_FLAGS 0x00080000
373 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
374 #define PSR_ALL 0x00090000
383 static CONST
struct asm_psr psrs
[] =
387 {"cpsr_all", CPSR_ALL
},
389 {"spsr_all", SPSR_ALL
},
392 {"cpsr_flg", CPSR_FLG
},
393 {"spsr_flg", SPSR_FLG
},
396 {"cpsr_c", CPSR_CTL
},
397 {"cpsr_ctl", CPSR_CTL
},
398 {"spsr_c", SPSR_CTL
},
399 {"spsr_ctl", SPSR_CTL
}
402 /* Functions called by parser */
403 /* ARM instructions */
404 static void do_arit
PARAMS ((char *operands
, unsigned long flags
));
405 static void do_cmp
PARAMS ((char *operands
, unsigned long flags
));
406 static void do_mov
PARAMS ((char *operands
, unsigned long flags
));
407 static void do_ldst
PARAMS ((char *operands
, unsigned long flags
));
408 static void do_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
409 static void do_branch
PARAMS ((char *operands
, unsigned long flags
));
410 static void do_swi
PARAMS ((char *operands
, unsigned long flags
));
411 /* Pseudo Op codes */
412 static void do_adr
PARAMS ((char *operands
, unsigned long flags
));
413 static void do_nop
PARAMS ((char *operands
, unsigned long flags
));
415 static void do_mul
PARAMS ((char *operands
, unsigned long flags
));
416 static void do_mla
PARAMS ((char *operands
, unsigned long flags
));
418 static void do_swap
PARAMS ((char *operands
, unsigned long flags
));
420 static void do_msr
PARAMS ((char *operands
, unsigned long flags
));
421 static void do_mrs
PARAMS ((char *operands
, unsigned long flags
));
423 static void do_mull
PARAMS ((char *operands
, unsigned long flags
));
425 static void do_bx
PARAMS ((char *operands
, unsigned long flags
));
427 /* Coprocessor Instructions */
428 static void do_cdp
PARAMS ((char *operands
, unsigned long flags
));
429 static void do_lstc
PARAMS ((char *operands
, unsigned long flags
));
430 static void do_co_reg
PARAMS ((char *operands
, unsigned long flags
));
431 static void do_fp_ctrl
PARAMS ((char *operands
, unsigned long flags
));
432 static void do_fp_ldst
PARAMS ((char *operands
, unsigned long flags
));
433 static void do_fp_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
434 static void do_fp_dyadic
PARAMS ((char *operands
, unsigned long flags
));
435 static void do_fp_monadic
PARAMS ((char *operands
, unsigned long flags
));
436 static void do_fp_cmp
PARAMS ((char *operands
, unsigned long flags
));
437 static void do_fp_from_reg
PARAMS ((char *operands
, unsigned long flags
));
438 static void do_fp_to_reg
PARAMS ((char *operands
, unsigned long flags
));
440 static void fix_new_arm
PARAMS ((fragS
*frag
, int where
,
441 short int size
, expressionS
*exp
,
442 int pc_rel
, int reloc
));
443 static int arm_reg_parse
PARAMS ((char **ccp
));
444 static int arm_psr_parse
PARAMS ((char **ccp
));
445 static void symbol_locate
PARAMS ((symbolS
*, CONST
char *, segT
,
447 static int add_to_lit_pool
PARAMS ((void));
448 static unsigned validate_immediate
PARAMS ((unsigned));
449 static int validate_offset_imm
PARAMS ((int, int));
450 static void opcode_select
PARAMS ((int));
451 static void end_of_line
PARAMS ((char *));
452 static int reg_required_here
PARAMS ((char **, int));
453 static int psr_required_here
PARAMS ((char **, int, int));
454 static int co_proc_number
PARAMS ((char **));
455 static int cp_opc_expr
PARAMS ((char **, int, int));
456 static int cp_reg_required_here
PARAMS ((char **, int));
457 static int fp_reg_required_here
PARAMS ((char **, int));
458 static int cp_address_offset
PARAMS ((char **));
459 static int cp_address_required_here
PARAMS ((char **));
460 static int my_get_float_expression
PARAMS ((char **));
461 static int skip_past_comma
PARAMS ((char **));
462 static int walk_no_bignums
PARAMS ((symbolS
*));
463 static int negate_data_op
PARAMS ((unsigned long *,
465 static int data_op2
PARAMS ((char **));
466 static int fp_op2
PARAMS ((char **));
467 static long reg_list
PARAMS ((char **));
468 static void thumb_load_store
PARAMS ((char *, int, int));
469 static int decode_shift
PARAMS ((char **, int));
470 static int ldst_extend
PARAMS ((char **, int));
471 static void thumb_add_sub
PARAMS ((char *, int));
472 static void insert_reg
PARAMS ((int));
473 static void thumb_shift
PARAMS ((char *, int));
474 static void thumb_mov_compare
PARAMS ((char *, int));
475 static void set_constant_flonums
PARAMS ((void));
476 static valueT md_chars_to_number
PARAMS ((char *, int));
477 static void insert_reg_alias
PARAMS ((char *, int));
478 static void output_inst
PARAMS ((char *));
480 /* ARM instructions take 4bytes in the object file, Thumb instructions
484 /* LONGEST_INST is the longest basic instruction name without conditions or
486 * ARM7M has 4 of length 5
489 #define LONGEST_INST 5
493 CONST
char *template; /* Basic string to match */
494 unsigned long value
; /* Basic instruction code */
495 CONST
char *comp_suffix
; /* Compulsory suffix that must follow conds */
496 CONST
struct asm_flg
*flags
; /* Bits to toggle if flag 'n' set */
497 unsigned long variants
; /* Which CPU variants this exists for */
498 /* Function to call to parse args */
499 void (*parms
) PARAMS ((char *, unsigned long));
502 static CONST
struct asm_opcode insns
[] =
504 /* ARM Instructions */
505 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
506 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
507 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
508 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
509 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
510 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
511 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
512 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
513 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
514 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
515 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
516 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
517 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
518 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
519 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
520 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
521 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
522 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
523 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
524 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
525 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
526 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
527 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
530 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
531 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
533 /* ARM 2 multiplies */
534 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
535 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
537 /* ARM 3 - swp instructions */
538 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
540 /* ARM 6 Coprocessor instructions */
541 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
542 {"msr", 0x0120f000, NULL
, NULL
, ARM_6UP
, do_msr
},
544 /* ARM 7M long multiplies - need signed/unsigned flags! */
545 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
546 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
547 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
548 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
550 /* ARM THUMB interworking */
551 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
553 /* Floating point instructions */
554 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
555 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
556 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
557 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
558 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
559 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
560 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
561 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
562 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
563 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
564 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
565 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
566 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
567 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
568 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
569 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
570 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
571 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
572 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
573 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
574 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
575 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
576 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
577 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
578 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
579 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
580 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
581 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
582 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
583 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
584 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
585 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
586 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
587 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
588 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
589 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
590 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
591 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
592 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
593 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
594 be an optional suffix, but part of the instruction. To be compatible,
596 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
597 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
598 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
599 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
601 /* Generic copressor instructions */
602 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
603 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
604 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
605 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
606 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
609 /* defines for various bits that we will want to toggle */
611 #define INST_IMMEDIATE 0x02000000
612 #define OFFSET_REG 0x02000000
613 #define HWOFFSET_IMM 0x00400000
614 #define SHIFT_BY_REG 0x00000010
615 #define PRE_INDEX 0x01000000
616 #define INDEX_UP 0x00800000
617 #define WRITE_BACK 0x00200000
618 #define MULTI_SET_PSR 0x00400000
620 #define LITERAL_MASK 0xf000f000
621 #define COND_MASK 0xf0000000
622 #define OPCODE_MASK 0xfe1fffff
623 #define DATA_OP_SHIFT 21
625 /* Codes to distinguish the arithmetic instructions */
637 #define OPCODE_CMP 10
638 #define OPCODE_CMN 11
639 #define OPCODE_ORR 12
640 #define OPCODE_MOV 13
641 #define OPCODE_BIC 14
642 #define OPCODE_MVN 15
644 static void do_t_nop
PARAMS ((char *operands
));
645 static void do_t_arit
PARAMS ((char *operands
));
646 static void do_t_add
PARAMS ((char *operands
));
647 static void do_t_asr
PARAMS ((char *operands
));
648 static void do_t_branch9
PARAMS ((char *operands
));
649 static void do_t_branch12
PARAMS ((char *operands
));
650 static void do_t_branch23
PARAMS ((char *operands
));
651 static void do_t_bx
PARAMS ((char *operands
));
652 static void do_t_compare
PARAMS ((char *operands
));
653 static void do_t_ldmstm
PARAMS ((char *operands
));
654 static void do_t_ldr
PARAMS ((char *operands
));
655 static void do_t_ldrb
PARAMS ((char *operands
));
656 static void do_t_ldrh
PARAMS ((char *operands
));
657 static void do_t_lds
PARAMS ((char *operands
));
658 static void do_t_lsl
PARAMS ((char *operands
));
659 static void do_t_lsr
PARAMS ((char *operands
));
660 static void do_t_mov
PARAMS ((char *operands
));
661 static void do_t_push_pop
PARAMS ((char *operands
));
662 static void do_t_str
PARAMS ((char *operands
));
663 static void do_t_strb
PARAMS ((char *operands
));
664 static void do_t_strh
PARAMS ((char *operands
));
665 static void do_t_sub
PARAMS ((char *operands
));
666 static void do_t_swi
PARAMS ((char *operands
));
667 static void do_t_adr
PARAMS ((char *operands
));
669 #define T_OPCODE_MUL 0x4340
670 #define T_OPCODE_TST 0x4200
671 #define T_OPCODE_CMN 0x42c0
672 #define T_OPCODE_NEG 0x4240
673 #define T_OPCODE_MVN 0x43c0
675 #define T_OPCODE_ADD_R3 0x1800
676 #define T_OPCODE_SUB_R3 0x1a00
677 #define T_OPCODE_ADD_HI 0x4400
678 #define T_OPCODE_ADD_ST 0xb000
679 #define T_OPCODE_SUB_ST 0xb080
680 #define T_OPCODE_ADD_SP 0xa800
681 #define T_OPCODE_ADD_PC 0xa000
682 #define T_OPCODE_ADD_I8 0x3000
683 #define T_OPCODE_SUB_I8 0x3800
684 #define T_OPCODE_ADD_I3 0x1c00
685 #define T_OPCODE_SUB_I3 0x1e00
687 #define T_OPCODE_ASR_R 0x4100
688 #define T_OPCODE_LSL_R 0x4080
689 #define T_OPCODE_LSR_R 0x40c0
690 #define T_OPCODE_ASR_I 0x1000
691 #define T_OPCODE_LSL_I 0x0000
692 #define T_OPCODE_LSR_I 0x0800
694 #define T_OPCODE_MOV_I8 0x2000
695 #define T_OPCODE_CMP_I8 0x2800
696 #define T_OPCODE_CMP_LR 0x4280
697 #define T_OPCODE_MOV_HR 0x4600
698 #define T_OPCODE_CMP_HR 0x4500
700 #define T_OPCODE_LDR_PC 0x4800
701 #define T_OPCODE_LDR_SP 0x9800
702 #define T_OPCODE_STR_SP 0x9000
703 #define T_OPCODE_LDR_IW 0x6800
704 #define T_OPCODE_STR_IW 0x6000
705 #define T_OPCODE_LDR_IH 0x8800
706 #define T_OPCODE_STR_IH 0x8000
707 #define T_OPCODE_LDR_IB 0x7800
708 #define T_OPCODE_STR_IB 0x7000
709 #define T_OPCODE_LDR_RW 0x5800
710 #define T_OPCODE_STR_RW 0x5000
711 #define T_OPCODE_LDR_RH 0x5a00
712 #define T_OPCODE_STR_RH 0x5200
713 #define T_OPCODE_LDR_RB 0x5c00
714 #define T_OPCODE_STR_RB 0x5400
716 #define T_OPCODE_PUSH 0xb400
717 #define T_OPCODE_POP 0xbc00
719 #define T_OPCODE_BRANCH 0xe7fe
721 static int thumb_reg
PARAMS ((char **str
, int hi_lo
));
723 #define THUMB_SIZE 2 /* Size of thumb instruction */
724 #define THUMB_REG_LO 0x1
725 #define THUMB_REG_HI 0x2
726 #define THUMB_REG_ANY 0x3
728 #define THUMB_H1 0x0080
729 #define THUMB_H2 0x0040
736 #define THUMB_COMPARE 1
739 #define THUMB_STORE 1
741 #define THUMB_PP_PC_LR 0x0100
743 /* These three are used for immediate shifts, do not alter */
745 #define THUMB_HALFWORD 1
750 CONST
char *template; /* Basic string to match */
751 unsigned long value
; /* Basic instruction code */
753 /* Function to call to parse args */
754 void (*parms
) PARAMS ((char *));
757 static CONST
struct thumb_opcode tinsns
[] =
759 {"adc", 0x4140, 2, do_t_arit
},
760 {"add", 0x0000, 2, do_t_add
},
761 {"and", 0x4000, 2, do_t_arit
},
762 {"asr", 0x0000, 2, do_t_asr
},
763 {"b", T_OPCODE_BRANCH
, 2, do_t_branch12
},
764 {"beq", 0xd0fe, 2, do_t_branch9
},
765 {"bne", 0xd1fe, 2, do_t_branch9
},
766 {"bcs", 0xd2fe, 2, do_t_branch9
},
767 {"bhs", 0xd2fe, 2, do_t_branch9
},
768 {"bcc", 0xd3fe, 2, do_t_branch9
},
769 {"bul", 0xd3fe, 2, do_t_branch9
},
770 {"blo", 0xd3fe, 2, do_t_branch9
},
771 {"bmi", 0xd4fe, 2, do_t_branch9
},
772 {"bpl", 0xd5fe, 2, do_t_branch9
},
773 {"bvs", 0xd6fe, 2, do_t_branch9
},
774 {"bvc", 0xd7fe, 2, do_t_branch9
},
775 {"bhi", 0xd8fe, 2, do_t_branch9
},
776 {"bls", 0xd9fe, 2, do_t_branch9
},
777 {"bge", 0xdafe, 2, do_t_branch9
},
778 {"blt", 0xdbfe, 2, do_t_branch9
},
779 {"bgt", 0xdcfe, 2, do_t_branch9
},
780 {"ble", 0xddfe, 2, do_t_branch9
},
781 {"bic", 0x4380, 2, do_t_arit
},
782 {"bl", 0xf7fffffe, 4, do_t_branch23
},
783 {"bx", 0x4700, 2, do_t_bx
},
784 {"cmn", T_OPCODE_CMN
, 2, do_t_arit
},
785 {"cmp", 0x0000, 2, do_t_compare
},
786 {"eor", 0x4040, 2, do_t_arit
},
787 {"ldmia", 0xc800, 2, do_t_ldmstm
},
788 {"ldr", 0x0000, 2, do_t_ldr
},
789 {"ldrb", 0x0000, 2, do_t_ldrb
},
790 {"ldrh", 0x0000, 2, do_t_ldrh
},
791 {"ldrsb", 0x5600, 2, do_t_lds
},
792 {"ldrsh", 0x5e00, 2, do_t_lds
},
793 {"ldsb", 0x5600, 2, do_t_lds
},
794 {"ldsh", 0x5e00, 2, do_t_lds
},
795 {"lsl", 0x0000, 2, do_t_lsl
},
796 {"lsr", 0x0000, 2, do_t_lsr
},
797 {"mov", 0x0000, 2, do_t_mov
},
798 {"mul", T_OPCODE_MUL
, 2, do_t_arit
},
799 {"mvn", T_OPCODE_MVN
, 2, do_t_arit
},
800 {"neg", T_OPCODE_NEG
, 2, do_t_arit
},
801 {"orr", 0x4300, 2, do_t_arit
},
802 {"pop", 0xbc00, 2, do_t_push_pop
},
803 {"push", 0xb400, 2, do_t_push_pop
},
804 {"ror", 0x41c0, 2, do_t_arit
},
805 {"sbc", 0x4180, 2, do_t_arit
},
806 {"stmia", 0xc000, 2, do_t_ldmstm
},
807 {"str", 0x0000, 2, do_t_str
},
808 {"strb", 0x0000, 2, do_t_strb
},
809 {"strh", 0x0000, 2, do_t_strh
},
810 {"swi", 0xdf00, 2, do_t_swi
},
811 {"sub", 0x0000, 2, do_t_sub
},
812 {"tst", T_OPCODE_TST
, 2, do_t_arit
},
814 {"adr", 0x0000, 2, do_t_adr
},
815 {"nop", 0x46C0, 2, do_t_nop
}, /* mov r8,r8 */
824 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
825 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
826 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
832 /* These are the standard names; Users can add aliases with .req */
833 static CONST
struct reg_entry reg_table
[] =
835 /* Processor Register Numbers */
836 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
837 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
838 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
839 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
840 /* APCS conventions */
841 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
842 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
843 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
844 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
846 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
847 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
848 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
849 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
850 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
851 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
852 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
853 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
854 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
855 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
859 #define bad_args _("Bad arguments to instruction");
860 #define bad_pc _("r15 not allowed here");
862 static struct hash_control
*arm_ops_hsh
= NULL
;
863 static struct hash_control
*arm_tops_hsh
= NULL
;
864 static struct hash_control
*arm_cond_hsh
= NULL
;
865 static struct hash_control
*arm_shift_hsh
= NULL
;
866 static struct hash_control
*arm_reg_hsh
= NULL
;
867 static struct hash_control
*arm_psr_hsh
= NULL
;
869 /* This table describes all the machine specific pseudo-ops the assembler
870 has to support. The fields are:
871 pseudo-op name without dot
872 function to call to execute this pseudo-op
873 Integer arg to pass to the function
876 static void s_req
PARAMS ((int));
877 static void s_align
PARAMS ((int));
878 static void s_bss
PARAMS ((int));
879 static void s_even
PARAMS ((int));
880 static void s_ltorg
PARAMS ((int));
881 static void s_arm
PARAMS ((int));
882 static void s_thumb
PARAMS ((int));
883 static void s_code
PARAMS ((int));
884 static void s_force_thumb
PARAMS ((int));
885 static void s_thumb_func
PARAMS ((int));
887 static int my_get_expression
PARAMS ((expressionS
*, char **));
889 CONST pseudo_typeS md_pseudo_table
[] =
891 {"req", s_req
, 0}, /* Never called becasue '.req' does not start line */
893 {"align", s_align
, 0},
895 {"thumb", s_thumb
, 0},
897 {"force_thumb", s_force_thumb
, 0},
898 {"thumb_func", s_thumb_func
, 0},
900 {"ltorg", s_ltorg
, 0},
901 {"pool", s_ltorg
, 0},
903 {"extend", float_cons
, 'x'},
904 {"ldouble", float_cons
, 'x'},
905 {"packed", float_cons
, 'p'},
909 /* Stuff needed to resolve the label ambiguity
919 symbolS
* last_label_seen
;
920 static int label_is_thumb_function_name
= false;
924 #define MAX_LITERAL_POOL_SIZE 1024
926 typedef struct literalS
928 struct expressionS exp
;
932 literalT literals
[MAX_LITERAL_POOL_SIZE
];
933 int next_literal_pool_place
= 0; /* Next free entry in the pool */
934 int lit_pool_num
= 1; /* Next literal pool number */
935 symbolS
*current_poolP
= NULL
;
936 symbolS
*symbol_make_empty
PARAMS ((void));
943 if (current_poolP
== NULL
)
944 current_poolP
= symbol_make_empty();
946 /* Check if this literal value is already in the pool: */
947 while (lit_count
< next_literal_pool_place
)
949 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
950 && inst
.reloc
.exp
.X_op
== O_constant
951 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
952 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
957 if (lit_count
== next_literal_pool_place
) /* new entry */
959 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
961 inst
.error
= _("Literal Pool Overflow");
965 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
966 lit_count
= next_literal_pool_place
++;
969 inst
.reloc
.exp
.X_op
= O_symbol
;
970 inst
.reloc
.exp
.X_add_number
= (lit_count
)*4-8;
971 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
976 /* Can't use symbol_new here, so have to create a symbol and then at
977 a later date assign it a value. Thats what these functions do */
979 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
981 CONST
char *name
; /* It is copied, the caller can modify */
982 segT segment
; /* Segment identifier (SEG_<something>) */
983 valueT valu
; /* Symbol value */
984 fragS
*frag
; /* Associated fragment */
986 unsigned int name_length
;
987 char *preserved_copy_of_name
;
989 name_length
= strlen (name
) + 1; /* +1 for \0 */
990 obstack_grow (¬es
, name
, name_length
);
991 preserved_copy_of_name
= obstack_finish (¬es
);
992 #ifdef STRIP_UNDERSCORE
993 if (preserved_copy_of_name
[0] == '_')
994 preserved_copy_of_name
++;
997 #ifdef tc_canonicalize_symbol_name
998 preserved_copy_of_name
=
999 tc_canonicalize_symbol_name (preserved_copy_of_name
);
1002 S_SET_NAME (symbolP
, preserved_copy_of_name
);
1004 S_SET_SEGMENT (symbolP
, segment
);
1005 S_SET_VALUE (symbolP
, valu
);
1006 symbol_clear_list_pointers(symbolP
);
1008 symbolP
->sy_frag
= frag
;
1011 * Link to end of symbol chain.
1014 extern int symbol_table_frozen
;
1015 if (symbol_table_frozen
)
1019 symbol_append (symbolP
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
1021 obj_symbol_new_hook (symbolP
);
1023 #ifdef tc_symbol_new_hook
1024 tc_symbol_new_hook (symbolP
);
1028 verify_symbol_chain(symbol_rootP
, symbol_lastP
);
1029 #endif /* DEBUG_SYMS */
1033 symbol_make_empty ()
1037 symbolP
= (symbolS
*) obstack_alloc (¬es
, sizeof (symbolS
));
1039 /* symbol must be born in some fixed state. This seems as good as any. */
1040 memset (symbolP
, 0, sizeof (symbolS
));
1042 symbolP
->bsym
= bfd_make_empty_symbol (stdoutput
);
1043 assert (symbolP
->bsym
!= 0);
1044 symbolP
->bsym
->udata
.p
= (PTR
) symbolP
;
1049 /* Check that an immediate is valid, and if so, convert it to the right format. */
1052 validate_immediate (val
)
1058 #define rotate_left(v, n) (v << n | v >> (32 - n))
1060 for (i
= 0; i
< 32; i
+= 2)
1061 if ((a
= rotate_left (val
, i
)) <= 0xff)
1062 return a
| (i
<< 7); /* 12-bit pack: [shift-cnt,const] */
1067 validate_offset_imm (val
, hwse
)
1071 if ((hwse
&& (val
< -255 || val
> 255))
1072 || (val
< -4095 || val
> 4095))
1082 as_bad (_("Invalid syntax for .req directive."));
1089 /* We don't support putting frags in the BSS segment, we fake it by
1090 marking in_bss, then looking at s_skip for clues?.. */
1091 subseg_set (bss_section
, 0);
1092 demand_empty_rest_of_line ();
1099 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1100 frag_align (1, 0, 0);
1101 record_alignment (now_seg
, 1);
1102 demand_empty_rest_of_line ();
1112 if (current_poolP
== NULL
)
1116 as_tsktsk (_("Nothing to put in the pool\n"));
1120 /* Align pool as you have word accesses */
1121 /* Only make a frag if we have to ... */
1123 frag_align (2, 0, 0);
1125 record_alignment (now_seg
, 2);
1128 as_tsktsk (_("Inserting implicit pool at change of section"));
1130 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1132 symbol_locate (current_poolP
, sym_name
, now_seg
,
1133 (valueT
) frag_now_fix (), frag_now
);
1134 symbol_table_insert (current_poolP
);
1136 ARM_SET_THUMB (current_poolP
, thumb_mode
);
1137 #if defined OBJ_COFF || defined OBJ_ELF
1138 ARM_SET_INTERWORK (current_poolP
, support_interwork
);
1141 while (lit_count
< next_literal_pool_place
)
1142 /* First output the expression in the instruction to the pool */
1143 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1145 next_literal_pool_place
= 0;
1146 current_poolP
= NULL
;
1149 #if 0 /* not used */
1151 arm_align (power
, fill
)
1155 /* Only make a frag if we HAVE to ... */
1156 if (power
&& !need_pass_2
)
1157 frag_align (power
, fill
, 0);
1159 record_alignment (now_seg
, power
);
1164 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1168 register long temp_fill
;
1169 long max_alignment
= 15;
1171 temp
= get_absolute_expression ();
1172 if (temp
> max_alignment
)
1173 as_bad (_("Alignment too large: %d. assumed."), temp
= max_alignment
);
1176 as_bad (_("Alignment negative. 0 assumed."));
1180 if (*input_line_pointer
== ',')
1182 input_line_pointer
++;
1183 temp_fill
= get_absolute_expression ();
1191 /* Only make a frag if we HAVE to. . . */
1192 if (temp
&& !need_pass_2
)
1193 frag_align (temp
, (int) temp_fill
, 0);
1194 demand_empty_rest_of_line ();
1196 record_alignment (now_seg
, temp
);
1200 s_force_thumb (ignore
)
1203 /* If we are not already in thumb mode go into it, EVEN if
1204 the target processor does not support thumb instructions.
1205 This is used by gcc/config/arm/lib1funcs.asm for example
1206 to compile interworking support functions even if the
1207 target processor should not support interworking. */
1213 record_alignment (now_seg
, 1);
1216 demand_empty_rest_of_line ();
1220 s_thumb_func (ignore
)
1223 /* The following label is the name/address of the start of a Thumb function.
1224 We need to know this for the interworking support. */
1226 label_is_thumb_function_name
= true;
1228 demand_empty_rest_of_line();
1232 opcode_select (width
)
1240 if (! (cpu_variant
& ARM_THUMB
))
1241 as_bad (_("selected processor does not support THUMB opcodes"));
1243 /* No need to force the alignment, since we will have been
1244 coming from ARM mode, which is word-aligned. */
1245 record_alignment (now_seg
, 1);
1252 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1253 as_bad (_("selected processor does not support ARM opcodes"));
1256 frag_align (2, 0, 0);
1257 record_alignment (now_seg
, 1);
1262 as_bad (_("invalid instruction size selected (%d)"), width
);
1271 demand_empty_rest_of_line ();
1279 demand_empty_rest_of_line ();
1288 temp
= get_absolute_expression ();
1293 opcode_select(temp
);
1297 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp
);
1309 inst
.error
= _("Garbage following instruction");
1313 skip_past_comma (str
)
1319 while ((c
= *p
) == ' ' || c
== ',')
1322 if (c
== ',' && comma
++)
1330 return comma
? SUCCESS
: FAIL
;
1333 /* A standard register must be given at this point. Shift is the place to
1334 put it in the instruction. */
1337 reg_required_here (str
, shift
)
1341 static char buff
[128]; /* XXX */
1345 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1348 inst
.instruction
|= reg
<< shift
;
1352 /* Restore the start point, we may have got a reg of the wrong class. */
1355 /* In the few cases where we might be able to accept something else
1356 this error can be overridden */
1357 sprintf (buff
, _("Register expected, not '%.100s'"), start
);
1364 psr_required_here (str
, cpsr
, spsr
)
1370 char * start
= *str
;
1371 psr
= arm_psr_parse (str
);
1373 if (psr
== cpsr
|| psr
== spsr
)
1376 inst
.instruction
|= 1 << 22;
1381 /* In the few cases where we might be able to accept something else
1382 this error can be overridden */
1383 inst
.error
= _("<psr(f)> expected");
1385 /* Restore the start point. */
1391 co_proc_number (str
)
1394 int processor
, pchar
;
1396 while (**str
== ' ')
1399 /* The data sheet seems to imply that just a number on its own is valid
1400 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1402 if (**str
== 'p' || **str
== 'P')
1406 if (pchar
>= '0' && pchar
<= '9')
1408 processor
= pchar
- '0';
1409 if (**str
>= '0' && **str
<= '9')
1411 processor
= processor
* 10 + *(*str
)++ - '0';
1414 inst
.error
= _("Illegal co-processor number");
1421 inst
.error
= _("Bad or missing co-processor number");
1425 inst
.instruction
|= processor
<< 8;
1430 cp_opc_expr (str
, where
, length
)
1437 while (**str
== ' ')
1440 memset (&expr
, '\0', sizeof (expr
));
1442 if (my_get_expression (&expr
, str
))
1444 if (expr
.X_op
!= O_constant
)
1446 inst
.error
= _("bad or missing expression");
1450 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1452 inst
.error
= _("immediate co-processor expression too large");
1456 inst
.instruction
|= expr
.X_add_number
<< where
;
1461 cp_reg_required_here (str
, where
)
1468 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1471 inst
.instruction
|= reg
<< where
;
1475 /* In the few cases where we might be able to accept something else
1476 this error can be overridden */
1477 inst
.error
= _("Co-processor register expected");
1479 /* Restore the start point */
1485 fp_reg_required_here (str
, where
)
1492 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1495 inst
.instruction
|= reg
<< where
;
1499 /* In the few cases where we might be able to accept something else
1500 this error can be overridden */
1501 inst
.error
= _("Floating point register expected");
1503 /* Restore the start point */
1509 cp_address_offset (str
)
1514 while (**str
== ' ')
1519 inst
.error
= _("immediate expression expected");
1524 if (my_get_expression (&inst
.reloc
.exp
, str
))
1526 if (inst
.reloc
.exp
.X_op
== O_constant
)
1528 offset
= inst
.reloc
.exp
.X_add_number
;
1531 inst
.error
= _("co-processor address must be word aligned");
1535 if (offset
> 1023 || offset
< -1023)
1537 inst
.error
= _("offset too large");
1542 inst
.instruction
|= INDEX_UP
;
1546 inst
.instruction
|= offset
>> 2;
1549 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1555 cp_address_required_here (str
)
1570 if ((reg
= reg_required_here (&p
, 16)) == FAIL
)
1579 if (skip_past_comma (&p
) == SUCCESS
)
1582 write_back
= WRITE_BACK
;
1585 inst
.error
= _("pc may not be used in post-increment");
1589 if (cp_address_offset (&p
) == FAIL
)
1593 pre_inc
= PRE_INDEX
| INDEX_UP
;
1597 /* '['Rn, #expr']'[!] */
1599 if (skip_past_comma (&p
) == FAIL
)
1601 inst
.error
= _("pre-indexed expression expected");
1605 pre_inc
= PRE_INDEX
;
1606 if (cp_address_offset (&p
) == FAIL
)
1614 inst
.error
= _("missing ]");
1625 inst
.error
= _("pc may not be used with write-back");
1630 write_back
= WRITE_BACK
;
1636 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1639 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1640 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1641 inst
.reloc
.pc_rel
= 1;
1642 inst
.instruction
|= (REG_PC
<< 16);
1643 pre_inc
= PRE_INDEX
;
1646 inst
.instruction
|= write_back
| pre_inc
;
1654 unsigned long flags
;
1656 /* Do nothing really */
1657 inst
.instruction
|= flags
; /* This is pointless */
1665 unsigned long flags
;
1667 /* Only one syntax */
1671 if (reg_required_here (&str
, 12) == FAIL
)
1673 inst
.error
= bad_args
;
1677 if (skip_past_comma (&str
) == FAIL
1678 || psr_required_here (& str
, CPSR_ALL
, SPSR_ALL
) == FAIL
)
1680 inst
.error
= _("<psr> expected");
1684 inst
.instruction
|= flags
;
1689 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1693 unsigned long flags
;
1700 if (psr_required_here (&str
, CPSR_ALL
, SPSR_ALL
) == SUCCESS
)
1702 inst
.instruction
|= PSR_ALL
;
1704 /* Sytax should be "<psr>, Rm" */
1705 if (skip_past_comma (&str
) == FAIL
1706 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1708 inst
.error
= bad_args
;
1714 if (psr_required_here (& str
, CPSR_FLG
, SPSR_FLG
) == SUCCESS
)
1716 inst
.instruction
|= PSR_FLAGS
;
1718 else if (psr_required_here (& str
, CPSR_CTL
, SPSR_CTL
) == SUCCESS
)
1720 inst
.instruction
|= PSR_CONTROL
;
1724 inst
.error
= bad_args
;
1728 if (skip_past_comma (&str
) == FAIL
)
1730 inst
.error
= bad_args
;
1734 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1736 if ((reg
= reg_required_here (&str
, 0)) != FAIL
)
1738 /* Immediate expression */
1739 else if (*(str
++) == '#')
1742 if (my_get_expression (&inst
.reloc
.exp
, &str
))
1744 inst
.error
= _("Register or shift expression expected");
1748 if (inst
.reloc
.exp
.X_add_symbol
)
1750 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1751 inst
.reloc
.pc_rel
= 0;
1755 unsigned value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1758 inst
.error
= _("Invalid constant");
1762 inst
.instruction
|= value
;
1765 flags
|= INST_IMMEDIATE
;
1769 inst
.error
= _("Error: unrecognised syntax for second argument to msr instruction");
1775 inst
.instruction
|= flags
;
1780 /* Long Multiply Parser
1781 UMULL RdLo, RdHi, Rm, Rs
1782 SMULL RdLo, RdHi, Rm, Rs
1783 UMLAL RdLo, RdHi, Rm, Rs
1784 SMLAL RdLo, RdHi, Rm, Rs
1787 do_mull (str
, flags
)
1789 unsigned long flags
;
1791 int rdlo
, rdhi
, rm
, rs
;
1793 /* only one format "rdlo, rdhi, rm, rs" */
1797 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1799 inst
.error
= bad_args
;
1803 if (skip_past_comma (&str
) == FAIL
1804 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1806 inst
.error
= bad_args
;
1810 if (skip_past_comma (&str
) == FAIL
1811 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1813 inst
.error
= bad_args
;
1817 /* rdhi, rdlo and rm must all be different */
1818 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1819 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1821 if (skip_past_comma (&str
) == FAIL
1822 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1824 inst
.error
= bad_args
;
1828 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1830 inst
.error
= bad_pc
;
1834 inst
.instruction
|= flags
;
1842 unsigned long flags
;
1846 /* only one format "rd, rm, rs" */
1850 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1852 inst
.error
= bad_args
;
1858 inst
.error
= bad_pc
;
1862 if (skip_past_comma (&str
) == FAIL
1863 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1865 inst
.error
= bad_args
;
1871 inst
.error
= bad_pc
;
1876 as_tsktsk (_("rd and rm should be different in mul"));
1878 if (skip_past_comma (&str
) == FAIL
1879 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
1881 inst
.error
= bad_args
;
1887 inst
.error
= bad_pc
;
1891 inst
.instruction
|= flags
;
1899 unsigned long flags
;
1903 /* only one format "rd, rm, rs, rn" */
1907 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1909 inst
.error
= bad_args
;
1915 inst
.error
= bad_pc
;
1919 if (skip_past_comma (&str
) == FAIL
1920 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1922 inst
.error
= bad_args
;
1928 inst
.error
= bad_pc
;
1933 as_tsktsk (_("rd and rm should be different in mla"));
1935 if (skip_past_comma (&str
) == FAIL
1936 || (rd
= reg_required_here (&str
, 8)) == FAIL
1937 || skip_past_comma (&str
) == FAIL
1938 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
1940 inst
.error
= bad_args
;
1944 if (rd
== REG_PC
|| rm
== REG_PC
)
1946 inst
.error
= bad_pc
;
1950 inst
.instruction
|= flags
;
1955 /* Returns the index into fp_values of a floating point number, or -1 if
1956 not in the table. */
1958 my_get_float_expression (str
)
1961 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1966 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
1967 /* Look for a raw floating point number */
1968 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
1969 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
1971 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
1973 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
1975 if (words
[j
] != fp_values
[i
][j
])
1979 if (j
== MAX_LITTLENUMS
)
1987 /* Try and parse a more complex expression, this will probably fail
1988 unless the code uses a floating point prefix (eg "0f") */
1989 save_in
= input_line_pointer
;
1990 input_line_pointer
= *str
;
1991 if (expression (&exp
) == absolute_section
1992 && exp
.X_op
== O_big
1993 && exp
.X_add_number
< 0)
1995 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
1997 if (gen_to_words (words
, 5, (long)15) == 0)
1999 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
2001 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
2003 if (words
[j
] != fp_values
[i
][j
])
2007 if (j
== MAX_LITTLENUMS
)
2009 *str
= input_line_pointer
;
2010 input_line_pointer
= save_in
;
2017 *str
= input_line_pointer
;
2018 input_line_pointer
= save_in
;
2022 /* Return true if anything in the expression is a bignum */
2024 walk_no_bignums (sp
)
2027 if (sp
->sy_value
.X_op
== O_big
)
2030 if (sp
->sy_value
.X_add_symbol
)
2032 return (walk_no_bignums (sp
->sy_value
.X_add_symbol
)
2033 || (sp
->sy_value
.X_op_symbol
2034 && walk_no_bignums (sp
->sy_value
.X_op_symbol
)));
2041 my_get_expression (ep
, str
)
2048 save_in
= input_line_pointer
;
2049 input_line_pointer
= *str
;
2050 seg
= expression (ep
);
2053 if (seg
!= absolute_section
2054 && seg
!= text_section
2055 && seg
!= data_section
2056 && seg
!= bss_section
2057 && seg
!= undefined_section
)
2059 inst
.error
= _("bad_segment");
2060 *str
= input_line_pointer
;
2061 input_line_pointer
= save_in
;
2066 /* Get rid of any bignums now, so that we don't generate an error for which
2067 we can't establish a line number later on. Big numbers are never valid
2068 in instructions, which is where this routine is always called. */
2069 if (ep
->X_op
== O_big
2070 || (ep
->X_add_symbol
2071 && (walk_no_bignums (ep
->X_add_symbol
)
2073 && walk_no_bignums (ep
->X_op_symbol
)))))
2075 inst
.error
= _("Invalid constant");
2076 *str
= input_line_pointer
;
2077 input_line_pointer
= save_in
;
2081 *str
= input_line_pointer
;
2082 input_line_pointer
= save_in
;
2086 /* unrestrict should be one if <shift> <register> is permitted for this
2090 decode_shift (str
, unrestrict
)
2094 struct asm_shift
*shft
;
2098 while (**str
== ' ')
2101 for (p
= *str
; isalpha (*p
); p
++)
2106 inst
.error
= _("Shift expression expected");
2112 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2116 if (!strncmp (*str
, "rrx", 3)
2117 || !strncmp (*str
, "RRX", 3))
2120 inst
.instruction
|= shft
->value
;
2127 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2129 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2137 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2140 /* Validate some simple #expressions */
2141 if (inst
.reloc
.exp
.X_op
== O_constant
)
2143 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2145 /* Reject operations greater than 32, or lsl #32 */
2146 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2148 inst
.error
= _("Invalid immediate shift");
2152 /* Shifts of zero should be converted to lsl (which is zero)*/
2159 /* Shifts of 32 are encoded as 0, for those shifts that
2164 inst
.instruction
|= (num
<< 7) | shft
->value
;
2169 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2170 inst
.reloc
.pc_rel
= 0;
2171 inst
.instruction
|= shft
->value
;
2177 inst
.error
= unrestrict
? _("shift requires register or #expression")
2178 : _("shift requires #expression");
2184 inst
.error
= _("Shift expression expected");
2188 /* Do those data_ops which can take a negative immediate constant */
2189 /* by altering the instuction. A bit of a hack really */
2193 by inverting the second operand, and
2196 by negating the second operand.
2199 negate_data_op (instruction
, value
)
2200 unsigned long *instruction
;
2201 unsigned long value
;
2204 unsigned long negated
, inverted
;
2206 negated
= validate_immediate (-value
);
2207 inverted
= validate_immediate (~value
);
2209 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2213 case OPCODE_SUB
: /* ADD <-> SUB */
2214 new_inst
= OPCODE_ADD
;
2219 new_inst
= OPCODE_SUB
;
2223 case OPCODE_CMP
: /* CMP <-> CMN */
2224 new_inst
= OPCODE_CMN
;
2229 new_inst
= OPCODE_CMP
;
2233 /* Now Inverted ops */
2234 case OPCODE_MOV
: /* MOV <-> MVN */
2235 new_inst
= OPCODE_MVN
;
2240 new_inst
= OPCODE_MOV
;
2244 case OPCODE_AND
: /* AND <-> BIC */
2245 new_inst
= OPCODE_BIC
;
2250 new_inst
= OPCODE_AND
;
2254 case OPCODE_ADC
: /* ADC <-> SBC */
2255 new_inst
= OPCODE_SBC
;
2260 new_inst
= OPCODE_ADC
;
2264 /* We cannot do anything */
2272 *instruction
&= OPCODE_MASK
;
2273 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2284 while (**str
== ' ')
2287 if (reg_required_here (str
, 0) != FAIL
)
2289 if (skip_past_comma (str
) == SUCCESS
)
2291 /* Shift operation on register */
2292 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2298 /* Immediate expression */
2299 if (*((*str
)++) == '#')
2302 if (my_get_expression (&inst
.reloc
.exp
, str
))
2305 if (inst
.reloc
.exp
.X_add_symbol
)
2307 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2308 inst
.reloc
.pc_rel
= 0;
2312 if (skip_past_comma (str
) == SUCCESS
)
2314 /* #x, y -- ie explicit rotation by Y */
2315 if (my_get_expression (&expr
, str
))
2318 if (expr
.X_op
!= O_constant
)
2320 inst
.error
= _("Constant expression expected");
2324 /* Rotate must be a multiple of 2 */
2325 if (((unsigned) expr
.X_add_number
) > 30
2326 || (expr
.X_add_number
& 1) != 0
2327 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2329 inst
.error
= _("Invalid constant");
2332 inst
.instruction
|= INST_IMMEDIATE
;
2333 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2334 inst
.instruction
|= expr
.X_add_number
<< 7;
2338 /* Implicit rotation, select a suitable one */
2339 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2343 /* Can't be done, perhaps the code reads something like
2344 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2345 if ((value
= negate_data_op (&inst
.instruction
,
2346 inst
.reloc
.exp
.X_add_number
))
2349 inst
.error
= _("Invalid constant");
2354 inst
.instruction
|= value
;
2357 inst
.instruction
|= INST_IMMEDIATE
;
2361 inst
.error
= _("Register or shift expression expected");
2370 while (**str
== ' ')
2373 if (fp_reg_required_here (str
, 0) != FAIL
)
2377 /* Immediate expression */
2378 if (*((*str
)++) == '#')
2383 while (**str
== ' ')
2386 /* First try and match exact strings, this is to guarantee that
2387 some formats will work even for cross assembly */
2389 for (i
= 0; fp_const
[i
]; i
++)
2391 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2395 *str
+= strlen (fp_const
[i
]);
2396 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2398 inst
.instruction
|= i
+ 8;
2405 /* Just because we didn't get a match doesn't mean that the
2406 constant isn't valid, just that it is in a format that we
2407 don't automatically recognize. Try parsing it with
2408 the standard expression routines. */
2409 if ((i
= my_get_float_expression (str
)) >= 0)
2411 inst
.instruction
|= i
+ 8;
2415 inst
.error
= _("Invalid floating point immediate expression");
2418 inst
.error
= _("Floating point register or immediate expression expected");
2424 do_arit (str
, flags
)
2426 unsigned long flags
;
2431 if (reg_required_here (&str
, 12) == FAIL
2432 || skip_past_comma (&str
) == FAIL
2433 || reg_required_here (&str
, 16) == FAIL
2434 || skip_past_comma (&str
) == FAIL
2435 || data_op2 (&str
) == FAIL
)
2438 inst
.error
= bad_args
;
2442 inst
.instruction
|= flags
;
2450 unsigned long flags
;
2452 /* This is a pseudo-op of the form "adr rd, label" to be converted
2453 into a relative address of the form "add rd, pc, #label-.-8" */
2458 if (reg_required_here (&str
, 12) == FAIL
2459 || skip_past_comma (&str
) == FAIL
2460 || my_get_expression (&inst
.reloc
.exp
, &str
))
2463 inst
.error
= bad_args
;
2466 /* Frag hacking will turn this into a sub instruction if the offset turns
2467 out to be negative. */
2468 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2469 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2470 inst
.reloc
.pc_rel
= 1;
2471 inst
.instruction
|= flags
;
2479 unsigned long flags
;
2484 if (reg_required_here (&str
, 16) == FAIL
)
2487 inst
.error
= bad_args
;
2491 if (skip_past_comma (&str
) == FAIL
2492 || data_op2 (&str
) == FAIL
)
2495 inst
.error
= bad_args
;
2499 inst
.instruction
|= flags
;
2500 if ((flags
& 0x0000f000) == 0)
2501 inst
.instruction
|= CONDS_BIT
;
2510 unsigned long flags
;
2515 if (reg_required_here (&str
, 12) == FAIL
)
2518 inst
.error
= bad_args
;
2522 if (skip_past_comma (&str
) == FAIL
2523 || data_op2 (&str
) == FAIL
)
2526 inst
.error
= bad_args
;
2530 inst
.instruction
|= flags
;
2536 ldst_extend (str
, hwse
)
2546 if (my_get_expression (&inst
.reloc
.exp
, str
))
2549 if (inst
.reloc
.exp
.X_op
== O_constant
)
2551 int value
= inst
.reloc
.exp
.X_add_number
;
2553 if ((hwse
&& (value
< -255 || value
> 255))
2554 || (value
< -4095 || value
> 4095))
2556 inst
.error
= _("address offset too large");
2566 /* Halfword and signextension instructions have the
2567 immediate value split across bits 11..8 and bits 3..0 */
2569 inst
.instruction
|= add
| HWOFFSET_IMM
| (value
>> 4) << 8 | value
& 0xF;
2571 inst
.instruction
|= add
| value
;
2577 inst
.instruction
|= HWOFFSET_IMM
;
2578 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2581 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2582 inst
.reloc
.pc_rel
= 0;
2587 add
= 0; /* and fall through */
2589 (*str
)++; /* and fall through */
2591 if (reg_required_here (str
, 0) == FAIL
)
2595 inst
.instruction
|= add
;
2598 inst
.instruction
|= add
| OFFSET_REG
;
2599 if (skip_past_comma (str
) == SUCCESS
)
2600 return decode_shift (str
, SHIFT_RESTRICT
);
2608 do_ldst (str
, flags
)
2610 unsigned long flags
;
2617 /* This is not ideal, but it is the simplest way of dealing with the
2618 ARM7T halfword instructions (since they use a different
2619 encoding, but the same mnemonic): */
2620 if (halfword
= ((flags
& 0x80000000) != 0))
2622 /* This is actually a load/store of a halfword, or a
2623 signed-extension load */
2624 if ((cpu_variant
& ARM_HALFWORD
) == 0)
2627 = _("Processor does not support halfwords or signed bytes");
2631 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2632 | (flags
& ~COND_MASK
);
2640 if ((conflict_reg
= reg_required_here (&str
, 12)) == FAIL
)
2643 if (skip_past_comma (&str
) == FAIL
)
2645 inst
.error
= _("Address expected");
2657 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2660 conflict_reg
= (((conflict_reg
== reg
)
2661 && (inst
.instruction
& LOAD_BIT
))
2670 if (skip_past_comma (&str
) == SUCCESS
)
2672 /* [Rn],... (post inc) */
2673 if (ldst_extend (&str
, halfword
) == FAIL
)
2676 as_warn (_("destination register same as write-back base\n"));
2682 inst
.instruction
|= HWOFFSET_IMM
;
2690 as_warn (_("destination register same as write-back base\n"));
2692 inst
.instruction
|= WRITE_BACK
;
2696 if (! (flags
& TRANS_BIT
))
2703 if (skip_past_comma (&str
) == FAIL
)
2705 inst
.error
= _("pre-indexed expression expected");
2710 if (ldst_extend (&str
, halfword
) == FAIL
)
2718 inst
.error
= _("missing ]");
2728 as_tsktsk (_("destination register same as write-back base\n"));
2730 inst
.instruction
|= WRITE_BACK
;
2734 else if (*str
== '=')
2736 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2742 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2745 if (inst
.reloc
.exp
.X_op
!= O_constant
2746 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2748 inst
.error
= _("Constant expression expected");
2752 if (inst
.reloc
.exp
.X_op
== O_constant
2753 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2755 /* This can be done with a mov instruction */
2756 inst
.instruction
&= LITERAL_MASK
;
2757 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2758 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2764 /* Insert into literal pool */
2765 if (add_to_lit_pool () == FAIL
)
2768 inst
.error
= _("literal pool insertion failed");
2772 /* Change the instruction exp to point to the pool */
2775 inst
.instruction
|= HWOFFSET_IMM
;
2776 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2779 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2780 inst
.reloc
.pc_rel
= 1;
2781 inst
.instruction
|= (REG_PC
<< 16);
2787 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2792 inst
.instruction
|= HWOFFSET_IMM
;
2793 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2796 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2797 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
2798 inst
.reloc
.pc_rel
= 1;
2799 inst
.instruction
|= (REG_PC
<< 16);
2803 if (pre_inc
&& (flags
& TRANS_BIT
))
2804 inst
.error
= _("Pre-increment instruction with translate");
2806 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
2819 /* We come back here if we get ranges concatenated by '+' or '|' */
2837 if ((reg
= reg_required_here (& str
, -1)) == FAIL
)
2846 inst
.error
= _("Bad range in register list");
2850 for (i
= cur_reg
+ 1; i
< reg
; i
++)
2852 if (range
& (1 << i
))
2854 (_("Warning: Duplicated register (r%d) in register list"),
2862 if (range
& (1 << reg
))
2863 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
2865 else if (reg
<= cur_reg
)
2866 as_tsktsk (_("Warning: Register range not in ascending order"));
2870 } while (skip_past_comma (&str
) != FAIL
2871 || (in_range
= 1, *str
++ == '-'));
2878 inst
.error
= _("Missing `}'");
2886 if (my_get_expression (&expr
, &str
))
2889 if (expr
.X_op
== O_constant
)
2891 if (expr
.X_add_number
2892 != (expr
.X_add_number
& 0x0000ffff))
2894 inst
.error
= _("invalid register mask");
2898 if ((range
& expr
.X_add_number
) != 0)
2900 int regno
= range
& expr
.X_add_number
;
2903 regno
= (1 << regno
) - 1;
2905 (_("Warning: Duplicated register (r%d) in register list"),
2909 range
|= expr
.X_add_number
;
2913 if (inst
.reloc
.type
!= 0)
2915 inst
.error
= _("expression too complex");
2919 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
2920 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
2921 inst
.reloc
.pc_rel
= 0;
2928 if (*str
== '|' || *str
== '+')
2933 } while (another_range
);
2940 do_ldmstm (str
, flags
)
2942 unsigned long flags
;
2950 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
2953 if (base_reg
== REG_PC
)
2955 inst
.error
= _("r15 not allowed as base register");
2963 flags
|= WRITE_BACK
;
2967 if (skip_past_comma (&str
) == FAIL
2968 || (range
= reg_list (&str
)) == FAIL
)
2971 inst
.error
= bad_args
;
2978 flags
|= MULTI_SET_PSR
;
2981 inst
.instruction
|= flags
| range
;
2989 unsigned long flags
;
2991 /* Allow optional leading '#'. */
2997 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3000 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
3001 inst
.reloc
.pc_rel
= 0;
3002 inst
.instruction
|= flags
;
3008 do_swap (str
, flags
)
3010 unsigned long flags
;
3017 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
3022 inst
.error
= _("r15 not allowed in swap");
3026 if (skip_past_comma (&str
) == FAIL
3027 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
3030 inst
.error
= bad_args
;
3036 inst
.error
= _("r15 not allowed in swap");
3040 if (skip_past_comma (&str
) == FAIL
3043 inst
.error
= bad_args
;
3050 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3055 inst
.error
= bad_pc
;
3064 inst
.error
= _("missing ]");
3068 inst
.instruction
|= flags
;
3074 do_branch (str
, flags
)
3076 unsigned long flags
;
3078 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3080 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3081 inst
.reloc
.pc_rel
= 1;
3089 unsigned long flags
;
3096 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3100 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3109 unsigned long flags
;
3111 /* Co-processor data operation.
3112 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3116 if (co_proc_number (&str
) == FAIL
)
3119 inst
.error
= bad_args
;
3123 if (skip_past_comma (&str
) == FAIL
3124 || cp_opc_expr (&str
, 20,4) == FAIL
)
3127 inst
.error
= bad_args
;
3131 if (skip_past_comma (&str
) == FAIL
3132 || cp_reg_required_here (&str
, 12) == FAIL
)
3135 inst
.error
= bad_args
;
3139 if (skip_past_comma (&str
) == FAIL
3140 || cp_reg_required_here (&str
, 16) == FAIL
)
3143 inst
.error
= bad_args
;
3147 if (skip_past_comma (&str
) == FAIL
3148 || cp_reg_required_here (&str
, 0) == FAIL
)
3151 inst
.error
= bad_args
;
3155 if (skip_past_comma (&str
) == SUCCESS
)
3157 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3160 inst
.error
= bad_args
;
3170 do_lstc (str
, flags
)
3172 unsigned long flags
;
3174 /* Co-processor register load/store.
3175 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3180 if (co_proc_number (&str
) == FAIL
)
3183 inst
.error
= bad_args
;
3187 if (skip_past_comma (&str
) == FAIL
3188 || cp_reg_required_here (&str
, 12) == FAIL
)
3191 inst
.error
= bad_args
;
3195 if (skip_past_comma (&str
) == FAIL
3196 || cp_address_required_here (&str
) == FAIL
)
3199 inst
.error
= bad_args
;
3203 inst
.instruction
|= flags
;
3209 do_co_reg (str
, flags
)
3211 unsigned long flags
;
3213 /* Co-processor register transfer.
3214 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3219 if (co_proc_number (&str
) == FAIL
)
3222 inst
.error
= bad_args
;
3226 if (skip_past_comma (&str
) == FAIL
3227 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3230 inst
.error
= bad_args
;
3234 if (skip_past_comma (&str
) == FAIL
3235 || reg_required_here (&str
, 12) == FAIL
)
3238 inst
.error
= bad_args
;
3242 if (skip_past_comma (&str
) == FAIL
3243 || cp_reg_required_here (&str
, 16) == FAIL
)
3246 inst
.error
= bad_args
;
3250 if (skip_past_comma (&str
) == FAIL
3251 || cp_reg_required_here (&str
, 0) == FAIL
)
3254 inst
.error
= bad_args
;
3258 if (skip_past_comma (&str
) == SUCCESS
)
3260 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3263 inst
.error
= bad_args
;
3273 do_fp_ctrl (str
, flags
)
3275 unsigned long flags
;
3277 /* FP control registers.
3278 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3283 if (reg_required_here (&str
, 12) == FAIL
)
3286 inst
.error
= bad_args
;
3295 do_fp_ldst (str
, flags
)
3297 unsigned long flags
;
3302 switch (inst
.suffix
)
3307 inst
.instruction
|= CP_T_X
;
3310 inst
.instruction
|= CP_T_Y
;
3313 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3319 if (fp_reg_required_here (&str
, 12) == FAIL
)
3322 inst
.error
= bad_args
;
3326 if (skip_past_comma (&str
) == FAIL
3327 || cp_address_required_here (&str
) == FAIL
)
3330 inst
.error
= bad_args
;
3338 do_fp_ldmstm (str
, flags
)
3340 unsigned long flags
;
3347 if (fp_reg_required_here (&str
, 12) == FAIL
)
3350 inst
.error
= bad_args
;
3354 /* Get Number of registers to transfer */
3355 if (skip_past_comma (&str
) == FAIL
3356 || my_get_expression (&inst
.reloc
.exp
, &str
))
3359 inst
.error
= _("constant expression expected");
3363 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3365 inst
.error
= _("Constant value required for number of registers");
3369 num_regs
= inst
.reloc
.exp
.X_add_number
;
3371 if (num_regs
< 1 || num_regs
> 4)
3373 inst
.error
= _("number of registers must be in the range [1:4]");
3380 inst
.instruction
|= CP_T_X
;
3383 inst
.instruction
|= CP_T_Y
;
3386 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3400 /* The instruction specified "ea" or "fd", so we can only accept
3401 [Rn]{!}. The instruction does not really support stacking or
3402 unstacking, so we have to emulate these by setting appropriate
3403 bits and offsets. */
3404 if (skip_past_comma (&str
) == FAIL
3408 inst
.error
= bad_args
;
3416 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3424 inst
.error
= bad_args
;
3435 inst
.error
= _("R15 not allowed as base register with write-back");
3442 if (flags
& CP_T_Pre
)
3445 offset
= 3 * num_regs
;
3451 /* Post-increment */
3455 offset
= 3 * num_regs
;
3459 /* No write-back, so convert this into a standard pre-increment
3460 instruction -- aesthetically more pleasing. */
3461 flags
= CP_T_Pre
| CP_T_UD
;
3466 inst
.instruction
|= flags
| offset
;
3468 else if (skip_past_comma (&str
) == FAIL
3469 || cp_address_required_here (&str
) == FAIL
)
3472 inst
.error
= bad_args
;
3480 do_fp_dyadic (str
, flags
)
3482 unsigned long flags
;
3487 switch (inst
.suffix
)
3492 inst
.instruction
|= 0x00000080;
3495 inst
.instruction
|= 0x00080000;
3501 if (fp_reg_required_here (&str
, 12) == FAIL
)
3504 inst
.error
= bad_args
;
3508 if (skip_past_comma (&str
) == FAIL
3509 || fp_reg_required_here (&str
, 16) == FAIL
)
3512 inst
.error
= bad_args
;
3516 if (skip_past_comma (&str
) == FAIL
3517 || fp_op2 (&str
) == FAIL
)
3520 inst
.error
= bad_args
;
3524 inst
.instruction
|= flags
;
3530 do_fp_monadic (str
, flags
)
3532 unsigned long flags
;
3537 switch (inst
.suffix
)
3542 inst
.instruction
|= 0x00000080;
3545 inst
.instruction
|= 0x00080000;
3551 if (fp_reg_required_here (&str
, 12) == FAIL
)
3554 inst
.error
= bad_args
;
3558 if (skip_past_comma (&str
) == FAIL
3559 || fp_op2 (&str
) == FAIL
)
3562 inst
.error
= bad_args
;
3566 inst
.instruction
|= flags
;
3572 do_fp_cmp (str
, flags
)
3574 unsigned long flags
;
3579 if (fp_reg_required_here (&str
, 16) == FAIL
)
3582 inst
.error
= bad_args
;
3586 if (skip_past_comma (&str
) == FAIL
3587 || fp_op2 (&str
) == FAIL
)
3590 inst
.error
= bad_args
;
3594 inst
.instruction
|= flags
;
3600 do_fp_from_reg (str
, flags
)
3602 unsigned long flags
;
3607 switch (inst
.suffix
)
3612 inst
.instruction
|= 0x00000080;
3615 inst
.instruction
|= 0x00080000;
3621 if (fp_reg_required_here (&str
, 16) == FAIL
)
3624 inst
.error
= bad_args
;
3628 if (skip_past_comma (&str
) == FAIL
3629 || reg_required_here (&str
, 12) == FAIL
)
3632 inst
.error
= bad_args
;
3636 inst
.instruction
|= flags
;
3642 do_fp_to_reg (str
, flags
)
3644 unsigned long flags
;
3649 if (reg_required_here (&str
, 12) == FAIL
)
3652 if (skip_past_comma (&str
) == FAIL
3653 || fp_reg_required_here (&str
, 0) == FAIL
)
3656 inst
.error
= bad_args
;
3660 inst
.instruction
|= flags
;
3665 /* Thumb specific routines */
3667 /* Parse and validate that a register is of the right form, this saves
3668 repeated checking of this information in many similar cases.
3669 Unlike the 32-bit case we do not insert the register into the opcode
3670 here, since the position is often unknown until the full instruction
3673 thumb_reg (strp
, hi_lo
)
3679 if ((reg
= reg_required_here (strp
, -1)) == FAIL
)
3687 inst
.error
= _("lo register required");
3695 inst
.error
= _("hi register required");
3707 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3710 thumb_add_sub (str
, subtract
)
3714 int Rd
, Rs
, Rn
= FAIL
;
3719 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3720 || skip_past_comma (&str
) == FAIL
)
3723 inst
.error
= bad_args
;
3731 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3736 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3739 if (skip_past_comma (&str
) == FAIL
)
3741 /* Two operand format, shuffle the registers and pretend there
3746 else if (*str
== '#')
3749 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3752 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3756 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3757 for the latter case, EXPR contains the immediate that was found. */
3760 /* All register format. */
3761 if (Rd
> 7 || Rs
> 7 || Rn
> 7)
3765 inst
.error
= _("dest and source1 must be the same register");
3769 /* Can't do this for SUB */
3772 inst
.error
= _("subtract valid only on lo regs");
3776 inst
.instruction
= (T_OPCODE_ADD_HI
3777 | (Rd
> 7 ? THUMB_H1
: 0)
3778 | (Rn
> 7 ? THUMB_H2
: 0));
3779 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
3783 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
3784 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
3789 /* Immediate expression, now things start to get nasty. */
3791 /* First deal with HI regs, only very restricted cases allowed:
3792 Adjusting SP, and using PC or SP to get an address. */
3793 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
3794 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
3796 inst
.error
= _("invalid Hi register with immediate");
3800 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3802 /* Value isn't known yet, all we can do is store all the fragments
3803 we know about in the instruction and let the reloc hacking
3805 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
3806 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
3810 int offset
= inst
.reloc
.exp
.X_add_number
;
3820 /* Quick check, in case offset is MIN_INT */
3823 inst
.error
= _("immediate value out of range");
3832 if (offset
& ~0x1fc)
3834 inst
.error
= _("invalid immediate value for stack adjust");
3837 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
3838 inst
.instruction
|= offset
>> 2;
3840 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
3843 || (offset
& ~0x3fc))
3845 inst
.error
= _("invalid immediate for address calculation");
3848 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
3850 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
3856 inst
.error
= _("immediate value out of range");
3859 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
3860 inst
.instruction
|= (Rd
<< 8) | offset
;
3866 inst
.error
= _("immediate value out of range");
3869 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
3870 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
3878 thumb_shift (str
, shift
)
3882 int Rd
, Rs
, Rn
= FAIL
;
3887 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
3888 || skip_past_comma (&str
) == FAIL
)
3891 inst
.error
= bad_args
;
3897 /* Two operand immediate format, set Rs to Rd. */
3900 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3905 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
3908 if (skip_past_comma (&str
) == FAIL
)
3910 /* Two operand format, shuffle the registers and pretend there
3915 else if (*str
== '#')
3918 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3921 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
3925 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3926 for the latter case, EXPR contains the immediate that was found. */
3932 inst
.error
= _("source1 and dest must be same register");
3938 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
3939 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
3940 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
3943 inst
.instruction
|= Rd
| (Rn
<< 3);
3949 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
3950 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
3951 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
3954 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3956 /* Value isn't known yet, create a dummy reloc and let reloc
3957 hacking fix it up */
3959 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
3963 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
3965 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
3967 inst
.error
= _("Invalid immediate for shift");
3971 /* Shifts of zero are handled by converting to LSL */
3972 if (shift_value
== 0)
3973 inst
.instruction
= T_OPCODE_LSL_I
;
3975 /* Shifts of 32 are encoded as a shift of zero */
3976 if (shift_value
== 32)
3979 inst
.instruction
|= shift_value
<< 6;
3982 inst
.instruction
|= Rd
| (Rs
<< 3);
3988 thumb_mov_compare (str
, move
)
3997 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3998 || skip_past_comma (&str
) == FAIL
)
4001 inst
.error
= bad_args
;
4008 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4011 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4016 if (Rs
< 8 && Rd
< 8)
4018 if (move
== THUMB_MOVE
)
4019 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4020 since a MOV instruction produces unpredictable results */
4021 inst
.instruction
= T_OPCODE_ADD_I3
;
4023 inst
.instruction
= T_OPCODE_CMP_LR
;
4024 inst
.instruction
|= Rd
| (Rs
<< 3);
4028 if (move
== THUMB_MOVE
)
4029 inst
.instruction
= T_OPCODE_MOV_HR
;
4031 inst
.instruction
= T_OPCODE_CMP_HR
;
4034 inst
.instruction
|= THUMB_H1
;
4037 inst
.instruction
|= THUMB_H2
;
4039 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
4046 inst
.error
= _("only lo regs allowed with immediate");
4050 if (move
== THUMB_MOVE
)
4051 inst
.instruction
= T_OPCODE_MOV_I8
;
4053 inst
.instruction
= T_OPCODE_CMP_I8
;
4055 inst
.instruction
|= Rd
<< 8;
4057 if (inst
.reloc
.exp
.X_op
!= O_constant
)
4058 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
4061 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4065 inst
.error
= _("invalid immediate");
4069 inst
.instruction
|= value
;
4077 thumb_load_store (str
, load_store
, size
)
4082 int Rd
, Rb
, Ro
= FAIL
;
4087 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4088 || skip_past_comma (&str
) == FAIL
)
4091 inst
.error
= bad_args
;
4098 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4101 if (skip_past_comma (&str
) != FAIL
)
4106 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4109 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4114 inst
.reloc
.exp
.X_op
= O_constant
;
4115 inst
.reloc
.exp
.X_add_number
= 0;
4120 inst
.error
= _("expected ']'");
4125 else if (*str
== '=')
4127 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4133 if (my_get_expression (& inst
.reloc
.exp
, & str
))
4138 if ( inst
.reloc
.exp
.X_op
!= O_constant
4139 && inst
.reloc
.exp
.X_op
!= O_symbol
)
4141 inst
.error
= "Constant expression expected";
4145 if (inst
.reloc
.exp
.X_op
== O_constant
4146 && ((inst
.reloc
.exp
.X_add_number
& ~0xFF) == 0))
4148 /* This can be done with a mov instruction */
4150 inst
.instruction
= T_OPCODE_MOV_I8
| (Rd
<< 8);
4151 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
4155 /* Insert into literal pool */
4156 if (add_to_lit_pool () == FAIL
)
4159 inst
.error
= "literal pool insertion failed";
4163 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4164 inst
.reloc
.pc_rel
= 1;
4165 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4166 inst
.reloc
.exp
.X_add_number
+= 4; /* Adjust ARM pipeline offset to Thumb */
4172 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4175 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4176 inst
.reloc
.pc_rel
= 1;
4177 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4178 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4183 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4185 if (size
!= THUMB_WORD
)
4187 inst
.error
= _("byte or halfword not valid for base register");
4190 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4192 inst
.error
= _("R15 based store not allowed");
4195 else if (Ro
!= FAIL
)
4197 inst
.error
= _("Invalid base register for register offset");
4202 inst
.instruction
= T_OPCODE_LDR_PC
;
4203 else if (load_store
== THUMB_LOAD
)
4204 inst
.instruction
= T_OPCODE_LDR_SP
;
4206 inst
.instruction
= T_OPCODE_STR_SP
;
4208 inst
.instruction
|= Rd
<< 8;
4209 if (inst
.reloc
.exp
.X_op
== O_constant
)
4211 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4213 if (offset
& ~0x3fc)
4215 inst
.error
= _("invalid offset");
4219 inst
.instruction
|= offset
>> 2;
4222 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4226 inst
.error
= _("invalid base register in load/store");
4229 else if (Ro
== FAIL
)
4231 /* Immediate offset */
4232 if (size
== THUMB_WORD
)
4233 inst
.instruction
= (load_store
== THUMB_LOAD
4234 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4235 else if (size
== THUMB_HALFWORD
)
4236 inst
.instruction
= (load_store
== THUMB_LOAD
4237 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4239 inst
.instruction
= (load_store
== THUMB_LOAD
4240 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4242 inst
.instruction
|= Rd
| (Rb
<< 3);
4244 if (inst
.reloc
.exp
.X_op
== O_constant
)
4246 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4248 if (offset
& ~(0x1f << size
))
4250 inst
.error
= _("Invalid offset");
4253 inst
.instruction
|= (offset
>> size
) << 6;
4256 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4260 /* Register offset */
4261 if (size
== THUMB_WORD
)
4262 inst
.instruction
= (load_store
== THUMB_LOAD
4263 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4264 else if (size
== THUMB_HALFWORD
)
4265 inst
.instruction
= (load_store
== THUMB_LOAD
4266 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4268 inst
.instruction
= (load_store
== THUMB_LOAD
4269 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4271 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4286 /* Handle the Format 4 instructions that do not have equivalents in other
4287 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4298 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4301 if (skip_past_comma (&str
) == FAIL
4302 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4305 inst
.error
= bad_args
;
4309 if (skip_past_comma (&str
) != FAIL
)
4311 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4312 (It isn't allowed for CMP either, but that isn't handled by this
4314 if (inst
.instruction
== T_OPCODE_TST
4315 || inst
.instruction
== T_OPCODE_CMN
4316 || inst
.instruction
== T_OPCODE_NEG
4317 || inst
.instruction
== T_OPCODE_MVN
)
4319 inst
.error
= bad_args
;
4323 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4328 inst
.error
= _("dest and source1 one must be the same register");
4334 if (inst
.instruction
== T_OPCODE_MUL
4336 as_tsktsk (_("Rs and Rd must be different in MUL"));
4338 inst
.instruction
|= Rd
| (Rs
<< 3);
4346 thumb_add_sub (str
, 0);
4353 thumb_shift (str
, THUMB_ASR
);
4360 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4362 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH9
;
4363 inst
.reloc
.pc_rel
= 1;
4371 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4373 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH12
;
4374 inst
.reloc
.pc_rel
= 1;
4378 /* Find the real, Thumb encoded start of a Thumb function. */
4381 find_real_start (symbolP
)
4385 const char * name
= S_GET_NAME (symbolP
);
4386 symbolS
* new_target
;
4388 /* This definitonmust agree with the one in gcc/config/arm/thumb.c */
4389 #define STUB_NAME ".real_start_of"
4394 /* Names that start with '.' are local labels, not function entry points.
4395 The compiler may generate BL instructions to these labels because it
4396 needs to perform a branch to a far away location. */
4400 real_start
= malloc (strlen (name
) + strlen (STUB_NAME
) + 1);
4401 sprintf (real_start
, "%s%s", STUB_NAME
, name
);
4403 new_target
= symbol_find (real_start
);
4405 if (new_target
== NULL
)
4407 as_warn ("Failed to find real start of function: %s\n", name
);
4408 new_target
= symbolP
;
4421 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4423 inst
.reloc
.type
= BFD_RELOC_THUMB_PCREL_BRANCH23
;
4424 inst
.reloc
.pc_rel
= 1;
4427 /* If the destination of the branch is a defined symbol which does not have
4428 the THUMB_FUNC attribute, then we must be calling a function which has
4429 the (interfacearm) attribute. We look for the Thumb entry point to that
4430 function and change the branch to refer to that function instead. */
4431 if ( inst
.reloc
.exp
.X_op
== O_symbol
4432 && inst
.reloc
.exp
.X_add_symbol
!= NULL
4433 && S_IS_DEFINED (inst
.reloc
.exp
.X_add_symbol
)
4434 && ! THUMB_IS_FUNC (inst
.reloc
.exp
.X_add_symbol
))
4435 inst
.reloc
.exp
.X_add_symbol
= find_real_start (inst
.reloc
.exp
.X_add_symbol
);
4447 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4450 /* This sets THUMB_H2 from the top bit of reg. */
4451 inst
.instruction
|= reg
<< 3;
4453 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4454 should cause the alignment to be checked once it is known. This is
4455 because BX PC only works if the instruction is word aligned. */
4464 thumb_mov_compare (str
, THUMB_COMPARE
);
4477 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4481 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4485 if (skip_past_comma (&str
) == FAIL
4486 || (range
= reg_list (&str
)) == FAIL
)
4489 inst
.error
= bad_args
;
4493 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4495 /* This really doesn't seem worth it. */
4496 inst
.reloc
.type
= BFD_RELOC_NONE
;
4497 inst
.error
= _("Expression too complex");
4503 inst
.error
= _("only lo-regs valid in load/store multiple");
4507 inst
.instruction
|= (Rb
<< 8) | range
;
4515 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4522 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4529 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4541 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4542 || skip_past_comma (&str
) == FAIL
4544 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4545 || skip_past_comma (&str
) == FAIL
4546 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4550 inst
.error
= _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4554 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4562 thumb_shift (str
, THUMB_LSL
);
4569 thumb_shift (str
, THUMB_LSR
);
4576 thumb_mov_compare (str
, THUMB_MOVE
);
4588 if ((range
= reg_list (&str
)) == FAIL
)
4591 inst
.error
= bad_args
;
4595 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4597 /* This really doesn't seem worth it. */
4598 inst
.reloc
.type
= BFD_RELOC_NONE
;
4599 inst
.error
= _("Expression too complex");
4605 if ((inst
.instruction
== T_OPCODE_PUSH
4606 && (range
& ~0xff) == 1 << REG_LR
)
4607 || (inst
.instruction
== T_OPCODE_POP
4608 && (range
& ~0xff) == 1 << REG_PC
))
4610 inst
.instruction
|= THUMB_PP_PC_LR
;
4615 inst
.error
= _("invalid register list to push/pop instruction");
4620 inst
.instruction
|= range
;
4628 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4635 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4642 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4649 thumb_add_sub (str
, 1);
4659 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4662 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4671 /* This is a pseudo-op of the form "adr rd, label" to be converted
4672 into a relative address of the form "add rd, pc, #label-.-4" */
4676 if (reg_required_here (&str
, 4) == FAIL
/* Store Rd in temporary location inside instruction. */
4677 || skip_past_comma (&str
) == FAIL
4678 || my_get_expression (&inst
.reloc
.exp
, &str
))
4681 inst
.error
= bad_args
;
4685 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4686 inst
.reloc
.exp
.X_add_number
-= 4; /* PC relative adjust */
4687 inst
.reloc
.pc_rel
= 1;
4688 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4696 int len
= strlen (reg_table
[entry
].name
) + 2;
4697 char *buf
= (char *) xmalloc (len
);
4698 char *buf2
= (char *) xmalloc (len
);
4701 #ifdef REGISTER_PREFIX
4702 buf
[i
++] = REGISTER_PREFIX
;
4705 strcpy (buf
+ i
, reg_table
[entry
].name
);
4707 for (i
= 0; buf
[i
]; i
++)
4708 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4712 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4713 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4717 insert_reg_alias (str
, regnum
)
4721 struct reg_entry
*new =
4722 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4723 char *name
= xmalloc (strlen (str
) + 1);
4727 new->number
= regnum
;
4729 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4733 set_constant_flonums ()
4737 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4738 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4747 if ((arm_ops_hsh
= hash_new ()) == NULL
4748 || (arm_tops_hsh
= hash_new ()) == NULL
4749 || (arm_cond_hsh
= hash_new ()) == NULL
4750 || (arm_shift_hsh
= hash_new ()) == NULL
4751 || (arm_reg_hsh
= hash_new ()) == NULL
4752 || (arm_psr_hsh
= hash_new ()) == NULL
)
4753 as_fatal (_("Virtual memory exhausted"));
4755 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4756 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4757 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4758 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4759 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4760 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4761 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4762 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4763 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4764 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4766 for (i
= 0; reg_table
[i
].name
; i
++)
4769 set_constant_flonums ();
4771 #if defined OBJ_COFF || defined OBJ_ELF
4773 unsigned int flags
= 0;
4775 /* Set the flags in the private structure */
4776 if (uses_apcs_26
) flags
|= F_APCS26
;
4777 if (support_interwork
) flags
|= F_INTERWORK
;
4778 if (uses_apcs_float
) flags
|= F_APCS_FLOAT
;
4779 if (pic_code
) flags
|= F_PIC
;
4781 bfd_set_private_flags (stdoutput
, flags
);
4788 /* Record the CPU type as well */
4789 switch (cpu_variant
& ARM_CPU_MASK
)
4792 mach
= bfd_mach_arm_2
;
4795 case ARM_3
: /* also ARM_250 */
4796 mach
= bfd_mach_arm_2a
;
4800 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
4801 mach
= bfd_mach_arm_4
;
4804 case ARM_7
: /* also ARM_6 */
4805 mach
= bfd_mach_arm_3
;
4809 /* Catch special cases */
4810 if (cpu_variant
!= (FPU_DEFAULT
| CPU_DEFAULT
))
4812 if (cpu_variant
& ARM_THUMB
)
4813 mach
= bfd_mach_arm_4T
;
4814 else if ((cpu_variant
& ARM_ARCHv4
) == ARM_ARCHv4
)
4815 mach
= bfd_mach_arm_4
;
4816 else if (cpu_variant
& ARM_LONGMUL
)
4817 mach
= bfd_mach_arm_3M
;
4820 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
4824 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4825 for use in the a.out file, and stores them in the array pointed to by buf.
4826 This knows about the endian-ness of the target machine and does
4827 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4828 2 (short) and 4 (long) Floating numbers are put out as a series of
4829 LITTLENUMS (shorts, here at least)
4832 md_number_to_chars (buf
, val
, n
)
4837 if (target_big_endian
)
4838 number_to_chars_bigendian (buf
, val
, n
);
4840 number_to_chars_littleendian (buf
, val
, n
);
4844 md_chars_to_number (buf
, n
)
4849 unsigned char *where
= (unsigned char *) buf
;
4851 if (target_big_endian
)
4856 result
|= (*where
++ & 255);
4864 result
|= (where
[n
] & 255);
4871 /* Turn a string in input_line_pointer into a floating point constant
4872 of type TYPE, and store the appropriate bytes in *litP. The number
4873 of LITTLENUMS emitted is stored in *sizeP . An error message is
4874 returned, or NULL on OK.
4876 Note that fp constants aren't represent in the normal way on the ARM.
4877 In big endian mode, things are as expected. However, in little endian
4878 mode fp constants are big-endian word-wise, and little-endian byte-wise
4879 within the words. For example, (double) 1.1 in big endian mode is
4880 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4881 the byte sequence 99 99 f1 3f 9a 99 99 99.
4883 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
4886 md_atof (type
, litP
, sizeP
)
4892 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4924 return _("Bad call to MD_ATOF()");
4927 t
= atof_ieee (input_line_pointer
, type
, words
);
4929 input_line_pointer
= t
;
4932 if (target_big_endian
)
4934 for (i
= 0; i
< prec
; i
++)
4936 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4942 /* For a 4 byte float the order of elements in `words' is 1 0. For an
4943 8 byte float the order is 1 0 3 2. */
4944 for (i
= 0; i
< prec
; i
+= 2)
4946 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4947 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4955 /* We have already put the pipeline compensation in the instruction */
4958 md_pcrel_from (fixP
)
4962 && S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
4963 && fixP
->fx_subsy
== NULL
)
4964 return 0; /* HACK */
4966 if (fixP
->fx_pcrel
&& (fixP
->fx_r_type
== BFD_RELOC_ARM_THUMB_ADD
))
4968 /* PC relative addressing on the Thumb is slightly odd
4969 as the bottom two bits of the PC are forced to zero
4970 for the calculation */
4971 return (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
) & ~3;
4974 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
4977 /* Round up a section size to the appropriate boundary. */
4979 md_section_align (segment
, size
)
4983 /* start-sanitize-armelf */
4985 /* Don't align the dwarf2 debug sections */
4986 if (!strncmp(segment
->name
,".debug",5))
4989 /* end-sanitize-armelf */
4990 /* Round all sects to multiple of 4 */
4991 return (size
+ 3) & ~3;
4994 /* We have no need to default values of symbols. */
4998 md_undefined_symbol (name
)
5004 /* arm_reg_parse () := if it looks like a register, return its token and
5005 advance the pointer. */
5009 register char **ccp
;
5014 struct reg_entry
*reg
;
5016 #ifdef REGISTER_PREFIX
5017 if (*start
!= REGISTER_PREFIX
)
5022 #ifdef OPTIONAL_REGISTER_PREFIX
5023 if (*p
== OPTIONAL_REGISTER_PREFIX
)
5027 if (!isalpha (*p
) || !is_name_beginner (*p
))
5031 while (isalpha (c
) || isdigit (c
) || c
== '_')
5035 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
5049 register char **ccp
;
5053 CONST
struct asm_psr
*psr
;
5057 while (isalpha (c
) || c
== '_')
5061 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
5074 md_apply_fix3 (fixP
, val
, seg
)
5079 offsetT value
= *val
;
5081 unsigned int newimm
;
5084 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
5085 arm_fix_data
*arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
5087 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
5089 /* Note whether this will delete the relocation. */
5090 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5091 if ((fixP
->fx_addsy
== 0 || fixP
->fx_addsy
->sy_value
.X_op
== O_constant
)
5094 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
5098 /* If this symbol is in a different section then we need to leave it for
5099 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5100 so we have to undo it's effects here. */
5103 if (fixP
->fx_addsy
!= NULL
5104 && S_IS_DEFINED (fixP
->fx_addsy
)
5105 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
5107 if (fixP
->fx_r_type
== BFD_RELOC_ARM_PCREL_BRANCH
)
5110 value
+= md_pcrel_from (fixP
);
5114 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc */
5116 switch (fixP
->fx_r_type
)
5118 case BFD_RELOC_ARM_IMMEDIATE
:
5119 newimm
= validate_immediate (value
);
5120 temp
= md_chars_to_number (buf
, INSN_SIZE
);
5122 /* If the instruction will fail, see if we can fix things up by
5123 changing the opcode. */
5124 if (newimm
== (unsigned int) FAIL
5125 && (newimm
= negate_data_op (&temp
, value
)) == (unsigned int) FAIL
)
5127 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5128 _("invalid constant after fixup\n"));
5132 newimm
|= (temp
& 0xfffff000);
5133 md_number_to_chars (buf
, (valueT
) newimm
, INSN_SIZE
);
5136 case BFD_RELOC_ARM_OFFSET_IMM
:
5138 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5140 as_bad (_("bad immediate value for offset (%d)"), val
);
5146 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5147 newval
&= 0xff7ff000;
5148 newval
|= value
| (sign
? INDEX_UP
: 0);
5149 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5152 case BFD_RELOC_ARM_OFFSET_IMM8
:
5153 case BFD_RELOC_ARM_HWLITERAL
:
5155 if ((value
= validate_offset_imm (value
, 1)) == FAIL
)
5157 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
5158 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5159 _("invalid literal constant: pool needs to be closer\n"));
5161 as_bad (_("bad immediate value for offset (%d)"), value
);
5168 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5169 newval
&= 0xff7ff0f0;
5170 newval
|= ((value
>> 4) << 8) | value
& 0xf | (sign
? INDEX_UP
: 0);
5171 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5174 case BFD_RELOC_ARM_LITERAL
:
5179 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
5181 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5182 _("invalid literal constant: pool needs to be closer\n"));
5186 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5187 newval
&= 0xff7ff000;
5188 newval
|= value
| (sign
? INDEX_UP
: 0);
5189 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5192 case BFD_RELOC_ARM_SHIFT_IMM
:
5193 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5194 if (((unsigned long) value
) > 32
5196 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
5198 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5199 _("shift expression is too large"));
5204 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
5205 else if (value
== 32)
5207 newval
&= 0xfffff07f;
5208 newval
|= (value
& 0x1f) << 7;
5209 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5212 case BFD_RELOC_ARM_SWI
:
5213 if (arm_data
->thumb_mode
)
5215 if (((unsigned long) value
) > 0xff)
5216 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5217 _("Invalid swi expression"));
5218 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
5220 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5224 if (((unsigned long) value
) > 0x00ffffff)
5225 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5226 _("Invalid swi expression"));
5227 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5229 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5233 case BFD_RELOC_ARM_MULTI
:
5234 if (((unsigned long) value
) > 0xffff)
5235 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5236 _("Invalid expression in load/store multiple"));
5237 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5238 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5241 case BFD_RELOC_ARM_PCREL_BRANCH
:
5242 value
= (value
>> 2) & 0x00ffffff;
5243 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5244 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5245 newval
= value
| (newval
& 0xff000000);
5246 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5249 case BFD_RELOC_THUMB_PCREL_BRANCH9
: /* conditional branch */
5250 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5252 addressT diff
= (newval
& 0xff) << 1;
5257 if ((value
& ~0xff) && ((value
& ~0xff) != ~0xff))
5258 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5259 _("Branch out of range"));
5260 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5262 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5265 case BFD_RELOC_THUMB_PCREL_BRANCH12
: /* unconditional branch */
5266 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5268 addressT diff
= (newval
& 0x7ff) << 1;
5273 if ((value
& ~0x7ff) && ((value
& ~0x7ff) != ~0x7ff))
5274 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5275 _("Branch out of range"));
5276 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5278 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5281 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5286 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5287 newval2
= md_chars_to_number (buf
+ THUMB_SIZE
, THUMB_SIZE
);
5288 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5289 if (diff
& 0x400000)
5292 if ((value
& ~0x3fffff) && ((value
& ~0x3fffff) != ~0x3fffff))
5293 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5294 _("Branch with link out of range"));
5296 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5297 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5298 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5299 md_number_to_chars (buf
+ THUMB_SIZE
, newval2
, THUMB_SIZE
);
5304 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5305 md_number_to_chars (buf
, value
, 1);
5309 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5310 md_number_to_chars (buf
, value
, 2);
5315 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5316 md_number_to_chars (buf
, value
, 4);
5319 case BFD_RELOC_ARM_CP_OFF_IMM
:
5321 if (value
< -1023 || value
> 1023 || (value
& 3))
5322 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5323 _("Illegal value for co-processor offset"));
5326 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5327 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5328 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5331 case BFD_RELOC_ARM_THUMB_OFFSET
:
5332 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5333 /* Exactly what ranges, and where the offset is inserted depends on
5334 the type of instruction, we can establish this from the top 4 bits */
5335 switch (newval
>> 12)
5337 case 4: /* PC load */
5338 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5339 forced to zero for these loads, so we will need to round
5340 up the offset if the instruction address is not word
5341 aligned (since the final address produced must be, and
5342 we can only describe word-aligned immediate offsets). */
5344 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5345 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5346 _("Invalid offset, target not word aligned (0x%08X)"),
5347 (unsigned int)(fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
));
5349 if ((value
+ 2) & ~0x3fe)
5350 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5351 _("Invalid offset"));
5353 /* Round up, since pc will be rounded down. */
5354 newval
|= (value
+ 2) >> 2;
5357 case 9: /* SP load/store */
5359 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5360 _("Invalid offset"));
5361 newval
|= value
>> 2;
5364 case 6: /* Word load/store */
5366 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5367 _("Invalid offset"));
5368 newval
|= value
<< 4; /* 6 - 2 */
5371 case 7: /* Byte load/store */
5373 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5374 _("Invalid offset"));
5375 newval
|= value
<< 6;
5378 case 8: /* Halfword load/store */
5380 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5381 _("Invalid offset"));
5382 newval
|= value
<< 5; /* 6 - 1 */
5386 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5387 "Unable to process relocation for thumb opcode: %x", newval
);
5390 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5393 case BFD_RELOC_ARM_THUMB_ADD
:
5394 /* This is a complicated relocation, since we use it for all of
5395 the following immediate relocations:
5398 9bit ADD/SUB SP word-aligned
5399 10bit ADD PC/SP word-aligned
5401 The type of instruction being processed is encoded in the
5407 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5409 int rd
= (newval
>> 4) & 0xf;
5410 int rs
= newval
& 0xf;
5411 int subtract
= newval
& 0x8000;
5416 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5417 _("Invalid immediate for stack address calculation"));
5418 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5419 newval
|= value
>> 2;
5421 else if (rs
== REG_PC
|| rs
== REG_SP
)
5425 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5426 _("Invalid immediate for address calculation (value = 0x%08X)"), value
);
5427 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5429 newval
|= value
>> 2;
5434 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5435 _("Invalid 8bit immediate"));
5436 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5437 newval
|= (rd
<< 8) | value
;
5442 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5443 _("Invalid 3bit immediate"));
5444 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5445 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5448 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5451 case BFD_RELOC_ARM_THUMB_IMM
:
5452 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5453 switch (newval
>> 11)
5455 case 0x04: /* 8bit immediate MOV */
5456 case 0x05: /* 8bit immediate CMP */
5457 if (value
< 0 || value
> 255)
5458 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5459 _("Invalid immediate: %d is too large"), value
);
5466 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5469 case BFD_RELOC_ARM_THUMB_SHIFT
:
5470 /* 5bit shift value (0..31) */
5471 if (value
< 0 || value
> 31)
5472 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5473 _("Illegal Thumb shift value: %d"), value
);
5474 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5475 newval
|= value
<< 6;
5476 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5479 case BFD_RELOC_NONE
:
5481 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5482 _("Bad relocation fixup type (%d)\n"), fixP
->fx_r_type
);
5488 /* Translate internal representation of relocation info to BFD target
5491 tc_gen_reloc (section
, fixp
)
5496 bfd_reloc_code_real_type code
;
5498 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5500 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
5501 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5503 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5505 if (fixp
->fx_pcrel
== 0)
5506 reloc
->addend
= fixp
->fx_offset
;
5508 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5510 reloc
->addend
= fixp
->fx_offset
;
5513 switch (fixp
->fx_r_type
)
5518 code
= BFD_RELOC_8_PCREL
;
5525 code
= BFD_RELOC_16_PCREL
;
5532 code
= BFD_RELOC_32_PCREL
;
5536 case BFD_RELOC_ARM_PCREL_BRANCH
:
5538 case BFD_RELOC_THUMB_PCREL_BRANCH9
:
5539 case BFD_RELOC_THUMB_PCREL_BRANCH12
:
5540 case BFD_RELOC_THUMB_PCREL_BRANCH23
:
5541 code
= fixp
->fx_r_type
;
5544 case BFD_RELOC_ARM_LITERAL
:
5545 case BFD_RELOC_ARM_HWLITERAL
:
5546 /* If this is called then the a literal has been referenced across
5547 a section boundry - possibly due to an implicit dump */
5548 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5549 _("Literal referenced across section boundry (Implicit dump?)"));
5552 case BFD_RELOC_ARM_IMMEDIATE
:
5553 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5554 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5558 case BFD_RELOC_ARM_OFFSET_IMM
:
5559 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5560 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5567 switch (fixp
->fx_r_type
)
5569 case BFD_RELOC_ARM_IMMEDIATE
: type
= "IMMEDIATE"; break;
5570 case BFD_RELOC_ARM_OFFSET_IMM
: type
= "OFFSET_IMM"; break;
5571 case BFD_RELOC_ARM_OFFSET_IMM8
: type
= "OFFSET_IMM8"; break;
5572 case BFD_RELOC_ARM_SHIFT_IMM
: type
= "SHIFT_IMM"; break;
5573 case BFD_RELOC_ARM_SWI
: type
= "SWI"; break;
5574 case BFD_RELOC_ARM_MULTI
: type
= "MULTI"; break;
5575 case BFD_RELOC_ARM_CP_OFF_IMM
: type
= "CP_OFF_IMM"; break;
5576 case BFD_RELOC_ARM_THUMB_ADD
: type
= "THUMB_ADD"; break;
5577 case BFD_RELOC_ARM_THUMB_SHIFT
: type
= "THUMB_SHIFT"; break;
5578 case BFD_RELOC_ARM_THUMB_IMM
: type
= "THUMB_IMM"; break;
5579 case BFD_RELOC_ARM_THUMB_OFFSET
: type
= "THUMB_OFFSET"; break;
5580 default: type
= "<unknown>"; break;
5582 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5583 _("Can not represent %s relocation in this object file format (%d)"),
5584 type
, fixp
->fx_pcrel
);
5589 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5591 if (reloc
->howto
== NULL
)
5593 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
5594 _("Can not represent %s relocation in this object file format"),
5595 bfd_get_reloc_code_name (code
));
5603 md_estimate_size_before_relax (fragP
, segtype
)
5607 as_fatal (_("md_estimate_size_before_relax\n"));
5619 as_bad (inst
.error
);
5623 to
= frag_more (inst
.size
);
5624 if (thumb_mode
&& (inst
.size
> THUMB_SIZE
))
5626 assert (inst
.size
== (2 * THUMB_SIZE
));
5627 md_number_to_chars (to
, inst
.instruction
>> 16, THUMB_SIZE
);
5628 md_number_to_chars (to
+ 2, inst
.instruction
, THUMB_SIZE
);
5631 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
5633 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5634 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
5635 inst
.size
, &inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
5646 char *p
, *q
, *start
;
5648 /* Align the instruction */
5649 /* this may not be the right thing to do but ... */
5650 /* arm_align (2, 0); */
5651 listing_prev_line (); /* Defined in listing.h */
5653 /* Align the previous label if needed */
5654 if (last_label_seen
!= NULL
)
5656 last_label_seen
->sy_frag
= frag_now
;
5657 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
5658 S_SET_SEGMENT (last_label_seen
, now_seg
);
5661 memset (&inst
, '\0', sizeof (inst
));
5662 inst
.reloc
.type
= BFD_RELOC_NONE
;
5665 str
++; /* Skip leading white space */
5667 /* scan up to the end of the op-code, which must end in white space or
5669 for (start
= p
= str
; *p
!= '\0'; p
++)
5675 as_bad (_("No operator -- statement `%s'\n"), str
);
5681 CONST
struct thumb_opcode
*opcode
;
5685 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
5689 inst
.instruction
= opcode
->value
;
5690 inst
.size
= opcode
->size
;
5691 (*opcode
->parms
)(p
);
5692 output_inst (start
);
5698 CONST
struct asm_opcode
*opcode
;
5700 inst
.size
= INSN_SIZE
;
5701 /* p now points to the end of the opcode, probably white space, but we
5702 have to break the opcode up in case it contains condionals and flags;
5703 keep trying with progressively smaller basic instructions until one
5704 matches, or we run out of opcode. */
5705 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
5706 for (; q
!= str
; q
--)
5710 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
5712 if (opcode
&& opcode
->template)
5714 unsigned long flag_bits
= 0;
5717 /* Check that this instruction is supported for this CPU */
5718 if ((opcode
->variants
& cpu_variant
) == 0)
5721 inst
.instruction
= opcode
->value
;
5722 if (q
== p
) /* Just a simple opcode */
5724 if (opcode
->comp_suffix
!= 0)
5725 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
5726 opcode
->comp_suffix
);
5729 inst
.instruction
|= COND_ALWAYS
;
5730 (*opcode
->parms
)(q
, 0);
5732 output_inst (start
);
5736 /* Now check for a conditional */
5740 CONST
struct asm_cond
*cond
;
5744 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
5748 if (cond
->value
== 0xf0000000)
5750 _("Warning: Use of the 'nv' conditional is deprecated\n"));
5752 inst
.instruction
|= cond
->value
;
5756 inst
.instruction
|= COND_ALWAYS
;
5759 inst
.instruction
|= COND_ALWAYS
;
5761 /* if there is a compulsory suffix, it should come here, before
5762 any optional flags. */
5763 if (opcode
->comp_suffix
)
5765 CONST
char *s
= opcode
->comp_suffix
;
5777 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str
,
5778 opcode
->comp_suffix
);
5785 /* The remainder, if any should now be flags for the instruction;
5786 Scan these checking each one found with the opcode. */
5790 CONST
struct asm_flg
*flag
= opcode
->flags
;
5799 for (flagno
= 0; flag
[flagno
].template; flagno
++)
5801 if (! strcmp (r
, flag
[flagno
].template))
5803 flag_bits
|= flag
[flagno
].set_bits
;
5809 if (! flag
[flagno
].template)
5816 (*opcode
->parms
) (p
, flag_bits
);
5817 output_inst (start
);
5826 /* It wasn't an instruction, but it might be a register alias of the form
5836 if (*q
&& !strncmp (q
, ".req ", 4))
5839 char * copy_of_str
= str
;
5846 for (r
= q
; *r
!= '\0'; r
++)
5856 regnum
= arm_reg_parse (& q
);
5859 reg
= arm_reg_parse (& str
);
5865 insert_reg_alias (str
, regnum
);
5869 as_warn (_("register '%s' does not exist\n"), q
);
5872 else if (regnum
!= FAIL
)
5875 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str
);
5877 /* Do not warn abpout redefinitions to the same alias. */
5880 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
5884 as_warn (_("ignoring incomplete .req pseuso op"));
5891 as_bad (_("bad instruction `%s'"), start
);
5896 * Invocation line includes a switch not recognized by the base assembler.
5897 * See if it's a processor-specific option. These are:
5898 * Cpu variants, the arm part is optional:
5899 * -m[arm]1 Currently not supported.
5900 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
5901 * -m[arm]3 Arm 3 processor
5902 * -m[arm]6, Arm 6 processors
5903 * -m[arm]7[t][[d]m] Arm 7 processors
5904 * -mall All (except the ARM1)
5906 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
5907 * -mfpe-old (No float load/store multiples)
5908 * -mno-fpu Disable all floating point instructions
5909 * Run-time endian selection:
5910 * -EB big endian cpu
5911 * -EL little endian cpu
5912 * ARM Procedure Calling Standard:
5913 * -mapcs-32 32 bit APCS
5914 * -mapcs-26 26 bit APCS
5915 * -mapcs-float Pass floats in float regs
5916 * -mapcs-reentrant Position independent code
5917 * -mthumb-interwork Code supports Arm/Thumb interworking
5920 CONST
char *md_shortopts
= "m:";
5921 struct option md_longopts
[] =
5923 #ifdef ARM_BI_ENDIAN
5924 #define OPTION_EB (OPTION_MD_BASE + 0)
5925 {"EB", no_argument
, NULL
, OPTION_EB
},
5926 #define OPTION_EL (OPTION_MD_BASE + 1)
5927 {"EL", no_argument
, NULL
, OPTION_EL
},
5929 {NULL
, no_argument
, NULL
, 0}
5931 size_t md_longopts_size
= sizeof (md_longopts
);
5934 md_parse_option (c
, arg
)
5942 #ifdef ARM_BI_ENDIAN
5944 target_big_endian
= 1;
5947 target_big_endian
= 0;
5955 if (! strcmp (str
, "fpa10"))
5956 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
5957 else if (! strcmp (str
, "fpa11"))
5958 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
5959 else if (! strcmp (str
, "fpe-old"))
5960 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
5966 if (! strcmp (str
, "no-fpu"))
5967 cpu_variant
&= ~FPU_ALL
;
5971 /* Limit assembler to generating only Thumb instructions: */
5972 if (! strcmp (str
, "thumb"))
5974 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
5975 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
5978 else if (! strcmp (str
, "thumb-interwork"))
5980 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
| ARM_ARCHv4
;
5981 #if defined OBJ_COFF || defined OBJ_ELF
5982 support_interwork
= true;
5990 if (! strcmp (str
, "all"))
5992 cpu_variant
= ARM_ALL
| FPU_ALL
;
5995 #if defined OBJ_COFF || defined OBJ_ELF
5996 if (! strncmp (str
, "apcs-", 5))
5998 /* GCC passes on all command line options starting "-mapcs-..."
5999 to us, so we must parse them here. */
6003 if (! strcmp (str
, "32"))
6005 uses_apcs_26
= false;
6008 else if (! strcmp (str
, "26"))
6010 uses_apcs_26
= true;
6013 else if (! strcmp (str
, "frame"))
6015 /* Stack frames are being generated - does not affect
6019 else if (! strcmp (str
, "stack-check"))
6021 /* Stack checking is being performed - does not affect
6022 linkage, but does require that the functions
6023 __rt_stkovf_split_small and __rt_stkovf_split_big be
6024 present in the final link. */
6028 else if (! strcmp (str
, "float"))
6030 /* Floating point arguments are being passed in the floating
6031 point registers. This does affect linking, since this
6032 version of the APCS is incompatible with the version that
6033 passes floating points in the integer registers. */
6035 uses_apcs_float
= true;
6038 else if (! strcmp (str
, "reentrant"))
6040 /* Reentrant code has been generated. This does affect
6041 linking, since there is no point in linking reentrant/
6042 position independent code with absolute position code. */
6047 as_bad (_("Unrecognised APCS switch -m%s"), arg
);
6051 /* Strip off optional "arm" */
6052 if (! strncmp (str
, "arm", 3))
6058 if (! strcmp (str
, "1"))
6059 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
6065 if (! strcmp (str
, "2"))
6066 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
6067 else if (! strcmp (str
, "250"))
6068 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
6074 if (! strcmp (str
, "3"))
6075 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
6081 if (! strcmp (str
, "strongarm") || ! strcmp (str
, "strongarm110"))
6082 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCHv4
| ARM_LONGMUL
;
6088 if (! strcmp (str
, "8"))
6089 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
| ARM_ARCHv4
| ARM_LONGMUL
;
6095 if (! strcmp (str
, "6"))
6096 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
6102 str
++; /* eat the '7' */
6103 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6109 cpu_variant
|= (ARM_THUMB
| ARM_ARCHv4
);
6113 cpu_variant
|= ARM_LONGMUL
;
6116 case 'f': /* fe => fp enabled cpu. */
6122 case 'c': /* Unknown */
6123 case 'd': /* debug */
6124 case 'i': /* embedded ice */
6125 /* Included for completeness in ARM processor naming. */
6135 /* Select variant based on architecture rather than processor */
6141 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
6142 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
6143 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6148 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
6152 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
6154 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6159 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_ARCHv4
;
6163 case 't': cpu_variant
|= ARM_THUMB
; break;
6165 default: as_bad (_("Invalid architecture variant -m%s"), arg
); break;
6170 as_bad (_("Invalid architecture variant -m%s"), arg
);
6177 as_bad (_("Invalid processor variant -m%s"), arg
);
6196 -m[arm][<processor name>] select processor variant\n\
6197 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
6198 -mthumb only allow Thumb instructions\n\
6199 -mthumb-interwork mark the assembled code as supporting interworking\n\
6200 -mall allow any instruction\n\
6201 -mfpa10, -mfpa11 select floating point architecture\n\
6202 -mfpe-old don't allow floating-point multiple instructions\n\
6203 -mno-fpu don't allow any floating-point instructions.\n"));
6204 #if defined OBJ_COFF || defined OBJ_ELF
6207 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard is in use\n"));
6210 -mapcs-float floating point args are passed in floating point regs\n"));
6213 -mapcs-reentrant position independent/reentrant code has been generated\n"));
6215 #ifdef ARM_BI_ENDIAN
6218 -EB assemble code for a big endian cpu\n\
6219 -EL assemble code for a little endian cpu\n"));
6223 /* We need to be able to fix up arbitrary expressions in some statements.
6224 This is so that we can handle symbols that are an arbitrary distance from
6225 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6226 which returns part of an address in a form which will be valid for
6227 a data instruction. We do this by pushing the expression into a symbol
6228 in the expr_section, and creating a fix for that. */
6231 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
6240 arm_fix_data
*arm_data
;
6248 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
6252 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
6257 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6258 arm_data
= (arm_fix_data
*) obstack_alloc (¬es
, sizeof (arm_fix_data
));
6259 new_fix
->tc_fix_data
= (PTR
) arm_data
;
6260 arm_data
->thumb_mode
= thumb_mode
;
6265 /* A good place to do this, although this was probably not intended
6266 * for this kind of use. We need to dump the literal pool before
6267 * references are made to a null symbol pointer. */
6271 if (current_poolP
!= NULL
)
6273 subseg_set (text_section
, 0); /* Put it at the end of text section */
6275 listing_prev_line ();
6280 arm_start_line_hook ()
6282 last_label_seen
= NULL
;
6286 arm_frob_label (sym
)
6289 last_label_seen
= sym
;
6290 ARM_SET_THUMB (sym
, thumb_mode
);
6291 #if defined OBJ_COFF || defined OBJ_ELF
6292 ARM_SET_INTERWORK (sym
, support_interwork
);
6295 if (label_is_thumb_function_name
)
6297 /* When the address of a Thumb function is taken the bottom
6298 bit of that address should be set. This will allow
6299 interworking between Arm and Thumb functions to work
6302 THUMB_SET_FUNC (sym
, 1);
6304 label_is_thumb_function_name
= false;
6308 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6312 #define S_GET_STORAGE_CLASS(S) (elf_symbol ((S)->bsym)->internal_elf_sym.st_other)
6313 #define S_SET_STORAGE_CLASS(S,V) (elf_symbol ((S)->bsym)->internal_elf_sym.st_other = (V))
6316 arm_adjust_symtab ()
6318 #if defined OBJ_COFF || defined OBJ_ELF
6321 for (sym
= symbol_rootP
; sym
!= NULL
; sym
= symbol_next (sym
))
6323 if (ARM_IS_THUMB (sym
))
6325 if (THUMB_IS_FUNC (sym
))
6327 /* Mark the symbol as a Thumb function. */
6328 if ( S_GET_STORAGE_CLASS (sym
) == C_STAT
6329 || S_GET_STORAGE_CLASS (sym
) == C_LABEL
) /* This can happen! */
6330 S_SET_STORAGE_CLASS (sym
, C_THUMBSTATFUNC
);
6331 else if (S_GET_STORAGE_CLASS (sym
) == C_EXT
)
6332 S_SET_STORAGE_CLASS (sym
, C_THUMBEXTFUNC
);
6334 as_bad (_("%s: unexpected function type: %d"), S_GET_NAME (sym
), S_GET_STORAGE_CLASS (sym
));
6336 else switch (S_GET_STORAGE_CLASS (sym
))
6339 S_SET_STORAGE_CLASS (sym
, C_THUMBEXT
);
6342 S_SET_STORAGE_CLASS (sym
, C_THUMBSTAT
);
6345 S_SET_STORAGE_CLASS (sym
, C_THUMBLABEL
);
6347 default: /* do nothing */
6353 if (ARM_IS_INTERWORK (sym
))
6354 coffsymbol(sym
->bsym
)->native
->u
.syment
.n_flags
= 0xFF;
6362 armelf_frob_symbol (symp
, puntp
)
6367 elf_frob_symbol (symp
, puntp
);
6369 if (S_IS_EXTERNAL (symp
))
6370 S_SET_STORAGE_CLASS(symp
, C_EXT
);
6372 if (S_GET_STORAGE_CLASS (symp
) == C_NULL
)
6374 if (S_GET_SEGMENT (symp
) == text_section
6375 && symp
!= seg_info (text_section
)->sym
)
6376 S_SET_STORAGE_CLASS (symp
, C_LABEL
);
6378 S_SET_STORAGE_CLASS (symp
, C_STAT
);
6385 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
6387 *input_line_pointer
= '/';
6388 input_line_pointer
+= 5;
6389 *input_line_pointer
= 0;
6396 arm_canonicalize_symbol_name (name
)
6401 if (thumb_mode
&& (len
= strlen (name
)) > 5
6402 && ! strcmp (name
+ len
- 5, "/data"))
6404 *(name
+ len
- 5) = 0;
6411 arm_validate_fix (fixP
)
6414 /* If the destination of the branch is a defined symbol which does not have
6415 the THUMB_FUNC attribute, then we must be calling a function which has
6416 the (interfacearm) attribute. We look for the Thumb entry point to that
6417 function and change the branch to refer to that function instead. */
6418 if ( fixP
->fx_r_type
== BFD_RELOC_THUMB_PCREL_BRANCH23
6419 && fixP
->fx_addsy
!= NULL
6420 && S_IS_DEFINED (fixP
->fx_addsy
)
6421 && ! THUMB_IS_FUNC (fixP
->fx_addsy
))
6423 fixP
->fx_addsy
= find_real_start (fixP
->fx_addsy
);