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
35 /* ??? This is currently unused. */
37 #define internalError() \
38 as_fatal (_("ARM Internal Error, line %d, %s"), __LINE__, __FILE__)
40 #define internalError() as_fatal (_("ARM Internal Error"))
43 /* Types of processor to assemble for. */
44 #define ARM_1 0x00000001
45 #define ARM_2 0x00000002
46 #define ARM_3 0x00000004
48 #define ARM_6 0x00000008
49 #define ARM_7 ARM_6 /* same core instruction set */
50 #define ARM_CPU_MASK 0x0000000f
52 /* The following bitmasks control CPU extensions (ARM7 onwards): */
53 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
54 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
55 #define ARM_THUMB 0x00000040 /* allow BX instruction */
57 #define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
59 /* Some useful combinations: */
60 #define ARM_ANY 0x00ffffff
61 #define ARM_2UP 0x00fffffe
62 #define ARM_ALL ARM_2UP /* Not arm1 only */
63 #define ARM_3UP 0x00fffffc
64 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
66 #define FPU_CORE 0x80000000
67 #define FPU_FPA10 0x40000000
68 #define FPU_FPA11 0x40000000
71 /* Some useful combinations */
72 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
73 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
78 #define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB)
80 #define CPU_DEFAULT ARM_ALL
85 #define FPU_DEFAULT FPU_ALL
88 static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
91 /* Flags stored in private area of BFD COFF structure */
92 static boolean uses_apcs_26 = false;
93 static boolean support_interwork = false;
94 static boolean uses_apcs_float = false;
95 static boolean pic_code = false;
98 /* This array holds the chars that always start a comment. If the
99 pre-processor is disabled, these aren't very useful */
100 CONST char comment_chars[] = "@";
102 /* This array holds the chars that only start a comment at the beginning of
103 a line. If the line seems to have the form '# 123 filename'
104 .line and .file directives will appear in the pre-processed output */
105 /* Note that input_file.c hand checks for '#' at the beginning of the
106 first line of the input file. This is because the compiler outputs
107 #NO_APP at the beginning of its output. */
108 /* Also note that comments like this one will always work. */
109 CONST char line_comment_chars[] = "#";
111 CONST char line_separator_chars[] = "";
113 /* Chars that can be used to separate mant from exp in floating point nums */
114 CONST char EXP_CHARS[] = "eE";
116 /* Chars that mean this number is a floating point constant */
120 CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
122 CONST int md_reloc_size = 8; /* Size of relocation record */
124 static int thumb_mode = 0; /* non-zero if assembling thumb instructions */
126 typedef struct arm_fix
134 unsigned long instruction;
139 bfd_reloc_code_real_type type;
149 CONST char *template;
153 static CONST struct asm_shift shift[] =
169 #define NO_SHIFT_RESTRICT 1
170 #define SHIFT_RESTRICT 0
172 #define NUM_FLOAT_VALS 8
174 CONST char *fp_const[] =
176 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
179 /* Number of littlenums required to hold an extended precision number */
180 #define MAX_LITTLENUMS 6
182 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
192 #define CP_T_X 0x00008000
193 #define CP_T_Y 0x00400000
194 #define CP_T_Pre 0x01000000
195 #define CP_T_UD 0x00800000
196 #define CP_T_WB 0x00200000
198 #define CONDS_BIT (0x00100000)
199 #define LOAD_BIT (0x00100000)
200 #define TRANS_BIT (0x00200000)
204 CONST char *template;
208 /* This is to save a hash look-up in the common case */
209 #define COND_ALWAYS 0xe0000000
211 static CONST struct asm_cond conds[] =
215 {"cs", 0x20000000}, {"hs", 0x20000000},
216 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
231 /* Warning: If the top bit of the set_bits is set, then the standard
232 instruction bitmask is ignored, and the new bitmask is taken from
236 CONST char *template; /* Basic flag string */
237 unsigned long set_bits; /* Bits to set */
240 static CONST struct asm_flg s_flag[] =
246 static CONST struct asm_flg ldr_flags[] =
250 {"bt", 0x00400000 | TRANS_BIT},
257 static CONST struct asm_flg str_flags[] =
261 {"bt", 0x00400000 | TRANS_BIT},
266 static CONST struct asm_flg byte_flag[] =
272 static CONST struct asm_flg cmp_flags[] =
279 static CONST struct asm_flg ldm_flags[] =
292 static CONST struct asm_flg stm_flags[] =
305 static CONST struct asm_flg lfm_flags[] =
312 static CONST struct asm_flg sfm_flags[] =
319 static CONST struct asm_flg round_flags[] =
327 /* The implementation of the FIX instruction is broken on some assemblers,
328 in that it accepts a precision specifier as well as a rounding specifier,
329 despite the fact that this is meaningless. To be more compatible, we
330 accept it as well, though of course it does not set any bits. */
331 static CONST struct asm_flg fix_flags[] =
348 static CONST struct asm_flg except_flag[] =
354 static CONST struct asm_flg cplong_flag[] =
362 CONST char *template;
363 unsigned long number;
366 #define PSR_FIELD_MASK 0x000f0000
368 #define PSR_FLAGS 0x00080000
369 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
370 #define PSR_ALL 0x00090000
379 static CONST struct asm_psr psrs[] =
383 {"cpsr_all", CPSR_ALL},
385 {"spsr_all", SPSR_ALL},
388 {"cpsr_flg", CPSR_FLG},
389 {"spsr_flg", SPSR_FLG},
392 {"cpsr_c", CPSR_CTL},
393 {"cpsr_ctl", CPSR_CTL},
394 {"spsr_c", SPSR_CTL},
395 {"spsr_ctl", SPSR_CTL}
398 /* Functions called by parser */
399 /* ARM instructions */
400 static void do_arit PARAMS ((char *operands, unsigned long flags));
401 static void do_cmp PARAMS ((char *operands, unsigned long flags));
402 static void do_mov PARAMS ((char *operands, unsigned long flags));
403 static void do_ldst PARAMS ((char *operands, unsigned long flags));
404 static void do_ldmstm PARAMS ((char *operands, unsigned long flags));
405 static void do_branch PARAMS ((char *operands, unsigned long flags));
406 static void do_swi PARAMS ((char *operands, unsigned long flags));
407 /* Pseudo Op codes */
408 static void do_adr PARAMS ((char *operands, unsigned long flags));
409 static void do_nop PARAMS ((char *operands, unsigned long flags));
411 static void do_mul PARAMS ((char *operands, unsigned long flags));
412 static void do_mla PARAMS ((char *operands, unsigned long flags));
414 static void do_swap PARAMS ((char *operands, unsigned long flags));
416 static void do_msr PARAMS ((char *operands, unsigned long flags));
417 static void do_mrs PARAMS ((char *operands, unsigned long flags));
419 static void do_mull PARAMS ((char *operands, unsigned long flags));
421 static void do_bx PARAMS ((char *operands, unsigned long flags));
423 /* Coprocessor Instructions */
424 static void do_cdp PARAMS ((char *operands, unsigned long flags));
425 static void do_lstc PARAMS ((char *operands, unsigned long flags));
426 static void do_co_reg PARAMS ((char *operands, unsigned long flags));
427 static void do_fp_ctrl PARAMS ((char *operands, unsigned long flags));
428 static void do_fp_ldst PARAMS ((char *operands, unsigned long flags));
429 static void do_fp_ldmstm PARAMS ((char *operands, unsigned long flags));
430 static void do_fp_dyadic PARAMS ((char *operands, unsigned long flags));
431 static void do_fp_monadic PARAMS ((char *operands, unsigned long flags));
432 static void do_fp_cmp PARAMS ((char *operands, unsigned long flags));
433 static void do_fp_from_reg PARAMS ((char *operands, unsigned long flags));
434 static void do_fp_to_reg PARAMS ((char *operands, unsigned long flags));
436 static void fix_new_arm PARAMS ((fragS *frag, int where,
437 short int size, expressionS *exp,
438 int pc_rel, int reloc));
439 static int arm_reg_parse PARAMS ((char **ccp));
440 static int arm_psr_parse PARAMS ((char **ccp));
441 static void symbol_locate PARAMS ((symbolS *, CONST char *, segT,
443 static int add_to_lit_pool PARAMS ((void));
444 static unsigned validate_immediate PARAMS ((unsigned));
445 static int validate_offset_imm PARAMS ((int, int));
446 static void opcode_select PARAMS ((int));
447 static void end_of_line PARAMS ((char *));
448 static int reg_required_here PARAMS ((char **, int));
449 static int psr_required_here PARAMS ((char **, int, int));
450 static int co_proc_number PARAMS ((char **));
451 static int cp_opc_expr PARAMS ((char **, int, int));
452 static int cp_reg_required_here PARAMS ((char **, int));
453 static int fp_reg_required_here PARAMS ((char **, int));
454 static int cp_address_offset PARAMS ((char **));
455 static int cp_address_required_here PARAMS ((char **));
456 static int my_get_float_expression PARAMS ((char **));
457 static int skip_past_comma PARAMS ((char **));
458 static int walk_no_bignums PARAMS ((symbolS *));
459 static int negate_data_op PARAMS ((unsigned long *,
461 static int data_op2 PARAMS ((char **));
462 static int fp_op2 PARAMS ((char **));
463 static long reg_list PARAMS ((char **));
464 static void thumb_load_store PARAMS ((char *, int, int));
465 static int decode_shift PARAMS ((char **, int));
466 static int ldst_extend PARAMS ((char **, int));
467 static void thumb_add_sub PARAMS ((char *, int));
468 static void insert_reg PARAMS ((int));
469 static void thumb_shift PARAMS ((char *, int));
470 static void thumb_mov_compare PARAMS ((char *, int));
471 static void set_constant_flonums PARAMS ((void));
472 static valueT md_chars_to_number PARAMS ((char *, int));
473 static void insert_reg_alias PARAMS ((char *, int));
474 static void output_inst PARAMS ((char *));
476 /* ARM instructions take 4bytes in the object file, Thumb instructions
480 /* LONGEST_INST is the longest basic instruction name without conditions or
482 * ARM7M has 4 of length 5
485 #define LONGEST_INST 5
489 CONST char *template; /* Basic string to match */
490 unsigned long value; /* Basic instruction code */
491 CONST char *comp_suffix; /* Compulsory suffix that must follow conds */
492 CONST struct asm_flg *flags; /* Bits to toggle if flag 'n' set */
493 unsigned long variants; /* Which CPU variants this exists for */
494 /* Function to call to parse args */
495 void (*parms) PARAMS ((char *, unsigned long));
498 static CONST struct asm_opcode insns[] =
500 /* ARM Instructions */
501 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
502 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
503 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
504 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
505 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
506 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
507 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
508 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
509 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
510 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
511 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
512 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
513 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
514 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
515 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
516 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
517 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
518 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
519 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
520 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
521 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
522 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
523 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
526 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
527 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
529 /* ARM 2 multiplies */
530 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
531 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
533 /* ARM 3 - swp instructions */
534 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
536 /* ARM 6 Coprocessor instructions */
537 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
538 {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr},
540 /* ARM 7M long multiplies - need signed/unsigned flags! */
541 {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull},
542 {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull},
543 {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull},
544 {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull},
546 /* ARM THUMB interworking */
547 {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx},
549 /* Floating point instructions */
550 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
551 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
552 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
553 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
554 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
555 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
556 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
557 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
558 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
559 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
560 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
561 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
562 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
563 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
564 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
565 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
566 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
567 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
568 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
569 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
570 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
571 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
572 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
573 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
574 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
575 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
576 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
577 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
578 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
579 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
580 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
581 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
582 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
583 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
584 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
585 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
586 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
587 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
588 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
589 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
590 be an optional suffix, but part of the instruction. To be compatible,
592 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
593 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
594 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
595 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
597 /* Generic copressor instructions */
598 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
599 {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc},
600 {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc},
601 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
602 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
605 /* defines for various bits that we will want to toggle */
607 #define INST_IMMEDIATE 0x02000000
608 #define OFFSET_REG 0x02000000
609 #define HWOFFSET_IMM 0x00400000
610 #define SHIFT_BY_REG 0x00000010
611 #define PRE_INDEX 0x01000000
612 #define INDEX_UP 0x00800000
613 #define WRITE_BACK 0x00200000
614 #define MULTI_SET_PSR 0x00400000
616 #define LITERAL_MASK 0xf000f000
617 #define COND_MASK 0xf0000000
618 #define OPCODE_MASK 0xfe1fffff
619 #define DATA_OP_SHIFT 21
621 /* Codes to distinguish the arithmetic instructions */
633 #define OPCODE_CMP 10
634 #define OPCODE_CMN 11
635 #define OPCODE_ORR 12
636 #define OPCODE_MOV 13
637 #define OPCODE_BIC 14
638 #define OPCODE_MVN 15
640 static void do_t_nop PARAMS ((char *operands));
641 static void do_t_arit PARAMS ((char *operands));
642 static void do_t_add PARAMS ((char *operands));
643 static void do_t_asr PARAMS ((char *operands));
644 static void do_t_branch9 PARAMS ((char *operands));
645 static void do_t_branch12 PARAMS ((char *operands));
646 static void do_t_branch23 PARAMS ((char *operands));
647 static void do_t_bx PARAMS ((char *operands));
648 static void do_t_compare PARAMS ((char *operands));
649 static void do_t_ldmstm PARAMS ((char *operands));
650 static void do_t_ldr PARAMS ((char *operands));
651 static void do_t_ldrb PARAMS ((char *operands));
652 static void do_t_ldrh PARAMS ((char *operands));
653 static void do_t_lds PARAMS ((char *operands));
654 static void do_t_lsl PARAMS ((char *operands));
655 static void do_t_lsr PARAMS ((char *operands));
656 static void do_t_mov PARAMS ((char *operands));
657 static void do_t_push_pop PARAMS ((char *operands));
658 static void do_t_str PARAMS ((char *operands));
659 static void do_t_strb PARAMS ((char *operands));
660 static void do_t_strh PARAMS ((char *operands));
661 static void do_t_sub PARAMS ((char *operands));
662 static void do_t_swi PARAMS ((char *operands));
663 static void do_t_adr PARAMS ((char *operands));
665 #define T_OPCODE_MUL 0x4340
666 #define T_OPCODE_TST 0x4200
667 #define T_OPCODE_CMN 0x42c0
668 #define T_OPCODE_NEG 0x4240
669 #define T_OPCODE_MVN 0x43c0
671 #define T_OPCODE_ADD_R3 0x1800
672 #define T_OPCODE_SUB_R3 0x1a00
673 #define T_OPCODE_ADD_HI 0x4400
674 #define T_OPCODE_ADD_ST 0xb000
675 #define T_OPCODE_SUB_ST 0xb080
676 #define T_OPCODE_ADD_SP 0xa800
677 #define T_OPCODE_ADD_PC 0xa000
678 #define T_OPCODE_ADD_I8 0x3000
679 #define T_OPCODE_SUB_I8 0x3800
680 #define T_OPCODE_ADD_I3 0x1c00
681 #define T_OPCODE_SUB_I3 0x1e00
683 #define T_OPCODE_ASR_R 0x4100
684 #define T_OPCODE_LSL_R 0x4080
685 #define T_OPCODE_LSR_R 0x40c0
686 #define T_OPCODE_ASR_I 0x1000
687 #define T_OPCODE_LSL_I 0x0000
688 #define T_OPCODE_LSR_I 0x0800
690 #define T_OPCODE_MOV_I8 0x2000
691 #define T_OPCODE_CMP_I8 0x2800
692 #define T_OPCODE_CMP_LR 0x4280
693 #define T_OPCODE_MOV_HR 0x4600
694 #define T_OPCODE_CMP_HR 0x4500
696 #define T_OPCODE_LDR_PC 0x4800
697 #define T_OPCODE_LDR_SP 0x9800
698 #define T_OPCODE_STR_SP 0x9000
699 #define T_OPCODE_LDR_IW 0x6800
700 #define T_OPCODE_STR_IW 0x6000
701 #define T_OPCODE_LDR_IH 0x8800
702 #define T_OPCODE_STR_IH 0x8000
703 #define T_OPCODE_LDR_IB 0x7800
704 #define T_OPCODE_STR_IB 0x7000
705 #define T_OPCODE_LDR_RW 0x5800
706 #define T_OPCODE_STR_RW 0x5000
707 #define T_OPCODE_LDR_RH 0x5a00
708 #define T_OPCODE_STR_RH 0x5200
709 #define T_OPCODE_LDR_RB 0x5c00
710 #define T_OPCODE_STR_RB 0x5400
712 #define T_OPCODE_PUSH 0xb400
713 #define T_OPCODE_POP 0xbc00
715 #define T_OPCODE_BRANCH 0xe7fe
717 static int thumb_reg PARAMS ((char **str, int hi_lo));
719 #define THUMB_SIZE 2 /* Size of thumb instruction */
720 #define THUMB_REG_LO 0x1
721 #define THUMB_REG_HI 0x2
722 #define THUMB_REG_ANY 0x3
724 #define THUMB_H1 0x0080
725 #define THUMB_H2 0x0040
732 #define THUMB_COMPARE 1
735 #define THUMB_STORE 1
737 #define THUMB_PP_PC_LR 0x0100
739 /* These three are used for immediate shifts, do not alter */
741 #define THUMB_HALFWORD 1
746 CONST char *template; /* Basic string to match */
747 unsigned long value; /* Basic instruction code */
749 /* Function to call to parse args */
750 void (*parms) PARAMS ((char *));
753 static CONST struct thumb_opcode tinsns[] =
755 {"adc", 0x4140, 2, do_t_arit},
756 {"add", 0x0000, 2, do_t_add},
757 {"and", 0x4000, 2, do_t_arit},
758 {"asr", 0x0000, 2, do_t_asr},
759 {"b", T_OPCODE_BRANCH, 2, do_t_branch12},
760 {"beq", 0xd0fe, 2, do_t_branch9},
761 {"bne", 0xd1fe, 2, do_t_branch9},
762 {"bcs", 0xd2fe, 2, do_t_branch9},
763 {"bhs", 0xd2fe, 2, do_t_branch9},
764 {"bcc", 0xd3fe, 2, do_t_branch9},
765 {"bul", 0xd3fe, 2, do_t_branch9},
766 {"blo", 0xd3fe, 2, do_t_branch9},
767 {"bmi", 0xd4fe, 2, do_t_branch9},
768 {"bpl", 0xd5fe, 2, do_t_branch9},
769 {"bvs", 0xd6fe, 2, do_t_branch9},
770 {"bvc", 0xd7fe, 2, do_t_branch9},
771 {"bhi", 0xd8fe, 2, do_t_branch9},
772 {"bls", 0xd9fe, 2, do_t_branch9},
773 {"bge", 0xdafe, 2, do_t_branch9},
774 {"blt", 0xdbfe, 2, do_t_branch9},
775 {"bgt", 0xdcfe, 2, do_t_branch9},
776 {"ble", 0xddfe, 2, do_t_branch9},
777 {"bic", 0x4380, 2, do_t_arit},
778 {"bl", 0xf7fffffe, 4, do_t_branch23},
779 {"bx", 0x4700, 2, do_t_bx},
780 {"cmn", T_OPCODE_CMN, 2, do_t_arit},
781 {"cmp", 0x0000, 2, do_t_compare},
782 {"eor", 0x4040, 2, do_t_arit},
783 {"ldmia", 0xc800, 2, do_t_ldmstm},
784 {"ldr", 0x0000, 2, do_t_ldr},
785 {"ldrb", 0x0000, 2, do_t_ldrb},
786 {"ldrh", 0x0000, 2, do_t_ldrh},
787 {"ldrsb", 0x5600, 2, do_t_lds},
788 {"ldrsh", 0x5e00, 2, do_t_lds},
789 {"ldsb", 0x5600, 2, do_t_lds},
790 {"ldsh", 0x5e00, 2, do_t_lds},
791 {"lsl", 0x0000, 2, do_t_lsl},
792 {"lsr", 0x0000, 2, do_t_lsr},
793 {"mov", 0x0000, 2, do_t_mov},
794 {"mul", T_OPCODE_MUL, 2, do_t_arit},
795 {"mvn", T_OPCODE_MVN, 2, do_t_arit},
796 {"neg", T_OPCODE_NEG, 2, do_t_arit},
797 {"orr", 0x4300, 2, do_t_arit},
798 {"pop", 0xbc00, 2, do_t_push_pop},
799 {"push", 0xb400, 2, do_t_push_pop},
800 {"ror", 0x41c0, 2, do_t_arit},
801 {"sbc", 0x4180, 2, do_t_arit},
802 {"stmia", 0xc000, 2, do_t_ldmstm},
803 {"str", 0x0000, 2, do_t_str},
804 {"strb", 0x0000, 2, do_t_strb},
805 {"strh", 0x0000, 2, do_t_strh},
806 {"swi", 0xdf00, 2, do_t_swi},
807 {"sub", 0x0000, 2, do_t_sub},
808 {"tst", T_OPCODE_TST, 2, do_t_arit},
810 {"adr", 0x0000, 2, do_t_adr},
811 {"nop", 0x46C0, 2, do_t_nop}, /* mov r8,r8 */
820 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
821 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
822 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
828 /* These are the standard names; Users can add aliases with .req */
829 static CONST struct reg_entry reg_table[] =
831 /* Processor Register Numbers */
832 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
833 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
834 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
835 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
836 /* APCS conventions */
837 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
838 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
839 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
840 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
842 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
843 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
844 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
845 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
846 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
847 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
848 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
849 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
850 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
851 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
855 #define bad_args _("Bad arguments to instruction");
856 #define bad_pc _("r15 not allowed here");
858 static struct hash_control *arm_ops_hsh = NULL;
859 static struct hash_control *arm_tops_hsh = NULL;
860 static struct hash_control *arm_cond_hsh = NULL;
861 static struct hash_control *arm_shift_hsh = NULL;
862 static struct hash_control *arm_reg_hsh = NULL;
863 static struct hash_control *arm_psr_hsh = NULL;
865 /* This table describes all the machine specific pseudo-ops the assembler
866 has to support. The fields are:
867 pseudo-op name without dot
868 function to call to execute this pseudo-op
869 Integer arg to pass to the function
872 static void s_req PARAMS ((int));
873 static void s_align PARAMS ((int));
874 static void s_bss PARAMS ((int));
875 static void s_even PARAMS ((int));
876 static void s_ltorg PARAMS ((int));
877 static void s_arm PARAMS ((int));
878 static void s_thumb PARAMS ((int));
879 static void s_code PARAMS ((int));
880 static void s_force_thumb PARAMS ((int));
881 static void s_thumb_func PARAMS ((int));
883 static int my_get_expression PARAMS ((expressionS *, char **));
885 CONST pseudo_typeS md_pseudo_table[] =
887 {"req", s_req, 0}, /* Never called becasue '.req' does not start line */
889 {"align", s_align, 0},
891 {"thumb", s_thumb, 0},
893 {"force_thumb", s_force_thumb, 0},
894 {"thumb_func", s_thumb_func, 0},
896 {"ltorg", s_ltorg, 0},
897 {"pool", s_ltorg, 0},
899 {"extend", float_cons, 'x'},
900 {"ldouble", float_cons, 'x'},
901 {"packed", float_cons, 'p'},
905 /* Stuff needed to resolve the label ambiguity
915 symbolS * last_label_seen;
916 static int label_is_thumb_function_name = false;
920 #define MAX_LITERAL_POOL_SIZE 1024
922 typedef struct literalS
924 struct expressionS exp;
928 literalT literals[MAX_LITERAL_POOL_SIZE];
929 int next_literal_pool_place = 0; /* Next free entry in the pool */
930 int lit_pool_num = 1; /* Next literal pool number */
931 symbolS *current_poolP = NULL;
932 symbolS *symbol_make_empty PARAMS ((void));
939 if (current_poolP == NULL)
940 current_poolP = symbol_make_empty();
942 /* Check if this literal value is already in the pool: */
943 while (lit_count < next_literal_pool_place)
945 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
946 && inst.reloc.exp.X_op == O_constant
947 && literals[lit_count].exp.X_add_number == inst.reloc.exp.X_add_number
948 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
953 if (lit_count == next_literal_pool_place) /* new entry */
955 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
957 inst.error = _("Literal Pool Overflow");
961 literals[next_literal_pool_place].exp = inst.reloc.exp;
962 lit_count = next_literal_pool_place++;
965 inst.reloc.exp.X_op = O_symbol;
966 inst.reloc.exp.X_add_number = (lit_count)*4-8;
967 inst.reloc.exp.X_add_symbol = current_poolP;
972 /* Can't use symbol_new here, so have to create a symbol and then at
973 a later date assign it a value. Thats what these functions do */
975 symbol_locate (symbolP, name, segment, valu, frag)
977 CONST char *name; /* It is copied, the caller can modify */
978 segT segment; /* Segment identifier (SEG_<something>) */
979 valueT valu; /* Symbol value */
980 fragS *frag; /* Associated fragment */
982 unsigned int name_length;
983 char *preserved_copy_of_name;
985 name_length = strlen (name) + 1; /* +1 for \0 */
986 obstack_grow (¬es, name, name_length);
987 preserved_copy_of_name = obstack_finish (¬es);
988 #ifdef STRIP_UNDERSCORE
989 if (preserved_copy_of_name[0] == '_')
990 preserved_copy_of_name++;
993 #ifdef tc_canonicalize_symbol_name
994 preserved_copy_of_name =
995 tc_canonicalize_symbol_name (preserved_copy_of_name);
998 S_SET_NAME (symbolP, preserved_copy_of_name);
1000 S_SET_SEGMENT (symbolP, segment);
1001 S_SET_VALUE (symbolP, valu);
1002 symbol_clear_list_pointers(symbolP);
1004 symbolP->sy_frag = frag;
1007 * Link to end of symbol chain.
1010 extern int symbol_table_frozen;
1011 if (symbol_table_frozen)
1015 symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
1017 obj_symbol_new_hook (symbolP);
1019 #ifdef tc_symbol_new_hook
1020 tc_symbol_new_hook (symbolP);
1024 verify_symbol_chain(symbol_rootP, symbol_lastP);
1025 #endif /* DEBUG_SYMS */
1029 symbol_make_empty ()
1033 symbolP = (symbolS *) obstack_alloc (¬es, sizeof (symbolS));
1035 /* symbol must be born in some fixed state. This seems as good as any. */
1036 memset (symbolP, 0, sizeof (symbolS));
1038 symbolP->bsym = bfd_make_empty_symbol (stdoutput);
1039 assert (symbolP->bsym != 0);
1040 symbolP->bsym->udata.p = (PTR) symbolP;
1045 /* Check that an immediate is valid, and if so, convert it to the right format. */
1048 validate_immediate (val)
1054 #define rotate_left(v, n) (v << n | v >> (32 - n))
1056 for (i = 0; i < 32; i += 2)
1057 if ((a = rotate_left (val, i)) <= 0xff)
1058 return a | (i << 7); /* 12-bit pack: [shift-cnt,const] */
1063 validate_offset_imm (val, hwse)
1067 if ((hwse && (val < -255 || val > 255))
1068 || (val < -4095 || val > 4095))
1078 as_bad (_("Invalid syntax for .req directive."));
1085 /* We don't support putting frags in the BSS segment, we fake it by
1086 marking in_bss, then looking at s_skip for clues?.. */
1087 subseg_set (bss_section, 0);
1088 demand_empty_rest_of_line ();
1095 if (!need_pass_2) /* Never make frag if expect extra pass. */
1096 frag_align (1, 0, 0);
1097 record_alignment (now_seg, 1);
1098 demand_empty_rest_of_line ();
1108 if (current_poolP == NULL)
1112 as_tsktsk (_("Nothing to put in the pool\n"));
1116 /* Align pool as you have word accesses */
1117 /* Only make a frag if we have to ... */
1119 frag_align (2, 0, 0);
1121 record_alignment (now_seg, 2);
1124 as_tsktsk (_("Inserting implicit pool at change of section"));
1126 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1128 symbol_locate (current_poolP, sym_name, now_seg,
1129 (valueT) frag_now_fix (), frag_now);
1130 symbol_table_insert (current_poolP);
1132 ARM_SET_THUMB (current_poolP, thumb_mode);
1134 ARM_SET_INTERWORK (current_poolP, support_interwork);
1137 while (lit_count < next_literal_pool_place)
1138 /* First output the expression in the instruction to the pool */
1139 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1141 next_literal_pool_place = 0;
1142 current_poolP = NULL;
1145 #if 0 /* not used */
1147 arm_align (power, fill)
1151 /* Only make a frag if we HAVE to ... */
1152 if (power && !need_pass_2)
1153 frag_align (power, fill, 0);
1155 record_alignment (now_seg, power);
1160 s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */
1164 register long temp_fill;
1165 long max_alignment = 15;
1167 temp = get_absolute_expression ();
1168 if (temp > max_alignment)
1169 as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
1172 as_bad (_("Alignment negative. 0 assumed."));
1176 if (*input_line_pointer == ',')
1178 input_line_pointer++;
1179 temp_fill = get_absolute_expression ();
1187 /* Only make a frag if we HAVE to. . . */
1188 if (temp && !need_pass_2)
1189 frag_align (temp, (int) temp_fill, 0);
1190 demand_empty_rest_of_line ();
1192 record_alignment (now_seg, temp);
1196 s_force_thumb (ignore)
1199 /* If we are not already in thumb mode go into it, EVEN if
1200 the target processor does not support thumb instructions.
1201 This is used by gcc/config/arm/lib1funcs.asm for example
1202 to compile interworking support functions even if the
1203 target processor should not support interworking. */
1209 record_alignment (now_seg, 1);
1212 demand_empty_rest_of_line ();
1216 s_thumb_func (ignore)
1219 /* The following label is the name/address of the start of a Thumb function.
1220 We need to know this for the interworking support. */
1222 label_is_thumb_function_name = true;
1224 demand_empty_rest_of_line();
1228 opcode_select (width)
1236 if (! (cpu_variant & ARM_THUMB))
1237 as_bad (_("selected processor does not support THUMB opcodes"));
1239 /* No need to force the alignment, since we will have been
1240 coming from ARM mode, which is word-aligned. */
1241 record_alignment (now_seg, 1);
1248 if ((cpu_variant & ARM_ANY) == ARM_THUMB)
1249 as_bad (_("selected processor does not support ARM opcodes"));
1252 frag_align (2, 0, 0);
1253 record_alignment (now_seg, 1);
1258 as_bad (_("invalid instruction size selected (%d)"), width);
1267 demand_empty_rest_of_line ();
1275 demand_empty_rest_of_line ();
1284 temp = get_absolute_expression ();
1289 opcode_select(temp);
1293 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1305 inst.error = _("Garbage following instruction");
1309 skip_past_comma (str)
1315 while ((c = *p) == ' ' || c == ',')
1318 if (c == ',' && comma++)
1326 return comma ? SUCCESS : FAIL;
1329 /* A standard register must be given at this point. Shift is the place to
1330 put it in the instruction. */
1333 reg_required_here (str, shift)
1340 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1342 inst.instruction |= reg << shift;
1346 /* In the few cases where we might be able to accept something else
1347 this error can be overridden */
1348 inst.error = _("Register expected");
1350 /* Restore the start point, we may have got a reg of the wrong class. */
1356 psr_required_here (str, cpsr, spsr)
1362 char * start = *str;
1363 psr = arm_psr_parse (str);
1365 if (psr == cpsr || psr == spsr)
1368 inst.instruction |= 1 << 22;
1373 /* In the few cases where we might be able to accept something else
1374 this error can be overridden */
1375 inst.error = _("<psr(f)> expected");
1377 /* Restore the start point. */
1383 co_proc_number (str)
1386 int processor, pchar;
1388 while (**str == ' ')
1391 /* The data sheet seems to imply that just a number on its own is valid
1392 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1394 if (**str == 'p' || **str == 'P')
1398 if (pchar >= '0' && pchar <= '9')
1400 processor = pchar - '0';
1401 if (**str >= '0' && **str <= '9')
1403 processor = processor * 10 + *(*str)++ - '0';
1406 inst.error = _("Illegal co-processor number");
1413 inst.error = _("Bad or missing co-processor number");
1417 inst.instruction |= processor << 8;
1422 cp_opc_expr (str, where, length)
1429 while (**str == ' ')
1432 memset (&expr, '\0', sizeof (expr));
1434 if (my_get_expression (&expr, str))
1436 if (expr.X_op != O_constant)
1438 inst.error = _("bad or missing expression");
1442 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1444 inst.error = _("immediate co-processor expression too large");
1448 inst.instruction |= expr.X_add_number << where;
1453 cp_reg_required_here (str, where)
1460 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1463 inst.instruction |= reg << where;
1467 /* In the few cases where we might be able to accept something else
1468 this error can be overridden */
1469 inst.error = _("Co-processor register expected");
1471 /* Restore the start point */
1477 fp_reg_required_here (str, where)
1484 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1487 inst.instruction |= reg << where;
1491 /* In the few cases where we might be able to accept something else
1492 this error can be overridden */
1493 inst.error = _("Floating point register expected");
1495 /* Restore the start point */
1501 cp_address_offset (str)
1506 while (**str == ' ')
1511 inst.error = _("immediate expression expected");
1516 if (my_get_expression (&inst.reloc.exp, str))
1518 if (inst.reloc.exp.X_op == O_constant)
1520 offset = inst.reloc.exp.X_add_number;
1523 inst.error = _("co-processor address must be word aligned");
1527 if (offset > 1023 || offset < -1023)
1529 inst.error = _("offset too large");
1534 inst.instruction |= INDEX_UP;
1538 inst.instruction |= offset >> 2;
1541 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1547 cp_address_required_here (str)
1562 if ((reg = reg_required_here (&p, 16)) == FAIL)
1564 inst.error = _("Register required");
1574 if (skip_past_comma (&p) == SUCCESS)
1577 write_back = WRITE_BACK;
1580 inst.error = _("pc may not be used in post-increment");
1584 if (cp_address_offset (&p) == FAIL)
1588 pre_inc = PRE_INDEX | INDEX_UP;
1592 /* '['Rn, #expr']'[!] */
1594 if (skip_past_comma (&p) == FAIL)
1596 inst.error = _("pre-indexed expression expected");
1600 pre_inc = PRE_INDEX;
1601 if (cp_address_offset (&p) == FAIL)
1609 inst.error = _("missing ]");
1620 inst.error = _("pc may not be used with write-back");
1625 write_back = WRITE_BACK;
1631 if (my_get_expression (&inst.reloc.exp, &p))
1634 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1635 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
1636 inst.reloc.pc_rel = 1;
1637 inst.instruction |= (REG_PC << 16);
1638 pre_inc = PRE_INDEX;
1641 inst.instruction |= write_back | pre_inc;
1649 unsigned long flags;
1651 /* Do nothing really */
1652 inst.instruction |= flags; /* This is pointless */
1660 unsigned long flags;
1662 /* Only one syntax */
1666 if (reg_required_here (&str, 12) == FAIL)
1668 inst.error = bad_args;
1672 if (skip_past_comma (&str) == FAIL
1673 || psr_required_here (& str, CPSR_ALL, SPSR_ALL) == FAIL)
1675 inst.error = _("<psr> expected");
1679 inst.instruction |= flags;
1684 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1688 unsigned long flags;
1695 if (psr_required_here (&str, CPSR_ALL, SPSR_ALL) == SUCCESS)
1697 inst.instruction |= PSR_ALL;
1699 /* Sytax should be "<psr>, Rm" */
1700 if (skip_past_comma (&str) == FAIL
1701 || (reg = reg_required_here (&str, 0)) == FAIL)
1703 inst.error = bad_args;
1709 if (psr_required_here (& str, CPSR_FLG, SPSR_FLG) == SUCCESS)
1711 inst.instruction |= PSR_FLAGS;
1713 else if (psr_required_here (& str, CPSR_CTL, SPSR_CTL) == SUCCESS)
1715 inst.instruction |= PSR_CONTROL;
1719 inst.error = bad_args;
1723 if (skip_past_comma (&str) == FAIL)
1725 inst.error = bad_args;
1729 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1731 if ((reg = reg_required_here (&str, 0)) != FAIL)
1733 /* Immediate expression */
1734 else if (*(str++) == '#')
1737 if (my_get_expression (&inst.reloc.exp, &str))
1739 inst.error = _("Register or shift expression expected");
1743 if (inst.reloc.exp.X_add_symbol)
1745 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
1746 inst.reloc.pc_rel = 0;
1750 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
1753 inst.error = _("Invalid constant");
1757 inst.instruction |= value;
1760 flags |= INST_IMMEDIATE;
1764 inst.error = _("Error: unrecognised syntax for second argument to msr instruction");
1770 inst.instruction |= flags;
1775 /* Long Multiply Parser
1776 UMULL RdLo, RdHi, Rm, Rs
1777 SMULL RdLo, RdHi, Rm, Rs
1778 UMLAL RdLo, RdHi, Rm, Rs
1779 SMLAL RdLo, RdHi, Rm, Rs
1782 do_mull (str, flags)
1784 unsigned long flags;
1786 int rdlo, rdhi, rm, rs;
1788 /* only one format "rdlo, rdhi, rm, rs" */
1792 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
1794 inst.error = bad_args;
1798 if (skip_past_comma (&str) == FAIL
1799 || (rdhi = reg_required_here (&str, 16)) == FAIL)
1801 inst.error = bad_args;
1805 if (skip_past_comma (&str) == FAIL
1806 || (rm = reg_required_here (&str, 0)) == FAIL)
1808 inst.error = bad_args;
1812 /* rdhi, rdlo and rm must all be different */
1813 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
1814 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1816 if (skip_past_comma (&str) == FAIL
1817 || (rs = reg_required_here (&str, 8)) == FAIL)
1819 inst.error = bad_args;
1823 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
1825 inst.error = bad_pc;
1829 inst.instruction |= flags;
1837 unsigned long flags;
1841 /* only one format "rd, rm, rs" */
1845 if ((rd = reg_required_here (&str, 16)) == FAIL)
1847 inst.error = bad_args;
1853 inst.error = bad_pc;
1857 if (skip_past_comma (&str) == FAIL
1858 || (rm = reg_required_here (&str, 0)) == FAIL)
1860 inst.error = bad_args;
1866 inst.error = bad_pc;
1871 as_tsktsk (_("rd and rm should be different in mul"));
1873 if (skip_past_comma (&str) == FAIL
1874 || (rm = reg_required_here (&str, 8)) == FAIL)
1876 inst.error = bad_args;
1882 inst.error = bad_pc;
1886 inst.instruction |= flags;
1894 unsigned long flags;
1898 /* only one format "rd, rm, rs, rn" */
1902 if ((rd = reg_required_here (&str, 16)) == FAIL)
1904 inst.error = bad_args;
1910 inst.error = bad_pc;
1914 if (skip_past_comma (&str) == FAIL
1915 || (rm = reg_required_here (&str, 0)) == FAIL)
1917 inst.error = bad_args;
1923 inst.error = bad_pc;
1928 as_tsktsk (_("rd and rm should be different in mla"));
1930 if (skip_past_comma (&str) == FAIL
1931 || (rd = reg_required_here (&str, 8)) == FAIL
1932 || skip_past_comma (&str) == FAIL
1933 || (rm = reg_required_here (&str, 12)) == FAIL)
1935 inst.error = bad_args;
1939 if (rd == REG_PC || rm == REG_PC)
1941 inst.error = bad_pc;
1945 inst.instruction |= flags;
1950 /* Returns the index into fp_values of a floating point number, or -1 if
1951 not in the table. */
1953 my_get_float_expression (str)
1956 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1961 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
1962 /* Look for a raw floating point number */
1963 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
1964 && (is_end_of_line [(int)(*save_in)] || *save_in == '\0'))
1966 for (i = 0; i < NUM_FLOAT_VALS; i++)
1968 for (j = 0; j < MAX_LITTLENUMS; j++)
1970 if (words[j] != fp_values[i][j])
1974 if (j == MAX_LITTLENUMS)
1982 /* Try and parse a more complex expression, this will probably fail
1983 unless the code uses a floating point prefix (eg "0f") */
1984 save_in = input_line_pointer;
1985 input_line_pointer = *str;
1986 if (expression (&exp) == absolute_section
1987 && exp.X_op == O_big
1988 && exp.X_add_number < 0)
1990 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
1992 if (gen_to_words (words, 5, (long)15) == 0)
1994 for (i = 0; i < NUM_FLOAT_VALS; i++)
1996 for (j = 0; j < MAX_LITTLENUMS; j++)
1998 if (words[j] != fp_values[i][j])
2002 if (j == MAX_LITTLENUMS)
2004 *str = input_line_pointer;
2005 input_line_pointer = save_in;
2012 *str = input_line_pointer;
2013 input_line_pointer = save_in;
2017 /* Return true if anything in the expression is a bignum */
2019 walk_no_bignums (sp)
2022 if (sp->sy_value.X_op == O_big)
2025 if (sp->sy_value.X_add_symbol)
2027 return (walk_no_bignums (sp->sy_value.X_add_symbol)
2028 || (sp->sy_value.X_op_symbol
2029 && walk_no_bignums (sp->sy_value.X_op_symbol)));
2036 my_get_expression (ep, str)
2043 save_in = input_line_pointer;
2044 input_line_pointer = *str;
2045 seg = expression (ep);
2048 if (seg != absolute_section
2049 && seg != text_section
2050 && seg != data_section
2051 && seg != bss_section
2052 && seg != undefined_section)
2054 inst.error = _("bad_segment");
2055 *str = input_line_pointer;
2056 input_line_pointer = save_in;
2061 /* Get rid of any bignums now, so that we don't generate an error for which
2062 we can't establish a line number later on. Big numbers are never valid
2063 in instructions, which is where this routine is always called. */
2064 if (ep->X_op == O_big
2065 || (ep->X_add_symbol
2066 && (walk_no_bignums (ep->X_add_symbol)
2068 && walk_no_bignums (ep->X_op_symbol)))))
2070 inst.error = _("Invalid constant");
2071 *str = input_line_pointer;
2072 input_line_pointer = save_in;
2076 *str = input_line_pointer;
2077 input_line_pointer = save_in;
2081 /* unrestrict should be one if <shift> <register> is permitted for this
2085 decode_shift (str, unrestrict)
2089 struct asm_shift *shft;
2093 while (**str == ' ')
2096 for (p = *str; isalpha (*p); p++)
2101 inst.error = _("Shift expression expected");
2107 shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
2111 if (!strncmp (*str, "rrx", 3)
2112 || !strncmp (*str, "RRX", 3))
2115 inst.instruction |= shft->value;
2122 if (unrestrict && reg_required_here (&p, 8) != FAIL)
2124 inst.instruction |= shft->value | SHIFT_BY_REG;
2132 if (my_get_expression (&inst.reloc.exp, &p))
2135 /* Validate some simple #expressions */
2136 if (inst.reloc.exp.X_op == O_constant)
2138 unsigned num = inst.reloc.exp.X_add_number;
2140 /* Reject operations greater than 32, or lsl #32 */
2141 if (num > 32 || (num == 32 && shft->value == 0))
2143 inst.error = _("Invalid immediate shift");
2147 /* Shifts of zero should be converted to lsl (which is zero)*/
2154 /* Shifts of 32 are encoded as 0, for those shifts that
2159 inst.instruction |= (num << 7) | shft->value;
2164 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
2165 inst.reloc.pc_rel = 0;
2166 inst.instruction |= shft->value;
2172 inst.error = unrestrict ? _("shift requires register or #expression")
2173 : _("shift requires #expression");
2179 inst.error = _("Shift expression expected");
2183 /* Do those data_ops which can take a negative immediate constant */
2184 /* by altering the instuction. A bit of a hack really */
2188 by inverting the second operand, and
2191 by negating the second operand.
2194 negate_data_op (instruction, value)
2195 unsigned long *instruction;
2196 unsigned long value;
2199 unsigned long negated, inverted;
2201 negated = validate_immediate (-value);
2202 inverted = validate_immediate (~value);
2204 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
2208 case OPCODE_SUB: /* ADD <-> SUB */
2209 new_inst = OPCODE_ADD;
2214 new_inst = OPCODE_SUB;
2218 case OPCODE_CMP: /* CMP <-> CMN */
2219 new_inst = OPCODE_CMN;
2224 new_inst = OPCODE_CMP;
2228 /* Now Inverted ops */
2229 case OPCODE_MOV: /* MOV <-> MVN */
2230 new_inst = OPCODE_MVN;
2235 new_inst = OPCODE_MOV;
2239 case OPCODE_AND: /* AND <-> BIC */
2240 new_inst = OPCODE_BIC;
2245 new_inst = OPCODE_AND;
2249 case OPCODE_ADC: /* ADC <-> SBC */
2250 new_inst = OPCODE_SBC;
2255 new_inst = OPCODE_ADC;
2259 /* We cannot do anything */
2267 *instruction &= OPCODE_MASK;
2268 *instruction |= new_inst << DATA_OP_SHIFT;
2279 while (**str == ' ')
2282 if (reg_required_here (str, 0) != FAIL)
2284 if (skip_past_comma (str) == SUCCESS)
2286 /* Shift operation on register */
2287 return decode_shift (str, NO_SHIFT_RESTRICT);
2293 /* Immediate expression */
2294 if (*((*str)++) == '#')
2297 if (my_get_expression (&inst.reloc.exp, str))
2300 if (inst.reloc.exp.X_add_symbol)
2302 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2303 inst.reloc.pc_rel = 0;
2307 if (skip_past_comma (str) == SUCCESS)
2309 /* #x, y -- ie explicit rotation by Y */
2310 if (my_get_expression (&expr, str))
2313 if (expr.X_op != O_constant)
2315 inst.error = _("Constant expression expected");
2319 /* Rotate must be a multiple of 2 */
2320 if (((unsigned) expr.X_add_number) > 30
2321 || (expr.X_add_number & 1) != 0
2322 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
2324 inst.error = _("Invalid constant");
2327 inst.instruction |= INST_IMMEDIATE;
2328 inst.instruction |= inst.reloc.exp.X_add_number;
2329 inst.instruction |= expr.X_add_number << 7;
2333 /* Implicit rotation, select a suitable one */
2334 value = validate_immediate (inst.reloc.exp.X_add_number);
2338 /* Can't be done, perhaps the code reads something like
2339 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2340 if ((value = negate_data_op (&inst.instruction,
2341 inst.reloc.exp.X_add_number))
2344 inst.error = _("Invalid constant");
2349 inst.instruction |= value;
2352 inst.instruction |= INST_IMMEDIATE;
2356 inst.error = _("Register or shift expression expected");
2365 while (**str == ' ')
2368 if (fp_reg_required_here (str, 0) != FAIL)
2372 /* Immediate expression */
2373 if (*((*str)++) == '#')
2378 while (**str == ' ')
2381 /* First try and match exact strings, this is to guarantee that
2382 some formats will work even for cross assembly */
2384 for (i = 0; fp_const[i]; i++)
2386 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2390 *str += strlen (fp_const[i]);
2391 if (is_end_of_line[(int)**str] || **str == '\0')
2393 inst.instruction |= i + 8;
2400 /* Just because we didn't get a match doesn't mean that the
2401 constant isn't valid, just that it is in a format that we
2402 don't automatically recognize. Try parsing it with
2403 the standard expression routines. */
2404 if ((i = my_get_float_expression (str)) >= 0)
2406 inst.instruction |= i + 8;
2410 inst.error = _("Invalid floating point immediate expression");
2413 inst.error = _("Floating point register or immediate expression expected");
2419 do_arit (str, flags)
2421 unsigned long flags;
2426 if (reg_required_here (&str, 12) == FAIL
2427 || skip_past_comma (&str) == FAIL
2428 || reg_required_here (&str, 16) == FAIL
2429 || skip_past_comma (&str) == FAIL
2430 || data_op2 (&str) == FAIL)
2433 inst.error = bad_args;
2437 inst.instruction |= flags;
2445 unsigned long flags;
2447 /* This is a pseudo-op of the form "adr rd, label" to be converted
2448 into a relative address of the form "add rd, pc, #label-.-8" */
2453 if (reg_required_here (&str, 12) == FAIL
2454 || skip_past_comma (&str) == FAIL
2455 || my_get_expression (&inst.reloc.exp, &str))
2458 inst.error = bad_args;
2461 /* Frag hacking will turn this into a sub instruction if the offset turns
2462 out to be negative. */
2463 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2464 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2465 inst.reloc.pc_rel = 1;
2466 inst.instruction |= flags;
2474 unsigned long flags;
2479 if (reg_required_here (&str, 16) == FAIL)
2482 inst.error = bad_args;
2486 if (skip_past_comma (&str) == FAIL
2487 || data_op2 (&str) == FAIL)
2490 inst.error = bad_args;
2494 inst.instruction |= flags;
2495 if ((flags & 0x0000f000) == 0)
2496 inst.instruction |= CONDS_BIT;
2505 unsigned long flags;
2510 if (reg_required_here (&str, 12) == FAIL)
2513 inst.error = bad_args;
2517 if (skip_past_comma (&str) == FAIL
2518 || data_op2 (&str) == FAIL)
2521 inst.error = bad_args;
2525 inst.instruction |= flags;
2531 ldst_extend (str, hwse)
2541 if (my_get_expression (&inst.reloc.exp, str))
2544 if (inst.reloc.exp.X_op == O_constant)
2546 int value = inst.reloc.exp.X_add_number;
2548 if ((hwse && (value < -255 || value > 255))
2549 || (value < -4095 || value > 4095))
2551 inst.error = _("address offset too large");
2561 /* Halfword and signextension instructions have the
2562 immediate value split across bits 11..8 and bits 3..0 */
2564 inst.instruction |= add | HWOFFSET_IMM | (value >> 4) << 8 | value & 0xF;
2566 inst.instruction |= add | value;
2572 inst.instruction |= HWOFFSET_IMM;
2573 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2576 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2577 inst.reloc.pc_rel = 0;
2582 add = 0; /* and fall through */
2584 (*str)++; /* and fall through */
2586 if (reg_required_here (str, 0) == FAIL)
2588 inst.error = _("Register expected");
2593 inst.instruction |= add;
2596 inst.instruction |= add | OFFSET_REG;
2597 if (skip_past_comma (str) == SUCCESS)
2598 return decode_shift (str, SHIFT_RESTRICT);
2606 do_ldst (str, flags)
2608 unsigned long flags;
2615 /* This is not ideal, but it is the simplest way of dealing with the
2616 ARM7T halfword instructions (since they use a different
2617 encoding, but the same mnemonic): */
2618 if (halfword = ((flags & 0x80000000) != 0))
2620 /* This is actually a load/store of a halfword, or a
2621 signed-extension load */
2622 if ((cpu_variant & ARM_HALFWORD) == 0)
2625 = _("Processor does not support halfwords or signed bytes");
2629 inst.instruction = (inst.instruction & COND_MASK)
2630 | (flags & ~COND_MASK);
2638 if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
2641 inst.error = bad_args;
2645 if (skip_past_comma (&str) == FAIL)
2647 inst.error = _("Address expected");
2659 if ((reg = reg_required_here (&str, 16)) == FAIL)
2661 inst.error = _("Register required");
2665 conflict_reg = (((conflict_reg == reg)
2666 && (inst.instruction & LOAD_BIT))
2675 if (skip_past_comma (&str) == SUCCESS)
2677 /* [Rn],... (post inc) */
2678 if (ldst_extend (&str, halfword) == FAIL)
2681 as_warn (_("destination register same as write-back base\n"));
2687 inst.instruction |= HWOFFSET_IMM;
2695 as_warn (_("destination register same as write-back base\n"));
2697 inst.instruction |= WRITE_BACK;
2701 if (! (flags & TRANS_BIT))
2708 if (skip_past_comma (&str) == FAIL)
2710 inst.error = _("pre-indexed expression expected");
2715 if (ldst_extend (&str, halfword) == FAIL)
2723 inst.error = _("missing ]");
2733 as_tsktsk (_("destination register same as write-back base\n"));
2735 inst.instruction |= WRITE_BACK;
2739 else if (*str == '=')
2741 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2747 if (my_get_expression (&inst.reloc.exp, &str))
2750 if (inst.reloc.exp.X_op != O_constant
2751 && inst.reloc.exp.X_op != O_symbol)
2753 inst.error = _("Constant expression expected");
2757 if (inst.reloc.exp.X_op == O_constant
2758 && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
2760 /* This can be done with a mov instruction */
2761 inst.instruction &= LITERAL_MASK;
2762 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
2763 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
2769 /* Insert into literal pool */
2770 if (add_to_lit_pool () == FAIL)
2773 inst.error = _("literal pool insertion failed");
2777 /* Change the instruction exp to point to the pool */
2780 inst.instruction |= HWOFFSET_IMM;
2781 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
2784 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
2785 inst.reloc.pc_rel = 1;
2786 inst.instruction |= (REG_PC << 16);
2792 if (my_get_expression (&inst.reloc.exp, &str))
2797 inst.instruction |= HWOFFSET_IMM;
2798 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2801 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2802 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
2803 inst.reloc.pc_rel = 1;
2804 inst.instruction |= (REG_PC << 16);
2808 if (pre_inc && (flags & TRANS_BIT))
2809 inst.error = _("Pre-increment instruction with translate");
2811 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
2824 /* We come back here if we get ranges concatenated by '+' or '|' */
2842 if ((reg = arm_reg_parse (&str)) == FAIL || !int_register (reg))
2844 inst.error = _("Register expected");
2854 inst.error = _("Bad range in register list");
2858 for (i = cur_reg + 1; i < reg; i++)
2860 if (range & (1 << i))
2862 (_("Warning: Duplicated register (r%d) in register list"),
2870 if (range & (1 << reg))
2871 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
2873 else if (reg <= cur_reg)
2874 as_tsktsk (_("Warning: Register range not in ascending order"));
2878 } while (skip_past_comma (&str) != FAIL
2879 || (in_range = 1, *str++ == '-'));
2886 inst.error = _("Missing `}'");
2894 if (my_get_expression (&expr, &str))
2897 if (expr.X_op == O_constant)
2899 if (expr.X_add_number
2900 != (expr.X_add_number & 0x0000ffff))
2902 inst.error = _("invalid register mask");
2906 if ((range & expr.X_add_number) != 0)
2908 int regno = range & expr.X_add_number;
2911 regno = (1 << regno) - 1;
2913 (_("Warning: Duplicated register (r%d) in register list"),
2917 range |= expr.X_add_number;
2921 if (inst.reloc.type != 0)
2923 inst.error = _("expression too complex");
2927 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
2928 inst.reloc.type = BFD_RELOC_ARM_MULTI;
2929 inst.reloc.pc_rel = 0;
2936 if (*str == '|' || *str == '+')
2941 } while (another_range);
2948 do_ldmstm (str, flags)
2950 unsigned long flags;
2958 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
2961 inst.error = bad_args;
2965 if (base_reg == REG_PC)
2967 inst.error = _("r15 not allowed as base register");
2975 flags |= WRITE_BACK;
2979 if (skip_past_comma (&str) == FAIL
2980 || (range = reg_list (&str)) == FAIL)
2983 inst.error = bad_args;
2990 flags |= MULTI_SET_PSR;
2993 inst.instruction |= flags | range;
3001 unsigned long flags;
3003 /* Allow optional leading '#'. */
3009 if (my_get_expression (&inst.reloc.exp, &str))
3012 inst.reloc.type = BFD_RELOC_ARM_SWI;
3013 inst.reloc.pc_rel = 0;
3014 inst.instruction |= flags;
3020 do_swap (str, flags)
3022 unsigned long flags;
3029 if ((reg = reg_required_here (&str, 12)) == FAIL)
3034 inst.error = _("r15 not allowed in swap");
3038 if (skip_past_comma (&str) == FAIL
3039 || (reg = reg_required_here (&str, 0)) == FAIL)
3042 inst.error = bad_args;
3048 inst.error = _("r15 not allowed in swap");
3052 if (skip_past_comma (&str) == FAIL
3055 inst.error = bad_args;
3062 if ((reg = reg_required_here (&str, 16)) == FAIL)
3067 inst.error = bad_pc;
3076 inst.error = _("missing ]");
3080 inst.instruction |= flags;
3086 do_branch (str, flags)
3088 unsigned long flags;
3090 if (my_get_expression (&inst.reloc.exp, &str))
3092 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3093 inst.reloc.pc_rel = 1;
3101 unsigned long flags;
3108 if ((reg = reg_required_here (&str, 0)) == FAIL)
3112 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3121 unsigned long flags;
3123 /* Co-processor data operation.
3124 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3128 if (co_proc_number (&str) == FAIL)
3131 inst.error = bad_args;
3135 if (skip_past_comma (&str) == FAIL
3136 || cp_opc_expr (&str, 20,4) == FAIL)
3139 inst.error = bad_args;
3143 if (skip_past_comma (&str) == FAIL
3144 || cp_reg_required_here (&str, 12) == FAIL)
3147 inst.error = bad_args;
3151 if (skip_past_comma (&str) == FAIL
3152 || cp_reg_required_here (&str, 16) == FAIL)
3155 inst.error = bad_args;
3159 if (skip_past_comma (&str) == FAIL
3160 || cp_reg_required_here (&str, 0) == FAIL)
3163 inst.error = bad_args;
3167 if (skip_past_comma (&str) == SUCCESS)
3169 if (cp_opc_expr (&str, 5, 3) == FAIL)
3172 inst.error = bad_args;
3182 do_lstc (str, flags)
3184 unsigned long flags;
3186 /* Co-processor register load/store.
3187 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3192 if (co_proc_number (&str) == FAIL)
3195 inst.error = bad_args;
3199 if (skip_past_comma (&str) == FAIL
3200 || cp_reg_required_here (&str, 12) == FAIL)
3203 inst.error = bad_args;
3207 if (skip_past_comma (&str) == FAIL
3208 || cp_address_required_here (&str) == FAIL)
3211 inst.error = bad_args;
3215 inst.instruction |= flags;
3221 do_co_reg (str, flags)
3223 unsigned long flags;
3225 /* Co-processor register transfer.
3226 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3231 if (co_proc_number (&str) == FAIL)
3234 inst.error = bad_args;
3238 if (skip_past_comma (&str) == FAIL
3239 || cp_opc_expr (&str, 21, 3) == FAIL)
3242 inst.error = bad_args;
3246 if (skip_past_comma (&str) == FAIL
3247 || reg_required_here (&str, 12) == FAIL)
3250 inst.error = bad_args;
3254 if (skip_past_comma (&str) == FAIL
3255 || cp_reg_required_here (&str, 16) == FAIL)
3258 inst.error = bad_args;
3262 if (skip_past_comma (&str) == FAIL
3263 || cp_reg_required_here (&str, 0) == FAIL)
3266 inst.error = bad_args;
3270 if (skip_past_comma (&str) == SUCCESS)
3272 if (cp_opc_expr (&str, 5, 3) == FAIL)
3275 inst.error = bad_args;
3285 do_fp_ctrl (str, flags)
3287 unsigned long flags;
3289 /* FP control registers.
3290 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3295 if (reg_required_here (&str, 12) == FAIL)
3298 inst.error = bad_args;
3307 do_fp_ldst (str, flags)
3309 unsigned long flags;
3314 switch (inst.suffix)
3319 inst.instruction |= CP_T_X;
3322 inst.instruction |= CP_T_Y;
3325 inst.instruction |= CP_T_X | CP_T_Y;
3331 if (fp_reg_required_here (&str, 12) == FAIL)
3334 inst.error = bad_args;
3338 if (skip_past_comma (&str) == FAIL
3339 || cp_address_required_here (&str) == FAIL)
3342 inst.error = bad_args;
3350 do_fp_ldmstm (str, flags)
3352 unsigned long flags;
3359 if (fp_reg_required_here (&str, 12) == FAIL)
3362 inst.error = bad_args;
3366 /* Get Number of registers to transfer */
3367 if (skip_past_comma (&str) == FAIL
3368 || my_get_expression (&inst.reloc.exp, &str))
3371 inst.error = _("constant expression expected");
3375 if (inst.reloc.exp.X_op != O_constant)
3377 inst.error = _("Constant value required for number of registers");
3381 num_regs = inst.reloc.exp.X_add_number;
3383 if (num_regs < 1 || num_regs > 4)
3385 inst.error = _("number of registers must be in the range [1:4]");
3392 inst.instruction |= CP_T_X;
3395 inst.instruction |= CP_T_Y;
3398 inst.instruction |= CP_T_Y | CP_T_X;
3412 /* The instruction specified "ea" or "fd", so we can only accept
3413 [Rn]{!}. The instruction does not really support stacking or
3414 unstacking, so we have to emulate these by setting appropriate
3415 bits and offsets. */
3416 if (skip_past_comma (&str) == FAIL
3420 inst.error = bad_args;
3428 if ((reg = reg_required_here (&str, 16)) == FAIL)
3430 inst.error = _("Register required");
3439 inst.error = bad_args;
3450 inst.error = _("R15 not allowed as base register with write-back");
3457 if (flags & CP_T_Pre)
3460 offset = 3 * num_regs;
3466 /* Post-increment */
3470 offset = 3 * num_regs;
3474 /* No write-back, so convert this into a standard pre-increment
3475 instruction -- aesthetically more pleasing. */
3476 flags = CP_T_Pre | CP_T_UD;
3481 inst.instruction |= flags | offset;
3483 else if (skip_past_comma (&str) == FAIL
3484 || cp_address_required_here (&str) == FAIL)
3487 inst.error = bad_args;
3495 do_fp_dyadic (str, flags)
3497 unsigned long flags;
3502 switch (inst.suffix)
3507 inst.instruction |= 0x00000080;
3510 inst.instruction |= 0x00080000;
3516 if (fp_reg_required_here (&str, 12) == FAIL)
3519 inst.error = bad_args;
3523 if (skip_past_comma (&str) == FAIL
3524 || fp_reg_required_here (&str, 16) == FAIL)
3527 inst.error = bad_args;
3531 if (skip_past_comma (&str) == FAIL
3532 || fp_op2 (&str) == FAIL)
3535 inst.error = bad_args;
3539 inst.instruction |= flags;
3545 do_fp_monadic (str, flags)
3547 unsigned long flags;
3552 switch (inst.suffix)
3557 inst.instruction |= 0x00000080;
3560 inst.instruction |= 0x00080000;
3566 if (fp_reg_required_here (&str, 12) == FAIL)
3569 inst.error = bad_args;
3573 if (skip_past_comma (&str) == FAIL
3574 || fp_op2 (&str) == FAIL)
3577 inst.error = bad_args;
3581 inst.instruction |= flags;
3587 do_fp_cmp (str, flags)
3589 unsigned long flags;
3594 if (fp_reg_required_here (&str, 16) == FAIL)
3597 inst.error = bad_args;
3601 if (skip_past_comma (&str) == FAIL
3602 || fp_op2 (&str) == FAIL)
3605 inst.error = bad_args;
3609 inst.instruction |= flags;
3615 do_fp_from_reg (str, flags)
3617 unsigned long flags;
3622 switch (inst.suffix)
3627 inst.instruction |= 0x00000080;
3630 inst.instruction |= 0x00080000;
3636 if (fp_reg_required_here (&str, 16) == FAIL)
3639 inst.error = bad_args;
3643 if (skip_past_comma (&str) == FAIL
3644 || reg_required_here (&str, 12) == FAIL)
3647 inst.error = bad_args;
3651 inst.instruction |= flags;
3657 do_fp_to_reg (str, flags)
3659 unsigned long flags;
3664 if (reg_required_here (&str, 12) == FAIL)
3667 inst.error = bad_args;
3671 if (skip_past_comma (&str) == FAIL
3672 || fp_reg_required_here (&str, 0) == FAIL)
3675 inst.error = bad_args;
3679 inst.instruction |= flags;
3684 /* Thumb specific routines */
3686 /* Parse and validate that a register is of the right form, this saves
3687 repeated checking of this information in many similar cases.
3688 Unlike the 32-bit case we do not insert the register into the opcode
3689 here, since the position is often unknown until the full instruction
3692 thumb_reg (strp, hi_lo)
3698 if ((reg = arm_reg_parse (strp)) == FAIL || ! int_register (reg))
3700 inst.error = _("Register expected");
3709 inst.error = _("lo register required");
3717 inst.error = _("hi register required");
3729 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3732 thumb_add_sub (str, subtract)
3736 int Rd, Rs, Rn = FAIL;
3741 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
3742 || skip_past_comma (&str) == FAIL)
3745 inst.error = bad_args;
3753 if (my_get_expression (&inst.reloc.exp, &str))
3758 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3761 if (skip_past_comma (&str) == FAIL)
3763 /* Two operand format, shuffle the registers and pretend there
3768 else if (*str == '#')
3771 if (my_get_expression (&inst.reloc.exp, &str))
3774 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3778 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3779 for the latter case, EXPR contains the immediate that was found. */
3782 /* All register format. */
3783 if (Rd > 7 || Rs > 7 || Rn > 7)
3787 inst.error = _("dest and source1 must be the same register");
3791 /* Can't do this for SUB */
3794 inst.error = _("subtract valid only on lo regs");
3798 inst.instruction = (T_OPCODE_ADD_HI
3799 | (Rd > 7 ? THUMB_H1 : 0)
3800 | (Rn > 7 ? THUMB_H2 : 0));
3801 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
3805 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
3806 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
3811 /* Immediate expression, now things start to get nasty. */
3813 /* First deal with HI regs, only very restricted cases allowed:
3814 Adjusting SP, and using PC or SP to get an address. */
3815 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
3816 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
3818 inst.error = _("invalid Hi register with immediate");
3822 if (inst.reloc.exp.X_op != O_constant)
3824 /* Value isn't known yet, all we can do is store all the fragments
3825 we know about in the instruction and let the reloc hacking
3827 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
3828 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
3832 int offset = inst.reloc.exp.X_add_number;
3842 /* Quick check, in case offset is MIN_INT */
3845 inst.error = _("immediate value out of range");
3854 if (offset & ~0x1fc)
3856 inst.error = _("invalid immediate value for stack adjust");
3859 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
3860 inst.instruction |= offset >> 2;
3862 else if (Rs == REG_PC || Rs == REG_SP)
3865 || (offset & ~0x3fc))
3867 inst.error = _("invalid immediate for address calculation");
3870 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
3872 inst.instruction |= (Rd << 8) | (offset >> 2);
3878 inst.error = _("immediate value out of range");
3881 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
3882 inst.instruction |= (Rd << 8) | offset;
3888 inst.error = _("immediate value out of range");
3891 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
3892 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
3900 thumb_shift (str, shift)
3904 int Rd, Rs, Rn = FAIL;
3909 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
3910 || skip_past_comma (&str) == FAIL)
3913 inst.error = bad_args;
3919 /* Two operand immediate format, set Rs to Rd. */
3922 if (my_get_expression (&inst.reloc.exp, &str))
3927 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
3930 if (skip_past_comma (&str) == FAIL)
3932 /* Two operand format, shuffle the registers and pretend there
3937 else if (*str == '#')
3940 if (my_get_expression (&inst.reloc.exp, &str))
3943 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
3947 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3948 for the latter case, EXPR contains the immediate that was found. */
3954 inst.error = _("source1 and dest must be same register");
3960 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
3961 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
3962 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
3965 inst.instruction |= Rd | (Rn << 3);
3971 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
3972 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
3973 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
3976 if (inst.reloc.exp.X_op != O_constant)
3978 /* Value isn't known yet, create a dummy reloc and let reloc
3979 hacking fix it up */
3981 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
3985 unsigned shift_value = inst.reloc.exp.X_add_number;
3987 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
3989 inst.error = _("Invalid immediate for shift");
3993 /* Shifts of zero are handled by converting to LSL */
3994 if (shift_value == 0)
3995 inst.instruction = T_OPCODE_LSL_I;
3997 /* Shifts of 32 are encoded as a shift of zero */
3998 if (shift_value == 32)
4001 inst.instruction |= shift_value << 6;
4004 inst.instruction |= Rd | (Rs << 3);
4010 thumb_mov_compare (str, move)
4019 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4020 || skip_past_comma (&str) == FAIL)
4023 inst.error = bad_args;
4030 if (my_get_expression (&inst.reloc.exp, &str))
4033 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4038 if (Rs < 8 && Rd < 8)
4040 if (move == THUMB_MOVE)
4041 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4042 since a MOV instruction produces unpredictable results */
4043 inst.instruction = T_OPCODE_ADD_I3;
4045 inst.instruction = T_OPCODE_CMP_LR;
4046 inst.instruction |= Rd | (Rs << 3);
4050 if (move == THUMB_MOVE)
4051 inst.instruction = T_OPCODE_MOV_HR;
4053 inst.instruction = T_OPCODE_CMP_HR;
4056 inst.instruction |= THUMB_H1;
4059 inst.instruction |= THUMB_H2;
4061 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4068 inst.error = _("only lo regs allowed with immediate");
4072 if (move == THUMB_MOVE)
4073 inst.instruction = T_OPCODE_MOV_I8;
4075 inst.instruction = T_OPCODE_CMP_I8;
4077 inst.instruction |= Rd << 8;
4079 if (inst.reloc.exp.X_op != O_constant)
4080 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4083 unsigned value = inst.reloc.exp.X_add_number;
4087 inst.error = _("invalid immediate");
4091 inst.instruction |= value;
4099 thumb_load_store (str, load_store, size)
4104 int Rd, Rb, Ro = FAIL;
4109 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4110 || skip_past_comma (&str) == FAIL)
4113 inst.error = bad_args;
4120 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4123 if (skip_past_comma (&str) != FAIL)
4128 if (my_get_expression (&inst.reloc.exp, &str))
4131 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4136 inst.reloc.exp.X_op = O_constant;
4137 inst.reloc.exp.X_add_number = 0;
4142 inst.error = _("expected ']'");
4147 else if (*str == '=')
4149 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4155 if (my_get_expression (& inst.reloc.exp, & str))
4160 if ( inst.reloc.exp.X_op != O_constant
4161 && inst.reloc.exp.X_op != O_symbol)
4163 inst.error = "Constant expression expected";
4167 if (inst.reloc.exp.X_op == O_constant
4168 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
4170 /* This can be done with a mov instruction */
4172 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
4173 inst.instruction |= inst.reloc.exp.X_add_number;
4177 /* Insert into literal pool */
4178 if (add_to_lit_pool () == FAIL)
4181 inst.error = "literal pool insertion failed";
4185 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4186 inst.reloc.pc_rel = 1;
4187 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4188 inst.reloc.exp.X_add_number += 4; /* Adjust ARM pipeline offset to Thumb */
4194 if (my_get_expression (&inst.reloc.exp, &str))
4197 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4198 inst.reloc.pc_rel = 1;
4199 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
4200 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4205 if (Rb == REG_PC || Rb == REG_SP)
4207 if (size != THUMB_WORD)
4209 inst.error = _("byte or halfword not valid for base register");
4212 else if (Rb == REG_PC && load_store != THUMB_LOAD)
4214 inst.error = _("R15 based store not allowed");
4217 else if (Ro != FAIL)
4219 inst.error = _("Invalid base register for register offset");
4224 inst.instruction = T_OPCODE_LDR_PC;
4225 else if (load_store == THUMB_LOAD)
4226 inst.instruction = T_OPCODE_LDR_SP;
4228 inst.instruction = T_OPCODE_STR_SP;
4230 inst.instruction |= Rd << 8;
4231 if (inst.reloc.exp.X_op == O_constant)
4233 unsigned offset = inst.reloc.exp.X_add_number;
4235 if (offset & ~0x3fc)
4237 inst.error = _("invalid offset");
4241 inst.instruction |= offset >> 2;
4244 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4248 inst.error = _("invalid base register in load/store");
4251 else if (Ro == FAIL)
4253 /* Immediate offset */
4254 if (size == THUMB_WORD)
4255 inst.instruction = (load_store == THUMB_LOAD
4256 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
4257 else if (size == THUMB_HALFWORD)
4258 inst.instruction = (load_store == THUMB_LOAD
4259 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
4261 inst.instruction = (load_store == THUMB_LOAD
4262 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
4264 inst.instruction |= Rd | (Rb << 3);
4266 if (inst.reloc.exp.X_op == O_constant)
4268 unsigned offset = inst.reloc.exp.X_add_number;
4270 if (offset & ~(0x1f << size))
4272 inst.error = _("Invalid offset");
4275 inst.instruction |= (offset >> size) << 6;
4278 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4282 /* Register offset */
4283 if (size == THUMB_WORD)
4284 inst.instruction = (load_store == THUMB_LOAD
4285 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
4286 else if (size == THUMB_HALFWORD)
4287 inst.instruction = (load_store == THUMB_LOAD
4288 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
4290 inst.instruction = (load_store == THUMB_LOAD
4291 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
4293 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4308 /* Handle the Format 4 instructions that do not have equivalents in other
4309 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4320 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4323 if (skip_past_comma (&str) == FAIL
4324 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4327 inst.error = bad_args;
4331 if (skip_past_comma (&str) != FAIL)
4333 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4334 (It isn't allowed for CMP either, but that isn't handled by this
4336 if (inst.instruction == T_OPCODE_TST
4337 || inst.instruction == T_OPCODE_CMN
4338 || inst.instruction == T_OPCODE_NEG
4339 || inst.instruction == T_OPCODE_MVN)
4341 inst.error = bad_args;
4345 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4350 inst.error = _("dest and source1 one must be the same register");
4356 if (inst.instruction == T_OPCODE_MUL
4358 as_tsktsk (_("Rs and Rd must be different in MUL"));
4360 inst.instruction |= Rd | (Rs << 3);
4368 thumb_add_sub (str, 0);
4375 thumb_shift (str, THUMB_ASR);
4382 if (my_get_expression (&inst.reloc.exp, &str))
4384 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
4385 inst.reloc.pc_rel = 1;
4393 if (my_get_expression (&inst.reloc.exp, &str))
4395 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
4396 inst.reloc.pc_rel = 1;
4400 /* Find the real, Thumb encoded start of a Thumb function. */
4403 find_real_start (symbolP)
4407 const char * name = S_GET_NAME (symbolP);
4408 symbolS * new_target;
4410 /* This definitonmust agree with the one in gcc/config/arm/thumb.c */
4411 #define STUB_NAME ".real_start_of"
4413 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
4414 sprintf (real_start, "%s%s", STUB_NAME, name);
4416 new_target = symbol_find (real_start);
4418 if (new_target == NULL)
4431 if (my_get_expression (&inst.reloc.exp, &str))
4433 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
4434 inst.reloc.pc_rel = 1;
4437 /* If the destination of the branch is a defined symbol which does not have
4438 the THUMB_FUNC attribute, then we must be calling a function which has
4439 the (interfacearm) attribute. We look for the Thumb entry point to that
4440 function and change the branch to refer to that function instead. */
4441 if ( inst.reloc.exp.X_op == O_symbol
4442 && inst.reloc.exp.X_add_symbol != NULL
4443 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
4444 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
4445 inst.reloc.exp.X_add_symbol = find_real_start (inst.reloc.exp.X_add_symbol);
4457 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4460 /* This sets THUMB_H2 from the top bit of reg. */
4461 inst.instruction |= reg << 3;
4463 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4464 should cause the alignment to be checked once it is known. This is
4465 because BX PC only works if the instruction is word aligned. */
4474 thumb_mov_compare (str, THUMB_COMPARE);
4487 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4491 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4495 if (skip_past_comma (&str) == FAIL
4496 || (range = reg_list (&str)) == FAIL)
4499 inst.error = bad_args;
4503 if (inst.reloc.type != BFD_RELOC_NONE)
4505 /* This really doesn't seem worth it. */
4506 inst.reloc.type = BFD_RELOC_NONE;
4507 inst.error = _("Expression too complex");
4513 inst.error = _("only lo-regs valid in load/store multiple");
4517 inst.instruction |= (Rb << 8) | range;
4525 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4532 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4539 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4551 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4552 || skip_past_comma (&str) == FAIL
4554 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4555 || skip_past_comma (&str) == FAIL
4556 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4560 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4564 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4572 thumb_shift (str, THUMB_LSL);
4579 thumb_shift (str, THUMB_LSR);
4586 thumb_mov_compare (str, THUMB_MOVE);
4598 if ((range = reg_list (&str)) == FAIL)
4601 inst.error = bad_args;
4605 if (inst.reloc.type != BFD_RELOC_NONE)
4607 /* This really doesn't seem worth it. */
4608 inst.reloc.type = BFD_RELOC_NONE;
4609 inst.error = _("Expression too complex");
4615 if ((inst.instruction == T_OPCODE_PUSH
4616 && (range & ~0xff) == 1 << REG_LR)
4617 || (inst.instruction == T_OPCODE_POP
4618 && (range & ~0xff) == 1 << REG_PC))
4620 inst.instruction |= THUMB_PP_PC_LR;
4625 inst.error = _("invalid register list to push/pop instruction");
4630 inst.instruction |= range;
4638 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4645 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4652 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4659 thumb_add_sub (str, 1);
4669 if (my_get_expression (&inst.reloc.exp, &str))
4672 inst.reloc.type = BFD_RELOC_ARM_SWI;
4681 /* This is a pseudo-op of the form "adr rd, label" to be converted
4682 into a relative address of the form "add rd, pc, #label-.-4" */
4686 if (reg_required_here (&str, 4) == FAIL /* Store Rd in temporary location inside instruction. */
4687 || skip_past_comma (&str) == FAIL
4688 || my_get_expression (&inst.reloc.exp, &str))
4691 inst.error = bad_args;
4695 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4696 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
4697 inst.reloc.pc_rel = 1;
4698 inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
4706 int len = strlen (reg_table[entry].name) + 2;
4707 char *buf = (char *) xmalloc (len);
4708 char *buf2 = (char *) xmalloc (len);
4711 #ifdef REGISTER_PREFIX
4712 buf[i++] = REGISTER_PREFIX;
4715 strcpy (buf + i, reg_table[entry].name);
4717 for (i = 0; buf[i]; i++)
4718 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
4722 hash_insert (arm_reg_hsh, buf, (PTR) ®_table[entry]);
4723 hash_insert (arm_reg_hsh, buf2, (PTR) ®_table[entry]);
4727 insert_reg_alias (str, regnum)
4731 struct reg_entry *new =
4732 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
4733 char *name = xmalloc (strlen (str) + 1);
4737 new->number = regnum;
4739 hash_insert (arm_reg_hsh, name, (PTR) new);
4743 set_constant_flonums ()
4747 for (i = 0; i < NUM_FLOAT_VALS; i++)
4748 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
4757 if ((arm_ops_hsh = hash_new ()) == NULL
4758 || (arm_tops_hsh = hash_new ()) == NULL
4759 || (arm_cond_hsh = hash_new ()) == NULL
4760 || (arm_shift_hsh = hash_new ()) == NULL
4761 || (arm_reg_hsh = hash_new ()) == NULL
4762 || (arm_psr_hsh = hash_new ()) == NULL)
4763 as_fatal (_("Virtual memory exhausted"));
4765 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
4766 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
4767 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
4768 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
4769 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
4770 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
4771 for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
4772 hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
4773 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
4774 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
4776 for (i = 0; reg_table[i].name; i++)
4779 set_constant_flonums ();
4783 unsigned int flags = 0;
4785 /* Set the flags in the private structure */
4786 if (uses_apcs_26) flags |= F_APCS26;
4787 if (support_interwork) flags |= F_INTERWORK;
4788 if (uses_apcs_float) flags |= F_APCS_FLOAT;
4789 if (pic_code) flags |= F_PIC;
4791 bfd_set_private_flags (stdoutput, flags);
4798 /* Record the CPU type as well */
4799 switch (cpu_variant & ARM_CPU_MASK)
4802 mach = bfd_mach_arm_2;
4805 case ARM_3: /* also ARM_250 */
4806 mach = bfd_mach_arm_2a;
4810 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined */
4811 mach = bfd_mach_arm_4;
4814 case ARM_7: /* also ARM_6 */
4815 mach = bfd_mach_arm_3;
4819 /* Catch special cases */
4820 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
4822 if (cpu_variant & ARM_THUMB)
4823 mach = bfd_mach_arm_4T;
4824 else if ((cpu_variant & ARM_ARCHv4) == ARM_ARCHv4)
4825 mach = bfd_mach_arm_4;
4826 else if (cpu_variant & ARM_LONGMUL)
4827 mach = bfd_mach_arm_3M;
4830 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
4834 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4835 for use in the a.out file, and stores them in the array pointed to by buf.
4836 This knows about the endian-ness of the target machine and does
4837 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4838 2 (short) and 4 (long) Floating numbers are put out as a series of
4839 LITTLENUMS (shorts, here at least)
4842 md_number_to_chars (buf, val, n)
4847 if (target_big_endian)
4848 number_to_chars_bigendian (buf, val, n);
4850 number_to_chars_littleendian (buf, val, n);
4854 md_chars_to_number (buf, n)
4859 unsigned char *where = (unsigned char *) buf;
4861 if (target_big_endian)
4866 result |= (*where++ & 255);
4874 result |= (where[n] & 255);
4881 /* Turn a string in input_line_pointer into a floating point constant
4882 of type TYPE, and store the appropriate bytes in *litP. The number
4883 of LITTLENUMS emitted is stored in *sizeP . An error message is
4884 returned, or NULL on OK.
4886 Note that fp constants aren't represent in the normal way on the ARM.
4887 In big endian mode, things are as expected. However, in little endian
4888 mode fp constants are big-endian word-wise, and little-endian byte-wise
4889 within the words. For example, (double) 1.1 in big endian mode is
4890 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4891 the byte sequence 99 99 f1 3f 9a 99 99 99.
4893 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
4896 md_atof (type, litP, sizeP)
4902 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4934 return _("Bad call to MD_ATOF()");
4937 t = atof_ieee (input_line_pointer, type, words);
4939 input_line_pointer = t;
4942 if (target_big_endian)
4944 for (i = 0; i < prec; i++)
4946 md_number_to_chars (litP, (valueT) words[i], 2);
4952 /* For a 4 byte float the order of elements in `words' is 1 0. For an
4953 8 byte float the order is 1 0 3 2. */
4954 for (i = 0; i < prec; i += 2)
4956 md_number_to_chars (litP, (valueT) words[i + 1], 2);
4957 md_number_to_chars (litP + 2, (valueT) words[i], 2);
4965 /* We have already put the pipeline compensation in the instruction */
4968 md_pcrel_from (fixP)
4972 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
4973 && fixP->fx_subsy == NULL)
4974 return 0; /* HACK */
4976 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
4978 /* PC relative addressing on the Thumb is slightly odd
4979 as the bottom two bits of the PC are forced to zero
4980 for the calculation */
4981 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
4984 return fixP->fx_where + fixP->fx_frag->fr_address;
4987 /* Round up a section size to the appropriate boundary. */
4989 md_section_align (segment, size)
4993 /* Round all sects to multiple of 4 */
4994 return (size + 3) & ~3;
4997 /* We have no need to default values of symbols. */
5001 md_undefined_symbol (name)
5007 /* arm_reg_parse () := if it looks like a register, return its token and
5008 advance the pointer. */
5012 register char **ccp;
5017 struct reg_entry *reg;
5019 #ifdef REGISTER_PREFIX
5020 if (*start != REGISTER_PREFIX)
5025 #ifdef OPTIONAL_REGISTER_PREFIX
5026 if (*p == OPTIONAL_REGISTER_PREFIX)
5030 if (!isalpha (*p) || !is_name_beginner (*p))
5034 while (isalpha (c) || isdigit (c) || c == '_')
5038 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
5052 register char **ccp;
5056 CONST struct asm_psr *psr;
5060 while (isalpha (c) || c == '_')
5064 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
5077 md_apply_fix3 (fixP, val, seg)
5082 offsetT value = *val;
5084 unsigned int newimm;
5087 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5088 arm_fix_data *arm_data = (arm_fix_data *) fixP->tc_fix_data;
5090 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5092 /* Note whether this will delete the relocation. */
5093 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5094 if ((fixP->fx_addsy == 0 || fixP->fx_addsy->sy_value.X_op == O_constant)
5097 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5101 /* If this symbol is in a different section then we need to leave it for
5102 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5103 so we have to undo it's effects here. */
5106 if (fixP->fx_addsy != NULL
5107 && S_IS_DEFINED (fixP->fx_addsy)
5108 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5110 if (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
5113 value += md_pcrel_from (fixP);
5117 fixP->fx_addnumber = value; /* Remember value for emit_reloc */
5119 switch (fixP->fx_r_type)
5121 case BFD_RELOC_ARM_IMMEDIATE:
5122 newimm = validate_immediate (value);
5123 temp = md_chars_to_number (buf, INSN_SIZE);
5125 /* If the instruction will fail, see if we can fix things up by
5126 changing the opcode. */
5127 if (newimm == (unsigned int) FAIL
5128 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5130 as_bad_where (fixP->fx_file, fixP->fx_line,
5131 _("invalid constant after fixup\n"));
5135 newimm |= (temp & 0xfffff000);
5136 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5139 case BFD_RELOC_ARM_OFFSET_IMM:
5141 if ((value = validate_offset_imm (value, 0)) == FAIL)
5143 as_bad (_("bad immediate value for offset (%d)"), val);
5149 newval = md_chars_to_number (buf, INSN_SIZE);
5150 newval &= 0xff7ff000;
5151 newval |= value | (sign ? INDEX_UP : 0);
5152 md_number_to_chars (buf, newval, INSN_SIZE);
5155 case BFD_RELOC_ARM_OFFSET_IMM8:
5156 case BFD_RELOC_ARM_HWLITERAL:
5158 if ((value = validate_offset_imm (value, 1)) == FAIL)
5160 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5161 as_bad_where (fixP->fx_file, fixP->fx_line,
5162 _("invalid literal constant: pool needs to be closer\n"));
5164 as_bad (_("bad immediate value for offset (%d)"), value);
5171 newval = md_chars_to_number (buf, INSN_SIZE);
5172 newval &= 0xff7ff0f0;
5173 newval |= ((value >> 4) << 8) | value & 0xf | (sign ? INDEX_UP : 0);
5174 md_number_to_chars (buf, newval, INSN_SIZE);
5177 case BFD_RELOC_ARM_LITERAL:
5182 if ((value = validate_offset_imm (value, 0)) == FAIL)
5184 as_bad_where (fixP->fx_file, fixP->fx_line,
5185 _("invalid literal constant: pool needs to be closer\n"));
5189 newval = md_chars_to_number (buf, INSN_SIZE);
5190 newval &= 0xff7ff000;
5191 newval |= value | (sign ? INDEX_UP : 0);
5192 md_number_to_chars (buf, newval, INSN_SIZE);
5195 case BFD_RELOC_ARM_SHIFT_IMM:
5196 newval = md_chars_to_number (buf, INSN_SIZE);
5197 if (((unsigned long) value) > 32
5199 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5201 as_bad_where (fixP->fx_file, fixP->fx_line,
5202 _("shift expression is too large"));
5207 newval &= ~0x60; /* Shifts of zero must be done as lsl */
5208 else if (value == 32)
5210 newval &= 0xfffff07f;
5211 newval |= (value & 0x1f) << 7;
5212 md_number_to_chars (buf, newval , INSN_SIZE);
5215 case BFD_RELOC_ARM_SWI:
5216 if (arm_data->thumb_mode)
5218 if (((unsigned long) value) > 0xff)
5219 as_bad_where (fixP->fx_file, fixP->fx_line,
5220 _("Invalid swi expression"));
5221 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5223 md_number_to_chars (buf, newval, THUMB_SIZE);
5227 if (((unsigned long) value) > 0x00ffffff)
5228 as_bad_where (fixP->fx_file, fixP->fx_line,
5229 _("Invalid swi expression"));
5230 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5232 md_number_to_chars (buf, newval , INSN_SIZE);
5236 case BFD_RELOC_ARM_MULTI:
5237 if (((unsigned long) value) > 0xffff)
5238 as_bad_where (fixP->fx_file, fixP->fx_line,
5239 _("Invalid expression in load/store multiple"));
5240 newval = value | md_chars_to_number (buf, INSN_SIZE);
5241 md_number_to_chars (buf, newval, INSN_SIZE);
5244 case BFD_RELOC_ARM_PCREL_BRANCH:
5245 value = (value >> 2) & 0x00ffffff;
5246 newval = md_chars_to_number (buf, INSN_SIZE);
5247 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5248 newval = value | (newval & 0xff000000);
5249 md_number_to_chars (buf, newval, INSN_SIZE);
5252 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5253 newval = md_chars_to_number (buf, THUMB_SIZE);
5255 addressT diff = (newval & 0xff) << 1;
5260 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5261 as_bad_where (fixP->fx_file, fixP->fx_line,
5262 _("Branch out of range"));
5263 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5265 md_number_to_chars (buf, newval, THUMB_SIZE);
5268 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5269 newval = md_chars_to_number (buf, THUMB_SIZE);
5271 addressT diff = (newval & 0x7ff) << 1;
5276 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5277 as_bad_where (fixP->fx_file, fixP->fx_line,
5278 _("Branch out of range"));
5279 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5281 md_number_to_chars (buf, newval, THUMB_SIZE);
5284 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5289 newval = md_chars_to_number (buf, THUMB_SIZE);
5290 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5291 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5292 if (diff & 0x400000)
5295 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5296 as_bad_where (fixP->fx_file, fixP->fx_line,
5297 _("Branch with link out of range"));
5299 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5300 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5301 md_number_to_chars (buf, newval, THUMB_SIZE);
5302 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5307 if (fixP->fx_done || fixP->fx_pcrel)
5308 md_number_to_chars (buf, value, 1);
5312 if (fixP->fx_done || fixP->fx_pcrel)
5313 md_number_to_chars (buf, value, 2);
5318 if (fixP->fx_done || fixP->fx_pcrel)
5319 md_number_to_chars (buf, value, 4);
5322 case BFD_RELOC_ARM_CP_OFF_IMM:
5324 if (value < -1023 || value > 1023 || (value & 3))
5325 as_bad_where (fixP->fx_file, fixP->fx_line,
5326 _("Illegal value for co-processor offset"));
5329 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5330 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5331 md_number_to_chars (buf, newval , INSN_SIZE);
5334 case BFD_RELOC_ARM_THUMB_OFFSET:
5335 newval = md_chars_to_number (buf, THUMB_SIZE);
5336 /* Exactly what ranges, and where the offset is inserted depends on
5337 the type of instruction, we can establish this from the top 4 bits */
5338 switch (newval >> 12)
5340 case 4: /* PC load */
5341 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5342 forced to zero for these loads, so we will need to round
5343 up the offset if the instruction address is not word
5344 aligned (since the final address produced must be, and
5345 we can only describe word-aligned immediate offsets). */
5347 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5348 as_bad_where (fixP->fx_file, fixP->fx_line,
5349 _("Invalid offset, target not word aligned (0x%08X)"),
5350 (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5352 if ((value + 2) & ~0x3fe)
5353 as_bad_where (fixP->fx_file, fixP->fx_line,
5354 _("Invalid offset"));
5356 /* Round up, since pc will be rounded down. */
5357 newval |= (value + 2) >> 2;
5360 case 9: /* SP load/store */
5362 as_bad_where (fixP->fx_file, fixP->fx_line,
5363 _("Invalid offset"));
5364 newval |= value >> 2;
5367 case 6: /* Word load/store */
5369 as_bad_where (fixP->fx_file, fixP->fx_line,
5370 _("Invalid offset"));
5371 newval |= value << 4; /* 6 - 2 */
5374 case 7: /* Byte load/store */
5376 as_bad_where (fixP->fx_file, fixP->fx_line,
5377 _("Invalid offset"));
5378 newval |= value << 6;
5381 case 8: /* Halfword load/store */
5383 as_bad_where (fixP->fx_file, fixP->fx_line,
5384 _("Invalid offset"));
5385 newval |= value << 5; /* 6 - 1 */
5389 as_bad_where (fixP->fx_file, fixP->fx_line,
5390 "Unable to process relocation for thumb opcode: %x", newval);
5393 md_number_to_chars (buf, newval, THUMB_SIZE);
5396 case BFD_RELOC_ARM_THUMB_ADD:
5397 /* This is a complicated relocation, since we use it for all of
5398 the following immediate relocations:
5401 9bit ADD/SUB SP word-aligned
5402 10bit ADD PC/SP word-aligned
5404 The type of instruction being processed is encoded in the
5410 newval = md_chars_to_number (buf, THUMB_SIZE);
5412 int rd = (newval >> 4) & 0xf;
5413 int rs = newval & 0xf;
5414 int subtract = newval & 0x8000;
5419 as_bad_where (fixP->fx_file, fixP->fx_line,
5420 _("Invalid immediate for stack address calculation"));
5421 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5422 newval |= value >> 2;
5424 else if (rs == REG_PC || rs == REG_SP)
5428 as_bad_where (fixP->fx_file, fixP->fx_line,
5429 _("Invalid immediate for address calculation (value = 0x%08X)"), value);
5430 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5432 newval |= value >> 2;
5437 as_bad_where (fixP->fx_file, fixP->fx_line,
5438 _("Invalid 8bit immediate"));
5439 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5440 newval |= (rd << 8) | value;
5445 as_bad_where (fixP->fx_file, fixP->fx_line,
5446 _("Invalid 3bit immediate"));
5447 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5448 newval |= rd | (rs << 3) | (value << 6);
5451 md_number_to_chars (buf, newval , THUMB_SIZE);
5454 case BFD_RELOC_ARM_THUMB_IMM:
5455 newval = md_chars_to_number (buf, THUMB_SIZE);
5456 switch (newval >> 11)
5458 case 0x04: /* 8bit immediate MOV */
5459 case 0x05: /* 8bit immediate CMP */
5460 if (value < 0 || value > 255)
5461 as_bad_where (fixP->fx_file, fixP->fx_line,
5462 _("Invalid immediate: %d is too large"), value);
5469 md_number_to_chars (buf, newval , THUMB_SIZE);
5472 case BFD_RELOC_ARM_THUMB_SHIFT:
5473 /* 5bit shift value (0..31) */
5474 if (value < 0 || value > 31)
5475 as_bad_where (fixP->fx_file, fixP->fx_line,
5476 _("Illegal Thumb shift value: %d"), value);
5477 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5478 newval |= value << 6;
5479 md_number_to_chars (buf, newval , THUMB_SIZE);
5482 case BFD_RELOC_NONE:
5484 as_bad_where (fixP->fx_file, fixP->fx_line,
5485 _("Bad relocation fixup type (%d)\n"), fixP->fx_r_type);
5491 /* Translate internal representation of relocation info to BFD target
5494 tc_gen_reloc (section, fixp)
5499 bfd_reloc_code_real_type code;
5501 reloc = (arelent *) xmalloc (sizeof (arelent));
5503 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
5504 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5506 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5507 if (fixp->fx_pcrel == 0)
5508 reloc->addend = fixp->fx_offset;
5510 reloc->addend = fixp->fx_offset = reloc->address;
5512 switch (fixp->fx_r_type)
5517 code = BFD_RELOC_8_PCREL;
5524 code = BFD_RELOC_16_PCREL;
5531 code = BFD_RELOC_32_PCREL;
5535 case BFD_RELOC_ARM_PCREL_BRANCH:
5537 case BFD_RELOC_THUMB_PCREL_BRANCH9:
5538 case BFD_RELOC_THUMB_PCREL_BRANCH12:
5539 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5540 code = fixp->fx_r_type;
5543 case BFD_RELOC_ARM_LITERAL:
5544 case BFD_RELOC_ARM_HWLITERAL:
5545 /* If this is called then the a literal has been referenced across
5546 a section boundry - possibly due to an implicit dump */
5547 as_bad_where (fixp->fx_file, fixp->fx_line,
5548 _("Literal referenced across section boundry (Implicit dump?)"));
5551 case BFD_RELOC_ARM_IMMEDIATE:
5552 as_bad_where (fixp->fx_file, fixp->fx_line,
5553 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5557 case BFD_RELOC_ARM_OFFSET_IMM:
5558 as_bad_where (fixp->fx_file, fixp->fx_line,
5559 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5566 switch (fixp->fx_r_type)
5568 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
5569 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
5570 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
5571 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
5572 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
5573 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
5574 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
5575 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
5576 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
5577 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
5578 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
5579 default: type = "<unknown>"; break;
5581 as_bad_where (fixp->fx_file, fixp->fx_line,
5582 _("Can not represent %s relocation in this object file format (%d)"),
5583 type, fixp->fx_pcrel);
5588 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5590 if (reloc->howto == NULL)
5592 as_bad_where (fixp->fx_file, fixp->fx_line,
5593 _("Can not represent %s relocation in this object file format"),
5594 bfd_get_reloc_code_name (code));
5601 CONST int md_short_jump_size = 4;
5602 CONST int md_long_jump_size = 4;
5604 /* These should never be called on the arm */
5606 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
5608 addressT from_addr, to_addr;
5612 as_fatal (_("md_create_long_jump\n"));
5616 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
5618 addressT from_addr, to_addr;
5622 as_fatal (_("md_create_short_jump\n"));
5626 md_estimate_size_before_relax (fragP, segtype)
5630 as_fatal (_("md_estimate_size_before_relax\n"));
5642 as_bad (inst.error);
5646 to = frag_more (inst.size);
5647 if (thumb_mode && (inst.size > THUMB_SIZE))
5649 assert (inst.size == (2 * THUMB_SIZE));
5650 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
5651 md_number_to_chars (to + 2, inst.instruction, THUMB_SIZE);
5654 md_number_to_chars (to, inst.instruction, inst.size);
5656 if (inst.reloc.type != BFD_RELOC_NONE)
5657 fix_new_arm (frag_now, to - frag_now->fr_literal,
5658 inst.size, &inst.reloc.exp, inst.reloc.pc_rel,
5669 char *p, *q, *start;
5671 /* Align the instruction */
5672 /* this may not be the right thing to do but ... */
5673 /* arm_align (2, 0); */
5674 listing_prev_line (); /* Defined in listing.h */
5676 /* Align the previous label if needed */
5677 if (last_label_seen != NULL)
5679 last_label_seen->sy_frag = frag_now;
5680 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
5681 S_SET_SEGMENT (last_label_seen, now_seg);
5684 memset (&inst, '\0', sizeof (inst));
5685 inst.reloc.type = BFD_RELOC_NONE;
5688 str++; /* Skip leading white space */
5690 /* scan up to the end of the op-code, which must end in white space or
5692 for (start = p = str; *p != '\0'; p++)
5698 as_bad (_("No operator -- statement `%s'\n"), str);
5704 CONST struct thumb_opcode *opcode;
5708 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
5712 inst.instruction = opcode->value;
5713 inst.size = opcode->size;
5714 (*opcode->parms)(p);
5715 output_inst (start);
5721 CONST struct asm_opcode *opcode;
5723 inst.size = INSN_SIZE;
5724 /* p now points to the end of the opcode, probably white space, but we
5725 have to break the opcode up in case it contains condionals and flags;
5726 keep trying with progressively smaller basic instructions until one
5727 matches, or we run out of opcode. */
5728 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
5729 for (; q != str; q--)
5733 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
5735 if (opcode && opcode->template)
5737 unsigned long flag_bits = 0;
5740 /* Check that this instruction is supported for this CPU */
5741 if ((opcode->variants & cpu_variant) == 0)
5744 inst.instruction = opcode->value;
5745 if (q == p) /* Just a simple opcode */
5747 if (opcode->comp_suffix != 0)
5748 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
5749 opcode->comp_suffix);
5752 inst.instruction |= COND_ALWAYS;
5753 (*opcode->parms)(q, 0);
5755 output_inst (start);
5759 /* Now check for a conditional */
5763 CONST struct asm_cond *cond;
5767 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
5771 if (cond->value == 0xf0000000)
5773 _("Warning: Use of the 'nv' conditional is deprecated\n"));
5775 inst.instruction |= cond->value;
5779 inst.instruction |= COND_ALWAYS;
5782 inst.instruction |= COND_ALWAYS;
5784 /* if there is a compulsory suffix, it should come here, before
5785 any optional flags. */
5786 if (opcode->comp_suffix)
5788 CONST char *s = opcode->comp_suffix;
5800 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
5801 opcode->comp_suffix);
5808 /* The remainder, if any should now be flags for the instruction;
5809 Scan these checking each one found with the opcode. */
5813 CONST struct asm_flg *flag = opcode->flags;
5822 for (flagno = 0; flag[flagno].template; flagno++)
5824 if (! strcmp (r, flag[flagno].template))
5826 flag_bits |= flag[flagno].set_bits;
5832 if (! flag[flagno].template)
5839 (*opcode->parms) (p, flag_bits);
5840 output_inst (start);
5849 /* It wasn't an instruction, but it might be a register alias of the form
5859 if (*q && !strncmp (q, ".req ", 4))
5862 char * copy_of_str = str;
5869 for (r = q; *r != '\0'; r++)
5879 regnum = arm_reg_parse (& q);
5882 reg = arm_reg_parse (& str);
5888 insert_reg_alias (str, regnum);
5892 as_warn (_("register '%s' does not exist\n"), q);
5895 else if (regnum != FAIL)
5898 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str );
5900 /* Do not warn abpout redefinitions to the same alias. */
5903 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
5907 as_warn (_("ignoring incomplete .req pseuso op"));
5914 as_bad (_("bad instruction `%s'"), start);
5919 * Invocation line includes a switch not recognized by the base assembler.
5920 * See if it's a processor-specific option. These are:
5921 * Cpu variants, the arm part is optional:
5922 * -m[arm]1 Currently not supported.
5923 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
5924 * -m[arm]3 Arm 3 processor
5925 * -m[arm]6, Arm 6 processors
5926 * -m[arm]7[t][[d]m] Arm 7 processors
5927 * -mall All (except the ARM1)
5929 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
5930 * -mfpe-old (No float load/store multiples)
5931 * -mno-fpu Disable all floating point instructions
5932 * Run-time endian selection:
5933 * -EB big endian cpu
5934 * -EL little endian cpu
5935 * ARM Procedure Calling Standard:
5936 * -mapcs-32 32 bit APCS
5937 * -mapcs-26 26 bit APCS
5938 * -mapcs-float Pass floats in float regs
5939 * -mapcs-reentrant Position independent code
5940 * -mthumb-interwork Code supports Arm/Thumb interworking
5943 CONST char *md_shortopts = "m:";
5944 struct option md_longopts[] =
5946 #ifdef ARM_BI_ENDIAN
5947 #define OPTION_EB (OPTION_MD_BASE + 0)
5948 {"EB", no_argument, NULL, OPTION_EB},
5949 #define OPTION_EL (OPTION_MD_BASE + 1)
5950 {"EL", no_argument, NULL, OPTION_EL},
5952 {NULL, no_argument, NULL, 0}
5954 size_t md_longopts_size = sizeof (md_longopts);
5957 md_parse_option (c, arg)
5965 #ifdef ARM_BI_ENDIAN
5967 target_big_endian = 1;
5970 target_big_endian = 0;
5978 if (! strcmp (str, "fpa10"))
5979 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
5980 else if (! strcmp (str, "fpa11"))
5981 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
5982 else if (! strcmp (str, "fpe-old"))
5983 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
5989 if (! strcmp (str, "no-fpu"))
5990 cpu_variant &= ~FPU_ALL;
5994 /* Limit assembler to generating only Thumb instructions: */
5995 if (! strcmp (str, "thumb"))
5997 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
5998 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6001 else if (! strcmp (str, "thumb-interwork"))
6003 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCHv4;
6005 support_interwork = true;
6013 if (! strcmp (str, "all"))
6015 cpu_variant = ARM_ALL | FPU_ALL;
6019 if (! strncmp (str, "apcs-", 5))
6021 /* GCC passes on all command line options starting "-mapcs-..."
6022 to us, so we must parse them here. */
6026 if (! strcmp (str, "32"))
6028 uses_apcs_26 = false;
6031 else if (! strcmp (str, "26"))
6033 uses_apcs_26 = true;
6036 else if (! strcmp (str, "frame"))
6038 /* Stack frames are being generated - does not affect
6042 else if (! strcmp (str, "stack-check"))
6044 /* Stack checking is being performed - does not affect
6045 linkage, but does require that the functions
6046 __rt_stkovf_split_small and __rt_stkovf_split_big be
6047 present in the final link. */
6051 else if (! strcmp (str, "float"))
6053 /* Floating point arguments are being passed in the floating
6054 point registers. This does affect linking, since this
6055 version of the APCS is incompatible with the version that
6056 passes floating points in the integer registers. */
6058 uses_apcs_float = true;
6061 else if (! strcmp (str, "reentrant"))
6063 /* Reentrant code has been generated. This does affect
6064 linking, since there is no point in linking reentrant/
6065 position independent code with absolute position code. */
6070 as_bad (_("Unrecognised APCS switch -m%s"), arg);
6074 /* Strip off optional "arm" */
6075 if (! strncmp (str, "arm", 3))
6081 if (! strcmp (str, "1"))
6082 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6088 if (! strcmp (str, "2"))
6089 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6090 else if (! strcmp (str, "250"))
6091 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6097 if (! strcmp (str, "3"))
6098 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6104 if (! strcmp (str, "strongarm") || ! strcmp (str, "strongarm110"))
6105 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCHv4 | ARM_LONGMUL;
6111 if (! strcmp (str, "8"))
6112 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCHv4 | ARM_LONGMUL;
6118 if (! strcmp (str, "6"))
6119 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6125 str++; /* eat the '7' */
6126 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6132 cpu_variant |= (ARM_THUMB | ARM_ARCHv4);
6136 cpu_variant |= ARM_LONGMUL;
6139 case 'f': /* fe => fp enabled cpu. */
6145 case 'c': /* Unknown */
6146 case 'd': /* debug */
6147 case 'i': /* embedded ice */
6148 /* Included for completeness in ARM processor naming. */
6158 /* Select variant based on architecture rather than processor */
6164 case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
6165 case 0: cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
6166 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6171 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6175 case 'm': cpu_variant |= ARM_LONGMUL; break;
6177 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6182 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCHv4;
6186 case 't': cpu_variant |= ARM_THUMB; break;
6188 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6193 as_bad (_("Invalid architecture variant -m%s"), arg);
6200 as_bad (_("Invalid processor variant -m%s"), arg);
6218 _("-m[arm][<processor name>] select processor variant\n\
6219 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
6220 -mthumb\t\t\tonly allow Thumb instructions\n\
6221 -mthumb-interwork\tmark the assembled code as supporting interworking\n\
6222 -mall\t\t\tallow any instruction\n\
6223 -mfpa10, -mfpa11\tselect floating point architecture\n\
6224 -mfpe-old\t\tdon't allow floating-point multiple instructions\n\
6225 -mno-fpu\t\tdon't allow any floating-point instructions.\n"));
6228 _("-mapcs-32, -mapcs-26\tspecify which ARM Procedure Calling Standard is in use\n"));
6230 _("-mapcs-float\t\tfloating point args are passed in floating point regs\n"));
6232 _("-mapcs-reentrant\tposition independent/reentrant code has been generated\n"));
6234 #ifdef ARM_BI_ENDIAN
6236 _("-EB\t\t\tassemble code for a big endian cpu\n\
6237 -EL\t\t\tassemble code for a little endian cpu\n"));
6241 /* We need to be able to fix up arbitrary expressions in some statements.
6242 This is so that we can handle symbols that are an arbitrary distance from
6243 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6244 which returns part of an address in a form which will be valid for
6245 a data instruction. We do this by pushing the expression into a symbol
6246 in the expr_section, and creating a fix for that. */
6249 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6258 arm_fix_data *arm_data;
6266 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6270 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6275 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6276 arm_data = (arm_fix_data *) obstack_alloc (¬es, sizeof (arm_fix_data));
6277 new_fix->tc_fix_data = (PTR) arm_data;
6278 arm_data->thumb_mode = thumb_mode;
6283 /* A good place to do this, although this was probably not intended
6284 * for this kind of use. We need to dump the literal pool before
6285 * references are made to a null symbol pointer. */
6289 if (current_poolP != NULL)
6291 subseg_set (text_section, 0); /* Put it at the end of text section */
6293 listing_prev_line ();
6298 arm_start_line_hook ()
6300 last_label_seen = NULL;
6304 arm_frob_label (sym)
6307 last_label_seen = sym;
6308 ARM_SET_THUMB (sym, thumb_mode);
6310 ARM_SET_INTERWORK (sym, support_interwork);
6313 if (label_is_thumb_function_name)
6315 /* When the address of a Thumb function is taken the bottom
6316 bit of that address should be set. This will allow
6317 interworking between Arm and Thumb functions to work
6320 THUMB_SET_FUNC (sym, 1);
6322 label_is_thumb_function_name = false;
6326 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6330 arm_adjust_symtab ()
6335 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6337 if (ARM_IS_THUMB (sym))
6339 if (THUMB_IS_FUNC (sym))
6341 /* Mark the symbol as a Thumb function. */
6342 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
6343 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6344 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6345 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6346 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6348 as_bad (_("%s: unexpected function type: %d"), S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6350 else switch (S_GET_STORAGE_CLASS (sym))
6353 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6356 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6359 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6361 default: /* do nothing */
6366 if (ARM_IS_INTERWORK (sym))
6368 coffsymbol(sym->bsym)->native->u.syment.n_flags = 0xFF;
6377 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
6379 *input_line_pointer = '/';
6380 input_line_pointer += 5;
6381 *input_line_pointer = 0;
6388 arm_canonicalize_symbol_name (name)
6393 if (thumb_mode && (len = strlen (name)) > 5
6394 && ! strcmp (name + len - 5, "/data"))
6396 *(name + len - 5) = 0;
6403 arm_validate_fix (fixP)
6406 /* If the destination of the branch is a defined symbol which does not have
6407 the THUMB_FUNC attribute, then we must be calling a function which has
6408 the (interfacearm) attribute. We look for the Thumb entry point to that
6409 function and change the branch to refer to that function instead. */
6410 if ( fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
6411 && fixP->fx_addsy != NULL
6412 && S_IS_DEFINED (fixP->fx_addsy)
6413 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6415 fixP->fx_addsy = find_real_start (fixP->fx_addsy);