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 */
51 /* The following bitmasks control CPU extensions (ARM7 onwards): */
52 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
53 #define ARM_ARCH4 0x00000020
54 #define ARM_THUMB ARM_ARCH4
56 /* Some useful combinations: */
57 #define ARM_ANY 0x00ffffff
58 #define ARM_2UP 0x00fffffe
59 #define ARM_ALL ARM_2UP /* Not arm1 only */
60 #define ARM_3UP 0x00fffffc
61 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
63 #define FPU_CORE 0x80000000
64 #define FPU_FPA10 0x40000000
65 #define FPU_FPA11 0x40000000
68 /* Some useful combinations */
69 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
70 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
73 #define CPU_DEFAULT ARM_ALL
77 #define FPU_DEFAULT FPU_ALL
80 unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
82 /* This array holds the chars that always start a comment. If the
83 pre-processor is disabled, these aren't very useful */
84 CONST char comment_chars[] = "@";
86 /* This array holds the chars that only start a comment at the beginning of
87 a line. If the line seems to have the form '# 123 filename'
88 .line and .file directives will appear in the pre-processed output */
89 /* Note that input_file.c hand checks for '#' at the beginning of the
90 first line of the input file. This is because the compiler outputs
91 #NO_APP at the beginning of its output. */
92 /* Also note that comments like this one will always work. */
93 CONST char line_comment_chars[] = "#";
95 CONST char line_separator_chars[] = "";
97 /* Chars that can be used to separate mant from exp in floating point nums */
98 CONST char EXP_CHARS[] = "eE";
100 /* Chars that mean this number is a floating point constant */
104 CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
106 CONST int md_reloc_size = 8; /* Size of relocation record */
108 static int thumb_mode = 0; /* non-zero if assembling thumb instructions */
110 typedef struct arm_fix
118 unsigned long instruction;
123 bfd_reloc_code_real_type type;
133 CONST char *template;
137 static CONST struct asm_shift shift[] =
153 #define NO_SHIFT_RESTRICT 1
154 #define SHIFT_RESTRICT 0
156 #define NUM_FLOAT_VALS 8
158 CONST char *fp_const[] =
160 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
163 /* Number of littlenums required to hold an extended precision number */
164 #define MAX_LITTLENUMS 6
166 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
176 #define CP_T_X 0x00008000
177 #define CP_T_Y 0x00400000
178 #define CP_T_Pre 0x01000000
179 #define CP_T_UD 0x00800000
180 #define CP_T_WB 0x00200000
182 #define CONDS_BIT (0x00100000)
183 #define LOAD_BIT (0x00100000)
184 #define TRANS_BIT (0x00200000)
188 CONST char *template;
192 /* This is to save a hash look-up in the common case */
193 #define COND_ALWAYS 0xe0000000
195 static CONST struct asm_cond conds[] =
199 {"cs", 0x20000000}, {"hs", 0x20000000},
200 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
215 /* Warning: If the top bit of the set_bits is set, then the standard
216 instruction bitmask is ignored, and the new bitmask is taken from
220 CONST char *template; /* Basic flag string */
221 unsigned long set_bits; /* Bits to set */
224 static CONST struct asm_flg s_flag[] =
230 static CONST struct asm_flg ldr_flags[] =
234 {"bt", 0x00400000 | TRANS_BIT},
241 static CONST struct asm_flg str_flags[] =
245 {"bt", 0x00400000 | TRANS_BIT},
250 static CONST struct asm_flg byte_flag[] =
256 static CONST struct asm_flg cmp_flags[] =
263 static CONST struct asm_flg ldm_flags[] =
276 static CONST struct asm_flg stm_flags[] =
289 static CONST struct asm_flg lfm_flags[] =
296 static CONST struct asm_flg sfm_flags[] =
303 static CONST struct asm_flg round_flags[] =
311 /* The implementation of the FIX instruction is broken on some assemblers,
312 in that it accepts a precision specifier as well as a rounding specifier,
313 despite the fact that this is meaningless. To be more compatible, we
314 accept it as well, though of course it does not set any bits. */
315 static CONST struct asm_flg fix_flags[] =
332 static CONST struct asm_flg except_flag[] =
338 static CONST struct asm_flg cplong_flag[] =
346 CONST char *template;
347 unsigned long number;
350 #define PSR_ALL 0x00010000
352 static CONST struct asm_psr psrs[] =
365 /* Functions called by parser */
366 /* ARM instructions */
367 static void do_arit PARAMS ((char *operands, unsigned long flags));
368 static void do_cmp PARAMS ((char *operands, unsigned long flags));
369 static void do_mov PARAMS ((char *operands, unsigned long flags));
370 static void do_ldst PARAMS ((char *operands, unsigned long flags));
371 static void do_ldmstm PARAMS ((char *operands, unsigned long flags));
372 static void do_branch PARAMS ((char *operands, unsigned long flags));
373 static void do_swi PARAMS ((char *operands, unsigned long flags));
374 /* Pseudo Op codes */
375 static void do_adr PARAMS ((char *operands, unsigned long flags));
376 static void do_nop PARAMS ((char *operands, unsigned long flags));
378 static void do_mul PARAMS ((char *operands, unsigned long flags));
379 static void do_mla PARAMS ((char *operands, unsigned long flags));
381 static void do_swap PARAMS ((char *operands, unsigned long flags));
383 static void do_msr PARAMS ((char *operands, unsigned long flags));
384 static void do_mrs PARAMS ((char *operands, unsigned long flags));
386 static void do_mull PARAMS ((char *operands, unsigned long flags));
388 static void do_bx PARAMS ((char *operands, unsigned long flags));
390 /* Coprocessor Instructions */
391 static void do_cdp PARAMS ((char *operands, unsigned long flags));
392 static void do_lstc PARAMS ((char *operands, unsigned long flags));
393 static void do_co_reg PARAMS ((char *operands, unsigned long flags));
394 static void do_fp_ctrl PARAMS ((char *operands, unsigned long flags));
395 static void do_fp_ldst PARAMS ((char *operands, unsigned long flags));
396 static void do_fp_ldmstm PARAMS ((char *operands, unsigned long flags));
397 static void do_fp_dyadic PARAMS ((char *operands, unsigned long flags));
398 static void do_fp_monadic PARAMS ((char *operands, unsigned long flags));
399 static void do_fp_cmp PARAMS ((char *operands, unsigned long flags));
400 static void do_fp_from_reg PARAMS ((char *operands, unsigned long flags));
401 static void do_fp_to_reg PARAMS ((char *operands, unsigned long flags));
403 static void fix_new_arm PARAMS ((fragS *frag, int where,
404 short int size, expressionS *exp,
405 int pc_rel, int reloc));
406 static int arm_reg_parse PARAMS ((char **ccp));
407 static int arm_psr_parse PARAMS ((char **ccp));
409 /* ARM instructions take 4bytes in the object file, Thumb instructions
413 /* LONGEST_INST is the longest basic instruction name without conditions or
415 * ARM7M has 4 of length 5
418 #define LONGEST_INST 5
422 CONST char *template; /* Basic string to match */
423 unsigned long value; /* Basic instruction code */
424 CONST char *comp_suffix; /* Compulsory suffix that must follow conds */
425 CONST struct asm_flg *flags; /* Bits to toggle if flag 'n' set */
426 unsigned long variants; /* Which CPU variants this exists for */
427 void (*parms)(); /* Function to call to parse args */
430 static CONST struct asm_opcode insns[] =
432 /* ARM Instructions */
433 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
434 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
435 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
436 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
437 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
438 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
439 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
440 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
441 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
442 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
443 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
444 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
445 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
446 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
447 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
448 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
449 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
450 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
451 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
452 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
453 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
454 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
455 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
458 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
459 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
461 /* ARM 2 multiplies */
462 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
463 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
465 /* ARM 3 - swp instructions */
466 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
468 /* ARM 6 Coprocessor instructions */
469 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
470 {"msr", 0x0128f000, NULL, NULL, ARM_6UP, do_msr},
472 /* ARM 7M long multiplies - need signed/unsigned flags! */
473 {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull},
474 {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull},
475 {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull},
476 {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull},
478 /* ARM THUMB interworking */
479 {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx},
481 /* Floating point instructions */
482 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
483 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
484 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
485 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
486 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
487 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
488 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
489 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
490 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
491 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
492 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
493 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
494 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
495 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
496 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
497 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
498 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
499 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
500 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
501 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
502 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
503 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
504 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
505 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
506 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
507 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
508 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
509 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
510 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
511 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
512 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
513 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
514 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
515 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
516 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
517 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
518 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
519 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
520 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
521 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
522 be an optional suffix, but part of the instruction. To be compatible,
524 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
525 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
526 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
527 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
529 /* Generic copressor instructions */
530 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
531 {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc},
532 {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc},
533 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
534 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
537 /* defines for various bits that we will want to toggle */
539 #define INST_IMMEDIATE 0x02000000
540 #define OFFSET_REG 0x02000000
541 #define HWOFFSET_IMM 0x00400000
542 #define SHIFT_BY_REG 0x00000010
543 #define PRE_INDEX 0x01000000
544 #define INDEX_UP 0x00800000
545 #define WRITE_BACK 0x00200000
546 #define MULTI_SET_PSR 0x00400000
548 #define LITERAL_MASK 0xf000f000
549 #define COND_MASK 0xf0000000
550 #define OPCODE_MASK 0xfe1fffff
551 #define DATA_OP_SHIFT 21
553 /* Codes to distinguish the arithmetic instructions */
565 #define OPCODE_CMP 10
566 #define OPCODE_CMN 11
567 #define OPCODE_ORR 12
568 #define OPCODE_MOV 13
569 #define OPCODE_BIC 14
570 #define OPCODE_MVN 15
572 static void do_t_arit PARAMS ((char *operands));
573 static void do_t_add PARAMS ((char *operands));
574 static void do_t_asr PARAMS ((char *operands));
575 static void do_t_branch PARAMS ((char *operands));
576 static void do_t_bx PARAMS ((char *operands));
577 static void do_t_compare PARAMS ((char *operands));
578 static void do_t_ldmstm PARAMS ((char *operands));
579 static void do_t_ldr PARAMS ((char *operands));
580 static void do_t_ldrb PARAMS ((char *operands));
581 static void do_t_ldrh PARAMS ((char *operands));
582 static void do_t_lds PARAMS ((char *operands));
583 static void do_t_lsl PARAMS ((char *operands));
584 static void do_t_lsr PARAMS ((char *operands));
585 static void do_t_mov PARAMS ((char *operands));
586 static void do_t_push_pop PARAMS ((char *operands));
587 static void do_t_str PARAMS ((char *operands));
588 static void do_t_strb PARAMS ((char *operands));
589 static void do_t_strh PARAMS ((char *operands));
590 static void do_t_sub PARAMS ((char *operands));
591 static void do_t_swi PARAMS ((char *operands));
592 static void do_t_adr PARAMS ((char *operands));
594 #define T_OPCODE_MUL 0x4340
595 #define T_OPCODE_TST 0x4200
596 #define T_OPCODE_CMN 0x42c0
597 #define T_OPCODE_NEG 0x4240
598 #define T_OPCODE_MVN 0x43c0
600 #define T_OPCODE_ADD_R3 0x1800
601 #define T_OPCODE_SUB_R3 0x1a00
602 #define T_OPCODE_ADD_HI 0x4400
603 #define T_OPCODE_ADD_ST 0xb000
604 #define T_OPCODE_SUB_ST 0xb080
605 #define T_OPCODE_ADD_SP 0xa800
606 #define T_OPCODE_ADD_PC 0xa000
607 #define T_OPCODE_ADD_I8 0x3000
608 #define T_OPCODE_SUB_I8 0x3800
609 #define T_OPCODE_ADD_I3 0x1c00
610 #define T_OPCODE_SUB_I3 0x1e00
612 #define T_OPCODE_ASR_R 0x4100
613 #define T_OPCODE_LSL_R 0x4080
614 #define T_OPCODE_LSR_R 0x40c0
615 #define T_OPCODE_ASR_I 0x1000
616 #define T_OPCODE_LSL_I 0x0000
617 #define T_OPCODE_LSR_I 0x0800
619 #define T_OPCODE_MOV_I8 0x2000
620 #define T_OPCODE_CMP_I8 0x2800
621 #define T_OPCODE_CMP_LR 0x4280
622 #define T_OPCODE_MOV_HR 0x4600
623 #define T_OPCODE_CMP_HR 0x4500
625 #define T_OPCODE_LDR_PC 0x4800
626 #define T_OPCODE_LDR_SP 0x9800
627 #define T_OPCODE_STR_SP 0x9000
628 #define T_OPCODE_LDR_IW 0x6800
629 #define T_OPCODE_STR_IW 0x6000
630 #define T_OPCODE_LDR_IH 0x8800
631 #define T_OPCODE_STR_IH 0x8000
632 #define T_OPCODE_LDR_IB 0x7800
633 #define T_OPCODE_STR_IB 0x7000
634 #define T_OPCODE_LDR_RW 0x5800
635 #define T_OPCODE_STR_RW 0x5000
636 #define T_OPCODE_LDR_RH 0x5a00
637 #define T_OPCODE_STR_RH 0x5200
638 #define T_OPCODE_LDR_RB 0x5c00
639 #define T_OPCODE_STR_RB 0x5400
641 #define T_OPCODE_PUSH 0xb400
642 #define T_OPCODE_POP 0xbc00
644 #define T_OPCODE_BRANCH 0xe7fe
646 static int thumb_reg PARAMS ((char **str, int hi_lo));
648 #define THUMB_SIZE 2 /* Size of thumb instruction */
649 #define THUMB_REG_LO 0x1
650 #define THUMB_REG_HI 0x2
651 #define THUMB_REG_ANY 0x3
653 #define THUMB_H1 0x0080
654 #define THUMB_H2 0x0040
661 #define THUMB_COMPARE 1
664 #define THUMB_STORE 1
666 #define THUMB_PP_PC_LR 0x0100
668 /* These three are used for immediate shifts, do not alter */
670 #define THUMB_HALFWORD 1
675 CONST char *template; /* Basic string to match */
676 unsigned long value; /* Basic instruction code */
678 void (*parms)(); /* Function to call to parse args */
681 static CONST struct thumb_opcode tinsns[] =
683 {"adc", 0x4140, 2, do_t_arit},
684 {"add", 0x0000, 2, do_t_add},
685 {"and", 0x4000, 2, do_t_arit},
686 {"asr", 0x0000, 2, do_t_asr},
687 {"b", T_OPCODE_BRANCH, 2, do_t_branch},
688 {"beq", 0xd0fe, 2, do_t_branch},
689 {"bne", 0xd1fe, 2, do_t_branch},
690 {"bcs", 0xd2fe, 2, do_t_branch},
691 {"bhs", 0xd2fe, 2, do_t_branch},
692 {"bcc", 0xd3fe, 2, do_t_branch},
693 {"bul", 0xd3fe, 2, do_t_branch},
694 {"blo", 0xd3fe, 2, do_t_branch},
695 {"bmi", 0xd4fe, 2, do_t_branch},
696 {"bpl", 0xd5fe, 2, do_t_branch},
697 {"bvs", 0xd6fe, 2, do_t_branch},
698 {"bvc", 0xd7fe, 2, do_t_branch},
699 {"bhi", 0xd8fe, 2, do_t_branch},
700 {"bls", 0xd9fe, 2, do_t_branch},
701 {"bge", 0xdafe, 2, do_t_branch},
702 {"blt", 0xdbfe, 2, do_t_branch},
703 {"bgt", 0xdcfe, 2, do_t_branch},
704 {"ble", 0xddfe, 2, do_t_branch},
705 {"bic", 0x4380, 2, do_t_arit},
706 {"bl", 0xf7fffffe, 4, do_t_branch},
707 {"bx", 0x4700, 2, do_t_bx},
708 {"cmn", T_OPCODE_CMN, 2, do_t_arit},
709 {"cmp", 0x0000, 2, do_t_compare},
710 {"eor", 0x4040, 2, do_t_arit},
711 {"ldmia", 0xc800, 2, do_t_ldmstm},
712 {"ldr", 0x0000, 2, do_t_ldr},
713 {"ldrb", 0x0000, 2, do_t_ldrb},
714 {"ldrh", 0x0000, 2, do_t_ldrh},
715 {"ldrsb", 0x5600, 2, do_t_lds},
716 {"ldrsh", 0x5e00, 2, do_t_lds},
717 {"ldsb", 0x5600, 2, do_t_lds},
718 {"ldsh", 0x5e00, 2, do_t_lds},
719 {"lsl", 0x0000, 2, do_t_lsl},
720 {"lsr", 0x0000, 2, do_t_lsr},
721 {"mov", 0x0000, 2, do_t_mov},
722 {"mul", T_OPCODE_MUL, 2, do_t_arit},
723 {"mvn", T_OPCODE_MVN, 2, do_t_arit},
724 {"neg", T_OPCODE_NEG, 2, do_t_arit},
725 {"orr", 0x4300, 2, do_t_arit},
726 {"pop", 0xbc00, 2, do_t_push_pop},
727 {"push", 0xb400, 2, do_t_push_pop},
728 {"ror", 0x41c0, 2, do_t_arit},
729 {"sbc", 0x4180, 2, do_t_arit},
730 {"stmia", 0xc000, 2, do_t_ldmstm},
731 {"str", 0x0000, 2, do_t_str},
732 {"strb", 0x0000, 2, do_t_strb},
733 {"strh", 0x0000, 2, do_t_strh},
734 {"swi", 0xdf00, 2, do_t_swi},
735 {"sub", 0x0000, 2, do_t_sub},
736 {"tst", T_OPCODE_TST, 2, do_t_arit},
738 {"adr", 0x0000, 2, do_t_adr},
739 {"nop", 0x0000, 2, do_nop},
748 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
749 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
750 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
756 /* These are the standard names; Users can add aliases with .req */
757 static CONST struct reg_entry reg_table[] =
759 /* Processor Register Numbers */
760 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
761 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
762 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
763 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
764 /* APCS conventions */
765 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
766 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
767 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
768 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
770 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
771 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
772 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
773 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
774 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
775 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
776 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
777 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
778 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
779 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
783 static CONST char *bad_args = "Bad arguments to instruction";
784 static CONST char *bad_pc = "r15 not allowed here";
786 static struct hash_control *arm_ops_hsh = NULL;
787 static struct hash_control *arm_tops_hsh = NULL;
788 static struct hash_control *arm_cond_hsh = NULL;
789 static struct hash_control *arm_shift_hsh = NULL;
790 static struct hash_control *arm_reg_hsh = NULL;
791 static struct hash_control *arm_psr_hsh = NULL;
793 /* This table describes all the machine specific pseudo-ops the assembler
794 has to support. The fields are:
795 pseudo-op name without dot
796 function to call to execute this pseudo-op
797 Integer arg to pass to the function
800 static void s_req PARAMS ((int));
801 static void s_align PARAMS ((int));
802 static void s_bss PARAMS ((int));
803 static void s_even PARAMS ((int));
804 static void s_ltorg PARAMS ((int));
805 static void s_arm PARAMS ((int));
806 static void s_thumb PARAMS ((int));
807 static void s_code PARAMS ((int));
809 static int my_get_expression PARAMS ((expressionS *, char **));
811 CONST pseudo_typeS md_pseudo_table[] =
813 {"req", s_req, 0}, /* Never called becasue '.req' does not start line */
815 {"align", s_align, 0},
817 {"thumb", s_thumb, 0},
820 {"ltorg", s_ltorg, 0},
821 {"pool", s_ltorg, 0},
823 {"extend", float_cons, 'x'},
824 {"ldouble", float_cons, 'x'},
825 {"packed", float_cons, 'p'},
829 /* Stuff needed to resolve the label ambiguity
839 symbolS *last_label_seen;
843 #define MAX_LITERAL_POOL_SIZE 1024
845 typedef struct literalS
847 struct expressionS exp;
851 literalT literals[MAX_LITERAL_POOL_SIZE];
852 int next_literal_pool_place = 0; /* Next free entry in the pool */
853 int lit_pool_num = 1; /* Next literal pool number */
854 symbolS *current_poolP = NULL;
855 symbolS *symbol_make_empty ();
862 if (current_poolP == NULL)
863 current_poolP = symbol_make_empty();
865 /* Check if this literal value is already in the pool: */
866 while (lit_count < next_literal_pool_place)
868 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
869 && inst.reloc.exp.X_op == O_constant
870 && literals[lit_count].exp.X_add_number == inst.reloc.exp.X_add_number
871 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
876 if (lit_count == next_literal_pool_place) /* new entry */
878 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
880 inst.error = "Literal Pool Overflow\n";
884 literals[next_literal_pool_place].exp = inst.reloc.exp;
885 lit_count = next_literal_pool_place++;
888 inst.reloc.exp.X_op = O_symbol;
889 inst.reloc.exp.X_add_number = (lit_count)*4-8;
890 inst.reloc.exp.X_add_symbol = current_poolP;
895 /* Can't use symbol_new here, so have to create a symbol and them at
896 a later date assign it a value. Thats what these functions do */
898 symbol_locate (symbolP, name, segment, valu, frag)
900 CONST char *name; /* It is copied, the caller can modify */
901 segT segment; /* Segment identifier (SEG_<something>) */
902 valueT valu; /* Symbol value */
903 fragS *frag; /* Associated fragment */
905 unsigned int name_length;
906 char *preserved_copy_of_name;
908 name_length = strlen (name) + 1; /* +1 for \0 */
909 obstack_grow (¬es, name, name_length);
910 preserved_copy_of_name = obstack_finish (¬es);
911 #ifdef STRIP_UNDERSCORE
912 if (preserved_copy_of_name[0] == '_')
913 preserved_copy_of_name++;
916 #ifdef tc_canonicalize_symbol_name
917 preserved_copy_of_name =
918 tc_canonicalize_symbol_name (preserved_copy_of_name);
921 S_SET_NAME (symbolP, preserved_copy_of_name);
923 S_SET_SEGMENT (symbolP, segment);
924 S_SET_VALUE (symbolP, valu);
925 symbol_clear_list_pointers(symbolP);
927 symbolP->sy_frag = frag;
930 * Link to end of symbol chain.
933 extern int symbol_table_frozen;
934 if (symbol_table_frozen)
938 symbol_append (symbolP, symbol_lastP, &symbol_rootP, &symbol_lastP);
940 obj_symbol_new_hook (symbolP);
942 #ifdef tc_symbol_new_hook
943 tc_symbol_new_hook (symbolP);
947 verify_symbol_chain(symbol_rootP, symbol_lastP);
948 #endif /* DEBUG_SYMS */
956 symbolP = (symbolS *) obstack_alloc (¬es, sizeof (symbolS));
958 /* symbol must be born in some fixed state. This seems as good as any. */
959 memset (symbolP, 0, sizeof (symbolS));
962 symbolP->bsym = bfd_make_empty_symbol (stdoutput);
963 assert (symbolP->bsym != 0);
964 symbolP->bsym->udata.p = (PTR) symbolP;
970 /* Check that an immediate is valid, and if so, convert it to the right format
973 /* OH, for a rotate instruction in C! */
976 validate_immediate (val)
979 unsigned int a = (unsigned int) val;
982 /* Do the easy (and most common ones) quickly */
983 for (i = 0; i <= 24; i += 2)
985 if ((a & (0xff << i)) == a)
986 return (int) (((32 - i) & 0x1e) << 7) | ((a >> i) & 0xff);
989 /* Now do the harder ones */
990 for (; i < 32; i += 2)
992 if ((a & ((0xff << i) | (0xff >> (32 - i)))) == a)
994 a = ((a >> i) & 0xff) | ((a << (32 - i)) & 0xff);
995 return (int) a | (((32 - i) >> 1) << 8);
1002 validate_offset_imm (val, hwse)
1006 if ((hwse && (val < -255 || val > 255))
1007 || (val < -4095 || val > 4095))
1017 as_bad ("Invalid syntax for .req directive.");
1024 /* We don't support putting frags in the BSS segment, we fake it by
1025 marking in_bss, then looking at s_skip for clues?.. */
1026 subseg_set (bss_section, 0);
1027 demand_empty_rest_of_line ();
1034 if (!need_pass_2) /* Never make frag if expect extra pass. */
1035 frag_align (1, 0, 0);
1036 record_alignment (now_seg, 1);
1037 demand_empty_rest_of_line ();
1047 if (current_poolP == NULL)
1051 as_tsktsk ("Nothing to put in the pool\n");
1055 /* Align pool as you have word accesses */
1056 /* Only make a frag if we have to ... */
1058 frag_align (2, 0, 0);
1060 record_alignment (now_seg, 2);
1063 as_tsktsk ("Inserting implicit pool at change of section");
1065 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1067 symbol_locate (current_poolP, sym_name, now_seg,
1068 (valueT) frag_now_fix (), frag_now);
1069 symbol_table_insert (current_poolP);
1071 while (lit_count < next_literal_pool_place)
1072 /* First output the expression in the instruction to the pool */
1073 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1075 next_literal_pool_place = 0;
1076 current_poolP = NULL;
1079 #if 0 /* not used */
1081 arm_align (power, fill)
1085 /* Only make a frag if we HAVE to ... */
1086 if (power && !need_pass_2)
1087 frag_align (power, fill, 0);
1089 record_alignment (now_seg, power);
1094 s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */
1098 register long temp_fill;
1099 long max_alignment = 15;
1101 temp = get_absolute_expression ();
1102 if (temp > max_alignment)
1103 as_bad ("Alignment too large: %d. assumed.", temp = max_alignment);
1106 as_bad ("Alignment negative. 0 assumed.");
1110 if (*input_line_pointer == ',')
1112 input_line_pointer++;
1113 temp_fill = get_absolute_expression ();
1121 /* Only make a frag if we HAVE to. . . */
1122 if (temp && !need_pass_2)
1123 frag_align (temp, (int) temp_fill, 0);
1124 demand_empty_rest_of_line ();
1126 record_alignment (now_seg, temp);
1130 opcode_select (width)
1138 if (! (cpu_variant & ARM_THUMB))
1139 as_bad ("selected processor does not support THUMB opcodes");
1141 /* No need to force the alignment, since we will have been
1142 coming from ARM mode, which is word-aligned. */
1143 record_alignment (now_seg, 1);
1150 if ((cpu_variant & ARM_ANY) == ARM_THUMB)
1151 as_bad ("selected processor does not support ARM opcodes");
1154 frag_align (2, 0, 0);
1155 record_alignment (now_seg, 1);
1160 as_bad ("invalid instruction size selected (%d)", width);
1169 demand_empty_rest_of_line ();
1177 demand_empty_rest_of_line ();
1186 temp = get_absolute_expression ();
1191 opcode_select(temp);
1195 as_bad ("invalid operand to .code directive (%d)", temp);
1207 inst.error = "Garbage following instruction";
1211 skip_past_comma (str)
1217 while ((c = *p) == ' ' || c == ',')
1220 if (c == ',' && comma++)
1228 return comma ? SUCCESS : FAIL;
1231 /* A standard register must be given at this point. Shift is the place to
1232 put it in the instruction. */
1235 reg_required_here (str, shift)
1242 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1244 inst.instruction |= reg << shift;
1248 /* In the few cases where we might be able to accept something else
1249 this error can be overridden */
1250 inst.error = "Register expected";
1252 /* Restore the start point, we may have got a reg of the wrong class. */
1258 psr_required_here (str, shift)
1265 if ((psr = arm_psr_parse (str)) != FAIL && psr < 2)
1268 inst.instruction |= 1 << shift; /* Should be bit 22 */
1272 /* In the few cases where we might be able to accept something else
1273 this error can be overridden */
1274 inst.error = "<psr> expected";
1276 /* Restore the start point. */
1282 psrf_required_here (str, shift)
1289 if ((psrf = arm_psr_parse (str)) != FAIL && psrf > 1)
1291 if (psrf == 1 || psrf == 3)
1292 inst.instruction |= 1 << shift; /* Should be bit 22 */
1296 /* In the few cases where we might be able to accept something else
1297 this error can be overridden */
1298 inst.error = "<psrf> expected";
1300 /* Restore the start point. */
1306 co_proc_number (str)
1309 int processor, pchar;
1311 while (**str == ' ')
1314 /* The data sheet seems to imply that just a number on its own is valid
1315 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1317 if (**str == 'p' || **str == 'P')
1321 if (pchar >= '0' && pchar <= '9')
1323 processor = pchar - '0';
1324 if (**str >= '0' && **str <= '9')
1326 processor = processor * 10 + *(*str)++ - '0';
1329 inst.error = "Illegal co-processor number";
1336 inst.error = "Bad or missing co-processor number";
1340 inst.instruction |= processor << 8;
1345 cp_opc_expr (str, where, length)
1352 while (**str == ' ')
1355 memset (&expr, '\0', sizeof (expr));
1357 if (my_get_expression (&expr, str))
1359 if (expr.X_op != O_constant)
1361 inst.error = "bad or missing expression";
1365 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1367 inst.error = "immediate co-processor expression too large";
1371 inst.instruction |= expr.X_add_number << where;
1376 cp_reg_required_here (str, where)
1383 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1386 inst.instruction |= reg << where;
1390 /* In the few cases where we might be able to accept something else
1391 this error can be overridden */
1392 inst.error = "Co-processor register expected";
1394 /* Restore the start point */
1400 fp_reg_required_here (str, where)
1407 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1410 inst.instruction |= reg << where;
1414 /* In the few cases where we might be able to accept something else
1415 this error can be overridden */
1416 inst.error = "Floating point register expected";
1418 /* Restore the start point */
1424 cp_address_offset (str)
1429 while (**str == ' ')
1434 inst.error = "immediate expression expected";
1439 if (my_get_expression (&inst.reloc.exp, str))
1441 if (inst.reloc.exp.X_op == O_constant)
1443 offset = inst.reloc.exp.X_add_number;
1446 inst.error = "co-processor address must be word aligned";
1450 if (offset > 1023 || offset < -1023)
1452 inst.error = "offset too large";
1457 inst.instruction |= INDEX_UP;
1461 inst.instruction |= offset >> 2;
1464 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1470 cp_address_required_here (str)
1485 if ((reg = reg_required_here (&p, 16)) == FAIL)
1487 inst.error = "Register required";
1497 if (skip_past_comma (&p) == SUCCESS)
1500 write_back = WRITE_BACK;
1503 inst.error = "pc may not be used in post-increment";
1507 if (cp_address_offset (&p) == FAIL)
1511 pre_inc = PRE_INDEX | INDEX_UP;
1515 /* '['Rn, #expr']'[!] */
1517 if (skip_past_comma (&p) == FAIL)
1519 inst.error = "pre-indexed expression expected";
1523 pre_inc = PRE_INDEX;
1524 if (cp_address_offset (&p) == FAIL)
1532 inst.error = "missing ]";
1543 inst.error = "pc may not be used with write-back";
1548 write_back = WRITE_BACK;
1554 if (my_get_expression (&inst.reloc.exp, &p))
1557 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1558 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
1559 inst.reloc.pc_rel = 1;
1560 inst.instruction |= (REG_PC << 16);
1561 pre_inc = PRE_INDEX;
1564 inst.instruction |= write_back | pre_inc;
1572 unsigned long flags;
1574 /* Do nothing really */
1575 inst.instruction |= flags; /* This is pointless */
1583 unsigned long flags;
1585 /* Only one syntax */
1589 if (reg_required_here (&str, 12) == FAIL)
1591 inst.error = bad_args;
1595 if (skip_past_comma (&str) == FAIL
1596 || psr_required_here (&str, 22) == FAIL)
1598 inst.error = "<psr> expected";
1602 inst.instruction |= flags;
1610 unsigned long flags;
1613 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1618 if ((psr = psr_required_here (&str, 22)) != FAIL)
1620 inst.instruction |= PSR_ALL;
1621 /* Sytax should be "<psr>, Rm" */
1622 if (skip_past_comma (&str) == FAIL
1623 || (reg = reg_required_here (&str, 0)) == FAIL)
1625 inst.error = bad_args;
1629 else if ((psrf = psrf_required_here (&str, 22)) != FAIL)
1630 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1632 if (skip_past_comma (&str) == FAIL)
1634 inst.error = bad_args;
1637 if ((reg = reg_required_here (&str, 0)) != FAIL)
1639 /* Immediate expression */
1640 else if (*(str++) == '#')
1643 if (my_get_expression (&inst.reloc.exp, &str))
1645 inst.error = "Register or shift expression expected";
1649 if (inst.reloc.exp.X_add_symbol)
1651 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
1652 inst.reloc.pc_rel = 0;
1656 int value = validate_immediate (inst.reloc.exp.X_add_number);
1659 inst.error = "Invalid constant";
1663 inst.instruction |= value;
1666 flags |= INST_IMMEDIATE;
1670 inst.error = "Error: the other";
1676 inst.error = bad_args;
1681 inst.instruction |= flags;
1686 /* Long Multiply Parser
1687 UMULL RdLo, RdHi, Rm, Rs
1688 SMULL RdLo, RdHi, Rm, Rs
1689 UMLAL RdLo, RdHi, Rm, Rs
1690 SMLAL RdLo, RdHi, Rm, Rs
1693 do_mull (str, flags)
1695 unsigned long flags;
1697 int rdlo, rdhi, rm, rs;
1699 /* only one format "rdlo, rdhi, rm, rs" */
1703 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
1705 inst.error = bad_args;
1709 if (skip_past_comma (&str) == FAIL
1710 || (rdhi = reg_required_here (&str, 16)) == FAIL)
1712 inst.error = bad_args;
1716 if (skip_past_comma (&str) == FAIL
1717 || (rm = reg_required_here (&str, 0)) == FAIL)
1719 inst.error = bad_args;
1723 /* rdhi, rdlo and rm must all be different */
1724 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
1725 as_tsktsk ("rdhi, rdlo and rm must all be different");
1727 if (skip_past_comma (&str) == FAIL
1728 || (rs = reg_required_here (&str, 8)) == FAIL)
1730 inst.error = bad_args;
1734 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
1736 inst.error = bad_pc;
1740 inst.instruction |= flags;
1748 unsigned long flags;
1752 /* only one format "rd, rm, rs" */
1756 if ((rd = reg_required_here (&str, 16)) == FAIL)
1758 inst.error = bad_args;
1764 inst.error = bad_pc;
1768 if (skip_past_comma (&str) == FAIL
1769 || (rm = reg_required_here (&str, 0)) == FAIL)
1771 inst.error = bad_args;
1777 inst.error = bad_pc;
1782 as_tsktsk ("rd and rm should be different in mul");
1784 if (skip_past_comma (&str) == FAIL
1785 || (rm = reg_required_here (&str, 8)) == FAIL)
1787 inst.error = bad_args;
1793 inst.error = bad_pc;
1797 inst.instruction |= flags;
1805 unsigned long flags;
1809 /* only one format "rd, rm, rs, rn" */
1813 if ((rd = reg_required_here (&str, 16)) == FAIL)
1815 inst.error = bad_args;
1821 inst.error = bad_pc;
1825 if (skip_past_comma (&str) == FAIL
1826 || (rm = reg_required_here (&str, 0)) == FAIL)
1828 inst.error = bad_args;
1834 inst.error = bad_pc;
1839 as_tsktsk ("rd and rm should be different in mla");
1841 if (skip_past_comma (&str) == FAIL
1842 || (rd = reg_required_here (&str, 8)) == FAIL
1843 || skip_past_comma (&str) == FAIL
1844 || (rm = reg_required_here (&str, 12)) == FAIL)
1846 inst.error = bad_args;
1850 if (rd == REG_PC || rm == REG_PC)
1852 inst.error = bad_pc;
1856 inst.instruction |= flags;
1861 /* Returns the index into fp_values of a floating point number, or -1 if
1862 not in the table. */
1864 my_get_float_expression (str)
1867 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1872 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
1873 /* Look for a raw floating point number */
1874 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
1875 && (is_end_of_line [(int)(*save_in)] || *save_in == '\0'))
1877 for (i = 0; i < NUM_FLOAT_VALS; i++)
1879 for (j = 0; j < MAX_LITTLENUMS; j++)
1881 if (words[j] != fp_values[i][j])
1885 if (j == MAX_LITTLENUMS)
1893 /* Try and parse a more complex expression, this will probably fail
1894 unless the code uses a floating point prefix (eg "0f") */
1895 save_in = input_line_pointer;
1896 input_line_pointer = *str;
1897 if (expression (&exp) == absolute_section
1898 && exp.X_op == O_big
1899 && exp.X_add_number < 0)
1901 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
1903 if (gen_to_words (words, 5, (long)15) == 0)
1905 for (i = 0; i < NUM_FLOAT_VALS; i++)
1907 for (j = 0; j < MAX_LITTLENUMS; j++)
1909 if (words[j] != fp_values[i][j])
1913 if (j == MAX_LITTLENUMS)
1915 *str = input_line_pointer;
1916 input_line_pointer = save_in;
1923 *str = input_line_pointer;
1924 input_line_pointer = save_in;
1928 /* Return true if anything in the expression is a bignum */
1930 walk_no_bignums (sp)
1933 if (sp->sy_value.X_op == O_big)
1936 if (sp->sy_value.X_add_symbol)
1938 return (walk_no_bignums (sp->sy_value.X_add_symbol)
1939 || (sp->sy_value.X_op_symbol
1940 && walk_no_bignums (sp->sy_value.X_op_symbol)));
1947 my_get_expression (ep, str)
1954 save_in = input_line_pointer;
1955 input_line_pointer = *str;
1956 seg = expression (ep);
1959 if (seg != absolute_section
1960 && seg != text_section
1961 && seg != data_section
1962 && seg != bss_section
1963 && seg != undefined_section)
1965 inst.error = "bad_segment";
1966 *str = input_line_pointer;
1967 input_line_pointer = save_in;
1972 /* Get rid of any bignums now, so that we don't generate an error for which
1973 we can't establish a line number later on. Big numbers are never valid
1974 in instructions, which is where this routine is always called. */
1975 if (ep->X_op == O_big
1976 || (ep->X_add_symbol
1977 && (walk_no_bignums (ep->X_add_symbol)
1979 && walk_no_bignums (ep->X_op_symbol)))))
1981 inst.error = "Invalid constant";
1982 *str = input_line_pointer;
1983 input_line_pointer = save_in;
1987 *str = input_line_pointer;
1988 input_line_pointer = save_in;
1992 /* unrestrict should be one if <shift> <register> is permitted for this
1996 decode_shift (str, unrestrict)
2000 struct asm_shift *shft;
2004 while (**str == ' ')
2007 for (p = *str; isalpha (*p); p++)
2012 inst.error = "Shift expression expected";
2018 shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
2022 if (!strcmp (*str, "rrx")
2023 || !strcmp (*str, "RRX"))
2026 inst.instruction |= shft->value;
2033 if (unrestrict && reg_required_here (&p, 8) != FAIL)
2035 inst.instruction |= shft->value | SHIFT_BY_REG;
2043 if (my_get_expression (&inst.reloc.exp, &p))
2046 /* Validate some simple #expressions */
2047 if (inst.reloc.exp.X_op == O_constant)
2049 unsigned num = inst.reloc.exp.X_add_number;
2051 /* Reject operations greater than 32, or lsl #32 */
2052 if (num > 32 || (num == 32 && shft->value == 0))
2054 inst.error = "Invalid immediate shift";
2058 /* Shifts of zero should be converted to lsl (which is zero)*/
2065 /* Shifts of 32 are encoded as 0, for those shifts that
2070 inst.instruction |= (num << 7) | shft->value;
2075 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
2076 inst.reloc.pc_rel = 0;
2077 inst.instruction |= shft->value;
2083 inst.error = unrestrict ? "shift requires register or #expression"
2084 : "shift requires #expression";
2090 inst.error = "Shift expression expected";
2094 /* Do those data_ops which can take a negative immediate constant */
2095 /* by altering the instuction. A bit of a hack really */
2099 by inverting the second operand, and
2102 by negating the second operand.
2105 negate_data_op (instruction, value)
2106 unsigned long *instruction;
2107 unsigned long value;
2110 unsigned long negated, inverted;
2112 negated = validate_immediate (-value);
2113 inverted = validate_immediate (~value);
2115 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
2119 case OPCODE_SUB: /* ADD <-> SUB */
2120 new_inst = OPCODE_ADD;
2125 new_inst = OPCODE_SUB;
2129 case OPCODE_CMP: /* CMP <-> CMN */
2130 new_inst = OPCODE_CMN;
2135 new_inst = OPCODE_CMP;
2139 /* Now Inverted ops */
2140 case OPCODE_MOV: /* MOV <-> MVN */
2141 new_inst = OPCODE_MVN;
2146 new_inst = OPCODE_MOV;
2150 case OPCODE_AND: /* AND <-> BIC */
2151 new_inst = OPCODE_BIC;
2156 new_inst = OPCODE_AND;
2160 case OPCODE_ADC: /* ADC <-> SBC */
2161 new_inst = OPCODE_SBC;
2166 new_inst = OPCODE_ADC;
2170 /* We cannot do anything */
2178 *instruction &= OPCODE_MASK;
2179 *instruction |= new_inst << DATA_OP_SHIFT;
2190 while (**str == ' ')
2193 if (reg_required_here (str, 0) != FAIL)
2195 if (skip_past_comma (str) == SUCCESS)
2197 /* Shift operation on register */
2198 return decode_shift (str, NO_SHIFT_RESTRICT);
2204 /* Immediate expression */
2205 if (*((*str)++) == '#')
2208 if (my_get_expression (&inst.reloc.exp, str))
2211 if (inst.reloc.exp.X_add_symbol)
2213 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2214 inst.reloc.pc_rel = 0;
2218 if (skip_past_comma (str) == SUCCESS)
2220 /* #x, y -- ie explicit rotation by Y */
2221 if (my_get_expression (&expr, str))
2224 if (expr.X_op != O_constant)
2226 inst.error = "Constant expression expected";
2230 /* Rotate must be a multiple of 2 */
2231 if (((unsigned) expr.X_add_number) > 30
2232 || (expr.X_add_number & 1) != 0
2233 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
2235 inst.error = "Invalid constant";
2238 inst.instruction |= INST_IMMEDIATE;
2239 inst.instruction |= inst.reloc.exp.X_add_number;
2240 inst.instruction |= expr.X_add_number << 7;
2244 /* Implicit rotation, select a suitable one */
2245 value = validate_immediate (inst.reloc.exp.X_add_number);
2249 /* Can't be done, perhaps the code reads something like
2250 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2251 if ((value = negate_data_op (&inst.instruction,
2252 inst.reloc.exp.X_add_number))
2255 inst.error = "Invalid constant";
2260 inst.instruction |= value;
2263 inst.instruction |= INST_IMMEDIATE;
2267 inst.error = "Register or shift expression expected";
2275 unsigned long flags;
2277 while (**str == ' ')
2280 if (fp_reg_required_here (str, 0) != FAIL)
2284 /* Immediate expression */
2285 if (*((*str)++) == '#')
2290 while (**str == ' ')
2293 /* First try and match exact strings, this is to guarantee that
2294 some formats will work even for cross assembly */
2296 for (i = 0; fp_const[i]; i++)
2298 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2302 *str += strlen (fp_const[i]);
2303 if (is_end_of_line[(int)**str] || **str == '\0')
2305 inst.instruction |= i + 8;
2312 /* Just because we didn't get a match doesn't mean that the
2313 constant isn't valid, just that it is in a format that we
2314 don't automatically recognize. Try parsing it with
2315 the standard expression routines. */
2316 if ((i = my_get_float_expression (str)) >= 0)
2318 inst.instruction |= i + 8;
2322 inst.error = "Invalid floating point immediate expression";
2325 inst.error = "Floating point register or immediate expression expected";
2331 do_arit (str, flags)
2333 unsigned long flags;
2338 if (reg_required_here (&str, 12) == FAIL
2339 || skip_past_comma (&str) == FAIL
2340 || reg_required_here (&str, 16) == FAIL
2341 || skip_past_comma (&str) == FAIL
2342 || data_op2 (&str) == FAIL)
2345 inst.error = bad_args;
2349 inst.instruction |= flags;
2357 unsigned long flags;
2359 /* This is a pseudo-op of the form "adr rd, label" to be converted
2360 into a relative address of the form "add rd, pc, #label-.-8" */
2365 if (reg_required_here (&str, 12) == FAIL
2366 || skip_past_comma (&str) == FAIL
2367 || my_get_expression (&inst.reloc.exp, &str))
2370 inst.error = bad_args;
2373 /* Frag hacking will turn this into a sub instruction if the offset turns
2374 out to be negative. */
2375 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2376 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2377 inst.reloc.pc_rel = 1;
2378 inst.instruction |= flags;
2386 unsigned long flags;
2391 if (reg_required_here (&str, 16) == FAIL)
2394 inst.error = bad_args;
2398 if (skip_past_comma (&str) == FAIL
2399 || data_op2 (&str) == FAIL)
2402 inst.error = bad_args;
2406 inst.instruction |= flags;
2407 if ((flags & 0x0000f000) == 0)
2408 inst.instruction |= CONDS_BIT;
2417 unsigned long flags;
2422 if (reg_required_here (&str, 12) == FAIL)
2425 inst.error = bad_args;
2429 if (skip_past_comma (&str) == FAIL
2430 || data_op2 (&str) == FAIL)
2433 inst.error = bad_args;
2437 inst.instruction |= flags;
2443 ldst_extend (str, hwse)
2453 if (my_get_expression (&inst.reloc.exp, str))
2456 if (inst.reloc.exp.X_op == O_constant)
2458 int value = inst.reloc.exp.X_add_number;
2460 if ((hwse && (value < -255 || value > 255))
2461 || (value < -4095 || value > 4095))
2463 inst.error = "address offset too large";
2473 /* Halfword and signextension instructions have the
2474 immediate value split across bits 11..8 and bits 3..0 */
2476 inst.instruction |= add | HWOFFSET_IMM | (value >> 4) << 8 | value & 0xF;
2478 inst.instruction |= add | value;
2484 inst.instruction |= HWOFFSET_IMM;
2485 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2488 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2489 inst.reloc.pc_rel = 0;
2494 add = 0; /* and fall through */
2496 (*str)++; /* and fall through */
2498 if (reg_required_here (str, 0) == FAIL)
2500 inst.error = "Register expected";
2505 inst.instruction |= add;
2508 inst.instruction |= add | OFFSET_REG;
2509 if (skip_past_comma (str) == SUCCESS)
2510 return decode_shift (str, SHIFT_RESTRICT);
2518 do_ldst (str, flags)
2520 unsigned long flags;
2527 /* This is not ideal, but it is the simplest way of dealing with the
2528 ARM7T halfword instructions (since they use a different
2529 encoding, but the same mnemonic): */
2530 if (halfword = ((flags & 0x80000000) != 0))
2532 /* This is actually a load/store of a halfword, or a
2533 signed-extension load */
2534 if ((cpu_variant & ARM_ARCH4) == 0)
2537 = "Processor does not support halfwords or signed bytes\n";
2541 inst.instruction = (inst.instruction & COND_MASK)
2542 | (flags & ~COND_MASK);
2550 if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
2553 inst.error = bad_args;
2557 if (skip_past_comma (&str) == FAIL)
2559 inst.error = "Address expected";
2571 if ((reg = reg_required_here (&str, 16)) == FAIL)
2573 inst.error = "Register required";
2577 conflict_reg = (((conflict_reg == reg)
2578 && (inst.instruction & LOAD_BIT))
2587 if (skip_past_comma (&str) == SUCCESS)
2589 /* [Rn],... (post inc) */
2590 if (ldst_extend (&str, halfword) == FAIL)
2593 as_warn ("destination register same as write-back base\n");
2599 inst.instruction |= HWOFFSET_IMM;
2607 as_warn ("destination register same as write-back base\n");
2609 inst.instruction |= WRITE_BACK;
2613 if (! (flags & TRANS_BIT))
2620 if (skip_past_comma (&str) == FAIL)
2622 inst.error = "pre-indexed expression expected";
2627 if (ldst_extend (&str, halfword) == FAIL)
2635 inst.error = "missing ]";
2645 as_tsktsk ("destination register same as write-back base\n");
2647 inst.instruction |= WRITE_BACK;
2651 else if (*str == '=')
2653 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2659 if (my_get_expression (&inst.reloc.exp, &str))
2662 if (inst.reloc.exp.X_op != O_constant
2663 && inst.reloc.exp.X_op != O_symbol)
2665 inst.error = "Constant expression expected";
2669 if (inst.reloc.exp.X_op == O_constant
2670 && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
2672 /* This can be done with a mov instruction */
2673 inst.instruction &= LITERAL_MASK;
2674 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
2675 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
2681 /* Insert into literal pool */
2682 if (add_to_lit_pool () == FAIL)
2685 inst.error = "literal pool insertion failed\n";
2689 /* Change the instruction exp to point to the pool */
2692 inst.instruction |= HWOFFSET_IMM;
2693 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
2696 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
2697 inst.reloc.pc_rel = 1;
2698 inst.instruction |= (REG_PC << 16);
2704 if (my_get_expression (&inst.reloc.exp, &str))
2709 inst.instruction |= HWOFFSET_IMM;
2710 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2713 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2714 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
2715 inst.reloc.pc_rel = 1;
2716 inst.instruction |= (REG_PC << 16);
2720 if (pre_inc && (flags & TRANS_BIT))
2721 inst.error = "Pre-increment instruction with translate";
2723 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
2736 /* We come back here if we get ranges concatenated by '+' or '|' */
2754 if ((reg = arm_reg_parse (&str)) == FAIL || !int_register (reg))
2756 inst.error = "Register expected";
2766 inst.error = "Bad range in register list";
2770 for (i = cur_reg + 1; i < reg; i++)
2772 if (range & (1 << i))
2774 ("Warning: Duplicated register (r%d) in register list",
2782 if (range & (1 << reg))
2783 as_tsktsk ("Warning: Duplicated register (r%d) in register list",
2785 else if (reg <= cur_reg)
2786 as_tsktsk ("Warning: Register range not in ascending order");
2790 } while (skip_past_comma (&str) != FAIL
2791 || (in_range = 1, *str++ == '-'));
2798 inst.error = "Missing `}'";
2806 if (my_get_expression (&expr, &str))
2809 if (expr.X_op == O_constant)
2811 if (expr.X_add_number
2812 != (expr.X_add_number & 0x0000ffff))
2814 inst.error = "invalid register mask";
2818 if ((range & expr.X_add_number) != 0)
2820 int regno = range & expr.X_add_number;
2823 regno = (1 << regno) - 1;
2825 ("Warning: Duplicated register (r%d) in register list",
2829 range |= expr.X_add_number;
2833 if (inst.reloc.type != 0)
2835 inst.error = "expression too complex";
2839 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
2840 inst.reloc.type = BFD_RELOC_ARM_MULTI;
2841 inst.reloc.pc_rel = 0;
2848 if (*str == '|' || *str == '+')
2853 } while (another_range);
2860 do_ldmstm (str, flags)
2862 unsigned long flags;
2870 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
2873 inst.error = bad_args;
2877 if (base_reg == REG_PC)
2879 inst.error = "r15 not allowed as base register";
2887 flags |= WRITE_BACK;
2891 if (skip_past_comma (&str) == FAIL
2892 || (range = reg_list (&str)) == FAIL)
2895 inst.error = bad_args;
2902 flags |= MULTI_SET_PSR;
2905 inst.instruction |= flags | range;
2913 unsigned long flags;
2915 /* Allow optional leading '#'. */
2921 if (my_get_expression (&inst.reloc.exp, &str))
2924 inst.reloc.type = BFD_RELOC_ARM_SWI;
2925 inst.reloc.pc_rel = 0;
2926 inst.instruction |= flags;
2932 do_swap (str, flags)
2934 unsigned long flags;
2941 if ((reg = reg_required_here (&str, 12)) == FAIL)
2946 inst.error = "r15 not allowed in swap";
2950 if (skip_past_comma (&str) == FAIL
2951 || (reg = reg_required_here (&str, 0)) == FAIL)
2954 inst.error = bad_args;
2960 inst.error = "r15 not allowed in swap";
2964 if (skip_past_comma (&str) == FAIL
2967 inst.error = bad_args;
2974 if ((reg = reg_required_here (&str, 16)) == FAIL)
2979 inst.error = bad_pc;
2988 inst.error = "missing ]";
2992 inst.instruction |= flags;
2998 do_branch (str, flags)
3000 unsigned long flags;
3002 if (my_get_expression (&inst.reloc.exp, &str))
3004 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3005 inst.reloc.pc_rel = 1;
3013 unsigned long flags;
3020 if ((reg = reg_required_here (&str, 0)) == FAIL)
3024 as_tsktsk ("Use of r15 in bx has undefined behaviour");
3033 unsigned long flags;
3035 /* Co-processor data operation.
3036 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3040 if (co_proc_number (&str) == FAIL)
3043 inst.error = bad_args;
3047 if (skip_past_comma (&str) == FAIL
3048 || cp_opc_expr (&str, 20,4) == FAIL)
3051 inst.error = bad_args;
3055 if (skip_past_comma (&str) == FAIL
3056 || cp_reg_required_here (&str, 12) == FAIL)
3059 inst.error = bad_args;
3063 if (skip_past_comma (&str) == FAIL
3064 || cp_reg_required_here (&str, 16) == FAIL)
3067 inst.error = bad_args;
3071 if (skip_past_comma (&str) == FAIL
3072 || cp_reg_required_here (&str, 0) == FAIL)
3075 inst.error = bad_args;
3079 if (skip_past_comma (&str) == SUCCESS)
3081 if (cp_opc_expr (&str, 5, 3) == FAIL)
3084 inst.error = bad_args;
3094 do_lstc (str, flags)
3096 unsigned long flags;
3098 /* Co-processor register load/store.
3099 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3104 if (co_proc_number (&str) == FAIL)
3107 inst.error = bad_args;
3111 if (skip_past_comma (&str) == FAIL
3112 || cp_reg_required_here (&str, 12) == FAIL)
3115 inst.error = bad_args;
3119 if (skip_past_comma (&str) == FAIL
3120 || cp_address_required_here (&str) == FAIL)
3123 inst.error = bad_args;
3127 inst.instruction |= flags;
3133 do_co_reg (str, flags)
3135 unsigned long flags;
3137 /* Co-processor register transfer.
3138 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3143 if (co_proc_number (&str) == FAIL)
3146 inst.error = bad_args;
3150 if (skip_past_comma (&str) == FAIL
3151 || cp_opc_expr (&str, 21, 3) == FAIL)
3154 inst.error = bad_args;
3158 if (skip_past_comma (&str) == FAIL
3159 || reg_required_here (&str, 12) == FAIL)
3162 inst.error = bad_args;
3166 if (skip_past_comma (&str) == FAIL
3167 || cp_reg_required_here (&str, 16) == FAIL)
3170 inst.error = bad_args;
3174 if (skip_past_comma (&str) == FAIL
3175 || cp_reg_required_here (&str, 0) == FAIL)
3178 inst.error = bad_args;
3182 if (skip_past_comma (&str) == SUCCESS)
3184 if (cp_opc_expr (&str, 5, 3) == FAIL)
3187 inst.error = bad_args;
3197 do_fp_ctrl (str, flags)
3199 unsigned long flags;
3201 /* FP control registers.
3202 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3207 if (reg_required_here (&str, 12) == FAIL)
3210 inst.error = bad_args;
3219 do_fp_ldst (str, flags)
3221 unsigned long flags;
3226 switch (inst.suffix)
3231 inst.instruction |= CP_T_X;
3234 inst.instruction |= CP_T_Y;
3237 inst.instruction |= CP_T_X | CP_T_Y;
3243 if (fp_reg_required_here (&str, 12) == FAIL)
3246 inst.error = bad_args;
3250 if (skip_past_comma (&str) == FAIL
3251 || cp_address_required_here (&str) == FAIL)
3254 inst.error = bad_args;
3262 do_fp_ldmstm (str, flags)
3264 unsigned long flags;
3271 if (fp_reg_required_here (&str, 12) == FAIL)
3274 inst.error = bad_args;
3278 /* Get Number of registers to transfer */
3279 if (skip_past_comma (&str) == FAIL
3280 || my_get_expression (&inst.reloc.exp, &str))
3283 inst.error = "constant expression expected";
3287 if (inst.reloc.exp.X_op != O_constant)
3289 inst.error = "Constant value required for number of registers";
3293 num_regs = inst.reloc.exp.X_add_number;
3295 if (num_regs < 1 || num_regs > 4)
3297 inst.error = "number of registers must be in the range [1:4]";
3304 inst.instruction |= CP_T_X;
3307 inst.instruction |= CP_T_Y;
3310 inst.instruction |= CP_T_Y | CP_T_X;
3324 /* The instruction specified "ea" or "fd", so we can only accept
3325 [Rn]{!}. The instruction does not really support stacking or
3326 unstacking, so we have to emulate these by setting appropriate
3327 bits and offsets. */
3328 if (skip_past_comma (&str) == FAIL
3332 inst.error = bad_args;
3340 if ((reg = reg_required_here (&str, 16)) == FAIL)
3342 inst.error = "Register required";
3351 inst.error = bad_args;
3362 inst.error = "R15 not allowed as base register with write-back";
3369 if (flags & CP_T_Pre)
3372 offset = 3 * num_regs;
3378 /* Post-increment */
3382 offset = 3 * num_regs;
3386 /* No write-back, so convert this into a standard pre-increment
3387 instruction -- aesthetically more pleasing. */
3388 flags = CP_T_Pre | CP_T_UD;
3393 inst.instruction |= flags | offset;
3395 else if (skip_past_comma (&str) == FAIL
3396 || cp_address_required_here (&str) == FAIL)
3399 inst.error = bad_args;
3407 do_fp_dyadic (str, flags)
3409 unsigned long flags;
3414 switch (inst.suffix)
3419 inst.instruction |= 0x00000080;
3422 inst.instruction |= 0x00080000;
3428 if (fp_reg_required_here (&str, 12) == FAIL)
3431 inst.error = bad_args;
3435 if (skip_past_comma (&str) == FAIL
3436 || fp_reg_required_here (&str, 16) == FAIL)
3439 inst.error = bad_args;
3443 if (skip_past_comma (&str) == FAIL
3444 || fp_op2 (&str) == FAIL)
3447 inst.error = bad_args;
3451 inst.instruction |= flags;
3457 do_fp_monadic (str, flags)
3459 unsigned long flags;
3464 switch (inst.suffix)
3469 inst.instruction |= 0x00000080;
3472 inst.instruction |= 0x00080000;
3478 if (fp_reg_required_here (&str, 12) == FAIL)
3481 inst.error = bad_args;
3485 if (skip_past_comma (&str) == FAIL
3486 || fp_op2 (&str) == FAIL)
3489 inst.error = bad_args;
3493 inst.instruction |= flags;
3499 do_fp_cmp (str, flags)
3501 unsigned long flags;
3506 if (fp_reg_required_here (&str, 16) == FAIL)
3509 inst.error = bad_args;
3513 if (skip_past_comma (&str) == FAIL
3514 || fp_op2 (&str) == FAIL)
3517 inst.error = bad_args;
3521 inst.instruction |= flags;
3527 do_fp_from_reg (str, flags)
3529 unsigned long flags;
3534 switch (inst.suffix)
3539 inst.instruction |= 0x00000080;
3542 inst.instruction |= 0x00080000;
3548 if (fp_reg_required_here (&str, 16) == FAIL)
3551 inst.error = bad_args;
3555 if (skip_past_comma (&str) == FAIL
3556 || reg_required_here (&str, 12) == FAIL)
3559 inst.error = bad_args;
3563 inst.instruction |= flags;
3569 do_fp_to_reg (str, flags)
3571 unsigned long flags;
3576 if (reg_required_here (&str, 12) == FAIL)
3579 inst.error = bad_args;
3583 if (skip_past_comma (&str) == FAIL
3584 || fp_reg_required_here (&str, 0) == FAIL)
3587 inst.error = bad_args;
3591 inst.instruction |= flags;
3596 /* Thumb specific routines */
3598 /* Parse and validate that a register is of the right form, this saves
3599 repeated checking of this information in many similar cases.
3600 Unlike the 32-bit case we do not insert the register into the opcode
3601 here, since the position is often unknown until the full instruction
3604 thumb_reg (strp, hi_lo)
3610 if ((reg = arm_reg_parse (strp)) == FAIL || ! int_register (reg))
3612 inst.error = "Register expected";
3621 inst.error = "lo register required";
3629 inst.error = "hi register required";
3641 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3644 thumb_add_sub (str, subtract)
3648 int Rd, Rs, Rn = FAIL;
3653 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
3654 || skip_past_comma (&str) == FAIL)
3657 inst.error = bad_args;
3665 if (my_get_expression (&inst.reloc.exp, &str))
3670 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3673 if (skip_past_comma (&str) == FAIL)
3675 /* Two operand format, shuffle the registers and pretend there
3680 else if (*str == '#')
3683 if (my_get_expression (&inst.reloc.exp, &str))
3686 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3690 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3691 for the latter case, EXPR contains the immediate that was found. */
3694 /* All register format. */
3695 if (Rd > 7 || Rs > 7 || Rd > 7)
3699 inst.error = "dest and source1 must be the same register";
3703 /* Can't do this for SUB */
3706 inst.error = "subtract valid only on lo regs";
3710 inst.instruction = (T_OPCODE_ADD_HI
3711 | (Rd > 7 ? THUMB_H1 : 0)
3712 | (Rn > 7 ? THUMB_H2 : 0));
3713 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
3717 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
3718 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
3723 /* Immediate expression, now things start to get nasty. */
3725 /* First deal with HI regs, only very restricted cases allowed:
3726 Adjusting SP, and using PC or SP to get an address. */
3727 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
3728 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
3730 inst.error = "invalid Hi register with immediate";
3734 if (inst.reloc.exp.X_op != O_constant)
3736 /* Value isn't known yet, all we can do is store all the fragments
3737 we know about in the instruction and let the reloc hacking
3739 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
3740 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
3744 int offset = inst.reloc.exp.X_add_number;
3754 /* Quick check, in case offset is MIN_INT */
3757 inst.error = "immediate value out of range";
3766 if (offset & ~0x1fc)
3768 inst.error = "invalid immediate value for stack adjust";
3771 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
3772 inst.instruction |= offset >> 2;
3774 else if (Rs == REG_PC || Rs == REG_SP)
3777 || (offset & ~0x3fc))
3779 inst.error = "invalid immediate for address calculation";
3782 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
3784 inst.instruction |= (Rd << 8) | (offset >> 2);
3790 inst.error = "immediate value out of range";
3793 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
3794 inst.instruction |= (Rd << 8) | offset;
3800 inst.error = "immediate value out of range";
3803 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
3804 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
3812 thumb_shift (str, shift)
3816 int Rd, Rs, Rn = FAIL;
3821 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
3822 || skip_past_comma (&str) == FAIL)
3825 inst.error = bad_args;
3831 /* Two operand immediate format, set Rs to Rd. */
3834 if (my_get_expression (&inst.reloc.exp, &str))
3839 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
3842 if (skip_past_comma (&str) == FAIL)
3844 /* Two operand format, shuffle the registers and pretend there
3849 else if (*str == '#')
3852 if (my_get_expression (&inst.reloc.exp, &str))
3855 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
3859 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3860 for the latter case, EXPR contains the immediate that was found. */
3866 inst.error = "source1 and dest must be same register";
3872 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
3873 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
3874 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
3877 inst.instruction |= Rd | (Rn << 3);
3883 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
3884 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
3885 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
3888 if (inst.reloc.exp.X_op != O_constant)
3890 /* Value isn't known yet, create a dummy reloc and let reloc
3891 hacking fix it up */
3893 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
3897 unsigned shift_value = inst.reloc.exp.X_add_number;
3899 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
3901 inst.error = "Invalid immediate for shift";
3905 /* Shifts of zero are handled by converting to LSL */
3906 if (shift_value == 0)
3907 inst.instruction = T_OPCODE_LSL_I;
3909 /* Shifts of 32 are encoded as a shift of zero */
3910 if (shift_value == 32)
3913 inst.instruction |= shift_value << 6;
3916 inst.instruction |= Rd | (Rs << 3);
3922 thumb_mov_compare (str, move)
3931 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
3932 || skip_past_comma (&str) == FAIL)
3935 inst.error = bad_args;
3942 if (my_get_expression (&inst.reloc.exp, &str))
3945 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3950 if (Rs < 8 && Rd < 8)
3952 if (move == THUMB_MOVE)
3953 /* A move of two lowregs is, by convention, encoded as
3955 inst.instruction = T_OPCODE_ADD_I3;
3957 inst.instruction = T_OPCODE_CMP_LR;
3958 inst.instruction |= Rd | (Rs << 3);
3962 if (move == THUMB_MOVE)
3963 inst.instruction = T_OPCODE_MOV_HR;
3965 inst.instruction = T_OPCODE_CMP_HR;
3968 inst.instruction |= THUMB_H1;
3971 inst.instruction |= THUMB_H2;
3973 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
3980 inst.error = "only lo regs allowed with immediate";
3984 if (move == THUMB_MOVE)
3985 inst.instruction = T_OPCODE_MOV_I8;
3987 inst.instruction = T_OPCODE_CMP_I8;
3989 inst.instruction |= Rd << 8;
3991 if (inst.reloc.exp.X_op != O_constant)
3992 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
3995 unsigned value = inst.reloc.exp.X_add_number;
3999 inst.error = "invalid immediate";
4003 inst.instruction |= value;
4011 thumb_load_store (str, load_store, size)
4016 int Rd, Rb, Ro = FAIL;
4021 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4022 || skip_past_comma (&str) == FAIL)
4025 inst.error = bad_args;
4032 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4035 if (skip_past_comma (&str) != FAIL)
4040 if (my_get_expression (&inst.reloc.exp, &str))
4043 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4048 inst.reloc.exp.X_op = O_constant;
4049 inst.reloc.exp.X_add_number = 0;
4054 inst.error = "expected ']'";
4059 else if (*str == '=')
4065 if (my_get_expression (&inst.reloc.exp, &str))
4068 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4069 inst.reloc.pc_rel = 1;
4070 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
4071 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4076 if (Rb == REG_PC || Rb == REG_SP)
4078 if (size != THUMB_WORD)
4080 inst.error = "byte or halfword not valid for base register";
4083 else if (Rb == REG_PC && load_store != THUMB_LOAD)
4085 inst.error = "R15 based store not allowed";
4088 else if (Ro != FAIL)
4090 inst.error = "Invalid base register for register offset";
4095 inst.instruction = T_OPCODE_LDR_PC;
4096 else if (load_store == THUMB_LOAD)
4097 inst.instruction = T_OPCODE_LDR_SP;
4099 inst.instruction = T_OPCODE_STR_SP;
4101 inst.instruction |= Rd << 8;
4102 if (inst.reloc.exp.X_op == O_constant)
4104 unsigned offset = inst.reloc.exp.X_add_number;
4106 if (offset & ~0x3fc)
4108 inst.error = "invalid offset";
4112 inst.instruction |= offset >> 2;
4115 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4119 inst.error = "invalid base register in load/store";
4122 else if (Ro == FAIL)
4124 /* Immediate offset */
4125 if (size == THUMB_WORD)
4126 inst.instruction = (load_store == THUMB_LOAD
4127 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
4128 else if (size == THUMB_HALFWORD)
4129 inst.instruction = (load_store == THUMB_LOAD
4130 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
4132 inst.instruction = (load_store == THUMB_LOAD
4133 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
4135 inst.instruction |= Rd | (Rb << 3);
4137 if (inst.reloc.exp.X_op == O_constant)
4139 unsigned offset = inst.reloc.exp.X_add_number;
4141 if (offset & ~(0x1f << size))
4143 inst.error = "Invalid offset";
4146 inst.instruction |= offset << 6;
4149 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4153 /* Register offset */
4154 if (size == THUMB_WORD)
4155 inst.instruction = (load_store == THUMB_LOAD
4156 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
4157 else if (size == THUMB_HALFWORD)
4158 inst.instruction = (load_store == THUMB_LOAD
4159 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
4161 inst.instruction = (load_store == THUMB_LOAD
4162 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
4164 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4170 /* Handle the Format 4 instructions that do not have equivalents in other
4171 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4182 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4185 if (skip_past_comma (&str) == FAIL
4186 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4189 inst.error = bad_args;
4193 if (skip_past_comma (&str) != FAIL)
4195 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4196 (It isn't allowed for CMP either, but that isn't handled by this
4198 if (inst.instruction == T_OPCODE_TST
4199 || inst.instruction == T_OPCODE_CMN
4200 || inst.instruction == T_OPCODE_NEG
4201 || inst.instruction == T_OPCODE_MVN)
4203 inst.error = bad_args;
4207 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4212 inst.error = "dest and source1 one must be the same register";
4218 if (inst.instruction == T_OPCODE_MUL
4220 as_tsktsk ("Rs and Rd must be different in MUL");
4222 inst.instruction |= Rd | (Rs << 3);
4230 thumb_add_sub (str, 0);
4237 thumb_shift (str, THUMB_ASR);
4244 if (my_get_expression (&inst.reloc.exp, &str))
4246 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
4247 inst.reloc.pc_rel = 1;
4260 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4263 /* This sets THUMB_H2 from the top bit of reg. */
4264 inst.instruction |= reg << 3;
4266 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4267 should cause the alignment to be checked once it is known. This is
4268 because BX PC only works if the instruction is word aligned. */
4277 thumb_mov_compare (str, THUMB_COMPARE);
4290 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4294 as_warn ("Inserted missing '!': load/store multiple always writes back base register");
4298 if (skip_past_comma (&str) == FAIL
4299 || (range = reg_list (&str)) == FAIL)
4302 inst.error = bad_args;
4306 if (inst.reloc.type != BFD_RELOC_NONE)
4308 /* This really doesn't seem worth it. */
4309 inst.reloc.type = BFD_RELOC_NONE;
4310 inst.error = "Expression too complex";
4316 inst.error = "only lo-regs valid in load/store multiple";
4320 inst.instruction |= (Rb << 8) | range;
4328 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4335 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4342 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4354 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4355 || skip_past_comma (&str) == FAIL
4357 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4358 || skip_past_comma (&str) == FAIL
4359 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4363 inst.error = "Syntax: ldrs[b] Rd, [Rb, Ro]";
4367 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4375 thumb_shift (str, THUMB_LSL);
4382 thumb_shift (str, THUMB_LSR);
4389 thumb_mov_compare (str, THUMB_MOVE);
4401 if ((range = reg_list (&str)) == FAIL)
4404 inst.error = bad_args;
4408 if (inst.reloc.type != BFD_RELOC_NONE)
4410 /* This really doesn't seem worth it. */
4411 inst.reloc.type = BFD_RELOC_NONE;
4412 inst.error = "Expression too complex";
4418 if ((inst.instruction == T_OPCODE_PUSH
4419 && (range & ~0xff) == 1 << REG_LR)
4420 || (inst.instruction == T_OPCODE_POP
4421 && (range & ~0xff) == 1 << REG_PC))
4423 inst.instruction |= THUMB_PP_PC_LR;
4428 inst.error = "invalid register list to push/pop instruction";
4433 inst.instruction |= range;
4441 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4448 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4455 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4462 thumb_add_sub (str, 1);
4472 if (my_get_expression (&inst.reloc.exp, &str))
4475 inst.reloc.type = BFD_RELOC_ARM_SWI;
4484 /* This is a pseudo-op of the form "adr rd, label" to be converted
4485 into a relative address of the form "add rd, pc, #label-.-8" */
4489 if (reg_required_here (&str, 8) == FAIL
4490 || skip_past_comma (&str) == FAIL
4491 || my_get_expression (&inst.reloc.exp, &str))
4494 inst.error = bad_args;
4498 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4499 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
4500 inst.reloc.pc_rel = 1;
4501 inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
4509 int len = strlen (reg_table[entry].name) + 2;
4510 char *buf = (char *) xmalloc (len);
4511 char *buf2 = (char *) xmalloc (len);
4514 #ifdef REGISTER_PREFIX
4515 buf[i++] = REGISTER_PREFIX;
4518 strcpy (buf + i, reg_table[entry].name);
4520 for (i = 0; buf[i]; i++)
4521 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
4525 hash_insert (arm_reg_hsh, buf, (PTR) ®_table[entry]);
4526 hash_insert (arm_reg_hsh, buf2, (PTR) ®_table[entry]);
4530 insert_reg_alias (str, regnum)
4534 struct reg_entry *new =
4535 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
4536 char *name = xmalloc (strlen (str) + 1);
4540 new->number = regnum;
4542 hash_insert (arm_reg_hsh, name, (PTR) new);
4546 set_constant_flonums ()
4550 for (i = 0; i < NUM_FLOAT_VALS; i++)
4551 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
4560 if ((arm_ops_hsh = hash_new ()) == NULL
4561 || (arm_tops_hsh = hash_new ()) == NULL
4562 || (arm_cond_hsh = hash_new ()) == NULL
4563 || (arm_shift_hsh = hash_new ()) == NULL
4564 || (arm_reg_hsh = hash_new ()) == NULL
4565 || (arm_psr_hsh = hash_new ()) == NULL)
4566 as_fatal ("Virtual memory exhausted");
4568 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
4569 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
4570 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
4571 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
4572 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
4573 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
4574 for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
4575 hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
4576 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
4577 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
4579 for (i = 0; reg_table[i].name; i++)
4582 set_constant_flonums ();
4585 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4586 for use in the a.out file, and stores them in the array pointed to by buf.
4587 This knows about the endian-ness of the target machine and does
4588 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4589 2 (short) and 4 (long) Floating numbers are put out as a series of
4590 LITTLENUMS (shorts, here at least)
4593 md_number_to_chars (buf, val, n)
4598 if (target_big_endian)
4599 number_to_chars_bigendian (buf, val, n);
4601 number_to_chars_littleendian (buf, val, n);
4605 md_chars_to_number (buf, n)
4610 unsigned char *where = (unsigned char *) buf;
4612 if (target_big_endian)
4617 result |= (*where++ & 255);
4625 result |= (where[n] & 255);
4632 /* Turn a string in input_line_pointer into a floating point constant
4633 of type TYPE, and store the appropriate bytes in *litP. The number
4634 of LITTLENUMS emitted is stored in *sizeP . An error message is
4635 returned, or NULL on OK.
4637 Note that fp constants aren't represent in the normal way on the ARM.
4638 In big endian mode, things are as expected. However, in little endian
4639 mode fp constants are big-endian word-wise, and little-endian byte-wise
4640 within the words. For example, (double) 1.1 in big endian mode is
4641 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4642 the byte sequence 99 99 f1 3f 9a 99 99 99.
4644 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
4647 md_atof (type, litP, sizeP)
4653 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4685 return "Bad call to MD_ATOF()";
4688 t = atof_ieee (input_line_pointer, type, words);
4690 input_line_pointer = t;
4693 if (target_big_endian)
4695 for (i = 0; i < prec; i++)
4697 md_number_to_chars (litP, (valueT) words[i], 2);
4703 /* For a 4 byte float the order of elements in `words' is 1 0. For an
4704 8 byte float the order is 1 0 3 2. */
4705 for (i = 0; i < prec; i += 2)
4707 md_number_to_chars (litP, (valueT) words[i + 1], 2);
4708 md_number_to_chars (litP + 2, (valueT) words[i], 2);
4716 /* We have already put the pipeline compensation in the instruction */
4719 md_pcrel_from (fixP)
4722 if (fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
4723 && fixP->fx_subsy == NULL)
4724 return 0; /* HACK */
4726 return fixP->fx_where + fixP->fx_frag->fr_address;
4729 /* Round up a section size to the appropriate boundary. */
4731 md_section_align (segment, size)
4735 /* Round all sects to multiple of 4 */
4736 return (size + 3) & ~3;
4739 /* We have no need to default values of symbols. */
4743 md_undefined_symbol (name)
4749 /* arm_reg_parse () := if it looks like a register, return its token and
4750 advance the pointer. */
4754 register char **ccp;
4759 struct reg_entry *reg;
4761 #ifdef REGISTER_PREFIX
4762 if (*start != REGISTER_PREFIX)
4767 #ifdef OPTIONAL_REGISTER_PREFIX
4768 if (*p == OPTIONAL_REGISTER_PREFIX)
4772 if (!isalpha (*p) || !is_name_beginner (*p))
4776 while (isalpha (c) || isdigit (c) || c == '_')
4780 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
4794 register char **ccp;
4798 CONST struct asm_psr *psr;
4802 while (isalpha (c) || c == '_')
4806 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
4819 md_apply_fix3 (fixP, val, seg)
4824 offsetT value = *val;
4825 offsetT newval, temp;
4827 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
4828 arm_fix_data *arm_data = (arm_fix_data *) fixP->tc_fix_data;
4830 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
4832 /* Note whether this will delete the relocation. */
4833 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
4836 /* If this symbol is in a different section then we need to leave it for
4837 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
4838 so we have to undo it's effects here. */
4841 if (S_IS_DEFINED (fixP->fx_addsy)
4842 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
4843 value += md_pcrel_from (fixP);
4846 fixP->fx_addnumber = value; /* Remember value for emit_reloc */
4848 switch (fixP->fx_r_type)
4850 case BFD_RELOC_ARM_IMMEDIATE:
4851 newval = validate_immediate (value);
4852 temp = md_chars_to_number (buf, INSN_SIZE);
4854 /* If the instruction will fail, see if we can fix things up by
4855 changing the opcode. */
4857 && (newval = negate_data_op (&temp, value)) == FAIL)
4859 as_bad_where (fixP->fx_file, fixP->fx_line,
4860 "invalid constant after fixup\n");
4864 newval |= (temp & 0xfffff000);
4865 md_number_to_chars (buf, newval, INSN_SIZE);
4868 case BFD_RELOC_ARM_OFFSET_IMM:
4870 if ((value = validate_offset_imm (value, 0)) == FAIL)
4872 as_bad ("bad immediate value for offset (%d)", val);
4878 newval = md_chars_to_number (buf, INSN_SIZE);
4879 newval &= 0xff7ff000;
4880 newval |= value | (sign ? INDEX_UP : 0);
4881 md_number_to_chars (buf, newval, INSN_SIZE);
4884 case BFD_RELOC_ARM_OFFSET_IMM8:
4885 case BFD_RELOC_ARM_HWLITERAL:
4887 if ((value = validate_offset_imm (value, 1)) == FAIL)
4889 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
4890 as_bad_where (fixP->fx_file, fixP->fx_line,
4891 "invalid literal constant: pool needs to be closer\n");
4893 as_bad ("bad immediate value for offset (%d)", value);
4900 newval = md_chars_to_number (buf, INSN_SIZE);
4901 newval &= 0xff7ff0f0;
4902 newval |= ((value >> 4) << 8) | value & 0xf | (sign ? INDEX_UP : 0);
4903 md_number_to_chars (buf, newval, INSN_SIZE);
4906 case BFD_RELOC_ARM_LITERAL:
4911 if ((value = validate_offset_imm (value, 0)) == FAIL)
4913 as_bad_where (fixP->fx_file, fixP->fx_line,
4914 "invalid literal constant: pool needs to be closer\n");
4918 newval = md_chars_to_number (buf, INSN_SIZE);
4919 newval &= 0xff7ff000;
4920 newval |= value | (sign ? INDEX_UP : 0);
4921 md_number_to_chars (buf, newval, INSN_SIZE);
4924 case BFD_RELOC_ARM_SHIFT_IMM:
4925 newval = md_chars_to_number (buf, INSN_SIZE);
4926 if (((unsigned long) value) > 32
4928 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
4930 as_bad_where (fixP->fx_file, fixP->fx_line,
4931 "shift expression is too large");
4936 newval &= ~0x60; /* Shifts of zero must be done as lsl */
4937 else if (value == 32)
4939 newval &= 0xfffff07f;
4940 newval |= (value & 0x1f) << 7;
4941 md_number_to_chars (buf, newval , INSN_SIZE);
4944 case BFD_RELOC_ARM_SWI:
4945 if (arm_data->thumb_mode)
4947 if (((unsigned long) value) > 0xff)
4948 as_bad_where (fixP->fx_file, fixP->fx_line,
4949 "Invalid swi expression");
4950 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
4952 md_number_to_chars (buf, newval, THUMB_SIZE);
4956 if (((unsigned long) value) > 0x00ffffff)
4957 as_bad_where (fixP->fx_file, fixP->fx_line,
4958 "Invalid swi expression");
4959 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
4961 md_number_to_chars (buf, newval , INSN_SIZE);
4965 case BFD_RELOC_ARM_MULTI:
4966 if (((unsigned long) value) > 0xffff)
4967 as_bad_where (fixP->fx_file, fixP->fx_line,
4968 "Invalid expression in load/store multiple");
4969 newval = value | md_chars_to_number (buf, INSN_SIZE);
4970 md_number_to_chars (buf, newval, INSN_SIZE);
4973 case BFD_RELOC_ARM_PCREL_BRANCH:
4974 if (arm_data->thumb_mode)
4976 unsigned long newval2;
4977 newval = md_chars_to_number (buf, THUMB_SIZE);
4978 if (fixP->fx_size == 4)
4982 newval2 = md_chars_to_number (buf, THUMB_SIZE);
4983 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
4984 if (diff & 0x400000)
4987 if ((value & 0x400000) && ((value & ~0x3fffff) != ~0x3fffff))
4988 as_bad_where (fixP->fx_file, fixP->fx_line,
4989 "Branch with link out of range");
4991 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
4992 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
4993 md_number_to_chars (buf, newval, THUMB_SIZE);
4994 md_number_to_chars (buf, newval2, THUMB_SIZE);
4998 if (newval == T_OPCODE_BRANCH)
5000 unsigned long diff = (newval & 0x7ff) << 1;
5005 if ((value & 0x800) && ((value & ~0x7ff) != ~0x7ff))
5006 as_bad_where (fixP->fx_file, fixP->fx_line,
5007 "Branch out of range");
5008 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5012 unsigned long diff = (newval & 0xff) << 1;
5017 if ((value & 0x100) && ((value & ~0xff) != ~0xff))
5018 as_bad_where (fixP->fx_file, fixP->fx_line,
5019 "Branch out of range");
5020 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5022 md_number_to_chars (buf, newval, THUMB_SIZE);
5027 value = (value >> 2) & 0x00ffffff;
5028 newval = md_chars_to_number (buf, INSN_SIZE);
5029 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5030 newval = value | (newval & 0xff000000);
5031 md_number_to_chars (buf, newval, INSN_SIZE);
5036 if (fixP->fx_done || fixP->fx_pcrel)
5037 md_number_to_chars (buf, value, 1);
5041 if (fixP->fx_done || fixP->fx_pcrel)
5042 md_number_to_chars (buf, value, 2);
5047 if (fixP->fx_done || fixP->fx_pcrel)
5048 md_number_to_chars (buf, value, 4);
5051 case BFD_RELOC_ARM_CP_OFF_IMM:
5053 if (value < -1023 || value > 1023 || (value & 3))
5054 as_bad_where (fixP->fx_file, fixP->fx_line,
5055 "Illegal value for co-processor offset");
5058 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5059 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5060 md_number_to_chars (buf, newval , INSN_SIZE);
5063 case BFD_RELOC_ARM_THUMB_OFFSET:
5064 newval = md_chars_to_number (buf, THUMB_SIZE);
5065 /* Exactly what ranges, and where the offset is inserted depends on
5066 the type of instruction, we can establish this from the top 4 bits */
5067 switch (newval >> 12)
5069 case 4: /* PC load */
5070 /* PC loads are somewhat odd, bit 2 of the PC is forced to zero
5071 for these loads, so we may need to round up the offset if the
5072 instruction is not word aligned since the final address must
5075 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5076 as_bad_where (fixP->fx_file, fixP->fx_line,
5077 "Invalid offset, target not word aligned");
5079 if ((value + 2) & ~0x3fe)
5080 as_bad_where (fixP->fx_file, fixP->fx_line,
5082 /* Round up, since pc will be rounded down. */
5083 newval |= (value + 2) >> 2;
5086 case 9: /* SP load/store */
5088 as_bad_where (fixP->fx_file, fixP->fx_line,
5090 newval |= value >> 2;
5093 case 6: /* Word load/store */
5095 as_bad_where (fixP->fx_file, fixP->fx_line,
5097 newval |= value << 4; /* 6 - 2 */
5100 case 7: /* Byte load/store */
5102 as_bad_where (fixP->fx_file, fixP->fx_line,
5104 newval |= value << 6;
5107 case 8: /* Halfword load/store */
5109 as_bad_where (fixP->fx_file, fixP->fx_line,
5111 newval |= value << 5; /* 6 - 1 */
5117 md_number_to_chars (buf, newval, THUMB_SIZE);
5120 case BFD_RELOC_ARM_THUMB_ADD:
5121 /* This is a complicated relocation, since we use it for all of
5122 the following immediate relocations:
5125 9bit ADD/SUB SP word-aligned
5126 10bit ADD PC/SP word-aligned
5128 The type of instruction being processed is encoded in the
5134 newval = md_chars_to_number (buf, THUMB_SIZE);
5136 int rd = (newval >> 4) & 0xf;
5137 int rs = newval & 0xf;
5138 int subtract = newval & 0x8000;
5143 as_bad_where (fixP->fx_file, fixP->fx_line,
5144 "Invalid immediate for stack address calculation");
5145 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5146 newval |= value >> 2;
5148 else if (rs == REG_PC || rs == REG_SP)
5152 as_bad_where (fixP->fx_file, fixP->fx_line,
5153 "Invalid immediate for address calculation (value = 0x%08X)", value);
5154 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5155 newval |= value >> 2;
5160 as_bad_where (fixP->fx_file, fixP->fx_line,
5161 "Invalid 8bit immediate");
5162 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5163 newval |= (rd << 8) | value;
5168 as_bad_where (fixP->fx_file, fixP->fx_line,
5169 "Invalid 3bit immediate");
5170 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5171 newval |= rd | (rs << 3) | (value << 6);
5174 md_number_to_chars (buf, newval , THUMB_SIZE);
5177 case BFD_RELOC_ARM_THUMB_IMM:
5178 newval = md_chars_to_number (buf, THUMB_SIZE);
5179 switch (newval >> 11)
5181 case 0x04: /* 8bit immediate MOV */
5182 case 0x05: /* 8bit immediate CMP */
5183 if (value < 0 || value > 255)
5184 as_bad_where (fixP->fx_file, fixP->fx_line,
5185 "Invalid immediate: %d is too large", value);
5192 md_number_to_chars (buf, newval , THUMB_SIZE);
5195 case BFD_RELOC_ARM_THUMB_SHIFT:
5196 /* 5bit shift value (0..31) */
5197 if (value < 0 || value > 31)
5198 as_bad_where (fixP->fx_file, fixP->fx_line,
5199 "Illegal Thumb shift value: %d", value);
5200 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5201 newval |= value << 6;
5202 md_number_to_chars (buf, newval , THUMB_SIZE);
5205 case BFD_RELOC_NONE:
5207 as_bad_where (fixP->fx_file, fixP->fx_line,
5208 "Bad relocation fixup type (%d)\n", fixP->fx_r_type);
5214 /* Translate internal representation of relocation info to BFD target
5217 tc_gen_reloc (section, fixp)
5222 bfd_reloc_code_real_type code;
5224 reloc = (arelent *) xmalloc (sizeof (arelent));
5226 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
5227 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5229 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5230 if (fixp->fx_pcrel == 0)
5231 reloc->addend = fixp->fx_offset;
5233 reloc->addend = fixp->fx_offset = reloc->address;
5235 switch (fixp->fx_r_type)
5240 code = BFD_RELOC_8_PCREL;
5247 code = BFD_RELOC_16_PCREL;
5254 code = BFD_RELOC_32_PCREL;
5258 case BFD_RELOC_ARM_PCREL_BRANCH:
5260 code = fixp->fx_r_type;
5263 case BFD_RELOC_ARM_LITERAL:
5264 case BFD_RELOC_ARM_HWLITERAL:
5265 /* If this is called then the a literal has been referenced across
5266 a section boundry - possibly due to an implicit dump */
5267 as_bad ("Literal referenced across section boundry (Implicit dump?)");
5270 case BFD_RELOC_ARM_IMMEDIATE:
5271 as_bad ("Internal_relocation (type %d) not fixed up (IMMEDIATE)"
5275 case BFD_RELOC_ARM_OFFSET_IMM:
5276 as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"
5280 case BFD_RELOC_ARM_OFFSET_IMM8:
5281 as_bad ("Internal_relocation (type %d) not fixed up (OFFSET_IMM8)"
5285 case BFD_RELOC_ARM_SHIFT_IMM:
5286 as_bad ("Internal_relocation (type %d) not fixed up (SHIFT_IMM)"
5290 case BFD_RELOC_ARM_SWI:
5291 as_bad ("Internal_relocation (type %d) not fixed up (SWI)"
5295 case BFD_RELOC_ARM_MULTI:
5296 as_bad ("Internal_relocation (type %d) not fixed up (MULTI)"
5300 case BFD_RELOC_ARM_CP_OFF_IMM:
5301 as_bad ("Internal_relocation (type %d) not fixed up (CP_OFF_IMM)"
5305 case BFD_RELOC_ARM_THUMB_OFFSET:
5306 as_bad ("Internal_relocation (type %d) not fixed up (THUMB_OFFSET)"
5314 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5315 assert (reloc->howto != 0);
5320 CONST int md_short_jump_size = 4;
5321 CONST int md_long_jump_size = 4;
5323 /* These should never be called on the arm */
5325 md_create_long_jump (ptr, from_addr, to_addr, frag, to_symbol)
5327 addressT from_addr, to_addr;
5331 as_fatal ("md_create_long_jump\n");
5335 md_create_short_jump (ptr, from_addr, to_addr, frag, to_symbol)
5337 addressT from_addr, to_addr;
5341 as_fatal ("md_create_short_jump\n");
5345 md_estimate_size_before_relax (fragP, segtype)
5349 as_fatal ("md_estimate_size_before_relax\n");
5361 as_bad ("%s -- statement `%s'\n", inst.error, str);
5365 to = frag_more (inst.size);
5366 if (thumb_mode && (inst.size > 2))
5368 md_number_to_chars (to, inst.instruction >> 16, 2);
5373 md_number_to_chars (to, inst.instruction, inst.size);
5375 if (inst.reloc.type != BFD_RELOC_NONE)
5376 fix_new_arm (frag_now, to - frag_now->fr_literal,
5377 inst.size, &inst.reloc.exp, inst.reloc.pc_rel,
5388 char *p, *q, *start;
5390 /* Align the instruction */
5391 /* this may not be the right thing to do but ... */
5392 /* arm_align (2, 0); */
5393 listing_prev_line (); /* Defined in listing.h */
5395 /* Align the previous label if needed */
5396 if (last_label_seen != NULL)
5398 last_label_seen->sy_frag = frag_now;
5399 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
5400 S_SET_SEGMENT (last_label_seen, now_seg);
5403 memset (&inst, '\0', sizeof (inst));
5404 inst.reloc.type = BFD_RELOC_NONE;
5407 str++; /* Skip leading white space */
5409 /* scan up to the end of the op-code, which must end in white space or
5411 for (start = p = str; *p != '\0'; p++)
5417 as_bad ("No operator -- statement `%s'\n", str);
5423 CONST struct thumb_opcode *opcode;
5427 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
5431 inst.instruction = opcode->value;
5432 inst.size = opcode->size;
5433 (*opcode->parms)(p);
5434 output_inst (start);
5440 CONST struct asm_opcode *opcode;
5442 inst.size = INSN_SIZE;
5443 /* p now points to the end of the opcode, probably white space, but we
5444 have to break the opcode up in case it contains condionals and flags;
5445 keep trying with progressively smaller basic instructions until one
5446 matches, or we run out of opcode. */
5447 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
5448 for (; q != str; q--)
5452 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
5454 if (opcode && opcode->template)
5456 unsigned long flag_bits = 0;
5459 /* Check that this instruction is supported for this CPU */
5460 if ((opcode->variants & cpu_variant) == 0)
5463 inst.instruction = opcode->value;
5464 if (q == p) /* Just a simple opcode */
5466 if (opcode->comp_suffix != 0)
5467 as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
5468 opcode->comp_suffix);
5471 inst.instruction |= COND_ALWAYS;
5472 (*opcode->parms)(q, 0);
5474 output_inst (start);
5478 /* Now check for a conditional */
5482 CONST struct asm_cond *cond;
5486 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
5490 if (cond->value == 0xf0000000)
5492 "Warning: Use of the 'nv' conditional is deprecated\n");
5494 inst.instruction |= cond->value;
5498 inst.instruction |= COND_ALWAYS;
5501 inst.instruction |= COND_ALWAYS;
5503 /* if there is a compulsory suffix, it should come here, before
5504 any optional flags. */
5505 if (opcode->comp_suffix)
5507 CONST char *s = opcode->comp_suffix;
5519 as_bad ("Opcode `%s' must have suffix from <%s>\n", str,
5520 opcode->comp_suffix);
5527 /* The remainder, if any should now be flags for the instruction;
5528 Scan these checking each one found with the opcode. */
5532 CONST struct asm_flg *flag = opcode->flags;
5541 for (flagno = 0; flag[flagno].template; flagno++)
5543 if (! strcmp (r, flag[flagno].template))
5545 flag_bits |= flag[flagno].set_bits;
5551 if (! flag[flagno].template)
5558 (*opcode->parms) (p, flag_bits);
5559 output_inst (start);
5568 /* It wasn't an instruction, but it might be a register alias of the form
5578 if (*q && !strncmp (q, ".req ", 4))
5581 if ((reg = arm_reg_parse (&str)) == FAIL)
5589 for (r = q; *r != '\0'; r++)
5599 regnum = arm_reg_parse (&q);
5603 insert_reg_alias (str, regnum);
5617 as_bad ("bad instruction `%s'", start);
5622 * Invocation line includes a switch not recognized by the base assembler.
5623 * See if it's a processor-specific option. These are:
5624 * Cpu variants, the arm part is optional:
5625 * -m[arm]1 Currently not supported.
5626 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
5627 * -m[arm]3 Arm 3 processor
5628 * -m[arm]6, Arm 6 processors
5629 * -m[arm]7[t][[d]m] Arm 7 processors
5630 * -mall All (except the ARM1)
5632 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
5633 * -mfpe-old (No float load/store multiples)
5634 * -mno-fpu Disable all floating point instructions
5635 * Run-time endian selection:
5636 * -EB big endian cpu
5637 * -EL little endian cpu
5640 CONST char *md_shortopts = "m:";
5641 struct option md_longopts[] = {
5642 #ifdef ARM_BI_ENDIAN
5643 #define OPTION_EB (OPTION_MD_BASE + 0)
5644 {"EB", no_argument, NULL, OPTION_EB},
5645 #define OPTION_EL (OPTION_MD_BASE + 1)
5646 {"EL", no_argument, NULL, OPTION_EL},
5648 {NULL, no_argument, NULL, 0}
5650 size_t md_longopts_size = sizeof (md_longopts);
5653 md_parse_option (c, arg)
5661 #ifdef ARM_BI_ENDIAN
5663 target_big_endian = 1;
5666 target_big_endian = 0;
5674 if (! strcmp (str, "fpa10"))
5675 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
5676 else if (! strcmp (str, "fpa11"))
5677 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
5678 else if (! strcmp (str, "fpe-old"))
5679 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
5685 if (! strcmp (str, "no-fpu"))
5686 cpu_variant &= ~FPU_ALL;
5690 /* Limit assembler to generating only Thumb instructions: */
5691 if (! strcmp (str, "thumb"))
5693 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
5694 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
5702 if (! strcmp (str, "all"))
5704 cpu_variant = ARM_ALL | FPU_ALL;
5708 /* Strip off optional "arm" */
5709 if (! strncmp (str, "arm", 3))
5715 if (! strcmp (str, "1"))
5716 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
5722 if (! strcmp (str, "2"))
5723 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
5724 else if (! strcmp (str, "250"))
5725 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
5731 if (! strcmp (str, "3"))
5732 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
5738 if (! strcmp (str, "6"))
5739 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
5745 str++; /* eat the '7' */
5746 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
5752 cpu_variant |= ARM_THUMB;
5756 cpu_variant |= ARM_LONGMUL;
5759 case 'd': /* debug */
5760 case 'i': /* embedded ice */
5761 /* Included for completeness in ARM processor
5773 as_bad ("Invalid architecture -m%s", arg);
5791 "-m[arm]1, -m[arm]2, -m[arm]250,\n-m[arm]3, -m[arm]6, -m[arm]7[t][[d]m]\n\
5792 -mthumb\t\t\tselect processor architecture\n\
5793 -mall\t\t\tallow any instruction\n\
5794 -mfpa10, -mfpa11\tselect floating point architecture\n\
5795 -mfpe-old\t\tdon't allow floating-point multiple instructions\n\
5796 -mno-fpu\t\tdon't allow any floating-point instructions.\n");
5797 #ifdef ARM_BI_ENDIAN
5799 "-EB\t\t\tassemble code for a big endian cpu\n\
5800 -EL\t\t\tassemble code for a little endian cpu\n");
5804 /* We need to be able to fix up arbitrary expressions in some statements.
5805 This is so that we can handle symbols that are an arbitrary distance from
5806 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
5807 which returns part of an address in a form which will be valid for
5808 a data instruction. We do this by pushing the expression into a symbol
5809 in the expr_section, and creating a fix for that. */
5812 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
5821 arm_fix_data *arm_data;
5829 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
5833 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
5838 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
5839 arm_data = (arm_fix_data *) obstack_alloc (¬es, sizeof (arm_fix_data));
5840 new_fix->tc_fix_data = (PTR) arm_data;
5841 arm_data->thumb_mode = thumb_mode;
5846 /* A good place to do this, although this was probably not intended
5847 * for this kind of use. We need to dump the literal pool before
5848 * references are made to a null symbol pointer. */
5850 arm_after_pass_hook (ignore)
5853 if (current_poolP != NULL)
5855 subseg_set (text_section, 0); /* Put it at the end of text section */
5857 listing_prev_line ();
5862 arm_start_line_hook ()
5864 last_label_seen = NULL;
5868 arm_frob_label (sym)
5871 last_label_seen = sym;
5877 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
5879 *input_line_pointer = '/';
5880 input_line_pointer += 5;
5881 *input_line_pointer = 0;
5888 arm_canonicalize_symbol_name (name)
5893 if (thumb_mode && (len = strlen (name)) > 5
5894 && ! strcmp (name + len - 5, "/data"))
5896 *(name + len - 5) = 0;