1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 1997 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_ARCH4 0x00000020
55 #define ARM_THUMB ARM_ARCH4
57 /* Some useful combinations: */
58 #define ARM_ANY 0x00ffffff
59 #define ARM_2UP 0x00fffffe
60 #define ARM_ALL ARM_2UP /* Not arm1 only */
61 #define ARM_3UP 0x00fffffc
62 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
64 #define FPU_CORE 0x80000000
65 #define FPU_FPA10 0x40000000
66 #define FPU_FPA11 0x40000000
69 /* Some useful combinations */
70 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
71 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
74 #define CPU_DEFAULT ARM_ALL
78 #define FPU_DEFAULT FPU_ALL
81 static unsigned long cpu_variant
= CPU_DEFAULT
| FPU_DEFAULT
;
83 /* Flags stored in private area of BFD COFF structure */
84 static boolean uses_apcs_26
= false;
86 /* This array holds the chars that always start a comment. If the
87 pre-processor is disabled, these aren't very useful */
88 CONST
char comment_chars
[] = "@";
90 /* This array holds the chars that only start a comment at the beginning of
91 a line. If the line seems to have the form '# 123 filename'
92 .line and .file directives will appear in the pre-processed output */
93 /* Note that input_file.c hand checks for '#' at the beginning of the
94 first line of the input file. This is because the compiler outputs
95 #NO_APP at the beginning of its output. */
96 /* Also note that comments like this one will always work. */
97 CONST
char line_comment_chars
[] = "#";
99 CONST
char line_separator_chars
[] = "";
101 /* Chars that can be used to separate mant from exp in floating point nums */
102 CONST
char EXP_CHARS
[] = "eE";
104 /* Chars that mean this number is a floating point constant */
108 CONST
char FLT_CHARS
[] = "rRsSfFdDxXeEpP";
110 CONST
int md_reloc_size
= 8; /* Size of relocation record */
112 static int thumb_mode
= 0; /* non-zero if assembling thumb instructions */
114 typedef struct arm_fix
122 unsigned long instruction
;
127 bfd_reloc_code_real_type type
;
137 CONST
char *template;
141 static CONST
struct asm_shift shift
[] =
157 #define NO_SHIFT_RESTRICT 1
158 #define SHIFT_RESTRICT 0
160 #define NUM_FLOAT_VALS 8
162 CONST
char *fp_const
[] =
164 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
167 /* Number of littlenums required to hold an extended precision number */
168 #define MAX_LITTLENUMS 6
170 LITTLENUM_TYPE fp_values
[NUM_FLOAT_VALS
][MAX_LITTLENUMS
];
180 #define CP_T_X 0x00008000
181 #define CP_T_Y 0x00400000
182 #define CP_T_Pre 0x01000000
183 #define CP_T_UD 0x00800000
184 #define CP_T_WB 0x00200000
186 #define CONDS_BIT (0x00100000)
187 #define LOAD_BIT (0x00100000)
188 #define TRANS_BIT (0x00200000)
192 CONST
char *template;
196 /* This is to save a hash look-up in the common case */
197 #define COND_ALWAYS 0xe0000000
199 static CONST
struct asm_cond conds
[] =
203 {"cs", 0x20000000}, {"hs", 0x20000000},
204 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
219 /* Warning: If the top bit of the set_bits is set, then the standard
220 instruction bitmask is ignored, and the new bitmask is taken from
224 CONST
char *template; /* Basic flag string */
225 unsigned long set_bits
; /* Bits to set */
228 static CONST
struct asm_flg s_flag
[] =
234 static CONST
struct asm_flg ldr_flags
[] =
238 {"bt", 0x00400000 | TRANS_BIT
},
245 static CONST
struct asm_flg str_flags
[] =
249 {"bt", 0x00400000 | TRANS_BIT
},
254 static CONST
struct asm_flg byte_flag
[] =
260 static CONST
struct asm_flg cmp_flags
[] =
267 static CONST
struct asm_flg ldm_flags
[] =
280 static CONST
struct asm_flg stm_flags
[] =
293 static CONST
struct asm_flg lfm_flags
[] =
300 static CONST
struct asm_flg sfm_flags
[] =
307 static CONST
struct asm_flg round_flags
[] =
315 /* The implementation of the FIX instruction is broken on some assemblers,
316 in that it accepts a precision specifier as well as a rounding specifier,
317 despite the fact that this is meaningless. To be more compatible, we
318 accept it as well, though of course it does not set any bits. */
319 static CONST
struct asm_flg fix_flags
[] =
336 static CONST
struct asm_flg except_flag
[] =
342 static CONST
struct asm_flg cplong_flag
[] =
350 CONST
char *template;
351 unsigned long number
;
354 #define PSR_ALL 0x00010000
356 static CONST
struct asm_psr psrs
[] =
369 /* Functions called by parser */
370 /* ARM instructions */
371 static void do_arit
PARAMS ((char *operands
, unsigned long flags
));
372 static void do_cmp
PARAMS ((char *operands
, unsigned long flags
));
373 static void do_mov
PARAMS ((char *operands
, unsigned long flags
));
374 static void do_ldst
PARAMS ((char *operands
, unsigned long flags
));
375 static void do_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
376 static void do_branch
PARAMS ((char *operands
, unsigned long flags
));
377 static void do_swi
PARAMS ((char *operands
, unsigned long flags
));
378 /* Pseudo Op codes */
379 static void do_adr
PARAMS ((char *operands
, unsigned long flags
));
380 static void do_nop
PARAMS ((char *operands
, unsigned long flags
));
382 static void do_mul
PARAMS ((char *operands
, unsigned long flags
));
383 static void do_mla
PARAMS ((char *operands
, unsigned long flags
));
385 static void do_swap
PARAMS ((char *operands
, unsigned long flags
));
387 static void do_msr
PARAMS ((char *operands
, unsigned long flags
));
388 static void do_mrs
PARAMS ((char *operands
, unsigned long flags
));
390 static void do_mull
PARAMS ((char *operands
, unsigned long flags
));
392 static void do_bx
PARAMS ((char *operands
, unsigned long flags
));
394 /* Coprocessor Instructions */
395 static void do_cdp
PARAMS ((char *operands
, unsigned long flags
));
396 static void do_lstc
PARAMS ((char *operands
, unsigned long flags
));
397 static void do_co_reg
PARAMS ((char *operands
, unsigned long flags
));
398 static void do_fp_ctrl
PARAMS ((char *operands
, unsigned long flags
));
399 static void do_fp_ldst
PARAMS ((char *operands
, unsigned long flags
));
400 static void do_fp_ldmstm
PARAMS ((char *operands
, unsigned long flags
));
401 static void do_fp_dyadic
PARAMS ((char *operands
, unsigned long flags
));
402 static void do_fp_monadic
PARAMS ((char *operands
, unsigned long flags
));
403 static void do_fp_cmp
PARAMS ((char *operands
, unsigned long flags
));
404 static void do_fp_from_reg
PARAMS ((char *operands
, unsigned long flags
));
405 static void do_fp_to_reg
PARAMS ((char *operands
, unsigned long flags
));
407 static void fix_new_arm
PARAMS ((fragS
*frag
, int where
,
408 short int size
, expressionS
*exp
,
409 int pc_rel
, int reloc
));
410 static int arm_reg_parse
PARAMS ((char **ccp
));
411 static int arm_psr_parse
PARAMS ((char **ccp
));
413 /* ARM instructions take 4bytes in the object file, Thumb instructions
417 /* LONGEST_INST is the longest basic instruction name without conditions or
419 * ARM7M has 4 of length 5
422 #define LONGEST_INST 5
426 CONST
char *template; /* Basic string to match */
427 unsigned long value
; /* Basic instruction code */
428 CONST
char *comp_suffix
; /* Compulsory suffix that must follow conds */
429 CONST
struct asm_flg
*flags
; /* Bits to toggle if flag 'n' set */
430 unsigned long variants
; /* Which CPU variants this exists for */
431 void (*parms
)(); /* Function to call to parse args */
434 static CONST
struct asm_opcode insns
[] =
436 /* ARM Instructions */
437 {"and", 0x00000000, NULL
, s_flag
, ARM_ANY
, do_arit
},
438 {"eor", 0x00200000, NULL
, s_flag
, ARM_ANY
, do_arit
},
439 {"sub", 0x00400000, NULL
, s_flag
, ARM_ANY
, do_arit
},
440 {"rsb", 0x00600000, NULL
, s_flag
, ARM_ANY
, do_arit
},
441 {"add", 0x00800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
442 {"adc", 0x00a00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
443 {"sbc", 0x00c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
444 {"rsc", 0x00e00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
445 {"orr", 0x01800000, NULL
, s_flag
, ARM_ANY
, do_arit
},
446 {"bic", 0x01c00000, NULL
, s_flag
, ARM_ANY
, do_arit
},
447 {"tst", 0x01000000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
448 {"teq", 0x01200000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
449 {"cmp", 0x01400000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
450 {"cmn", 0x01600000, NULL
, cmp_flags
, ARM_ANY
, do_cmp
},
451 {"mov", 0x01a00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
452 {"mvn", 0x01e00000, NULL
, s_flag
, ARM_ANY
, do_mov
},
453 {"str", 0x04000000, NULL
, str_flags
, ARM_ANY
, do_ldst
},
454 {"ldr", 0x04100000, NULL
, ldr_flags
, ARM_ANY
, do_ldst
},
455 {"stm", 0x08000000, NULL
, stm_flags
, ARM_ANY
, do_ldmstm
},
456 {"ldm", 0x08100000, NULL
, ldm_flags
, ARM_ANY
, do_ldmstm
},
457 {"swi", 0x0f000000, NULL
, NULL
, ARM_ANY
, do_swi
},
458 {"bl", 0x0bfffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
459 {"b", 0x0afffffe, NULL
, NULL
, ARM_ANY
, do_branch
},
462 {"adr", 0x028f0000, NULL
, NULL
, ARM_ANY
, do_adr
},
463 {"nop", 0x01a00000, NULL
, NULL
, ARM_ANY
, do_nop
},
465 /* ARM 2 multiplies */
466 {"mul", 0x00000090, NULL
, s_flag
, ARM_2UP
, do_mul
},
467 {"mla", 0x00200090, NULL
, s_flag
, ARM_2UP
, do_mla
},
469 /* ARM 3 - swp instructions */
470 {"swp", 0x01000090, NULL
, byte_flag
, ARM_3UP
, do_swap
},
472 /* ARM 6 Coprocessor instructions */
473 {"mrs", 0x010f0000, NULL
, NULL
, ARM_6UP
, do_mrs
},
474 {"msr", 0x0128f000, NULL
, NULL
, ARM_6UP
, do_msr
},
476 /* ARM 7M long multiplies - need signed/unsigned flags! */
477 {"smull", 0x00c00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
478 {"umull", 0x00800090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
479 {"smlal", 0x00e00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
480 {"umlal", 0x00a00090, NULL
, s_flag
, ARM_LONGMUL
, do_mull
},
482 /* ARM THUMB interworking */
483 {"bx", 0x012fff10, NULL
, NULL
, ARM_THUMB
, do_bx
},
485 /* Floating point instructions */
486 {"wfs", 0x0e200110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
487 {"rfs", 0x0e300110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
488 {"wfc", 0x0e400110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
489 {"rfc", 0x0e500110, NULL
, NULL
, FPU_ALL
, do_fp_ctrl
},
490 {"ldf", 0x0c100100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
491 {"stf", 0x0c000100, "sdep", NULL
, FPU_ALL
, do_fp_ldst
},
492 {"lfm", 0x0c100200, NULL
, lfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
493 {"sfm", 0x0c000200, NULL
, sfm_flags
, FPU_MEMMULTI
, do_fp_ldmstm
},
494 {"mvf", 0x0e008100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
495 {"mnf", 0x0e108100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
496 {"abs", 0x0e208100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
497 {"rnd", 0x0e308100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
498 {"sqt", 0x0e408100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
499 {"log", 0x0e508100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
500 {"lgn", 0x0e608100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
501 {"exp", 0x0e708100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
502 {"sin", 0x0e808100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
503 {"cos", 0x0e908100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
504 {"tan", 0x0ea08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
505 {"asn", 0x0eb08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
506 {"acs", 0x0ec08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
507 {"atn", 0x0ed08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
508 {"urd", 0x0ee08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
509 {"nrm", 0x0ef08100, "sde", round_flags
, FPU_ALL
, do_fp_monadic
},
510 {"adf", 0x0e000100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
511 {"suf", 0x0e200100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
512 {"rsf", 0x0e300100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
513 {"muf", 0x0e100100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
514 {"dvf", 0x0e400100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
515 {"rdf", 0x0e500100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
516 {"pow", 0x0e600100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
517 {"rpw", 0x0e700100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
518 {"rmf", 0x0e800100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
519 {"fml", 0x0e900100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
520 {"fdv", 0x0ea00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
521 {"frd", 0x0eb00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
522 {"pol", 0x0ec00100, "sde", round_flags
, FPU_ALL
, do_fp_dyadic
},
523 {"cmf", 0x0e90f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
524 {"cnf", 0x0eb0f110, NULL
, except_flag
, FPU_ALL
, do_fp_cmp
},
525 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
526 be an optional suffix, but part of the instruction. To be compatible,
528 {"cmfe", 0x0ed0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
529 {"cnfe", 0x0ef0f110, NULL
, NULL
, FPU_ALL
, do_fp_cmp
},
530 {"flt", 0x0e000110, "sde", round_flags
, FPU_ALL
, do_fp_from_reg
},
531 {"fix", 0x0e100110, NULL
, fix_flags
, FPU_ALL
, do_fp_to_reg
},
533 /* Generic copressor instructions */
534 {"cdp", 0x0e000000, NULL
, NULL
, ARM_2UP
, do_cdp
},
535 {"ldc", 0x0c100000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
536 {"stc", 0x0c000000, NULL
, cplong_flag
, ARM_2UP
, do_lstc
},
537 {"mcr", 0x0e000010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
538 {"mrc", 0x0e100010, NULL
, NULL
, ARM_2UP
, do_co_reg
},
541 /* defines for various bits that we will want to toggle */
543 #define INST_IMMEDIATE 0x02000000
544 #define OFFSET_REG 0x02000000
545 #define HWOFFSET_IMM 0x00400000
546 #define SHIFT_BY_REG 0x00000010
547 #define PRE_INDEX 0x01000000
548 #define INDEX_UP 0x00800000
549 #define WRITE_BACK 0x00200000
550 #define MULTI_SET_PSR 0x00400000
552 #define LITERAL_MASK 0xf000f000
553 #define COND_MASK 0xf0000000
554 #define OPCODE_MASK 0xfe1fffff
555 #define DATA_OP_SHIFT 21
557 /* Codes to distinguish the arithmetic instructions */
569 #define OPCODE_CMP 10
570 #define OPCODE_CMN 11
571 #define OPCODE_ORR 12
572 #define OPCODE_MOV 13
573 #define OPCODE_BIC 14
574 #define OPCODE_MVN 15
576 static void do_t_arit
PARAMS ((char *operands
));
577 static void do_t_add
PARAMS ((char *operands
));
578 static void do_t_asr
PARAMS ((char *operands
));
579 static void do_t_branch
PARAMS ((char *operands
));
580 static void do_t_bx
PARAMS ((char *operands
));
581 static void do_t_compare
PARAMS ((char *operands
));
582 static void do_t_ldmstm
PARAMS ((char *operands
));
583 static void do_t_ldr
PARAMS ((char *operands
));
584 static void do_t_ldrb
PARAMS ((char *operands
));
585 static void do_t_ldrh
PARAMS ((char *operands
));
586 static void do_t_lds
PARAMS ((char *operands
));
587 static void do_t_lsl
PARAMS ((char *operands
));
588 static void do_t_lsr
PARAMS ((char *operands
));
589 static void do_t_mov
PARAMS ((char *operands
));
590 static void do_t_push_pop
PARAMS ((char *operands
));
591 static void do_t_str
PARAMS ((char *operands
));
592 static void do_t_strb
PARAMS ((char *operands
));
593 static void do_t_strh
PARAMS ((char *operands
));
594 static void do_t_sub
PARAMS ((char *operands
));
595 static void do_t_swi
PARAMS ((char *operands
));
596 static void do_t_adr
PARAMS ((char *operands
));
598 #define T_OPCODE_MUL 0x4340
599 #define T_OPCODE_TST 0x4200
600 #define T_OPCODE_CMN 0x42c0
601 #define T_OPCODE_NEG 0x4240
602 #define T_OPCODE_MVN 0x43c0
604 #define T_OPCODE_ADD_R3 0x1800
605 #define T_OPCODE_SUB_R3 0x1a00
606 #define T_OPCODE_ADD_HI 0x4400
607 #define T_OPCODE_ADD_ST 0xb000
608 #define T_OPCODE_SUB_ST 0xb080
609 #define T_OPCODE_ADD_SP 0xa800
610 #define T_OPCODE_ADD_PC 0xa000
611 #define T_OPCODE_ADD_I8 0x3000
612 #define T_OPCODE_SUB_I8 0x3800
613 #define T_OPCODE_ADD_I3 0x1c00
614 #define T_OPCODE_SUB_I3 0x1e00
616 #define T_OPCODE_ASR_R 0x4100
617 #define T_OPCODE_LSL_R 0x4080
618 #define T_OPCODE_LSR_R 0x40c0
619 #define T_OPCODE_ASR_I 0x1000
620 #define T_OPCODE_LSL_I 0x0000
621 #define T_OPCODE_LSR_I 0x0800
623 #define T_OPCODE_MOV_I8 0x2000
624 #define T_OPCODE_CMP_I8 0x2800
625 #define T_OPCODE_CMP_LR 0x4280
626 #define T_OPCODE_MOV_HR 0x4600
627 #define T_OPCODE_CMP_HR 0x4500
629 #define T_OPCODE_LDR_PC 0x4800
630 #define T_OPCODE_LDR_SP 0x9800
631 #define T_OPCODE_STR_SP 0x9000
632 #define T_OPCODE_LDR_IW 0x6800
633 #define T_OPCODE_STR_IW 0x6000
634 #define T_OPCODE_LDR_IH 0x8800
635 #define T_OPCODE_STR_IH 0x8000
636 #define T_OPCODE_LDR_IB 0x7800
637 #define T_OPCODE_STR_IB 0x7000
638 #define T_OPCODE_LDR_RW 0x5800
639 #define T_OPCODE_STR_RW 0x5000
640 #define T_OPCODE_LDR_RH 0x5a00
641 #define T_OPCODE_STR_RH 0x5200
642 #define T_OPCODE_LDR_RB 0x5c00
643 #define T_OPCODE_STR_RB 0x5400
645 #define T_OPCODE_PUSH 0xb400
646 #define T_OPCODE_POP 0xbc00
648 #define T_OPCODE_BRANCH 0xe7fe
650 static int thumb_reg
PARAMS ((char **str
, int hi_lo
));
652 #define THUMB_SIZE 2 /* Size of thumb instruction */
653 #define THUMB_REG_LO 0x1
654 #define THUMB_REG_HI 0x2
655 #define THUMB_REG_ANY 0x3
657 #define THUMB_H1 0x0080
658 #define THUMB_H2 0x0040
665 #define THUMB_COMPARE 1
668 #define THUMB_STORE 1
670 #define THUMB_PP_PC_LR 0x0100
672 /* These three are used for immediate shifts, do not alter */
674 #define THUMB_HALFWORD 1
679 CONST
char *template; /* Basic string to match */
680 unsigned long value
; /* Basic instruction code */
682 void (*parms
)(); /* Function to call to parse args */
685 static CONST
struct thumb_opcode tinsns
[] =
687 {"adc", 0x4140, 2, do_t_arit
},
688 {"add", 0x0000, 2, do_t_add
},
689 {"and", 0x4000, 2, do_t_arit
},
690 {"asr", 0x0000, 2, do_t_asr
},
691 {"b", T_OPCODE_BRANCH
, 2, do_t_branch
},
692 {"beq", 0xd0fe, 2, do_t_branch
},
693 {"bne", 0xd1fe, 2, do_t_branch
},
694 {"bcs", 0xd2fe, 2, do_t_branch
},
695 {"bhs", 0xd2fe, 2, do_t_branch
},
696 {"bcc", 0xd3fe, 2, do_t_branch
},
697 {"bul", 0xd3fe, 2, do_t_branch
},
698 {"blo", 0xd3fe, 2, do_t_branch
},
699 {"bmi", 0xd4fe, 2, do_t_branch
},
700 {"bpl", 0xd5fe, 2, do_t_branch
},
701 {"bvs", 0xd6fe, 2, do_t_branch
},
702 {"bvc", 0xd7fe, 2, do_t_branch
},
703 {"bhi", 0xd8fe, 2, do_t_branch
},
704 {"bls", 0xd9fe, 2, do_t_branch
},
705 {"bge", 0xdafe, 2, do_t_branch
},
706 {"blt", 0xdbfe, 2, do_t_branch
},
707 {"bgt", 0xdcfe, 2, do_t_branch
},
708 {"ble", 0xddfe, 2, do_t_branch
},
709 {"bic", 0x4380, 2, do_t_arit
},
710 {"bl", 0xf7fffffe, 4, do_t_branch
},
711 {"bx", 0x4700, 2, do_t_bx
},
712 {"cmn", T_OPCODE_CMN
, 2, do_t_arit
},
713 {"cmp", 0x0000, 2, do_t_compare
},
714 {"eor", 0x4040, 2, do_t_arit
},
715 {"ldmia", 0xc800, 2, do_t_ldmstm
},
716 {"ldr", 0x0000, 2, do_t_ldr
},
717 {"ldrb", 0x0000, 2, do_t_ldrb
},
718 {"ldrh", 0x0000, 2, do_t_ldrh
},
719 {"ldrsb", 0x5600, 2, do_t_lds
},
720 {"ldrsh", 0x5e00, 2, do_t_lds
},
721 {"ldsb", 0x5600, 2, do_t_lds
},
722 {"ldsh", 0x5e00, 2, do_t_lds
},
723 {"lsl", 0x0000, 2, do_t_lsl
},
724 {"lsr", 0x0000, 2, do_t_lsr
},
725 {"mov", 0x0000, 2, do_t_mov
},
726 {"mul", T_OPCODE_MUL
, 2, do_t_arit
},
727 {"mvn", T_OPCODE_MVN
, 2, do_t_arit
},
728 {"neg", T_OPCODE_NEG
, 2, do_t_arit
},
729 {"orr", 0x4300, 2, do_t_arit
},
730 {"pop", 0xbc00, 2, do_t_push_pop
},
731 {"push", 0xb400, 2, do_t_push_pop
},
732 {"ror", 0x41c0, 2, do_t_arit
},
733 {"sbc", 0x4180, 2, do_t_arit
},
734 {"stmia", 0xc000, 2, do_t_ldmstm
},
735 {"str", 0x0000, 2, do_t_str
},
736 {"strb", 0x0000, 2, do_t_strb
},
737 {"strh", 0x0000, 2, do_t_strh
},
738 {"swi", 0xdf00, 2, do_t_swi
},
739 {"sub", 0x0000, 2, do_t_sub
},
740 {"tst", T_OPCODE_TST
, 2, do_t_arit
},
742 {"adr", 0x0000, 2, do_t_adr
},
743 {"nop", 0x0000, 2, do_nop
},
752 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
753 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
754 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
760 /* These are the standard names; Users can add aliases with .req */
761 static CONST
struct reg_entry reg_table
[] =
763 /* Processor Register Numbers */
764 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
765 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
766 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
767 {"r12", 12}, {"r13", REG_SP
},{"r14", REG_LR
},{"r15", REG_PC
},
768 /* APCS conventions */
769 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
770 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
771 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
772 {"fp", 11}, {"ip", 12}, {"sp", REG_SP
},{"lr", REG_LR
},{"pc", REG_PC
},
774 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
775 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
776 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
777 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
778 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
779 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
780 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
781 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
782 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
783 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
787 static CONST
char *bad_args
= "Bad arguments to instruction";
788 static CONST
char *bad_pc
= "r15 not allowed here";
790 static struct hash_control
*arm_ops_hsh
= NULL
;
791 static struct hash_control
*arm_tops_hsh
= NULL
;
792 static struct hash_control
*arm_cond_hsh
= NULL
;
793 static struct hash_control
*arm_shift_hsh
= NULL
;
794 static struct hash_control
*arm_reg_hsh
= NULL
;
795 static struct hash_control
*arm_psr_hsh
= NULL
;
797 /* This table describes all the machine specific pseudo-ops the assembler
798 has to support. The fields are:
799 pseudo-op name without dot
800 function to call to execute this pseudo-op
801 Integer arg to pass to the function
804 static void s_req
PARAMS ((int));
805 static void s_align
PARAMS ((int));
806 static void s_bss
PARAMS ((int));
807 static void s_even
PARAMS ((int));
808 static void s_ltorg
PARAMS ((int));
809 static void s_arm
PARAMS ((int));
810 static void s_thumb
PARAMS ((int));
811 static void s_code
PARAMS ((int));
813 static int my_get_expression
PARAMS ((expressionS
*, char **));
815 CONST pseudo_typeS md_pseudo_table
[] =
817 {"req", s_req
, 0}, /* Never called becasue '.req' does not start line */
819 {"align", s_align
, 0},
821 {"thumb", s_thumb
, 0},
824 {"ltorg", s_ltorg
, 0},
825 {"pool", s_ltorg
, 0},
827 {"extend", float_cons
, 'x'},
828 {"ldouble", float_cons
, 'x'},
829 {"packed", float_cons
, 'p'},
833 /* Stuff needed to resolve the label ambiguity
843 symbolS
*last_label_seen
;
847 #define MAX_LITERAL_POOL_SIZE 1024
849 typedef struct literalS
851 struct expressionS exp
;
855 literalT literals
[MAX_LITERAL_POOL_SIZE
];
856 int next_literal_pool_place
= 0; /* Next free entry in the pool */
857 int lit_pool_num
= 1; /* Next literal pool number */
858 symbolS
*current_poolP
= NULL
;
859 symbolS
*symbol_make_empty ();
866 if (current_poolP
== NULL
)
867 current_poolP
= symbol_make_empty();
869 /* Check if this literal value is already in the pool: */
870 while (lit_count
< next_literal_pool_place
)
872 if (literals
[lit_count
].exp
.X_op
== inst
.reloc
.exp
.X_op
873 && inst
.reloc
.exp
.X_op
== O_constant
874 && literals
[lit_count
].exp
.X_add_number
== inst
.reloc
.exp
.X_add_number
875 && literals
[lit_count
].exp
.X_unsigned
== inst
.reloc
.exp
.X_unsigned
)
880 if (lit_count
== next_literal_pool_place
) /* new entry */
882 if (next_literal_pool_place
> MAX_LITERAL_POOL_SIZE
)
884 inst
.error
= "Literal Pool Overflow\n";
888 literals
[next_literal_pool_place
].exp
= inst
.reloc
.exp
;
889 lit_count
= next_literal_pool_place
++;
892 inst
.reloc
.exp
.X_op
= O_symbol
;
893 inst
.reloc
.exp
.X_add_number
= (lit_count
)*4-8;
894 inst
.reloc
.exp
.X_add_symbol
= current_poolP
;
899 /* Can't use symbol_new here, so have to create a symbol and them at
900 a later date assign it a value. Thats what these functions do */
902 symbol_locate (symbolP
, name
, segment
, valu
, frag
)
904 CONST
char *name
; /* It is copied, the caller can modify */
905 segT segment
; /* Segment identifier (SEG_<something>) */
906 valueT valu
; /* Symbol value */
907 fragS
*frag
; /* Associated fragment */
909 unsigned int name_length
;
910 char *preserved_copy_of_name
;
912 name_length
= strlen (name
) + 1; /* +1 for \0 */
913 obstack_grow (¬es
, name
, name_length
);
914 preserved_copy_of_name
= obstack_finish (¬es
);
915 #ifdef STRIP_UNDERSCORE
916 if (preserved_copy_of_name
[0] == '_')
917 preserved_copy_of_name
++;
920 #ifdef tc_canonicalize_symbol_name
921 preserved_copy_of_name
=
922 tc_canonicalize_symbol_name (preserved_copy_of_name
);
925 S_SET_NAME (symbolP
, preserved_copy_of_name
);
927 S_SET_SEGMENT (symbolP
, segment
);
928 S_SET_VALUE (symbolP
, valu
);
929 symbol_clear_list_pointers(symbolP
);
931 symbolP
->sy_frag
= frag
;
934 * Link to end of symbol chain.
937 extern int symbol_table_frozen
;
938 if (symbol_table_frozen
)
942 symbol_append (symbolP
, symbol_lastP
, &symbol_rootP
, &symbol_lastP
);
944 obj_symbol_new_hook (symbolP
);
946 #ifdef tc_symbol_new_hook
947 tc_symbol_new_hook (symbolP
);
951 verify_symbol_chain(symbol_rootP
, symbol_lastP
);
952 #endif /* DEBUG_SYMS */
960 symbolP
= (symbolS
*) obstack_alloc (¬es
, sizeof (symbolS
));
962 /* symbol must be born in some fixed state. This seems as good as any. */
963 memset (symbolP
, 0, sizeof (symbolS
));
965 symbolP
->bsym
= bfd_make_empty_symbol (stdoutput
);
966 assert (symbolP
->bsym
!= 0);
967 symbolP
->bsym
->udata
.p
= (PTR
) symbolP
;
972 /* Check that an immediate is valid, and if so, convert it to the right format
975 /* OH, for a rotate instruction in C! */
978 validate_immediate (val
)
981 unsigned int a
= (unsigned int) val
;
984 /* Do the easy (and most common ones) quickly */
985 for (i
= 0; i
<= 24; i
+= 2)
987 if ((a
& (0xff << i
)) == a
)
988 return (int) (((32 - i
) & 0x1e) << 7) | ((a
>> i
) & 0xff);
991 /* Now do the harder ones */
992 for (; i
< 32; i
+= 2)
994 if ((a
& ((0xff << i
) | (0xff >> (32 - i
)))) == a
)
996 a
= ((a
>> i
) & 0xff) | ((a
<< (32 - i
)) & 0xff);
997 return (int) a
| (((32 - i
) >> 1) << 8);
1004 validate_offset_imm (val
, hwse
)
1008 if ((hwse
&& (val
< -255 || val
> 255))
1009 || (val
< -4095 || val
> 4095))
1019 as_bad ("Invalid syntax for .req directive.");
1026 /* We don't support putting frags in the BSS segment, we fake it by
1027 marking in_bss, then looking at s_skip for clues?.. */
1028 subseg_set (bss_section
, 0);
1029 demand_empty_rest_of_line ();
1036 if (!need_pass_2
) /* Never make frag if expect extra pass. */
1037 frag_align (1, 0, 0);
1038 record_alignment (now_seg
, 1);
1039 demand_empty_rest_of_line ();
1049 if (current_poolP
== NULL
)
1053 as_tsktsk ("Nothing to put in the pool\n");
1057 /* Align pool as you have word accesses */
1058 /* Only make a frag if we have to ... */
1060 frag_align (2, 0, 0);
1062 record_alignment (now_seg
, 2);
1065 as_tsktsk ("Inserting implicit pool at change of section");
1067 sprintf (sym_name
, "$$lit_\002%x", lit_pool_num
++);
1069 symbol_locate (current_poolP
, sym_name
, now_seg
,
1070 (valueT
) frag_now_fix (), frag_now
);
1071 symbol_table_insert (current_poolP
);
1073 while (lit_count
< next_literal_pool_place
)
1074 /* First output the expression in the instruction to the pool */
1075 emit_expr (&(literals
[lit_count
++].exp
), 4); /* .word */
1077 next_literal_pool_place
= 0;
1078 current_poolP
= NULL
;
1081 #if 0 /* not used */
1083 arm_align (power
, fill
)
1087 /* Only make a frag if we HAVE to ... */
1088 if (power
&& !need_pass_2
)
1089 frag_align (power
, fill
, 0);
1091 record_alignment (now_seg
, power
);
1096 s_align (unused
) /* Same as s_align_ptwo but align 0 => align 2 */
1100 register long temp_fill
;
1101 long max_alignment
= 15;
1103 temp
= get_absolute_expression ();
1104 if (temp
> max_alignment
)
1105 as_bad ("Alignment too large: %d. assumed.", temp
= max_alignment
);
1108 as_bad ("Alignment negative. 0 assumed.");
1112 if (*input_line_pointer
== ',')
1114 input_line_pointer
++;
1115 temp_fill
= get_absolute_expression ();
1123 /* Only make a frag if we HAVE to. . . */
1124 if (temp
&& !need_pass_2
)
1125 frag_align (temp
, (int) temp_fill
, 0);
1126 demand_empty_rest_of_line ();
1128 record_alignment (now_seg
, temp
);
1132 opcode_select (width
)
1140 if (! (cpu_variant
& ARM_THUMB
))
1141 as_bad ("selected processor does not support THUMB opcodes");
1143 /* No need to force the alignment, since we will have been
1144 coming from ARM mode, which is word-aligned. */
1145 record_alignment (now_seg
, 1);
1152 if ((cpu_variant
& ARM_ANY
) == ARM_THUMB
)
1153 as_bad ("selected processor does not support ARM opcodes");
1156 frag_align (2, 0, 0);
1157 record_alignment (now_seg
, 1);
1162 as_bad ("invalid instruction size selected (%d)", width
);
1171 demand_empty_rest_of_line ();
1179 demand_empty_rest_of_line ();
1188 temp
= get_absolute_expression ();
1193 opcode_select(temp
);
1197 as_bad ("invalid operand to .code directive (%d)", temp
);
1209 inst
.error
= "Garbage following instruction";
1213 skip_past_comma (str
)
1219 while ((c
= *p
) == ' ' || c
== ',')
1222 if (c
== ',' && comma
++)
1230 return comma
? SUCCESS
: FAIL
;
1233 /* A standard register must be given at this point. Shift is the place to
1234 put it in the instruction. */
1237 reg_required_here (str
, shift
)
1244 if ((reg
= arm_reg_parse (str
)) != FAIL
&& int_register (reg
))
1246 inst
.instruction
|= reg
<< shift
;
1250 /* In the few cases where we might be able to accept something else
1251 this error can be overridden */
1252 inst
.error
= "Register expected";
1254 /* Restore the start point, we may have got a reg of the wrong class. */
1260 psr_required_here (str
, shift
)
1267 if ((psr
= arm_psr_parse (str
)) != FAIL
&& psr
< 2)
1270 inst
.instruction
|= 1 << shift
; /* Should be bit 22 */
1274 /* In the few cases where we might be able to accept something else
1275 this error can be overridden */
1276 inst
.error
= "<psr> expected";
1278 /* Restore the start point. */
1284 psrf_required_here (str
, shift
)
1291 if ((psrf
= arm_psr_parse (str
)) != FAIL
&& psrf
> 1)
1293 if (psrf
== 1 || psrf
== 3)
1294 inst
.instruction
|= 1 << shift
; /* Should be bit 22 */
1298 /* In the few cases where we might be able to accept something else
1299 this error can be overridden */
1300 inst
.error
= "<psrf> expected";
1302 /* Restore the start point. */
1308 co_proc_number (str
)
1311 int processor
, pchar
;
1313 while (**str
== ' ')
1316 /* The data sheet seems to imply that just a number on its own is valid
1317 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1319 if (**str
== 'p' || **str
== 'P')
1323 if (pchar
>= '0' && pchar
<= '9')
1325 processor
= pchar
- '0';
1326 if (**str
>= '0' && **str
<= '9')
1328 processor
= processor
* 10 + *(*str
)++ - '0';
1331 inst
.error
= "Illegal co-processor number";
1338 inst
.error
= "Bad or missing co-processor number";
1342 inst
.instruction
|= processor
<< 8;
1347 cp_opc_expr (str
, where
, length
)
1354 while (**str
== ' ')
1357 memset (&expr
, '\0', sizeof (expr
));
1359 if (my_get_expression (&expr
, str
))
1361 if (expr
.X_op
!= O_constant
)
1363 inst
.error
= "bad or missing expression";
1367 if ((expr
.X_add_number
& ((1 << length
) - 1)) != expr
.X_add_number
)
1369 inst
.error
= "immediate co-processor expression too large";
1373 inst
.instruction
|= expr
.X_add_number
<< where
;
1378 cp_reg_required_here (str
, where
)
1385 if ((reg
= arm_reg_parse (str
)) != FAIL
&& cp_register (reg
))
1388 inst
.instruction
|= reg
<< where
;
1392 /* In the few cases where we might be able to accept something else
1393 this error can be overridden */
1394 inst
.error
= "Co-processor register expected";
1396 /* Restore the start point */
1402 fp_reg_required_here (str
, where
)
1409 if ((reg
= arm_reg_parse (str
)) != FAIL
&& fp_register (reg
))
1412 inst
.instruction
|= reg
<< where
;
1416 /* In the few cases where we might be able to accept something else
1417 this error can be overridden */
1418 inst
.error
= "Floating point register expected";
1420 /* Restore the start point */
1426 cp_address_offset (str
)
1431 while (**str
== ' ')
1436 inst
.error
= "immediate expression expected";
1441 if (my_get_expression (&inst
.reloc
.exp
, str
))
1443 if (inst
.reloc
.exp
.X_op
== O_constant
)
1445 offset
= inst
.reloc
.exp
.X_add_number
;
1448 inst
.error
= "co-processor address must be word aligned";
1452 if (offset
> 1023 || offset
< -1023)
1454 inst
.error
= "offset too large";
1459 inst
.instruction
|= INDEX_UP
;
1463 inst
.instruction
|= offset
>> 2;
1466 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1472 cp_address_required_here (str
)
1487 if ((reg
= reg_required_here (&p
, 16)) == FAIL
)
1489 inst
.error
= "Register required";
1499 if (skip_past_comma (&p
) == SUCCESS
)
1502 write_back
= WRITE_BACK
;
1505 inst
.error
= "pc may not be used in post-increment";
1509 if (cp_address_offset (&p
) == FAIL
)
1513 pre_inc
= PRE_INDEX
| INDEX_UP
;
1517 /* '['Rn, #expr']'[!] */
1519 if (skip_past_comma (&p
) == FAIL
)
1521 inst
.error
= "pre-indexed expression expected";
1525 pre_inc
= PRE_INDEX
;
1526 if (cp_address_offset (&p
) == FAIL
)
1534 inst
.error
= "missing ]";
1545 inst
.error
= "pc may not be used with write-back";
1550 write_back
= WRITE_BACK
;
1556 if (my_get_expression (&inst
.reloc
.exp
, &p
))
1559 inst
.reloc
.type
= BFD_RELOC_ARM_CP_OFF_IMM
;
1560 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
1561 inst
.reloc
.pc_rel
= 1;
1562 inst
.instruction
|= (REG_PC
<< 16);
1563 pre_inc
= PRE_INDEX
;
1566 inst
.instruction
|= write_back
| pre_inc
;
1574 unsigned long flags
;
1576 /* Do nothing really */
1577 inst
.instruction
|= flags
; /* This is pointless */
1585 unsigned long flags
;
1587 /* Only one syntax */
1591 if (reg_required_here (&str
, 12) == FAIL
)
1593 inst
.error
= bad_args
;
1597 if (skip_past_comma (&str
) == FAIL
1598 || psr_required_here (&str
, 22) == FAIL
)
1600 inst
.error
= "<psr> expected";
1604 inst
.instruction
|= flags
;
1612 unsigned long flags
;
1615 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1620 if ((psr
= psr_required_here (&str
, 22)) != FAIL
)
1622 inst
.instruction
|= PSR_ALL
;
1623 /* Sytax should be "<psr>, Rm" */
1624 if (skip_past_comma (&str
) == FAIL
1625 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
1627 inst
.error
= bad_args
;
1631 else if ((psrf
= psrf_required_here (&str
, 22)) != FAIL
)
1632 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1634 if (skip_past_comma (&str
) == FAIL
)
1636 inst
.error
= bad_args
;
1639 if ((reg
= reg_required_here (&str
, 0)) != FAIL
)
1641 /* Immediate expression */
1642 else if (*(str
++) == '#')
1645 if (my_get_expression (&inst
.reloc
.exp
, &str
))
1647 inst
.error
= "Register or shift expression expected";
1651 if (inst
.reloc
.exp
.X_add_symbol
)
1653 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
1654 inst
.reloc
.pc_rel
= 0;
1658 int value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
1661 inst
.error
= "Invalid constant";
1665 inst
.instruction
|= value
;
1668 flags
|= INST_IMMEDIATE
;
1672 inst
.error
= "Error: the other";
1678 inst
.error
= bad_args
;
1683 inst
.instruction
|= flags
;
1688 /* Long Multiply Parser
1689 UMULL RdLo, RdHi, Rm, Rs
1690 SMULL RdLo, RdHi, Rm, Rs
1691 UMLAL RdLo, RdHi, Rm, Rs
1692 SMLAL RdLo, RdHi, Rm, Rs
1695 do_mull (str
, flags
)
1697 unsigned long flags
;
1699 int rdlo
, rdhi
, rm
, rs
;
1701 /* only one format "rdlo, rdhi, rm, rs" */
1705 if ((rdlo
= reg_required_here (&str
, 12)) == FAIL
)
1707 inst
.error
= bad_args
;
1711 if (skip_past_comma (&str
) == FAIL
1712 || (rdhi
= reg_required_here (&str
, 16)) == FAIL
)
1714 inst
.error
= bad_args
;
1718 if (skip_past_comma (&str
) == FAIL
1719 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1721 inst
.error
= bad_args
;
1725 /* rdhi, rdlo and rm must all be different */
1726 if (rdlo
== rdhi
|| rdlo
== rm
|| rdhi
== rm
)
1727 as_tsktsk ("rdhi, rdlo and rm must all be different");
1729 if (skip_past_comma (&str
) == FAIL
1730 || (rs
= reg_required_here (&str
, 8)) == FAIL
)
1732 inst
.error
= bad_args
;
1736 if (rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
|| rdhi
== REG_PC
)
1738 inst
.error
= bad_pc
;
1742 inst
.instruction
|= flags
;
1750 unsigned long flags
;
1754 /* only one format "rd, rm, rs" */
1758 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1760 inst
.error
= bad_args
;
1766 inst
.error
= bad_pc
;
1770 if (skip_past_comma (&str
) == FAIL
1771 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1773 inst
.error
= bad_args
;
1779 inst
.error
= bad_pc
;
1784 as_tsktsk ("rd and rm should be different in mul");
1786 if (skip_past_comma (&str
) == FAIL
1787 || (rm
= reg_required_here (&str
, 8)) == FAIL
)
1789 inst
.error
= bad_args
;
1795 inst
.error
= bad_pc
;
1799 inst
.instruction
|= flags
;
1807 unsigned long flags
;
1811 /* only one format "rd, rm, rs, rn" */
1815 if ((rd
= reg_required_here (&str
, 16)) == FAIL
)
1817 inst
.error
= bad_args
;
1823 inst
.error
= bad_pc
;
1827 if (skip_past_comma (&str
) == FAIL
1828 || (rm
= reg_required_here (&str
, 0)) == FAIL
)
1830 inst
.error
= bad_args
;
1836 inst
.error
= bad_pc
;
1841 as_tsktsk ("rd and rm should be different in mla");
1843 if (skip_past_comma (&str
) == FAIL
1844 || (rd
= reg_required_here (&str
, 8)) == FAIL
1845 || skip_past_comma (&str
) == FAIL
1846 || (rm
= reg_required_here (&str
, 12)) == FAIL
)
1848 inst
.error
= bad_args
;
1852 if (rd
== REG_PC
|| rm
== REG_PC
)
1854 inst
.error
= bad_pc
;
1858 inst
.instruction
|= flags
;
1863 /* Returns the index into fp_values of a floating point number, or -1 if
1864 not in the table. */
1866 my_get_float_expression (str
)
1869 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1874 memset (words
, 0, MAX_LITTLENUMS
* sizeof (LITTLENUM_TYPE
));
1875 /* Look for a raw floating point number */
1876 if ((save_in
= atof_ieee (*str
, 'x', words
)) != NULL
1877 && (is_end_of_line
[(int)(*save_in
)] || *save_in
== '\0'))
1879 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
1881 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
1883 if (words
[j
] != fp_values
[i
][j
])
1887 if (j
== MAX_LITTLENUMS
)
1895 /* Try and parse a more complex expression, this will probably fail
1896 unless the code uses a floating point prefix (eg "0f") */
1897 save_in
= input_line_pointer
;
1898 input_line_pointer
= *str
;
1899 if (expression (&exp
) == absolute_section
1900 && exp
.X_op
== O_big
1901 && exp
.X_add_number
< 0)
1903 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
1905 if (gen_to_words (words
, 5, (long)15) == 0)
1907 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
1909 for (j
= 0; j
< MAX_LITTLENUMS
; j
++)
1911 if (words
[j
] != fp_values
[i
][j
])
1915 if (j
== MAX_LITTLENUMS
)
1917 *str
= input_line_pointer
;
1918 input_line_pointer
= save_in
;
1925 *str
= input_line_pointer
;
1926 input_line_pointer
= save_in
;
1930 /* Return true if anything in the expression is a bignum */
1932 walk_no_bignums (sp
)
1935 if (sp
->sy_value
.X_op
== O_big
)
1938 if (sp
->sy_value
.X_add_symbol
)
1940 return (walk_no_bignums (sp
->sy_value
.X_add_symbol
)
1941 || (sp
->sy_value
.X_op_symbol
1942 && walk_no_bignums (sp
->sy_value
.X_op_symbol
)));
1949 my_get_expression (ep
, str
)
1956 save_in
= input_line_pointer
;
1957 input_line_pointer
= *str
;
1958 seg
= expression (ep
);
1961 if (seg
!= absolute_section
1962 && seg
!= text_section
1963 && seg
!= data_section
1964 && seg
!= bss_section
1965 && seg
!= undefined_section
)
1967 inst
.error
= "bad_segment";
1968 *str
= input_line_pointer
;
1969 input_line_pointer
= save_in
;
1974 /* Get rid of any bignums now, so that we don't generate an error for which
1975 we can't establish a line number later on. Big numbers are never valid
1976 in instructions, which is where this routine is always called. */
1977 if (ep
->X_op
== O_big
1978 || (ep
->X_add_symbol
1979 && (walk_no_bignums (ep
->X_add_symbol
)
1981 && walk_no_bignums (ep
->X_op_symbol
)))))
1983 inst
.error
= "Invalid constant";
1984 *str
= input_line_pointer
;
1985 input_line_pointer
= save_in
;
1989 *str
= input_line_pointer
;
1990 input_line_pointer
= save_in
;
1994 /* unrestrict should be one if <shift> <register> is permitted for this
1998 decode_shift (str
, unrestrict
)
2002 struct asm_shift
*shft
;
2006 while (**str
== ' ')
2009 for (p
= *str
; isalpha (*p
); p
++)
2014 inst
.error
= "Shift expression expected";
2020 shft
= (struct asm_shift
*) hash_find (arm_shift_hsh
, *str
);
2024 if (!strcmp (*str
, "rrx")
2025 || !strcmp (*str
, "RRX"))
2028 inst
.instruction
|= shft
->value
;
2035 if (unrestrict
&& reg_required_here (&p
, 8) != FAIL
)
2037 inst
.instruction
|= shft
->value
| SHIFT_BY_REG
;
2045 if (my_get_expression (&inst
.reloc
.exp
, &p
))
2048 /* Validate some simple #expressions */
2049 if (inst
.reloc
.exp
.X_op
== O_constant
)
2051 unsigned num
= inst
.reloc
.exp
.X_add_number
;
2053 /* Reject operations greater than 32, or lsl #32 */
2054 if (num
> 32 || (num
== 32 && shft
->value
== 0))
2056 inst
.error
= "Invalid immediate shift";
2060 /* Shifts of zero should be converted to lsl (which is zero)*/
2067 /* Shifts of 32 are encoded as 0, for those shifts that
2072 inst
.instruction
|= (num
<< 7) | shft
->value
;
2077 inst
.reloc
.type
= BFD_RELOC_ARM_SHIFT_IMM
;
2078 inst
.reloc
.pc_rel
= 0;
2079 inst
.instruction
|= shft
->value
;
2085 inst
.error
= unrestrict
? "shift requires register or #expression"
2086 : "shift requires #expression";
2092 inst
.error
= "Shift expression expected";
2096 /* Do those data_ops which can take a negative immediate constant */
2097 /* by altering the instuction. A bit of a hack really */
2101 by inverting the second operand, and
2104 by negating the second operand.
2107 negate_data_op (instruction
, value
)
2108 unsigned long *instruction
;
2109 unsigned long value
;
2112 unsigned long negated
, inverted
;
2114 negated
= validate_immediate (-value
);
2115 inverted
= validate_immediate (~value
);
2117 op
= (*instruction
>> DATA_OP_SHIFT
) & 0xf;
2121 case OPCODE_SUB
: /* ADD <-> SUB */
2122 new_inst
= OPCODE_ADD
;
2127 new_inst
= OPCODE_SUB
;
2131 case OPCODE_CMP
: /* CMP <-> CMN */
2132 new_inst
= OPCODE_CMN
;
2137 new_inst
= OPCODE_CMP
;
2141 /* Now Inverted ops */
2142 case OPCODE_MOV
: /* MOV <-> MVN */
2143 new_inst
= OPCODE_MVN
;
2148 new_inst
= OPCODE_MOV
;
2152 case OPCODE_AND
: /* AND <-> BIC */
2153 new_inst
= OPCODE_BIC
;
2158 new_inst
= OPCODE_AND
;
2162 case OPCODE_ADC
: /* ADC <-> SBC */
2163 new_inst
= OPCODE_SBC
;
2168 new_inst
= OPCODE_ADC
;
2172 /* We cannot do anything */
2180 *instruction
&= OPCODE_MASK
;
2181 *instruction
|= new_inst
<< DATA_OP_SHIFT
;
2192 while (**str
== ' ')
2195 if (reg_required_here (str
, 0) != FAIL
)
2197 if (skip_past_comma (str
) == SUCCESS
)
2199 /* Shift operation on register */
2200 return decode_shift (str
, NO_SHIFT_RESTRICT
);
2206 /* Immediate expression */
2207 if (*((*str
)++) == '#')
2210 if (my_get_expression (&inst
.reloc
.exp
, str
))
2213 if (inst
.reloc
.exp
.X_add_symbol
)
2215 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2216 inst
.reloc
.pc_rel
= 0;
2220 if (skip_past_comma (str
) == SUCCESS
)
2222 /* #x, y -- ie explicit rotation by Y */
2223 if (my_get_expression (&expr
, str
))
2226 if (expr
.X_op
!= O_constant
)
2228 inst
.error
= "Constant expression expected";
2232 /* Rotate must be a multiple of 2 */
2233 if (((unsigned) expr
.X_add_number
) > 30
2234 || (expr
.X_add_number
& 1) != 0
2235 || ((unsigned) inst
.reloc
.exp
.X_add_number
) > 255)
2237 inst
.error
= "Invalid constant";
2240 inst
.instruction
|= INST_IMMEDIATE
;
2241 inst
.instruction
|= inst
.reloc
.exp
.X_add_number
;
2242 inst
.instruction
|= expr
.X_add_number
<< 7;
2246 /* Implicit rotation, select a suitable one */
2247 value
= validate_immediate (inst
.reloc
.exp
.X_add_number
);
2251 /* Can't be done, perhaps the code reads something like
2252 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2253 if ((value
= negate_data_op (&inst
.instruction
,
2254 inst
.reloc
.exp
.X_add_number
))
2257 inst
.error
= "Invalid constant";
2262 inst
.instruction
|= value
;
2265 inst
.instruction
|= INST_IMMEDIATE
;
2269 inst
.error
= "Register or shift expression expected";
2277 unsigned long flags
;
2279 while (**str
== ' ')
2282 if (fp_reg_required_here (str
, 0) != FAIL
)
2286 /* Immediate expression */
2287 if (*((*str
)++) == '#')
2292 while (**str
== ' ')
2295 /* First try and match exact strings, this is to guarantee that
2296 some formats will work even for cross assembly */
2298 for (i
= 0; fp_const
[i
]; i
++)
2300 if (strncmp (*str
, fp_const
[i
], strlen (fp_const
[i
])) == 0)
2304 *str
+= strlen (fp_const
[i
]);
2305 if (is_end_of_line
[(int)**str
] || **str
== '\0')
2307 inst
.instruction
|= i
+ 8;
2314 /* Just because we didn't get a match doesn't mean that the
2315 constant isn't valid, just that it is in a format that we
2316 don't automatically recognize. Try parsing it with
2317 the standard expression routines. */
2318 if ((i
= my_get_float_expression (str
)) >= 0)
2320 inst
.instruction
|= i
+ 8;
2324 inst
.error
= "Invalid floating point immediate expression";
2327 inst
.error
= "Floating point register or immediate expression expected";
2333 do_arit (str
, flags
)
2335 unsigned long flags
;
2340 if (reg_required_here (&str
, 12) == FAIL
2341 || skip_past_comma (&str
) == FAIL
2342 || reg_required_here (&str
, 16) == FAIL
2343 || skip_past_comma (&str
) == FAIL
2344 || data_op2 (&str
) == FAIL
)
2347 inst
.error
= bad_args
;
2351 inst
.instruction
|= flags
;
2359 unsigned long flags
;
2361 /* This is a pseudo-op of the form "adr rd, label" to be converted
2362 into a relative address of the form "add rd, pc, #label-.-8" */
2367 if (reg_required_here (&str
, 12) == FAIL
2368 || skip_past_comma (&str
) == FAIL
2369 || my_get_expression (&inst
.reloc
.exp
, &str
))
2372 inst
.error
= bad_args
;
2375 /* Frag hacking will turn this into a sub instruction if the offset turns
2376 out to be negative. */
2377 inst
.reloc
.type
= BFD_RELOC_ARM_IMMEDIATE
;
2378 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
2379 inst
.reloc
.pc_rel
= 1;
2380 inst
.instruction
|= flags
;
2388 unsigned long flags
;
2393 if (reg_required_here (&str
, 16) == FAIL
)
2396 inst
.error
= bad_args
;
2400 if (skip_past_comma (&str
) == FAIL
2401 || data_op2 (&str
) == FAIL
)
2404 inst
.error
= bad_args
;
2408 inst
.instruction
|= flags
;
2409 if ((flags
& 0x0000f000) == 0)
2410 inst
.instruction
|= CONDS_BIT
;
2419 unsigned long flags
;
2424 if (reg_required_here (&str
, 12) == FAIL
)
2427 inst
.error
= bad_args
;
2431 if (skip_past_comma (&str
) == FAIL
2432 || data_op2 (&str
) == FAIL
)
2435 inst
.error
= bad_args
;
2439 inst
.instruction
|= flags
;
2445 ldst_extend (str
, hwse
)
2455 if (my_get_expression (&inst
.reloc
.exp
, str
))
2458 if (inst
.reloc
.exp
.X_op
== O_constant
)
2460 int value
= inst
.reloc
.exp
.X_add_number
;
2462 if ((hwse
&& (value
< -255 || value
> 255))
2463 || (value
< -4095 || value
> 4095))
2465 inst
.error
= "address offset too large";
2475 /* Halfword and signextension instructions have the
2476 immediate value split across bits 11..8 and bits 3..0 */
2478 inst
.instruction
|= add
| HWOFFSET_IMM
| (value
>> 4) << 8 | value
& 0xF;
2480 inst
.instruction
|= add
| value
;
2486 inst
.instruction
|= HWOFFSET_IMM
;
2487 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2490 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2491 inst
.reloc
.pc_rel
= 0;
2496 add
= 0; /* and fall through */
2498 (*str
)++; /* and fall through */
2500 if (reg_required_here (str
, 0) == FAIL
)
2502 inst
.error
= "Register expected";
2507 inst
.instruction
|= add
;
2510 inst
.instruction
|= add
| OFFSET_REG
;
2511 if (skip_past_comma (str
) == SUCCESS
)
2512 return decode_shift (str
, SHIFT_RESTRICT
);
2520 do_ldst (str
, flags
)
2522 unsigned long flags
;
2529 /* This is not ideal, but it is the simplest way of dealing with the
2530 ARM7T halfword instructions (since they use a different
2531 encoding, but the same mnemonic): */
2532 if (halfword
= ((flags
& 0x80000000) != 0))
2534 /* This is actually a load/store of a halfword, or a
2535 signed-extension load */
2536 if ((cpu_variant
& ARM_ARCH4
) == 0)
2539 = "Processor does not support halfwords or signed bytes\n";
2543 inst
.instruction
= (inst
.instruction
& COND_MASK
)
2544 | (flags
& ~COND_MASK
);
2552 if ((conflict_reg
= reg_required_here (&str
, 12)) == FAIL
)
2555 inst
.error
= bad_args
;
2559 if (skip_past_comma (&str
) == FAIL
)
2561 inst
.error
= "Address expected";
2573 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2575 inst
.error
= "Register required";
2579 conflict_reg
= (((conflict_reg
== reg
)
2580 && (inst
.instruction
& LOAD_BIT
))
2589 if (skip_past_comma (&str
) == SUCCESS
)
2591 /* [Rn],... (post inc) */
2592 if (ldst_extend (&str
, halfword
) == FAIL
)
2595 as_warn ("destination register same as write-back base\n");
2601 inst
.instruction
|= HWOFFSET_IMM
;
2609 as_warn ("destination register same as write-back base\n");
2611 inst
.instruction
|= WRITE_BACK
;
2615 if (! (flags
& TRANS_BIT
))
2622 if (skip_past_comma (&str
) == FAIL
)
2624 inst
.error
= "pre-indexed expression expected";
2629 if (ldst_extend (&str
, halfword
) == FAIL
)
2637 inst
.error
= "missing ]";
2647 as_tsktsk ("destination register same as write-back base\n");
2649 inst
.instruction
|= WRITE_BACK
;
2653 else if (*str
== '=')
2655 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2661 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2664 if (inst
.reloc
.exp
.X_op
!= O_constant
2665 && inst
.reloc
.exp
.X_op
!= O_symbol
)
2667 inst
.error
= "Constant expression expected";
2671 if (inst
.reloc
.exp
.X_op
== O_constant
2672 && (value
= validate_immediate(inst
.reloc
.exp
.X_add_number
)) != FAIL
)
2674 /* This can be done with a mov instruction */
2675 inst
.instruction
&= LITERAL_MASK
;
2676 inst
.instruction
|= INST_IMMEDIATE
| (OPCODE_MOV
<< DATA_OP_SHIFT
);
2677 inst
.instruction
|= (flags
& COND_MASK
) | (value
& 0xfff);
2683 /* Insert into literal pool */
2684 if (add_to_lit_pool () == FAIL
)
2687 inst
.error
= "literal pool insertion failed\n";
2691 /* Change the instruction exp to point to the pool */
2694 inst
.instruction
|= HWOFFSET_IMM
;
2695 inst
.reloc
.type
= BFD_RELOC_ARM_HWLITERAL
;
2698 inst
.reloc
.type
= BFD_RELOC_ARM_LITERAL
;
2699 inst
.reloc
.pc_rel
= 1;
2700 inst
.instruction
|= (REG_PC
<< 16);
2706 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2711 inst
.instruction
|= HWOFFSET_IMM
;
2712 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM8
;
2715 inst
.reloc
.type
= BFD_RELOC_ARM_OFFSET_IMM
;
2716 inst
.reloc
.exp
.X_add_number
-= 8; /* PC rel adjust */
2717 inst
.reloc
.pc_rel
= 1;
2718 inst
.instruction
|= (REG_PC
<< 16);
2722 if (pre_inc
&& (flags
& TRANS_BIT
))
2723 inst
.error
= "Pre-increment instruction with translate";
2725 inst
.instruction
|= flags
| (pre_inc
? PRE_INDEX
: 0);
2738 /* We come back here if we get ranges concatenated by '+' or '|' */
2756 if ((reg
= arm_reg_parse (&str
)) == FAIL
|| !int_register (reg
))
2758 inst
.error
= "Register expected";
2768 inst
.error
= "Bad range in register list";
2772 for (i
= cur_reg
+ 1; i
< reg
; i
++)
2774 if (range
& (1 << i
))
2776 ("Warning: Duplicated register (r%d) in register list",
2784 if (range
& (1 << reg
))
2785 as_tsktsk ("Warning: Duplicated register (r%d) in register list",
2787 else if (reg
<= cur_reg
)
2788 as_tsktsk ("Warning: Register range not in ascending order");
2792 } while (skip_past_comma (&str
) != FAIL
2793 || (in_range
= 1, *str
++ == '-'));
2800 inst
.error
= "Missing `}'";
2808 if (my_get_expression (&expr
, &str
))
2811 if (expr
.X_op
== O_constant
)
2813 if (expr
.X_add_number
2814 != (expr
.X_add_number
& 0x0000ffff))
2816 inst
.error
= "invalid register mask";
2820 if ((range
& expr
.X_add_number
) != 0)
2822 int regno
= range
& expr
.X_add_number
;
2825 regno
= (1 << regno
) - 1;
2827 ("Warning: Duplicated register (r%d) in register list",
2831 range
|= expr
.X_add_number
;
2835 if (inst
.reloc
.type
!= 0)
2837 inst
.error
= "expression too complex";
2841 memcpy (&inst
.reloc
.exp
, &expr
, sizeof (expressionS
));
2842 inst
.reloc
.type
= BFD_RELOC_ARM_MULTI
;
2843 inst
.reloc
.pc_rel
= 0;
2850 if (*str
== '|' || *str
== '+')
2855 } while (another_range
);
2862 do_ldmstm (str
, flags
)
2864 unsigned long flags
;
2872 if ((base_reg
= reg_required_here (&str
, 16)) == FAIL
)
2875 inst
.error
= bad_args
;
2879 if (base_reg
== REG_PC
)
2881 inst
.error
= "r15 not allowed as base register";
2889 flags
|= WRITE_BACK
;
2893 if (skip_past_comma (&str
) == FAIL
2894 || (range
= reg_list (&str
)) == FAIL
)
2897 inst
.error
= bad_args
;
2904 flags
|= MULTI_SET_PSR
;
2907 inst
.instruction
|= flags
| range
;
2915 unsigned long flags
;
2917 /* Allow optional leading '#'. */
2923 if (my_get_expression (&inst
.reloc
.exp
, &str
))
2926 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
2927 inst
.reloc
.pc_rel
= 0;
2928 inst
.instruction
|= flags
;
2934 do_swap (str
, flags
)
2936 unsigned long flags
;
2943 if ((reg
= reg_required_here (&str
, 12)) == FAIL
)
2948 inst
.error
= "r15 not allowed in swap";
2952 if (skip_past_comma (&str
) == FAIL
2953 || (reg
= reg_required_here (&str
, 0)) == FAIL
)
2956 inst
.error
= bad_args
;
2962 inst
.error
= "r15 not allowed in swap";
2966 if (skip_past_comma (&str
) == FAIL
2969 inst
.error
= bad_args
;
2976 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
2981 inst
.error
= bad_pc
;
2990 inst
.error
= "missing ]";
2994 inst
.instruction
|= flags
;
3000 do_branch (str
, flags
)
3002 unsigned long flags
;
3004 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3006 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
3007 inst
.reloc
.pc_rel
= 1;
3015 unsigned long flags
;
3022 if ((reg
= reg_required_here (&str
, 0)) == FAIL
)
3026 as_tsktsk ("Use of r15 in bx has undefined behaviour");
3035 unsigned long flags
;
3037 /* Co-processor data operation.
3038 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3042 if (co_proc_number (&str
) == FAIL
)
3045 inst
.error
= bad_args
;
3049 if (skip_past_comma (&str
) == FAIL
3050 || cp_opc_expr (&str
, 20,4) == FAIL
)
3053 inst
.error
= bad_args
;
3057 if (skip_past_comma (&str
) == FAIL
3058 || cp_reg_required_here (&str
, 12) == FAIL
)
3061 inst
.error
= bad_args
;
3065 if (skip_past_comma (&str
) == FAIL
3066 || cp_reg_required_here (&str
, 16) == FAIL
)
3069 inst
.error
= bad_args
;
3073 if (skip_past_comma (&str
) == FAIL
3074 || cp_reg_required_here (&str
, 0) == FAIL
)
3077 inst
.error
= bad_args
;
3081 if (skip_past_comma (&str
) == SUCCESS
)
3083 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3086 inst
.error
= bad_args
;
3096 do_lstc (str
, flags
)
3098 unsigned long flags
;
3100 /* Co-processor register load/store.
3101 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3106 if (co_proc_number (&str
) == FAIL
)
3109 inst
.error
= bad_args
;
3113 if (skip_past_comma (&str
) == FAIL
3114 || cp_reg_required_here (&str
, 12) == FAIL
)
3117 inst
.error
= bad_args
;
3121 if (skip_past_comma (&str
) == FAIL
3122 || cp_address_required_here (&str
) == FAIL
)
3125 inst
.error
= bad_args
;
3129 inst
.instruction
|= flags
;
3135 do_co_reg (str
, flags
)
3137 unsigned long flags
;
3139 /* Co-processor register transfer.
3140 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3145 if (co_proc_number (&str
) == FAIL
)
3148 inst
.error
= bad_args
;
3152 if (skip_past_comma (&str
) == FAIL
3153 || cp_opc_expr (&str
, 21, 3) == FAIL
)
3156 inst
.error
= bad_args
;
3160 if (skip_past_comma (&str
) == FAIL
3161 || reg_required_here (&str
, 12) == FAIL
)
3164 inst
.error
= bad_args
;
3168 if (skip_past_comma (&str
) == FAIL
3169 || cp_reg_required_here (&str
, 16) == FAIL
)
3172 inst
.error
= bad_args
;
3176 if (skip_past_comma (&str
) == FAIL
3177 || cp_reg_required_here (&str
, 0) == FAIL
)
3180 inst
.error
= bad_args
;
3184 if (skip_past_comma (&str
) == SUCCESS
)
3186 if (cp_opc_expr (&str
, 5, 3) == FAIL
)
3189 inst
.error
= bad_args
;
3199 do_fp_ctrl (str
, flags
)
3201 unsigned long flags
;
3203 /* FP control registers.
3204 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3209 if (reg_required_here (&str
, 12) == FAIL
)
3212 inst
.error
= bad_args
;
3221 do_fp_ldst (str
, flags
)
3223 unsigned long flags
;
3228 switch (inst
.suffix
)
3233 inst
.instruction
|= CP_T_X
;
3236 inst
.instruction
|= CP_T_Y
;
3239 inst
.instruction
|= CP_T_X
| CP_T_Y
;
3245 if (fp_reg_required_here (&str
, 12) == FAIL
)
3248 inst
.error
= bad_args
;
3252 if (skip_past_comma (&str
) == FAIL
3253 || cp_address_required_here (&str
) == FAIL
)
3256 inst
.error
= bad_args
;
3264 do_fp_ldmstm (str
, flags
)
3266 unsigned long flags
;
3273 if (fp_reg_required_here (&str
, 12) == FAIL
)
3276 inst
.error
= bad_args
;
3280 /* Get Number of registers to transfer */
3281 if (skip_past_comma (&str
) == FAIL
3282 || my_get_expression (&inst
.reloc
.exp
, &str
))
3285 inst
.error
= "constant expression expected";
3289 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3291 inst
.error
= "Constant value required for number of registers";
3295 num_regs
= inst
.reloc
.exp
.X_add_number
;
3297 if (num_regs
< 1 || num_regs
> 4)
3299 inst
.error
= "number of registers must be in the range [1:4]";
3306 inst
.instruction
|= CP_T_X
;
3309 inst
.instruction
|= CP_T_Y
;
3312 inst
.instruction
|= CP_T_Y
| CP_T_X
;
3326 /* The instruction specified "ea" or "fd", so we can only accept
3327 [Rn]{!}. The instruction does not really support stacking or
3328 unstacking, so we have to emulate these by setting appropriate
3329 bits and offsets. */
3330 if (skip_past_comma (&str
) == FAIL
3334 inst
.error
= bad_args
;
3342 if ((reg
= reg_required_here (&str
, 16)) == FAIL
)
3344 inst
.error
= "Register required";
3353 inst
.error
= bad_args
;
3364 inst
.error
= "R15 not allowed as base register with write-back";
3371 if (flags
& CP_T_Pre
)
3374 offset
= 3 * num_regs
;
3380 /* Post-increment */
3384 offset
= 3 * num_regs
;
3388 /* No write-back, so convert this into a standard pre-increment
3389 instruction -- aesthetically more pleasing. */
3390 flags
= CP_T_Pre
| CP_T_UD
;
3395 inst
.instruction
|= flags
| offset
;
3397 else if (skip_past_comma (&str
) == FAIL
3398 || cp_address_required_here (&str
) == FAIL
)
3401 inst
.error
= bad_args
;
3409 do_fp_dyadic (str
, flags
)
3411 unsigned long flags
;
3416 switch (inst
.suffix
)
3421 inst
.instruction
|= 0x00000080;
3424 inst
.instruction
|= 0x00080000;
3430 if (fp_reg_required_here (&str
, 12) == FAIL
)
3433 inst
.error
= bad_args
;
3437 if (skip_past_comma (&str
) == FAIL
3438 || fp_reg_required_here (&str
, 16) == FAIL
)
3441 inst
.error
= bad_args
;
3445 if (skip_past_comma (&str
) == FAIL
3446 || fp_op2 (&str
) == FAIL
)
3449 inst
.error
= bad_args
;
3453 inst
.instruction
|= flags
;
3459 do_fp_monadic (str
, flags
)
3461 unsigned long flags
;
3466 switch (inst
.suffix
)
3471 inst
.instruction
|= 0x00000080;
3474 inst
.instruction
|= 0x00080000;
3480 if (fp_reg_required_here (&str
, 12) == FAIL
)
3483 inst
.error
= bad_args
;
3487 if (skip_past_comma (&str
) == FAIL
3488 || fp_op2 (&str
) == FAIL
)
3491 inst
.error
= bad_args
;
3495 inst
.instruction
|= flags
;
3501 do_fp_cmp (str
, flags
)
3503 unsigned long flags
;
3508 if (fp_reg_required_here (&str
, 16) == FAIL
)
3511 inst
.error
= bad_args
;
3515 if (skip_past_comma (&str
) == FAIL
3516 || fp_op2 (&str
) == FAIL
)
3519 inst
.error
= bad_args
;
3523 inst
.instruction
|= flags
;
3529 do_fp_from_reg (str
, flags
)
3531 unsigned long flags
;
3536 switch (inst
.suffix
)
3541 inst
.instruction
|= 0x00000080;
3544 inst
.instruction
|= 0x00080000;
3550 if (fp_reg_required_here (&str
, 16) == FAIL
)
3553 inst
.error
= bad_args
;
3557 if (skip_past_comma (&str
) == FAIL
3558 || reg_required_here (&str
, 12) == FAIL
)
3561 inst
.error
= bad_args
;
3565 inst
.instruction
|= flags
;
3571 do_fp_to_reg (str
, flags
)
3573 unsigned long flags
;
3578 if (reg_required_here (&str
, 12) == FAIL
)
3581 inst
.error
= bad_args
;
3585 if (skip_past_comma (&str
) == FAIL
3586 || fp_reg_required_here (&str
, 0) == FAIL
)
3589 inst
.error
= bad_args
;
3593 inst
.instruction
|= flags
;
3598 /* Thumb specific routines */
3600 /* Parse and validate that a register is of the right form, this saves
3601 repeated checking of this information in many similar cases.
3602 Unlike the 32-bit case we do not insert the register into the opcode
3603 here, since the position is often unknown until the full instruction
3606 thumb_reg (strp
, hi_lo
)
3612 if ((reg
= arm_reg_parse (strp
)) == FAIL
|| ! int_register (reg
))
3614 inst
.error
= "Register expected";
3623 inst
.error
= "lo register required";
3631 inst
.error
= "hi register required";
3643 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3646 thumb_add_sub (str
, subtract
)
3650 int Rd
, Rs
, Rn
= FAIL
;
3655 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3656 || skip_past_comma (&str
) == FAIL
)
3659 inst
.error
= bad_args
;
3667 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3672 if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3675 if (skip_past_comma (&str
) == FAIL
)
3677 /* Two operand format, shuffle the registers and pretend there
3682 else if (*str
== '#')
3685 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3688 else if ((Rn
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3692 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3693 for the latter case, EXPR contains the immediate that was found. */
3696 /* All register format. */
3697 if (Rd
> 7 || Rs
> 7 || Rd
> 7)
3701 inst
.error
= "dest and source1 must be the same register";
3705 /* Can't do this for SUB */
3708 inst
.error
= "subtract valid only on lo regs";
3712 inst
.instruction
= (T_OPCODE_ADD_HI
3713 | (Rd
> 7 ? THUMB_H1
: 0)
3714 | (Rn
> 7 ? THUMB_H2
: 0));
3715 inst
.instruction
|= (Rd
& 7) | ((Rn
& 7) << 3);
3719 inst
.instruction
= subtract
? T_OPCODE_SUB_R3
: T_OPCODE_ADD_R3
;
3720 inst
.instruction
|= Rd
| (Rs
<< 3) | (Rn
<< 6);
3725 /* Immediate expression, now things start to get nasty. */
3727 /* First deal with HI regs, only very restricted cases allowed:
3728 Adjusting SP, and using PC or SP to get an address. */
3729 if ((Rd
> 7 && (Rd
!= REG_SP
|| Rs
!= REG_SP
))
3730 || (Rs
> 7 && Rs
!= REG_SP
&& Rs
!= REG_PC
))
3732 inst
.error
= "invalid Hi register with immediate";
3736 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3738 /* Value isn't known yet, all we can do is store all the fragments
3739 we know about in the instruction and let the reloc hacking
3741 inst
.instruction
= (subtract
? 0x8000 : 0) | (Rd
<< 4) | Rs
;
3742 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
3746 int offset
= inst
.reloc
.exp
.X_add_number
;
3756 /* Quick check, in case offset is MIN_INT */
3759 inst
.error
= "immediate value out of range";
3768 if (offset
& ~0x1fc)
3770 inst
.error
= "invalid immediate value for stack adjust";
3773 inst
.instruction
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
3774 inst
.instruction
|= offset
>> 2;
3776 else if (Rs
== REG_PC
|| Rs
== REG_SP
)
3779 || (offset
& ~0x3fc))
3781 inst
.error
= "invalid immediate for address calculation";
3784 inst
.instruction
= (Rs
== REG_PC
? T_OPCODE_ADD_PC
3786 inst
.instruction
|= (Rd
<< 8) | (offset
>> 2);
3792 inst
.error
= "immediate value out of range";
3795 inst
.instruction
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
3796 inst
.instruction
|= (Rd
<< 8) | offset
;
3802 inst
.error
= "immediate value out of range";
3805 inst
.instruction
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
3806 inst
.instruction
|= Rd
| (Rs
<< 3) | (offset
<< 6);
3814 thumb_shift (str
, shift
)
3818 int Rd
, Rs
, Rn
= FAIL
;
3823 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
3824 || skip_past_comma (&str
) == FAIL
)
3827 inst
.error
= bad_args
;
3833 /* Two operand immediate format, set Rs to Rd. */
3836 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3841 if ((Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
3844 if (skip_past_comma (&str
) == FAIL
)
3846 /* Two operand format, shuffle the registers and pretend there
3851 else if (*str
== '#')
3854 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3857 else if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
3861 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3862 for the latter case, EXPR contains the immediate that was found. */
3868 inst
.error
= "source1 and dest must be same register";
3874 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_R
; break;
3875 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_R
; break;
3876 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_R
; break;
3879 inst
.instruction
|= Rd
| (Rn
<< 3);
3885 case THUMB_ASR
: inst
.instruction
= T_OPCODE_ASR_I
; break;
3886 case THUMB_LSL
: inst
.instruction
= T_OPCODE_LSL_I
; break;
3887 case THUMB_LSR
: inst
.instruction
= T_OPCODE_LSR_I
; break;
3890 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3892 /* Value isn't known yet, create a dummy reloc and let reloc
3893 hacking fix it up */
3895 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_SHIFT
;
3899 unsigned shift_value
= inst
.reloc
.exp
.X_add_number
;
3901 if (shift_value
> 32 || (shift_value
== 32 && shift
== THUMB_LSL
))
3903 inst
.error
= "Invalid immediate for shift";
3907 /* Shifts of zero are handled by converting to LSL */
3908 if (shift_value
== 0)
3909 inst
.instruction
= T_OPCODE_LSL_I
;
3911 /* Shifts of 32 are encoded as a shift of zero */
3912 if (shift_value
== 32)
3915 inst
.instruction
|= shift_value
<< 6;
3918 inst
.instruction
|= Rd
| (Rs
<< 3);
3924 thumb_mov_compare (str
, move
)
3933 if ((Rd
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
3934 || skip_past_comma (&str
) == FAIL
)
3937 inst
.error
= bad_args
;
3944 if (my_get_expression (&inst
.reloc
.exp
, &str
))
3947 else if ((Rs
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
3952 if (Rs
< 8 && Rd
< 8)
3954 if (move
== THUMB_MOVE
)
3955 /* A move of two lowregs is, by convention, encoded as
3957 inst
.instruction
= T_OPCODE_ADD_I3
;
3959 inst
.instruction
= T_OPCODE_CMP_LR
;
3960 inst
.instruction
|= Rd
| (Rs
<< 3);
3964 if (move
== THUMB_MOVE
)
3965 inst
.instruction
= T_OPCODE_MOV_HR
;
3967 inst
.instruction
= T_OPCODE_CMP_HR
;
3970 inst
.instruction
|= THUMB_H1
;
3973 inst
.instruction
|= THUMB_H2
;
3975 inst
.instruction
|= (Rd
& 7) | ((Rs
& 7) << 3);
3982 inst
.error
= "only lo regs allowed with immediate";
3986 if (move
== THUMB_MOVE
)
3987 inst
.instruction
= T_OPCODE_MOV_I8
;
3989 inst
.instruction
= T_OPCODE_CMP_I8
;
3991 inst
.instruction
|= Rd
<< 8;
3993 if (inst
.reloc
.exp
.X_op
!= O_constant
)
3994 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_IMM
;
3997 unsigned value
= inst
.reloc
.exp
.X_add_number
;
4001 inst
.error
= "invalid immediate";
4005 inst
.instruction
|= value
;
4013 thumb_load_store (str
, load_store
, size
)
4018 int Rd
, Rb
, Ro
= FAIL
;
4023 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4024 || skip_past_comma (&str
) == FAIL
)
4027 inst
.error
= bad_args
;
4034 if ((Rb
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4037 if (skip_past_comma (&str
) != FAIL
)
4042 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4045 else if ((Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4050 inst
.reloc
.exp
.X_op
= O_constant
;
4051 inst
.reloc
.exp
.X_add_number
= 0;
4056 inst
.error
= "expected ']'";
4061 else if (*str
== '=')
4067 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4070 inst
.instruction
= T_OPCODE_LDR_PC
| (Rd
<< 8);
4071 inst
.reloc
.pc_rel
= 1;
4072 inst
.reloc
.exp
.X_add_number
-= 4; /* Pipeline offset */
4073 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4078 if (Rb
== REG_PC
|| Rb
== REG_SP
)
4080 if (size
!= THUMB_WORD
)
4082 inst
.error
= "byte or halfword not valid for base register";
4085 else if (Rb
== REG_PC
&& load_store
!= THUMB_LOAD
)
4087 inst
.error
= "R15 based store not allowed";
4090 else if (Ro
!= FAIL
)
4092 inst
.error
= "Invalid base register for register offset";
4097 inst
.instruction
= T_OPCODE_LDR_PC
;
4098 else if (load_store
== THUMB_LOAD
)
4099 inst
.instruction
= T_OPCODE_LDR_SP
;
4101 inst
.instruction
= T_OPCODE_STR_SP
;
4103 inst
.instruction
|= Rd
<< 8;
4104 if (inst
.reloc
.exp
.X_op
== O_constant
)
4106 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4108 if (offset
& ~0x3fc)
4110 inst
.error
= "invalid offset";
4114 inst
.instruction
|= offset
>> 2;
4117 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4121 inst
.error
= "invalid base register in load/store";
4124 else if (Ro
== FAIL
)
4126 /* Immediate offset */
4127 if (size
== THUMB_WORD
)
4128 inst
.instruction
= (load_store
== THUMB_LOAD
4129 ? T_OPCODE_LDR_IW
: T_OPCODE_STR_IW
);
4130 else if (size
== THUMB_HALFWORD
)
4131 inst
.instruction
= (load_store
== THUMB_LOAD
4132 ? T_OPCODE_LDR_IH
: T_OPCODE_STR_IH
);
4134 inst
.instruction
= (load_store
== THUMB_LOAD
4135 ? T_OPCODE_LDR_IB
: T_OPCODE_STR_IB
);
4137 inst
.instruction
|= Rd
| (Rb
<< 3);
4139 if (inst
.reloc
.exp
.X_op
== O_constant
)
4141 unsigned offset
= inst
.reloc
.exp
.X_add_number
;
4143 if (offset
& ~(0x1f << size
))
4145 inst
.error
= "Invalid offset";
4148 inst
.instruction
|= offset
<< 6;
4151 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_OFFSET
;
4155 /* Register offset */
4156 if (size
== THUMB_WORD
)
4157 inst
.instruction
= (load_store
== THUMB_LOAD
4158 ? T_OPCODE_LDR_RW
: T_OPCODE_STR_RW
);
4159 else if (size
== THUMB_HALFWORD
)
4160 inst
.instruction
= (load_store
== THUMB_LOAD
4161 ? T_OPCODE_LDR_RH
: T_OPCODE_STR_RH
);
4163 inst
.instruction
= (load_store
== THUMB_LOAD
4164 ? T_OPCODE_LDR_RB
: T_OPCODE_STR_RB
);
4166 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4172 /* Handle the Format 4 instructions that do not have equivalents in other
4173 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4184 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4187 if (skip_past_comma (&str
) == FAIL
4188 || (Rs
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4191 inst
.error
= bad_args
;
4195 if (skip_past_comma (&str
) != FAIL
)
4197 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4198 (It isn't allowed for CMP either, but that isn't handled by this
4200 if (inst
.instruction
== T_OPCODE_TST
4201 || inst
.instruction
== T_OPCODE_CMN
4202 || inst
.instruction
== T_OPCODE_NEG
4203 || inst
.instruction
== T_OPCODE_MVN
)
4205 inst
.error
= bad_args
;
4209 if ((Rn
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4214 inst
.error
= "dest and source1 one must be the same register";
4220 if (inst
.instruction
== T_OPCODE_MUL
4222 as_tsktsk ("Rs and Rd must be different in MUL");
4224 inst
.instruction
|= Rd
| (Rs
<< 3);
4232 thumb_add_sub (str
, 0);
4239 thumb_shift (str
, THUMB_ASR
);
4246 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4248 inst
.reloc
.type
= BFD_RELOC_ARM_PCREL_BRANCH
;
4249 inst
.reloc
.pc_rel
= 1;
4262 if ((reg
= thumb_reg (&str
, THUMB_REG_ANY
)) == FAIL
)
4265 /* This sets THUMB_H2 from the top bit of reg. */
4266 inst
.instruction
|= reg
<< 3;
4268 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4269 should cause the alignment to be checked once it is known. This is
4270 because BX PC only works if the instruction is word aligned. */
4279 thumb_mov_compare (str
, THUMB_COMPARE
);
4292 if ((Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
)
4296 as_warn ("Inserted missing '!': load/store multiple always writes back base register");
4300 if (skip_past_comma (&str
) == FAIL
4301 || (range
= reg_list (&str
)) == FAIL
)
4304 inst
.error
= bad_args
;
4308 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4310 /* This really doesn't seem worth it. */
4311 inst
.reloc
.type
= BFD_RELOC_NONE
;
4312 inst
.error
= "Expression too complex";
4318 inst
.error
= "only lo-regs valid in load/store multiple";
4322 inst
.instruction
|= (Rb
<< 8) | range
;
4330 thumb_load_store (str
, THUMB_LOAD
, THUMB_WORD
);
4337 thumb_load_store (str
, THUMB_LOAD
, THUMB_BYTE
);
4344 thumb_load_store (str
, THUMB_LOAD
, THUMB_HALFWORD
);
4356 if ((Rd
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4357 || skip_past_comma (&str
) == FAIL
4359 || (Rb
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4360 || skip_past_comma (&str
) == FAIL
4361 || (Ro
= thumb_reg (&str
, THUMB_REG_LO
)) == FAIL
4365 inst
.error
= "Syntax: ldrs[b] Rd, [Rb, Ro]";
4369 inst
.instruction
|= Rd
| (Rb
<< 3) | (Ro
<< 6);
4377 thumb_shift (str
, THUMB_LSL
);
4384 thumb_shift (str
, THUMB_LSR
);
4391 thumb_mov_compare (str
, THUMB_MOVE
);
4403 if ((range
= reg_list (&str
)) == FAIL
)
4406 inst
.error
= bad_args
;
4410 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
4412 /* This really doesn't seem worth it. */
4413 inst
.reloc
.type
= BFD_RELOC_NONE
;
4414 inst
.error
= "Expression too complex";
4420 if ((inst
.instruction
== T_OPCODE_PUSH
4421 && (range
& ~0xff) == 1 << REG_LR
)
4422 || (inst
.instruction
== T_OPCODE_POP
4423 && (range
& ~0xff) == 1 << REG_PC
))
4425 inst
.instruction
|= THUMB_PP_PC_LR
;
4430 inst
.error
= "invalid register list to push/pop instruction";
4435 inst
.instruction
|= range
;
4443 thumb_load_store (str
, THUMB_STORE
, THUMB_WORD
);
4450 thumb_load_store (str
, THUMB_STORE
, THUMB_BYTE
);
4457 thumb_load_store (str
, THUMB_STORE
, THUMB_HALFWORD
);
4464 thumb_add_sub (str
, 1);
4474 if (my_get_expression (&inst
.reloc
.exp
, &str
))
4477 inst
.reloc
.type
= BFD_RELOC_ARM_SWI
;
4486 /* This is a pseudo-op of the form "adr rd, label" to be converted
4487 into a relative address of the form "add rd, pc, #label-.-8" */
4491 if (reg_required_here (&str
, 8) == FAIL
4492 || skip_past_comma (&str
) == FAIL
4493 || my_get_expression (&inst
.reloc
.exp
, &str
))
4496 inst
.error
= bad_args
;
4500 inst
.reloc
.type
= BFD_RELOC_ARM_THUMB_ADD
;
4501 inst
.reloc
.exp
.X_add_number
-= 8; /* PC relative adjust */
4502 inst
.reloc
.pc_rel
= 1;
4503 inst
.instruction
|= REG_PC
; /* Rd is already placed into the instruction */
4511 int len
= strlen (reg_table
[entry
].name
) + 2;
4512 char *buf
= (char *) xmalloc (len
);
4513 char *buf2
= (char *) xmalloc (len
);
4516 #ifdef REGISTER_PREFIX
4517 buf
[i
++] = REGISTER_PREFIX
;
4520 strcpy (buf
+ i
, reg_table
[entry
].name
);
4522 for (i
= 0; buf
[i
]; i
++)
4523 buf2
[i
] = islower (buf
[i
]) ? toupper (buf
[i
]) : buf
[i
];
4527 hash_insert (arm_reg_hsh
, buf
, (PTR
) ®_table
[entry
]);
4528 hash_insert (arm_reg_hsh
, buf2
, (PTR
) ®_table
[entry
]);
4532 insert_reg_alias (str
, regnum
)
4536 struct reg_entry
*new =
4537 (struct reg_entry
*)xmalloc (sizeof (struct reg_entry
));
4538 char *name
= xmalloc (strlen (str
) + 1);
4542 new->number
= regnum
;
4544 hash_insert (arm_reg_hsh
, name
, (PTR
) new);
4548 set_constant_flonums ()
4552 for (i
= 0; i
< NUM_FLOAT_VALS
; i
++)
4553 if (atof_ieee ((char *)fp_const
[i
], 'x', fp_values
[i
]) == NULL
)
4562 if ((arm_ops_hsh
= hash_new ()) == NULL
4563 || (arm_tops_hsh
= hash_new ()) == NULL
4564 || (arm_cond_hsh
= hash_new ()) == NULL
4565 || (arm_shift_hsh
= hash_new ()) == NULL
4566 || (arm_reg_hsh
= hash_new ()) == NULL
4567 || (arm_psr_hsh
= hash_new ()) == NULL
)
4568 as_fatal ("Virtual memory exhausted");
4570 for (i
= 0; i
< sizeof (insns
) / sizeof (struct asm_opcode
); i
++)
4571 hash_insert (arm_ops_hsh
, insns
[i
].template, (PTR
) (insns
+ i
));
4572 for (i
= 0; i
< sizeof (tinsns
) / sizeof (struct thumb_opcode
); i
++)
4573 hash_insert (arm_tops_hsh
, tinsns
[i
].template, (PTR
) (tinsns
+ i
));
4574 for (i
= 0; i
< sizeof (conds
) / sizeof (struct asm_cond
); i
++)
4575 hash_insert (arm_cond_hsh
, conds
[i
].template, (PTR
) (conds
+ i
));
4576 for (i
= 0; i
< sizeof (shift
) / sizeof (struct asm_shift
); i
++)
4577 hash_insert (arm_shift_hsh
, shift
[i
].template, (PTR
) (shift
+ i
));
4578 for (i
= 0; i
< sizeof (psrs
) / sizeof (struct asm_psr
); i
++)
4579 hash_insert (arm_psr_hsh
, psrs
[i
].template, (PTR
) (psrs
+ i
));
4581 for (i
= 0; reg_table
[i
].name
; i
++)
4584 set_constant_flonums ();
4587 /* Set the flags in the private structure */
4588 coff_arm_bfd_set_private_flags (stdoutput
, uses_apcs_26
? F_APCS26
: 0);
4594 /* Record the CPU type as well */
4595 switch (cpu_variant
& ARM_CPU_MASK
)
4598 mach
= bfd_mach_arm_2
;
4601 case ARM_3
: /* also ARM_250 */
4602 mach
= bfd_mach_arm_2a
;
4606 case ARM_6
| ARM_3
| ARM_2
: /* Actually no CPU type defined */
4607 case ARM_7
: /* also ARM_6 */
4608 mach
= bfd_mach_arm_3
;
4612 /* Catch special cases */
4613 if (cpu_variant
& ARM_THUMB
)
4614 mach
= bfd_mach_arm_4T
;
4615 else if (cpu_variant
& ARM_LONGMUL
)
4616 mach
= bfd_mach_arm_3M
;
4617 else if (cpu_variant
& ARM_ARCH4
)
4618 mach
= bfd_mach_arm_4
;
4620 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach
);
4624 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4625 for use in the a.out file, and stores them in the array pointed to by buf.
4626 This knows about the endian-ness of the target machine and does
4627 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4628 2 (short) and 4 (long) Floating numbers are put out as a series of
4629 LITTLENUMS (shorts, here at least)
4632 md_number_to_chars (buf
, val
, n
)
4637 if (target_big_endian
)
4638 number_to_chars_bigendian (buf
, val
, n
);
4640 number_to_chars_littleendian (buf
, val
, n
);
4644 md_chars_to_number (buf
, n
)
4649 unsigned char *where
= (unsigned char *) buf
;
4651 if (target_big_endian
)
4656 result
|= (*where
++ & 255);
4664 result
|= (where
[n
] & 255);
4671 /* Turn a string in input_line_pointer into a floating point constant
4672 of type TYPE, and store the appropriate bytes in *litP. The number
4673 of LITTLENUMS emitted is stored in *sizeP . An error message is
4674 returned, or NULL on OK.
4676 Note that fp constants aren't represent in the normal way on the ARM.
4677 In big endian mode, things are as expected. However, in little endian
4678 mode fp constants are big-endian word-wise, and little-endian byte-wise
4679 within the words. For example, (double) 1.1 in big endian mode is
4680 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4681 the byte sequence 99 99 f1 3f 9a 99 99 99.
4683 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
4686 md_atof (type
, litP
, sizeP
)
4692 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
4724 return "Bad call to MD_ATOF()";
4727 t
= atof_ieee (input_line_pointer
, type
, words
);
4729 input_line_pointer
= t
;
4732 if (target_big_endian
)
4734 for (i
= 0; i
< prec
; i
++)
4736 md_number_to_chars (litP
, (valueT
) words
[i
], 2);
4742 /* For a 4 byte float the order of elements in `words' is 1 0. For an
4743 8 byte float the order is 1 0 3 2. */
4744 for (i
= 0; i
< prec
; i
+= 2)
4746 md_number_to_chars (litP
, (valueT
) words
[i
+ 1], 2);
4747 md_number_to_chars (litP
+ 2, (valueT
) words
[i
], 2);
4755 /* We have already put the pipeline compensation in the instruction */
4758 md_pcrel_from (fixP
)
4761 if (fixP
->fx_addsy
&& S_GET_SEGMENT (fixP
->fx_addsy
) == undefined_section
4762 && fixP
->fx_subsy
== NULL
)
4763 return 0; /* HACK */
4765 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
4768 /* Round up a section size to the appropriate boundary. */
4770 md_section_align (segment
, size
)
4774 /* Round all sects to multiple of 4 */
4775 return (size
+ 3) & ~3;
4778 /* We have no need to default values of symbols. */
4782 md_undefined_symbol (name
)
4788 /* arm_reg_parse () := if it looks like a register, return its token and
4789 advance the pointer. */
4793 register char **ccp
;
4798 struct reg_entry
*reg
;
4800 #ifdef REGISTER_PREFIX
4801 if (*start
!= REGISTER_PREFIX
)
4806 #ifdef OPTIONAL_REGISTER_PREFIX
4807 if (*p
== OPTIONAL_REGISTER_PREFIX
)
4811 if (!isalpha (*p
) || !is_name_beginner (*p
))
4815 while (isalpha (c
) || isdigit (c
) || c
== '_')
4819 reg
= (struct reg_entry
*) hash_find (arm_reg_hsh
, start
);
4833 register char **ccp
;
4837 CONST
struct asm_psr
*psr
;
4841 while (isalpha (c
) || c
== '_')
4845 psr
= (CONST
struct asm_psr
*) hash_find (arm_psr_hsh
, start
);
4858 md_apply_fix3 (fixP
, val
, seg
)
4863 offsetT value
= *val
;
4864 offsetT newval
, temp
;
4866 char *buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
4867 arm_fix_data
*arm_data
= (arm_fix_data
*) fixP
->tc_fix_data
;
4869 assert (fixP
->fx_r_type
< BFD_RELOC_UNUSED
);
4871 /* Note whether this will delete the relocation. */
4872 if (fixP
->fx_addsy
== 0 && !fixP
->fx_pcrel
)
4875 /* If this symbol is in a different section then we need to leave it for
4876 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
4877 so we have to undo it's effects here. */
4880 if (S_IS_DEFINED (fixP
->fx_addsy
)
4881 && S_GET_SEGMENT (fixP
->fx_addsy
) != seg
)
4882 value
+= md_pcrel_from (fixP
);
4885 fixP
->fx_addnumber
= value
; /* Remember value for emit_reloc */
4887 switch (fixP
->fx_r_type
)
4889 case BFD_RELOC_ARM_IMMEDIATE
:
4890 newval
= validate_immediate (value
);
4891 temp
= md_chars_to_number (buf
, INSN_SIZE
);
4893 /* If the instruction will fail, see if we can fix things up by
4894 changing the opcode. */
4896 && (newval
= negate_data_op (&temp
, value
)) == FAIL
)
4898 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4899 "invalid constant after fixup\n");
4903 newval
|= (temp
& 0xfffff000);
4904 md_number_to_chars (buf
, newval
, INSN_SIZE
);
4907 case BFD_RELOC_ARM_OFFSET_IMM
:
4909 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
4911 as_bad ("bad immediate value for offset (%d)", val
);
4917 newval
= md_chars_to_number (buf
, INSN_SIZE
);
4918 newval
&= 0xff7ff000;
4919 newval
|= value
| (sign
? INDEX_UP
: 0);
4920 md_number_to_chars (buf
, newval
, INSN_SIZE
);
4923 case BFD_RELOC_ARM_OFFSET_IMM8
:
4924 case BFD_RELOC_ARM_HWLITERAL
:
4926 if ((value
= validate_offset_imm (value
, 1)) == FAIL
)
4928 if (fixP
->fx_r_type
== BFD_RELOC_ARM_HWLITERAL
)
4929 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4930 "invalid literal constant: pool needs to be closer\n");
4932 as_bad ("bad immediate value for offset (%d)", value
);
4939 newval
= md_chars_to_number (buf
, INSN_SIZE
);
4940 newval
&= 0xff7ff0f0;
4941 newval
|= ((value
>> 4) << 8) | value
& 0xf | (sign
? INDEX_UP
: 0);
4942 md_number_to_chars (buf
, newval
, INSN_SIZE
);
4945 case BFD_RELOC_ARM_LITERAL
:
4950 if ((value
= validate_offset_imm (value
, 0)) == FAIL
)
4952 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4953 "invalid literal constant: pool needs to be closer\n");
4957 newval
= md_chars_to_number (buf
, INSN_SIZE
);
4958 newval
&= 0xff7ff000;
4959 newval
|= value
| (sign
? INDEX_UP
: 0);
4960 md_number_to_chars (buf
, newval
, INSN_SIZE
);
4963 case BFD_RELOC_ARM_SHIFT_IMM
:
4964 newval
= md_chars_to_number (buf
, INSN_SIZE
);
4965 if (((unsigned long) value
) > 32
4967 && (((newval
& 0x60) == 0) || (newval
& 0x60) == 0x60)))
4969 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4970 "shift expression is too large");
4975 newval
&= ~0x60; /* Shifts of zero must be done as lsl */
4976 else if (value
== 32)
4978 newval
&= 0xfffff07f;
4979 newval
|= (value
& 0x1f) << 7;
4980 md_number_to_chars (buf
, newval
, INSN_SIZE
);
4983 case BFD_RELOC_ARM_SWI
:
4984 if (arm_data
->thumb_mode
)
4986 if (((unsigned long) value
) > 0xff)
4987 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4988 "Invalid swi expression");
4989 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xff00;
4991 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
4995 if (((unsigned long) value
) > 0x00ffffff)
4996 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
4997 "Invalid swi expression");
4998 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff000000;
5000 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5004 case BFD_RELOC_ARM_MULTI
:
5005 if (((unsigned long) value
) > 0xffff)
5006 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5007 "Invalid expression in load/store multiple");
5008 newval
= value
| md_chars_to_number (buf
, INSN_SIZE
);
5009 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5012 case BFD_RELOC_ARM_PCREL_BRANCH
:
5013 if (arm_data
->thumb_mode
)
5015 unsigned long newval2
;
5016 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5017 if (fixP
->fx_size
== 4)
5021 newval2
= md_chars_to_number (buf
, THUMB_SIZE
);
5022 diff
= ((newval
& 0x7ff) << 12) | ((newval2
& 0x7ff) << 1);
5023 if (diff
& 0x400000)
5026 if ((value
& 0x400000) && ((value
& ~0x3fffff) != ~0x3fffff))
5027 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5028 "Branch with link out of range");
5030 newval
= (newval
& 0xf800) | ((value
& 0x7fffff) >> 12);
5031 newval2
= (newval2
& 0xf800) | ((value
& 0xfff) >> 1);
5032 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5033 md_number_to_chars (buf
, newval2
, THUMB_SIZE
);
5037 if (newval
== T_OPCODE_BRANCH
)
5039 unsigned long diff
= (newval
& 0x7ff) << 1;
5044 if ((value
& 0x800) && ((value
& ~0x7ff) != ~0x7ff))
5045 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5046 "Branch out of range");
5047 newval
= (newval
& 0xf800) | ((value
& 0xfff) >> 1);
5051 unsigned long diff
= (newval
& 0xff) << 1;
5056 if ((value
& 0x100) && ((value
& ~0xff) != ~0xff))
5057 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5058 "Branch out of range");
5059 newval
= (newval
& 0xff00) | ((value
& 0x1ff) >> 1);
5061 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5066 value
= (value
>> 2) & 0x00ffffff;
5067 newval
= md_chars_to_number (buf
, INSN_SIZE
);
5068 value
= (value
+ (newval
& 0x00ffffff)) & 0x00ffffff;
5069 newval
= value
| (newval
& 0xff000000);
5070 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5075 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5076 md_number_to_chars (buf
, value
, 1);
5080 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5081 md_number_to_chars (buf
, value
, 2);
5086 if (fixP
->fx_done
|| fixP
->fx_pcrel
)
5087 md_number_to_chars (buf
, value
, 4);
5090 case BFD_RELOC_ARM_CP_OFF_IMM
:
5092 if (value
< -1023 || value
> 1023 || (value
& 3))
5093 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5094 "Illegal value for co-processor offset");
5097 newval
= md_chars_to_number (buf
, INSN_SIZE
) & 0xff7fff00;
5098 newval
|= (value
>> 2) | (sign
? INDEX_UP
: 0);
5099 md_number_to_chars (buf
, newval
, INSN_SIZE
);
5102 case BFD_RELOC_ARM_THUMB_OFFSET
:
5103 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5104 /* Exactly what ranges, and where the offset is inserted depends on
5105 the type of instruction, we can establish this from the top 4 bits */
5106 switch (newval
>> 12)
5108 case 4: /* PC load */
5109 /* PC loads are somewhat odd, bit 2 of the PC is forced to zero
5110 for these loads, so we may need to round up the offset if the
5111 instruction is not word aligned since the final address must
5114 if ((fixP
->fx_frag
->fr_address
+ fixP
->fx_where
+ value
) & 3)
5115 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5116 "Invalid offset, target not word aligned");
5118 if ((value
+ 2) & ~0x3fe)
5119 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5121 /* Round up, since pc will be rounded down. */
5122 newval
|= (value
+ 2) >> 2;
5125 case 9: /* SP load/store */
5127 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5129 newval
|= value
>> 2;
5132 case 6: /* Word load/store */
5134 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5136 newval
|= value
<< 4; /* 6 - 2 */
5139 case 7: /* Byte load/store */
5141 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5143 newval
|= value
<< 6;
5146 case 8: /* Halfword load/store */
5148 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5150 newval
|= value
<< 5; /* 6 - 1 */
5156 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5159 case BFD_RELOC_ARM_THUMB_ADD
:
5160 /* This is a complicated relocation, since we use it for all of
5161 the following immediate relocations:
5164 9bit ADD/SUB SP word-aligned
5165 10bit ADD PC/SP word-aligned
5167 The type of instruction being processed is encoded in the
5173 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5175 int rd
= (newval
>> 4) & 0xf;
5176 int rs
= newval
& 0xf;
5177 int subtract
= newval
& 0x8000;
5182 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5183 "Invalid immediate for stack address calculation");
5184 newval
= subtract
? T_OPCODE_SUB_ST
: T_OPCODE_ADD_ST
;
5185 newval
|= value
>> 2;
5187 else if (rs
== REG_PC
|| rs
== REG_SP
)
5191 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5192 "Invalid immediate for address calculation (value = 0x%08X)", value
);
5193 newval
= (rs
== REG_PC
? T_OPCODE_ADD_PC
: T_OPCODE_ADD_SP
);
5194 newval
|= value
>> 2;
5199 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5200 "Invalid 8bit immediate");
5201 newval
= subtract
? T_OPCODE_SUB_I8
: T_OPCODE_ADD_I8
;
5202 newval
|= (rd
<< 8) | value
;
5207 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5208 "Invalid 3bit immediate");
5209 newval
= subtract
? T_OPCODE_SUB_I3
: T_OPCODE_ADD_I3
;
5210 newval
|= rd
| (rs
<< 3) | (value
<< 6);
5213 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5216 case BFD_RELOC_ARM_THUMB_IMM
:
5217 newval
= md_chars_to_number (buf
, THUMB_SIZE
);
5218 switch (newval
>> 11)
5220 case 0x04: /* 8bit immediate MOV */
5221 case 0x05: /* 8bit immediate CMP */
5222 if (value
< 0 || value
> 255)
5223 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5224 "Invalid immediate: %d is too large", value
);
5231 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5234 case BFD_RELOC_ARM_THUMB_SHIFT
:
5235 /* 5bit shift value (0..31) */
5236 if (value
< 0 || value
> 31)
5237 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5238 "Illegal Thumb shift value: %d", value
);
5239 newval
= md_chars_to_number (buf
, THUMB_SIZE
) & 0xf03f;
5240 newval
|= value
<< 6;
5241 md_number_to_chars (buf
, newval
, THUMB_SIZE
);
5244 case BFD_RELOC_NONE
:
5246 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
5247 "Bad relocation fixup type (%d)\n", fixP
->fx_r_type
);
5253 /* Translate internal representation of relocation info to BFD target
5256 tc_gen_reloc (section
, fixp
)
5261 bfd_reloc_code_real_type code
;
5263 reloc
= (arelent
*) xmalloc (sizeof (arelent
));
5265 reloc
->sym_ptr_ptr
= &fixp
->fx_addsy
->bsym
;
5266 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
5268 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5269 if (fixp
->fx_pcrel
== 0)
5270 reloc
->addend
= fixp
->fx_offset
;
5272 reloc
->addend
= fixp
->fx_offset
= reloc
->address
;
5274 switch (fixp
->fx_r_type
)
5279 code
= BFD_RELOC_8_PCREL
;
5286 code
= BFD_RELOC_16_PCREL
;
5293 code
= BFD_RELOC_32_PCREL
;
5297 case BFD_RELOC_ARM_PCREL_BRANCH
:
5299 code
= fixp
->fx_r_type
;
5302 case BFD_RELOC_ARM_LITERAL
:
5303 case BFD_RELOC_ARM_HWLITERAL
:
5304 /* If this is called then the a literal has been referenced across
5305 a section boundry - possibly due to an implicit dump */
5306 as_bad ("Literal referenced across section boundry (Implicit dump?)");
5309 case BFD_RELOC_ARM_IMMEDIATE
:
5310 as_bad ("Internal_relocation (type %d) not fixed up (IMMEDIATE)"
5314 case BFD_RELOC_ARM_OFFSET_IMM
:
5315 as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"
5319 case BFD_RELOC_ARM_OFFSET_IMM8
:
5320 as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM8)"
5324 case BFD_RELOC_ARM_SHIFT_IMM
:
5325 as_bad ("Internal_relocation (type %d) not fixed up (SHIFT_IMM)"
5329 case BFD_RELOC_ARM_SWI
:
5330 as_bad ("Internal_relocation (type %d) not fixed up (SWI)"
5334 case BFD_RELOC_ARM_MULTI
:
5335 as_bad ("Internal_relocation (type %d) not fixed up (MULTI)"
5339 case BFD_RELOC_ARM_CP_OFF_IMM
:
5340 as_bad ("Internal_relocation (type %d) not fixed up (CP_OFF_IMM)"
5344 case BFD_RELOC_ARM_THUMB_OFFSET
:
5345 as_bad ("Internal_relocation (type %d) not fixed up (THUMB_OFFSET)"
5353 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
5354 assert (reloc
->howto
!= 0);
5359 CONST
int md_short_jump_size
= 4;
5360 CONST
int md_long_jump_size
= 4;
5362 /* These should never be called on the arm */
5364 md_create_long_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
5366 addressT from_addr
, to_addr
;
5370 as_fatal ("md_create_long_jump\n");
5374 md_create_short_jump (ptr
, from_addr
, to_addr
, frag
, to_symbol
)
5376 addressT from_addr
, to_addr
;
5380 as_fatal ("md_create_short_jump\n");
5384 md_estimate_size_before_relax (fragP
, segtype
)
5388 as_fatal ("md_estimate_size_before_relax\n");
5400 as_bad ("%s -- statement `%s'\n", inst
.error
, str
);
5404 to
= frag_more (inst
.size
);
5405 if (thumb_mode
&& (inst
.size
> 2))
5407 md_number_to_chars (to
, inst
.instruction
>> 16, 2);
5412 md_number_to_chars (to
, inst
.instruction
, inst
.size
);
5414 if (inst
.reloc
.type
!= BFD_RELOC_NONE
)
5415 fix_new_arm (frag_now
, to
- frag_now
->fr_literal
,
5416 inst
.size
, &inst
.reloc
.exp
, inst
.reloc
.pc_rel
,
5427 char *p
, *q
, *start
;
5429 /* Align the instruction */
5430 /* this may not be the right thing to do but ... */
5431 /* arm_align (2, 0); */
5432 listing_prev_line (); /* Defined in listing.h */
5434 /* Align the previous label if needed */
5435 if (last_label_seen
!= NULL
)
5437 last_label_seen
->sy_frag
= frag_now
;
5438 S_SET_VALUE (last_label_seen
, (valueT
) frag_now_fix ());
5439 S_SET_SEGMENT (last_label_seen
, now_seg
);
5442 memset (&inst
, '\0', sizeof (inst
));
5443 inst
.reloc
.type
= BFD_RELOC_NONE
;
5446 str
++; /* Skip leading white space */
5448 /* scan up to the end of the op-code, which must end in white space or
5450 for (start
= p
= str
; *p
!= '\0'; p
++)
5456 as_bad ("No operator -- statement `%s'\n", str
);
5462 CONST
struct thumb_opcode
*opcode
;
5466 opcode
= (CONST
struct thumb_opcode
*) hash_find (arm_tops_hsh
, str
);
5470 inst
.instruction
= opcode
->value
;
5471 inst
.size
= opcode
->size
;
5472 (*opcode
->parms
)(p
);
5473 output_inst (start
);
5479 CONST
struct asm_opcode
*opcode
;
5481 inst
.size
= INSN_SIZE
;
5482 /* p now points to the end of the opcode, probably white space, but we
5483 have to break the opcode up in case it contains condionals and flags;
5484 keep trying with progressively smaller basic instructions until one
5485 matches, or we run out of opcode. */
5486 q
= (p
- str
> LONGEST_INST
) ? str
+ LONGEST_INST
: p
;
5487 for (; q
!= str
; q
--)
5491 opcode
= (CONST
struct asm_opcode
*) hash_find (arm_ops_hsh
, str
);
5493 if (opcode
&& opcode
->template)
5495 unsigned long flag_bits
= 0;
5498 /* Check that this instruction is supported for this CPU */
5499 if ((opcode
->variants
& cpu_variant
) == 0)
5502 inst
.instruction
= opcode
->value
;
5503 if (q
== p
) /* Just a simple opcode */
5505 if (opcode
->comp_suffix
!= 0)
5506 as_bad ("Opcode `%s' must have suffix from <%s>\n", str
,
5507 opcode
->comp_suffix
);
5510 inst
.instruction
|= COND_ALWAYS
;
5511 (*opcode
->parms
)(q
, 0);
5513 output_inst (start
);
5517 /* Now check for a conditional */
5521 CONST
struct asm_cond
*cond
;
5525 cond
= (CONST
struct asm_cond
*) hash_find (arm_cond_hsh
, r
);
5529 if (cond
->value
== 0xf0000000)
5531 "Warning: Use of the 'nv' conditional is deprecated\n");
5533 inst
.instruction
|= cond
->value
;
5537 inst
.instruction
|= COND_ALWAYS
;
5540 inst
.instruction
|= COND_ALWAYS
;
5542 /* if there is a compulsory suffix, it should come here, before
5543 any optional flags. */
5544 if (opcode
->comp_suffix
)
5546 CONST
char *s
= opcode
->comp_suffix
;
5558 as_bad ("Opcode `%s' must have suffix from <%s>\n", str
,
5559 opcode
->comp_suffix
);
5566 /* The remainder, if any should now be flags for the instruction;
5567 Scan these checking each one found with the opcode. */
5571 CONST
struct asm_flg
*flag
= opcode
->flags
;
5580 for (flagno
= 0; flag
[flagno
].template; flagno
++)
5582 if (! strcmp (r
, flag
[flagno
].template))
5584 flag_bits
|= flag
[flagno
].set_bits
;
5590 if (! flag
[flagno
].template)
5597 (*opcode
->parms
) (p
, flag_bits
);
5598 output_inst (start
);
5607 /* It wasn't an instruction, but it might be a register alias of the form
5617 if (*q
&& !strncmp (q
, ".req ", 4))
5620 if ((reg
= arm_reg_parse (&str
)) == FAIL
)
5628 for (r
= q
; *r
!= '\0'; r
++)
5638 regnum
= arm_reg_parse (&q
);
5642 insert_reg_alias (str
, regnum
);
5656 as_bad ("bad instruction `%s'", start
);
5661 * Invocation line includes a switch not recognized by the base assembler.
5662 * See if it's a processor-specific option. These are:
5663 * Cpu variants, the arm part is optional:
5664 * -m[arm]1 Currently not supported.
5665 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
5666 * -m[arm]3 Arm 3 processor
5667 * -m[arm]6, Arm 6 processors
5668 * -m[arm]7[t][[d]m] Arm 7 processors
5669 * -mall All (except the ARM1)
5671 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
5672 * -mfpe-old (No float load/store multiples)
5673 * -mno-fpu Disable all floating point instructions
5674 * Run-time endian selection:
5675 * -EB big endian cpu
5676 * -EL little endian cpu
5677 * ARM Procedure Calling Standard:
5678 * -mapcs-32 32 bit APCS
5679 * -mapcs-26 26 bit APCS
5682 CONST
char *md_shortopts
= "m:";
5683 struct option md_longopts
[] =
5685 #ifdef ARM_BI_ENDIAN
5686 #define OPTION_EB (OPTION_MD_BASE + 0)
5687 {"EB", no_argument
, NULL
, OPTION_EB
},
5688 #define OPTION_EL (OPTION_MD_BASE + 1)
5689 {"EL", no_argument
, NULL
, OPTION_EL
},
5691 {NULL
, no_argument
, NULL
, 0}
5693 size_t md_longopts_size
= sizeof (md_longopts
);
5696 md_parse_option (c
, arg
)
5704 #ifdef ARM_BI_ENDIAN
5706 target_big_endian
= 1;
5709 target_big_endian
= 0;
5717 if (! strcmp (str
, "fpa10"))
5718 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA10
;
5719 else if (! strcmp (str
, "fpa11"))
5720 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_FPA11
;
5721 else if (! strcmp (str
, "fpe-old"))
5722 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_CORE
;
5728 if (! strcmp (str
, "no-fpu"))
5729 cpu_variant
&= ~FPU_ALL
;
5733 /* Limit assembler to generating only Thumb instructions: */
5734 if (! strcmp (str
, "thumb"))
5736 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_THUMB
;
5737 cpu_variant
= (cpu_variant
& ~FPU_ALL
) | FPU_NONE
;
5745 if (! strcmp (str
, "all"))
5747 cpu_variant
= ARM_ALL
| FPU_ALL
;
5750 else if (! strcmp( str
, "apcs-32" ))
5752 uses_apcs_26
= false;
5755 else if (! strcmp( str
, "apcs-26" ))
5757 uses_apcs_26
= true;
5761 /* Strip off optional "arm" */
5762 if (! strncmp (str
, "arm", 3))
5768 if (! strcmp (str
, "1"))
5769 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_1
;
5775 if (! strcmp (str
, "2"))
5776 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
;
5777 else if (! strcmp (str
, "250"))
5778 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_250
;
5784 if (! strcmp (str
, "3"))
5785 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
;
5791 if (! strcmp (str
, "6"))
5792 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_6
;
5798 str
++; /* eat the '7' */
5799 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
5805 cpu_variant
|= ARM_THUMB
;
5809 cpu_variant
|= ARM_LONGMUL
;
5812 case 'd': /* debug */
5813 case 'i': /* embedded ice */
5814 /* Included for completeness in ARM processor
5825 /* Select variant based on architecture rather than processor */
5831 case 'a': cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_3
; break;
5832 case 0: cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_2
; break;
5833 default: as_bad( "Invalid architecture variant -m%s", arg
); break;
5838 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
5842 case 'm': cpu_variant
|= ARM_LONGMUL
; break;
5844 default: as_bad( "Invalid architecture variant -m%s", arg
); break;
5849 cpu_variant
= (cpu_variant
& ~ARM_ANY
) | ARM_7
;
5853 case 't': cpu_variant
|= ARM_THUMB
; break;
5855 default: as_bad( "Invalid architecture variant -m%s", arg
); break;
5860 as_bad( "Invalid architecture variant -m%s", arg
);
5867 as_bad ("Invalid processor variant -m%s", arg
);
5885 "-m[arm][1|2|250|3|6|7[t][d][m][i]] select processor variant\n\
5886 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
5887 -mthumb\t\t\tonly allow Thumb instructions\n\
5888 -mall\t\t\tallow any instruction\n\
5889 -mfpa10, -mfpa11\tselect floating point architecture\n\
5890 -mfpe-old\t\tdon't allow floating-point multiple instructions\n\
5891 -mno-fpu\t\tdon't allow any floating-point instructions.\n\
5892 -mapcs-32, -mapcs-26\tspecify which ARM Procedure Calling Standard is in use\n");
5893 #ifdef ARM_BI_ENDIAN
5895 "-EB\t\t\tassemble code for a big endian cpu\n\
5896 -EL\t\t\tassemble code for a little endian cpu\n");
5900 /* We need to be able to fix up arbitrary expressions in some statements.
5901 This is so that we can handle symbols that are an arbitrary distance from
5902 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
5903 which returns part of an address in a form which will be valid for
5904 a data instruction. We do this by pushing the expression into a symbol
5905 in the expr_section, and creating a fix for that. */
5908 fix_new_arm (frag
, where
, size
, exp
, pc_rel
, reloc
)
5917 arm_fix_data
*arm_data
;
5925 new_fix
= fix_new_exp (frag
, where
, size
, exp
, pc_rel
, reloc
);
5929 new_fix
= fix_new (frag
, where
, size
, make_expr_symbol (exp
), 0,
5934 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
5935 arm_data
= (arm_fix_data
*) obstack_alloc (¬es
, sizeof (arm_fix_data
));
5936 new_fix
->tc_fix_data
= (PTR
) arm_data
;
5937 arm_data
->thumb_mode
= thumb_mode
;
5942 /* A good place to do this, although this was probably not intended
5943 * for this kind of use. We need to dump the literal pool before
5944 * references are made to a null symbol pointer. */
5946 arm_after_pass_hook (ignore
)
5949 if (current_poolP
!= NULL
)
5951 subseg_set (text_section
, 0); /* Put it at the end of text section */
5953 listing_prev_line ();
5958 arm_start_line_hook ()
5960 last_label_seen
= NULL
;
5964 arm_frob_label (sym
)
5967 last_label_seen
= sym
;
5973 if (thumb_mode
&& ! strncmp (input_line_pointer
+ 1, "data:", 5))
5975 *input_line_pointer
= '/';
5976 input_line_pointer
+= 5;
5977 *input_line_pointer
= 0;
5984 arm_canonicalize_symbol_name (name
)
5989 if (thumb_mode
&& (len
= strlen (name
)) > 5
5990 && ! strcmp (name
+ len
- 5, "/data"))
5992 *(name
+ len
- 5) = 0;