file bfdt.texi was initially added on branch binutils-2_10-branch.
[binutils.git] / gas / config / tc-arm.c
blob4c71976c877e1eb0034b94e7bb4fa7483ace18ae
1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000 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 */
54 #define ARM_EXT_V5 0x00000080 /* allow CLZ etc */
56 /* Architectures are the sum of the base and extensions. */
57 #define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
58 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
59 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
60 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
62 /* Some useful combinations: */
63 #define ARM_ANY 0x00ffffff
64 #define ARM_2UP (ARM_ANY - ARM_1)
65 #define ARM_ALL ARM_2UP /* Not arm1 only */
66 #define ARM_3UP 0x00fffffc
67 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
69 #define FPU_CORE 0x80000000
70 #define FPU_FPA10 0x40000000
71 #define FPU_FPA11 0x40000000
72 #define FPU_NONE 0
74 /* Some useful combinations */
75 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
76 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
79 #ifndef CPU_DEFAULT
80 #if defined __thumb__
81 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
82 #else
83 #define CPU_DEFAULT ARM_ALL
84 #endif
85 #endif
87 #ifndef FPU_DEFAULT
88 #define FPU_DEFAULT FPU_ALL
89 #endif
91 #define streq(a, b) (strcmp (a, b) == 0)
92 #define skip_whitespace(str) while (* (str) == ' ') ++ (str)
94 static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
95 static int target_oabi = 0;
97 #if defined OBJ_COFF || defined OBJ_ELF
98 /* Flags stored in private area of BFD structure */
99 static boolean uses_apcs_26 = false;
100 static boolean support_interwork = false;
101 static boolean uses_apcs_float = false;
102 static boolean pic_code = false;
103 #endif
105 /* This array holds the chars that always start a comment. If the
106 pre-processor is disabled, these aren't very useful. */
107 CONST char comment_chars[] = "@";
109 /* This array holds the chars that only start a comment at the beginning of
110 a line. If the line seems to have the form '# 123 filename'
111 .line and .file directives will appear in the pre-processed output. */
112 /* Note that input_file.c hand checks for '#' at the beginning of the
113 first line of the input file. This is because the compiler outputs
114 #NO_APP at the beginning of its output. */
115 /* Also note that comments like this one will always work. */
116 CONST char line_comment_chars[] = "#";
118 #ifdef TE_LINUX
119 CONST char line_separator_chars[] = ";";
120 #else
121 CONST char line_separator_chars[] = "";
122 #endif
124 /* Chars that can be used to separate mant
125 from exp in floating point numbers. */
126 CONST char EXP_CHARS[] = "eE";
128 /* Chars that mean this number is a floating point constant */
129 /* As in 0f12.456 */
130 /* or 0d1.2345e12 */
132 CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
134 /* Prefix characters that indicate the start of an immediate
135 value. */
136 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
138 #ifdef OBJ_ELF
139 symbolS * GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
140 #endif
142 CONST int md_reloc_size = 8; /* Size of relocation record */
144 static int thumb_mode = 0; /* 0: assemble for ARM, 1: assemble for Thumb,
145 2: assemble for Thumb even though target cpu
146 does not support thumb instructions. */
147 typedef struct arm_fix
149 int thumb_mode;
150 } arm_fix_data;
152 struct arm_it
154 CONST char * error;
155 unsigned long instruction;
156 int suffix;
157 int size;
158 struct
160 bfd_reloc_code_real_type type;
161 expressionS exp;
162 int pc_rel;
163 } reloc;
166 struct arm_it inst;
168 struct asm_shift
170 CONST char * template;
171 unsigned long value;
174 static CONST struct asm_shift shift[] =
176 {"asl", 0},
177 {"lsl", 0},
178 {"lsr", 0x00000020},
179 {"asr", 0x00000040},
180 {"ror", 0x00000060},
181 {"rrx", 0x00000060},
182 {"ASL", 0},
183 {"LSL", 0},
184 {"LSR", 0x00000020},
185 {"ASR", 0x00000040},
186 {"ROR", 0x00000060},
187 {"RRX", 0x00000060}
190 #define NO_SHIFT_RESTRICT 1
191 #define SHIFT_RESTRICT 0
193 #define NUM_FLOAT_VALS 8
195 CONST char * fp_const[] =
197 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
200 /* Number of littlenums required to hold an extended precision number. */
201 #define MAX_LITTLENUMS 6
203 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
205 #define FAIL (-1)
206 #define SUCCESS (0)
208 #define SUFF_S 1
209 #define SUFF_D 2
210 #define SUFF_E 3
211 #define SUFF_P 4
213 #define CP_T_X 0x00008000
214 #define CP_T_Y 0x00400000
215 #define CP_T_Pre 0x01000000
216 #define CP_T_UD 0x00800000
217 #define CP_T_WB 0x00200000
219 #define CONDS_BIT (0x00100000)
220 #define LOAD_BIT (0x00100000)
221 #define TRANS_BIT (0x00200000)
223 struct asm_cond
225 CONST char * template;
226 unsigned long value;
229 /* This is to save a hash look-up in the common case. */
230 #define COND_ALWAYS 0xe0000000
232 static CONST struct asm_cond conds[] =
234 {"eq", 0x00000000},
235 {"ne", 0x10000000},
236 {"cs", 0x20000000}, {"hs", 0x20000000},
237 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
238 {"mi", 0x40000000},
239 {"pl", 0x50000000},
240 {"vs", 0x60000000},
241 {"vc", 0x70000000},
242 {"hi", 0x80000000},
243 {"ls", 0x90000000},
244 {"ge", 0xa0000000},
245 {"lt", 0xb0000000},
246 {"gt", 0xc0000000},
247 {"le", 0xd0000000},
248 {"al", 0xe0000000},
249 {"nv", 0xf0000000}
252 /* Warning: If the top bit of the set_bits is set, then the standard
253 instruction bitmask is ignored, and the new bitmask is taken from
254 the set_bits: */
255 struct asm_flg
257 CONST char * template; /* Basic flag string */
258 unsigned long set_bits; /* Bits to set */
261 static CONST struct asm_flg s_flag[] =
263 {"s", CONDS_BIT},
264 {NULL, 0}
267 static CONST struct asm_flg ldr_flags[] =
269 {"b", 0x00400000},
270 {"t", TRANS_BIT},
271 {"bt", 0x00400000 | TRANS_BIT},
272 {"h", 0x801000b0},
273 {"sh", 0x801000f0},
274 {"sb", 0x801000d0},
275 {NULL, 0}
278 static CONST struct asm_flg str_flags[] =
280 {"b", 0x00400000},
281 {"t", TRANS_BIT},
282 {"bt", 0x00400000 | TRANS_BIT},
283 {"h", 0x800000b0},
284 {NULL, 0}
287 static CONST struct asm_flg byte_flag[] =
289 {"b", 0x00400000},
290 {NULL, 0}
293 static CONST struct asm_flg cmp_flags[] =
295 {"s", CONDS_BIT},
296 {"p", 0x0010f000},
297 {NULL, 0}
300 static CONST struct asm_flg ldm_flags[] =
302 {"ed", 0x01800000},
303 {"fd", 0x00800000},
304 {"ea", 0x01000000},
305 {"fa", 0x08000000},
306 {"ib", 0x01800000},
307 {"ia", 0x00800000},
308 {"db", 0x01000000},
309 {"da", 0x08000000},
310 {NULL, 0}
313 static CONST struct asm_flg stm_flags[] =
315 {"ed", 0x08000000},
316 {"fd", 0x01000000},
317 {"ea", 0x00800000},
318 {"fa", 0x01800000},
319 {"ib", 0x01800000},
320 {"ia", 0x00800000},
321 {"db", 0x01000000},
322 {"da", 0x08000000},
323 {NULL, 0}
326 static CONST struct asm_flg lfm_flags[] =
328 {"fd", 0x00800000},
329 {"ea", 0x01000000},
330 {NULL, 0}
333 static CONST struct asm_flg sfm_flags[] =
335 {"fd", 0x01000000},
336 {"ea", 0x00800000},
337 {NULL, 0}
340 static CONST struct asm_flg round_flags[] =
342 {"p", 0x00000020},
343 {"m", 0x00000040},
344 {"z", 0x00000060},
345 {NULL, 0}
348 /* The implementation of the FIX instruction is broken on some assemblers,
349 in that it accepts a precision specifier as well as a rounding specifier,
350 despite the fact that this is meaningless. To be more compatible, we
351 accept it as well, though of course it does not set any bits. */
352 static CONST struct asm_flg fix_flags[] =
354 {"p", 0x00000020},
355 {"m", 0x00000040},
356 {"z", 0x00000060},
357 {"sp", 0x00000020},
358 {"sm", 0x00000040},
359 {"sz", 0x00000060},
360 {"dp", 0x00000020},
361 {"dm", 0x00000040},
362 {"dz", 0x00000060},
363 {"ep", 0x00000020},
364 {"em", 0x00000040},
365 {"ez", 0x00000060},
366 {NULL, 0}
369 static CONST struct asm_flg except_flag[] =
371 {"e", 0x00400000},
372 {NULL, 0}
375 static CONST struct asm_flg cplong_flag[] =
377 {"l", 0x00400000},
378 {NULL, 0}
381 struct asm_psr
383 CONST char * template;
384 boolean cpsr;
385 unsigned long field;
388 #define SPSR_BIT (1 << 22) /* The bit that distnguishes CPSR and SPSR. */
389 #define PSR_SHIFT 16 /* How many bits to shift the PSR_xxx bits up by. */
391 #define PSR_c (1 << 0)
392 #define PSR_x (1 << 1)
393 #define PSR_s (1 << 2)
394 #define PSR_f (1 << 3)
396 static CONST struct asm_psr psrs[] =
398 {"CPSR", true, PSR_c | PSR_f},
399 {"CPSR_all", true, PSR_c | PSR_f},
400 {"SPSR", false, PSR_c | PSR_f},
401 {"SPSR_all", false, PSR_c | PSR_f},
402 {"CPSR_flg", true, PSR_f},
403 {"CPSR_f", true, PSR_f},
404 {"SPSR_flg", false, PSR_f},
405 {"SPSR_f", false, PSR_f},
406 {"CPSR_c", true, PSR_c},
407 {"CPSR_ctl", true, PSR_c},
408 {"SPSR_c", false, PSR_c},
409 {"SPSR_ctl", false, PSR_c},
410 {"CPSR_x", true, PSR_x},
411 {"CPSR_s", true, PSR_s},
412 {"SPSR_x", false, PSR_x},
413 {"SPSR_s", false, PSR_s},
414 /* For backwards compatability with older toolchain we also
415 support lower case versions of some of these flags. */
416 {"cpsr", true, PSR_c | PSR_f},
417 {"cpsr_all", true, PSR_c | PSR_f},
418 {"spsr", false, PSR_c | PSR_f},
419 {"spsr_all", false, PSR_c | PSR_f},
420 {"cpsr_flg", true, PSR_f},
421 {"cpsr_f", true, PSR_f},
422 {"spsr_flg", false, PSR_f},
423 {"spsr_f", false, PSR_f},
424 {"cpsr_c", true, PSR_c},
425 {"cpsr_ctl", true, PSR_c},
426 {"spsr_c", false, PSR_c},
427 {"spsr_ctl", false, PSR_c}
430 /* Functions called by parser. */
431 /* ARM instructions */
432 static void do_arit PARAMS ((char *, unsigned long));
433 static void do_cmp PARAMS ((char *, unsigned long));
434 static void do_mov PARAMS ((char *, unsigned long));
435 static void do_ldst PARAMS ((char *, unsigned long));
436 static void do_ldmstm PARAMS ((char *, unsigned long));
437 static void do_branch PARAMS ((char *, unsigned long));
438 static void do_swi PARAMS ((char *, unsigned long));
439 /* Pseudo Op codes */
440 static void do_adr PARAMS ((char *, unsigned long));
441 static void do_adrl PARAMS ((char *, unsigned long));
442 static void do_nop PARAMS ((char *, unsigned long));
443 /* ARM 2 */
444 static void do_mul PARAMS ((char *, unsigned long));
445 static void do_mla PARAMS ((char *, unsigned long));
446 /* ARM 3 */
447 static void do_swap PARAMS ((char *, unsigned long));
448 /* ARM 6 */
449 static void do_msr PARAMS ((char *, unsigned long));
450 static void do_mrs PARAMS ((char *, unsigned long));
451 /* ARM 7M */
452 static void do_mull PARAMS ((char *, unsigned long));
453 /* ARM THUMB */
454 static void do_bx PARAMS ((char *, unsigned long));
457 /* Coprocessor Instructions */
458 static void do_cdp PARAMS ((char *, unsigned long));
459 static void do_lstc PARAMS ((char *, unsigned long));
460 static void do_co_reg PARAMS ((char *, unsigned long));
461 static void do_fp_ctrl PARAMS ((char *, unsigned long));
462 static void do_fp_ldst PARAMS ((char *, unsigned long));
463 static void do_fp_ldmstm PARAMS ((char *, unsigned long));
464 static void do_fp_dyadic PARAMS ((char *, unsigned long));
465 static void do_fp_monadic PARAMS ((char *, unsigned long));
466 static void do_fp_cmp PARAMS ((char *, unsigned long));
467 static void do_fp_from_reg PARAMS ((char *, unsigned long));
468 static void do_fp_to_reg PARAMS ((char *, unsigned long));
470 static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *, int, int));
471 static int arm_reg_parse PARAMS ((char **));
472 static CONST struct asm_psr * arm_psr_parse PARAMS ((char **));
473 static void symbol_locate PARAMS ((symbolS *, CONST char *, segT, valueT, fragS *));
474 static int add_to_lit_pool PARAMS ((void));
475 static unsigned validate_immediate PARAMS ((unsigned));
476 static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *));
477 static int validate_offset_imm PARAMS ((unsigned int, int));
478 static void opcode_select PARAMS ((int));
479 static void end_of_line PARAMS ((char *));
480 static int reg_required_here PARAMS ((char **, int));
481 static int psr_required_here PARAMS ((char **));
482 static int co_proc_number PARAMS ((char **));
483 static int cp_opc_expr PARAMS ((char **, int, int));
484 static int cp_reg_required_here PARAMS ((char **, int));
485 static int fp_reg_required_here PARAMS ((char **, int));
486 static int cp_address_offset PARAMS ((char **));
487 static int cp_address_required_here PARAMS ((char **));
488 static int my_get_float_expression PARAMS ((char **));
489 static int skip_past_comma PARAMS ((char **));
490 static int walk_no_bignums PARAMS ((symbolS *));
491 static int negate_data_op PARAMS ((unsigned long *, unsigned long));
492 static int data_op2 PARAMS ((char **));
493 static int fp_op2 PARAMS ((char **));
494 static long reg_list PARAMS ((char **));
495 static void thumb_load_store PARAMS ((char *, int, int));
496 static int decode_shift PARAMS ((char **, int));
497 static int ldst_extend PARAMS ((char **, int));
498 static void thumb_add_sub PARAMS ((char *, int));
499 static void insert_reg PARAMS ((int));
500 static void thumb_shift PARAMS ((char *, int));
501 static void thumb_mov_compare PARAMS ((char *, int));
502 static void set_constant_flonums PARAMS ((void));
503 static valueT md_chars_to_number PARAMS ((char *, int));
504 static void insert_reg_alias PARAMS ((char *, int));
505 static void output_inst PARAMS ((void));
506 #ifdef OBJ_ELF
507 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
508 #endif
510 /* ARM instructions take 4bytes in the object file, Thumb instructions
511 take 2: */
512 #define INSN_SIZE 4
514 /* LONGEST_INST is the longest basic instruction name without conditions or
515 flags. ARM7M has 4 of length 5. */
517 #define LONGEST_INST 5
520 struct asm_opcode
522 CONST char * template; /* Basic string to match */
523 unsigned long value; /* Basic instruction code */
525 /* Compulsory suffix that must follow conds. If "", then the
526 instruction is not conditional and must have no suffix. */
527 CONST char * comp_suffix;
529 CONST struct asm_flg * flags; /* Bits to toggle if flag 'n' set */
530 unsigned long variants; /* Which CPU variants this exists for */
531 /* Function to call to parse args */
532 void (* parms) PARAMS ((char *, unsigned long));
535 static CONST struct asm_opcode insns[] =
537 /* ARM Instructions */
538 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
539 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
540 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
541 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
542 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
543 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
544 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
545 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
546 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
547 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
548 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
549 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
550 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
551 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
552 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
553 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
554 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
555 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
556 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
557 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
558 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
559 #ifdef TE_WINCE
560 {"bl", 0x0b000000, NULL, NULL, ARM_ANY, do_branch},
561 {"b", 0x0a000000, NULL, NULL, ARM_ANY, do_branch},
562 #else
563 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
564 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
565 #endif
567 /* Pseudo ops */
568 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
569 {"adrl", 0x028f0000, NULL, NULL, ARM_ANY, do_adrl},
570 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
572 /* ARM 2 multiplies */
573 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
574 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
576 /* ARM 3 - swp instructions */
577 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
579 /* ARM 6 Coprocessor instructions */
580 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
581 {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr},
582 /* ScottB: our code uses 0x0128f000 for msr.
583 NickC: but this is wrong because the bits 16 through 19 are
584 handled by the PSR_xxx defines above. */
586 /* ARM 7M long multiplies - need signed/unsigned flags! */
587 {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull},
588 {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull},
589 {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull},
590 {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull},
592 /* ARM THUMB interworking */
593 {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx},
595 /* Floating point instructions */
596 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
597 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
598 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
599 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
600 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
601 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
602 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
603 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
604 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
605 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
606 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
607 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
608 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
609 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
610 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
611 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
612 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
613 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
614 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
615 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
616 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
617 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
618 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
619 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
620 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
621 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
622 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
623 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
624 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
625 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
626 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
627 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
628 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
629 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
630 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
631 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
632 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
633 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
634 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
635 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
636 be an optional suffix, but part of the instruction. To be compatible,
637 we accept either. */
638 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
639 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
640 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
641 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
643 /* Generic copressor instructions. */
644 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
645 {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc},
646 {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc},
647 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
648 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
651 /* Defines for various bits that we will want to toggle. */
652 #define INST_IMMEDIATE 0x02000000
653 #define OFFSET_REG 0x02000000
654 #define HWOFFSET_IMM 0x00400000
655 #define SHIFT_BY_REG 0x00000010
656 #define PRE_INDEX 0x01000000
657 #define INDEX_UP 0x00800000
658 #define WRITE_BACK 0x00200000
659 #define LDM_TYPE_2_OR_3 0x00400000
661 #define LITERAL_MASK 0xf000f000
662 #define COND_MASK 0xf0000000
663 #define OPCODE_MASK 0xfe1fffff
664 #define DATA_OP_SHIFT 21
666 /* Codes to distinguish the arithmetic instructions. */
667 #define OPCODE_AND 0
668 #define OPCODE_EOR 1
669 #define OPCODE_SUB 2
670 #define OPCODE_RSB 3
671 #define OPCODE_ADD 4
672 #define OPCODE_ADC 5
673 #define OPCODE_SBC 6
674 #define OPCODE_RSC 7
675 #define OPCODE_TST 8
676 #define OPCODE_TEQ 9
677 #define OPCODE_CMP 10
678 #define OPCODE_CMN 11
679 #define OPCODE_ORR 12
680 #define OPCODE_MOV 13
681 #define OPCODE_BIC 14
682 #define OPCODE_MVN 15
684 static void do_t_nop PARAMS ((char *));
685 static void do_t_arit PARAMS ((char *));
686 static void do_t_add PARAMS ((char *));
687 static void do_t_asr PARAMS ((char *));
688 static void do_t_branch9 PARAMS ((char *));
689 static void do_t_branch12 PARAMS ((char *));
690 static void do_t_branch23 PARAMS ((char *));
691 static void do_t_bx PARAMS ((char *));
692 static void do_t_compare PARAMS ((char *));
693 static void do_t_ldmstm PARAMS ((char *));
694 static void do_t_ldr PARAMS ((char *));
695 static void do_t_ldrb PARAMS ((char *));
696 static void do_t_ldrh PARAMS ((char *));
697 static void do_t_lds PARAMS ((char *));
698 static void do_t_lsl PARAMS ((char *));
699 static void do_t_lsr PARAMS ((char *));
700 static void do_t_mov PARAMS ((char *));
701 static void do_t_push_pop PARAMS ((char *));
702 static void do_t_str PARAMS ((char *));
703 static void do_t_strb PARAMS ((char *));
704 static void do_t_strh PARAMS ((char *));
705 static void do_t_sub PARAMS ((char *));
706 static void do_t_swi PARAMS ((char *));
707 static void do_t_adr PARAMS ((char *));
709 #define T_OPCODE_MUL 0x4340
710 #define T_OPCODE_TST 0x4200
711 #define T_OPCODE_CMN 0x42c0
712 #define T_OPCODE_NEG 0x4240
713 #define T_OPCODE_MVN 0x43c0
715 #define T_OPCODE_ADD_R3 0x1800
716 #define T_OPCODE_SUB_R3 0x1a00
717 #define T_OPCODE_ADD_HI 0x4400
718 #define T_OPCODE_ADD_ST 0xb000
719 #define T_OPCODE_SUB_ST 0xb080
720 #define T_OPCODE_ADD_SP 0xa800
721 #define T_OPCODE_ADD_PC 0xa000
722 #define T_OPCODE_ADD_I8 0x3000
723 #define T_OPCODE_SUB_I8 0x3800
724 #define T_OPCODE_ADD_I3 0x1c00
725 #define T_OPCODE_SUB_I3 0x1e00
727 #define T_OPCODE_ASR_R 0x4100
728 #define T_OPCODE_LSL_R 0x4080
729 #define T_OPCODE_LSR_R 0x40c0
730 #define T_OPCODE_ASR_I 0x1000
731 #define T_OPCODE_LSL_I 0x0000
732 #define T_OPCODE_LSR_I 0x0800
734 #define T_OPCODE_MOV_I8 0x2000
735 #define T_OPCODE_CMP_I8 0x2800
736 #define T_OPCODE_CMP_LR 0x4280
737 #define T_OPCODE_MOV_HR 0x4600
738 #define T_OPCODE_CMP_HR 0x4500
740 #define T_OPCODE_LDR_PC 0x4800
741 #define T_OPCODE_LDR_SP 0x9800
742 #define T_OPCODE_STR_SP 0x9000
743 #define T_OPCODE_LDR_IW 0x6800
744 #define T_OPCODE_STR_IW 0x6000
745 #define T_OPCODE_LDR_IH 0x8800
746 #define T_OPCODE_STR_IH 0x8000
747 #define T_OPCODE_LDR_IB 0x7800
748 #define T_OPCODE_STR_IB 0x7000
749 #define T_OPCODE_LDR_RW 0x5800
750 #define T_OPCODE_STR_RW 0x5000
751 #define T_OPCODE_LDR_RH 0x5a00
752 #define T_OPCODE_STR_RH 0x5200
753 #define T_OPCODE_LDR_RB 0x5c00
754 #define T_OPCODE_STR_RB 0x5400
756 #define T_OPCODE_PUSH 0xb400
757 #define T_OPCODE_POP 0xbc00
759 #define T_OPCODE_BRANCH 0xe7fe
761 static int thumb_reg PARAMS ((char ** str, int hi_lo));
763 #define THUMB_SIZE 2 /* Size of thumb instruction. */
764 #define THUMB_REG_LO 0x1
765 #define THUMB_REG_HI 0x2
766 #define THUMB_REG_ANY 0x3
768 #define THUMB_H1 0x0080
769 #define THUMB_H2 0x0040
771 #define THUMB_ASR 0
772 #define THUMB_LSL 1
773 #define THUMB_LSR 2
775 #define THUMB_MOVE 0
776 #define THUMB_COMPARE 1
778 #define THUMB_LOAD 0
779 #define THUMB_STORE 1
781 #define THUMB_PP_PC_LR 0x0100
783 /* These three are used for immediate shifts, do not alter. */
784 #define THUMB_WORD 2
785 #define THUMB_HALFWORD 1
786 #define THUMB_BYTE 0
788 struct thumb_opcode
790 CONST char * template; /* Basic string to match */
791 unsigned long value; /* Basic instruction code */
792 int size;
793 unsigned long variants; /* Which CPU variants this exists for */
794 void (* parms) PARAMS ((char *)); /* Function to call to parse args */
797 static CONST struct thumb_opcode tinsns[] =
799 {"adc", 0x4140, 2, ARM_THUMB, do_t_arit},
800 {"add", 0x0000, 2, ARM_THUMB, do_t_add},
801 {"and", 0x4000, 2, ARM_THUMB, do_t_arit},
802 {"asr", 0x0000, 2, ARM_THUMB, do_t_asr},
803 {"b", T_OPCODE_BRANCH, 2, ARM_THUMB, do_t_branch12},
804 {"beq", 0xd0fe, 2, ARM_THUMB, do_t_branch9},
805 {"bne", 0xd1fe, 2, ARM_THUMB, do_t_branch9},
806 {"bcs", 0xd2fe, 2, ARM_THUMB, do_t_branch9},
807 {"bhs", 0xd2fe, 2, ARM_THUMB, do_t_branch9},
808 {"bcc", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
809 {"bul", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
810 {"blo", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
811 {"bmi", 0xd4fe, 2, ARM_THUMB, do_t_branch9},
812 {"bpl", 0xd5fe, 2, ARM_THUMB, do_t_branch9},
813 {"bvs", 0xd6fe, 2, ARM_THUMB, do_t_branch9},
814 {"bvc", 0xd7fe, 2, ARM_THUMB, do_t_branch9},
815 {"bhi", 0xd8fe, 2, ARM_THUMB, do_t_branch9},
816 {"bls", 0xd9fe, 2, ARM_THUMB, do_t_branch9},
817 {"bge", 0xdafe, 2, ARM_THUMB, do_t_branch9},
818 {"blt", 0xdbfe, 2, ARM_THUMB, do_t_branch9},
819 {"bgt", 0xdcfe, 2, ARM_THUMB, do_t_branch9},
820 {"ble", 0xddfe, 2, ARM_THUMB, do_t_branch9},
821 {"bal", 0xdefe, 2, ARM_THUMB, do_t_branch9},
822 {"bic", 0x4380, 2, ARM_THUMB, do_t_arit},
823 {"bl", 0xf7fffffe, 4, ARM_THUMB, do_t_branch23},
824 {"bx", 0x4700, 2, ARM_THUMB, do_t_bx},
825 {"cmn", T_OPCODE_CMN, 2, ARM_THUMB, do_t_arit},
826 {"cmp", 0x0000, 2, ARM_THUMB, do_t_compare},
827 {"eor", 0x4040, 2, ARM_THUMB, do_t_arit},
828 {"ldmia", 0xc800, 2, ARM_THUMB, do_t_ldmstm},
829 {"ldr", 0x0000, 2, ARM_THUMB, do_t_ldr},
830 {"ldrb", 0x0000, 2, ARM_THUMB, do_t_ldrb},
831 {"ldrh", 0x0000, 2, ARM_THUMB, do_t_ldrh},
832 {"ldrsb", 0x5600, 2, ARM_THUMB, do_t_lds},
833 {"ldrsh", 0x5e00, 2, ARM_THUMB, do_t_lds},
834 {"ldsb", 0x5600, 2, ARM_THUMB, do_t_lds},
835 {"ldsh", 0x5e00, 2, ARM_THUMB, do_t_lds},
836 {"lsl", 0x0000, 2, ARM_THUMB, do_t_lsl},
837 {"lsr", 0x0000, 2, ARM_THUMB, do_t_lsr},
838 {"mov", 0x0000, 2, ARM_THUMB, do_t_mov},
839 {"mul", T_OPCODE_MUL, 2, ARM_THUMB, do_t_arit},
840 {"mvn", T_OPCODE_MVN, 2, ARM_THUMB, do_t_arit},
841 {"neg", T_OPCODE_NEG, 2, ARM_THUMB, do_t_arit},
842 {"orr", 0x4300, 2, ARM_THUMB, do_t_arit},
843 {"pop", 0xbc00, 2, ARM_THUMB, do_t_push_pop},
844 {"push", 0xb400, 2, ARM_THUMB, do_t_push_pop},
845 {"ror", 0x41c0, 2, ARM_THUMB, do_t_arit},
846 {"sbc", 0x4180, 2, ARM_THUMB, do_t_arit},
847 {"stmia", 0xc000, 2, ARM_THUMB, do_t_ldmstm},
848 {"str", 0x0000, 2, ARM_THUMB, do_t_str},
849 {"strb", 0x0000, 2, ARM_THUMB, do_t_strb},
850 {"strh", 0x0000, 2, ARM_THUMB, do_t_strh},
851 {"swi", 0xdf00, 2, ARM_THUMB, do_t_swi},
852 {"sub", 0x0000, 2, ARM_THUMB, do_t_sub},
853 {"tst", T_OPCODE_TST, 2, ARM_THUMB, do_t_arit},
854 /* Pseudo ops: */
855 {"adr", 0x0000, 2, ARM_THUMB, do_t_adr},
856 {"nop", 0x46C0, 2, ARM_THUMB, do_t_nop}, /* mov r8,r8 */
859 struct reg_entry
861 CONST char * name;
862 int number;
865 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
866 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
867 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
869 #define REG_PC 15
870 #define REG_LR 14
871 #define REG_SP 13
873 /* These are the standard names. Users can add aliases with .req */
874 static CONST struct reg_entry reg_table[] =
876 /* Processor Register Numbers. */
877 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
878 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
879 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
880 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
881 /* APCS conventions. */
882 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
883 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
884 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
885 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
886 /* ATPCS additions to APCS conventions. */
887 {"wr", 7}, {"v8", 11},
888 /* FP Registers. */
889 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
890 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
891 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
892 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
893 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
894 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
895 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
896 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
897 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
898 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
899 /* ATPCS additions to float register names. */
900 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
901 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
902 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
903 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
904 /* FIXME: At some point we need to add VFP register names. */
905 /* Array terminator. */
906 {NULL, 0}
909 #define BAD_ARGS _("Bad arguments to instruction")
910 #define BAD_PC _("r15 not allowed here")
911 #define BAD_FLAGS _("Instruction should not have flags")
912 #define BAD_COND _("Instruction is not conditional")
914 static struct hash_control * arm_ops_hsh = NULL;
915 static struct hash_control * arm_tops_hsh = NULL;
916 static struct hash_control * arm_cond_hsh = NULL;
917 static struct hash_control * arm_shift_hsh = NULL;
918 static struct hash_control * arm_reg_hsh = NULL;
919 static struct hash_control * arm_psr_hsh = NULL;
921 /* This table describes all the machine specific pseudo-ops the assembler
922 has to support. The fields are:
923 pseudo-op name without dot
924 function to call to execute this pseudo-op
925 Integer arg to pass to the function. */
927 static void s_req PARAMS ((int));
928 static void s_align PARAMS ((int));
929 static void s_bss PARAMS ((int));
930 static void s_even PARAMS ((int));
931 static void s_ltorg PARAMS ((int));
932 static void s_arm PARAMS ((int));
933 static void s_thumb PARAMS ((int));
934 static void s_code PARAMS ((int));
935 static void s_force_thumb PARAMS ((int));
936 static void s_thumb_func PARAMS ((int));
937 static void s_thumb_set PARAMS ((int));
938 static void arm_s_text PARAMS ((int));
939 static void arm_s_data PARAMS ((int));
940 #ifdef OBJ_ELF
941 static void arm_s_section PARAMS ((int));
942 static void s_arm_elf_cons PARAMS ((int));
943 #endif
945 static int my_get_expression PARAMS ((expressionS *, char **));
947 CONST pseudo_typeS md_pseudo_table[] =
949 { "req", s_req, 0 }, /* Never called becasue '.req' does not start line */
950 { "bss", s_bss, 0 },
951 { "align", s_align, 0 },
952 { "arm", s_arm, 0 },
953 { "thumb", s_thumb, 0 },
954 { "code", s_code, 0 },
955 { "force_thumb", s_force_thumb, 0 },
956 { "thumb_func", s_thumb_func, 0 },
957 { "thumb_set", s_thumb_set, 0 },
958 { "even", s_even, 0 },
959 { "ltorg", s_ltorg, 0 },
960 { "pool", s_ltorg, 0 },
961 /* Allow for the effect of section changes. */
962 { "text", arm_s_text, 0 },
963 { "data", arm_s_data, 0 },
964 #ifdef OBJ_ELF
965 { "section", arm_s_section, 0 },
966 { "section.s", arm_s_section, 0 },
967 { "sect", arm_s_section, 0 },
968 { "sect.s", arm_s_section, 0 },
969 { "word", s_arm_elf_cons, 4 },
970 { "long", s_arm_elf_cons, 4 },
971 #else
972 { "word", cons, 4},
973 #endif
974 { "extend", float_cons, 'x' },
975 { "ldouble", float_cons, 'x' },
976 { "packed", float_cons, 'p' },
977 { 0, 0, 0 }
980 /* Stuff needed to resolve the label ambiguity
983 label: <insn>
984 may differ from:
986 label:
987 <insn>
990 symbolS * last_label_seen;
991 static int label_is_thumb_function_name = false;
993 /* Literal stuff */
995 #define MAX_LITERAL_POOL_SIZE 1024
997 typedef struct literalS
999 struct expressionS exp;
1000 struct arm_it * inst;
1001 } literalT;
1003 literalT literals[MAX_LITERAL_POOL_SIZE];
1004 int next_literal_pool_place = 0; /* Next free entry in the pool */
1005 int lit_pool_num = 1; /* Next literal pool number */
1006 symbolS * current_poolP = NULL;
1008 static int
1009 add_to_lit_pool ()
1011 int lit_count = 0;
1013 if (current_poolP == NULL)
1014 current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,
1015 (valueT) 0, &zero_address_frag);
1017 /* Check if this literal value is already in the pool: */
1018 while (lit_count < next_literal_pool_place)
1020 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
1021 && inst.reloc.exp.X_op == O_constant
1022 && literals[lit_count].exp.X_add_number
1023 == inst.reloc.exp.X_add_number
1024 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
1025 break;
1026 lit_count++;
1029 if (lit_count == next_literal_pool_place) /* new entry */
1031 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
1033 inst.error = _("Literal Pool Overflow");
1034 return FAIL;
1037 literals[next_literal_pool_place].exp = inst.reloc.exp;
1038 lit_count = next_literal_pool_place++;
1041 inst.reloc.exp.X_op = O_symbol;
1042 inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
1043 inst.reloc.exp.X_add_symbol = current_poolP;
1045 return SUCCESS;
1048 /* Can't use symbol_new here, so have to create a symbol and then at
1049 a later date assign it a value. Thats what these functions do. */
1050 static void
1051 symbol_locate (symbolP, name, segment, valu, frag)
1052 symbolS * symbolP;
1053 CONST char * name; /* It is copied, the caller can modify */
1054 segT segment; /* Segment identifier (SEG_<something>) */
1055 valueT valu; /* Symbol value */
1056 fragS * frag; /* Associated fragment */
1058 unsigned int name_length;
1059 char * preserved_copy_of_name;
1061 name_length = strlen (name) + 1; /* +1 for \0 */
1062 obstack_grow (&notes, name, name_length);
1063 preserved_copy_of_name = obstack_finish (&notes);
1064 #ifdef STRIP_UNDERSCORE
1065 if (preserved_copy_of_name[0] == '_')
1066 preserved_copy_of_name++;
1067 #endif
1069 #ifdef tc_canonicalize_symbol_name
1070 preserved_copy_of_name =
1071 tc_canonicalize_symbol_name (preserved_copy_of_name);
1072 #endif
1074 S_SET_NAME (symbolP, preserved_copy_of_name);
1076 S_SET_SEGMENT (symbolP, segment);
1077 S_SET_VALUE (symbolP, valu);
1078 symbol_clear_list_pointers(symbolP);
1080 symbol_set_frag (symbolP, frag);
1082 /* Link to end of symbol chain. */
1084 extern int symbol_table_frozen;
1085 if (symbol_table_frozen)
1086 abort ();
1089 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1091 obj_symbol_new_hook (symbolP);
1093 #ifdef tc_symbol_new_hook
1094 tc_symbol_new_hook (symbolP);
1095 #endif
1097 #ifdef DEBUG_SYMS
1098 verify_symbol_chain (symbol_rootP, symbol_lastP);
1099 #endif /* DEBUG_SYMS */
1102 /* Check that an immediate is valid, and if so,
1103 convert it to the right format. */
1104 static unsigned int
1105 validate_immediate (val)
1106 unsigned int val;
1108 unsigned int a;
1109 unsigned int i;
1111 #define rotate_left(v, n) (v << n | v >> (32 - n))
1113 for (i = 0; i < 32; i += 2)
1114 if ((a = rotate_left (val, i)) <= 0xff)
1115 return a | (i << 7); /* 12-bit pack: [shift-cnt,const] */
1117 return FAIL;
1120 /* Check to see if an immediate can be computed as two seperate immediate
1121 values, added together. We already know that this value cannot be
1122 computed by just one ARM instruction. */
1123 static unsigned int
1124 validate_immediate_twopart (val, highpart)
1125 unsigned int val;
1126 unsigned int * highpart;
1128 unsigned int a;
1129 unsigned int i;
1131 for (i = 0; i < 32; i += 2)
1132 if (((a = rotate_left (val, i)) & 0xff) != 0)
1134 if (a & 0xff00)
1136 if (a & ~ 0xffff)
1137 continue;
1138 * highpart = (a >> 8) | ((i + 24) << 7);
1140 else if (a & 0xff0000)
1142 if (a & 0xff000000)
1143 continue;
1145 * highpart = (a >> 16) | ((i + 16) << 7);
1147 else
1149 assert (a & 0xff000000);
1151 * highpart = (a >> 24) | ((i + 8) << 7);
1154 return (a & 0xff) | (i << 7);
1157 return FAIL;
1160 static int
1161 validate_offset_imm (val, hwse)
1162 unsigned int val;
1163 int hwse;
1165 if ((hwse && val > 255) || val > 4095)
1166 return FAIL;
1167 return val;
1171 static void
1172 s_req (a)
1173 int a ATTRIBUTE_UNUSED;
1175 as_bad (_("Invalid syntax for .req directive."));
1178 static void
1179 s_bss (ignore)
1180 int ignore ATTRIBUTE_UNUSED;
1182 /* We don't support putting frags in the BSS segment, we fake it by
1183 marking in_bss, then looking at s_skip for clues?.. */
1184 subseg_set (bss_section, 0);
1185 demand_empty_rest_of_line ();
1188 static void
1189 s_even (ignore)
1190 int ignore ATTRIBUTE_UNUSED;
1192 if (!need_pass_2) /* Never make frag if expect extra pass. */
1193 frag_align (1, 0, 0);
1195 record_alignment (now_seg, 1);
1197 demand_empty_rest_of_line ();
1200 static void
1201 s_ltorg (ignored)
1202 int ignored ATTRIBUTE_UNUSED;
1204 int lit_count = 0;
1205 char sym_name[20];
1207 if (current_poolP == NULL)
1208 return;
1210 /* Align pool as you have word accesses */
1211 /* Only make a frag if we have to ... */
1212 if (!need_pass_2)
1213 frag_align (2, 0, 0);
1215 record_alignment (now_seg, 2);
1217 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1219 symbol_locate (current_poolP, sym_name, now_seg,
1220 (valueT) frag_now_fix (), frag_now);
1221 symbol_table_insert (current_poolP);
1223 ARM_SET_THUMB (current_poolP, thumb_mode);
1225 #if defined OBJ_COFF || defined OBJ_ELF
1226 ARM_SET_INTERWORK (current_poolP, support_interwork);
1227 #endif
1229 while (lit_count < next_literal_pool_place)
1230 /* First output the expression in the instruction to the pool. */
1231 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1233 next_literal_pool_place = 0;
1234 current_poolP = NULL;
1237 static void
1238 s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */
1239 int unused ATTRIBUTE_UNUSED;
1241 register int temp;
1242 register long temp_fill;
1243 long max_alignment = 15;
1245 temp = get_absolute_expression ();
1246 if (temp > max_alignment)
1247 as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
1248 else if (temp < 0)
1250 as_bad (_("Alignment negative. 0 assumed."));
1251 temp = 0;
1254 if (*input_line_pointer == ',')
1256 input_line_pointer++;
1257 temp_fill = get_absolute_expression ();
1259 else
1260 temp_fill = 0;
1262 if (!temp)
1263 temp = 2;
1265 /* Only make a frag if we HAVE to. . . */
1266 if (temp && !need_pass_2)
1267 frag_align (temp, (int) temp_fill, 0);
1268 demand_empty_rest_of_line ();
1270 record_alignment (now_seg, temp);
1273 static void
1274 s_force_thumb (ignore)
1275 int ignore ATTRIBUTE_UNUSED;
1277 /* If we are not already in thumb mode go into it, EVEN if
1278 the target processor does not support thumb instructions.
1279 This is used by gcc/config/arm/lib1funcs.asm for example
1280 to compile interworking support functions even if the
1281 target processor should not support interworking. */
1283 if (! thumb_mode)
1285 thumb_mode = 2;
1287 record_alignment (now_seg, 1);
1290 demand_empty_rest_of_line ();
1293 static void
1294 s_thumb_func (ignore)
1295 int ignore ATTRIBUTE_UNUSED;
1297 /* The following label is the name/address of the start of a Thumb function.
1298 We need to know this for the interworking support. */
1300 label_is_thumb_function_name = true;
1302 demand_empty_rest_of_line ();
1305 /* Perform a .set directive, but also mark the alias as
1306 being a thumb function. */
1308 static void
1309 s_thumb_set (equiv)
1310 int equiv;
1312 /* XXX the following is a duplicate of the code for s_set() in read.c
1313 We cannot just call that code as we need to get at the symbol that
1314 is created. */
1315 register char * name;
1316 register char delim;
1317 register char * end_name;
1318 register symbolS * symbolP;
1321 * Especial apologies for the random logic:
1322 * this just grew, and could be parsed much more simply!
1323 * Dean in haste.
1325 name = input_line_pointer;
1326 delim = get_symbol_end ();
1327 end_name = input_line_pointer;
1328 *end_name = delim;
1330 SKIP_WHITESPACE ();
1332 if (*input_line_pointer != ',')
1334 *end_name = 0;
1335 as_bad (_("Expected comma after name \"%s\""), name);
1336 *end_name = delim;
1337 ignore_rest_of_line ();
1338 return;
1341 input_line_pointer++;
1342 *end_name = 0;
1344 if (name[0] == '.' && name[1] == '\0')
1346 /* XXX - this should not happen to .thumb_set */
1347 abort ();
1350 if ((symbolP = symbol_find (name)) == NULL
1351 && (symbolP = md_undefined_symbol (name)) == NULL)
1353 #ifndef NO_LISTING
1354 /* When doing symbol listings, play games with dummy fragments living
1355 outside the normal fragment chain to record the file and line info
1356 for this symbol. */
1357 if (listing & LISTING_SYMBOLS)
1359 extern struct list_info_struct * listing_tail;
1360 fragS * dummy_frag = (fragS *) xmalloc (sizeof(fragS));
1361 memset (dummy_frag, 0, sizeof(fragS));
1362 dummy_frag->fr_type = rs_fill;
1363 dummy_frag->line = listing_tail;
1364 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1365 dummy_frag->fr_symbol = symbolP;
1367 else
1368 #endif
1369 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1371 #ifdef OBJ_COFF
1372 /* "set" symbols are local unless otherwise specified. */
1373 SF_SET_LOCAL (symbolP);
1374 #endif /* OBJ_COFF */
1375 } /* make a new symbol */
1377 symbol_table_insert (symbolP);
1379 * end_name = delim;
1381 if (equiv
1382 && S_IS_DEFINED (symbolP)
1383 && S_GET_SEGMENT (symbolP) != reg_section)
1384 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1386 pseudo_set (symbolP);
1388 demand_empty_rest_of_line ();
1390 /* XXX Now we come to the Thumb specific bit of code. */
1392 THUMB_SET_FUNC (symbolP, 1);
1393 ARM_SET_THUMB (symbolP, 1);
1394 #if defined OBJ_ELF || defined OBJ_COFF
1395 ARM_SET_INTERWORK (symbolP, support_interwork);
1396 #endif
1399 /* If we change section we must dump the literal pool first. */
1400 static void
1401 arm_s_text (ignore)
1402 int ignore;
1404 if (now_seg != text_section)
1405 s_ltorg (0);
1407 #ifdef OBJ_ELF
1408 obj_elf_text (ignore);
1409 #else
1410 s_text (ignore);
1411 #endif
1414 static void
1415 arm_s_data (ignore)
1416 int ignore;
1418 if (flag_readonly_data_in_text)
1420 if (now_seg != text_section)
1421 s_ltorg (0);
1423 else if (now_seg != data_section)
1424 s_ltorg (0);
1426 #ifdef OBJ_ELF
1427 obj_elf_data (ignore);
1428 #else
1429 s_data (ignore);
1430 #endif
1433 #ifdef OBJ_ELF
1434 static void
1435 arm_s_section (ignore)
1436 int ignore;
1438 s_ltorg (0);
1440 obj_elf_section (ignore);
1442 #endif
1444 static void
1445 opcode_select (width)
1446 int width;
1448 switch (width)
1450 case 16:
1451 if (! thumb_mode)
1453 if (! (cpu_variant & ARM_THUMB))
1454 as_bad (_("selected processor does not support THUMB opcodes"));
1455 thumb_mode = 1;
1456 /* No need to force the alignment, since we will have been
1457 coming from ARM mode, which is word-aligned. */
1458 record_alignment (now_seg, 1);
1460 break;
1462 case 32:
1463 if (thumb_mode)
1465 if ((cpu_variant & ARM_ANY) == ARM_THUMB)
1466 as_bad (_("selected processor does not support ARM opcodes"));
1467 thumb_mode = 0;
1468 if (!need_pass_2)
1469 frag_align (2, 0, 0);
1470 record_alignment (now_seg, 1);
1472 break;
1474 default:
1475 as_bad (_("invalid instruction size selected (%d)"), width);
1479 static void
1480 s_arm (ignore)
1481 int ignore ATTRIBUTE_UNUSED;
1483 opcode_select (32);
1484 demand_empty_rest_of_line ();
1487 static void
1488 s_thumb (ignore)
1489 int ignore ATTRIBUTE_UNUSED;
1491 opcode_select (16);
1492 demand_empty_rest_of_line ();
1495 static void
1496 s_code (unused)
1497 int unused ATTRIBUTE_UNUSED;
1499 register int temp;
1501 temp = get_absolute_expression ();
1502 switch (temp)
1504 case 16:
1505 case 32:
1506 opcode_select (temp);
1507 break;
1509 default:
1510 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1514 static void
1515 end_of_line (str)
1516 char * str;
1518 skip_whitespace (str);
1520 if (* str != '\0')
1521 inst.error = _("Garbage following instruction");
1524 static int
1525 skip_past_comma (str)
1526 char ** str;
1528 char *p = *str, c;
1529 int comma = 0;
1531 while ((c = *p) == ' ' || c == ',')
1533 p++;
1534 if (c == ',' && comma++)
1535 return FAIL;
1538 if (c == '\0')
1539 return FAIL;
1541 *str = p;
1542 return comma ? SUCCESS : FAIL;
1545 /* A standard register must be given at this point.
1546 Shift is the place to put it in inst.instruction.
1547 Restores input start point on err.
1548 Returns the reg#, or FAIL. */
1549 static int
1550 reg_required_here (str, shift)
1551 char ** str;
1552 int shift;
1554 static char buff [128]; /* XXX */
1555 int reg;
1556 char * start = *str;
1558 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1560 if (shift >= 0)
1561 inst.instruction |= reg << shift;
1562 return reg;
1565 /* Restore the start point, we may have got a reg of the wrong class. */
1566 *str = start;
1568 /* In the few cases where we might be able to accept something else
1569 this error can be overridden. */
1570 sprintf (buff, _("Register expected, not '%.100s'"), start);
1571 inst.error = buff;
1573 return FAIL;
1576 static CONST struct asm_psr *
1577 arm_psr_parse (ccp)
1578 register char ** ccp;
1580 char * start = * ccp;
1581 char c;
1582 char * p;
1583 CONST struct asm_psr * psr;
1585 p = start;
1587 /* Skip to the end of the next word in the input stream. */
1590 c = *p++;
1592 while (isalpha (c) || c == '_');
1594 /* Terminate the word. */
1595 *--p = 0;
1597 /* Now locate the word in the psr hash table. */
1598 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
1600 /* Restore the input stream. */
1601 *p = c;
1603 /* If we found a valid match, advance the
1604 stream pointer past the end of the word. */
1605 *ccp = p;
1607 return psr;
1610 /* Parse the input looking for a PSR flag. */
1611 static int
1612 psr_required_here (str)
1613 char ** str;
1615 char * start = *str;
1616 CONST struct asm_psr * psr;
1618 psr = arm_psr_parse (str);
1620 if (psr)
1622 /* If this is the SPSR that is being modified, set the R bit. */
1623 if (! psr->cpsr)
1624 inst.instruction |= SPSR_BIT;
1626 /* Set the psr flags in the MSR instruction. */
1627 inst.instruction |= psr->field << PSR_SHIFT;
1629 return SUCCESS;
1632 /* In the few cases where we might be able to accept
1633 something else this error can be overridden. */
1634 inst.error = _("flag for {c}psr instruction expected");
1636 /* Restore the start point. */
1637 *str = start;
1638 return FAIL;
1641 static int
1642 co_proc_number (str)
1643 char ** str;
1645 int processor, pchar;
1647 skip_whitespace (* str);
1649 /* The data sheet seems to imply that just a number on its own is valid
1650 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1651 accept either. */
1652 if (**str == 'p' || **str == 'P')
1653 (*str)++;
1655 pchar = *(*str)++;
1656 if (pchar >= '0' && pchar <= '9')
1658 processor = pchar - '0';
1659 if (**str >= '0' && **str <= '9')
1661 processor = processor * 10 + *(*str)++ - '0';
1662 if (processor > 15)
1664 inst.error = _("Illegal co-processor number");
1665 return FAIL;
1669 else
1671 inst.error = _("Bad or missing co-processor number");
1672 return FAIL;
1675 inst.instruction |= processor << 8;
1676 return SUCCESS;
1679 static int
1680 cp_opc_expr (str, where, length)
1681 char ** str;
1682 int where;
1683 int length;
1685 expressionS expr;
1687 skip_whitespace (* str);
1689 memset (&expr, '\0', sizeof (expr));
1691 if (my_get_expression (&expr, str))
1692 return FAIL;
1693 if (expr.X_op != O_constant)
1695 inst.error = _("bad or missing expression");
1696 return FAIL;
1699 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1701 inst.error = _("immediate co-processor expression too large");
1702 return FAIL;
1705 inst.instruction |= expr.X_add_number << where;
1706 return SUCCESS;
1709 static int
1710 cp_reg_required_here (str, where)
1711 char ** str;
1712 int where;
1714 int reg;
1715 char * start = *str;
1717 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1719 reg &= 15;
1720 inst.instruction |= reg << where;
1721 return reg;
1724 /* In the few cases where we might be able to accept something else
1725 this error can be overridden. */
1726 inst.error = _("Co-processor register expected");
1728 /* Restore the start point. */
1729 *str = start;
1730 return FAIL;
1733 static int
1734 fp_reg_required_here (str, where)
1735 char ** str;
1736 int where;
1738 int reg;
1739 char * start = *str;
1741 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1743 reg &= 7;
1744 inst.instruction |= reg << where;
1745 return reg;
1748 /* In the few cases where we might be able to accept something else
1749 this error can be overridden. */
1750 inst.error = _("Floating point register expected");
1752 /* Restore the start point. */
1753 *str = start;
1754 return FAIL;
1757 static int
1758 cp_address_offset (str)
1759 char ** str;
1761 int offset;
1763 skip_whitespace (* str);
1765 if (! is_immediate_prefix (**str))
1767 inst.error = _("immediate expression expected");
1768 return FAIL;
1771 (*str)++;
1773 if (my_get_expression (& inst.reloc.exp, str))
1774 return FAIL;
1776 if (inst.reloc.exp.X_op == O_constant)
1778 offset = inst.reloc.exp.X_add_number;
1780 if (offset & 3)
1782 inst.error = _("co-processor address must be word aligned");
1783 return FAIL;
1786 if (offset > 1023 || offset < -1023)
1788 inst.error = _("offset too large");
1789 return FAIL;
1792 if (offset >= 0)
1793 inst.instruction |= INDEX_UP;
1794 else
1795 offset = -offset;
1797 inst.instruction |= offset >> 2;
1799 else
1800 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1802 return SUCCESS;
1805 static int
1806 cp_address_required_here (str)
1807 char ** str;
1809 char * p = * str;
1810 int pre_inc = 0;
1811 int write_back = 0;
1813 if (*p == '[')
1815 int reg;
1817 p++;
1818 skip_whitespace (p);
1820 if ((reg = reg_required_here (& p, 16)) == FAIL)
1821 return FAIL;
1823 skip_whitespace (p);
1825 if (*p == ']')
1827 p++;
1829 if (skip_past_comma (& p) == SUCCESS)
1831 /* [Rn], #expr */
1832 write_back = WRITE_BACK;
1834 if (reg == REG_PC)
1836 inst.error = _("pc may not be used in post-increment");
1837 return FAIL;
1840 if (cp_address_offset (& p) == FAIL)
1841 return FAIL;
1843 else
1844 pre_inc = PRE_INDEX | INDEX_UP;
1846 else
1848 /* '['Rn, #expr']'[!] */
1850 if (skip_past_comma (& p) == FAIL)
1852 inst.error = _("pre-indexed expression expected");
1853 return FAIL;
1856 pre_inc = PRE_INDEX;
1858 if (cp_address_offset (& p) == FAIL)
1859 return FAIL;
1861 skip_whitespace (p);
1863 if (*p++ != ']')
1865 inst.error = _("missing ]");
1866 return FAIL;
1869 skip_whitespace (p);
1871 if (*p == '!')
1873 if (reg == REG_PC)
1875 inst.error = _("pc may not be used with write-back");
1876 return FAIL;
1879 p++;
1880 write_back = WRITE_BACK;
1884 else
1886 if (my_get_expression (&inst.reloc.exp, &p))
1887 return FAIL;
1889 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1890 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
1891 inst.reloc.pc_rel = 1;
1892 inst.instruction |= (REG_PC << 16);
1893 pre_inc = PRE_INDEX;
1896 inst.instruction |= write_back | pre_inc;
1897 *str = p;
1898 return SUCCESS;
1901 static void
1902 do_nop (str, flags)
1903 char * str;
1904 unsigned long flags;
1906 /* Do nothing really. */
1907 inst.instruction |= flags; /* This is pointless. */
1908 end_of_line (str);
1909 return;
1912 static void
1913 do_mrs (str, flags)
1914 char *str;
1915 unsigned long flags;
1917 /* Only one syntax. */
1918 skip_whitespace (str);
1920 if (reg_required_here (&str, 12) == FAIL)
1922 inst.error = BAD_ARGS;
1923 return;
1926 if (skip_past_comma (&str) == FAIL)
1928 inst.error = _("comma expected after register name");
1929 return;
1932 skip_whitespace (str);
1934 if ( strcmp (str, "CPSR") == 0
1935 || strcmp (str, "SPSR") == 0
1936 /* Lower case versions for backwards compatability. */
1937 || strcmp (str, "cpsr") == 0
1938 || strcmp (str, "spsr") == 0)
1939 str += 4;
1940 /* This is for backwards compatability with older toolchains. */
1941 else if (strcmp (str, "cpsr_all") == 0
1942 || strcmp (str, "spsr_all") == 0)
1943 str += 7;
1944 else
1946 inst.error = _("{C|S}PSR expected");
1947 return;
1950 if (* str == 's' || * str == 'S')
1951 inst.instruction |= SPSR_BIT;
1953 inst.instruction |= flags;
1954 end_of_line (str);
1957 /* Two possible forms:
1958 "{C|S}PSR_<field>, Rm",
1959 "{C|S}PSR_f, #expression". */
1960 static void
1961 do_msr (str, flags)
1962 char * str;
1963 unsigned long flags;
1965 skip_whitespace (str);
1967 if (psr_required_here (& str) == FAIL)
1968 return;
1970 if (skip_past_comma (& str) == FAIL)
1972 inst.error = _("comma missing after psr flags");
1973 return;
1976 skip_whitespace (str);
1978 if (reg_required_here (& str, 0) != FAIL)
1980 inst.error = NULL;
1981 inst.instruction |= flags;
1982 end_of_line (str);
1983 return;
1986 if (! is_immediate_prefix (* str))
1988 inst.error = _("only a register or immediate value can follow a psr flag");
1989 return;
1992 str ++;
1993 inst.error = NULL;
1995 if (my_get_expression (& inst.reloc.exp, & str))
1997 inst.error = _("only a register or immediate value can follow a psr flag");
1998 return;
2001 if (inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
2003 inst.error = _("can only set flag field with immediate value");
2004 return;
2007 flags |= INST_IMMEDIATE;
2009 if (inst.reloc.exp.X_add_symbol)
2011 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2012 inst.reloc.pc_rel = 0;
2014 else
2016 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
2018 if (value == (unsigned) FAIL)
2020 inst.error = _("Invalid constant");
2021 return;
2024 inst.instruction |= value;
2027 inst.error = NULL;
2028 inst.instruction |= flags;
2029 end_of_line (str);
2032 /* Long Multiply Parser
2033 UMULL RdLo, RdHi, Rm, Rs
2034 SMULL RdLo, RdHi, Rm, Rs
2035 UMLAL RdLo, RdHi, Rm, Rs
2036 SMLAL RdLo, RdHi, Rm, Rs
2038 static void
2039 do_mull (str, flags)
2040 char * str;
2041 unsigned long flags;
2043 int rdlo, rdhi, rm, rs;
2045 /* Only one format "rdlo, rdhi, rm, rs" */
2046 skip_whitespace (str);
2048 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
2050 inst.error = BAD_ARGS;
2051 return;
2054 if (skip_past_comma (&str) == FAIL
2055 || (rdhi = reg_required_here (&str, 16)) == FAIL)
2057 inst.error = BAD_ARGS;
2058 return;
2061 if (skip_past_comma (&str) == FAIL
2062 || (rm = reg_required_here (&str, 0)) == FAIL)
2064 inst.error = BAD_ARGS;
2065 return;
2068 /* rdhi, rdlo and rm must all be different */
2069 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
2070 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2072 if (skip_past_comma (&str) == FAIL
2073 || (rs = reg_required_here (&str, 8)) == FAIL)
2075 inst.error = BAD_ARGS;
2076 return;
2079 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2081 inst.error = BAD_PC;
2082 return;
2085 inst.instruction |= flags;
2086 end_of_line (str);
2087 return;
2090 static void
2091 do_mul (str, flags)
2092 char * str;
2093 unsigned long flags;
2095 int rd, rm;
2097 /* Only one format "rd, rm, rs" */
2098 skip_whitespace (str);
2100 if ((rd = reg_required_here (&str, 16)) == FAIL)
2102 inst.error = BAD_ARGS;
2103 return;
2106 if (rd == REG_PC)
2108 inst.error = BAD_PC;
2109 return;
2112 if (skip_past_comma (&str) == FAIL
2113 || (rm = reg_required_here (&str, 0)) == FAIL)
2115 inst.error = BAD_ARGS;
2116 return;
2119 if (rm == REG_PC)
2121 inst.error = BAD_PC;
2122 return;
2125 if (rm == rd)
2126 as_tsktsk (_("rd and rm should be different in mul"));
2128 if (skip_past_comma (&str) == FAIL
2129 || (rm = reg_required_here (&str, 8)) == FAIL)
2131 inst.error = BAD_ARGS;
2132 return;
2135 if (rm == REG_PC)
2137 inst.error = BAD_PC;
2138 return;
2141 inst.instruction |= flags;
2142 end_of_line (str);
2143 return;
2146 static void
2147 do_mla (str, flags)
2148 char * str;
2149 unsigned long flags;
2151 int rd, rm;
2153 /* Only one format "rd, rm, rs, rn" */
2154 skip_whitespace (str);
2156 if ((rd = reg_required_here (&str, 16)) == FAIL)
2158 inst.error = BAD_ARGS;
2159 return;
2162 if (rd == REG_PC)
2164 inst.error = BAD_PC;
2165 return;
2168 if (skip_past_comma (&str) == FAIL
2169 || (rm = reg_required_here (&str, 0)) == FAIL)
2171 inst.error = BAD_ARGS;
2172 return;
2175 if (rm == REG_PC)
2177 inst.error = BAD_PC;
2178 return;
2181 if (rm == rd)
2182 as_tsktsk (_("rd and rm should be different in mla"));
2184 if (skip_past_comma (&str) == FAIL
2185 || (rd = reg_required_here (&str, 8)) == FAIL
2186 || skip_past_comma (&str) == FAIL
2187 || (rm = reg_required_here (&str, 12)) == FAIL)
2189 inst.error = BAD_ARGS;
2190 return;
2193 if (rd == REG_PC || rm == REG_PC)
2195 inst.error = BAD_PC;
2196 return;
2199 inst.instruction |= flags;
2200 end_of_line (str);
2201 return;
2204 /* Returns the index into fp_values of a floating point number, or -1 if
2205 not in the table. */
2206 static int
2207 my_get_float_expression (str)
2208 char ** str;
2210 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2211 char * save_in;
2212 expressionS exp;
2213 int i;
2214 int j;
2216 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
2217 /* Look for a raw floating point number */
2218 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
2219 && (is_end_of_line [(int)(*save_in)] || *save_in == '\0'))
2221 for (i = 0; i < NUM_FLOAT_VALS; i++)
2223 for (j = 0; j < MAX_LITTLENUMS; j++)
2225 if (words[j] != fp_values[i][j])
2226 break;
2229 if (j == MAX_LITTLENUMS)
2231 *str = save_in;
2232 return i;
2237 /* Try and parse a more complex expression, this will probably fail
2238 unless the code uses a floating point prefix (eg "0f") */
2239 save_in = input_line_pointer;
2240 input_line_pointer = *str;
2241 if (expression (&exp) == absolute_section
2242 && exp.X_op == O_big
2243 && exp.X_add_number < 0)
2245 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2246 Ditto for 15. */
2247 if (gen_to_words (words, 5, (long)15) == 0)
2249 for (i = 0; i < NUM_FLOAT_VALS; i++)
2251 for (j = 0; j < MAX_LITTLENUMS; j++)
2253 if (words[j] != fp_values[i][j])
2254 break;
2257 if (j == MAX_LITTLENUMS)
2259 *str = input_line_pointer;
2260 input_line_pointer = save_in;
2261 return i;
2267 *str = input_line_pointer;
2268 input_line_pointer = save_in;
2269 return -1;
2272 /* Return true if anything in the expression is a bignum */
2273 static int
2274 walk_no_bignums (sp)
2275 symbolS * sp;
2277 if (symbol_get_value_expression (sp)->X_op == O_big)
2278 return 1;
2280 if (symbol_get_value_expression (sp)->X_add_symbol)
2282 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
2283 || (symbol_get_value_expression (sp)->X_op_symbol
2284 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
2287 return 0;
2290 static int
2291 my_get_expression (ep, str)
2292 expressionS * ep;
2293 char ** str;
2295 char * save_in;
2296 segT seg;
2298 save_in = input_line_pointer;
2299 input_line_pointer = *str;
2300 seg = expression (ep);
2302 #ifdef OBJ_AOUT
2303 if (seg != absolute_section
2304 && seg != text_section
2305 && seg != data_section
2306 && seg != bss_section
2307 && seg != undefined_section)
2309 inst.error = _("bad_segment");
2310 *str = input_line_pointer;
2311 input_line_pointer = save_in;
2312 return 1;
2314 #endif
2316 /* Get rid of any bignums now, so that we don't generate an error for which
2317 we can't establish a line number later on. Big numbers are never valid
2318 in instructions, which is where this routine is always called. */
2319 if (ep->X_op == O_big
2320 || (ep->X_add_symbol
2321 && (walk_no_bignums (ep->X_add_symbol)
2322 || (ep->X_op_symbol
2323 && walk_no_bignums (ep->X_op_symbol)))))
2325 inst.error = _("Invalid constant");
2326 *str = input_line_pointer;
2327 input_line_pointer = save_in;
2328 return 1;
2331 *str = input_line_pointer;
2332 input_line_pointer = save_in;
2333 return 0;
2336 /* unrestrict should be one if <shift> <register> is permitted for this
2337 instruction */
2339 static int
2340 decode_shift (str, unrestrict)
2341 char ** str;
2342 int unrestrict;
2344 struct asm_shift * shft;
2345 char * p;
2346 char c;
2348 skip_whitespace (* str);
2350 for (p = *str; isalpha (*p); p++)
2353 if (p == *str)
2355 inst.error = _("Shift expression expected");
2356 return FAIL;
2359 c = *p;
2360 *p = '\0';
2361 shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
2362 *p = c;
2363 if (shft)
2365 if (!strncmp (*str, "rrx", 3)
2366 || !strncmp (*str, "RRX", 3))
2368 *str = p;
2369 inst.instruction |= shft->value;
2370 return SUCCESS;
2373 skip_whitespace (p);
2375 if (unrestrict && reg_required_here (&p, 8) != FAIL)
2377 inst.instruction |= shft->value | SHIFT_BY_REG;
2378 *str = p;
2379 return SUCCESS;
2381 else if (is_immediate_prefix (* p))
2383 inst.error = NULL;
2384 p++;
2385 if (my_get_expression (&inst.reloc.exp, &p))
2386 return FAIL;
2388 /* Validate some simple #expressions */
2389 if (inst.reloc.exp.X_op == O_constant)
2391 unsigned num = inst.reloc.exp.X_add_number;
2393 /* Reject operations greater than 32, or lsl #32 */
2394 if (num > 32 || (num == 32 && shft->value == 0))
2396 inst.error = _("Invalid immediate shift");
2397 return FAIL;
2400 /* Shifts of zero should be converted to lsl (which is zero)*/
2401 if (num == 0)
2403 *str = p;
2404 return SUCCESS;
2407 /* Shifts of 32 are encoded as 0, for those shifts that
2408 support it. */
2409 if (num == 32)
2410 num = 0;
2412 inst.instruction |= (num << 7) | shft->value;
2413 *str = p;
2414 return SUCCESS;
2417 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
2418 inst.reloc.pc_rel = 0;
2419 inst.instruction |= shft->value;
2420 *str = p;
2421 return SUCCESS;
2423 else
2425 inst.error = unrestrict ? _("shift requires register or #expression")
2426 : _("shift requires #expression");
2427 *str = p;
2428 return FAIL;
2432 inst.error = _("Shift expression expected");
2433 return FAIL;
2436 /* Do those data_ops which can take a negative immediate constant */
2437 /* by altering the instuction. A bit of a hack really */
2438 /* MOV <-> MVN
2439 AND <-> BIC
2440 ADC <-> SBC
2441 by inverting the second operand, and
2442 ADD <-> SUB
2443 CMP <-> CMN
2444 by negating the second operand.
2446 static int
2447 negate_data_op (instruction, value)
2448 unsigned long * instruction;
2449 unsigned long value;
2451 int op, new_inst;
2452 unsigned long negated, inverted;
2454 negated = validate_immediate (-value);
2455 inverted = validate_immediate (~value);
2457 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
2458 switch (op)
2460 /* First negates */
2461 case OPCODE_SUB: /* ADD <-> SUB */
2462 new_inst = OPCODE_ADD;
2463 value = negated;
2464 break;
2466 case OPCODE_ADD:
2467 new_inst = OPCODE_SUB;
2468 value = negated;
2469 break;
2471 case OPCODE_CMP: /* CMP <-> CMN */
2472 new_inst = OPCODE_CMN;
2473 value = negated;
2474 break;
2476 case OPCODE_CMN:
2477 new_inst = OPCODE_CMP;
2478 value = negated;
2479 break;
2481 /* Now Inverted ops */
2482 case OPCODE_MOV: /* MOV <-> MVN */
2483 new_inst = OPCODE_MVN;
2484 value = inverted;
2485 break;
2487 case OPCODE_MVN:
2488 new_inst = OPCODE_MOV;
2489 value = inverted;
2490 break;
2492 case OPCODE_AND: /* AND <-> BIC */
2493 new_inst = OPCODE_BIC;
2494 value = inverted;
2495 break;
2497 case OPCODE_BIC:
2498 new_inst = OPCODE_AND;
2499 value = inverted;
2500 break;
2502 case OPCODE_ADC: /* ADC <-> SBC */
2503 new_inst = OPCODE_SBC;
2504 value = inverted;
2505 break;
2507 case OPCODE_SBC:
2508 new_inst = OPCODE_ADC;
2509 value = inverted;
2510 break;
2512 /* We cannot do anything */
2513 default:
2514 return FAIL;
2517 if (value == (unsigned) FAIL)
2518 return FAIL;
2520 *instruction &= OPCODE_MASK;
2521 *instruction |= new_inst << DATA_OP_SHIFT;
2522 return value;
2525 static int
2526 data_op2 (str)
2527 char ** str;
2529 int value;
2530 expressionS expr;
2532 skip_whitespace (* str);
2534 if (reg_required_here (str, 0) != FAIL)
2536 if (skip_past_comma (str) == SUCCESS)
2537 /* Shift operation on register. */
2538 return decode_shift (str, NO_SHIFT_RESTRICT);
2540 return SUCCESS;
2542 else
2544 /* Immediate expression */
2545 if (is_immediate_prefix (**str))
2547 (*str)++;
2548 inst.error = NULL;
2550 if (my_get_expression (&inst.reloc.exp, str))
2551 return FAIL;
2553 if (inst.reloc.exp.X_add_symbol)
2555 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2556 inst.reloc.pc_rel = 0;
2558 else
2560 if (skip_past_comma (str) == SUCCESS)
2562 /* #x, y -- ie explicit rotation by Y */
2563 if (my_get_expression (&expr, str))
2564 return FAIL;
2566 if (expr.X_op != O_constant)
2568 inst.error = _("Constant expression expected");
2569 return FAIL;
2572 /* Rotate must be a multiple of 2 */
2573 if (((unsigned) expr.X_add_number) > 30
2574 || (expr.X_add_number & 1) != 0
2575 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
2577 inst.error = _("Invalid constant");
2578 return FAIL;
2580 inst.instruction |= INST_IMMEDIATE;
2581 inst.instruction |= inst.reloc.exp.X_add_number;
2582 inst.instruction |= expr.X_add_number << 7;
2583 return SUCCESS;
2586 /* Implicit rotation, select a suitable one */
2587 value = validate_immediate (inst.reloc.exp.X_add_number);
2589 if (value == FAIL)
2591 /* Can't be done, perhaps the code reads something like
2592 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2593 if ((value = negate_data_op (&inst.instruction,
2594 inst.reloc.exp.X_add_number))
2595 == FAIL)
2597 inst.error = _("Invalid constant");
2598 return FAIL;
2602 inst.instruction |= value;
2605 inst.instruction |= INST_IMMEDIATE;
2606 return SUCCESS;
2609 (*str)++;
2610 inst.error = _("Register or shift expression expected");
2611 return FAIL;
2615 static int
2616 fp_op2 (str)
2617 char ** str;
2619 skip_whitespace (* str);
2621 if (fp_reg_required_here (str, 0) != FAIL)
2622 return SUCCESS;
2623 else
2625 /* Immediate expression */
2626 if (*((*str)++) == '#')
2628 int i;
2630 inst.error = NULL;
2632 skip_whitespace (* str);
2634 /* First try and match exact strings, this is to guarantee that
2635 some formats will work even for cross assembly */
2637 for (i = 0; fp_const[i]; i++)
2639 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2641 char *start = *str;
2643 *str += strlen (fp_const[i]);
2644 if (is_end_of_line[(int)**str] || **str == '\0')
2646 inst.instruction |= i + 8;
2647 return SUCCESS;
2649 *str = start;
2653 /* Just because we didn't get a match doesn't mean that the
2654 constant isn't valid, just that it is in a format that we
2655 don't automatically recognize. Try parsing it with
2656 the standard expression routines. */
2657 if ((i = my_get_float_expression (str)) >= 0)
2659 inst.instruction |= i + 8;
2660 return SUCCESS;
2663 inst.error = _("Invalid floating point immediate expression");
2664 return FAIL;
2666 inst.error = _("Floating point register or immediate expression expected");
2667 return FAIL;
2671 static void
2672 do_arit (str, flags)
2673 char * str;
2674 unsigned long flags;
2676 skip_whitespace (str);
2678 if (reg_required_here (&str, 12) == FAIL
2679 || skip_past_comma (&str) == FAIL
2680 || reg_required_here (&str, 16) == FAIL
2681 || skip_past_comma (&str) == FAIL
2682 || data_op2 (&str) == FAIL)
2684 if (!inst.error)
2685 inst.error = BAD_ARGS;
2686 return;
2689 inst.instruction |= flags;
2690 end_of_line (str);
2691 return;
2694 static void
2695 do_adr (str, flags)
2696 char * str;
2697 unsigned long flags;
2699 /* This is a pseudo-op of the form "adr rd, label" to be converted
2700 into a relative address of the form "add rd, pc, #label-.-8". */
2701 skip_whitespace (str);
2703 if (reg_required_here (&str, 12) == FAIL
2704 || skip_past_comma (&str) == FAIL
2705 || my_get_expression (&inst.reloc.exp, &str))
2707 if (!inst.error)
2708 inst.error = BAD_ARGS;
2709 return;
2712 /* Frag hacking will turn this into a sub instruction if the offset turns
2713 out to be negative. */
2714 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2715 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
2716 inst.reloc.pc_rel = 1;
2717 inst.instruction |= flags;
2719 end_of_line (str);
2722 static void
2723 do_adrl (str, flags)
2724 char * str;
2725 unsigned long flags;
2727 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2728 into a relative address of the form:
2729 add rd, pc, #low(label-.-8)"
2730 add rd, rd, #high(label-.-8)" */
2732 skip_whitespace (str);
2734 if (reg_required_here (& str, 12) == FAIL
2735 || skip_past_comma (& str) == FAIL
2736 || my_get_expression (& inst.reloc.exp, & str))
2738 if (!inst.error)
2739 inst.error = BAD_ARGS;
2740 return;
2743 end_of_line (str);
2745 /* Frag hacking will turn this into a sub instruction if the offset turns
2746 out to be negative. */
2747 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
2748 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2749 inst.reloc.pc_rel = 1;
2750 inst.instruction |= flags;
2751 inst.size = INSN_SIZE * 2;
2753 return;
2756 static void
2757 do_cmp (str, flags)
2758 char * str;
2759 unsigned long flags;
2761 skip_whitespace (str);
2763 if (reg_required_here (&str, 16) == FAIL)
2765 if (!inst.error)
2766 inst.error = BAD_ARGS;
2767 return;
2770 if (skip_past_comma (&str) == FAIL
2771 || data_op2 (&str) == FAIL)
2773 if (!inst.error)
2774 inst.error = BAD_ARGS;
2775 return;
2778 inst.instruction |= flags;
2779 if ((flags & 0x0000f000) == 0)
2780 inst.instruction |= CONDS_BIT;
2782 end_of_line (str);
2783 return;
2786 static void
2787 do_mov (str, flags)
2788 char * str;
2789 unsigned long flags;
2791 skip_whitespace (str);
2793 if (reg_required_here (&str, 12) == FAIL)
2795 if (!inst.error)
2796 inst.error = BAD_ARGS;
2797 return;
2800 if (skip_past_comma (&str) == FAIL
2801 || data_op2 (&str) == FAIL)
2803 if (!inst.error)
2804 inst.error = BAD_ARGS;
2805 return;
2808 inst.instruction |= flags;
2809 end_of_line (str);
2810 return;
2813 static int
2814 ldst_extend (str, hwse)
2815 char ** str;
2816 int hwse;
2818 int add = INDEX_UP;
2820 switch (**str)
2822 case '#':
2823 case '$':
2824 (*str)++;
2825 if (my_get_expression (& inst.reloc.exp, str))
2826 return FAIL;
2828 if (inst.reloc.exp.X_op == O_constant)
2830 int value = inst.reloc.exp.X_add_number;
2832 if ((hwse && (value < -255 || value > 255))
2833 || (value < -4095 || value > 4095))
2835 inst.error = _("address offset too large");
2836 return FAIL;
2839 if (value < 0)
2841 value = -value;
2842 add = 0;
2845 /* Halfword and signextension instructions have the
2846 immediate value split across bits 11..8 and bits 3..0 */
2847 if (hwse)
2848 inst.instruction |= add | HWOFFSET_IMM | ((value >> 4) << 8) | (value & 0xF);
2849 else
2850 inst.instruction |= add | value;
2852 else
2854 if (hwse)
2856 inst.instruction |= HWOFFSET_IMM;
2857 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2859 else
2860 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2861 inst.reloc.pc_rel = 0;
2863 return SUCCESS;
2865 case '-':
2866 add = 0; /* and fall through */
2867 case '+':
2868 (*str)++; /* and fall through */
2869 default:
2870 if (reg_required_here (str, 0) == FAIL)
2871 return FAIL;
2873 if (hwse)
2874 inst.instruction |= add;
2875 else
2877 inst.instruction |= add | OFFSET_REG;
2878 if (skip_past_comma (str) == SUCCESS)
2879 return decode_shift (str, SHIFT_RESTRICT);
2882 return SUCCESS;
2886 static void
2887 do_ldst (str, flags)
2888 char * str;
2889 unsigned long flags;
2891 int halfword = 0;
2892 int pre_inc = 0;
2893 int conflict_reg;
2894 int value;
2896 /* This is not ideal, but it is the simplest way of dealing with the
2897 ARM7T halfword instructions (since they use a different
2898 encoding, but the same mnemonic): */
2899 halfword = (flags & 0x80000000) != 0;
2900 if (halfword)
2902 /* This is actually a load/store of a halfword, or a
2903 signed-extension load */
2904 if ((cpu_variant & ARM_HALFWORD) == 0)
2906 inst.error
2907 = _("Processor does not support halfwords or signed bytes");
2908 return;
2911 inst.instruction = (inst.instruction & COND_MASK)
2912 | (flags & ~COND_MASK);
2914 flags = 0;
2917 skip_whitespace (str);
2919 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
2921 if (!inst.error)
2922 inst.error = BAD_ARGS;
2923 return;
2926 if (skip_past_comma (& str) == FAIL)
2928 inst.error = _("Address expected");
2929 return;
2932 if (*str == '[')
2934 int reg;
2936 str++;
2938 skip_whitespace (str);
2940 if ((reg = reg_required_here (&str, 16)) == FAIL)
2941 return;
2943 /* Conflicts can occur on stores as well as loads. */
2944 conflict_reg = (conflict_reg == reg);
2946 skip_whitespace (str);
2948 if (*str == ']')
2950 str ++;
2952 if (skip_past_comma (&str) == SUCCESS)
2954 /* [Rn],... (post inc) */
2955 if (ldst_extend (&str, halfword) == FAIL)
2956 return;
2957 if (conflict_reg)
2958 as_warn (_("%s register same as write-back base"),
2959 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2961 else
2963 /* [Rn] */
2964 if (halfword)
2965 inst.instruction |= HWOFFSET_IMM;
2967 skip_whitespace (str);
2969 if (*str == '!')
2971 if (conflict_reg)
2972 as_warn (_("%s register same as write-back base"),
2973 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2974 str++;
2975 inst.instruction |= WRITE_BACK;
2978 flags |= INDEX_UP;
2979 if (! (flags & TRANS_BIT))
2980 pre_inc = 1;
2983 else
2985 /* [Rn,...] */
2986 if (skip_past_comma (&str) == FAIL)
2988 inst.error = _("pre-indexed expression expected");
2989 return;
2992 pre_inc = 1;
2993 if (ldst_extend (&str, halfword) == FAIL)
2994 return;
2996 skip_whitespace (str);
2998 if (*str++ != ']')
3000 inst.error = _("missing ]");
3001 return;
3004 skip_whitespace (str);
3006 if (*str == '!')
3008 if (conflict_reg)
3009 as_warn (_("%s register same as write-back base"),
3010 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
3011 str++;
3012 inst.instruction |= WRITE_BACK;
3016 else if (*str == '=')
3018 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
3019 str++;
3021 skip_whitespace (str);
3023 if (my_get_expression (&inst.reloc.exp, &str))
3024 return;
3026 if (inst.reloc.exp.X_op != O_constant
3027 && inst.reloc.exp.X_op != O_symbol)
3029 inst.error = _("Constant expression expected");
3030 return;
3033 if (inst.reloc.exp.X_op == O_constant
3034 && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
3036 /* This can be done with a mov instruction */
3037 inst.instruction &= LITERAL_MASK;
3038 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
3039 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
3040 end_of_line(str);
3041 return;
3043 else
3045 /* Insert into literal pool */
3046 if (add_to_lit_pool () == FAIL)
3048 if (!inst.error)
3049 inst.error = _("literal pool insertion failed");
3050 return;
3053 /* Change the instruction exp to point to the pool */
3054 if (halfword)
3056 inst.instruction |= HWOFFSET_IMM;
3057 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
3059 else
3060 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
3061 inst.reloc.pc_rel = 1;
3062 inst.instruction |= (REG_PC << 16);
3063 pre_inc = 1;
3066 else
3068 if (my_get_expression (&inst.reloc.exp, &str))
3069 return;
3071 if (halfword)
3073 inst.instruction |= HWOFFSET_IMM;
3074 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
3076 else
3077 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
3078 #ifndef TE_WINCE
3079 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
3080 #endif
3081 inst.reloc.pc_rel = 1;
3082 inst.instruction |= (REG_PC << 16);
3083 pre_inc = 1;
3086 if (pre_inc && (flags & TRANS_BIT))
3087 inst.error = _("Pre-increment instruction with translate");
3089 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
3090 end_of_line (str);
3091 return;
3094 static long
3095 reg_list (strp)
3096 char ** strp;
3098 char * str = *strp;
3099 long range = 0;
3100 int another_range;
3102 /* We come back here if we get ranges concatenated by '+' or '|' */
3105 another_range = 0;
3107 if (*str == '{')
3109 int in_range = 0;
3110 int cur_reg = -1;
3112 str++;
3115 int reg;
3117 skip_whitespace (str);
3119 if ((reg = reg_required_here (& str, -1)) == FAIL)
3120 return FAIL;
3122 if (in_range)
3124 int i;
3126 if (reg <= cur_reg)
3128 inst.error = _("Bad range in register list");
3129 return FAIL;
3132 for (i = cur_reg + 1; i < reg; i++)
3134 if (range & (1 << i))
3135 as_tsktsk
3136 (_("Warning: Duplicated register (r%d) in register list"),
3138 else
3139 range |= 1 << i;
3141 in_range = 0;
3144 if (range & (1 << reg))
3145 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3146 reg);
3147 else if (reg <= cur_reg)
3148 as_tsktsk (_("Warning: Register range not in ascending order"));
3150 range |= 1 << reg;
3151 cur_reg = reg;
3152 } while (skip_past_comma (&str) != FAIL
3153 || (in_range = 1, *str++ == '-'));
3154 str--;
3155 skip_whitespace (str);
3157 if (*str++ != '}')
3159 inst.error = _("Missing `}'");
3160 return FAIL;
3163 else
3165 expressionS expr;
3167 if (my_get_expression (&expr, &str))
3168 return FAIL;
3170 if (expr.X_op == O_constant)
3172 if (expr.X_add_number
3173 != (expr.X_add_number & 0x0000ffff))
3175 inst.error = _("invalid register mask");
3176 return FAIL;
3179 if ((range & expr.X_add_number) != 0)
3181 int regno = range & expr.X_add_number;
3183 regno &= -regno;
3184 regno = (1 << regno) - 1;
3185 as_tsktsk
3186 (_("Warning: Duplicated register (r%d) in register list"),
3187 regno);
3190 range |= expr.X_add_number;
3192 else
3194 if (inst.reloc.type != 0)
3196 inst.error = _("expression too complex");
3197 return FAIL;
3200 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
3201 inst.reloc.type = BFD_RELOC_ARM_MULTI;
3202 inst.reloc.pc_rel = 0;
3206 skip_whitespace (str);
3208 if (*str == '|' || *str == '+')
3210 str++;
3211 another_range = 1;
3213 } while (another_range);
3215 *strp = str;
3216 return range;
3219 static void
3220 do_ldmstm (str, flags)
3221 char * str;
3222 unsigned long flags;
3224 int base_reg;
3225 long range;
3227 skip_whitespace (str);
3229 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
3230 return;
3232 if (base_reg == REG_PC)
3234 inst.error = _("r15 not allowed as base register");
3235 return;
3238 skip_whitespace (str);
3240 if (*str == '!')
3242 flags |= WRITE_BACK;
3243 str++;
3246 if (skip_past_comma (&str) == FAIL
3247 || (range = reg_list (&str)) == FAIL)
3249 if (! inst.error)
3250 inst.error = BAD_ARGS;
3251 return;
3254 if (*str == '^')
3256 str++;
3257 flags |= LDM_TYPE_2_OR_3;
3260 inst.instruction |= flags | range;
3261 end_of_line (str);
3262 return;
3265 static void
3266 do_swi (str, flags)
3267 char * str;
3268 unsigned long flags;
3270 skip_whitespace (str);
3272 /* Allow optional leading '#'. */
3273 if (is_immediate_prefix (*str))
3274 str++;
3276 if (my_get_expression (& inst.reloc.exp, & str))
3277 return;
3279 inst.reloc.type = BFD_RELOC_ARM_SWI;
3280 inst.reloc.pc_rel = 0;
3281 inst.instruction |= flags;
3283 end_of_line (str);
3285 return;
3288 static void
3289 do_swap (str, flags)
3290 char * str;
3291 unsigned long flags;
3293 int reg;
3295 skip_whitespace (str);
3297 if ((reg = reg_required_here (&str, 12)) == FAIL)
3298 return;
3300 if (reg == REG_PC)
3302 inst.error = _("r15 not allowed in swap");
3303 return;
3306 if (skip_past_comma (&str) == FAIL
3307 || (reg = reg_required_here (&str, 0)) == FAIL)
3309 if (!inst.error)
3310 inst.error = BAD_ARGS;
3311 return;
3314 if (reg == REG_PC)
3316 inst.error = _("r15 not allowed in swap");
3317 return;
3320 if (skip_past_comma (&str) == FAIL
3321 || *str++ != '[')
3323 inst.error = BAD_ARGS;
3324 return;
3327 skip_whitespace (str);
3329 if ((reg = reg_required_here (&str, 16)) == FAIL)
3330 return;
3332 if (reg == REG_PC)
3334 inst.error = BAD_PC;
3335 return;
3338 skip_whitespace (str);
3340 if (*str++ != ']')
3342 inst.error = _("missing ]");
3343 return;
3346 inst.instruction |= flags;
3347 end_of_line (str);
3348 return;
3351 static void
3352 do_branch (str, flags)
3353 char * str;
3354 unsigned long flags ATTRIBUTE_UNUSED;
3356 if (my_get_expression (&inst.reloc.exp, &str))
3357 return;
3359 #ifdef OBJ_ELF
3361 char * save_in;
3363 /* ScottB: February 5, 1998 */
3364 /* Check to see of PLT32 reloc required for the instruction. */
3366 /* arm_parse_reloc() works on input_line_pointer.
3367 We actually want to parse the operands to the branch instruction
3368 passed in 'str'. Save the input pointer and restore it later. */
3369 save_in = input_line_pointer;
3370 input_line_pointer = str;
3371 if (inst.reloc.exp.X_op == O_symbol
3372 && *str == '('
3373 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3375 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3376 inst.reloc.pc_rel = 0;
3377 /* Modify str to point to after parsed operands, otherwise
3378 end_of_line() will complain about the (PLT) left in str. */
3379 str = input_line_pointer;
3381 else
3383 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3384 inst.reloc.pc_rel = 1;
3386 input_line_pointer = save_in;
3388 #else
3389 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3390 inst.reloc.pc_rel = 1;
3391 #endif /* OBJ_ELF */
3393 end_of_line (str);
3394 return;
3397 static void
3398 do_bx (str, flags)
3399 char * str;
3400 unsigned long flags ATTRIBUTE_UNUSED;
3402 int reg;
3404 skip_whitespace (str);
3406 if ((reg = reg_required_here (&str, 0)) == FAIL)
3408 inst.error = BAD_ARGS;
3409 return;
3412 if (reg == REG_PC)
3413 inst.error = BAD_PC;
3415 end_of_line (str);
3418 static void
3419 do_cdp (str, flags)
3420 char * str;
3421 unsigned long flags ATTRIBUTE_UNUSED;
3423 /* Co-processor data operation.
3424 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3425 skip_whitespace (str);
3427 if (co_proc_number (&str) == FAIL)
3429 if (!inst.error)
3430 inst.error = BAD_ARGS;
3431 return;
3434 if (skip_past_comma (&str) == FAIL
3435 || cp_opc_expr (&str, 20,4) == FAIL)
3437 if (!inst.error)
3438 inst.error = BAD_ARGS;
3439 return;
3442 if (skip_past_comma (&str) == FAIL
3443 || cp_reg_required_here (&str, 12) == FAIL)
3445 if (!inst.error)
3446 inst.error = BAD_ARGS;
3447 return;
3450 if (skip_past_comma (&str) == FAIL
3451 || cp_reg_required_here (&str, 16) == FAIL)
3453 if (!inst.error)
3454 inst.error = BAD_ARGS;
3455 return;
3458 if (skip_past_comma (&str) == FAIL
3459 || cp_reg_required_here (&str, 0) == FAIL)
3461 if (!inst.error)
3462 inst.error = BAD_ARGS;
3463 return;
3466 if (skip_past_comma (&str) == SUCCESS)
3468 if (cp_opc_expr (&str, 5, 3) == FAIL)
3470 if (!inst.error)
3471 inst.error = BAD_ARGS;
3472 return;
3476 end_of_line (str);
3477 return;
3480 static void
3481 do_lstc (str, flags)
3482 char * str;
3483 unsigned long flags;
3485 /* Co-processor register load/store.
3486 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3488 skip_whitespace (str);
3490 if (co_proc_number (&str) == FAIL)
3492 if (!inst.error)
3493 inst.error = BAD_ARGS;
3494 return;
3497 if (skip_past_comma (&str) == FAIL
3498 || cp_reg_required_here (&str, 12) == FAIL)
3500 if (!inst.error)
3501 inst.error = BAD_ARGS;
3502 return;
3505 if (skip_past_comma (&str) == FAIL
3506 || cp_address_required_here (&str) == FAIL)
3508 if (! inst.error)
3509 inst.error = BAD_ARGS;
3510 return;
3513 inst.instruction |= flags;
3514 end_of_line (str);
3515 return;
3518 static void
3519 do_co_reg (str, flags)
3520 char * str;
3521 unsigned long flags;
3523 /* Co-processor register transfer.
3524 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3526 skip_whitespace (str);
3528 if (co_proc_number (&str) == FAIL)
3530 if (!inst.error)
3531 inst.error = BAD_ARGS;
3532 return;
3535 if (skip_past_comma (&str) == FAIL
3536 || cp_opc_expr (&str, 21, 3) == FAIL)
3538 if (!inst.error)
3539 inst.error = BAD_ARGS;
3540 return;
3543 if (skip_past_comma (&str) == FAIL
3544 || reg_required_here (&str, 12) == FAIL)
3546 if (!inst.error)
3547 inst.error = BAD_ARGS;
3548 return;
3551 if (skip_past_comma (&str) == FAIL
3552 || cp_reg_required_here (&str, 16) == FAIL)
3554 if (!inst.error)
3555 inst.error = BAD_ARGS;
3556 return;
3559 if (skip_past_comma (&str) == FAIL
3560 || cp_reg_required_here (&str, 0) == FAIL)
3562 if (!inst.error)
3563 inst.error = BAD_ARGS;
3564 return;
3567 if (skip_past_comma (&str) == SUCCESS)
3569 if (cp_opc_expr (&str, 5, 3) == FAIL)
3571 if (!inst.error)
3572 inst.error = BAD_ARGS;
3573 return;
3576 if (flags)
3578 inst.error = BAD_COND;
3581 end_of_line (str);
3582 return;
3585 static void
3586 do_fp_ctrl (str, flags)
3587 char * str;
3588 unsigned long flags ATTRIBUTE_UNUSED;
3590 /* FP control registers.
3591 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3593 skip_whitespace (str);
3595 if (reg_required_here (&str, 12) == FAIL)
3597 if (!inst.error)
3598 inst.error = BAD_ARGS;
3599 return;
3602 end_of_line (str);
3603 return;
3606 static void
3607 do_fp_ldst (str, flags)
3608 char * str;
3609 unsigned long flags ATTRIBUTE_UNUSED;
3611 skip_whitespace (str);
3613 switch (inst.suffix)
3615 case SUFF_S:
3616 break;
3617 case SUFF_D:
3618 inst.instruction |= CP_T_X;
3619 break;
3620 case SUFF_E:
3621 inst.instruction |= CP_T_Y;
3622 break;
3623 case SUFF_P:
3624 inst.instruction |= CP_T_X | CP_T_Y;
3625 break;
3626 default:
3627 abort ();
3630 if (fp_reg_required_here (&str, 12) == FAIL)
3632 if (!inst.error)
3633 inst.error = BAD_ARGS;
3634 return;
3637 if (skip_past_comma (&str) == FAIL
3638 || cp_address_required_here (&str) == FAIL)
3640 if (!inst.error)
3641 inst.error = BAD_ARGS;
3642 return;
3645 end_of_line (str);
3648 static void
3649 do_fp_ldmstm (str, flags)
3650 char * str;
3651 unsigned long flags;
3653 int num_regs;
3655 skip_whitespace (str);
3657 if (fp_reg_required_here (&str, 12) == FAIL)
3659 if (! inst.error)
3660 inst.error = BAD_ARGS;
3661 return;
3664 /* Get Number of registers to transfer */
3665 if (skip_past_comma (&str) == FAIL
3666 || my_get_expression (&inst.reloc.exp, &str))
3668 if (! inst.error)
3669 inst.error = _("constant expression expected");
3670 return;
3673 if (inst.reloc.exp.X_op != O_constant)
3675 inst.error = _("Constant value required for number of registers");
3676 return;
3679 num_regs = inst.reloc.exp.X_add_number;
3681 if (num_regs < 1 || num_regs > 4)
3683 inst.error = _("number of registers must be in the range [1:4]");
3684 return;
3687 switch (num_regs)
3689 case 1:
3690 inst.instruction |= CP_T_X;
3691 break;
3692 case 2:
3693 inst.instruction |= CP_T_Y;
3694 break;
3695 case 3:
3696 inst.instruction |= CP_T_Y | CP_T_X;
3697 break;
3698 case 4:
3699 break;
3700 default:
3701 abort ();
3704 if (flags)
3706 int reg;
3707 int write_back;
3708 int offset;
3710 /* The instruction specified "ea" or "fd", so we can only accept
3711 [Rn]{!}. The instruction does not really support stacking or
3712 unstacking, so we have to emulate these by setting appropriate
3713 bits and offsets. */
3714 if (skip_past_comma (&str) == FAIL
3715 || *str != '[')
3717 if (! inst.error)
3718 inst.error = BAD_ARGS;
3719 return;
3722 str++;
3723 skip_whitespace (str);
3725 if ((reg = reg_required_here (&str, 16)) == FAIL)
3726 return;
3728 skip_whitespace (str);
3730 if (*str != ']')
3732 inst.error = BAD_ARGS;
3733 return;
3736 str++;
3737 if (*str == '!')
3739 write_back = 1;
3740 str++;
3741 if (reg == REG_PC)
3743 inst.error = _("R15 not allowed as base register with write-back");
3744 return;
3747 else
3748 write_back = 0;
3750 if (flags & CP_T_Pre)
3752 /* Pre-decrement */
3753 offset = 3 * num_regs;
3754 if (write_back)
3755 flags |= CP_T_WB;
3757 else
3759 /* Post-increment */
3760 if (write_back)
3762 flags |= CP_T_WB;
3763 offset = 3 * num_regs;
3765 else
3767 /* No write-back, so convert this into a standard pre-increment
3768 instruction -- aesthetically more pleasing. */
3769 flags = CP_T_Pre | CP_T_UD;
3770 offset = 0;
3774 inst.instruction |= flags | offset;
3776 else if (skip_past_comma (&str) == FAIL
3777 || cp_address_required_here (&str) == FAIL)
3779 if (! inst.error)
3780 inst.error = BAD_ARGS;
3781 return;
3784 end_of_line (str);
3787 static void
3788 do_fp_dyadic (str, flags)
3789 char * str;
3790 unsigned long flags;
3792 skip_whitespace (str);
3794 switch (inst.suffix)
3796 case SUFF_S:
3797 break;
3798 case SUFF_D:
3799 inst.instruction |= 0x00000080;
3800 break;
3801 case SUFF_E:
3802 inst.instruction |= 0x00080000;
3803 break;
3804 default:
3805 abort ();
3808 if (fp_reg_required_here (&str, 12) == FAIL)
3810 if (! inst.error)
3811 inst.error = BAD_ARGS;
3812 return;
3815 if (skip_past_comma (&str) == FAIL
3816 || fp_reg_required_here (&str, 16) == FAIL)
3818 if (! inst.error)
3819 inst.error = BAD_ARGS;
3820 return;
3823 if (skip_past_comma (&str) == FAIL
3824 || fp_op2 (&str) == FAIL)
3826 if (! inst.error)
3827 inst.error = BAD_ARGS;
3828 return;
3831 inst.instruction |= flags;
3832 end_of_line (str);
3833 return;
3836 static void
3837 do_fp_monadic (str, flags)
3838 char * str;
3839 unsigned long flags;
3841 skip_whitespace (str);
3843 switch (inst.suffix)
3845 case SUFF_S:
3846 break;
3847 case SUFF_D:
3848 inst.instruction |= 0x00000080;
3849 break;
3850 case SUFF_E:
3851 inst.instruction |= 0x00080000;
3852 break;
3853 default:
3854 abort ();
3857 if (fp_reg_required_here (&str, 12) == FAIL)
3859 if (! inst.error)
3860 inst.error = BAD_ARGS;
3861 return;
3864 if (skip_past_comma (&str) == FAIL
3865 || fp_op2 (&str) == FAIL)
3867 if (! inst.error)
3868 inst.error = BAD_ARGS;
3869 return;
3872 inst.instruction |= flags;
3873 end_of_line (str);
3874 return;
3877 static void
3878 do_fp_cmp (str, flags)
3879 char * str;
3880 unsigned long flags;
3882 skip_whitespace (str);
3884 if (fp_reg_required_here (&str, 16) == FAIL)
3886 if (! inst.error)
3887 inst.error = BAD_ARGS;
3888 return;
3891 if (skip_past_comma (&str) == FAIL
3892 || fp_op2 (&str) == FAIL)
3894 if (! inst.error)
3895 inst.error = BAD_ARGS;
3896 return;
3899 inst.instruction |= flags;
3900 end_of_line (str);
3901 return;
3904 static void
3905 do_fp_from_reg (str, flags)
3906 char * str;
3907 unsigned long flags;
3909 skip_whitespace (str);
3911 switch (inst.suffix)
3913 case SUFF_S:
3914 break;
3915 case SUFF_D:
3916 inst.instruction |= 0x00000080;
3917 break;
3918 case SUFF_E:
3919 inst.instruction |= 0x00080000;
3920 break;
3921 default:
3922 abort ();
3925 if (fp_reg_required_here (&str, 16) == FAIL)
3927 if (! inst.error)
3928 inst.error = BAD_ARGS;
3929 return;
3932 if (skip_past_comma (&str) == FAIL
3933 || reg_required_here (&str, 12) == FAIL)
3935 if (! inst.error)
3936 inst.error = BAD_ARGS;
3937 return;
3940 inst.instruction |= flags;
3941 end_of_line (str);
3942 return;
3945 static void
3946 do_fp_to_reg (str, flags)
3947 char * str;
3948 unsigned long flags;
3950 skip_whitespace (str);
3952 if (reg_required_here (&str, 12) == FAIL)
3953 return;
3955 if (skip_past_comma (&str) == FAIL
3956 || fp_reg_required_here (&str, 0) == FAIL)
3958 if (! inst.error)
3959 inst.error = BAD_ARGS;
3960 return;
3963 inst.instruction |= flags;
3964 end_of_line (str);
3965 return;
3968 /* Thumb specific routines */
3970 /* Parse and validate that a register is of the right form, this saves
3971 repeated checking of this information in many similar cases.
3972 Unlike the 32-bit case we do not insert the register into the opcode
3973 here, since the position is often unknown until the full instruction
3974 has been parsed. */
3975 static int
3976 thumb_reg (strp, hi_lo)
3977 char ** strp;
3978 int hi_lo;
3980 int reg;
3982 if ((reg = reg_required_here (strp, -1)) == FAIL)
3983 return FAIL;
3985 switch (hi_lo)
3987 case THUMB_REG_LO:
3988 if (reg > 7)
3990 inst.error = _("lo register required");
3991 return FAIL;
3993 break;
3995 case THUMB_REG_HI:
3996 if (reg < 8)
3998 inst.error = _("hi register required");
3999 return FAIL;
4001 break;
4003 default:
4004 break;
4007 return reg;
4010 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4011 was SUB. */
4012 static void
4013 thumb_add_sub (str, subtract)
4014 char * str;
4015 int subtract;
4017 int Rd, Rs, Rn = FAIL;
4019 skip_whitespace (str);
4021 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4022 || skip_past_comma (&str) == FAIL)
4024 if (! inst.error)
4025 inst.error = BAD_ARGS;
4026 return;
4029 if (is_immediate_prefix (*str))
4031 Rs = Rd;
4032 str++;
4033 if (my_get_expression (&inst.reloc.exp, &str))
4034 return;
4036 else
4038 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4039 return;
4041 if (skip_past_comma (&str) == FAIL)
4043 /* Two operand format, shuffle the registers and pretend there
4044 are 3 */
4045 Rn = Rs;
4046 Rs = Rd;
4048 else if (is_immediate_prefix (*str))
4050 str++;
4051 if (my_get_expression (&inst.reloc.exp, &str))
4052 return;
4054 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4055 return;
4058 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4059 for the latter case, EXPR contains the immediate that was found. */
4060 if (Rn != FAIL)
4062 /* All register format. */
4063 if (Rd > 7 || Rs > 7 || Rn > 7)
4065 if (Rs != Rd)
4067 inst.error = _("dest and source1 must be the same register");
4068 return;
4071 /* Can't do this for SUB */
4072 if (subtract)
4074 inst.error = _("subtract valid only on lo regs");
4075 return;
4078 inst.instruction = (T_OPCODE_ADD_HI
4079 | (Rd > 7 ? THUMB_H1 : 0)
4080 | (Rn > 7 ? THUMB_H2 : 0));
4081 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
4083 else
4085 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
4086 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
4089 else
4091 /* Immediate expression, now things start to get nasty. */
4093 /* First deal with HI regs, only very restricted cases allowed:
4094 Adjusting SP, and using PC or SP to get an address. */
4095 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
4096 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
4098 inst.error = _("invalid Hi register with immediate");
4099 return;
4102 if (inst.reloc.exp.X_op != O_constant)
4104 /* Value isn't known yet, all we can do is store all the fragments
4105 we know about in the instruction and let the reloc hacking
4106 work it all out. */
4107 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
4108 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4110 else
4112 int offset = inst.reloc.exp.X_add_number;
4114 if (subtract)
4115 offset = -offset;
4117 if (offset < 0)
4119 offset = -offset;
4120 subtract = 1;
4122 /* Quick check, in case offset is MIN_INT */
4123 if (offset < 0)
4125 inst.error = _("immediate value out of range");
4126 return;
4129 else
4130 subtract = 0;
4132 if (Rd == REG_SP)
4134 if (offset & ~0x1fc)
4136 inst.error = _("invalid immediate value for stack adjust");
4137 return;
4139 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
4140 inst.instruction |= offset >> 2;
4142 else if (Rs == REG_PC || Rs == REG_SP)
4144 if (subtract
4145 || (offset & ~0x3fc))
4147 inst.error = _("invalid immediate for address calculation");
4148 return;
4150 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
4151 : T_OPCODE_ADD_SP);
4152 inst.instruction |= (Rd << 8) | (offset >> 2);
4154 else if (Rs == Rd)
4156 if (offset & ~0xff)
4158 inst.error = _("immediate value out of range");
4159 return;
4161 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
4162 inst.instruction |= (Rd << 8) | offset;
4164 else
4166 if (offset & ~0x7)
4168 inst.error = _("immediate value out of range");
4169 return;
4171 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
4172 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
4177 end_of_line (str);
4180 static void
4181 thumb_shift (str, shift)
4182 char * str;
4183 int shift;
4185 int Rd, Rs, Rn = FAIL;
4187 skip_whitespace (str);
4189 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4190 || skip_past_comma (&str) == FAIL)
4192 if (! inst.error)
4193 inst.error = BAD_ARGS;
4194 return;
4197 if (is_immediate_prefix (*str))
4199 /* Two operand immediate format, set Rs to Rd. */
4200 Rs = Rd;
4201 str ++;
4202 if (my_get_expression (&inst.reloc.exp, &str))
4203 return;
4205 else
4207 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4208 return;
4210 if (skip_past_comma (&str) == FAIL)
4212 /* Two operand format, shuffle the registers and pretend there
4213 are 3 */
4214 Rn = Rs;
4215 Rs = Rd;
4217 else if (is_immediate_prefix (*str))
4219 str++;
4220 if (my_get_expression (&inst.reloc.exp, &str))
4221 return;
4223 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4224 return;
4227 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4228 for the latter case, EXPR contains the immediate that was found. */
4230 if (Rn != FAIL)
4232 if (Rs != Rd)
4234 inst.error = _("source1 and dest must be same register");
4235 return;
4238 switch (shift)
4240 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
4241 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
4242 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
4245 inst.instruction |= Rd | (Rn << 3);
4247 else
4249 switch (shift)
4251 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
4252 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
4253 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
4256 if (inst.reloc.exp.X_op != O_constant)
4258 /* Value isn't known yet, create a dummy reloc and let reloc
4259 hacking fix it up */
4261 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
4263 else
4265 unsigned shift_value = inst.reloc.exp.X_add_number;
4267 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
4269 inst.error = _("Invalid immediate for shift");
4270 return;
4273 /* Shifts of zero are handled by converting to LSL */
4274 if (shift_value == 0)
4275 inst.instruction = T_OPCODE_LSL_I;
4277 /* Shifts of 32 are encoded as a shift of zero */
4278 if (shift_value == 32)
4279 shift_value = 0;
4281 inst.instruction |= shift_value << 6;
4284 inst.instruction |= Rd | (Rs << 3);
4287 end_of_line (str);
4290 static void
4291 thumb_mov_compare (str, move)
4292 char * str;
4293 int move;
4295 int Rd, Rs = FAIL;
4297 skip_whitespace (str);
4299 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4300 || skip_past_comma (&str) == FAIL)
4302 if (! inst.error)
4303 inst.error = BAD_ARGS;
4304 return;
4307 if (is_immediate_prefix (*str))
4309 str++;
4310 if (my_get_expression (&inst.reloc.exp, &str))
4311 return;
4313 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4314 return;
4316 if (Rs != FAIL)
4318 if (Rs < 8 && Rd < 8)
4320 if (move == THUMB_MOVE)
4321 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4322 since a MOV instruction produces unpredictable results */
4323 inst.instruction = T_OPCODE_ADD_I3;
4324 else
4325 inst.instruction = T_OPCODE_CMP_LR;
4326 inst.instruction |= Rd | (Rs << 3);
4328 else
4330 if (move == THUMB_MOVE)
4331 inst.instruction = T_OPCODE_MOV_HR;
4332 else
4333 inst.instruction = T_OPCODE_CMP_HR;
4335 if (Rd > 7)
4336 inst.instruction |= THUMB_H1;
4338 if (Rs > 7)
4339 inst.instruction |= THUMB_H2;
4341 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4344 else
4346 if (Rd > 7)
4348 inst.error = _("only lo regs allowed with immediate");
4349 return;
4352 if (move == THUMB_MOVE)
4353 inst.instruction = T_OPCODE_MOV_I8;
4354 else
4355 inst.instruction = T_OPCODE_CMP_I8;
4357 inst.instruction |= Rd << 8;
4359 if (inst.reloc.exp.X_op != O_constant)
4360 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4361 else
4363 unsigned value = inst.reloc.exp.X_add_number;
4365 if (value > 255)
4367 inst.error = _("invalid immediate");
4368 return;
4371 inst.instruction |= value;
4375 end_of_line (str);
4378 static void
4379 thumb_load_store (str, load_store, size)
4380 char * str;
4381 int load_store;
4382 int size;
4384 int Rd, Rb, Ro = FAIL;
4386 skip_whitespace (str);
4388 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4389 || skip_past_comma (&str) == FAIL)
4391 if (! inst.error)
4392 inst.error = BAD_ARGS;
4393 return;
4396 if (*str == '[')
4398 str++;
4399 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4400 return;
4402 if (skip_past_comma (&str) != FAIL)
4404 if (is_immediate_prefix (*str))
4406 str++;
4407 if (my_get_expression (&inst.reloc.exp, &str))
4408 return;
4410 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4411 return;
4413 else
4415 inst.reloc.exp.X_op = O_constant;
4416 inst.reloc.exp.X_add_number = 0;
4419 if (*str != ']')
4421 inst.error = _("expected ']'");
4422 return;
4424 str++;
4426 else if (*str == '=')
4428 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4429 str++;
4431 skip_whitespace (str);
4433 if (my_get_expression (& inst.reloc.exp, & str))
4434 return;
4436 end_of_line (str);
4438 if ( inst.reloc.exp.X_op != O_constant
4439 && inst.reloc.exp.X_op != O_symbol)
4441 inst.error = "Constant expression expected";
4442 return;
4445 if (inst.reloc.exp.X_op == O_constant
4446 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
4448 /* This can be done with a mov instruction */
4450 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
4451 inst.instruction |= inst.reloc.exp.X_add_number;
4452 return;
4455 /* Insert into literal pool */
4456 if (add_to_lit_pool () == FAIL)
4458 if (!inst.error)
4459 inst.error = "literal pool insertion failed";
4460 return;
4463 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4464 inst.reloc.pc_rel = 1;
4465 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4466 inst.reloc.exp.X_add_number += 4; /* Adjust ARM pipeline offset to Thumb */
4468 return;
4470 else
4472 if (my_get_expression (&inst.reloc.exp, &str))
4473 return;
4475 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4476 inst.reloc.pc_rel = 1;
4477 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
4478 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4479 end_of_line (str);
4480 return;
4483 if (Rb == REG_PC || Rb == REG_SP)
4485 if (size != THUMB_WORD)
4487 inst.error = _("byte or halfword not valid for base register");
4488 return;
4490 else if (Rb == REG_PC && load_store != THUMB_LOAD)
4492 inst.error = _("R15 based store not allowed");
4493 return;
4495 else if (Ro != FAIL)
4497 inst.error = _("Invalid base register for register offset");
4498 return;
4501 if (Rb == REG_PC)
4502 inst.instruction = T_OPCODE_LDR_PC;
4503 else if (load_store == THUMB_LOAD)
4504 inst.instruction = T_OPCODE_LDR_SP;
4505 else
4506 inst.instruction = T_OPCODE_STR_SP;
4508 inst.instruction |= Rd << 8;
4509 if (inst.reloc.exp.X_op == O_constant)
4511 unsigned offset = inst.reloc.exp.X_add_number;
4513 if (offset & ~0x3fc)
4515 inst.error = _("invalid offset");
4516 return;
4519 inst.instruction |= offset >> 2;
4521 else
4522 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4524 else if (Rb > 7)
4526 inst.error = _("invalid base register in load/store");
4527 return;
4529 else if (Ro == FAIL)
4531 /* Immediate offset */
4532 if (size == THUMB_WORD)
4533 inst.instruction = (load_store == THUMB_LOAD
4534 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
4535 else if (size == THUMB_HALFWORD)
4536 inst.instruction = (load_store == THUMB_LOAD
4537 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
4538 else
4539 inst.instruction = (load_store == THUMB_LOAD
4540 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
4542 inst.instruction |= Rd | (Rb << 3);
4544 if (inst.reloc.exp.X_op == O_constant)
4546 unsigned offset = inst.reloc.exp.X_add_number;
4548 if (offset & ~(0x1f << size))
4550 inst.error = _("Invalid offset");
4551 return;
4553 inst.instruction |= (offset >> size) << 6;
4555 else
4556 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4558 else
4560 /* Register offset */
4561 if (size == THUMB_WORD)
4562 inst.instruction = (load_store == THUMB_LOAD
4563 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
4564 else if (size == THUMB_HALFWORD)
4565 inst.instruction = (load_store == THUMB_LOAD
4566 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
4567 else
4568 inst.instruction = (load_store == THUMB_LOAD
4569 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
4571 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4574 end_of_line (str);
4577 static void
4578 do_t_nop (str)
4579 char * str;
4581 /* Do nothing */
4582 end_of_line (str);
4583 return;
4586 /* Handle the Format 4 instructions that do not have equivalents in other
4587 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4588 BIC and MVN. */
4589 static void
4590 do_t_arit (str)
4591 char * str;
4593 int Rd, Rs, Rn;
4595 skip_whitespace (str);
4597 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4598 || skip_past_comma (&str) == FAIL
4599 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4601 inst.error = BAD_ARGS;
4602 return;
4605 if (skip_past_comma (&str) != FAIL)
4607 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4608 (It isn't allowed for CMP either, but that isn't handled by this
4609 function.) */
4610 if (inst.instruction == T_OPCODE_TST
4611 || inst.instruction == T_OPCODE_CMN
4612 || inst.instruction == T_OPCODE_NEG
4613 || inst.instruction == T_OPCODE_MVN)
4615 inst.error = BAD_ARGS;
4616 return;
4619 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4620 return;
4622 if (Rs != Rd)
4624 inst.error = _("dest and source1 one must be the same register");
4625 return;
4627 Rs = Rn;
4630 if (inst.instruction == T_OPCODE_MUL
4631 && Rs == Rd)
4632 as_tsktsk (_("Rs and Rd must be different in MUL"));
4634 inst.instruction |= Rd | (Rs << 3);
4635 end_of_line (str);
4638 static void
4639 do_t_add (str)
4640 char * str;
4642 thumb_add_sub (str, 0);
4645 static void
4646 do_t_asr (str)
4647 char * str;
4649 thumb_shift (str, THUMB_ASR);
4652 static void
4653 do_t_branch9 (str)
4654 char * str;
4656 if (my_get_expression (&inst.reloc.exp, &str))
4657 return;
4658 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
4659 inst.reloc.pc_rel = 1;
4660 end_of_line (str);
4663 static void
4664 do_t_branch12 (str)
4665 char * str;
4667 if (my_get_expression (&inst.reloc.exp, &str))
4668 return;
4669 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
4670 inst.reloc.pc_rel = 1;
4671 end_of_line (str);
4674 /* Find the real, Thumb encoded start of a Thumb function. */
4676 static symbolS *
4677 find_real_start (symbolP)
4678 symbolS * symbolP;
4680 char * real_start;
4681 const char * name = S_GET_NAME (symbolP);
4682 symbolS * new_target;
4684 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4685 #define STUB_NAME ".real_start_of"
4687 if (name == NULL)
4688 abort();
4690 /* Names that start with '.' are local labels, not function entry points.
4691 The compiler may generate BL instructions to these labels because it
4692 needs to perform a branch to a far away location. */
4693 if (name[0] == '.')
4694 return symbolP;
4696 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
4697 sprintf (real_start, "%s%s", STUB_NAME, name);
4699 new_target = symbol_find (real_start);
4701 if (new_target == NULL)
4703 as_warn ("Failed to find real start of function: %s\n", name);
4704 new_target = symbolP;
4707 free (real_start);
4709 return new_target;
4713 static void
4714 do_t_branch23 (str)
4715 char * str;
4717 if (my_get_expression (& inst.reloc.exp, & str))
4718 return;
4720 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
4721 inst.reloc.pc_rel = 1;
4722 end_of_line (str);
4724 /* If the destination of the branch is a defined symbol which does not have
4725 the THUMB_FUNC attribute, then we must be calling a function which has
4726 the (interfacearm) attribute. We look for the Thumb entry point to that
4727 function and change the branch to refer to that function instead. */
4728 if ( inst.reloc.exp.X_op == O_symbol
4729 && inst.reloc.exp.X_add_symbol != NULL
4730 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
4731 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
4732 inst.reloc.exp.X_add_symbol = find_real_start (inst.reloc.exp.X_add_symbol);
4735 static void
4736 do_t_bx (str)
4737 char * str;
4739 int reg;
4741 skip_whitespace (str);
4743 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4744 return;
4746 /* This sets THUMB_H2 from the top bit of reg. */
4747 inst.instruction |= reg << 3;
4749 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4750 should cause the alignment to be checked once it is known. This is
4751 because BX PC only works if the instruction is word aligned. */
4753 end_of_line (str);
4756 static void
4757 do_t_compare (str)
4758 char * str;
4760 thumb_mov_compare (str, THUMB_COMPARE);
4763 static void
4764 do_t_ldmstm (str)
4765 char * str;
4767 int Rb;
4768 long range;
4770 skip_whitespace (str);
4772 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4773 return;
4775 if (*str != '!')
4776 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4777 else
4778 str++;
4780 if (skip_past_comma (&str) == FAIL
4781 || (range = reg_list (&str)) == FAIL)
4783 if (! inst.error)
4784 inst.error = BAD_ARGS;
4785 return;
4788 if (inst.reloc.type != BFD_RELOC_NONE)
4790 /* This really doesn't seem worth it. */
4791 inst.reloc.type = BFD_RELOC_NONE;
4792 inst.error = _("Expression too complex");
4793 return;
4796 if (range & ~0xff)
4798 inst.error = _("only lo-regs valid in load/store multiple");
4799 return;
4802 inst.instruction |= (Rb << 8) | range;
4803 end_of_line (str);
4806 static void
4807 do_t_ldr (str)
4808 char * str;
4810 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4813 static void
4814 do_t_ldrb (str)
4815 char * str;
4817 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4820 static void
4821 do_t_ldrh (str)
4822 char * str;
4824 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4827 static void
4828 do_t_lds (str)
4829 char * str;
4831 int Rd, Rb, Ro;
4833 skip_whitespace (str);
4835 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4836 || skip_past_comma (&str) == FAIL
4837 || *str++ != '['
4838 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4839 || skip_past_comma (&str) == FAIL
4840 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4841 || *str++ != ']')
4843 if (! inst.error)
4844 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4845 return;
4848 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4849 end_of_line (str);
4852 static void
4853 do_t_lsl (str)
4854 char * str;
4856 thumb_shift (str, THUMB_LSL);
4859 static void
4860 do_t_lsr (str)
4861 char * str;
4863 thumb_shift (str, THUMB_LSR);
4866 static void
4867 do_t_mov (str)
4868 char * str;
4870 thumb_mov_compare (str, THUMB_MOVE);
4873 static void
4874 do_t_push_pop (str)
4875 char * str;
4877 long range;
4879 skip_whitespace (str);
4881 if ((range = reg_list (&str)) == FAIL)
4883 if (! inst.error)
4884 inst.error = BAD_ARGS;
4885 return;
4888 if (inst.reloc.type != BFD_RELOC_NONE)
4890 /* This really doesn't seem worth it. */
4891 inst.reloc.type = BFD_RELOC_NONE;
4892 inst.error = _("Expression too complex");
4893 return;
4896 if (range & ~0xff)
4898 if ((inst.instruction == T_OPCODE_PUSH
4899 && (range & ~0xff) == 1 << REG_LR)
4900 || (inst.instruction == T_OPCODE_POP
4901 && (range & ~0xff) == 1 << REG_PC))
4903 inst.instruction |= THUMB_PP_PC_LR;
4904 range &= 0xff;
4906 else
4908 inst.error = _("invalid register list to push/pop instruction");
4909 return;
4913 inst.instruction |= range;
4914 end_of_line (str);
4917 static void
4918 do_t_str (str)
4919 char * str;
4921 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4924 static void
4925 do_t_strb (str)
4926 char * str;
4928 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4931 static void
4932 do_t_strh (str)
4933 char * str;
4935 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4938 static void
4939 do_t_sub (str)
4940 char * str;
4942 thumb_add_sub (str, 1);
4945 static void
4946 do_t_swi (str)
4947 char * str;
4949 skip_whitespace (str);
4951 if (my_get_expression (&inst.reloc.exp, &str))
4952 return;
4954 inst.reloc.type = BFD_RELOC_ARM_SWI;
4955 end_of_line (str);
4956 return;
4959 static void
4960 do_t_adr (str)
4961 char * str;
4963 int reg;
4965 /* This is a pseudo-op of the form "adr rd, label" to be converted
4966 into a relative address of the form "add rd, pc, #label-.-4". */
4967 skip_whitespace (str);
4969 /* Store Rd in temporary location inside instruction. */
4970 if ((reg = reg_required_here (&str, 4)) == FAIL
4971 || (reg > 7) /* For Thumb reg must be r0..r7. */
4972 || skip_past_comma (&str) == FAIL
4973 || my_get_expression (&inst.reloc.exp, &str))
4975 if (!inst.error)
4976 inst.error = BAD_ARGS;
4977 return;
4980 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4981 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
4982 inst.reloc.pc_rel = 1;
4983 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
4985 end_of_line (str);
4988 static void
4989 insert_reg (entry)
4990 int entry;
4992 int len = strlen (reg_table[entry].name) + 2;
4993 char * buf = (char *) xmalloc (len);
4994 char * buf2 = (char *) xmalloc (len);
4995 int i = 0;
4997 #ifdef REGISTER_PREFIX
4998 buf[i++] = REGISTER_PREFIX;
4999 #endif
5001 strcpy (buf + i, reg_table[entry].name);
5003 for (i = 0; buf[i]; i++)
5004 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
5006 buf2[i] = '\0';
5008 hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
5009 hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
5012 static void
5013 insert_reg_alias (str, regnum)
5014 char *str;
5015 int regnum;
5017 struct reg_entry *new =
5018 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
5019 char *name = xmalloc (strlen (str) + 1);
5020 strcpy (name, str);
5022 new->name = name;
5023 new->number = regnum;
5025 hash_insert (arm_reg_hsh, name, (PTR) new);
5028 static void
5029 set_constant_flonums ()
5031 int i;
5033 for (i = 0; i < NUM_FLOAT_VALS; i++)
5034 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
5035 abort ();
5038 void
5039 md_begin ()
5041 unsigned mach;
5042 unsigned int i;
5044 if ( (arm_ops_hsh = hash_new ()) == NULL
5045 || (arm_tops_hsh = hash_new ()) == NULL
5046 || (arm_cond_hsh = hash_new ()) == NULL
5047 || (arm_shift_hsh = hash_new ()) == NULL
5048 || (arm_reg_hsh = hash_new ()) == NULL
5049 || (arm_psr_hsh = hash_new ()) == NULL)
5050 as_fatal (_("Virtual memory exhausted"));
5052 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
5053 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
5054 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
5055 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
5056 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
5057 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
5058 for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
5059 hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
5060 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
5061 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
5063 for (i = 0; reg_table[i].name; i++)
5064 insert_reg (i);
5066 set_constant_flonums ();
5068 #if defined OBJ_COFF || defined OBJ_ELF
5070 unsigned int flags = 0;
5072 /* Set the flags in the private structure. */
5073 if (uses_apcs_26) flags |= F_APCS26;
5074 if (support_interwork) flags |= F_INTERWORK;
5075 if (uses_apcs_float) flags |= F_APCS_FLOAT;
5076 if (pic_code) flags |= F_PIC;
5077 if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT;
5079 bfd_set_private_flags (stdoutput, flags);
5081 #endif
5083 /* Record the CPU type as well. */
5084 switch (cpu_variant & ARM_CPU_MASK)
5086 case ARM_2:
5087 mach = bfd_mach_arm_2;
5088 break;
5090 case ARM_3: /* Also ARM_250. */
5091 mach = bfd_mach_arm_2a;
5092 break;
5094 default:
5095 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined. */
5096 mach = bfd_mach_arm_4;
5097 break;
5099 case ARM_7: /* Also ARM_6. */
5100 mach = bfd_mach_arm_3;
5101 break;
5104 /* Catch special cases. */
5105 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
5107 if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
5108 mach = bfd_mach_arm_5T;
5109 else if (cpu_variant & ARM_EXT_V5)
5110 mach = bfd_mach_arm_5;
5111 else if (cpu_variant & ARM_THUMB)
5112 mach = bfd_mach_arm_4T;
5113 else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
5114 mach = bfd_mach_arm_4;
5115 else if (cpu_variant & ARM_LONGMUL)
5116 mach = bfd_mach_arm_3M;
5119 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
5122 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5123 for use in the a.out file, and stores them in the array pointed to by buf.
5124 This knows about the endian-ness of the target machine and does
5125 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5126 2 (short) and 4 (long) Floating numbers are put out as a series of
5127 LITTLENUMS (shorts, here at least). */
5128 void
5129 md_number_to_chars (buf, val, n)
5130 char * buf;
5131 valueT val;
5132 int n;
5134 if (target_big_endian)
5135 number_to_chars_bigendian (buf, val, n);
5136 else
5137 number_to_chars_littleendian (buf, val, n);
5140 static valueT
5141 md_chars_to_number (buf, n)
5142 char * buf;
5143 int n;
5145 valueT result = 0;
5146 unsigned char * where = (unsigned char *) buf;
5148 if (target_big_endian)
5150 while (n--)
5152 result <<= 8;
5153 result |= (*where++ & 255);
5156 else
5158 while (n--)
5160 result <<= 8;
5161 result |= (where[n] & 255);
5165 return result;
5168 /* Turn a string in input_line_pointer into a floating point constant
5169 of type TYPE, and store the appropriate bytes in *litP. The number
5170 of LITTLENUMS emitted is stored in *sizeP . An error message is
5171 returned, or NULL on OK.
5173 Note that fp constants aren't represent in the normal way on the ARM.
5174 In big endian mode, things are as expected. However, in little endian
5175 mode fp constants are big-endian word-wise, and little-endian byte-wise
5176 within the words. For example, (double) 1.1 in big endian mode is
5177 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5178 the byte sequence 99 99 f1 3f 9a 99 99 99.
5180 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5182 char *
5183 md_atof (type, litP, sizeP)
5184 char type;
5185 char * litP;
5186 int * sizeP;
5188 int prec;
5189 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5190 char *t;
5191 int i;
5193 switch (type)
5195 case 'f':
5196 case 'F':
5197 case 's':
5198 case 'S':
5199 prec = 2;
5200 break;
5202 case 'd':
5203 case 'D':
5204 case 'r':
5205 case 'R':
5206 prec = 4;
5207 break;
5209 case 'x':
5210 case 'X':
5211 prec = 6;
5212 break;
5214 case 'p':
5215 case 'P':
5216 prec = 6;
5217 break;
5219 default:
5220 *sizeP = 0;
5221 return _("Bad call to MD_ATOF()");
5224 t = atof_ieee (input_line_pointer, type, words);
5225 if (t)
5226 input_line_pointer = t;
5227 *sizeP = prec * 2;
5229 if (target_big_endian)
5231 for (i = 0; i < prec; i++)
5233 md_number_to_chars (litP, (valueT) words[i], 2);
5234 litP += 2;
5237 else
5239 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5240 8 byte float the order is 1 0 3 2. */
5241 for (i = 0; i < prec; i += 2)
5243 md_number_to_chars (litP, (valueT) words[i + 1], 2);
5244 md_number_to_chars (litP + 2, (valueT) words[i], 2);
5245 litP += 4;
5249 return 0;
5252 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5253 long
5254 md_pcrel_from (fixP)
5255 fixS * fixP;
5257 if ( fixP->fx_addsy
5258 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
5259 && fixP->fx_subsy == NULL)
5260 return 0;
5262 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
5264 /* PC relative addressing on the Thumb is slightly odd
5265 as the bottom two bits of the PC are forced to zero
5266 for the calculation. */
5267 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
5270 #ifdef TE_WINCE
5271 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5272 so we un-adjust here to compensate for the accomodation. */
5273 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
5274 #else
5275 return fixP->fx_where + fixP->fx_frag->fr_address;
5276 #endif
5279 /* Round up a section size to the appropriate boundary. */
5280 valueT
5281 md_section_align (segment, size)
5282 segT segment ATTRIBUTE_UNUSED;
5283 valueT size;
5285 #ifdef OBJ_ELF
5286 return size;
5287 #else
5288 /* Round all sects to multiple of 4 */
5289 return (size + 3) & ~3;
5290 #endif
5293 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5294 we have no need to default values of symbols. */
5296 /* ARGSUSED */
5297 symbolS *
5298 md_undefined_symbol (name)
5299 char * name ATTRIBUTE_UNUSED;
5301 #ifdef OBJ_ELF
5302 if (name[0] == '_' && name[1] == 'G'
5303 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
5305 if (!GOT_symbol)
5307 if (symbol_find (name))
5308 as_bad ("GOT already in the symbol table");
5310 GOT_symbol = symbol_new (name, undefined_section,
5311 (valueT)0, & zero_address_frag);
5314 return GOT_symbol;
5316 #endif
5318 return 0;
5321 /* arm_reg_parse () := if it looks like a register, return its token and
5322 advance the pointer. */
5324 static int
5325 arm_reg_parse (ccp)
5326 register char ** ccp;
5328 char * start = * ccp;
5329 char c;
5330 char * p;
5331 struct reg_entry * reg;
5333 #ifdef REGISTER_PREFIX
5334 if (*start != REGISTER_PREFIX)
5335 return FAIL;
5336 p = start + 1;
5337 #else
5338 p = start;
5339 #ifdef OPTIONAL_REGISTER_PREFIX
5340 if (*p == OPTIONAL_REGISTER_PREFIX)
5341 p++, start++;
5342 #endif
5343 #endif
5344 if (!isalpha (*p) || !is_name_beginner (*p))
5345 return FAIL;
5347 c = *p++;
5348 while (isalpha (c) || isdigit (c) || c == '_')
5349 c = *p++;
5351 *--p = 0;
5352 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
5353 *p = c;
5355 if (reg)
5357 *ccp = p;
5358 return reg->number;
5361 return FAIL;
5365 md_apply_fix3 (fixP, val, seg)
5366 fixS * fixP;
5367 valueT * val;
5368 segT seg;
5370 offsetT value = * val;
5371 offsetT newval;
5372 unsigned int newimm;
5373 unsigned long temp;
5374 int sign;
5375 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5376 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
5378 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5380 /* Note whether this will delete the relocation. */
5381 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5382 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
5383 && !fixP->fx_pcrel)
5384 #else
5385 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5386 #endif
5387 fixP->fx_done = 1;
5389 /* If this symbol is in a different section then we need to leave it for
5390 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5391 so we have to undo it's effects here. */
5392 if (fixP->fx_pcrel)
5394 if (fixP->fx_addsy != NULL
5395 && S_IS_DEFINED (fixP->fx_addsy)
5396 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5398 if (target_oabi
5399 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
5400 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
5402 value = 0;
5403 else
5404 value += md_pcrel_from (fixP);
5408 fixP->fx_addnumber = value; /* Remember value for emit_reloc. */
5410 switch (fixP->fx_r_type)
5412 case BFD_RELOC_ARM_IMMEDIATE:
5413 newimm = validate_immediate (value);
5414 temp = md_chars_to_number (buf, INSN_SIZE);
5416 /* If the instruction will fail, see if we can fix things up by
5417 changing the opcode. */
5418 if (newimm == (unsigned int) FAIL
5419 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5421 as_bad_where (fixP->fx_file, fixP->fx_line,
5422 _("invalid constant (%lx) after fixup"),
5423 (unsigned long) value);
5424 break;
5427 newimm |= (temp & 0xfffff000);
5428 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5429 break;
5431 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5433 unsigned int highpart = 0;
5434 unsigned int newinsn = 0xe1a00000; /* nop */
5435 newimm = validate_immediate (value);
5436 temp = md_chars_to_number (buf, INSN_SIZE);
5438 /* If the instruction will fail, see if we can fix things up by
5439 changing the opcode. */
5440 if (newimm == (unsigned int) FAIL
5441 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
5443 /* No ? OK - try using two ADD instructions to generate the value. */
5444 newimm = validate_immediate_twopart (value, & highpart);
5446 /* Yes - then make sure that the second instruction is also an add. */
5447 if (newimm != (unsigned int) FAIL)
5448 newinsn = temp;
5449 /* Still No ? Try using a negated value. */
5450 else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL)
5451 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
5452 /* Otherwise - give up. */
5453 else
5455 as_bad_where (fixP->fx_file, fixP->fx_line,
5456 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value);
5457 break;
5460 /* Replace the first operand in the 2nd instruction (which is the PC)
5461 with the destination register. We have already added in the PC in the
5462 first instruction and we do not want to do it again. */
5463 newinsn &= ~ 0xf0000;
5464 newinsn |= ((newinsn & 0x0f000) << 4);
5467 newimm |= (temp & 0xfffff000);
5468 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5470 highpart |= (newinsn & 0xfffff000);
5471 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
5473 break;
5475 case BFD_RELOC_ARM_OFFSET_IMM:
5476 sign = value >= 0;
5478 if (value < 0)
5479 value = - value;
5481 if (validate_offset_imm (value, 0) == FAIL)
5483 as_bad_where (fixP->fx_file, fixP->fx_line,
5484 _("bad immediate value for offset (%ld)"), (long) value);
5485 break;
5488 newval = md_chars_to_number (buf, INSN_SIZE);
5489 newval &= 0xff7ff000;
5490 newval |= value | (sign ? INDEX_UP : 0);
5491 md_number_to_chars (buf, newval, INSN_SIZE);
5492 break;
5494 case BFD_RELOC_ARM_OFFSET_IMM8:
5495 case BFD_RELOC_ARM_HWLITERAL:
5496 sign = value >= 0;
5498 if (value < 0)
5499 value = - value;
5501 if (validate_offset_imm (value, 1) == FAIL)
5503 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5504 as_bad_where (fixP->fx_file, fixP->fx_line,
5505 _("invalid literal constant: pool needs to be closer"));
5506 else
5507 as_bad (_("bad immediate value for half-word offset (%ld)"),
5508 (long) value);
5509 break;
5512 newval = md_chars_to_number (buf, INSN_SIZE);
5513 newval &= 0xff7ff0f0;
5514 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
5515 md_number_to_chars (buf, newval, INSN_SIZE);
5516 break;
5518 case BFD_RELOC_ARM_LITERAL:
5519 sign = value >= 0;
5521 if (value < 0)
5522 value = - value;
5524 if (validate_offset_imm (value, 0) == FAIL)
5526 as_bad_where (fixP->fx_file, fixP->fx_line,
5527 _("invalid literal constant: pool needs to be closer"));
5528 break;
5531 newval = md_chars_to_number (buf, INSN_SIZE);
5532 newval &= 0xff7ff000;
5533 newval |= value | (sign ? INDEX_UP : 0);
5534 md_number_to_chars (buf, newval, INSN_SIZE);
5535 break;
5537 case BFD_RELOC_ARM_SHIFT_IMM:
5538 newval = md_chars_to_number (buf, INSN_SIZE);
5539 if (((unsigned long) value) > 32
5540 || (value == 32
5541 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5543 as_bad_where (fixP->fx_file, fixP->fx_line,
5544 _("shift expression is too large"));
5545 break;
5548 if (value == 0)
5549 newval &= ~0x60; /* Shifts of zero must be done as lsl */
5550 else if (value == 32)
5551 value = 0;
5552 newval &= 0xfffff07f;
5553 newval |= (value & 0x1f) << 7;
5554 md_number_to_chars (buf, newval , INSN_SIZE);
5555 break;
5557 case BFD_RELOC_ARM_SWI:
5558 if (arm_data->thumb_mode)
5560 if (((unsigned long) value) > 0xff)
5561 as_bad_where (fixP->fx_file, fixP->fx_line,
5562 _("Invalid swi expression"));
5563 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5564 newval |= value;
5565 md_number_to_chars (buf, newval, THUMB_SIZE);
5567 else
5569 if (((unsigned long) value) > 0x00ffffff)
5570 as_bad_where (fixP->fx_file, fixP->fx_line,
5571 _("Invalid swi expression"));
5572 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5573 newval |= value;
5574 md_number_to_chars (buf, newval , INSN_SIZE);
5576 break;
5578 case BFD_RELOC_ARM_MULTI:
5579 if (((unsigned long) value) > 0xffff)
5580 as_bad_where (fixP->fx_file, fixP->fx_line,
5581 _("Invalid expression in load/store multiple"));
5582 newval = value | md_chars_to_number (buf, INSN_SIZE);
5583 md_number_to_chars (buf, newval, INSN_SIZE);
5584 break;
5586 case BFD_RELOC_ARM_PCREL_BRANCH:
5587 newval = md_chars_to_number (buf, INSN_SIZE);
5589 /* Sign-extend a 24-bit number. */
5590 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5592 #ifdef OBJ_ELF
5593 if (! target_oabi)
5594 value = fixP->fx_offset;
5595 #endif
5597 /* We are going to store value (shifted right by two) in the
5598 instruction, in a 24 bit, signed field. Thus we need to check
5599 that none of the top 8 bits of the shifted value (top 7 bits of
5600 the unshifted, unsigned value) are set, or that they are all set. */
5601 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
5602 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
5604 #ifdef OBJ_ELF
5605 /* Normally we would be stuck at this point, since we cannot store
5606 the absolute address that is the destination of the branch in the
5607 24 bits of the branch instruction. If however, we happen to know
5608 that the destination of the branch is in the same section as the
5609 branch instruciton itself, then we can compute the relocation for
5610 ourselves and not have to bother the linker with it.
5612 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5613 because I have not worked out how to do this for OBJ_COFF or
5614 target_oabi. */
5615 if (! target_oabi
5616 && fixP->fx_addsy != NULL
5617 && S_IS_DEFINED (fixP->fx_addsy)
5618 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
5620 /* Get pc relative value to go into the branch. */
5621 value = * val;
5623 /* Permit a backward branch provided that enough bits are set.
5624 Allow a forwards branch, provided that enough bits are clear. */
5625 if ((value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
5626 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
5627 fixP->fx_done = 1;
5630 if (! fixP->fx_done)
5631 #endif
5632 as_bad_where (fixP->fx_file, fixP->fx_line,
5633 _("gas can't handle same-section branch dest >= 0x04000000"));
5636 value >>= 2;
5637 value += SEXT24 (newval);
5639 if ((value & ~ ((offsetT) 0xffffff)) != 0
5640 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
5641 as_bad_where (fixP->fx_file, fixP->fx_line,
5642 _("out of range branch"));
5644 newval = (value & 0x00ffffff) | (newval & 0xff000000);
5645 md_number_to_chars (buf, newval, INSN_SIZE);
5646 break;
5648 case BFD_RELOC_ARM_PCREL_BLX:
5650 offsetT hbit;
5651 newval = md_chars_to_number (buf, INSN_SIZE);
5653 #ifdef OBJ_ELF
5654 if (! target_oabi)
5655 value = fixP->fx_offset;
5656 #endif
5657 hbit = (value >> 1) & 1;
5658 value = (value >> 2) & 0x00ffffff;
5659 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5660 newval = value | (newval & 0xfe000000) | (hbit << 24);
5661 md_number_to_chars (buf, newval, INSN_SIZE);
5663 break;
5665 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5666 newval = md_chars_to_number (buf, THUMB_SIZE);
5668 addressT diff = (newval & 0xff) << 1;
5669 if (diff & 0x100)
5670 diff |= ~0xff;
5672 value += diff;
5673 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5674 as_bad_where (fixP->fx_file, fixP->fx_line,
5675 _("Branch out of range"));
5676 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5678 md_number_to_chars (buf, newval, THUMB_SIZE);
5679 break;
5681 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5682 newval = md_chars_to_number (buf, THUMB_SIZE);
5684 addressT diff = (newval & 0x7ff) << 1;
5685 if (diff & 0x800)
5686 diff |= ~0x7ff;
5688 value += diff;
5689 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5690 as_bad_where (fixP->fx_file, fixP->fx_line,
5691 _("Branch out of range"));
5692 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5694 md_number_to_chars (buf, newval, THUMB_SIZE);
5695 break;
5697 case BFD_RELOC_THUMB_PCREL_BLX:
5698 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5700 offsetT newval2;
5701 addressT diff;
5703 newval = md_chars_to_number (buf, THUMB_SIZE);
5704 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5705 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5706 if (diff & 0x400000)
5707 diff |= ~0x3fffff;
5708 #ifdef OBJ_ELF
5709 value = fixP->fx_offset;
5710 #endif
5711 value += diff;
5712 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5713 as_bad_where (fixP->fx_file, fixP->fx_line,
5714 _("Branch with link out of range"));
5716 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5717 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5718 md_number_to_chars (buf, newval, THUMB_SIZE);
5719 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5721 break;
5723 case BFD_RELOC_8:
5724 if (fixP->fx_done || fixP->fx_pcrel)
5725 md_number_to_chars (buf, value, 1);
5726 #ifdef OBJ_ELF
5727 else if (!target_oabi)
5729 value = fixP->fx_offset;
5730 md_number_to_chars (buf, value, 1);
5732 #endif
5733 break;
5735 case BFD_RELOC_16:
5736 if (fixP->fx_done || fixP->fx_pcrel)
5737 md_number_to_chars (buf, value, 2);
5738 #ifdef OBJ_ELF
5739 else if (!target_oabi)
5741 value = fixP->fx_offset;
5742 md_number_to_chars (buf, value, 2);
5744 #endif
5745 break;
5747 #ifdef OBJ_ELF
5748 case BFD_RELOC_ARM_GOT32:
5749 case BFD_RELOC_ARM_GOTOFF:
5750 md_number_to_chars (buf, 0, 4);
5751 break;
5752 #endif
5754 case BFD_RELOC_RVA:
5755 case BFD_RELOC_32:
5756 if (fixP->fx_done || fixP->fx_pcrel)
5757 md_number_to_chars (buf, value, 4);
5758 #ifdef OBJ_ELF
5759 else if (!target_oabi)
5761 value = fixP->fx_offset;
5762 md_number_to_chars (buf, value, 4);
5764 #endif
5765 break;
5767 #ifdef OBJ_ELF
5768 case BFD_RELOC_ARM_PLT32:
5769 /* It appears the instruction is fully prepared at this point. */
5770 break;
5771 #endif
5773 case BFD_RELOC_ARM_GOTPC:
5774 md_number_to_chars (buf, value, 4);
5775 break;
5777 case BFD_RELOC_ARM_CP_OFF_IMM:
5778 sign = value >= 0;
5779 if (value < -1023 || value > 1023 || (value & 3))
5780 as_bad_where (fixP->fx_file, fixP->fx_line,
5781 _("Illegal value for co-processor offset"));
5782 if (value < 0)
5783 value = -value;
5784 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5785 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5786 md_number_to_chars (buf, newval , INSN_SIZE);
5787 break;
5789 case BFD_RELOC_ARM_THUMB_OFFSET:
5790 newval = md_chars_to_number (buf, THUMB_SIZE);
5791 /* Exactly what ranges, and where the offset is inserted depends on
5792 the type of instruction, we can establish this from the top 4 bits */
5793 switch (newval >> 12)
5795 case 4: /* PC load */
5796 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5797 forced to zero for these loads, so we will need to round
5798 up the offset if the instruction address is not word
5799 aligned (since the final address produced must be, and
5800 we can only describe word-aligned immediate offsets). */
5802 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5803 as_bad_where (fixP->fx_file, fixP->fx_line,
5804 _("Invalid offset, target not word aligned (0x%08X)"),
5805 (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5807 if ((value + 2) & ~0x3fe)
5808 as_bad_where (fixP->fx_file, fixP->fx_line,
5809 _("Invalid offset, value too big (0x%08X)"), value);
5811 /* Round up, since pc will be rounded down. */
5812 newval |= (value + 2) >> 2;
5813 break;
5815 case 9: /* SP load/store */
5816 if (value & ~0x3fc)
5817 as_bad_where (fixP->fx_file, fixP->fx_line,
5818 _("Invalid offset, value too big (0x%08X)"), value);
5819 newval |= value >> 2;
5820 break;
5822 case 6: /* Word load/store */
5823 if (value & ~0x7c)
5824 as_bad_where (fixP->fx_file, fixP->fx_line,
5825 _("Invalid offset, value too big (0x%08X)"), value);
5826 newval |= value << 4; /* 6 - 2 */
5827 break;
5829 case 7: /* Byte load/store */
5830 if (value & ~0x1f)
5831 as_bad_where (fixP->fx_file, fixP->fx_line,
5832 _("Invalid offset, value too big (0x%08X)"), value);
5833 newval |= value << 6;
5834 break;
5836 case 8: /* Halfword load/store */
5837 if (value & ~0x3e)
5838 as_bad_where (fixP->fx_file, fixP->fx_line,
5839 _("Invalid offset, value too big (0x%08X)"), value);
5840 newval |= value << 5; /* 6 - 1 */
5841 break;
5843 default:
5844 as_bad_where (fixP->fx_file, fixP->fx_line,
5845 "Unable to process relocation for thumb opcode: %lx",
5846 (unsigned long) newval);
5847 break;
5849 md_number_to_chars (buf, newval, THUMB_SIZE);
5850 break;
5852 case BFD_RELOC_ARM_THUMB_ADD:
5853 /* This is a complicated relocation, since we use it for all of
5854 the following immediate relocations:
5855 3bit ADD/SUB
5856 8bit ADD/SUB
5857 9bit ADD/SUB SP word-aligned
5858 10bit ADD PC/SP word-aligned
5860 The type of instruction being processed is encoded in the
5861 instruction field:
5862 0x8000 SUB
5863 0x00F0 Rd
5864 0x000F Rs
5866 newval = md_chars_to_number (buf, THUMB_SIZE);
5868 int rd = (newval >> 4) & 0xf;
5869 int rs = newval & 0xf;
5870 int subtract = newval & 0x8000;
5872 if (rd == REG_SP)
5874 if (value & ~0x1fc)
5875 as_bad_where (fixP->fx_file, fixP->fx_line,
5876 _("Invalid immediate for stack address calculation"));
5877 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5878 newval |= value >> 2;
5880 else if (rs == REG_PC || rs == REG_SP)
5882 if (subtract ||
5883 value & ~0x3fc)
5884 as_bad_where (fixP->fx_file, fixP->fx_line,
5885 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5886 (unsigned long) value);
5887 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5888 newval |= rd << 8;
5889 newval |= value >> 2;
5891 else if (rs == rd)
5893 if (value & ~0xff)
5894 as_bad_where (fixP->fx_file, fixP->fx_line,
5895 _("Invalid 8bit immediate"));
5896 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5897 newval |= (rd << 8) | value;
5899 else
5901 if (value & ~0x7)
5902 as_bad_where (fixP->fx_file, fixP->fx_line,
5903 _("Invalid 3bit immediate"));
5904 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5905 newval |= rd | (rs << 3) | (value << 6);
5908 md_number_to_chars (buf, newval , THUMB_SIZE);
5909 break;
5911 case BFD_RELOC_ARM_THUMB_IMM:
5912 newval = md_chars_to_number (buf, THUMB_SIZE);
5913 switch (newval >> 11)
5915 case 0x04: /* 8bit immediate MOV */
5916 case 0x05: /* 8bit immediate CMP */
5917 if (value < 0 || value > 255)
5918 as_bad_where (fixP->fx_file, fixP->fx_line,
5919 _("Invalid immediate: %ld is too large"),
5920 (long) value);
5921 newval |= value;
5922 break;
5924 default:
5925 abort ();
5927 md_number_to_chars (buf, newval , THUMB_SIZE);
5928 break;
5930 case BFD_RELOC_ARM_THUMB_SHIFT:
5931 /* 5bit shift value (0..31) */
5932 if (value < 0 || value > 31)
5933 as_bad_where (fixP->fx_file, fixP->fx_line,
5934 _("Illegal Thumb shift value: %ld"), (long) value);
5935 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5936 newval |= value << 6;
5937 md_number_to_chars (buf, newval , THUMB_SIZE);
5938 break;
5940 case BFD_RELOC_VTABLE_INHERIT:
5941 case BFD_RELOC_VTABLE_ENTRY:
5942 fixP->fx_done = 0;
5943 return 1;
5945 case BFD_RELOC_NONE:
5946 default:
5947 as_bad_where (fixP->fx_file, fixP->fx_line,
5948 _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
5951 return 1;
5954 /* Translate internal representation of relocation info to BFD target
5955 format. */
5956 arelent *
5957 tc_gen_reloc (section, fixp)
5958 asection * section ATTRIBUTE_UNUSED;
5959 fixS * fixp;
5961 arelent * reloc;
5962 bfd_reloc_code_real_type code;
5964 reloc = (arelent *) xmalloc (sizeof (arelent));
5966 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
5967 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5968 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5970 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5971 #ifndef OBJ_ELF
5972 if (fixp->fx_pcrel == 0)
5973 reloc->addend = fixp->fx_offset;
5974 else
5975 reloc->addend = fixp->fx_offset = reloc->address;
5976 #else /* OBJ_ELF */
5977 reloc->addend = fixp->fx_offset;
5978 #endif
5980 switch (fixp->fx_r_type)
5982 case BFD_RELOC_8:
5983 if (fixp->fx_pcrel)
5985 code = BFD_RELOC_8_PCREL;
5986 break;
5989 case BFD_RELOC_16:
5990 if (fixp->fx_pcrel)
5992 code = BFD_RELOC_16_PCREL;
5993 break;
5996 case BFD_RELOC_32:
5997 if (fixp->fx_pcrel)
5999 code = BFD_RELOC_32_PCREL;
6000 break;
6003 case BFD_RELOC_ARM_PCREL_BRANCH:
6004 case BFD_RELOC_ARM_PCREL_BLX:
6005 case BFD_RELOC_RVA:
6006 case BFD_RELOC_THUMB_PCREL_BRANCH9:
6007 case BFD_RELOC_THUMB_PCREL_BRANCH12:
6008 case BFD_RELOC_THUMB_PCREL_BRANCH23:
6009 case BFD_RELOC_THUMB_PCREL_BLX:
6010 case BFD_RELOC_VTABLE_ENTRY:
6011 case BFD_RELOC_VTABLE_INHERIT:
6012 code = fixp->fx_r_type;
6013 break;
6015 case BFD_RELOC_ARM_LITERAL:
6016 case BFD_RELOC_ARM_HWLITERAL:
6017 /* If this is called then the a literal has been referenced across
6018 a section boundary - possibly due to an implicit dump */
6019 as_bad_where (fixp->fx_file, fixp->fx_line,
6020 _("Literal referenced across section boundary (Implicit dump?)"));
6021 return NULL;
6023 #ifdef OBJ_ELF
6024 case BFD_RELOC_ARM_GOT32:
6025 case BFD_RELOC_ARM_GOTOFF:
6026 case BFD_RELOC_ARM_PLT32:
6027 code = fixp->fx_r_type;
6028 break;
6029 #endif
6031 case BFD_RELOC_ARM_IMMEDIATE:
6032 as_bad_where (fixp->fx_file, fixp->fx_line,
6033 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6034 fixp->fx_r_type);
6035 return NULL;
6037 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
6038 as_bad_where (fixp->fx_file, fixp->fx_line,
6039 _("ADRL used for a symbol not defined in the same file"),
6040 fixp->fx_r_type);
6041 return NULL;
6043 case BFD_RELOC_ARM_OFFSET_IMM:
6044 as_bad_where (fixp->fx_file, fixp->fx_line,
6045 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6046 fixp->fx_r_type);
6047 return NULL;
6049 default:
6051 char * type;
6052 switch (fixp->fx_r_type)
6054 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
6055 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
6056 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
6057 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
6058 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
6059 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
6060 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
6061 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
6062 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
6063 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
6064 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
6065 default: type = _("<unknown>"); break;
6067 as_bad_where (fixp->fx_file, fixp->fx_line,
6068 _("Can not represent %s relocation in this object file format (%d)"),
6069 type, fixp->fx_pcrel);
6070 return NULL;
6074 #ifdef OBJ_ELF
6075 if (code == BFD_RELOC_32_PCREL
6076 && GOT_symbol
6077 && fixp->fx_addsy == GOT_symbol)
6079 code = BFD_RELOC_ARM_GOTPC;
6080 reloc->addend = fixp->fx_offset = reloc->address;
6082 #endif
6084 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6086 if (reloc->howto == NULL)
6088 as_bad_where (fixp->fx_file, fixp->fx_line,
6089 _("Can not represent %s relocation in this object file format"),
6090 bfd_get_reloc_code_name (code));
6091 return NULL;
6094 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6095 vtable entry to be used in the relocation's section offset. */
6096 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6097 reloc->address = fixp->fx_offset;
6099 return reloc;
6103 md_estimate_size_before_relax (fragP, segtype)
6104 fragS * fragP ATTRIBUTE_UNUSED;
6105 segT segtype ATTRIBUTE_UNUSED;
6107 as_fatal (_("md_estimate_size_before_relax\n"));
6108 return 1;
6111 static void
6112 output_inst PARAMS ((void))
6114 char * to = NULL;
6116 if (inst.error)
6118 as_bad (inst.error);
6119 return;
6122 to = frag_more (inst.size);
6124 if (thumb_mode && (inst.size > THUMB_SIZE))
6126 assert (inst.size == (2 * THUMB_SIZE));
6127 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
6128 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
6130 else if (inst.size > INSN_SIZE)
6132 assert (inst.size == (2 * INSN_SIZE));
6133 md_number_to_chars (to, inst.instruction, INSN_SIZE);
6134 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
6136 else
6137 md_number_to_chars (to, inst.instruction, inst.size);
6139 if (inst.reloc.type != BFD_RELOC_NONE)
6140 fix_new_arm (frag_now, to - frag_now->fr_literal,
6141 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
6142 inst.reloc.type);
6144 return;
6147 void
6148 md_assemble (str)
6149 char * str;
6151 char c;
6152 char * p;
6153 char * q;
6154 char * start;
6156 /* Align the instruction.
6157 This may not be the right thing to do but ... */
6158 /* arm_align (2, 0); */
6159 listing_prev_line (); /* Defined in listing.h */
6161 /* Align the previous label if needed. */
6162 if (last_label_seen != NULL)
6164 symbol_set_frag (last_label_seen, frag_now);
6165 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
6166 S_SET_SEGMENT (last_label_seen, now_seg);
6169 memset (&inst, '\0', sizeof (inst));
6170 inst.reloc.type = BFD_RELOC_NONE;
6172 skip_whitespace (str);
6174 /* Scan up to the end of the op-code, which must end in white space or
6175 end of string. */
6176 for (start = p = str; *p != '\0'; p++)
6177 if (*p == ' ')
6178 break;
6180 if (p == str)
6182 as_bad (_("No operator -- statement `%s'\n"), str);
6183 return;
6186 if (thumb_mode)
6188 CONST struct thumb_opcode * opcode;
6190 c = *p;
6191 *p = '\0';
6192 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
6193 *p = c;
6195 if (opcode)
6197 /* Check that this instruction is supported for this CPU. */
6198 if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0)
6200 as_bad (_("selected processor does not support this opcode"));
6201 return;
6204 inst.instruction = opcode->value;
6205 inst.size = opcode->size;
6206 (*opcode->parms)(p);
6207 output_inst ();
6208 return;
6211 else
6213 CONST struct asm_opcode * opcode;
6214 unsigned long cond_code;
6216 inst.size = INSN_SIZE;
6217 /* p now points to the end of the opcode, probably white space, but we
6218 have to break the opcode up in case it contains condionals and flags;
6219 keep trying with progressively smaller basic instructions until one
6220 matches, or we run out of opcode. */
6221 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
6223 for (; q != str; q--)
6225 c = *q;
6226 *q = '\0';
6228 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
6229 *q = c;
6231 if (opcode && opcode->template)
6233 unsigned long flag_bits = 0;
6234 char * r;
6236 /* Check that this instruction is supported for this CPU. */
6237 if ((opcode->variants & cpu_variant) == 0)
6238 goto try_shorter;
6240 inst.instruction = opcode->value;
6241 if (q == p) /* Just a simple opcode. */
6243 if (opcode->comp_suffix)
6245 if (*opcode->comp_suffix != '\0')
6246 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6247 str, opcode->comp_suffix);
6248 else
6249 /* Not a conditional instruction. */
6250 (*opcode->parms)(q, 0);
6252 else
6254 /* A conditional instruction with default condition. */
6255 inst.instruction |= COND_ALWAYS;
6256 (*opcode->parms)(q, 0);
6258 output_inst ();
6259 return;
6262 /* Not just a simple opcode. Check if extra is a conditional. */
6263 r = q;
6264 if (p - r >= 2)
6266 CONST struct asm_cond *cond;
6267 char d = *(r + 2);
6269 *(r + 2) = '\0';
6270 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
6271 *(r + 2) = d;
6272 if (cond)
6274 if (cond->value == 0xf0000000)
6275 as_tsktsk (
6276 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6278 cond_code = cond->value;
6279 r += 2;
6281 else
6282 cond_code = COND_ALWAYS;
6284 else
6285 cond_code = COND_ALWAYS;
6287 /* Apply the conditional, or complain it's not allowed. */
6288 if (opcode->comp_suffix && *opcode->comp_suffix == '\0')
6290 /* Instruction isn't conditional */
6291 if (cond_code != COND_ALWAYS)
6293 as_bad (_("Opcode `%s' is unconditional\n"), str);
6294 return;
6297 else
6298 /* Instruction is conditional: set the condition into it. */
6299 inst.instruction |= cond_code;
6302 /* If there is a compulsory suffix, it should come here, before
6303 any optional flags. */
6304 if (opcode->comp_suffix && *opcode->comp_suffix != '\0')
6306 CONST char *s = opcode->comp_suffix;
6308 while (*s)
6310 inst.suffix++;
6311 if (*r == *s)
6312 break;
6313 s++;
6316 if (*s == '\0')
6318 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6319 opcode->comp_suffix);
6320 return;
6323 r++;
6326 /* The remainder, if any should now be flags for the instruction;
6327 Scan these checking each one found with the opcode. */
6328 if (r != p)
6330 char d;
6331 CONST struct asm_flg *flag = opcode->flags;
6333 if (flag)
6335 int flagno;
6337 d = *p;
6338 *p = '\0';
6340 for (flagno = 0; flag[flagno].template; flagno++)
6342 if (streq (r, flag[flagno].template))
6344 flag_bits |= flag[flagno].set_bits;
6345 break;
6349 *p = d;
6350 if (! flag[flagno].template)
6351 goto try_shorter;
6353 else
6354 goto try_shorter;
6357 (*opcode->parms) (p, flag_bits);
6358 output_inst ();
6359 return;
6362 try_shorter:
6367 /* It wasn't an instruction, but it might be a register alias of the form
6368 alias .req reg */
6369 q = p;
6370 skip_whitespace (q);
6372 c = *p;
6373 *p = '\0';
6375 if (*q && !strncmp (q, ".req ", 4))
6377 int reg;
6378 char * copy_of_str = str;
6379 char * r;
6381 q += 4;
6382 skip_whitespace (q);
6384 for (r = q; *r != '\0'; r++)
6385 if (*r == ' ')
6386 break;
6388 if (r != q)
6390 int regnum;
6391 char d = *r;
6393 *r = '\0';
6394 regnum = arm_reg_parse (& q);
6395 *r = d;
6397 reg = arm_reg_parse (& str);
6399 if (reg == FAIL)
6401 if (regnum != FAIL)
6402 insert_reg_alias (str, regnum);
6403 else
6404 as_warn (_("register '%s' does not exist\n"), q);
6406 else if (regnum != FAIL)
6408 if (reg != regnum)
6409 as_warn (_("ignoring redefinition of register alias '%s'"),
6410 copy_of_str );
6412 /* Do not warn about redefinitions to the same alias. */
6414 else
6415 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6416 copy_of_str, q);
6418 else
6419 as_warn (_("ignoring incomplete .req pseuso op"));
6421 *p = c;
6422 return;
6425 *p = c;
6426 as_bad (_("bad instruction `%s'"), start);
6430 * md_parse_option
6431 * Invocation line includes a switch not recognized by the base assembler.
6432 * See if it's a processor-specific option. These are:
6433 * Cpu variants, the arm part is optional:
6434 * -m[arm]1 Currently not supported.
6435 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6436 * -m[arm]3 Arm 3 processor
6437 * -m[arm]6[xx], Arm 6 processors
6438 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6439 * -m[arm]8[10] Arm 8 processors
6440 * -m[arm]9[20][tdmi] Arm 9 processors
6441 * -mstrongarm[110[0]] StrongARM processors
6442 * -m[arm]v[2345[t]] Arm architectures
6443 * -mall All (except the ARM1)
6444 * FP variants:
6445 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6446 * -mfpe-old (No float load/store multiples)
6447 * -mno-fpu Disable all floating point instructions
6448 * Run-time endian selection:
6449 * -EB big endian cpu
6450 * -EL little endian cpu
6451 * ARM Procedure Calling Standard:
6452 * -mapcs-32 32 bit APCS
6453 * -mapcs-26 26 bit APCS
6454 * -mapcs-float Pass floats in float regs
6455 * -mapcs-reentrant Position independent code
6456 * -mthumb-interwork Code supports Arm/Thumb interworking
6457 * -moabi Old ELF ABI
6460 CONST char * md_shortopts = "m:k";
6461 struct option md_longopts[] =
6463 #ifdef ARM_BI_ENDIAN
6464 #define OPTION_EB (OPTION_MD_BASE + 0)
6465 {"EB", no_argument, NULL, OPTION_EB},
6466 #define OPTION_EL (OPTION_MD_BASE + 1)
6467 {"EL", no_argument, NULL, OPTION_EL},
6468 #ifdef OBJ_ELF
6469 #define OPTION_OABI (OPTION_MD_BASE +2)
6470 {"oabi", no_argument, NULL, OPTION_OABI},
6471 #endif
6472 #endif
6473 {NULL, no_argument, NULL, 0}
6475 size_t md_longopts_size = sizeof (md_longopts);
6478 md_parse_option (c, arg)
6479 int c;
6480 char * arg;
6482 char * str = arg;
6484 switch (c)
6486 #ifdef ARM_BI_ENDIAN
6487 case OPTION_EB:
6488 target_big_endian = 1;
6489 break;
6490 case OPTION_EL:
6491 target_big_endian = 0;
6492 break;
6493 #endif
6495 case 'm':
6496 switch (*str)
6498 case 'f':
6499 if (streq (str, "fpa10"))
6500 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
6501 else if (streq (str, "fpa11"))
6502 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
6503 else if (streq (str, "fpe-old"))
6504 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
6505 else
6506 goto bad;
6507 break;
6509 case 'n':
6510 if (streq (str, "no-fpu"))
6511 cpu_variant &= ~FPU_ALL;
6512 break;
6514 #ifdef OBJ_ELF
6515 case 'o':
6516 if (streq (str, "oabi"))
6517 target_oabi = true;
6518 break;
6519 #endif
6521 case 't':
6522 /* Limit assembler to generating only Thumb instructions: */
6523 if (streq (str, "thumb"))
6525 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
6526 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6527 thumb_mode = 1;
6529 else if (streq (str, "thumb-interwork"))
6531 if ((cpu_variant & ARM_THUMB) == 0)
6532 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T;
6533 #if defined OBJ_COFF || defined OBJ_ELF
6534 support_interwork = true;
6535 #endif
6537 else
6538 goto bad;
6539 break;
6541 default:
6542 if (streq (str, "all"))
6544 cpu_variant = ARM_ALL | FPU_ALL;
6545 return 1;
6547 #if defined OBJ_COFF || defined OBJ_ELF
6548 if (! strncmp (str, "apcs-", 5))
6550 /* GCC passes on all command line options starting "-mapcs-..."
6551 to us, so we must parse them here. */
6553 str += 5;
6555 if (streq (str, "32"))
6557 uses_apcs_26 = false;
6558 return 1;
6560 else if (streq (str, "26"))
6562 uses_apcs_26 = true;
6563 return 1;
6565 else if (streq (str, "frame"))
6567 /* Stack frames are being generated - does not affect
6568 linkage of code. */
6569 return 1;
6571 else if (streq (str, "stack-check"))
6573 /* Stack checking is being performed - does not affect
6574 linkage, but does require that the functions
6575 __rt_stkovf_split_small and __rt_stkovf_split_big be
6576 present in the final link. */
6578 return 1;
6580 else if (streq (str, "float"))
6582 /* Floating point arguments are being passed in the floating
6583 point registers. This does affect linking, since this
6584 version of the APCS is incompatible with the version that
6585 passes floating points in the integer registers. */
6587 uses_apcs_float = true;
6588 return 1;
6590 else if (streq (str, "reentrant"))
6592 /* Reentrant code has been generated. This does affect
6593 linking, since there is no point in linking reentrant/
6594 position independent code with absolute position code. */
6595 pic_code = true;
6596 return 1;
6599 as_bad (_("Unrecognised APCS switch -m%s"), arg);
6600 return 0;
6602 #endif
6603 /* Strip off optional "arm" */
6604 if (! strncmp (str, "arm", 3))
6605 str += 3;
6607 switch (*str)
6609 case '1':
6610 if (streq (str, "1"))
6611 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6612 else
6613 goto bad;
6614 break;
6616 case '2':
6617 if (streq (str, "2"))
6618 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6619 else if (streq (str, "250"))
6620 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6621 else
6622 goto bad;
6623 break;
6625 case '3':
6626 if (streq (str, "3"))
6627 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6628 else
6629 goto bad;
6630 break;
6632 case '6':
6633 switch (strtol (str, NULL, 10))
6635 case 6:
6636 case 60:
6637 case 600:
6638 case 610:
6639 case 620:
6640 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6641 break;
6642 default:
6643 goto bad;
6645 break;
6647 case '7':
6648 switch (strtol (str, & str, 10)) /* Eat the processor name */
6650 case 7:
6651 case 70:
6652 case 700:
6653 case 710:
6654 case 720:
6655 case 7100:
6656 case 7500:
6657 break;
6658 default:
6659 goto bad;
6661 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6662 for (; *str; str++)
6664 switch (* str)
6666 case 't':
6667 cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
6668 break;
6670 case 'm':
6671 cpu_variant |= ARM_LONGMUL;
6672 break;
6674 case 'f': /* fe => fp enabled cpu. */
6675 if (str[1] == 'e')
6676 ++ str;
6677 else
6678 goto bad;
6680 case 'c': /* Left over from 710c processor name. */
6681 case 'd': /* Debug */
6682 case 'i': /* Embedded ICE */
6683 /* Included for completeness in ARM processor naming. */
6684 break;
6686 default:
6687 goto bad;
6690 break;
6692 case '8':
6693 if (streq (str, "8") || streq (str, "810"))
6694 cpu_variant = (cpu_variant & ~ARM_ANY)
6695 | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6696 else
6697 goto bad;
6698 break;
6700 case '9':
6701 if (streq (str, "9"))
6702 cpu_variant = (cpu_variant & ~ARM_ANY)
6703 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6704 else if (streq (str, "920"))
6705 cpu_variant = (cpu_variant & ~ARM_ANY)
6706 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
6707 else if (streq (str, "920t"))
6708 cpu_variant = (cpu_variant & ~ARM_ANY)
6709 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6710 else if (streq (str, "9tdmi"))
6711 cpu_variant = (cpu_variant & ~ARM_ANY)
6712 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6713 else
6714 goto bad;
6715 break;
6718 case 's':
6719 if (streq (str, "strongarm")
6720 || streq (str, "strongarm110")
6721 || streq (str, "strongarm1100"))
6722 cpu_variant = (cpu_variant & ~ARM_ANY)
6723 | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6724 else
6725 goto bad;
6726 break;
6728 case 'v':
6729 /* Select variant based on architecture rather than processor. */
6730 switch (*++str)
6732 case '2':
6733 switch (*++str)
6735 case 'a':
6736 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6737 break;
6738 case 0:
6739 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6740 break;
6741 default:
6742 as_bad (_("Invalid architecture variant -m%s"), arg);
6743 break;
6745 break;
6747 case '3':
6748 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6750 switch (*++str)
6752 case 'm': cpu_variant |= ARM_LONGMUL; break;
6753 case 0: break;
6754 default:
6755 as_bad (_("Invalid architecture variant -m%s"), arg);
6756 break;
6758 break;
6760 case '4':
6761 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4;
6763 switch (*++str)
6765 case 't': cpu_variant |= ARM_THUMB; break;
6766 case 0: break;
6767 default:
6768 as_bad (_("Invalid architecture variant -m%s"), arg);
6769 break;
6771 break;
6773 case '5':
6774 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
6775 switch (*++str)
6777 case 't': cpu_variant |= ARM_THUMB; break;
6778 case 0: break;
6779 default:
6780 as_bad (_("Invalid architecture variant -m%s"), arg);
6781 break;
6783 break;
6785 default:
6786 as_bad (_("Invalid architecture variant -m%s"), arg);
6787 break;
6789 break;
6791 default:
6792 bad:
6793 as_bad (_("Invalid processor variant -m%s"), arg);
6794 return 0;
6797 break;
6799 #if defined OBJ_ELF || defined OBJ_COFF
6800 case 'k':
6801 pic_code = 1;
6802 break;
6803 #endif
6805 default:
6806 return 0;
6809 return 1;
6812 void
6813 md_show_usage (fp)
6814 FILE * fp;
6816 fprintf (fp, _("\
6817 ARM Specific Assembler Options:\n\
6818 -m[arm][<processor name>] select processor variant\n\
6819 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
6820 -mthumb only allow Thumb instructions\n\
6821 -mthumb-interwork mark the assembled code as supporting interworking\n\
6822 -mall allow any instruction\n\
6823 -mfpa10, -mfpa11 select floating point architecture\n\
6824 -mfpe-old don't allow floating-point multiple instructions\n\
6825 -mno-fpu don't allow any floating-point instructions.\n\
6826 -k generate PIC code.\n"));
6827 #if defined OBJ_COFF || defined OBJ_ELF
6828 fprintf (fp, _("\
6829 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
6830 -mapcs-float floating point args are passed in FP regs\n\
6831 -mapcs-reentrant the code is position independent/reentrant\n"));
6832 #endif
6833 #ifdef OBJ_ELF
6834 fprintf (fp, _("\
6835 -moabi support the old ELF ABI\n"));
6836 #endif
6837 #ifdef ARM_BI_ENDIAN
6838 fprintf (fp, _("\
6839 -EB assemble code for a big endian cpu\n\
6840 -EL assemble code for a little endian cpu\n"));
6841 #endif
6844 /* We need to be able to fix up arbitrary expressions in some statements.
6845 This is so that we can handle symbols that are an arbitrary distance from
6846 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6847 which returns part of an address in a form which will be valid for
6848 a data instruction. We do this by pushing the expression into a symbol
6849 in the expr_section, and creating a fix for that. */
6851 static void
6852 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6853 fragS * frag;
6854 int where;
6855 short int size;
6856 expressionS * exp;
6857 int pc_rel;
6858 int reloc;
6860 fixS * new_fix;
6861 arm_fix_data * arm_data;
6863 switch (exp->X_op)
6865 case O_constant:
6866 case O_symbol:
6867 case O_add:
6868 case O_subtract:
6869 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6870 break;
6872 default:
6873 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6874 pc_rel, reloc);
6875 break;
6878 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6879 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
6880 new_fix->tc_fix_data = (PTR) arm_data;
6881 arm_data->thumb_mode = thumb_mode;
6883 return;
6887 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6888 void
6889 cons_fix_new_arm (frag, where, size, exp)
6890 fragS * frag;
6891 int where;
6892 int size;
6893 expressionS * exp;
6895 bfd_reloc_code_real_type type;
6896 int pcrel = 0;
6898 /* Pick a reloc ...
6900 * @@ Should look at CPU word size.
6902 switch (size)
6904 case 2:
6905 type = BFD_RELOC_16;
6906 break;
6907 case 4:
6908 default:
6909 type = BFD_RELOC_32;
6910 break;
6911 case 8:
6912 type = BFD_RELOC_64;
6913 break;
6916 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
6919 /* A good place to do this, although this was probably not intended
6920 for this kind of use. We need to dump the literal pool before
6921 references are made to a null symbol pointer. */
6922 void
6923 arm_cleanup ()
6925 if (current_poolP == NULL)
6926 return;
6928 subseg_set (text_section, 0); /* Put it at the end of text section. */
6929 s_ltorg (0);
6930 listing_prev_line ();
6933 void
6934 arm_start_line_hook ()
6936 last_label_seen = NULL;
6939 void
6940 arm_frob_label (sym)
6941 symbolS * sym;
6943 last_label_seen = sym;
6945 ARM_SET_THUMB (sym, thumb_mode);
6947 #if defined OBJ_COFF || defined OBJ_ELF
6948 ARM_SET_INTERWORK (sym, support_interwork);
6949 #endif
6951 if (label_is_thumb_function_name)
6953 /* When the address of a Thumb function is taken the bottom
6954 bit of that address should be set. This will allow
6955 interworking between Arm and Thumb functions to work
6956 correctly. */
6958 THUMB_SET_FUNC (sym, 1);
6960 label_is_thumb_function_name = false;
6964 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6965 ARM ones. */
6967 void
6968 arm_adjust_symtab ()
6970 #ifdef OBJ_COFF
6971 symbolS * sym;
6973 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6975 if (ARM_IS_THUMB (sym))
6977 if (THUMB_IS_FUNC (sym))
6979 /* Mark the symbol as a Thumb function. */
6980 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
6981 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6982 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6984 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6985 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6986 else
6987 as_bad (_("%s: unexpected function type: %d"),
6988 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6990 else switch (S_GET_STORAGE_CLASS (sym))
6992 case C_EXT:
6993 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6994 break;
6995 case C_STAT:
6996 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6997 break;
6998 case C_LABEL:
6999 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
7000 break;
7001 default: /* do nothing */
7002 break;
7006 if (ARM_IS_INTERWORK (sym))
7007 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
7009 #endif
7010 #ifdef OBJ_ELF
7011 symbolS * sym;
7012 char bind;
7014 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
7016 if (ARM_IS_THUMB (sym))
7018 elf_symbol_type * elf_sym;
7020 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
7021 bind = ELF_ST_BIND (elf_sym);
7023 /* If it's a .thumb_func, declare it as so,
7024 otherwise tag label as .code 16. */
7025 if (THUMB_IS_FUNC (sym))
7026 elf_sym->internal_elf_sym.st_info =
7027 ELF_ST_INFO (bind, STT_ARM_TFUNC);
7028 else
7029 elf_sym->internal_elf_sym.st_info =
7030 ELF_ST_INFO (bind, STT_ARM_16BIT);
7033 #endif
7037 arm_data_in_code ()
7039 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
7041 *input_line_pointer = '/';
7042 input_line_pointer += 5;
7043 *input_line_pointer = 0;
7044 return 1;
7047 return 0;
7050 char *
7051 arm_canonicalize_symbol_name (name)
7052 char * name;
7054 int len;
7056 if (thumb_mode && (len = strlen (name)) > 5
7057 && streq (name + len - 5, "/data"))
7058 *(name + len - 5) = 0;
7060 return name;
7063 boolean
7064 arm_validate_fix (fixP)
7065 fixS * fixP;
7067 /* If the destination of the branch is a defined symbol which does not have
7068 the THUMB_FUNC attribute, then we must be calling a function which has
7069 the (interfacearm) attribute. We look for the Thumb entry point to that
7070 function and change the branch to refer to that function instead. */
7071 if ( fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
7072 && fixP->fx_addsy != NULL
7073 && S_IS_DEFINED (fixP->fx_addsy)
7074 && ! THUMB_IS_FUNC (fixP->fx_addsy))
7076 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
7077 return true;
7080 return false;
7083 #ifdef OBJ_ELF
7084 /* Relocations against Thumb function names must be left unadjusted,
7085 so that the linker can use this information to correctly set the
7086 bottom bit of their addresses. The MIPS version of this function
7087 also prevents relocations that are mips-16 specific, but I do not
7088 know why it does this.
7090 FIXME:
7091 There is one other problem that ought to be addressed here, but
7092 which currently is not: Taking the address of a label (rather
7093 than a function) and then later jumping to that address. Such
7094 addresses also ought to have their bottom bit set (assuming that
7095 they reside in Thumb code), but at the moment they will not. */
7097 boolean
7098 arm_fix_adjustable (fixP)
7099 fixS * fixP;
7101 if (fixP->fx_addsy == NULL)
7102 return 1;
7104 /* Prevent all adjustments to global symbols. */
7105 if (S_IS_EXTERN (fixP->fx_addsy))
7106 return 0;
7108 if (S_IS_WEAK (fixP->fx_addsy))
7109 return 0;
7111 if (THUMB_IS_FUNC (fixP->fx_addsy)
7112 && fixP->fx_subsy == NULL)
7113 return 0;
7115 /* We need the symbol name for the VTABLE entries */
7116 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7117 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
7118 return 0;
7120 return 1;
7123 const char *
7124 elf32_arm_target_format ()
7126 if (target_big_endian)
7127 if (target_oabi)
7128 return "elf32-bigarm-oabi";
7129 else
7130 return "elf32-bigarm";
7131 else
7132 if (target_oabi)
7133 return "elf32-littlearm-oabi";
7134 else
7135 return "elf32-littlearm";
7138 void
7139 armelf_frob_symbol (symp, puntp)
7140 symbolS * symp;
7141 int * puntp;
7143 elf_frob_symbol (symp, puntp);
7147 arm_force_relocation (fixp)
7148 struct fix * fixp;
7150 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7151 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
7152 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
7153 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
7154 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
7155 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
7156 return 1;
7158 return 0;
7161 static bfd_reloc_code_real_type
7162 arm_parse_reloc ()
7164 char id[16];
7165 char * ip;
7166 unsigned int i;
7167 static struct
7169 char * str;
7170 int len;
7171 bfd_reloc_code_real_type reloc;
7173 reloc_map[] =
7175 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7176 MAP ("(got)", BFD_RELOC_ARM_GOT32),
7177 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
7178 /* ScottB: Jan 30, 1998 */
7179 /* Added support for parsing "var(PLT)" branch instructions */
7180 /* generated by GCC for PLT relocs */
7181 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
7182 { NULL, 0, BFD_RELOC_UNUSED }
7183 #undef MAP
7186 for (i = 0, ip = input_line_pointer;
7187 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
7188 i++, ip++)
7189 id[i] = tolower (*ip);
7191 for (i = 0; reloc_map[i].str; i++)
7192 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
7193 break;
7195 input_line_pointer += reloc_map[i].len;
7197 return reloc_map[i].reloc;
7200 static void
7201 s_arm_elf_cons (nbytes)
7202 int nbytes;
7204 expressionS exp;
7206 #ifdef md_flush_pending_output
7207 md_flush_pending_output ();
7208 #endif
7210 if (is_it_end_of_statement ())
7212 demand_empty_rest_of_line ();
7213 return;
7216 #ifdef md_cons_align
7217 md_cons_align (nbytes);
7218 #endif
7222 bfd_reloc_code_real_type reloc;
7224 expression (& exp);
7226 if (exp.X_op == O_symbol
7227 && * input_line_pointer == '('
7228 && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
7230 reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
7231 int size = bfd_get_reloc_size (howto);
7233 if (size > nbytes)
7234 as_bad ("%s relocations do not fit in %d bytes",
7235 howto->name, nbytes);
7236 else
7238 register char * p = frag_more ((int) nbytes);
7239 int offset = nbytes - size;
7241 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
7242 & exp, 0, reloc);
7245 else
7246 emit_expr (& exp, (unsigned int) nbytes);
7248 while (*input_line_pointer++ == ',');
7250 input_line_pointer--; /* Put terminator back into stream. */
7251 demand_empty_rest_of_line ();
7254 #endif /* OBJ_ELF */