Initial revision
[binutils.git] / gas / config / tc-arm.c
blobd898bf0ecd01be9a31ec7b8dd7d7021bc20302e9
1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
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
21 02111-1307, USA. */
23 #include <ctype.h>
24 #include <string.h>
25 #define NO_RELOC 0
26 #include "as.h"
28 /* need TARGET_CPU */
29 #include "config.h"
30 #include "subsegs.h"
31 #include "obstack.h"
32 #include "symbols.h"
33 #include "listing.h"
35 #ifdef OBJ_ELF
36 #include "elf/arm.h"
37 #endif
39 /* Types of processor to assemble for. */
40 #define ARM_1 0x00000001
41 #define ARM_2 0x00000002
42 #define ARM_3 0x00000004
43 #define ARM_250 ARM_3
44 #define ARM_6 0x00000008
45 #define ARM_7 ARM_6 /* same core instruction set */
46 #define ARM_8 ARM_6 /* same core instruction set */
47 #define ARM_9 ARM_6 /* same core instruction set */
48 #define ARM_CPU_MASK 0x0000000f
50 /* The following bitmasks control CPU extensions (ARM7 onwards): */
51 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
52 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
53 #define ARM_THUMB 0x00000040 /* allow BX instruction */
55 #define ARM_ARCHv4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
57 /* Some useful combinations: */
58 #define ARM_ANY 0x00ffffff
59 #define ARM_2UP 0x00fffffe
60 #define ARM_ALL ARM_2UP /* Not arm1 only */
61 #define ARM_3UP 0x00fffffc
62 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
64 #define FPU_CORE 0x80000000
65 #define FPU_FPA10 0x40000000
66 #define FPU_FPA11 0x40000000
67 #define FPU_NONE 0
69 /* Some useful combinations */
70 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
71 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
74 #ifndef CPU_DEFAULT
75 #if defined __thumb__
76 #define CPU_DEFAULT (ARM_ARCHv4 | ARM_THUMB)
77 #else
78 #define CPU_DEFAULT ARM_ALL
79 #endif
80 #endif
82 #ifndef FPU_DEFAULT
83 #define FPU_DEFAULT FPU_ALL
84 #endif
86 #define streq(a,b) (strcmp (a, b) == 0)
88 static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
89 static int target_oabi = 0;
91 #if defined OBJ_COFF || defined OBJ_ELF
92 /* Flags stored in private area of BFD structure */
93 static boolean uses_apcs_26 = false;
94 static boolean support_interwork = false;
95 static boolean uses_apcs_float = false;
96 static boolean pic_code = false;
97 #endif
99 /* This array holds the chars that always start a comment. If the
100 pre-processor is disabled, these aren't very useful */
101 CONST char comment_chars[] = "@";
103 /* This array holds the chars that only start a comment at the beginning of
104 a line. If the line seems to have the form '# 123 filename'
105 .line and .file directives will appear in the pre-processed output */
106 /* Note that input_file.c hand checks for '#' at the beginning of the
107 first line of the input file. This is because the compiler outputs
108 #NO_APP at the beginning of its output. */
109 /* Also note that comments like this one will always work. */
110 CONST char line_comment_chars[] = "#";
112 #ifdef TE_LINUX
113 CONST char line_separator_chars[] = ";";
114 #else
115 CONST char line_separator_chars[] = "";
116 #endif
118 /* Chars that can be used to separate mant from exp in floating point nums */
119 CONST char EXP_CHARS[] = "eE";
121 /* Chars that mean this number is a floating point constant */
122 /* As in 0f12.456 */
123 /* or 0d1.2345e12 */
125 CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
127 /* Prefix characters that indicate the start of an immediate
128 value. */
129 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
131 #ifdef OBJ_ELF
132 symbolS * GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
133 #endif
135 CONST int md_reloc_size = 8; /* Size of relocation record */
137 static int thumb_mode = 0; /* non-zero if assembling thumb instructions */
139 typedef struct arm_fix
141 int thumb_mode;
142 } arm_fix_data;
144 struct arm_it
146 CONST char * error;
147 unsigned long instruction;
148 int suffix;
149 int size;
150 struct
152 bfd_reloc_code_real_type type;
153 expressionS exp;
154 int pc_rel;
155 } reloc;
158 struct arm_it inst;
160 struct asm_shift
162 CONST char * template;
163 unsigned long value;
166 static CONST struct asm_shift shift[] =
168 {"asl", 0},
169 {"lsl", 0},
170 {"lsr", 0x00000020},
171 {"asr", 0x00000040},
172 {"ror", 0x00000060},
173 {"rrx", 0x00000060},
174 {"ASL", 0},
175 {"LSL", 0},
176 {"LSR", 0x00000020},
177 {"ASR", 0x00000040},
178 {"ROR", 0x00000060},
179 {"RRX", 0x00000060}
182 #define NO_SHIFT_RESTRICT 1
183 #define SHIFT_RESTRICT 0
185 #define NUM_FLOAT_VALS 8
187 CONST char * fp_const[] =
189 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
192 /* Number of littlenums required to hold an extended precision number */
193 #define MAX_LITTLENUMS 6
195 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
197 #define FAIL (-1)
198 #define SUCCESS (0)
200 #define SUFF_S 1
201 #define SUFF_D 2
202 #define SUFF_E 3
203 #define SUFF_P 4
205 #define CP_T_X 0x00008000
206 #define CP_T_Y 0x00400000
207 #define CP_T_Pre 0x01000000
208 #define CP_T_UD 0x00800000
209 #define CP_T_WB 0x00200000
211 #define CONDS_BIT (0x00100000)
212 #define LOAD_BIT (0x00100000)
213 #define TRANS_BIT (0x00200000)
215 struct asm_cond
217 CONST char * template;
218 unsigned long value;
221 /* This is to save a hash look-up in the common case */
222 #define COND_ALWAYS 0xe0000000
224 static CONST struct asm_cond conds[] =
226 {"eq", 0x00000000},
227 {"ne", 0x10000000},
228 {"cs", 0x20000000}, {"hs", 0x20000000},
229 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
230 {"mi", 0x40000000},
231 {"pl", 0x50000000},
232 {"vs", 0x60000000},
233 {"vc", 0x70000000},
234 {"hi", 0x80000000},
235 {"ls", 0x90000000},
236 {"ge", 0xa0000000},
237 {"lt", 0xb0000000},
238 {"gt", 0xc0000000},
239 {"le", 0xd0000000},
240 {"al", 0xe0000000},
241 {"nv", 0xf0000000}
244 /* Warning: If the top bit of the set_bits is set, then the standard
245 instruction bitmask is ignored, and the new bitmask is taken from
246 the set_bits: */
247 struct asm_flg
249 CONST char * template; /* Basic flag string */
250 unsigned long set_bits; /* Bits to set */
253 static CONST struct asm_flg s_flag[] =
255 {"s", CONDS_BIT},
256 {NULL, 0}
259 static CONST struct asm_flg ldr_flags[] =
261 {"b", 0x00400000},
262 {"t", TRANS_BIT},
263 {"bt", 0x00400000 | TRANS_BIT},
264 {"h", 0x801000b0},
265 {"sh", 0x801000f0},
266 {"sb", 0x801000d0},
267 {NULL, 0}
270 static CONST struct asm_flg str_flags[] =
272 {"b", 0x00400000},
273 {"t", TRANS_BIT},
274 {"bt", 0x00400000 | TRANS_BIT},
275 {"h", 0x800000b0},
276 {NULL, 0}
279 static CONST struct asm_flg byte_flag[] =
281 {"b", 0x00400000},
282 {NULL, 0}
285 static CONST struct asm_flg cmp_flags[] =
287 {"s", CONDS_BIT},
288 {"p", 0x0010f000},
289 {NULL, 0}
292 static CONST struct asm_flg ldm_flags[] =
294 {"ed", 0x01800000},
295 {"fd", 0x00800000},
296 {"ea", 0x01000000},
297 {"fa", 0x08000000},
298 {"ib", 0x01800000},
299 {"ia", 0x00800000},
300 {"db", 0x01000000},
301 {"da", 0x08000000},
302 {NULL, 0}
305 static CONST struct asm_flg stm_flags[] =
307 {"ed", 0x08000000},
308 {"fd", 0x01000000},
309 {"ea", 0x00800000},
310 {"fa", 0x01800000},
311 {"ib", 0x01800000},
312 {"ia", 0x00800000},
313 {"db", 0x01000000},
314 {"da", 0x08000000},
315 {NULL, 0}
318 static CONST struct asm_flg lfm_flags[] =
320 {"fd", 0x00800000},
321 {"ea", 0x01000000},
322 {NULL, 0}
325 static CONST struct asm_flg sfm_flags[] =
327 {"fd", 0x01000000},
328 {"ea", 0x00800000},
329 {NULL, 0}
332 static CONST struct asm_flg round_flags[] =
334 {"p", 0x00000020},
335 {"m", 0x00000040},
336 {"z", 0x00000060},
337 {NULL, 0}
340 /* The implementation of the FIX instruction is broken on some assemblers,
341 in that it accepts a precision specifier as well as a rounding specifier,
342 despite the fact that this is meaningless. To be more compatible, we
343 accept it as well, though of course it does not set any bits. */
344 static CONST struct asm_flg fix_flags[] =
346 {"p", 0x00000020},
347 {"m", 0x00000040},
348 {"z", 0x00000060},
349 {"sp", 0x00000020},
350 {"sm", 0x00000040},
351 {"sz", 0x00000060},
352 {"dp", 0x00000020},
353 {"dm", 0x00000040},
354 {"dz", 0x00000060},
355 {"ep", 0x00000020},
356 {"em", 0x00000040},
357 {"ez", 0x00000060},
358 {NULL, 0}
361 static CONST struct asm_flg except_flag[] =
363 {"e", 0x00400000},
364 {NULL, 0}
367 static CONST struct asm_flg cplong_flag[] =
369 {"l", 0x00400000},
370 {NULL, 0}
373 struct asm_psr
375 CONST char * template;
376 unsigned long number;
379 #define PSR_FIELD_MASK 0x000f0000
381 #define PSR_FLAGS 0x00080000
382 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
383 #define PSR_ALL 0x00090000
385 #define CPSR_ALL 0
386 #define SPSR_ALL 1
387 #define CPSR_FLG 2
388 #define SPSR_FLG 3
389 #define CPSR_CTL 4
390 #define SPSR_CTL 5
392 static CONST struct asm_psr psrs[] =
394 /* Valid <psr>'s */
395 {"cpsr", CPSR_ALL},
396 {"cpsr_all", CPSR_ALL},
397 {"spsr", SPSR_ALL},
398 {"spsr_all", SPSR_ALL},
400 /* Valid <psrf>'s */
401 {"cpsr_flg", CPSR_FLG},
402 {"spsr_flg", SPSR_FLG},
404 /* Valid <psrc>'s */
405 {"cpsr_c", CPSR_CTL},
406 {"cpsr_ctl", CPSR_CTL},
407 {"spsr_c", SPSR_CTL},
408 {"spsr_ctl", SPSR_CTL}
411 /* Functions called by parser */
412 /* ARM instructions */
413 static void do_arit PARAMS ((char *operands, unsigned long flags));
414 static void do_cmp PARAMS ((char *operands, unsigned long flags));
415 static void do_mov PARAMS ((char *operands, unsigned long flags));
416 static void do_ldst PARAMS ((char *operands, unsigned long flags));
417 static void do_ldmstm PARAMS ((char *operands, unsigned long flags));
418 static void do_branch PARAMS ((char *operands, unsigned long flags));
419 static void do_swi PARAMS ((char *operands, unsigned long flags));
420 /* Pseudo Op codes */
421 static void do_adr PARAMS ((char *operands, unsigned long flags));
422 static void do_nop PARAMS ((char *operands, unsigned long flags));
423 /* ARM 2 */
424 static void do_mul PARAMS ((char *operands, unsigned long flags));
425 static void do_mla PARAMS ((char *operands, unsigned long flags));
426 /* ARM 3 */
427 static void do_swap PARAMS ((char *operands, unsigned long flags));
428 /* ARM 6 */
429 static void do_msr PARAMS ((char *operands, unsigned long flags));
430 static void do_mrs PARAMS ((char *operands, unsigned long flags));
431 /* ARM 7M */
432 static void do_mull PARAMS ((char *operands, unsigned long flags));
433 /* ARM THUMB */
434 static void do_bx PARAMS ((char *operands, unsigned long flags));
436 /* Coprocessor Instructions */
437 static void do_cdp PARAMS ((char *operands, unsigned long flags));
438 static void do_lstc PARAMS ((char *operands, unsigned long flags));
439 static void do_co_reg PARAMS ((char *operands, unsigned long flags));
440 static void do_fp_ctrl PARAMS ((char *operands, unsigned long flags));
441 static void do_fp_ldst PARAMS ((char *operands, unsigned long flags));
442 static void do_fp_ldmstm PARAMS ((char *operands, unsigned long flags));
443 static void do_fp_dyadic PARAMS ((char *operands, unsigned long flags));
444 static void do_fp_monadic PARAMS ((char *operands, unsigned long flags));
445 static void do_fp_cmp PARAMS ((char *operands, unsigned long flags));
446 static void do_fp_from_reg PARAMS ((char *operands, unsigned long flags));
447 static void do_fp_to_reg PARAMS ((char *operands, unsigned long flags));
449 static void fix_new_arm PARAMS ((fragS *frag, int where,
450 short int size, expressionS *exp,
451 int pc_rel, int reloc));
452 static int arm_reg_parse PARAMS ((char **ccp));
453 static int arm_psr_parse PARAMS ((char **ccp));
454 static void symbol_locate PARAMS ((symbolS *, CONST char *, segT,
455 valueT, fragS *));
456 static int add_to_lit_pool PARAMS ((void));
457 static unsigned validate_immediate PARAMS ((unsigned));
458 static int validate_offset_imm PARAMS ((int, int));
459 static void opcode_select PARAMS ((int));
460 static void end_of_line PARAMS ((char *));
461 static int reg_required_here PARAMS ((char **, int));
462 static int psr_required_here PARAMS ((char **, int, int));
463 static int co_proc_number PARAMS ((char **));
464 static int cp_opc_expr PARAMS ((char **, int, int));
465 static int cp_reg_required_here PARAMS ((char **, int));
466 static int fp_reg_required_here PARAMS ((char **, int));
467 static int cp_address_offset PARAMS ((char **));
468 static int cp_address_required_here PARAMS ((char **));
469 static int my_get_float_expression PARAMS ((char **));
470 static int skip_past_comma PARAMS ((char **));
471 static int walk_no_bignums PARAMS ((symbolS *));
472 static int negate_data_op PARAMS ((unsigned long *,
473 unsigned long));
474 static int data_op2 PARAMS ((char **));
475 static int fp_op2 PARAMS ((char **));
476 static long reg_list PARAMS ((char **));
477 static void thumb_load_store PARAMS ((char *, int, int));
478 static int decode_shift PARAMS ((char **, int));
479 static int ldst_extend PARAMS ((char **, int));
480 static void thumb_add_sub PARAMS ((char *, int));
481 static void insert_reg PARAMS ((int));
482 static void thumb_shift PARAMS ((char *, int));
483 static void thumb_mov_compare PARAMS ((char *, int));
484 static void set_constant_flonums PARAMS ((void));
485 static valueT md_chars_to_number PARAMS ((char *, int));
486 static void insert_reg_alias PARAMS ((char *, int));
487 static void output_inst PARAMS ((char *));
488 #ifdef OBJ_ELF
489 static bfd_reloc_code_real_type arm_parse_reloc(void);
490 #endif
492 /* ARM instructions take 4bytes in the object file, Thumb instructions
493 take 2: */
494 #define INSN_SIZE 4
496 /* LONGEST_INST is the longest basic instruction name without conditions or
497 * flags.
498 * ARM7M has 4 of length 5
501 #define LONGEST_INST 5
503 struct asm_opcode
505 CONST char * template; /* Basic string to match */
506 unsigned long value; /* Basic instruction code */
507 CONST char * comp_suffix; /* Compulsory suffix that must follow conds */
508 CONST struct asm_flg * flags; /* Bits to toggle if flag 'n' set */
509 unsigned long variants; /* Which CPU variants this exists for */
510 /* Function to call to parse args */
511 void (* parms) PARAMS ((char *, unsigned long));
514 static CONST struct asm_opcode insns[] =
516 /* ARM Instructions */
517 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
518 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
519 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
520 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
521 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
522 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
523 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
524 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
525 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
526 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
527 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
528 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
529 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
530 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
531 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
532 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
533 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
534 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
535 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
536 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
537 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
538 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
539 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
541 /* Pseudo ops */
542 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
543 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
545 /* ARM 2 multiplies */
546 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
547 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
549 /* ARM 3 - swp instructions */
550 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
552 /* ARM 6 Coprocessor instructions */
553 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
554 {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr},
555 /* ScottB: our code uses 0x0128f000 for msr.
556 NickC: but this is wrong because the bits 16 and 19 are handled
557 by the PSR_xxx defines above. */
559 /* ARM 7M long multiplies - need signed/unsigned flags! */
560 {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull},
561 {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull},
562 {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull},
563 {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull},
565 /* ARM THUMB interworking */
566 {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx},
568 /* Floating point instructions */
569 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
570 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
571 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
572 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
573 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
574 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
575 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
576 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
577 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
578 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
579 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
580 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
581 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
582 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
583 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
584 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
585 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
586 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
587 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
588 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
589 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
590 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
591 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
592 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
593 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
594 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
595 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
596 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
597 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
598 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
599 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
600 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
601 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
602 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
603 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
604 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
605 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
606 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
607 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
608 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
609 be an optional suffix, but part of the instruction. To be compatible,
610 we accept either. */
611 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
612 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
613 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
614 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
616 /* Generic copressor instructions */
617 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
618 {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc},
619 {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc},
620 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
621 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
624 /* defines for various bits that we will want to toggle */
626 #define INST_IMMEDIATE 0x02000000
627 #define OFFSET_REG 0x02000000
628 #define HWOFFSET_IMM 0x00400000
629 #define SHIFT_BY_REG 0x00000010
630 #define PRE_INDEX 0x01000000
631 #define INDEX_UP 0x00800000
632 #define WRITE_BACK 0x00200000
633 #define MULTI_SET_PSR 0x00400000
635 #define LITERAL_MASK 0xf000f000
636 #define COND_MASK 0xf0000000
637 #define OPCODE_MASK 0xfe1fffff
638 #define DATA_OP_SHIFT 21
640 /* Codes to distinguish the arithmetic instructions */
642 #define OPCODE_AND 0
643 #define OPCODE_EOR 1
644 #define OPCODE_SUB 2
645 #define OPCODE_RSB 3
646 #define OPCODE_ADD 4
647 #define OPCODE_ADC 5
648 #define OPCODE_SBC 6
649 #define OPCODE_RSC 7
650 #define OPCODE_TST 8
651 #define OPCODE_TEQ 9
652 #define OPCODE_CMP 10
653 #define OPCODE_CMN 11
654 #define OPCODE_ORR 12
655 #define OPCODE_MOV 13
656 #define OPCODE_BIC 14
657 #define OPCODE_MVN 15
659 static void do_t_nop PARAMS ((char *operands));
660 static void do_t_arit PARAMS ((char *operands));
661 static void do_t_add PARAMS ((char *operands));
662 static void do_t_asr PARAMS ((char *operands));
663 static void do_t_branch9 PARAMS ((char *operands));
664 static void do_t_branch12 PARAMS ((char *operands));
665 static void do_t_branch23 PARAMS ((char *operands));
666 static void do_t_bx PARAMS ((char *operands));
667 static void do_t_compare PARAMS ((char *operands));
668 static void do_t_ldmstm PARAMS ((char *operands));
669 static void do_t_ldr PARAMS ((char *operands));
670 static void do_t_ldrb PARAMS ((char *operands));
671 static void do_t_ldrh PARAMS ((char *operands));
672 static void do_t_lds PARAMS ((char *operands));
673 static void do_t_lsl PARAMS ((char *operands));
674 static void do_t_lsr PARAMS ((char *operands));
675 static void do_t_mov PARAMS ((char *operands));
676 static void do_t_push_pop PARAMS ((char *operands));
677 static void do_t_str PARAMS ((char *operands));
678 static void do_t_strb PARAMS ((char *operands));
679 static void do_t_strh PARAMS ((char *operands));
680 static void do_t_sub PARAMS ((char *operands));
681 static void do_t_swi PARAMS ((char *operands));
682 static void do_t_adr PARAMS ((char *operands));
684 #define T_OPCODE_MUL 0x4340
685 #define T_OPCODE_TST 0x4200
686 #define T_OPCODE_CMN 0x42c0
687 #define T_OPCODE_NEG 0x4240
688 #define T_OPCODE_MVN 0x43c0
690 #define T_OPCODE_ADD_R3 0x1800
691 #define T_OPCODE_SUB_R3 0x1a00
692 #define T_OPCODE_ADD_HI 0x4400
693 #define T_OPCODE_ADD_ST 0xb000
694 #define T_OPCODE_SUB_ST 0xb080
695 #define T_OPCODE_ADD_SP 0xa800
696 #define T_OPCODE_ADD_PC 0xa000
697 #define T_OPCODE_ADD_I8 0x3000
698 #define T_OPCODE_SUB_I8 0x3800
699 #define T_OPCODE_ADD_I3 0x1c00
700 #define T_OPCODE_SUB_I3 0x1e00
702 #define T_OPCODE_ASR_R 0x4100
703 #define T_OPCODE_LSL_R 0x4080
704 #define T_OPCODE_LSR_R 0x40c0
705 #define T_OPCODE_ASR_I 0x1000
706 #define T_OPCODE_LSL_I 0x0000
707 #define T_OPCODE_LSR_I 0x0800
709 #define T_OPCODE_MOV_I8 0x2000
710 #define T_OPCODE_CMP_I8 0x2800
711 #define T_OPCODE_CMP_LR 0x4280
712 #define T_OPCODE_MOV_HR 0x4600
713 #define T_OPCODE_CMP_HR 0x4500
715 #define T_OPCODE_LDR_PC 0x4800
716 #define T_OPCODE_LDR_SP 0x9800
717 #define T_OPCODE_STR_SP 0x9000
718 #define T_OPCODE_LDR_IW 0x6800
719 #define T_OPCODE_STR_IW 0x6000
720 #define T_OPCODE_LDR_IH 0x8800
721 #define T_OPCODE_STR_IH 0x8000
722 #define T_OPCODE_LDR_IB 0x7800
723 #define T_OPCODE_STR_IB 0x7000
724 #define T_OPCODE_LDR_RW 0x5800
725 #define T_OPCODE_STR_RW 0x5000
726 #define T_OPCODE_LDR_RH 0x5a00
727 #define T_OPCODE_STR_RH 0x5200
728 #define T_OPCODE_LDR_RB 0x5c00
729 #define T_OPCODE_STR_RB 0x5400
731 #define T_OPCODE_PUSH 0xb400
732 #define T_OPCODE_POP 0xbc00
734 #define T_OPCODE_BRANCH 0xe7fe
736 static int thumb_reg PARAMS ((char ** str, int hi_lo));
738 #define THUMB_SIZE 2 /* Size of thumb instruction */
739 #define THUMB_REG_LO 0x1
740 #define THUMB_REG_HI 0x2
741 #define THUMB_REG_ANY 0x3
743 #define THUMB_H1 0x0080
744 #define THUMB_H2 0x0040
746 #define THUMB_ASR 0
747 #define THUMB_LSL 1
748 #define THUMB_LSR 2
750 #define THUMB_MOVE 0
751 #define THUMB_COMPARE 1
753 #define THUMB_LOAD 0
754 #define THUMB_STORE 1
756 #define THUMB_PP_PC_LR 0x0100
758 /* These three are used for immediate shifts, do not alter */
759 #define THUMB_WORD 2
760 #define THUMB_HALFWORD 1
761 #define THUMB_BYTE 0
763 struct thumb_opcode
765 CONST char * template; /* Basic string to match */
766 unsigned long value; /* Basic instruction code */
767 int size;
768 void (* parms) PARAMS ((char *)); /* Function to call to parse args */
771 static CONST struct thumb_opcode tinsns[] =
773 {"adc", 0x4140, 2, do_t_arit},
774 {"add", 0x0000, 2, do_t_add},
775 {"and", 0x4000, 2, do_t_arit},
776 {"asr", 0x0000, 2, do_t_asr},
777 {"b", T_OPCODE_BRANCH, 2, do_t_branch12},
778 {"beq", 0xd0fe, 2, do_t_branch9},
779 {"bne", 0xd1fe, 2, do_t_branch9},
780 {"bcs", 0xd2fe, 2, do_t_branch9},
781 {"bhs", 0xd2fe, 2, do_t_branch9},
782 {"bcc", 0xd3fe, 2, do_t_branch9},
783 {"bul", 0xd3fe, 2, do_t_branch9},
784 {"blo", 0xd3fe, 2, do_t_branch9},
785 {"bmi", 0xd4fe, 2, do_t_branch9},
786 {"bpl", 0xd5fe, 2, do_t_branch9},
787 {"bvs", 0xd6fe, 2, do_t_branch9},
788 {"bvc", 0xd7fe, 2, do_t_branch9},
789 {"bhi", 0xd8fe, 2, do_t_branch9},
790 {"bls", 0xd9fe, 2, do_t_branch9},
791 {"bge", 0xdafe, 2, do_t_branch9},
792 {"blt", 0xdbfe, 2, do_t_branch9},
793 {"bgt", 0xdcfe, 2, do_t_branch9},
794 {"ble", 0xddfe, 2, do_t_branch9},
795 {"bic", 0x4380, 2, do_t_arit},
796 {"bl", 0xf7fffffe, 4, do_t_branch23},
797 {"bx", 0x4700, 2, do_t_bx},
798 {"cmn", T_OPCODE_CMN, 2, do_t_arit},
799 {"cmp", 0x0000, 2, do_t_compare},
800 {"eor", 0x4040, 2, do_t_arit},
801 {"ldmia", 0xc800, 2, do_t_ldmstm},
802 {"ldr", 0x0000, 2, do_t_ldr},
803 {"ldrb", 0x0000, 2, do_t_ldrb},
804 {"ldrh", 0x0000, 2, do_t_ldrh},
805 {"ldrsb", 0x5600, 2, do_t_lds},
806 {"ldrsh", 0x5e00, 2, do_t_lds},
807 {"ldsb", 0x5600, 2, do_t_lds},
808 {"ldsh", 0x5e00, 2, do_t_lds},
809 {"lsl", 0x0000, 2, do_t_lsl},
810 {"lsr", 0x0000, 2, do_t_lsr},
811 {"mov", 0x0000, 2, do_t_mov},
812 {"mul", T_OPCODE_MUL, 2, do_t_arit},
813 {"mvn", T_OPCODE_MVN, 2, do_t_arit},
814 {"neg", T_OPCODE_NEG, 2, do_t_arit},
815 {"orr", 0x4300, 2, do_t_arit},
816 {"pop", 0xbc00, 2, do_t_push_pop},
817 {"push", 0xb400, 2, do_t_push_pop},
818 {"ror", 0x41c0, 2, do_t_arit},
819 {"sbc", 0x4180, 2, do_t_arit},
820 {"stmia", 0xc000, 2, do_t_ldmstm},
821 {"str", 0x0000, 2, do_t_str},
822 {"strb", 0x0000, 2, do_t_strb},
823 {"strh", 0x0000, 2, do_t_strh},
824 {"swi", 0xdf00, 2, do_t_swi},
825 {"sub", 0x0000, 2, do_t_sub},
826 {"tst", T_OPCODE_TST, 2, do_t_arit},
827 /* Pseudo ops: */
828 {"adr", 0x0000, 2, do_t_adr},
829 {"nop", 0x46C0, 2, do_t_nop}, /* mov r8,r8 */
832 struct reg_entry
834 CONST char * name;
835 int number;
838 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
839 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
840 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
842 #define REG_PC 15
843 #define REG_LR 14
844 #define REG_SP 13
846 /* These are the standard names; Users can add aliases with .req */
847 static CONST struct reg_entry reg_table[] =
849 /* Processor Register Numbers */
850 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
851 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
852 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
853 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
854 /* APCS conventions */
855 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
856 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
857 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
858 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
859 /* FP Registers */
860 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
861 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
862 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
863 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
864 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
865 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
866 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
867 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
868 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
869 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
870 {NULL, 0}
873 #define bad_args _("Bad arguments to instruction");
874 #define bad_pc _("r15 not allowed here");
876 static struct hash_control * arm_ops_hsh = NULL;
877 static struct hash_control * arm_tops_hsh = NULL;
878 static struct hash_control * arm_cond_hsh = NULL;
879 static struct hash_control * arm_shift_hsh = NULL;
880 static struct hash_control * arm_reg_hsh = NULL;
881 static struct hash_control * arm_psr_hsh = NULL;
883 /* This table describes all the machine specific pseudo-ops the assembler
884 has to support. The fields are:
885 pseudo-op name without dot
886 function to call to execute this pseudo-op
887 Integer arg to pass to the function
890 static void s_req PARAMS ((int));
891 static void s_align PARAMS ((int));
892 static void s_bss PARAMS ((int));
893 static void s_even PARAMS ((int));
894 static void s_ltorg PARAMS ((int));
895 static void s_arm PARAMS ((int));
896 static void s_thumb PARAMS ((int));
897 static void s_code PARAMS ((int));
898 static void s_force_thumb PARAMS ((int));
899 static void s_thumb_func PARAMS ((int));
900 #ifdef OBJ_ELF
901 static void s_arm_elf_cons PARAMS ((int));
902 #endif
904 static int my_get_expression PARAMS ((expressionS *, char **));
906 CONST pseudo_typeS md_pseudo_table[] =
908 {"req", s_req, 0}, /* Never called becasue '.req' does not start line */
909 {"bss", s_bss, 0},
910 {"align", s_align, 0},
911 {"arm", s_arm, 0},
912 {"thumb", s_thumb, 0},
913 {"code", s_code, 0},
914 {"force_thumb", s_force_thumb, 0},
915 {"thumb_func", s_thumb_func, 0},
916 {"even", s_even, 0},
917 {"ltorg", s_ltorg, 0},
918 {"pool", s_ltorg, 0},
919 #ifdef OBJ_ELF
920 {"word", s_arm_elf_cons, 4},
921 {"long", s_arm_elf_cons, 4},
922 #else
923 {"word", cons, 4},
924 #endif
925 {"extend", float_cons, 'x'},
926 {"ldouble", float_cons, 'x'},
927 {"packed", float_cons, 'p'},
928 {0, 0, 0}
931 /* Stuff needed to resolve the label ambiguity
934 label: <insn>
935 may differ from:
937 label:
938 <insn>
941 symbolS * last_label_seen;
942 static int label_is_thumb_function_name = false;
944 /* Literal stuff */
946 #define MAX_LITERAL_POOL_SIZE 1024
948 typedef struct literalS
950 struct expressionS exp;
951 struct arm_it * inst;
952 } literalT;
954 literalT literals[MAX_LITERAL_POOL_SIZE];
955 int next_literal_pool_place = 0; /* Next free entry in the pool */
956 int lit_pool_num = 1; /* Next literal pool number */
957 symbolS * current_poolP = NULL;
958 symbolS * symbol_make_empty PARAMS ((void));
960 static int
961 add_to_lit_pool ()
963 int lit_count = 0;
965 if (current_poolP == NULL)
966 current_poolP = symbol_make_empty ();
968 /* Check if this literal value is already in the pool: */
969 while (lit_count < next_literal_pool_place)
971 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
972 && inst.reloc.exp.X_op == O_constant
973 && literals[lit_count].exp.X_add_number == inst.reloc.exp.X_add_number
974 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
975 break;
976 lit_count++;
979 if (lit_count == next_literal_pool_place) /* new entry */
981 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
983 inst.error = _("Literal Pool Overflow");
984 return FAIL;
987 literals[next_literal_pool_place].exp = inst.reloc.exp;
988 lit_count = next_literal_pool_place++;
991 inst.reloc.exp.X_op = O_symbol;
992 inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
993 inst.reloc.exp.X_add_symbol = current_poolP;
995 return SUCCESS;
998 /* Can't use symbol_new here, so have to create a symbol and then at
999 a later date assign it a value. Thats what these functions do. */
1000 static void
1001 symbol_locate (symbolP, name, segment, valu, frag)
1002 symbolS * symbolP;
1003 CONST char * name; /* It is copied, the caller can modify */
1004 segT segment; /* Segment identifier (SEG_<something>) */
1005 valueT valu; /* Symbol value */
1006 fragS * frag; /* Associated fragment */
1008 unsigned int name_length;
1009 char * preserved_copy_of_name;
1011 name_length = strlen (name) + 1; /* +1 for \0 */
1012 obstack_grow (&notes, name, name_length);
1013 preserved_copy_of_name = obstack_finish (&notes);
1014 #ifdef STRIP_UNDERSCORE
1015 if (preserved_copy_of_name[0] == '_')
1016 preserved_copy_of_name++;
1017 #endif
1019 #ifdef tc_canonicalize_symbol_name
1020 preserved_copy_of_name =
1021 tc_canonicalize_symbol_name (preserved_copy_of_name);
1022 #endif
1024 S_SET_NAME (symbolP, preserved_copy_of_name);
1026 S_SET_SEGMENT (symbolP, segment);
1027 S_SET_VALUE (symbolP, valu);
1028 symbol_clear_list_pointers(symbolP);
1030 symbolP->sy_frag = frag;
1032 /* Link to end of symbol chain. */
1034 extern int symbol_table_frozen;
1035 if (symbol_table_frozen)
1036 abort ();
1039 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1041 obj_symbol_new_hook (symbolP);
1043 #ifdef tc_symbol_new_hook
1044 tc_symbol_new_hook (symbolP);
1045 #endif
1047 #ifdef DEBUG_SYMS
1048 verify_symbol_chain (symbol_rootP, symbol_lastP);
1049 #endif /* DEBUG_SYMS */
1052 symbolS *
1053 symbol_make_empty ()
1055 symbolS * symbolP;
1057 symbolP = (symbolS *) obstack_alloc (&notes, sizeof (symbolS));
1059 /* symbol must be born in some fixed state. This seems as good as any. */
1060 memset (symbolP, 0, sizeof (symbolS));
1062 symbolP->bsym = bfd_make_empty_symbol (stdoutput);
1063 assert (symbolP->bsym != 0);
1064 symbolP->bsym->udata.p = (PTR) symbolP;
1066 return symbolP;
1069 /* Check that an immediate is valid, and if so, convert it to the right format. */
1071 static unsigned int
1072 validate_immediate (val)
1073 unsigned int val;
1075 unsigned int a;
1076 unsigned int i;
1078 #define rotate_left(v, n) (v << n | v >> (32 - n))
1080 for (i = 0; i < 32; i += 2)
1081 if ((a = rotate_left (val, i)) <= 0xff)
1082 return a | (i << 7); /* 12-bit pack: [shift-cnt,const] */
1084 return FAIL;
1087 static int
1088 validate_offset_imm (val, hwse)
1089 int val;
1090 int hwse;
1092 if ((hwse && (val < -255 || val > 255))
1093 || (val < -4095 || val > 4095))
1094 return FAIL;
1095 return val;
1099 static void
1100 s_req (a)
1101 int a;
1103 as_bad (_("Invalid syntax for .req directive."));
1106 static void
1107 s_bss (ignore)
1108 int ignore;
1110 /* We don't support putting frags in the BSS segment, we fake it by
1111 marking in_bss, then looking at s_skip for clues?.. */
1112 subseg_set (bss_section, 0);
1113 demand_empty_rest_of_line ();
1116 static void
1117 s_even (ignore)
1118 int ignore;
1120 if (!need_pass_2) /* Never make frag if expect extra pass. */
1121 frag_align (1, 0, 0);
1123 record_alignment (now_seg, 1);
1125 demand_empty_rest_of_line ();
1128 static void
1129 s_ltorg (internal)
1130 int internal;
1132 int lit_count = 0;
1133 char sym_name[20];
1135 if (current_poolP == NULL)
1137 /* Nothing to do */
1138 if (!internal)
1139 as_tsktsk (_("Nothing to put in the pool\n"));
1140 return;
1143 /* Align pool as you have word accesses */
1144 /* Only make a frag if we have to ... */
1145 if (!need_pass_2)
1146 frag_align (2, 0, 0);
1148 record_alignment (now_seg, 2);
1150 if (internal)
1151 as_tsktsk (_("Inserting implicit pool at change of section"));
1153 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1155 symbol_locate (current_poolP, sym_name, now_seg,
1156 (valueT) frag_now_fix (), frag_now);
1157 symbol_table_insert (current_poolP);
1159 ARM_SET_THUMB (current_poolP, thumb_mode);
1161 #if defined OBJ_COFF || defined OBJ_ELF
1162 ARM_SET_INTERWORK (current_poolP, support_interwork);
1163 #endif
1165 while (lit_count < next_literal_pool_place)
1166 /* First output the expression in the instruction to the pool */
1167 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1169 next_literal_pool_place = 0;
1170 current_poolP = NULL;
1173 static void
1174 s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */
1175 int unused;
1177 register int temp;
1178 register long temp_fill;
1179 long max_alignment = 15;
1181 temp = get_absolute_expression ();
1182 if (temp > max_alignment)
1183 as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
1184 else if (temp < 0)
1186 as_bad (_("Alignment negative. 0 assumed."));
1187 temp = 0;
1190 if (*input_line_pointer == ',')
1192 input_line_pointer++;
1193 temp_fill = get_absolute_expression ();
1195 else
1196 temp_fill = 0;
1198 if (!temp)
1199 temp = 2;
1201 /* Only make a frag if we HAVE to. . . */
1202 if (temp && !need_pass_2)
1203 frag_align (temp, (int) temp_fill, 0);
1204 demand_empty_rest_of_line ();
1206 record_alignment (now_seg, temp);
1209 static void
1210 s_force_thumb (ignore)
1211 int ignore;
1213 /* If we are not already in thumb mode go into it, EVEN if
1214 the target processor does not support thumb instructions.
1215 This is used by gcc/config/arm/lib1funcs.asm for example
1216 to compile interworking support functions even if the
1217 target processor should not support interworking. */
1219 if (! thumb_mode)
1221 thumb_mode = 1;
1223 record_alignment (now_seg, 1);
1226 demand_empty_rest_of_line ();
1229 static void
1230 s_thumb_func (ignore)
1231 int ignore;
1233 /* The following label is the name/address of the start of a Thumb function.
1234 We need to know this for the interworking support. */
1236 label_is_thumb_function_name = true;
1238 demand_empty_rest_of_line ();
1241 static void
1242 opcode_select (width)
1243 int width;
1245 switch (width)
1247 case 16:
1248 if (! thumb_mode)
1250 if (! (cpu_variant & ARM_THUMB))
1251 as_bad (_("selected processor does not support THUMB opcodes"));
1252 thumb_mode = 1;
1253 /* No need to force the alignment, since we will have been
1254 coming from ARM mode, which is word-aligned. */
1255 record_alignment (now_seg, 1);
1257 break;
1259 case 32:
1260 if (thumb_mode)
1262 if ((cpu_variant & ARM_ANY) == ARM_THUMB)
1263 as_bad (_("selected processor does not support ARM opcodes"));
1264 thumb_mode = 0;
1265 if (!need_pass_2)
1266 frag_align (2, 0, 0);
1267 record_alignment (now_seg, 1);
1269 break;
1271 default:
1272 as_bad (_("invalid instruction size selected (%d)"), width);
1276 static void
1277 s_arm (ignore)
1278 int ignore;
1280 opcode_select (32);
1281 demand_empty_rest_of_line ();
1284 static void
1285 s_thumb (ignore)
1286 int ignore;
1288 opcode_select (16);
1289 demand_empty_rest_of_line ();
1292 static void
1293 s_code (unused)
1294 int unused;
1296 register int temp;
1298 temp = get_absolute_expression ();
1299 switch (temp)
1301 case 16:
1302 case 32:
1303 opcode_select (temp);
1304 break;
1306 default:
1307 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1311 static void
1312 end_of_line (str)
1313 char * str;
1315 while (*str == ' ')
1316 str++;
1318 if (*str != '\0')
1319 inst.error = _("Garbage following instruction");
1322 static int
1323 skip_past_comma (str)
1324 char ** str;
1326 char *p = *str, c;
1327 int comma = 0;
1329 while ((c = *p) == ' ' || c == ',')
1331 p++;
1332 if (c == ',' && comma++)
1333 return FAIL;
1336 if (c == '\0')
1337 return FAIL;
1339 *str = p;
1340 return comma ? SUCCESS : FAIL;
1343 /* A standard register must be given at this point. Shift is the place to
1344 put it in the instruction. */
1346 static int
1347 reg_required_here (str, shift)
1348 char ** str;
1349 int shift;
1351 static char buff [128]; /* XXX */
1352 int reg;
1353 char * start = *str;
1355 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1357 if (shift >= 0)
1358 inst.instruction |= reg << shift;
1359 return reg;
1362 /* Restore the start point, we may have got a reg of the wrong class. */
1363 *str = start;
1365 /* In the few cases where we might be able to accept something else
1366 this error can be overridden */
1367 sprintf (buff, _("Register expected, not '%.100s'"), start);
1368 inst.error = buff;
1370 return FAIL;
1373 static int
1374 psr_required_here (str, cpsr, spsr)
1375 char ** str;
1376 int cpsr;
1377 int spsr;
1379 int psr;
1380 char * start = *str;
1381 psr = arm_psr_parse (str);
1383 if (psr == cpsr || psr == spsr)
1385 if (psr == spsr)
1386 inst.instruction |= 1 << 22;
1388 return SUCCESS;
1391 /* In the few cases where we might be able to accept something else
1392 this error can be overridden */
1393 inst.error = _("<psr(f)> expected");
1395 /* Restore the start point. */
1396 *str = start;
1397 return FAIL;
1400 static int
1401 co_proc_number (str)
1402 char **str;
1404 int processor, pchar;
1406 while (**str == ' ')
1407 (*str)++;
1409 /* The data sheet seems to imply that just a number on its own is valid
1410 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1411 accept either. */
1412 if (**str == 'p' || **str == 'P')
1413 (*str)++;
1415 pchar = *(*str)++;
1416 if (pchar >= '0' && pchar <= '9')
1418 processor = pchar - '0';
1419 if (**str >= '0' && **str <= '9')
1421 processor = processor * 10 + *(*str)++ - '0';
1422 if (processor > 15)
1424 inst.error = _("Illegal co-processor number");
1425 return FAIL;
1429 else
1431 inst.error = _("Bad or missing co-processor number");
1432 return FAIL;
1435 inst.instruction |= processor << 8;
1436 return SUCCESS;
1439 static int
1440 cp_opc_expr (str, where, length)
1441 char ** str;
1442 int where;
1443 int length;
1445 expressionS expr;
1447 while (**str == ' ')
1448 (*str)++;
1450 memset (&expr, '\0', sizeof (expr));
1452 if (my_get_expression (&expr, str))
1453 return FAIL;
1454 if (expr.X_op != O_constant)
1456 inst.error = _("bad or missing expression");
1457 return FAIL;
1460 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1462 inst.error = _("immediate co-processor expression too large");
1463 return FAIL;
1466 inst.instruction |= expr.X_add_number << where;
1467 return SUCCESS;
1470 static int
1471 cp_reg_required_here (str, where)
1472 char ** str;
1473 int where;
1475 int reg;
1476 char * start = *str;
1478 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1480 reg &= 15;
1481 inst.instruction |= reg << where;
1482 return reg;
1485 /* In the few cases where we might be able to accept something else
1486 this error can be overridden */
1487 inst.error = _("Co-processor register expected");
1489 /* Restore the start point */
1490 *str = start;
1491 return FAIL;
1494 static int
1495 fp_reg_required_here (str, where)
1496 char ** str;
1497 int where;
1499 int reg;
1500 char * start = *str;
1502 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1504 reg &= 7;
1505 inst.instruction |= reg << where;
1506 return reg;
1509 /* In the few cases where we might be able to accept something else
1510 this error can be overridden */
1511 inst.error = _("Floating point register expected");
1513 /* Restore the start point */
1514 *str = start;
1515 return FAIL;
1518 static int
1519 cp_address_offset (str)
1520 char ** str;
1522 int offset;
1524 while (**str == ' ')
1525 (*str)++;
1527 if (! is_immediate_prefix (**str))
1529 inst.error = _("immediate expression expected");
1530 return FAIL;
1533 (*str)++;
1535 if (my_get_expression (& inst.reloc.exp, str))
1536 return FAIL;
1538 if (inst.reloc.exp.X_op == O_constant)
1540 offset = inst.reloc.exp.X_add_number;
1542 if (offset & 3)
1544 inst.error = _("co-processor address must be word aligned");
1545 return FAIL;
1548 if (offset > 1023 || offset < -1023)
1550 inst.error = _("offset too large");
1551 return FAIL;
1554 if (offset >= 0)
1555 inst.instruction |= INDEX_UP;
1556 else
1557 offset = -offset;
1559 inst.instruction |= offset >> 2;
1561 else
1562 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1564 return SUCCESS;
1567 static int
1568 cp_address_required_here (str)
1569 char ** str;
1571 char * p = * str;
1572 int pre_inc = 0;
1573 int write_back = 0;
1575 if (*p == '[')
1577 int reg;
1579 p++;
1580 while (*p == ' ')
1581 p++;
1583 if ((reg = reg_required_here (& p, 16)) == FAIL)
1584 return FAIL;
1586 while (*p == ' ')
1587 p++;
1589 if (*p == ']')
1591 p++;
1593 if (skip_past_comma (& p) == SUCCESS)
1595 /* [Rn], #expr */
1596 write_back = WRITE_BACK;
1598 if (reg == REG_PC)
1600 inst.error = _("pc may not be used in post-increment");
1601 return FAIL;
1604 if (cp_address_offset (& p) == FAIL)
1605 return FAIL;
1607 else
1608 pre_inc = PRE_INDEX | INDEX_UP;
1610 else
1612 /* '['Rn, #expr']'[!] */
1614 if (skip_past_comma (& p) == FAIL)
1616 inst.error = _("pre-indexed expression expected");
1617 return FAIL;
1620 pre_inc = PRE_INDEX;
1622 if (cp_address_offset (& p) == FAIL)
1623 return FAIL;
1625 while (*p == ' ')
1626 p++;
1628 if (*p++ != ']')
1630 inst.error = _("missing ]");
1631 return FAIL;
1634 while (*p == ' ')
1635 p++;
1637 if (*p == '!')
1639 if (reg == REG_PC)
1641 inst.error = _("pc may not be used with write-back");
1642 return FAIL;
1645 p++;
1646 write_back = WRITE_BACK;
1650 else
1652 if (my_get_expression (&inst.reloc.exp, &p))
1653 return FAIL;
1655 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1656 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
1657 inst.reloc.pc_rel = 1;
1658 inst.instruction |= (REG_PC << 16);
1659 pre_inc = PRE_INDEX;
1662 inst.instruction |= write_back | pre_inc;
1663 *str = p;
1664 return SUCCESS;
1667 static void
1668 do_nop (str, flags)
1669 char * str;
1670 unsigned long flags;
1672 /* Do nothing really */
1673 inst.instruction |= flags; /* This is pointless */
1674 end_of_line (str);
1675 return;
1678 static void
1679 do_mrs (str, flags)
1680 char *str;
1681 unsigned long flags;
1683 /* Only one syntax */
1684 while (*str == ' ')
1685 str++;
1687 if (reg_required_here (&str, 12) == FAIL)
1689 inst.error = bad_args;
1690 return;
1693 if (skip_past_comma (&str) == FAIL
1694 || psr_required_here (& str, CPSR_ALL, SPSR_ALL) == FAIL)
1696 inst.error = _("<psr> expected");
1697 return;
1700 inst.instruction |= flags;
1701 end_of_line (str);
1702 return;
1705 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression" */
1706 static void
1707 do_msr (str, flags)
1708 char * str;
1709 unsigned long flags;
1711 int reg;
1713 while (*str == ' ')
1714 str ++;
1716 if (psr_required_here (&str, CPSR_ALL, SPSR_ALL) == SUCCESS)
1718 inst.instruction |= PSR_ALL;
1720 /* Sytax should be "<psr>, Rm" */
1721 if (skip_past_comma (&str) == FAIL
1722 || (reg = reg_required_here (&str, 0)) == FAIL)
1724 inst.error = bad_args;
1725 return;
1728 else
1730 if (psr_required_here (& str, CPSR_FLG, SPSR_FLG) == SUCCESS)
1731 inst.instruction |= PSR_FLAGS;
1732 else if (psr_required_here (& str, CPSR_CTL, SPSR_CTL) == SUCCESS)
1733 inst.instruction |= PSR_CONTROL;
1734 else
1736 inst.error = bad_args;
1737 return;
1740 if (skip_past_comma (&str) == FAIL)
1742 inst.error = bad_args;
1743 return;
1746 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1748 if ((reg = reg_required_here (& str, 0)) != FAIL)
1750 /* Immediate expression */
1751 else if (is_immediate_prefix (* str))
1753 str ++;
1754 inst.error = NULL;
1756 if (my_get_expression (& inst.reloc.exp, & str))
1758 inst.error = _("Register or shift expression expected");
1759 return;
1762 if (inst.reloc.exp.X_add_symbol)
1764 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
1765 inst.reloc.pc_rel = 0;
1767 else
1769 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
1770 if (value == FAIL)
1772 inst.error = _("Invalid constant");
1773 return;
1776 inst.instruction |= value;
1779 flags |= INST_IMMEDIATE;
1781 else
1783 inst.error = _("Error: unrecognised syntax for second argument to msr instruction");
1784 return;
1788 inst.error = NULL;
1789 inst.instruction |= flags;
1790 end_of_line (str);
1791 return;
1794 /* Long Multiply Parser
1795 UMULL RdLo, RdHi, Rm, Rs
1796 SMULL RdLo, RdHi, Rm, Rs
1797 UMLAL RdLo, RdHi, Rm, Rs
1798 SMLAL RdLo, RdHi, Rm, Rs
1800 static void
1801 do_mull (str, flags)
1802 char * str;
1803 unsigned long flags;
1805 int rdlo, rdhi, rm, rs;
1807 /* only one format "rdlo, rdhi, rm, rs" */
1808 while (*str == ' ')
1809 str++;
1811 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
1813 inst.error = bad_args;
1814 return;
1817 if (skip_past_comma (&str) == FAIL
1818 || (rdhi = reg_required_here (&str, 16)) == FAIL)
1820 inst.error = bad_args;
1821 return;
1824 if (skip_past_comma (&str) == FAIL
1825 || (rm = reg_required_here (&str, 0)) == FAIL)
1827 inst.error = bad_args;
1828 return;
1831 /* rdhi, rdlo and rm must all be different */
1832 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
1833 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1835 if (skip_past_comma (&str) == FAIL
1836 || (rs = reg_required_here (&str, 8)) == FAIL)
1838 inst.error = bad_args;
1839 return;
1842 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
1844 inst.error = bad_pc;
1845 return;
1848 inst.instruction |= flags;
1849 end_of_line (str);
1850 return;
1853 static void
1854 do_mul (str, flags)
1855 char * str;
1856 unsigned long flags;
1858 int rd, rm;
1860 /* only one format "rd, rm, rs" */
1861 while (*str == ' ')
1862 str++;
1864 if ((rd = reg_required_here (&str, 16)) == FAIL)
1866 inst.error = bad_args;
1867 return;
1870 if (rd == REG_PC)
1872 inst.error = bad_pc;
1873 return;
1876 if (skip_past_comma (&str) == FAIL
1877 || (rm = reg_required_here (&str, 0)) == FAIL)
1879 inst.error = bad_args;
1880 return;
1883 if (rm == REG_PC)
1885 inst.error = bad_pc;
1886 return;
1889 if (rm == rd)
1890 as_tsktsk (_("rd and rm should be different in mul"));
1892 if (skip_past_comma (&str) == FAIL
1893 || (rm = reg_required_here (&str, 8)) == FAIL)
1895 inst.error = bad_args;
1896 return;
1899 if (rm == REG_PC)
1901 inst.error = bad_pc;
1902 return;
1905 inst.instruction |= flags;
1906 end_of_line (str);
1907 return;
1910 static void
1911 do_mla (str, flags)
1912 char * str;
1913 unsigned long flags;
1915 int rd, rm;
1917 /* only one format "rd, rm, rs, rn" */
1918 while (*str == ' ')
1919 str++;
1921 if ((rd = reg_required_here (&str, 16)) == FAIL)
1923 inst.error = bad_args;
1924 return;
1927 if (rd == REG_PC)
1929 inst.error = bad_pc;
1930 return;
1933 if (skip_past_comma (&str) == FAIL
1934 || (rm = reg_required_here (&str, 0)) == FAIL)
1936 inst.error = bad_args;
1937 return;
1940 if (rm == REG_PC)
1942 inst.error = bad_pc;
1943 return;
1946 if (rm == rd)
1947 as_tsktsk (_("rd and rm should be different in mla"));
1949 if (skip_past_comma (&str) == FAIL
1950 || (rd = reg_required_here (&str, 8)) == FAIL
1951 || skip_past_comma (&str) == FAIL
1952 || (rm = reg_required_here (&str, 12)) == FAIL)
1954 inst.error = bad_args;
1955 return;
1958 if (rd == REG_PC || rm == REG_PC)
1960 inst.error = bad_pc;
1961 return;
1964 inst.instruction |= flags;
1965 end_of_line (str);
1966 return;
1969 /* Returns the index into fp_values of a floating point number, or -1 if
1970 not in the table. */
1971 static int
1972 my_get_float_expression (str)
1973 char ** str;
1975 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1976 char * save_in;
1977 expressionS exp;
1978 int i;
1979 int j;
1981 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
1982 /* Look for a raw floating point number */
1983 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
1984 && (is_end_of_line [(int)(*save_in)] || *save_in == '\0'))
1986 for (i = 0; i < NUM_FLOAT_VALS; i++)
1988 for (j = 0; j < MAX_LITTLENUMS; j++)
1990 if (words[j] != fp_values[i][j])
1991 break;
1994 if (j == MAX_LITTLENUMS)
1996 *str = save_in;
1997 return i;
2002 /* Try and parse a more complex expression, this will probably fail
2003 unless the code uses a floating point prefix (eg "0f") */
2004 save_in = input_line_pointer;
2005 input_line_pointer = *str;
2006 if (expression (&exp) == absolute_section
2007 && exp.X_op == O_big
2008 && exp.X_add_number < 0)
2010 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2011 Ditto for 15. */
2012 if (gen_to_words (words, 5, (long)15) == 0)
2014 for (i = 0; i < NUM_FLOAT_VALS; i++)
2016 for (j = 0; j < MAX_LITTLENUMS; j++)
2018 if (words[j] != fp_values[i][j])
2019 break;
2022 if (j == MAX_LITTLENUMS)
2024 *str = input_line_pointer;
2025 input_line_pointer = save_in;
2026 return i;
2032 *str = input_line_pointer;
2033 input_line_pointer = save_in;
2034 return -1;
2037 /* Return true if anything in the expression is a bignum */
2038 static int
2039 walk_no_bignums (sp)
2040 symbolS * sp;
2042 if (sp->sy_value.X_op == O_big)
2043 return 1;
2045 if (sp->sy_value.X_add_symbol)
2047 return (walk_no_bignums (sp->sy_value.X_add_symbol)
2048 || (sp->sy_value.X_op_symbol
2049 && walk_no_bignums (sp->sy_value.X_op_symbol)));
2052 return 0;
2055 static int
2056 my_get_expression (ep, str)
2057 expressionS * ep;
2058 char ** str;
2060 char * save_in;
2061 segT seg;
2063 save_in = input_line_pointer;
2064 input_line_pointer = *str;
2065 seg = expression (ep);
2067 #ifdef OBJ_AOUT
2068 if (seg != absolute_section
2069 && seg != text_section
2070 && seg != data_section
2071 && seg != bss_section
2072 && seg != undefined_section)
2074 inst.error = _("bad_segment");
2075 *str = input_line_pointer;
2076 input_line_pointer = save_in;
2077 return 1;
2079 #endif
2081 /* Get rid of any bignums now, so that we don't generate an error for which
2082 we can't establish a line number later on. Big numbers are never valid
2083 in instructions, which is where this routine is always called. */
2084 if (ep->X_op == O_big
2085 || (ep->X_add_symbol
2086 && (walk_no_bignums (ep->X_add_symbol)
2087 || (ep->X_op_symbol
2088 && walk_no_bignums (ep->X_op_symbol)))))
2090 inst.error = _("Invalid constant");
2091 *str = input_line_pointer;
2092 input_line_pointer = save_in;
2093 return 1;
2096 *str = input_line_pointer;
2097 input_line_pointer = save_in;
2098 return 0;
2101 /* unrestrict should be one if <shift> <register> is permitted for this
2102 instruction */
2104 static int
2105 decode_shift (str, unrestrict)
2106 char ** str;
2107 int unrestrict;
2109 struct asm_shift * shft;
2110 char * p;
2111 char c;
2113 while (**str == ' ')
2114 (*str)++;
2116 for (p = *str; isalpha (*p); p++)
2119 if (p == *str)
2121 inst.error = _("Shift expression expected");
2122 return FAIL;
2125 c = *p;
2126 *p = '\0';
2127 shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
2128 *p = c;
2129 if (shft)
2131 if (!strncmp (*str, "rrx", 3)
2132 || !strncmp (*str, "RRX", 3))
2134 *str = p;
2135 inst.instruction |= shft->value;
2136 return SUCCESS;
2139 while (*p == ' ')
2140 p++;
2142 if (unrestrict && reg_required_here (&p, 8) != FAIL)
2144 inst.instruction |= shft->value | SHIFT_BY_REG;
2145 *str = p;
2146 return SUCCESS;
2148 else if (is_immediate_prefix (* p))
2150 inst.error = NULL;
2151 p++;
2152 if (my_get_expression (&inst.reloc.exp, &p))
2153 return FAIL;
2155 /* Validate some simple #expressions */
2156 if (inst.reloc.exp.X_op == O_constant)
2158 unsigned num = inst.reloc.exp.X_add_number;
2160 /* Reject operations greater than 32, or lsl #32 */
2161 if (num > 32 || (num == 32 && shft->value == 0))
2163 inst.error = _("Invalid immediate shift");
2164 return FAIL;
2167 /* Shifts of zero should be converted to lsl (which is zero)*/
2168 if (num == 0)
2170 *str = p;
2171 return SUCCESS;
2174 /* Shifts of 32 are encoded as 0, for those shifts that
2175 support it. */
2176 if (num == 32)
2177 num = 0;
2179 inst.instruction |= (num << 7) | shft->value;
2180 *str = p;
2181 return SUCCESS;
2184 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
2185 inst.reloc.pc_rel = 0;
2186 inst.instruction |= shft->value;
2187 *str = p;
2188 return SUCCESS;
2190 else
2192 inst.error = unrestrict ? _("shift requires register or #expression")
2193 : _("shift requires #expression");
2194 *str = p;
2195 return FAIL;
2199 inst.error = _("Shift expression expected");
2200 return FAIL;
2203 /* Do those data_ops which can take a negative immediate constant */
2204 /* by altering the instuction. A bit of a hack really */
2205 /* MOV <-> MVN
2206 AND <-> BIC
2207 ADC <-> SBC
2208 by inverting the second operand, and
2209 ADD <-> SUB
2210 CMP <-> CMN
2211 by negating the second operand.
2213 static int
2214 negate_data_op (instruction, value)
2215 unsigned long * instruction;
2216 unsigned long value;
2218 int op, new_inst;
2219 unsigned long negated, inverted;
2221 negated = validate_immediate (-value);
2222 inverted = validate_immediate (~value);
2224 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
2225 switch (op)
2227 /* First negates */
2228 case OPCODE_SUB: /* ADD <-> SUB */
2229 new_inst = OPCODE_ADD;
2230 value = negated;
2231 break;
2233 case OPCODE_ADD:
2234 new_inst = OPCODE_SUB;
2235 value = negated;
2236 break;
2238 case OPCODE_CMP: /* CMP <-> CMN */
2239 new_inst = OPCODE_CMN;
2240 value = negated;
2241 break;
2243 case OPCODE_CMN:
2244 new_inst = OPCODE_CMP;
2245 value = negated;
2246 break;
2248 /* Now Inverted ops */
2249 case OPCODE_MOV: /* MOV <-> MVN */
2250 new_inst = OPCODE_MVN;
2251 value = inverted;
2252 break;
2254 case OPCODE_MVN:
2255 new_inst = OPCODE_MOV;
2256 value = inverted;
2257 break;
2259 case OPCODE_AND: /* AND <-> BIC */
2260 new_inst = OPCODE_BIC;
2261 value = inverted;
2262 break;
2264 case OPCODE_BIC:
2265 new_inst = OPCODE_AND;
2266 value = inverted;
2267 break;
2269 case OPCODE_ADC: /* ADC <-> SBC */
2270 new_inst = OPCODE_SBC;
2271 value = inverted;
2272 break;
2274 case OPCODE_SBC:
2275 new_inst = OPCODE_ADC;
2276 value = inverted;
2277 break;
2279 /* We cannot do anything */
2280 default:
2281 return FAIL;
2284 if (value == FAIL)
2285 return FAIL;
2287 *instruction &= OPCODE_MASK;
2288 *instruction |= new_inst << DATA_OP_SHIFT;
2289 return value;
2292 static int
2293 data_op2 (str)
2294 char ** str;
2296 int value;
2297 expressionS expr;
2299 while (**str == ' ')
2300 (*str)++;
2302 if (reg_required_here (str, 0) != FAIL)
2304 if (skip_past_comma (str) == SUCCESS)
2306 /* Shift operation on register */
2307 return decode_shift (str, NO_SHIFT_RESTRICT);
2309 return SUCCESS;
2311 else
2313 /* Immediate expression */
2314 if (is_immediate_prefix (**str))
2316 (*str)++;
2317 inst.error = NULL;
2318 if (my_get_expression (&inst.reloc.exp, str))
2319 return FAIL;
2321 if (inst.reloc.exp.X_add_symbol)
2323 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2324 inst.reloc.pc_rel = 0;
2326 else
2328 if (skip_past_comma (str) == SUCCESS)
2330 /* #x, y -- ie explicit rotation by Y */
2331 if (my_get_expression (&expr, str))
2332 return FAIL;
2334 if (expr.X_op != O_constant)
2336 inst.error = _("Constant expression expected");
2337 return FAIL;
2340 /* Rotate must be a multiple of 2 */
2341 if (((unsigned) expr.X_add_number) > 30
2342 || (expr.X_add_number & 1) != 0
2343 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
2345 inst.error = _("Invalid constant");
2346 return FAIL;
2348 inst.instruction |= INST_IMMEDIATE;
2349 inst.instruction |= inst.reloc.exp.X_add_number;
2350 inst.instruction |= expr.X_add_number << 7;
2351 return SUCCESS;
2354 /* Implicit rotation, select a suitable one */
2355 value = validate_immediate (inst.reloc.exp.X_add_number);
2357 if (value == FAIL)
2359 /* Can't be done, perhaps the code reads something like
2360 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2361 if ((value = negate_data_op (&inst.instruction,
2362 inst.reloc.exp.X_add_number))
2363 == FAIL)
2365 inst.error = _("Invalid constant");
2366 return FAIL;
2370 inst.instruction |= value;
2373 inst.instruction |= INST_IMMEDIATE;
2374 return SUCCESS;
2377 (*str)++;
2378 inst.error = _("Register or shift expression expected");
2379 return FAIL;
2383 static int
2384 fp_op2 (str)
2385 char ** str;
2387 while (**str == ' ')
2388 (*str)++;
2390 if (fp_reg_required_here (str, 0) != FAIL)
2391 return SUCCESS;
2392 else
2394 /* Immediate expression */
2395 if (*((*str)++) == '#')
2397 int i;
2399 inst.error = NULL;
2400 while (**str == ' ')
2401 (*str)++;
2403 /* First try and match exact strings, this is to guarantee that
2404 some formats will work even for cross assembly */
2406 for (i = 0; fp_const[i]; i++)
2408 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2410 char *start = *str;
2412 *str += strlen (fp_const[i]);
2413 if (is_end_of_line[(int)**str] || **str == '\0')
2415 inst.instruction |= i + 8;
2416 return SUCCESS;
2418 *str = start;
2422 /* Just because we didn't get a match doesn't mean that the
2423 constant isn't valid, just that it is in a format that we
2424 don't automatically recognize. Try parsing it with
2425 the standard expression routines. */
2426 if ((i = my_get_float_expression (str)) >= 0)
2428 inst.instruction |= i + 8;
2429 return SUCCESS;
2432 inst.error = _("Invalid floating point immediate expression");
2433 return FAIL;
2435 inst.error = _("Floating point register or immediate expression expected");
2436 return FAIL;
2440 static void
2441 do_arit (str, flags)
2442 char * str;
2443 unsigned long flags;
2445 while (*str == ' ')
2446 str++;
2448 if (reg_required_here (&str, 12) == FAIL
2449 || skip_past_comma (&str) == FAIL
2450 || reg_required_here (&str, 16) == FAIL
2451 || skip_past_comma (&str) == FAIL
2452 || data_op2 (&str) == FAIL)
2454 if (!inst.error)
2455 inst.error = bad_args;
2456 return;
2459 inst.instruction |= flags;
2460 end_of_line (str);
2461 return;
2464 static void
2465 do_adr (str, flags)
2466 char * str;
2467 unsigned long flags;
2469 /* This is a pseudo-op of the form "adr rd, label" to be converted
2470 into a relative address of the form "add rd, pc, #label-.-8" */
2472 while (*str == ' ')
2473 str++;
2475 if (reg_required_here (&str, 12) == FAIL
2476 || skip_past_comma (&str) == FAIL
2477 || my_get_expression (&inst.reloc.exp, &str))
2479 if (!inst.error)
2480 inst.error = bad_args;
2481 return;
2483 /* Frag hacking will turn this into a sub instruction if the offset turns
2484 out to be negative. */
2485 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2486 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2487 inst.reloc.pc_rel = 1;
2488 inst.instruction |= flags;
2489 end_of_line (str);
2490 return;
2493 static void
2494 do_cmp (str, flags)
2495 char * str;
2496 unsigned long flags;
2498 while (*str == ' ')
2499 str++;
2501 if (reg_required_here (&str, 16) == FAIL)
2503 if (!inst.error)
2504 inst.error = bad_args;
2505 return;
2508 if (skip_past_comma (&str) == FAIL
2509 || data_op2 (&str) == FAIL)
2511 if (!inst.error)
2512 inst.error = bad_args;
2513 return;
2516 inst.instruction |= flags;
2517 if ((flags & 0x0000f000) == 0)
2518 inst.instruction |= CONDS_BIT;
2520 end_of_line (str);
2521 return;
2524 static void
2525 do_mov (str, flags)
2526 char * str;
2527 unsigned long flags;
2529 while (*str == ' ')
2530 str++;
2532 if (reg_required_here (&str, 12) == FAIL)
2534 if (!inst.error)
2535 inst.error = bad_args;
2536 return;
2539 if (skip_past_comma (&str) == FAIL
2540 || data_op2 (&str) == FAIL)
2542 if (!inst.error)
2543 inst.error = bad_args;
2544 return;
2547 inst.instruction |= flags;
2548 end_of_line (str);
2549 return;
2552 static int
2553 ldst_extend (str, hwse)
2554 char ** str;
2555 int hwse;
2557 int add = INDEX_UP;
2559 switch (**str)
2561 case '#':
2562 case '$':
2563 (*str)++;
2564 if (my_get_expression (& inst.reloc.exp, str))
2565 return FAIL;
2567 if (inst.reloc.exp.X_op == O_constant)
2569 int value = inst.reloc.exp.X_add_number;
2571 if ((hwse && (value < -255 || value > 255))
2572 || (value < -4095 || value > 4095))
2574 inst.error = _("address offset too large");
2575 return FAIL;
2578 if (value < 0)
2580 value = -value;
2581 add = 0;
2584 /* Halfword and signextension instructions have the
2585 immediate value split across bits 11..8 and bits 3..0 */
2586 if (hwse)
2587 inst.instruction |= add | HWOFFSET_IMM | (value >> 4) << 8 | value & 0xF;
2588 else
2589 inst.instruction |= add | value;
2591 else
2593 if (hwse)
2595 inst.instruction |= HWOFFSET_IMM;
2596 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2598 else
2599 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2600 inst.reloc.pc_rel = 0;
2602 return SUCCESS;
2604 case '-':
2605 add = 0; /* and fall through */
2606 case '+':
2607 (*str)++; /* and fall through */
2608 default:
2609 if (reg_required_here (str, 0) == FAIL)
2610 return FAIL;
2612 if (hwse)
2613 inst.instruction |= add;
2614 else
2616 inst.instruction |= add | OFFSET_REG;
2617 if (skip_past_comma (str) == SUCCESS)
2618 return decode_shift (str, SHIFT_RESTRICT);
2621 return SUCCESS;
2625 static void
2626 do_ldst (str, flags)
2627 char * str;
2628 unsigned long flags;
2630 int halfword = 0;
2631 int pre_inc = 0;
2632 int conflict_reg;
2633 int value;
2635 /* This is not ideal, but it is the simplest way of dealing with the
2636 ARM7T halfword instructions (since they use a different
2637 encoding, but the same mnemonic): */
2638 if (halfword = ((flags & 0x80000000) != 0))
2640 /* This is actually a load/store of a halfword, or a
2641 signed-extension load */
2642 if ((cpu_variant & ARM_HALFWORD) == 0)
2644 inst.error
2645 = _("Processor does not support halfwords or signed bytes");
2646 return;
2649 inst.instruction = (inst.instruction & COND_MASK)
2650 | (flags & ~COND_MASK);
2652 flags = 0;
2655 while (*str == ' ')
2656 str++;
2658 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
2660 if (!inst.error)
2661 inst.error = bad_args;
2662 return;
2665 if (skip_past_comma (& str) == FAIL)
2667 inst.error = _("Address expected");
2668 return;
2671 if (*str == '[')
2673 int reg;
2675 str++;
2676 while (*str == ' ')
2677 str++;
2679 if ((reg = reg_required_here (&str, 16)) == FAIL)
2680 return;
2682 conflict_reg = (((conflict_reg == reg)
2683 && (inst.instruction & LOAD_BIT))
2684 ? 1 : 0);
2686 while (*str == ' ')
2687 str++;
2689 if (*str == ']')
2691 str++;
2692 if (skip_past_comma (&str) == SUCCESS)
2694 /* [Rn],... (post inc) */
2695 if (ldst_extend (&str, halfword) == FAIL)
2696 return;
2697 if (conflict_reg)
2698 as_warn (_("destination register same as write-back base\n"));
2700 else
2702 /* [Rn] */
2703 if (halfword)
2704 inst.instruction |= HWOFFSET_IMM;
2706 while (*str == ' ')
2707 str++;
2709 if (*str == '!')
2711 if (conflict_reg)
2712 as_warn (_("destination register same as write-back base\n"));
2713 str++;
2714 inst.instruction |= WRITE_BACK;
2717 flags |= INDEX_UP;
2718 if (! (flags & TRANS_BIT))
2719 pre_inc = 1;
2722 else
2724 /* [Rn,...] */
2725 if (skip_past_comma (&str) == FAIL)
2727 inst.error = _("pre-indexed expression expected");
2728 return;
2731 pre_inc = 1;
2732 if (ldst_extend (&str, halfword) == FAIL)
2733 return;
2735 while (*str == ' ')
2736 str++;
2738 if (*str++ != ']')
2740 inst.error = _("missing ]");
2741 return;
2744 while (*str == ' ')
2745 str++;
2747 if (*str == '!')
2749 if (conflict_reg)
2750 as_tsktsk (_("destination register same as write-back base\n"));
2751 str++;
2752 inst.instruction |= WRITE_BACK;
2756 else if (*str == '=')
2758 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2759 str++;
2761 while (*str == ' ')
2762 str++;
2764 if (my_get_expression (&inst.reloc.exp, &str))
2765 return;
2767 if (inst.reloc.exp.X_op != O_constant
2768 && inst.reloc.exp.X_op != O_symbol)
2770 inst.error = _("Constant expression expected");
2771 return;
2774 if (inst.reloc.exp.X_op == O_constant
2775 && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
2777 /* This can be done with a mov instruction */
2778 inst.instruction &= LITERAL_MASK;
2779 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
2780 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
2781 end_of_line(str);
2782 return;
2784 else
2786 /* Insert into literal pool */
2787 if (add_to_lit_pool () == FAIL)
2789 if (!inst.error)
2790 inst.error = _("literal pool insertion failed");
2791 return;
2794 /* Change the instruction exp to point to the pool */
2795 if (halfword)
2797 inst.instruction |= HWOFFSET_IMM;
2798 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
2800 else
2801 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
2802 inst.reloc.pc_rel = 1;
2803 inst.instruction |= (REG_PC << 16);
2804 pre_inc = 1;
2807 else
2809 if (my_get_expression (&inst.reloc.exp, &str))
2810 return;
2812 if (halfword)
2814 inst.instruction |= HWOFFSET_IMM;
2815 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2817 else
2818 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2819 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
2820 inst.reloc.pc_rel = 1;
2821 inst.instruction |= (REG_PC << 16);
2822 pre_inc = 1;
2825 if (pre_inc && (flags & TRANS_BIT))
2826 inst.error = _("Pre-increment instruction with translate");
2828 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
2829 end_of_line (str);
2830 return;
2833 static long
2834 reg_list (strp)
2835 char ** strp;
2837 char * str = *strp;
2838 long range = 0;
2839 int another_range;
2841 /* We come back here if we get ranges concatenated by '+' or '|' */
2844 another_range = 0;
2846 if (*str == '{')
2848 int in_range = 0;
2849 int cur_reg = -1;
2851 str++;
2854 int reg;
2856 while (*str == ' ')
2857 str++;
2859 if ((reg = reg_required_here (& str, -1)) == FAIL)
2860 return FAIL;
2862 if (in_range)
2864 int i;
2866 if (reg <= cur_reg)
2868 inst.error = _("Bad range in register list");
2869 return FAIL;
2872 for (i = cur_reg + 1; i < reg; i++)
2874 if (range & (1 << i))
2875 as_tsktsk
2876 (_("Warning: Duplicated register (r%d) in register list"),
2878 else
2879 range |= 1 << i;
2881 in_range = 0;
2884 if (range & (1 << reg))
2885 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
2886 reg);
2887 else if (reg <= cur_reg)
2888 as_tsktsk (_("Warning: Register range not in ascending order"));
2890 range |= 1 << reg;
2891 cur_reg = reg;
2892 } while (skip_past_comma (&str) != FAIL
2893 || (in_range = 1, *str++ == '-'));
2894 str--;
2895 while (*str == ' ')
2896 str++;
2898 if (*str++ != '}')
2900 inst.error = _("Missing `}'");
2901 return FAIL;
2904 else
2906 expressionS expr;
2908 if (my_get_expression (&expr, &str))
2909 return FAIL;
2911 if (expr.X_op == O_constant)
2913 if (expr.X_add_number
2914 != (expr.X_add_number & 0x0000ffff))
2916 inst.error = _("invalid register mask");
2917 return FAIL;
2920 if ((range & expr.X_add_number) != 0)
2922 int regno = range & expr.X_add_number;
2924 regno &= -regno;
2925 regno = (1 << regno) - 1;
2926 as_tsktsk
2927 (_("Warning: Duplicated register (r%d) in register list"),
2928 regno);
2931 range |= expr.X_add_number;
2933 else
2935 if (inst.reloc.type != 0)
2937 inst.error = _("expression too complex");
2938 return FAIL;
2941 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
2942 inst.reloc.type = BFD_RELOC_ARM_MULTI;
2943 inst.reloc.pc_rel = 0;
2947 while (*str == ' ')
2948 str++;
2950 if (*str == '|' || *str == '+')
2952 str++;
2953 another_range = 1;
2955 } while (another_range);
2957 *strp = str;
2958 return range;
2961 static void
2962 do_ldmstm (str, flags)
2963 char * str;
2964 unsigned long flags;
2966 int base_reg;
2967 long range;
2969 while (*str == ' ')
2970 str++;
2972 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
2973 return;
2975 if (base_reg == REG_PC)
2977 inst.error = _("r15 not allowed as base register");
2978 return;
2981 while (*str == ' ')
2982 str++;
2983 if (*str == '!')
2985 flags |= WRITE_BACK;
2986 str++;
2989 if (skip_past_comma (&str) == FAIL
2990 || (range = reg_list (&str)) == FAIL)
2992 if (! inst.error)
2993 inst.error = bad_args;
2994 return;
2997 if (*str == '^')
2999 str++;
3000 flags |= MULTI_SET_PSR;
3003 inst.instruction |= flags | range;
3004 end_of_line (str);
3005 return;
3008 static void
3009 do_swi (str, flags)
3010 char * str;
3011 unsigned long flags;
3013 while (*str == ' ')
3014 str++;
3016 /* Allow optional leading '#'. */
3017 if (is_immediate_prefix (*str))
3018 str++;
3020 if (my_get_expression (& inst.reloc.exp, & str))
3021 return;
3023 inst.reloc.type = BFD_RELOC_ARM_SWI;
3024 inst.reloc.pc_rel = 0;
3025 inst.instruction |= flags;
3027 end_of_line (str);
3029 return;
3032 static void
3033 do_swap (str, flags)
3034 char * str;
3035 unsigned long flags;
3037 int reg;
3039 while (*str == ' ')
3040 str++;
3042 if ((reg = reg_required_here (&str, 12)) == FAIL)
3043 return;
3045 if (reg == REG_PC)
3047 inst.error = _("r15 not allowed in swap");
3048 return;
3051 if (skip_past_comma (&str) == FAIL
3052 || (reg = reg_required_here (&str, 0)) == FAIL)
3054 if (!inst.error)
3055 inst.error = bad_args;
3056 return;
3059 if (reg == REG_PC)
3061 inst.error = _("r15 not allowed in swap");
3062 return;
3065 if (skip_past_comma (&str) == FAIL
3066 || *str++ != '[')
3068 inst.error = bad_args;
3069 return;
3072 while (*str == ' ')
3073 str++;
3075 if ((reg = reg_required_here (&str, 16)) == FAIL)
3076 return;
3078 if (reg == REG_PC)
3080 inst.error = bad_pc;
3081 return;
3084 while (*str == ' ')
3085 str++;
3087 if (*str++ != ']')
3089 inst.error = _("missing ]");
3090 return;
3093 inst.instruction |= flags;
3094 end_of_line (str);
3095 return;
3098 static void
3099 do_branch (str, flags)
3100 char * str;
3101 unsigned long flags;
3103 if (my_get_expression (&inst.reloc.exp, &str))
3104 return;
3106 #ifdef OBJ_ELF
3108 char * save_in;
3110 /* ScottB: February 5, 1998 */
3111 /* Check to see of PLT32 reloc required for the instruction. */
3113 /* arm_parse_reloc() works on input_line_pointer.
3114 We actually want to parse the operands to the branch instruction
3115 passed in 'str'. Save the input pointer and restore it later. */
3116 save_in = input_line_pointer;
3117 input_line_pointer = str;
3118 if (inst.reloc.exp.X_op == O_symbol
3119 && *str == '('
3120 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3122 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3123 inst.reloc.pc_rel = 0;
3124 /* Modify str to point to after parsed operands, otherwise
3125 end_of_line() will complain about the (PLT) left in str. */
3126 str = input_line_pointer;
3128 else
3130 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3131 inst.reloc.pc_rel = 1;
3133 input_line_pointer = save_in;
3135 #else
3136 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3137 inst.reloc.pc_rel = 1;
3138 #endif /* OBJ_ELF */
3140 end_of_line (str);
3141 return;
3144 static void
3145 do_bx (str, flags)
3146 char * str;
3147 unsigned long flags;
3149 int reg;
3151 while (*str == ' ')
3152 str++;
3154 if ((reg = reg_required_here (&str, 0)) == FAIL)
3155 return;
3157 if (reg == REG_PC)
3158 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3160 end_of_line (str);
3161 return;
3164 static void
3165 do_cdp (str, flags)
3166 char * str;
3167 unsigned long flags;
3169 /* Co-processor data operation.
3170 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3171 while (*str == ' ')
3172 str++;
3174 if (co_proc_number (&str) == FAIL)
3176 if (!inst.error)
3177 inst.error = bad_args;
3178 return;
3181 if (skip_past_comma (&str) == FAIL
3182 || cp_opc_expr (&str, 20,4) == FAIL)
3184 if (!inst.error)
3185 inst.error = bad_args;
3186 return;
3189 if (skip_past_comma (&str) == FAIL
3190 || cp_reg_required_here (&str, 12) == FAIL)
3192 if (!inst.error)
3193 inst.error = bad_args;
3194 return;
3197 if (skip_past_comma (&str) == FAIL
3198 || cp_reg_required_here (&str, 16) == FAIL)
3200 if (!inst.error)
3201 inst.error = bad_args;
3202 return;
3205 if (skip_past_comma (&str) == FAIL
3206 || cp_reg_required_here (&str, 0) == FAIL)
3208 if (!inst.error)
3209 inst.error = bad_args;
3210 return;
3213 if (skip_past_comma (&str) == SUCCESS)
3215 if (cp_opc_expr (&str, 5, 3) == FAIL)
3217 if (!inst.error)
3218 inst.error = bad_args;
3219 return;
3223 end_of_line (str);
3224 return;
3227 static void
3228 do_lstc (str, flags)
3229 char * str;
3230 unsigned long flags;
3232 /* Co-processor register load/store.
3233 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3235 while (*str == ' ')
3236 str++;
3238 if (co_proc_number (&str) == FAIL)
3240 if (!inst.error)
3241 inst.error = bad_args;
3242 return;
3245 if (skip_past_comma (&str) == FAIL
3246 || cp_reg_required_here (&str, 12) == FAIL)
3248 if (!inst.error)
3249 inst.error = bad_args;
3250 return;
3253 if (skip_past_comma (&str) == FAIL
3254 || cp_address_required_here (&str) == FAIL)
3256 if (! inst.error)
3257 inst.error = bad_args;
3258 return;
3261 inst.instruction |= flags;
3262 end_of_line (str);
3263 return;
3266 static void
3267 do_co_reg (str, flags)
3268 char * str;
3269 unsigned long flags;
3271 /* Co-processor register transfer.
3272 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3274 while (*str == ' ')
3275 str++;
3277 if (co_proc_number (&str) == FAIL)
3279 if (!inst.error)
3280 inst.error = bad_args;
3281 return;
3284 if (skip_past_comma (&str) == FAIL
3285 || cp_opc_expr (&str, 21, 3) == FAIL)
3287 if (!inst.error)
3288 inst.error = bad_args;
3289 return;
3292 if (skip_past_comma (&str) == FAIL
3293 || reg_required_here (&str, 12) == FAIL)
3295 if (!inst.error)
3296 inst.error = bad_args;
3297 return;
3300 if (skip_past_comma (&str) == FAIL
3301 || cp_reg_required_here (&str, 16) == FAIL)
3303 if (!inst.error)
3304 inst.error = bad_args;
3305 return;
3308 if (skip_past_comma (&str) == FAIL
3309 || cp_reg_required_here (&str, 0) == FAIL)
3311 if (!inst.error)
3312 inst.error = bad_args;
3313 return;
3316 if (skip_past_comma (&str) == SUCCESS)
3318 if (cp_opc_expr (&str, 5, 3) == FAIL)
3320 if (!inst.error)
3321 inst.error = bad_args;
3322 return;
3326 end_of_line (str);
3327 return;
3330 static void
3331 do_fp_ctrl (str, flags)
3332 char * str;
3333 unsigned long flags;
3335 /* FP control registers.
3336 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3338 while (*str == ' ')
3339 str++;
3341 if (reg_required_here (&str, 12) == FAIL)
3343 if (!inst.error)
3344 inst.error = bad_args;
3345 return;
3348 end_of_line (str);
3349 return;
3352 static void
3353 do_fp_ldst (str, flags)
3354 char * str;
3355 unsigned long flags;
3357 while (*str == ' ')
3358 str++;
3360 switch (inst.suffix)
3362 case SUFF_S:
3363 break;
3364 case SUFF_D:
3365 inst.instruction |= CP_T_X;
3366 break;
3367 case SUFF_E:
3368 inst.instruction |= CP_T_Y;
3369 break;
3370 case SUFF_P:
3371 inst.instruction |= CP_T_X | CP_T_Y;
3372 break;
3373 default:
3374 abort ();
3377 if (fp_reg_required_here (&str, 12) == FAIL)
3379 if (!inst.error)
3380 inst.error = bad_args;
3381 return;
3384 if (skip_past_comma (&str) == FAIL
3385 || cp_address_required_here (&str) == FAIL)
3387 if (!inst.error)
3388 inst.error = bad_args;
3389 return;
3392 end_of_line (str);
3395 static void
3396 do_fp_ldmstm (str, flags)
3397 char * str;
3398 unsigned long flags;
3400 int num_regs;
3402 while (*str == ' ')
3403 str++;
3405 if (fp_reg_required_here (&str, 12) == FAIL)
3407 if (! inst.error)
3408 inst.error = bad_args;
3409 return;
3412 /* Get Number of registers to transfer */
3413 if (skip_past_comma (&str) == FAIL
3414 || my_get_expression (&inst.reloc.exp, &str))
3416 if (! inst.error)
3417 inst.error = _("constant expression expected");
3418 return;
3421 if (inst.reloc.exp.X_op != O_constant)
3423 inst.error = _("Constant value required for number of registers");
3424 return;
3427 num_regs = inst.reloc.exp.X_add_number;
3429 if (num_regs < 1 || num_regs > 4)
3431 inst.error = _("number of registers must be in the range [1:4]");
3432 return;
3435 switch (num_regs)
3437 case 1:
3438 inst.instruction |= CP_T_X;
3439 break;
3440 case 2:
3441 inst.instruction |= CP_T_Y;
3442 break;
3443 case 3:
3444 inst.instruction |= CP_T_Y | CP_T_X;
3445 break;
3446 case 4:
3447 break;
3448 default:
3449 abort ();
3452 if (flags)
3454 int reg;
3455 int write_back;
3456 int offset;
3458 /* The instruction specified "ea" or "fd", so we can only accept
3459 [Rn]{!}. The instruction does not really support stacking or
3460 unstacking, so we have to emulate these by setting appropriate
3461 bits and offsets. */
3462 if (skip_past_comma (&str) == FAIL
3463 || *str != '[')
3465 if (! inst.error)
3466 inst.error = bad_args;
3467 return;
3470 str++;
3471 while (*str == ' ')
3472 str++;
3474 if ((reg = reg_required_here (&str, 16)) == FAIL)
3475 return;
3477 while (*str == ' ')
3478 str++;
3480 if (*str != ']')
3482 inst.error = bad_args;
3483 return;
3486 str++;
3487 if (*str == '!')
3489 write_back = 1;
3490 str++;
3491 if (reg == REG_PC)
3493 inst.error = _("R15 not allowed as base register with write-back");
3494 return;
3497 else
3498 write_back = 0;
3500 if (flags & CP_T_Pre)
3502 /* Pre-decrement */
3503 offset = 3 * num_regs;
3504 if (write_back)
3505 flags |= CP_T_WB;
3507 else
3509 /* Post-increment */
3510 if (write_back)
3512 flags |= CP_T_WB;
3513 offset = 3 * num_regs;
3515 else
3517 /* No write-back, so convert this into a standard pre-increment
3518 instruction -- aesthetically more pleasing. */
3519 flags = CP_T_Pre | CP_T_UD;
3520 offset = 0;
3524 inst.instruction |= flags | offset;
3526 else if (skip_past_comma (&str) == FAIL
3527 || cp_address_required_here (&str) == FAIL)
3529 if (! inst.error)
3530 inst.error = bad_args;
3531 return;
3534 end_of_line (str);
3537 static void
3538 do_fp_dyadic (str, flags)
3539 char * str;
3540 unsigned long flags;
3542 while (*str == ' ')
3543 str++;
3545 switch (inst.suffix)
3547 case SUFF_S:
3548 break;
3549 case SUFF_D:
3550 inst.instruction |= 0x00000080;
3551 break;
3552 case SUFF_E:
3553 inst.instruction |= 0x00080000;
3554 break;
3555 default:
3556 abort ();
3559 if (fp_reg_required_here (&str, 12) == FAIL)
3561 if (! inst.error)
3562 inst.error = bad_args;
3563 return;
3566 if (skip_past_comma (&str) == FAIL
3567 || fp_reg_required_here (&str, 16) == FAIL)
3569 if (! inst.error)
3570 inst.error = bad_args;
3571 return;
3574 if (skip_past_comma (&str) == FAIL
3575 || fp_op2 (&str) == FAIL)
3577 if (! inst.error)
3578 inst.error = bad_args;
3579 return;
3582 inst.instruction |= flags;
3583 end_of_line (str);
3584 return;
3587 static void
3588 do_fp_monadic (str, flags)
3589 char * str;
3590 unsigned long flags;
3592 while (*str == ' ')
3593 str++;
3595 switch (inst.suffix)
3597 case SUFF_S:
3598 break;
3599 case SUFF_D:
3600 inst.instruction |= 0x00000080;
3601 break;
3602 case SUFF_E:
3603 inst.instruction |= 0x00080000;
3604 break;
3605 default:
3606 abort ();
3609 if (fp_reg_required_here (&str, 12) == FAIL)
3611 if (! inst.error)
3612 inst.error = bad_args;
3613 return;
3616 if (skip_past_comma (&str) == FAIL
3617 || fp_op2 (&str) == FAIL)
3619 if (! inst.error)
3620 inst.error = bad_args;
3621 return;
3624 inst.instruction |= flags;
3625 end_of_line (str);
3626 return;
3629 static void
3630 do_fp_cmp (str, flags)
3631 char * str;
3632 unsigned long flags;
3634 while (*str == ' ')
3635 str++;
3637 if (fp_reg_required_here (&str, 16) == FAIL)
3639 if (! inst.error)
3640 inst.error = bad_args;
3641 return;
3644 if (skip_past_comma (&str) == FAIL
3645 || fp_op2 (&str) == FAIL)
3647 if (! inst.error)
3648 inst.error = bad_args;
3649 return;
3652 inst.instruction |= flags;
3653 end_of_line (str);
3654 return;
3657 static void
3658 do_fp_from_reg (str, flags)
3659 char * str;
3660 unsigned long flags;
3662 while (*str == ' ')
3663 str++;
3665 switch (inst.suffix)
3667 case SUFF_S:
3668 break;
3669 case SUFF_D:
3670 inst.instruction |= 0x00000080;
3671 break;
3672 case SUFF_E:
3673 inst.instruction |= 0x00080000;
3674 break;
3675 default:
3676 abort ();
3679 if (fp_reg_required_here (&str, 16) == FAIL)
3681 if (! inst.error)
3682 inst.error = bad_args;
3683 return;
3686 if (skip_past_comma (&str) == FAIL
3687 || reg_required_here (&str, 12) == FAIL)
3689 if (! inst.error)
3690 inst.error = bad_args;
3691 return;
3694 inst.instruction |= flags;
3695 end_of_line (str);
3696 return;
3699 static void
3700 do_fp_to_reg (str, flags)
3701 char * str;
3702 unsigned long flags;
3704 while (*str == ' ')
3705 str++;
3707 if (reg_required_here (&str, 12) == FAIL)
3708 return;
3710 if (skip_past_comma (&str) == FAIL
3711 || fp_reg_required_here (&str, 0) == FAIL)
3713 if (! inst.error)
3714 inst.error = bad_args;
3715 return;
3718 inst.instruction |= flags;
3719 end_of_line (str);
3720 return;
3723 /* Thumb specific routines */
3725 /* Parse and validate that a register is of the right form, this saves
3726 repeated checking of this information in many similar cases.
3727 Unlike the 32-bit case we do not insert the register into the opcode
3728 here, since the position is often unknown until the full instruction
3729 has been parsed. */
3730 static int
3731 thumb_reg (strp, hi_lo)
3732 char ** strp;
3733 int hi_lo;
3735 int reg;
3737 if ((reg = reg_required_here (strp, -1)) == FAIL)
3738 return FAIL;
3740 switch (hi_lo)
3742 case THUMB_REG_LO:
3743 if (reg > 7)
3745 inst.error = _("lo register required");
3746 return FAIL;
3748 break;
3750 case THUMB_REG_HI:
3751 if (reg < 8)
3753 inst.error = _("hi register required");
3754 return FAIL;
3756 break;
3758 default:
3759 break;
3762 return reg;
3765 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3766 was SUB. */
3767 static void
3768 thumb_add_sub (str, subtract)
3769 char * str;
3770 int subtract;
3772 int Rd, Rs, Rn = FAIL;
3774 while (*str == ' ')
3775 str++;
3777 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
3778 || skip_past_comma (&str) == FAIL)
3780 if (! inst.error)
3781 inst.error = bad_args;
3782 return;
3785 if (is_immediate_prefix (*str))
3787 Rs = Rd;
3788 str++;
3789 if (my_get_expression (&inst.reloc.exp, &str))
3790 return;
3792 else
3794 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3795 return;
3797 if (skip_past_comma (&str) == FAIL)
3799 /* Two operand format, shuffle the registers and pretend there
3800 are 3 */
3801 Rn = Rs;
3802 Rs = Rd;
3804 else if (is_immediate_prefix (*str))
3806 str++;
3807 if (my_get_expression (&inst.reloc.exp, &str))
3808 return;
3810 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3811 return;
3814 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3815 for the latter case, EXPR contains the immediate that was found. */
3816 if (Rn != FAIL)
3818 /* All register format. */
3819 if (Rd > 7 || Rs > 7 || Rn > 7)
3821 if (Rs != Rd)
3823 inst.error = _("dest and source1 must be the same register");
3824 return;
3827 /* Can't do this for SUB */
3828 if (subtract)
3830 inst.error = _("subtract valid only on lo regs");
3831 return;
3834 inst.instruction = (T_OPCODE_ADD_HI
3835 | (Rd > 7 ? THUMB_H1 : 0)
3836 | (Rn > 7 ? THUMB_H2 : 0));
3837 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
3839 else
3841 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
3842 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
3845 else
3847 /* Immediate expression, now things start to get nasty. */
3849 /* First deal with HI regs, only very restricted cases allowed:
3850 Adjusting SP, and using PC or SP to get an address. */
3851 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
3852 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
3854 inst.error = _("invalid Hi register with immediate");
3855 return;
3858 if (inst.reloc.exp.X_op != O_constant)
3860 /* Value isn't known yet, all we can do is store all the fragments
3861 we know about in the instruction and let the reloc hacking
3862 work it all out. */
3863 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
3864 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
3866 else
3868 int offset = inst.reloc.exp.X_add_number;
3870 if (subtract)
3871 offset = -offset;
3873 if (offset < 0)
3875 offset = -offset;
3876 subtract = 1;
3878 /* Quick check, in case offset is MIN_INT */
3879 if (offset < 0)
3881 inst.error = _("immediate value out of range");
3882 return;
3885 else
3886 subtract = 0;
3888 if (Rd == REG_SP)
3890 if (offset & ~0x1fc)
3892 inst.error = _("invalid immediate value for stack adjust");
3893 return;
3895 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
3896 inst.instruction |= offset >> 2;
3898 else if (Rs == REG_PC || Rs == REG_SP)
3900 if (subtract
3901 || (offset & ~0x3fc))
3903 inst.error = _("invalid immediate for address calculation");
3904 return;
3906 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
3907 : T_OPCODE_ADD_SP);
3908 inst.instruction |= (Rd << 8) | (offset >> 2);
3910 else if (Rs == Rd)
3912 if (offset & ~0xff)
3914 inst.error = _("immediate value out of range");
3915 return;
3917 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
3918 inst.instruction |= (Rd << 8) | offset;
3920 else
3922 if (offset & ~0x7)
3924 inst.error = _("immediate value out of range");
3925 return;
3927 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
3928 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
3932 end_of_line (str);
3935 static void
3936 thumb_shift (str, shift)
3937 char * str;
3938 int shift;
3940 int Rd, Rs, Rn = FAIL;
3942 while (*str == ' ')
3943 str++;
3945 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
3946 || skip_past_comma (&str) == FAIL)
3948 if (! inst.error)
3949 inst.error = bad_args;
3950 return;
3953 if (is_immediate_prefix (*str))
3955 /* Two operand immediate format, set Rs to Rd. */
3956 Rs = Rd;
3957 str++;
3958 if (my_get_expression (&inst.reloc.exp, &str))
3959 return;
3961 else
3963 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
3964 return;
3966 if (skip_past_comma (&str) == FAIL)
3968 /* Two operand format, shuffle the registers and pretend there
3969 are 3 */
3970 Rn = Rs;
3971 Rs = Rd;
3973 else if (is_immediate_prefix (*str))
3975 str++;
3976 if (my_get_expression (&inst.reloc.exp, &str))
3977 return;
3979 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
3980 return;
3983 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3984 for the latter case, EXPR contains the immediate that was found. */
3986 if (Rn != FAIL)
3988 if (Rs != Rd)
3990 inst.error = _("source1 and dest must be same register");
3991 return;
3994 switch (shift)
3996 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
3997 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
3998 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
4001 inst.instruction |= Rd | (Rn << 3);
4003 else
4005 switch (shift)
4007 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
4008 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
4009 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
4012 if (inst.reloc.exp.X_op != O_constant)
4014 /* Value isn't known yet, create a dummy reloc and let reloc
4015 hacking fix it up */
4017 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
4019 else
4021 unsigned shift_value = inst.reloc.exp.X_add_number;
4023 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
4025 inst.error = _("Invalid immediate for shift");
4026 return;
4029 /* Shifts of zero are handled by converting to LSL */
4030 if (shift_value == 0)
4031 inst.instruction = T_OPCODE_LSL_I;
4033 /* Shifts of 32 are encoded as a shift of zero */
4034 if (shift_value == 32)
4035 shift_value = 0;
4037 inst.instruction |= shift_value << 6;
4040 inst.instruction |= Rd | (Rs << 3);
4042 end_of_line (str);
4045 static void
4046 thumb_mov_compare (str, move)
4047 char * str;
4048 int move;
4050 int Rd, Rs = FAIL;
4052 while (*str == ' ')
4053 str++;
4055 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4056 || skip_past_comma (&str) == FAIL)
4058 if (! inst.error)
4059 inst.error = bad_args;
4060 return;
4063 if (is_immediate_prefix (*str))
4065 str++;
4066 if (my_get_expression (&inst.reloc.exp, &str))
4067 return;
4069 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4070 return;
4072 if (Rs != FAIL)
4074 if (Rs < 8 && Rd < 8)
4076 if (move == THUMB_MOVE)
4077 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4078 since a MOV instruction produces unpredictable results */
4079 inst.instruction = T_OPCODE_ADD_I3;
4080 else
4081 inst.instruction = T_OPCODE_CMP_LR;
4082 inst.instruction |= Rd | (Rs << 3);
4084 else
4086 if (move == THUMB_MOVE)
4087 inst.instruction = T_OPCODE_MOV_HR;
4088 else
4089 inst.instruction = T_OPCODE_CMP_HR;
4091 if (Rd > 7)
4092 inst.instruction |= THUMB_H1;
4094 if (Rs > 7)
4095 inst.instruction |= THUMB_H2;
4097 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4100 else
4102 if (Rd > 7)
4104 inst.error = _("only lo regs allowed with immediate");
4105 return;
4108 if (move == THUMB_MOVE)
4109 inst.instruction = T_OPCODE_MOV_I8;
4110 else
4111 inst.instruction = T_OPCODE_CMP_I8;
4113 inst.instruction |= Rd << 8;
4115 if (inst.reloc.exp.X_op != O_constant)
4116 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4117 else
4119 unsigned value = inst.reloc.exp.X_add_number;
4121 if (value > 255)
4123 inst.error = _("invalid immediate");
4124 return;
4127 inst.instruction |= value;
4131 end_of_line (str);
4134 static void
4135 thumb_load_store (str, load_store, size)
4136 char * str;
4137 int load_store;
4138 int size;
4140 int Rd, Rb, Ro = FAIL;
4142 while (*str == ' ')
4143 str++;
4145 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4146 || skip_past_comma (&str) == FAIL)
4148 if (! inst.error)
4149 inst.error = bad_args;
4150 return;
4153 if (*str == '[')
4155 str++;
4156 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4157 return;
4159 if (skip_past_comma (&str) != FAIL)
4161 if (is_immediate_prefix (*str))
4163 str++;
4164 if (my_get_expression (&inst.reloc.exp, &str))
4165 return;
4167 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4168 return;
4170 else
4172 inst.reloc.exp.X_op = O_constant;
4173 inst.reloc.exp.X_add_number = 0;
4176 if (*str != ']')
4178 inst.error = _("expected ']'");
4179 return;
4181 str++;
4183 else if (*str == '=')
4185 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4186 str++;
4188 while (*str == ' ')
4189 str++;
4191 if (my_get_expression (& inst.reloc.exp, & str))
4192 return;
4194 end_of_line (str);
4196 if ( inst.reloc.exp.X_op != O_constant
4197 && inst.reloc.exp.X_op != O_symbol)
4199 inst.error = "Constant expression expected";
4200 return;
4203 if (inst.reloc.exp.X_op == O_constant
4204 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
4206 /* This can be done with a mov instruction */
4208 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
4209 inst.instruction |= inst.reloc.exp.X_add_number;
4210 return;
4213 /* Insert into literal pool */
4214 if (add_to_lit_pool () == FAIL)
4216 if (!inst.error)
4217 inst.error = "literal pool insertion failed";
4218 return;
4221 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4222 inst.reloc.pc_rel = 1;
4223 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4224 inst.reloc.exp.X_add_number += 4; /* Adjust ARM pipeline offset to Thumb */
4226 return;
4228 else
4230 if (my_get_expression (&inst.reloc.exp, &str))
4231 return;
4233 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4234 inst.reloc.pc_rel = 1;
4235 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
4236 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4237 end_of_line (str);
4238 return;
4241 if (Rb == REG_PC || Rb == REG_SP)
4243 if (size != THUMB_WORD)
4245 inst.error = _("byte or halfword not valid for base register");
4246 return;
4248 else if (Rb == REG_PC && load_store != THUMB_LOAD)
4250 inst.error = _("R15 based store not allowed");
4251 return;
4253 else if (Ro != FAIL)
4255 inst.error = _("Invalid base register for register offset");
4256 return;
4259 if (Rb == REG_PC)
4260 inst.instruction = T_OPCODE_LDR_PC;
4261 else if (load_store == THUMB_LOAD)
4262 inst.instruction = T_OPCODE_LDR_SP;
4263 else
4264 inst.instruction = T_OPCODE_STR_SP;
4266 inst.instruction |= Rd << 8;
4267 if (inst.reloc.exp.X_op == O_constant)
4269 unsigned offset = inst.reloc.exp.X_add_number;
4271 if (offset & ~0x3fc)
4273 inst.error = _("invalid offset");
4274 return;
4277 inst.instruction |= offset >> 2;
4279 else
4280 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4282 else if (Rb > 7)
4284 inst.error = _("invalid base register in load/store");
4285 return;
4287 else if (Ro == FAIL)
4289 /* Immediate offset */
4290 if (size == THUMB_WORD)
4291 inst.instruction = (load_store == THUMB_LOAD
4292 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
4293 else if (size == THUMB_HALFWORD)
4294 inst.instruction = (load_store == THUMB_LOAD
4295 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
4296 else
4297 inst.instruction = (load_store == THUMB_LOAD
4298 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
4300 inst.instruction |= Rd | (Rb << 3);
4302 if (inst.reloc.exp.X_op == O_constant)
4304 unsigned offset = inst.reloc.exp.X_add_number;
4306 if (offset & ~(0x1f << size))
4308 inst.error = _("Invalid offset");
4309 return;
4311 inst.instruction |= (offset >> size) << 6;
4313 else
4314 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4316 else
4318 /* Register offset */
4319 if (size == THUMB_WORD)
4320 inst.instruction = (load_store == THUMB_LOAD
4321 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
4322 else if (size == THUMB_HALFWORD)
4323 inst.instruction = (load_store == THUMB_LOAD
4324 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
4325 else
4326 inst.instruction = (load_store == THUMB_LOAD
4327 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
4329 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4332 end_of_line (str);
4335 static void
4336 do_t_nop (str)
4337 char * str;
4339 /* Do nothing */
4340 end_of_line (str);
4341 return;
4344 /* Handle the Format 4 instructions that do not have equivalents in other
4345 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4346 BIC and MVN. */
4347 static void
4348 do_t_arit (str)
4349 char * str;
4351 int Rd, Rs, Rn;
4353 while (*str == ' ')
4354 str++;
4356 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4357 return;
4359 if (skip_past_comma (&str) == FAIL
4360 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4362 if (! inst.error)
4363 inst.error = bad_args;
4364 return;
4367 if (skip_past_comma (&str) != FAIL)
4369 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4370 (It isn't allowed for CMP either, but that isn't handled by this
4371 function.) */
4372 if (inst.instruction == T_OPCODE_TST
4373 || inst.instruction == T_OPCODE_CMN
4374 || inst.instruction == T_OPCODE_NEG
4375 || inst.instruction == T_OPCODE_MVN)
4377 inst.error = bad_args;
4378 return;
4381 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4382 return;
4384 if (Rs != Rd)
4386 inst.error = _("dest and source1 one must be the same register");
4387 return;
4389 Rs = Rn;
4392 if (inst.instruction == T_OPCODE_MUL
4393 && Rs == Rd)
4394 as_tsktsk (_("Rs and Rd must be different in MUL"));
4396 inst.instruction |= Rd | (Rs << 3);
4397 end_of_line (str);
4400 static void
4401 do_t_add (str)
4402 char * str;
4404 thumb_add_sub (str, 0);
4407 static void
4408 do_t_asr (str)
4409 char * str;
4411 thumb_shift (str, THUMB_ASR);
4414 static void
4415 do_t_branch9 (str)
4416 char * str;
4418 if (my_get_expression (&inst.reloc.exp, &str))
4419 return;
4420 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
4421 inst.reloc.pc_rel = 1;
4422 end_of_line (str);
4425 static void
4426 do_t_branch12 (str)
4427 char * str;
4429 if (my_get_expression (&inst.reloc.exp, &str))
4430 return;
4431 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
4432 inst.reloc.pc_rel = 1;
4433 end_of_line (str);
4436 /* Find the real, Thumb encoded start of a Thumb function. */
4438 static symbolS *
4439 find_real_start (symbolP)
4440 symbolS * symbolP;
4442 char * real_start;
4443 const char * name = S_GET_NAME (symbolP);
4444 symbolS * new_target;
4446 /* This definitonmust agree with the one in gcc/config/arm/thumb.c */
4447 #define STUB_NAME ".real_start_of"
4449 if (name == NULL)
4450 abort();
4452 /* Names that start with '.' are local labels, not function entry points.
4453 The compiler may generate BL instructions to these labels because it
4454 needs to perform a branch to a far away location. */
4455 if (name[0] == '.')
4456 return symbolP;
4458 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
4459 sprintf (real_start, "%s%s", STUB_NAME, name);
4461 new_target = symbol_find (real_start);
4463 if (new_target == NULL)
4465 as_warn ("Failed to find real start of function: %s\n", name);
4466 new_target = symbolP;
4469 free (real_start);
4471 return new_target;
4475 static void
4476 do_t_branch23 (str)
4477 char * str;
4479 if (my_get_expression (&inst.reloc.exp, &str))
4480 return;
4481 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
4482 inst.reloc.pc_rel = 1;
4483 end_of_line (str);
4485 /* If the destination of the branch is a defined symbol which does not have
4486 the THUMB_FUNC attribute, then we must be calling a function which has
4487 the (interfacearm) attribute. We look for the Thumb entry point to that
4488 function and change the branch to refer to that function instead. */
4489 if ( inst.reloc.exp.X_op == O_symbol
4490 && inst.reloc.exp.X_add_symbol != NULL
4491 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
4492 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
4493 inst.reloc.exp.X_add_symbol = find_real_start (inst.reloc.exp.X_add_symbol);
4496 static void
4497 do_t_bx (str)
4498 char * str;
4500 int reg;
4502 while (*str == ' ')
4503 str++;
4505 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4506 return;
4508 /* This sets THUMB_H2 from the top bit of reg. */
4509 inst.instruction |= reg << 3;
4511 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4512 should cause the alignment to be checked once it is known. This is
4513 because BX PC only works if the instruction is word aligned. */
4515 end_of_line (str);
4518 static void
4519 do_t_compare (str)
4520 char * str;
4522 thumb_mov_compare (str, THUMB_COMPARE);
4525 static void
4526 do_t_ldmstm (str)
4527 char * str;
4529 int Rb;
4530 long range;
4532 while (*str == ' ')
4533 str++;
4535 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4536 return;
4538 if (*str != '!')
4539 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4540 else
4541 str++;
4543 if (skip_past_comma (&str) == FAIL
4544 || (range = reg_list (&str)) == FAIL)
4546 if (! inst.error)
4547 inst.error = bad_args;
4548 return;
4551 if (inst.reloc.type != BFD_RELOC_NONE)
4553 /* This really doesn't seem worth it. */
4554 inst.reloc.type = BFD_RELOC_NONE;
4555 inst.error = _("Expression too complex");
4556 return;
4559 if (range & ~0xff)
4561 inst.error = _("only lo-regs valid in load/store multiple");
4562 return;
4565 inst.instruction |= (Rb << 8) | range;
4566 end_of_line (str);
4569 static void
4570 do_t_ldr (str)
4571 char * str;
4573 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4576 static void
4577 do_t_ldrb (str)
4578 char * str;
4580 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4583 static void
4584 do_t_ldrh (str)
4585 char * str;
4587 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4590 static void
4591 do_t_lds (str)
4592 char * str;
4594 int Rd, Rb, Ro;
4596 while (*str == ' ')
4597 str++;
4599 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4600 || skip_past_comma (&str) == FAIL
4601 || *str++ != '['
4602 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4603 || skip_past_comma (&str) == FAIL
4604 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4605 || *str++ != ']')
4607 if (! inst.error)
4608 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4609 return;
4612 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4613 end_of_line (str);
4616 static void
4617 do_t_lsl (str)
4618 char * str;
4620 thumb_shift (str, THUMB_LSL);
4623 static void
4624 do_t_lsr (str)
4625 char * str;
4627 thumb_shift (str, THUMB_LSR);
4630 static void
4631 do_t_mov (str)
4632 char * str;
4634 thumb_mov_compare (str, THUMB_MOVE);
4637 static void
4638 do_t_push_pop (str)
4639 char * str;
4641 long range;
4643 while (*str == ' ')
4644 str++;
4646 if ((range = reg_list (&str)) == FAIL)
4648 if (! inst.error)
4649 inst.error = bad_args;
4650 return;
4653 if (inst.reloc.type != BFD_RELOC_NONE)
4655 /* This really doesn't seem worth it. */
4656 inst.reloc.type = BFD_RELOC_NONE;
4657 inst.error = _("Expression too complex");
4658 return;
4661 if (range & ~0xff)
4663 if ((inst.instruction == T_OPCODE_PUSH
4664 && (range & ~0xff) == 1 << REG_LR)
4665 || (inst.instruction == T_OPCODE_POP
4666 && (range & ~0xff) == 1 << REG_PC))
4668 inst.instruction |= THUMB_PP_PC_LR;
4669 range &= 0xff;
4671 else
4673 inst.error = _("invalid register list to push/pop instruction");
4674 return;
4678 inst.instruction |= range;
4679 end_of_line (str);
4682 static void
4683 do_t_str (str)
4684 char * str;
4686 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4689 static void
4690 do_t_strb (str)
4691 char * str;
4693 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4696 static void
4697 do_t_strh (str)
4698 char * str;
4700 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4703 static void
4704 do_t_sub (str)
4705 char * str;
4707 thumb_add_sub (str, 1);
4710 static void
4711 do_t_swi (str)
4712 char * str;
4714 while (*str == ' ')
4715 str++;
4717 if (my_get_expression (&inst.reloc.exp, &str))
4718 return;
4720 inst.reloc.type = BFD_RELOC_ARM_SWI;
4721 end_of_line (str);
4722 return;
4725 static void
4726 do_t_adr (str)
4727 char * str;
4729 /* This is a pseudo-op of the form "adr rd, label" to be converted
4730 into a relative address of the form "add rd, pc, #label-.-4" */
4731 while (*str == ' ')
4732 str++;
4734 if (reg_required_here (&str, 4) == FAIL /* Store Rd in temporary location inside instruction. */
4735 || skip_past_comma (&str) == FAIL
4736 || my_get_expression (&inst.reloc.exp, &str))
4738 if (!inst.error)
4739 inst.error = bad_args;
4740 return;
4743 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4744 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
4745 inst.reloc.pc_rel = 1;
4746 inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
4747 end_of_line (str);
4750 static void
4751 insert_reg (entry)
4752 int entry;
4754 int len = strlen (reg_table[entry].name) + 2;
4755 char * buf = (char *) xmalloc (len);
4756 char * buf2 = (char *) xmalloc (len);
4757 int i = 0;
4759 #ifdef REGISTER_PREFIX
4760 buf[i++] = REGISTER_PREFIX;
4761 #endif
4763 strcpy (buf + i, reg_table[entry].name);
4765 for (i = 0; buf[i]; i++)
4766 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
4768 buf2[i] = '\0';
4770 hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
4771 hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
4774 static void
4775 insert_reg_alias (str, regnum)
4776 char *str;
4777 int regnum;
4779 struct reg_entry *new =
4780 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
4781 char *name = xmalloc (strlen (str) + 1);
4782 strcpy (name, str);
4784 new->name = name;
4785 new->number = regnum;
4787 hash_insert (arm_reg_hsh, name, (PTR) new);
4790 static void
4791 set_constant_flonums ()
4793 int i;
4795 for (i = 0; i < NUM_FLOAT_VALS; i++)
4796 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
4797 abort ();
4800 void
4801 md_begin ()
4803 int i;
4805 if ( (arm_ops_hsh = hash_new ()) == NULL
4806 || (arm_tops_hsh = hash_new ()) == NULL
4807 || (arm_cond_hsh = hash_new ()) == NULL
4808 || (arm_shift_hsh = hash_new ()) == NULL
4809 || (arm_reg_hsh = hash_new ()) == NULL
4810 || (arm_psr_hsh = hash_new ()) == NULL)
4811 as_fatal (_("Virtual memory exhausted"));
4813 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
4814 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
4815 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
4816 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
4817 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
4818 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
4819 for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
4820 hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
4821 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
4822 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
4824 for (i = 0; reg_table[i].name; i++)
4825 insert_reg (i);
4827 set_constant_flonums ();
4829 #if defined OBJ_COFF || defined OBJ_ELF
4831 unsigned int flags = 0;
4833 /* Set the flags in the private structure */
4834 if (uses_apcs_26) flags |= F_APCS26;
4835 if (support_interwork) flags |= F_INTERWORK;
4836 if (uses_apcs_float) flags |= F_APCS_FLOAT;
4837 if (pic_code) flags |= F_PIC;
4839 bfd_set_private_flags (stdoutput, flags);
4841 #endif
4844 unsigned mach;
4846 /* Record the CPU type as well */
4847 switch (cpu_variant & ARM_CPU_MASK)
4849 case ARM_2:
4850 mach = bfd_mach_arm_2;
4851 break;
4853 case ARM_3: /* also ARM_250 */
4854 mach = bfd_mach_arm_2a;
4855 break;
4857 default:
4858 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined */
4859 mach = bfd_mach_arm_4;
4860 break;
4862 case ARM_7: /* also ARM_6 */
4863 mach = bfd_mach_arm_3;
4864 break;
4867 /* Catch special cases */
4868 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
4870 if (cpu_variant & ARM_THUMB)
4871 mach = bfd_mach_arm_4T;
4872 else if ((cpu_variant & ARM_ARCHv4) == ARM_ARCHv4)
4873 mach = bfd_mach_arm_4;
4874 else if (cpu_variant & ARM_LONGMUL)
4875 mach = bfd_mach_arm_3M;
4878 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
4882 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
4883 for use in the a.out file, and stores them in the array pointed to by buf.
4884 This knows about the endian-ness of the target machine and does
4885 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
4886 2 (short) and 4 (long) Floating numbers are put out as a series of
4887 LITTLENUMS (shorts, here at least)
4889 void
4890 md_number_to_chars (buf, val, n)
4891 char * buf;
4892 valueT val;
4893 int n;
4895 if (target_big_endian)
4896 number_to_chars_bigendian (buf, val, n);
4897 else
4898 number_to_chars_littleendian (buf, val, n);
4901 static valueT
4902 md_chars_to_number (buf, n)
4903 char * buf;
4904 int n;
4906 valueT result = 0;
4907 unsigned char * where = (unsigned char *) buf;
4909 if (target_big_endian)
4911 while (n--)
4913 result <<= 8;
4914 result |= (*where++ & 255);
4917 else
4919 while (n--)
4921 result <<= 8;
4922 result |= (where[n] & 255);
4926 return result;
4929 /* Turn a string in input_line_pointer into a floating point constant
4930 of type TYPE, and store the appropriate bytes in *litP. The number
4931 of LITTLENUMS emitted is stored in *sizeP . An error message is
4932 returned, or NULL on OK.
4934 Note that fp constants aren't represent in the normal way on the ARM.
4935 In big endian mode, things are as expected. However, in little endian
4936 mode fp constants are big-endian word-wise, and little-endian byte-wise
4937 within the words. For example, (double) 1.1 in big endian mode is
4938 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
4939 the byte sequence 99 99 f1 3f 9a 99 99 99.
4941 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
4943 char *
4944 md_atof (type, litP, sizeP)
4945 char type;
4946 char * litP;
4947 int * sizeP;
4949 int prec;
4950 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4951 char *t;
4952 int i;
4954 switch (type)
4956 case 'f':
4957 case 'F':
4958 case 's':
4959 case 'S':
4960 prec = 2;
4961 break;
4963 case 'd':
4964 case 'D':
4965 case 'r':
4966 case 'R':
4967 prec = 4;
4968 break;
4970 case 'x':
4971 case 'X':
4972 prec = 6;
4973 break;
4975 case 'p':
4976 case 'P':
4977 prec = 6;
4978 break;
4980 default:
4981 *sizeP = 0;
4982 return _("Bad call to MD_ATOF()");
4985 t = atof_ieee (input_line_pointer, type, words);
4986 if (t)
4987 input_line_pointer = t;
4988 *sizeP = prec * 2;
4990 if (target_big_endian)
4992 for (i = 0; i < prec; i++)
4994 md_number_to_chars (litP, (valueT) words[i], 2);
4995 litP += 2;
4998 else
5000 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5001 8 byte float the order is 1 0 3 2. */
5002 for (i = 0; i < prec; i += 2)
5004 md_number_to_chars (litP, (valueT) words[i + 1], 2);
5005 md_number_to_chars (litP + 2, (valueT) words[i], 2);
5006 litP += 4;
5010 return 0;
5013 /* The knowledge of the PC's pipeline offset is built into the relocs
5014 for the ELF port and into the insns themselves for the COFF port. */
5015 long
5016 md_pcrel_from (fixP)
5017 fixS * fixP;
5019 if ( fixP->fx_addsy
5020 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
5021 && fixP->fx_subsy == NULL)
5022 return 0;
5024 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
5026 /* PC relative addressing on the Thumb is slightly odd
5027 as the bottom two bits of the PC are forced to zero
5028 for the calculation */
5029 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
5032 return fixP->fx_where + fixP->fx_frag->fr_address;
5035 /* Round up a section size to the appropriate boundary. */
5036 valueT
5037 md_section_align (segment, size)
5038 segT segment;
5039 valueT size;
5041 #ifdef OBJ_ELF
5042 /* Don't align the dwarf2 debug sections */
5043 if (!strncmp (segment->name, ".debug", 5))
5044 return size;
5045 #endif
5046 /* Round all sects to multiple of 4 */
5047 return (size + 3) & ~3;
5050 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5051 we have no need to default values of symbols. */
5053 /* ARGSUSED */
5054 symbolS *
5055 md_undefined_symbol (name)
5056 char * name;
5058 #ifdef OBJ_ELF
5059 if (name[0] == '_' && name[1] == 'G'
5060 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
5062 if (!GOT_symbol)
5064 if (symbol_find (name))
5065 as_bad ("GOT already in the symbol table");
5067 GOT_symbol = symbol_new (name, undefined_section,
5068 (valueT)0, & zero_address_frag);
5071 return GOT_symbol;
5073 #endif
5075 return 0;
5078 /* arm_reg_parse () := if it looks like a register, return its token and
5079 advance the pointer. */
5081 static int
5082 arm_reg_parse (ccp)
5083 register char ** ccp;
5085 char * start = * ccp;
5086 char c;
5087 char * p;
5088 struct reg_entry * reg;
5090 #ifdef REGISTER_PREFIX
5091 if (*start != REGISTER_PREFIX)
5092 return FAIL;
5093 p = start + 1;
5094 #else
5095 p = start;
5096 #ifdef OPTIONAL_REGISTER_PREFIX
5097 if (*p == OPTIONAL_REGISTER_PREFIX)
5098 p++, start++;
5099 #endif
5100 #endif
5101 if (!isalpha (*p) || !is_name_beginner (*p))
5102 return FAIL;
5104 c = *p++;
5105 while (isalpha (c) || isdigit (c) || c == '_')
5106 c = *p++;
5108 *--p = 0;
5109 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
5110 *p = c;
5112 if (reg)
5114 *ccp = p;
5115 return reg->number;
5118 return FAIL;
5121 static int
5122 arm_psr_parse (ccp)
5123 register char ** ccp;
5125 char * start = * ccp;
5126 char c;
5127 char * p;
5128 CONST struct asm_psr * psr;
5130 p = start;
5131 c = *p++;
5132 while (isalpha (c) || c == '_')
5133 c = *p++;
5135 *--p = 0;
5136 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
5137 *p = c;
5139 if (psr)
5141 *ccp = p;
5142 return psr->number;
5145 return FAIL;
5149 md_apply_fix3 (fixP, val, seg)
5150 fixS * fixP;
5151 valueT * val;
5152 segT seg;
5154 offsetT value = * val;
5155 offsetT newval;
5156 unsigned int newimm;
5157 unsigned long temp;
5158 int sign;
5159 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5160 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
5162 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5164 /* Note whether this will delete the relocation. */
5165 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5166 if ((fixP->fx_addsy == 0 || fixP->fx_addsy->sy_value.X_op == O_constant)
5167 && !fixP->fx_pcrel)
5168 #else
5169 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5170 #endif
5171 fixP->fx_done = 1;
5173 /* If this symbol is in a different section then we need to leave it for
5174 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5175 so we have to undo it's effects here. */
5176 if (fixP->fx_pcrel)
5178 if (fixP->fx_addsy != NULL
5179 && S_IS_DEFINED (fixP->fx_addsy)
5180 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5182 if (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
5183 value = 0;
5184 else
5185 value += md_pcrel_from (fixP);
5189 fixP->fx_addnumber = value; /* Remember value for emit_reloc */
5191 switch (fixP->fx_r_type)
5193 case BFD_RELOC_ARM_IMMEDIATE:
5194 newimm = validate_immediate (value);
5195 temp = md_chars_to_number (buf, INSN_SIZE);
5197 /* If the instruction will fail, see if we can fix things up by
5198 changing the opcode. */
5199 if (newimm == (unsigned int) FAIL
5200 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5202 as_bad_where (fixP->fx_file, fixP->fx_line,
5203 _("invalid constant (%x) after fixup\n"), value);
5204 break;
5207 newimm |= (temp & 0xfffff000);
5208 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5209 break;
5211 case BFD_RELOC_ARM_OFFSET_IMM:
5212 sign = value >= 0;
5213 if ((value = validate_offset_imm (value, 0)) == FAIL)
5215 as_bad (_("bad immediate value for offset (%d)"), val);
5216 break;
5218 if (value < 0)
5219 value = -value;
5221 newval = md_chars_to_number (buf, INSN_SIZE);
5222 newval &= 0xff7ff000;
5223 newval |= value | (sign ? INDEX_UP : 0);
5224 md_number_to_chars (buf, newval, INSN_SIZE);
5225 break;
5227 case BFD_RELOC_ARM_OFFSET_IMM8:
5228 case BFD_RELOC_ARM_HWLITERAL:
5229 sign = value >= 0;
5230 if ((value = validate_offset_imm (value, 1)) == FAIL)
5232 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5233 as_bad_where (fixP->fx_file, fixP->fx_line,
5234 _("invalid literal constant: pool needs to be closer\n"));
5235 else
5236 as_bad (_("bad immediate value for offset (%d)"), value);
5237 break;
5240 if (value < 0)
5241 value = -value;
5243 newval = md_chars_to_number (buf, INSN_SIZE);
5244 newval &= 0xff7ff0f0;
5245 newval |= ((value >> 4) << 8) | value & 0xf | (sign ? INDEX_UP : 0);
5246 md_number_to_chars (buf, newval, INSN_SIZE);
5247 break;
5249 case BFD_RELOC_ARM_LITERAL:
5250 sign = value >= 0;
5251 if (value < 0)
5252 value = -value;
5254 if ((value = validate_offset_imm (value, 0)) == FAIL)
5256 as_bad_where (fixP->fx_file, fixP->fx_line,
5257 _("invalid literal constant: pool needs to be closer\n"));
5258 break;
5261 newval = md_chars_to_number (buf, INSN_SIZE);
5262 newval &= 0xff7ff000;
5263 newval |= value | (sign ? INDEX_UP : 0);
5264 md_number_to_chars (buf, newval, INSN_SIZE);
5265 break;
5267 case BFD_RELOC_ARM_SHIFT_IMM:
5268 newval = md_chars_to_number (buf, INSN_SIZE);
5269 if (((unsigned long) value) > 32
5270 || (value == 32
5271 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5273 as_bad_where (fixP->fx_file, fixP->fx_line,
5274 _("shift expression is too large"));
5275 break;
5278 if (value == 0)
5279 newval &= ~0x60; /* Shifts of zero must be done as lsl */
5280 else if (value == 32)
5281 value = 0;
5282 newval &= 0xfffff07f;
5283 newval |= (value & 0x1f) << 7;
5284 md_number_to_chars (buf, newval , INSN_SIZE);
5285 break;
5287 case BFD_RELOC_ARM_SWI:
5288 if (arm_data->thumb_mode)
5290 if (((unsigned long) value) > 0xff)
5291 as_bad_where (fixP->fx_file, fixP->fx_line,
5292 _("Invalid swi expression"));
5293 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5294 newval |= value;
5295 md_number_to_chars (buf, newval, THUMB_SIZE);
5297 else
5299 if (((unsigned long) value) > 0x00ffffff)
5300 as_bad_where (fixP->fx_file, fixP->fx_line,
5301 _("Invalid swi expression"));
5302 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5303 newval |= value;
5304 md_number_to_chars (buf, newval , INSN_SIZE);
5306 break;
5308 case BFD_RELOC_ARM_MULTI:
5309 if (((unsigned long) value) > 0xffff)
5310 as_bad_where (fixP->fx_file, fixP->fx_line,
5311 _("Invalid expression in load/store multiple"));
5312 newval = value | md_chars_to_number (buf, INSN_SIZE);
5313 md_number_to_chars (buf, newval, INSN_SIZE);
5314 break;
5316 case BFD_RELOC_ARM_PCREL_BRANCH:
5317 newval = md_chars_to_number (buf, INSN_SIZE);
5318 #ifdef OBJ_ELF
5319 newval &= 0xff000000;
5320 if (! target_oabi)
5321 value = fixP->fx_offset;
5322 else
5323 #else
5324 value = (value >> 2) & 0x00ffffff;
5325 #endif
5326 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5327 newval = value | (newval & 0xff000000);
5328 md_number_to_chars (buf, newval, INSN_SIZE);
5329 break;
5331 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5332 newval = md_chars_to_number (buf, THUMB_SIZE);
5334 addressT diff = (newval & 0xff) << 1;
5335 if (diff & 0x100)
5336 diff |= ~0xff;
5338 value += diff;
5339 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5340 as_bad_where (fixP->fx_file, fixP->fx_line,
5341 _("Branch out of range"));
5342 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5344 md_number_to_chars (buf, newval, THUMB_SIZE);
5345 break;
5347 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5348 newval = md_chars_to_number (buf, THUMB_SIZE);
5350 addressT diff = (newval & 0x7ff) << 1;
5351 if (diff & 0x800)
5352 diff |= ~0x7ff;
5354 value += diff;
5355 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5356 as_bad_where (fixP->fx_file, fixP->fx_line,
5357 _("Branch out of range"));
5358 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5360 md_number_to_chars (buf, newval, THUMB_SIZE);
5361 break;
5363 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5365 offsetT newval2;
5366 addressT diff;
5368 newval = md_chars_to_number (buf, THUMB_SIZE);
5369 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5370 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5371 if (diff & 0x400000)
5372 diff |= ~0x3fffff;
5373 value += diff;
5374 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5375 as_bad_where (fixP->fx_file, fixP->fx_line,
5376 _("Branch with link out of range"));
5378 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5379 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5380 md_number_to_chars (buf, newval, THUMB_SIZE);
5381 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5383 break;
5385 case BFD_RELOC_8:
5386 if (fixP->fx_done || fixP->fx_pcrel)
5387 md_number_to_chars (buf, value, 1);
5388 #ifdef OBJ_ELF
5389 else if (!target_oabi)
5391 value = fixP->fx_offset;
5392 md_number_to_chars (buf, value, 1);
5394 #endif
5395 break;
5397 case BFD_RELOC_16:
5398 if (fixP->fx_done || fixP->fx_pcrel)
5399 md_number_to_chars (buf, value, 2);
5400 #ifdef OBJ_ELF
5401 else if (!target_oabi)
5403 value = fixP->fx_offset;
5404 md_number_to_chars (buf, value, 2);
5406 #endif
5407 break;
5409 #ifdef OBJ_ELF
5410 case BFD_RELOC_ARM_GOT32:
5411 case BFD_RELOC_ARM_GOTOFF:
5412 md_number_to_chars (buf, 0, 4);
5413 break;
5414 #endif
5416 case BFD_RELOC_RVA:
5417 case BFD_RELOC_32:
5418 if (fixP->fx_done || fixP->fx_pcrel)
5419 md_number_to_chars (buf, value, 4);
5420 #ifdef OBJ_ELF
5421 else if (!target_oabi)
5423 value = fixP->fx_offset;
5424 md_number_to_chars (buf, value, 4);
5426 #endif
5427 break;
5429 #ifdef OBJ_ELF
5430 case BFD_RELOC_ARM_PLT32:
5431 /* It appears the instruction is fully prepared at this point. */
5432 break;
5433 #endif
5435 case BFD_RELOC_ARM_GOTPC:
5436 md_number_to_chars (buf, value, 4);
5437 break;
5439 case BFD_RELOC_ARM_CP_OFF_IMM:
5440 sign = value >= 0;
5441 if (value < -1023 || value > 1023 || (value & 3))
5442 as_bad_where (fixP->fx_file, fixP->fx_line,
5443 _("Illegal value for co-processor offset"));
5444 if (value < 0)
5445 value = -value;
5446 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5447 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5448 md_number_to_chars (buf, newval , INSN_SIZE);
5449 break;
5451 case BFD_RELOC_ARM_THUMB_OFFSET:
5452 newval = md_chars_to_number (buf, THUMB_SIZE);
5453 /* Exactly what ranges, and where the offset is inserted depends on
5454 the type of instruction, we can establish this from the top 4 bits */
5455 switch (newval >> 12)
5457 case 4: /* PC load */
5458 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5459 forced to zero for these loads, so we will need to round
5460 up the offset if the instruction address is not word
5461 aligned (since the final address produced must be, and
5462 we can only describe word-aligned immediate offsets). */
5464 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5465 as_bad_where (fixP->fx_file, fixP->fx_line,
5466 _("Invalid offset, target not word aligned (0x%08X)"),
5467 (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5469 if ((value + 2) & ~0x3fe)
5470 as_bad_where (fixP->fx_file, fixP->fx_line,
5471 _("Invalid offset"));
5473 /* Round up, since pc will be rounded down. */
5474 newval |= (value + 2) >> 2;
5475 break;
5477 case 9: /* SP load/store */
5478 if (value & ~0x3fc)
5479 as_bad_where (fixP->fx_file, fixP->fx_line,
5480 _("Invalid offset"));
5481 newval |= value >> 2;
5482 break;
5484 case 6: /* Word load/store */
5485 if (value & ~0x7c)
5486 as_bad_where (fixP->fx_file, fixP->fx_line,
5487 _("Invalid offset"));
5488 newval |= value << 4; /* 6 - 2 */
5489 break;
5491 case 7: /* Byte load/store */
5492 if (value & ~0x1f)
5493 as_bad_where (fixP->fx_file, fixP->fx_line,
5494 _("Invalid offset"));
5495 newval |= value << 6;
5496 break;
5498 case 8: /* Halfword load/store */
5499 if (value & ~0x3e)
5500 as_bad_where (fixP->fx_file, fixP->fx_line,
5501 _("Invalid offset"));
5502 newval |= value << 5; /* 6 - 1 */
5503 break;
5505 default:
5506 as_bad_where (fixP->fx_file, fixP->fx_line,
5507 "Unable to process relocation for thumb opcode: %x", newval);
5508 break;
5510 md_number_to_chars (buf, newval, THUMB_SIZE);
5511 break;
5513 case BFD_RELOC_ARM_THUMB_ADD:
5514 /* This is a complicated relocation, since we use it for all of
5515 the following immediate relocations:
5516 3bit ADD/SUB
5517 8bit ADD/SUB
5518 9bit ADD/SUB SP word-aligned
5519 10bit ADD PC/SP word-aligned
5521 The type of instruction being processed is encoded in the
5522 instruction field:
5523 0x8000 SUB
5524 0x00F0 Rd
5525 0x000F Rs
5527 newval = md_chars_to_number (buf, THUMB_SIZE);
5529 int rd = (newval >> 4) & 0xf;
5530 int rs = newval & 0xf;
5531 int subtract = newval & 0x8000;
5533 if (rd == REG_SP)
5535 if (value & ~0x1fc)
5536 as_bad_where (fixP->fx_file, fixP->fx_line,
5537 _("Invalid immediate for stack address calculation"));
5538 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5539 newval |= value >> 2;
5541 else if (rs == REG_PC || rs == REG_SP)
5543 if (subtract ||
5544 value & ~0x3fc)
5545 as_bad_where (fixP->fx_file, fixP->fx_line,
5546 _("Invalid immediate for address calculation (value = 0x%08X)"), value);
5547 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5548 newval |= rd << 8;
5549 newval |= value >> 2;
5551 else if (rs == rd)
5553 if (value & ~0xff)
5554 as_bad_where (fixP->fx_file, fixP->fx_line,
5555 _("Invalid 8bit immediate"));
5556 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5557 newval |= (rd << 8) | value;
5559 else
5561 if (value & ~0x7)
5562 as_bad_where (fixP->fx_file, fixP->fx_line,
5563 _("Invalid 3bit immediate"));
5564 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5565 newval |= rd | (rs << 3) | (value << 6);
5568 md_number_to_chars (buf, newval , THUMB_SIZE);
5569 break;
5571 case BFD_RELOC_ARM_THUMB_IMM:
5572 newval = md_chars_to_number (buf, THUMB_SIZE);
5573 switch (newval >> 11)
5575 case 0x04: /* 8bit immediate MOV */
5576 case 0x05: /* 8bit immediate CMP */
5577 if (value < 0 || value > 255)
5578 as_bad_where (fixP->fx_file, fixP->fx_line,
5579 _("Invalid immediate: %d is too large"), value);
5580 newval |= value;
5581 break;
5583 default:
5584 abort ();
5586 md_number_to_chars (buf, newval , THUMB_SIZE);
5587 break;
5589 case BFD_RELOC_ARM_THUMB_SHIFT:
5590 /* 5bit shift value (0..31) */
5591 if (value < 0 || value > 31)
5592 as_bad_where (fixP->fx_file, fixP->fx_line,
5593 _("Illegal Thumb shift value: %d"), value);
5594 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5595 newval |= value << 6;
5596 md_number_to_chars (buf, newval , THUMB_SIZE);
5597 break;
5599 case BFD_RELOC_VTABLE_INHERIT:
5600 case BFD_RELOC_VTABLE_ENTRY:
5601 fixP->fx_done = 0;
5602 return 1;
5604 case BFD_RELOC_NONE:
5605 default:
5606 as_bad_where (fixP->fx_file, fixP->fx_line,
5607 _("Bad relocation fixup type (%d)\n"), fixP->fx_r_type);
5610 return 1;
5613 /* Translate internal representation of relocation info to BFD target
5614 format. */
5615 arelent *
5616 tc_gen_reloc (section, fixp)
5617 asection * section;
5618 fixS * fixp;
5620 arelent * reloc;
5621 bfd_reloc_code_real_type code;
5623 reloc = (arelent *) xmalloc (sizeof (arelent));
5625 reloc->sym_ptr_ptr = &fixp->fx_addsy->bsym;
5626 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5628 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5629 #ifndef OBJ_ELF
5630 if (fixp->fx_pcrel == 0)
5631 reloc->addend = fixp->fx_offset;
5632 else
5633 reloc->addend = fixp->fx_offset = reloc->address;
5634 #else /* OBJ_ELF */
5635 reloc->addend = fixp->fx_offset;
5636 #endif
5638 switch (fixp->fx_r_type)
5640 case BFD_RELOC_8:
5641 if (fixp->fx_pcrel)
5643 code = BFD_RELOC_8_PCREL;
5644 break;
5647 case BFD_RELOC_16:
5648 if (fixp->fx_pcrel)
5650 code = BFD_RELOC_16_PCREL;
5651 break;
5654 case BFD_RELOC_32:
5655 if (fixp->fx_pcrel)
5657 code = BFD_RELOC_32_PCREL;
5658 break;
5661 case BFD_RELOC_ARM_PCREL_BRANCH:
5662 case BFD_RELOC_RVA:
5663 case BFD_RELOC_THUMB_PCREL_BRANCH9:
5664 case BFD_RELOC_THUMB_PCREL_BRANCH12:
5665 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5666 case BFD_RELOC_VTABLE_ENTRY:
5667 case BFD_RELOC_VTABLE_INHERIT:
5668 code = fixp->fx_r_type;
5669 break;
5671 case BFD_RELOC_ARM_LITERAL:
5672 case BFD_RELOC_ARM_HWLITERAL:
5673 /* If this is called then the a literal has been referenced across
5674 a section boundry - possibly due to an implicit dump */
5675 as_bad_where (fixp->fx_file, fixp->fx_line,
5676 _("Literal referenced across section boundry (Implicit dump?)"));
5677 return NULL;
5679 case BFD_RELOC_ARM_GOTPC:
5680 assert (fixp->fx_pcrel != 0);
5681 code = fixp->fx_r_type;
5682 code = BFD_RELOC_32_PCREL;
5683 break;
5685 #ifdef OBJ_ELF
5686 case BFD_RELOC_ARM_GOT32:
5687 case BFD_RELOC_ARM_GOTOFF:
5688 case BFD_RELOC_ARM_PLT32:
5689 code = fixp->fx_r_type;
5690 break;
5691 #endif
5693 case BFD_RELOC_ARM_IMMEDIATE:
5694 as_bad_where (fixp->fx_file, fixp->fx_line,
5695 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5696 fixp->fx_r_type);
5697 return NULL;
5699 case BFD_RELOC_ARM_OFFSET_IMM:
5700 as_bad_where (fixp->fx_file, fixp->fx_line,
5701 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5702 fixp->fx_r_type);
5703 return NULL;
5705 default:
5707 char * type;
5708 switch (fixp->fx_r_type)
5710 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
5711 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
5712 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
5713 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
5714 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
5715 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
5716 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
5717 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
5718 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
5719 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
5720 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
5721 default: type = "<unknown>"; break;
5723 as_bad_where (fixp->fx_file, fixp->fx_line,
5724 _("Can not represent %s relocation in this object file format (%d)"),
5725 type, fixp->fx_pcrel);
5726 return NULL;
5730 #ifdef OBJ_ELF
5731 if (code == BFD_RELOC_32_PCREL
5732 && GOT_symbol
5733 && fixp->fx_addsy == GOT_symbol)
5734 code = BFD_RELOC_ARM_GOTPC;
5735 #endif
5737 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5739 if (reloc->howto == NULL)
5741 as_bad_where (fixp->fx_file, fixp->fx_line,
5742 _("Can not represent %s relocation in this object file format"),
5743 bfd_get_reloc_code_name (code));
5744 return NULL;
5747 return reloc;
5751 md_estimate_size_before_relax (fragP, segtype)
5752 fragS * fragP;
5753 segT segtype;
5755 as_fatal (_("md_estimate_size_before_relax\n"));
5756 return 1;
5759 static void
5760 output_inst (str)
5761 char * str;
5763 char * to = NULL;
5765 if (inst.error)
5767 as_bad (inst.error);
5768 return;
5771 to = frag_more (inst.size);
5772 if (thumb_mode && (inst.size > THUMB_SIZE))
5774 assert (inst.size == (2 * THUMB_SIZE));
5775 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
5776 md_number_to_chars (to + 2, inst.instruction, THUMB_SIZE);
5778 else
5779 md_number_to_chars (to, inst.instruction, inst.size);
5781 if (inst.reloc.type != BFD_RELOC_NONE)
5782 fix_new_arm (frag_now, to - frag_now->fr_literal,
5783 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
5784 inst.reloc.type);
5786 return;
5789 void
5790 md_assemble (str)
5791 char * str;
5793 char c;
5794 char * p;
5795 char * q;
5796 char * start;
5798 /* Align the instruction.
5799 This may not be the right thing to do but ... */
5800 /* arm_align (2, 0); */
5801 listing_prev_line (); /* Defined in listing.h */
5803 /* Align the previous label if needed. */
5804 if (last_label_seen != NULL)
5806 last_label_seen->sy_frag = frag_now;
5807 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
5808 S_SET_SEGMENT (last_label_seen, now_seg);
5811 memset (&inst, '\0', sizeof (inst));
5812 inst.reloc.type = BFD_RELOC_NONE;
5814 if (*str == ' ')
5815 str++; /* Skip leading white space */
5817 /* Scan up to the end of the op-code, which must end in white space or
5818 end of string. */
5819 for (start = p = str; *p != '\0'; p++)
5820 if (*p == ' ')
5821 break;
5823 if (p == str)
5825 as_bad (_("No operator -- statement `%s'\n"), str);
5826 return;
5829 if (thumb_mode)
5831 CONST struct thumb_opcode *opcode;
5833 c = *p;
5834 *p = '\0';
5835 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
5836 *p = c;
5837 if (opcode)
5839 inst.instruction = opcode->value;
5840 inst.size = opcode->size;
5841 (*opcode->parms)(p);
5842 output_inst (start);
5843 return;
5846 else
5848 CONST struct asm_opcode *opcode;
5850 inst.size = INSN_SIZE;
5851 /* p now points to the end of the opcode, probably white space, but we
5852 have to break the opcode up in case it contains condionals and flags;
5853 keep trying with progressively smaller basic instructions until one
5854 matches, or we run out of opcode. */
5855 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
5856 for (; q != str; q--)
5858 c = *q;
5859 *q = '\0';
5860 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
5861 *q = c;
5862 if (opcode && opcode->template)
5864 unsigned long flag_bits = 0;
5865 char *r;
5867 /* Check that this instruction is supported for this CPU */
5868 if ((opcode->variants & cpu_variant) == 0)
5869 goto try_shorter;
5871 inst.instruction = opcode->value;
5872 if (q == p) /* Just a simple opcode */
5874 if (opcode->comp_suffix != 0)
5875 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
5876 opcode->comp_suffix);
5877 else
5879 inst.instruction |= COND_ALWAYS;
5880 (*opcode->parms)(q, 0);
5882 output_inst (start);
5883 return;
5886 /* Now check for a conditional */
5887 r = q;
5888 if (p - r >= 2)
5890 CONST struct asm_cond *cond;
5891 char d = *(r + 2);
5893 *(r + 2) = '\0';
5894 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
5895 *(r + 2) = d;
5896 if (cond)
5898 if (cond->value == 0xf0000000)
5899 as_tsktsk (
5900 _("Warning: Use of the 'nv' conditional is deprecated\n"));
5902 inst.instruction |= cond->value;
5903 r += 2;
5905 else
5906 inst.instruction |= COND_ALWAYS;
5908 else
5909 inst.instruction |= COND_ALWAYS;
5911 /* if there is a compulsory suffix, it should come here, before
5912 any optional flags. */
5913 if (opcode->comp_suffix)
5915 CONST char *s = opcode->comp_suffix;
5917 while (*s)
5919 inst.suffix++;
5920 if (*r == *s)
5921 break;
5922 s++;
5925 if (*s == '\0')
5927 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
5928 opcode->comp_suffix);
5929 return;
5932 r++;
5935 /* The remainder, if any should now be flags for the instruction;
5936 Scan these checking each one found with the opcode. */
5937 if (r != p)
5939 char d;
5940 CONST struct asm_flg *flag = opcode->flags;
5942 if (flag)
5944 int flagno;
5946 d = *p;
5947 *p = '\0';
5949 for (flagno = 0; flag[flagno].template; flagno++)
5951 if (streq (r, flag[flagno].template))
5953 flag_bits |= flag[flagno].set_bits;
5954 break;
5958 *p = d;
5959 if (! flag[flagno].template)
5960 goto try_shorter;
5962 else
5963 goto try_shorter;
5966 (*opcode->parms) (p, flag_bits);
5967 output_inst (start);
5968 return;
5971 try_shorter:
5976 /* It wasn't an instruction, but it might be a register alias of the form
5977 alias .req reg
5979 q = p;
5980 while (*q == ' ')
5981 q++;
5983 c = *p;
5984 *p = '\0';
5986 if (*q && !strncmp (q, ".req ", 4))
5988 int reg;
5989 char * copy_of_str = str;
5990 char * r;
5992 q += 4;
5993 while (*q == ' ')
5994 q++;
5996 for (r = q; *r != '\0'; r++)
5997 if (*r == ' ')
5998 break;
6000 if (r != q)
6002 int regnum;
6003 char d = *r;
6005 *r = '\0';
6006 regnum = arm_reg_parse (& q);
6007 *r = d;
6009 reg = arm_reg_parse (& str);
6011 if (reg == FAIL)
6013 if (regnum != FAIL)
6015 insert_reg_alias (str, regnum);
6017 else
6019 as_warn (_("register '%s' does not exist\n"), q);
6022 else if (regnum != FAIL)
6024 if (reg != regnum)
6025 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str );
6027 /* Do not warn abpout redefinitions to the same alias. */
6029 else
6030 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6031 copy_of_str, q);
6033 else
6034 as_warn (_("ignoring incomplete .req pseuso op"));
6036 *p = c;
6037 return;
6040 *p = c;
6041 as_bad (_("bad instruction `%s'"), start);
6045 * md_parse_option
6046 * Invocation line includes a switch not recognized by the base assembler.
6047 * See if it's a processor-specific option. These are:
6048 * Cpu variants, the arm part is optional:
6049 * -m[arm]1 Currently not supported.
6050 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6051 * -m[arm]3 Arm 3 processor
6052 * -m[arm]6[xx], Arm 6 processors
6053 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6054 * -mstrongarm[110] Arm 8 processors
6055 * -mall All (except the ARM1)
6056 * FP variants:
6057 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6058 * -mfpe-old (No float load/store multiples)
6059 * -mno-fpu Disable all floating point instructions
6060 * Run-time endian selection:
6061 * -EB big endian cpu
6062 * -EL little endian cpu
6063 * ARM Procedure Calling Standard:
6064 * -mapcs-32 32 bit APCS
6065 * -mapcs-26 26 bit APCS
6066 * -mapcs-float Pass floats in float regs
6067 * -mapcs-reentrant Position independent code
6068 * -mthumb-interwork Code supports Arm/Thumb interworking
6069 * -moabi Old ELF ABI
6072 CONST char * md_shortopts = "m:k";
6073 struct option md_longopts[] =
6075 #ifdef ARM_BI_ENDIAN
6076 #define OPTION_EB (OPTION_MD_BASE + 0)
6077 {"EB", no_argument, NULL, OPTION_EB},
6078 #define OPTION_EL (OPTION_MD_BASE + 1)
6079 {"EL", no_argument, NULL, OPTION_EL},
6080 #ifdef OBJ_ELF
6081 #define OPTION_OABI (OPTION_MD_BASE +2)
6082 {"oabi", no_argument, NULL, OPTION_OABI},
6083 #endif
6084 #endif
6085 {NULL, no_argument, NULL, 0}
6087 size_t md_longopts_size = sizeof (md_longopts);
6090 md_parse_option (c, arg)
6091 int c;
6092 char * arg;
6094 char * str = arg;
6096 switch (c)
6098 #ifdef ARM_BI_ENDIAN
6099 case OPTION_EB:
6100 target_big_endian = 1;
6101 break;
6102 case OPTION_EL:
6103 target_big_endian = 0;
6104 break;
6105 #endif
6107 case 'm':
6108 switch (*str)
6110 case 'f':
6111 if (streq (str, "fpa10"))
6112 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
6113 else if (streq (str, "fpa11"))
6114 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
6115 else if (streq (str, "fpe-old"))
6116 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
6117 else
6118 goto bad;
6119 break;
6121 case 'n':
6122 if (streq (str, "no-fpu"))
6123 cpu_variant &= ~FPU_ALL;
6124 break;
6126 #ifdef OBJ_ELF
6127 case 'o':
6128 if (streq (str, "oabi"))
6129 target_oabi = true;
6130 break;
6131 #endif
6133 case 't':
6134 /* Limit assembler to generating only Thumb instructions: */
6135 if (streq (str, "thumb"))
6137 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
6138 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6139 thumb_mode = 1;
6141 else if (streq (str, "thumb-interwork"))
6143 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCHv4;
6144 #if defined OBJ_COFF || defined OBJ_ELF
6145 support_interwork = true;
6146 #endif
6148 else
6149 goto bad;
6150 break;
6152 default:
6153 if (streq (str, "all"))
6155 cpu_variant = ARM_ALL | FPU_ALL;
6156 return 1;
6158 #if defined OBJ_COFF || defined OBJ_ELF
6159 if (! strncmp (str, "apcs-", 5))
6161 /* GCC passes on all command line options starting "-mapcs-..."
6162 to us, so we must parse them here. */
6164 str += 5;
6166 if (streq (str, "32"))
6168 uses_apcs_26 = false;
6169 return 1;
6171 else if (streq (str, "26"))
6173 uses_apcs_26 = true;
6174 return 1;
6176 else if (streq (str, "frame"))
6178 /* Stack frames are being generated - does not affect
6179 linkage of code. */
6180 return 1;
6182 else if (streq (str, "stack-check"))
6184 /* Stack checking is being performed - does not affect
6185 linkage, but does require that the functions
6186 __rt_stkovf_split_small and __rt_stkovf_split_big be
6187 present in the final link. */
6189 return 1;
6191 else if (streq (str, "float"))
6193 /* Floating point arguments are being passed in the floating
6194 point registers. This does affect linking, since this
6195 version of the APCS is incompatible with the version that
6196 passes floating points in the integer registers. */
6198 uses_apcs_float = true;
6199 return 1;
6201 else if (streq (str, "reentrant"))
6203 /* Reentrant code has been generated. This does affect
6204 linking, since there is no point in linking reentrant/
6205 position independent code with absolute position code. */
6206 pic_code = true;
6207 return 1;
6210 as_bad (_("Unrecognised APCS switch -m%s"), arg);
6211 return 0;
6213 #endif
6214 /* Strip off optional "arm" */
6215 if (! strncmp (str, "arm", 3))
6216 str += 3;
6218 switch (*str)
6220 case '1':
6221 if (streq (str, "1"))
6222 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6223 else
6224 goto bad;
6225 break;
6227 case '2':
6228 if (streq (str, "2"))
6229 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6230 else if (streq (str, "250"))
6231 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6232 else
6233 goto bad;
6234 break;
6236 case '3':
6237 if (streq (str, "3"))
6238 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6239 else
6240 goto bad;
6241 break;
6243 case '6':
6244 switch (strtol (str, NULL, 10))
6246 case 6:
6247 case 60:
6248 case 600:
6249 case 610:
6250 case 620:
6251 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6252 break;
6253 default:
6254 goto bad;
6256 break;
6258 case '7':
6259 switch (strtol (str, & str, 10)) /* Eat the processor name */
6261 case 7:
6262 case 70:
6263 case 700:
6264 case 710:
6265 case 7100:
6266 case 7500:
6267 break;
6268 default:
6269 goto bad;
6271 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6272 for (; *str; str++)
6274 switch (* str)
6276 case 't':
6277 cpu_variant |= (ARM_THUMB | ARM_ARCHv4);
6278 break;
6280 case 'm':
6281 cpu_variant |= ARM_LONGMUL;
6282 break;
6284 case 'f': /* fe => fp enabled cpu. */
6285 if (str[1] == 'e')
6286 ++ str;
6287 else
6288 goto bad;
6290 case 'c': /* Left over from 710c processor name. */
6291 case 'd': /* Debug */
6292 case 'i': /* Embedded ICE */
6293 /* Included for completeness in ARM processor naming. */
6294 break;
6296 default:
6297 goto bad;
6300 break;
6302 case '8':
6303 if (streq (str, "8") || streq (str, "810"))
6304 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCHv4 | ARM_LONGMUL;
6305 else
6306 goto bad;
6307 break;
6309 case '9':
6310 if (streq (str, "9"))
6311 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL;
6312 else if (streq (str, "9tdmi"))
6313 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCHv4 | ARM_LONGMUL | ARM_THUMB;
6314 else
6315 goto bad;
6316 break;
6318 case 's':
6319 if (streq (str, "strongarm")
6320 || streq (str, "strongarm110")
6321 || streq (str, "strongarm1100"))
6322 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCHv4 | ARM_LONGMUL;
6323 else
6324 goto bad;
6325 break;
6327 case 'v':
6328 /* Select variant based on architecture rather than processor */
6329 switch (*++str)
6331 case '2':
6332 switch (*++str)
6334 case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
6335 case 0: cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
6336 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6338 break;
6340 case '3':
6341 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6343 switch (*++str)
6345 case 'm': cpu_variant |= ARM_LONGMUL; break;
6346 case 0: break;
6347 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6349 break;
6351 case '4':
6352 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCHv4;
6354 switch (*++str)
6356 case 't': cpu_variant |= ARM_THUMB; break;
6357 case 0: break;
6358 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6360 break;
6362 default:
6363 as_bad (_("Invalid architecture variant -m%s"), arg);
6364 break;
6366 break;
6368 default:
6369 bad:
6370 as_bad (_("Invalid processor variant -m%s"), arg);
6371 return 0;
6374 break;
6376 case 'k':
6377 pic_code = 1;
6378 break;
6380 default:
6381 return 0;
6384 return 1;
6387 void
6388 md_show_usage (fp)
6389 FILE * fp;
6391 fprintf (fp,
6392 _("\
6393 ARM Specific Assembler Options:\n\
6394 -m[arm][<processor name>] select processor variant\n\
6395 -m[arm]v[2|2a|3|3m|4|4t] select architecture variant\n\
6396 -mthumb only allow Thumb instructions\n\
6397 -mthumb-interwork mark the assembled code as supporting interworking\n\
6398 -mall allow any instruction\n\
6399 -mfpa10, -mfpa11 select floating point architecture\n\
6400 -mfpe-old don't allow floating-point multiple instructions\n\
6401 -mno-fpu don't allow any floating-point instructions.\n"));
6402 fprintf (fp,
6403 _("\
6404 -k generate PIC code.\n"));
6405 #if defined OBJ_COFF || defined OBJ_ELF
6406 fprintf (fp,
6407 _("\
6408 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6409 fprintf (fp,
6410 _("\
6411 -mapcs-float floating point args are passed in FP regs\n"));
6412 fprintf (fp,
6413 _("\
6414 -mapcs-reentrant the code is position independent/reentrant\n"));
6415 #endif
6416 #ifdef OBJ_ELF
6417 fprintf (fp,
6418 _("\
6419 -moabi support the old ELF ABI\n"));
6420 #endif
6421 #ifdef ARM_BI_ENDIAN
6422 fprintf (fp,
6423 _("\
6424 -EB assemble code for a big endian cpu\n\
6425 -EL assemble code for a little endian cpu\n"));
6426 #endif
6429 /* We need to be able to fix up arbitrary expressions in some statements.
6430 This is so that we can handle symbols that are an arbitrary distance from
6431 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6432 which returns part of an address in a form which will be valid for
6433 a data instruction. We do this by pushing the expression into a symbol
6434 in the expr_section, and creating a fix for that. */
6436 static void
6437 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6438 fragS * frag;
6439 int where;
6440 short int size;
6441 expressionS * exp;
6442 int pc_rel;
6443 int reloc;
6445 fixS * new_fix;
6446 arm_fix_data * arm_data;
6448 switch (exp->X_op)
6450 case O_constant:
6451 case O_symbol:
6452 case O_add:
6453 case O_subtract:
6454 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6455 break;
6457 default:
6458 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6459 pc_rel, reloc);
6460 break;
6463 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6464 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
6465 new_fix->tc_fix_data = (PTR) arm_data;
6466 arm_data->thumb_mode = thumb_mode;
6468 return;
6473 * This fix_new is called by cons via TC_CONS_FIX_NEW
6475 * We check the expression to see if it is of the form
6476 * __GLOBAL_OFFSET_TABLE + ???
6477 * If it is then this is a PC relative reference to the GOT.
6478 * i.e.
6479 * ldr sl, L1
6480 * add sl, pc, sl
6481 * L2:
6482 * ...
6483 * L1:
6484 * .word __GLOBAL_OFFSET_TABLE + (. - (L2 + 4))
6486 * In this case use a reloc type BFD_RELOC_ARM_GOTPC instead of the
6487 * normal BFD_RELOC_{16,32,64}
6490 void
6491 cons_fix_new_arm (frag, where, size, exp)
6492 fragS * frag;
6493 int where;
6494 int size;
6495 expressionS * exp;
6497 bfd_reloc_code_real_type type;
6498 int pcrel = 0;
6500 /* Pick a reloc ...
6502 * @@ Should look at CPU word size.
6504 switch (size)
6506 case 2:
6507 type = BFD_RELOC_16;
6508 break;
6509 case 4:
6510 default:
6511 type = BFD_RELOC_32;
6512 break;
6513 case 8:
6514 type = BFD_RELOC_64;
6515 break;
6518 /* Look for possible GOTPC reloc */
6521 * Look for pic assembler and 'undef symbol + expr symbol' expression
6522 * and a 32 bit size.
6525 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
6528 /* A good place to do this, although this was probably not intended
6529 * for this kind of use. We need to dump the literal pool before
6530 * references are made to a null symbol pointer. */
6531 void
6532 arm_cleanup ()
6534 if (current_poolP != NULL)
6536 subseg_set (text_section, 0); /* Put it at the end of text section */
6537 s_ltorg (0);
6538 listing_prev_line ();
6542 void
6543 arm_start_line_hook ()
6545 last_label_seen = NULL;
6548 void
6549 arm_frob_label (sym)
6550 symbolS * sym;
6552 last_label_seen = sym;
6554 ARM_SET_THUMB (sym, thumb_mode);
6556 #if defined OBJ_COFF || defined OBJ_ELF
6557 ARM_SET_INTERWORK (sym, support_interwork);
6558 #endif
6560 if (label_is_thumb_function_name)
6562 /* When the address of a Thumb function is taken the bottom
6563 bit of that address should be set. This will allow
6564 interworking between Arm and Thumb functions to work
6565 correctly. */
6567 THUMB_SET_FUNC (sym, 1);
6569 label_is_thumb_function_name = false;
6573 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6574 ARM ones. */
6576 void
6577 arm_adjust_symtab ()
6579 #ifdef OBJ_COFF
6580 symbolS * sym;
6582 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6584 if (ARM_IS_THUMB (sym))
6586 if (THUMB_IS_FUNC (sym))
6588 /* Mark the symbol as a Thumb function. */
6589 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
6590 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6591 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6593 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6594 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6595 else
6596 as_bad (_("%s: unexpected function type: %d"),
6597 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6599 else switch (S_GET_STORAGE_CLASS (sym))
6601 case C_EXT:
6602 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6603 break;
6604 case C_STAT:
6605 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6606 break;
6607 case C_LABEL:
6608 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6609 break;
6610 default: /* do nothing */
6611 break;
6615 if (ARM_IS_INTERWORK (sym))
6616 coffsymbol(sym->bsym)->native->u.syment.n_flags = 0xFF;
6618 #endif
6619 #ifdef OBJ_ELF
6620 symbolS * sym;
6621 elf_symbol_type * elf_sym;
6622 char bind;
6624 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6626 if (ARM_IS_THUMB (sym))
6628 if (THUMB_IS_FUNC (sym))
6630 elf_sym = elf_symbol (sym->bsym);
6631 bind = ELF_ST_BIND (elf_sym);
6632 elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC);
6636 #endif
6640 arm_data_in_code ()
6642 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
6644 *input_line_pointer = '/';
6645 input_line_pointer += 5;
6646 *input_line_pointer = 0;
6647 return 1;
6650 return 0;
6653 char *
6654 arm_canonicalize_symbol_name (name)
6655 char * name;
6657 int len;
6659 if (thumb_mode && (len = strlen (name)) > 5
6660 && streq (name + len - 5, "/data"))
6662 *(name + len - 5) = 0;
6665 return name;
6668 boolean
6669 arm_validate_fix (fixP)
6670 fixS * fixP;
6672 /* If the destination of the branch is a defined symbol which does not have
6673 the THUMB_FUNC attribute, then we must be calling a function which has
6674 the (interfacearm) attribute. We look for the Thumb entry point to that
6675 function and change the branch to refer to that function instead. */
6676 if ( fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
6677 && fixP->fx_addsy != NULL
6678 && S_IS_DEFINED (fixP->fx_addsy)
6679 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6681 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6682 return true;
6685 return false;
6688 #ifdef OBJ_ELF
6689 /* Relocations against Thumb function names must be left unadjusted,
6690 so that the linker can use this information to correctly set the
6691 bottom bit of their addresses. The MIPS version of this function
6692 also prevents relocations that are mips-16 specific, but I do not
6693 know why it does this.
6695 FIXME:
6696 There is one other problem that ought to be addressed here, but
6697 which currently is not: Taking the address of a label (rather
6698 than a function) and then later jumping to that address. Such
6699 addresses also ought to have their bottom bit set (assuming that
6700 they reside in Thumb code), but at the moment they will not. */
6702 boolean
6703 arm_fix_adjustable (fixP)
6704 fixS * fixP;
6707 if (fixP->fx_addsy == NULL)
6708 return 1;
6710 /* Prevent all adjustments to global symbols. */
6711 if (S_IS_EXTERN (fixP->fx_addsy))
6712 return 0;
6714 if (S_IS_WEAK (fixP->fx_addsy))
6715 return 0;
6717 if (THUMB_IS_FUNC (fixP->fx_addsy)
6718 && fixP->fx_subsy == NULL)
6719 return 0;
6721 /* We need the symbol name for the VTABLE entries */
6722 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6723 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6724 return 0;
6726 return 1;
6729 const char *
6730 elf32_arm_target_format ()
6732 if (target_big_endian)
6733 if (target_oabi)
6734 return "elf32-bigarm-oabi";
6735 else
6736 return "elf32-bigarm";
6737 else
6738 if (target_oabi)
6739 return "elf32-littlearm-oabi";
6740 else
6741 return "elf32-littlearm";
6744 void
6745 armelf_frob_symbol (symp, puntp)
6746 symbolS * symp;
6747 int * puntp;
6749 elf_frob_symbol (symp, puntp);
6753 arm_force_relocation (fixp)
6754 struct fix * fixp;
6756 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6757 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
6758 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
6759 return 1;
6761 return 0;
6764 static bfd_reloc_code_real_type
6765 arm_parse_reloc ()
6767 char id[16];
6768 char * ip;
6769 int i;
6770 static struct
6772 char * str;
6773 int len;
6774 bfd_reloc_code_real_type reloc;
6776 reloc_map[] =
6778 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
6779 MAP ("(got)", BFD_RELOC_ARM_GOT32),
6780 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
6781 /* ScottB: Jan 30, 1998 */
6782 /* Added support for parsing "var(PLT)" branch instructions */
6783 /* generated by GCC for PLT relocs */
6784 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
6785 NULL, 0, BFD_RELOC_UNUSED
6786 #undef MAP
6789 for (i = 0, ip = input_line_pointer;
6790 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
6791 i++, ip++)
6792 id[i] = tolower (*ip);
6794 for (i = 0; reloc_map[i].str; i++)
6795 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
6796 break;
6798 input_line_pointer += reloc_map[i].len;
6800 return reloc_map[i].reloc;
6803 static void
6804 s_arm_elf_cons (nbytes)
6805 int nbytes;
6807 expressionS exp;
6809 #ifdef md_flush_pending_output
6810 md_flush_pending_output ();
6811 #endif
6813 if (is_it_end_of_statement ())
6815 demand_empty_rest_of_line ();
6816 return;
6819 #ifdef md_cons_align
6820 md_cons_align (nbytes);
6821 #endif
6825 bfd_reloc_code_real_type reloc;
6827 expression (& exp);
6829 if (exp.X_op == O_symbol
6830 && * input_line_pointer == '('
6831 && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
6833 reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
6834 int size = bfd_get_reloc_size (howto);
6836 if (size > nbytes)
6837 as_bad ("%s relocations do not fit in %d bytes", howto->name, nbytes);
6838 else
6840 register char * p = frag_more ((int) nbytes);
6841 int offset = nbytes - size;
6843 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
6844 & exp, 0, reloc);
6847 else
6848 emit_expr (& exp, (unsigned int) nbytes);
6850 while (*input_line_pointer++ == ',');
6852 input_line_pointer--; /* Put terminator back into stream. */
6853 demand_empty_rest_of_line ();
6856 #endif /* OBJ_ELF */