2000-06-06 Michael Snyder <msnyder@seadog.cygnus.com>
[binutils.git] / gas / config / tc-arm.c
blob1a9ebc8020687a2d7493f01495e2e3177cb69d34
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 int skip = 0;
1919 /* Only one syntax. */
1920 skip_whitespace (str);
1922 if (reg_required_here (&str, 12) == FAIL)
1924 inst.error = BAD_ARGS;
1925 return;
1928 if (skip_past_comma (&str) == FAIL)
1930 inst.error = _("comma expected after register name");
1931 return;
1934 skip_whitespace (str);
1936 if ( strcmp (str, "CPSR") == 0
1937 || strcmp (str, "SPSR") == 0
1938 /* Lower case versions for backwards compatability. */
1939 || strcmp (str, "cpsr") == 0
1940 || strcmp (str, "spsr") == 0)
1941 skip = 4;
1942 /* This is for backwards compatability with older toolchains. */
1943 else if (strcmp (str, "cpsr_all") == 0
1944 || strcmp (str, "spsr_all") == 0)
1945 skip = 7;
1946 else
1948 inst.error = _("{C|S}PSR expected");
1949 return;
1952 if (* str == 's' || * str == 'S')
1953 inst.instruction |= SPSR_BIT;
1954 str += skip;
1956 inst.instruction |= flags;
1957 end_of_line (str);
1960 /* Two possible forms:
1961 "{C|S}PSR_<field>, Rm",
1962 "{C|S}PSR_f, #expression". */
1963 static void
1964 do_msr (str, flags)
1965 char * str;
1966 unsigned long flags;
1968 skip_whitespace (str);
1970 if (psr_required_here (& str) == FAIL)
1971 return;
1973 if (skip_past_comma (& str) == FAIL)
1975 inst.error = _("comma missing after psr flags");
1976 return;
1979 skip_whitespace (str);
1981 if (reg_required_here (& str, 0) != FAIL)
1983 inst.error = NULL;
1984 inst.instruction |= flags;
1985 end_of_line (str);
1986 return;
1989 if (! is_immediate_prefix (* str))
1991 inst.error = _("only a register or immediate value can follow a psr flag");
1992 return;
1995 str ++;
1996 inst.error = NULL;
1998 if (my_get_expression (& inst.reloc.exp, & str))
2000 inst.error = _("only a register or immediate value can follow a psr flag");
2001 return;
2004 if (inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
2006 inst.error = _("can only set flag field with immediate value");
2007 return;
2010 flags |= INST_IMMEDIATE;
2012 if (inst.reloc.exp.X_add_symbol)
2014 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2015 inst.reloc.pc_rel = 0;
2017 else
2019 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
2021 if (value == (unsigned) FAIL)
2023 inst.error = _("Invalid constant");
2024 return;
2027 inst.instruction |= value;
2030 inst.error = NULL;
2031 inst.instruction |= flags;
2032 end_of_line (str);
2035 /* Long Multiply Parser
2036 UMULL RdLo, RdHi, Rm, Rs
2037 SMULL RdLo, RdHi, Rm, Rs
2038 UMLAL RdLo, RdHi, Rm, Rs
2039 SMLAL RdLo, RdHi, Rm, Rs
2041 static void
2042 do_mull (str, flags)
2043 char * str;
2044 unsigned long flags;
2046 int rdlo, rdhi, rm, rs;
2048 /* Only one format "rdlo, rdhi, rm, rs" */
2049 skip_whitespace (str);
2051 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
2053 inst.error = BAD_ARGS;
2054 return;
2057 if (skip_past_comma (&str) == FAIL
2058 || (rdhi = reg_required_here (&str, 16)) == FAIL)
2060 inst.error = BAD_ARGS;
2061 return;
2064 if (skip_past_comma (&str) == FAIL
2065 || (rm = reg_required_here (&str, 0)) == FAIL)
2067 inst.error = BAD_ARGS;
2068 return;
2071 /* rdhi, rdlo and rm must all be different */
2072 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
2073 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2075 if (skip_past_comma (&str) == FAIL
2076 || (rs = reg_required_here (&str, 8)) == FAIL)
2078 inst.error = BAD_ARGS;
2079 return;
2082 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2084 inst.error = BAD_PC;
2085 return;
2088 inst.instruction |= flags;
2089 end_of_line (str);
2090 return;
2093 static void
2094 do_mul (str, flags)
2095 char * str;
2096 unsigned long flags;
2098 int rd, rm;
2100 /* Only one format "rd, rm, rs" */
2101 skip_whitespace (str);
2103 if ((rd = reg_required_here (&str, 16)) == FAIL)
2105 inst.error = BAD_ARGS;
2106 return;
2109 if (rd == REG_PC)
2111 inst.error = BAD_PC;
2112 return;
2115 if (skip_past_comma (&str) == FAIL
2116 || (rm = reg_required_here (&str, 0)) == FAIL)
2118 inst.error = BAD_ARGS;
2119 return;
2122 if (rm == REG_PC)
2124 inst.error = BAD_PC;
2125 return;
2128 if (rm == rd)
2129 as_tsktsk (_("rd and rm should be different in mul"));
2131 if (skip_past_comma (&str) == FAIL
2132 || (rm = reg_required_here (&str, 8)) == FAIL)
2134 inst.error = BAD_ARGS;
2135 return;
2138 if (rm == REG_PC)
2140 inst.error = BAD_PC;
2141 return;
2144 inst.instruction |= flags;
2145 end_of_line (str);
2146 return;
2149 static void
2150 do_mla (str, flags)
2151 char * str;
2152 unsigned long flags;
2154 int rd, rm;
2156 /* Only one format "rd, rm, rs, rn" */
2157 skip_whitespace (str);
2159 if ((rd = reg_required_here (&str, 16)) == FAIL)
2161 inst.error = BAD_ARGS;
2162 return;
2165 if (rd == REG_PC)
2167 inst.error = BAD_PC;
2168 return;
2171 if (skip_past_comma (&str) == FAIL
2172 || (rm = reg_required_here (&str, 0)) == FAIL)
2174 inst.error = BAD_ARGS;
2175 return;
2178 if (rm == REG_PC)
2180 inst.error = BAD_PC;
2181 return;
2184 if (rm == rd)
2185 as_tsktsk (_("rd and rm should be different in mla"));
2187 if (skip_past_comma (&str) == FAIL
2188 || (rd = reg_required_here (&str, 8)) == FAIL
2189 || skip_past_comma (&str) == FAIL
2190 || (rm = reg_required_here (&str, 12)) == FAIL)
2192 inst.error = BAD_ARGS;
2193 return;
2196 if (rd == REG_PC || rm == REG_PC)
2198 inst.error = BAD_PC;
2199 return;
2202 inst.instruction |= flags;
2203 end_of_line (str);
2204 return;
2207 /* Returns the index into fp_values of a floating point number, or -1 if
2208 not in the table. */
2209 static int
2210 my_get_float_expression (str)
2211 char ** str;
2213 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2214 char * save_in;
2215 expressionS exp;
2216 int i;
2217 int j;
2219 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
2220 /* Look for a raw floating point number */
2221 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
2222 && is_end_of_line [(unsigned char) *save_in])
2224 for (i = 0; i < NUM_FLOAT_VALS; i++)
2226 for (j = 0; j < MAX_LITTLENUMS; j++)
2228 if (words[j] != fp_values[i][j])
2229 break;
2232 if (j == MAX_LITTLENUMS)
2234 *str = save_in;
2235 return i;
2240 /* Try and parse a more complex expression, this will probably fail
2241 unless the code uses a floating point prefix (eg "0f") */
2242 save_in = input_line_pointer;
2243 input_line_pointer = *str;
2244 if (expression (&exp) == absolute_section
2245 && exp.X_op == O_big
2246 && exp.X_add_number < 0)
2248 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2249 Ditto for 15. */
2250 if (gen_to_words (words, 5, (long)15) == 0)
2252 for (i = 0; i < NUM_FLOAT_VALS; i++)
2254 for (j = 0; j < MAX_LITTLENUMS; j++)
2256 if (words[j] != fp_values[i][j])
2257 break;
2260 if (j == MAX_LITTLENUMS)
2262 *str = input_line_pointer;
2263 input_line_pointer = save_in;
2264 return i;
2270 *str = input_line_pointer;
2271 input_line_pointer = save_in;
2272 return -1;
2275 /* Return true if anything in the expression is a bignum */
2276 static int
2277 walk_no_bignums (sp)
2278 symbolS * sp;
2280 if (symbol_get_value_expression (sp)->X_op == O_big)
2281 return 1;
2283 if (symbol_get_value_expression (sp)->X_add_symbol)
2285 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
2286 || (symbol_get_value_expression (sp)->X_op_symbol
2287 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
2290 return 0;
2293 static int
2294 my_get_expression (ep, str)
2295 expressionS * ep;
2296 char ** str;
2298 char * save_in;
2299 segT seg;
2301 save_in = input_line_pointer;
2302 input_line_pointer = *str;
2303 seg = expression (ep);
2305 #ifdef OBJ_AOUT
2306 if (seg != absolute_section
2307 && seg != text_section
2308 && seg != data_section
2309 && seg != bss_section
2310 && seg != undefined_section)
2312 inst.error = _("bad_segment");
2313 *str = input_line_pointer;
2314 input_line_pointer = save_in;
2315 return 1;
2317 #endif
2319 /* Get rid of any bignums now, so that we don't generate an error for which
2320 we can't establish a line number later on. Big numbers are never valid
2321 in instructions, which is where this routine is always called. */
2322 if (ep->X_op == O_big
2323 || (ep->X_add_symbol
2324 && (walk_no_bignums (ep->X_add_symbol)
2325 || (ep->X_op_symbol
2326 && walk_no_bignums (ep->X_op_symbol)))))
2328 inst.error = _("Invalid constant");
2329 *str = input_line_pointer;
2330 input_line_pointer = save_in;
2331 return 1;
2334 *str = input_line_pointer;
2335 input_line_pointer = save_in;
2336 return 0;
2339 /* unrestrict should be one if <shift> <register> is permitted for this
2340 instruction */
2342 static int
2343 decode_shift (str, unrestrict)
2344 char ** str;
2345 int unrestrict;
2347 struct asm_shift * shft;
2348 char * p;
2349 char c;
2351 skip_whitespace (* str);
2353 for (p = *str; isalpha (*p); p++)
2356 if (p == *str)
2358 inst.error = _("Shift expression expected");
2359 return FAIL;
2362 c = *p;
2363 *p = '\0';
2364 shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
2365 *p = c;
2366 if (shft)
2368 if (!strncmp (*str, "rrx", 3)
2369 || !strncmp (*str, "RRX", 3))
2371 *str = p;
2372 inst.instruction |= shft->value;
2373 return SUCCESS;
2376 skip_whitespace (p);
2378 if (unrestrict && reg_required_here (&p, 8) != FAIL)
2380 inst.instruction |= shft->value | SHIFT_BY_REG;
2381 *str = p;
2382 return SUCCESS;
2384 else if (is_immediate_prefix (* p))
2386 inst.error = NULL;
2387 p++;
2388 if (my_get_expression (&inst.reloc.exp, &p))
2389 return FAIL;
2391 /* Validate some simple #expressions */
2392 if (inst.reloc.exp.X_op == O_constant)
2394 unsigned num = inst.reloc.exp.X_add_number;
2396 /* Reject operations greater than 32, or lsl #32 */
2397 if (num > 32 || (num == 32 && shft->value == 0))
2399 inst.error = _("Invalid immediate shift");
2400 return FAIL;
2403 /* Shifts of zero should be converted to lsl (which is zero)*/
2404 if (num == 0)
2406 *str = p;
2407 return SUCCESS;
2410 /* Shifts of 32 are encoded as 0, for those shifts that
2411 support it. */
2412 if (num == 32)
2413 num = 0;
2415 inst.instruction |= (num << 7) | shft->value;
2416 *str = p;
2417 return SUCCESS;
2420 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
2421 inst.reloc.pc_rel = 0;
2422 inst.instruction |= shft->value;
2423 *str = p;
2424 return SUCCESS;
2426 else
2428 inst.error = unrestrict ? _("shift requires register or #expression")
2429 : _("shift requires #expression");
2430 *str = p;
2431 return FAIL;
2435 inst.error = _("Shift expression expected");
2436 return FAIL;
2439 /* Do those data_ops which can take a negative immediate constant */
2440 /* by altering the instuction. A bit of a hack really */
2441 /* MOV <-> MVN
2442 AND <-> BIC
2443 ADC <-> SBC
2444 by inverting the second operand, and
2445 ADD <-> SUB
2446 CMP <-> CMN
2447 by negating the second operand.
2449 static int
2450 negate_data_op (instruction, value)
2451 unsigned long * instruction;
2452 unsigned long value;
2454 int op, new_inst;
2455 unsigned long negated, inverted;
2457 negated = validate_immediate (-value);
2458 inverted = validate_immediate (~value);
2460 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
2461 switch (op)
2463 /* First negates */
2464 case OPCODE_SUB: /* ADD <-> SUB */
2465 new_inst = OPCODE_ADD;
2466 value = negated;
2467 break;
2469 case OPCODE_ADD:
2470 new_inst = OPCODE_SUB;
2471 value = negated;
2472 break;
2474 case OPCODE_CMP: /* CMP <-> CMN */
2475 new_inst = OPCODE_CMN;
2476 value = negated;
2477 break;
2479 case OPCODE_CMN:
2480 new_inst = OPCODE_CMP;
2481 value = negated;
2482 break;
2484 /* Now Inverted ops */
2485 case OPCODE_MOV: /* MOV <-> MVN */
2486 new_inst = OPCODE_MVN;
2487 value = inverted;
2488 break;
2490 case OPCODE_MVN:
2491 new_inst = OPCODE_MOV;
2492 value = inverted;
2493 break;
2495 case OPCODE_AND: /* AND <-> BIC */
2496 new_inst = OPCODE_BIC;
2497 value = inverted;
2498 break;
2500 case OPCODE_BIC:
2501 new_inst = OPCODE_AND;
2502 value = inverted;
2503 break;
2505 case OPCODE_ADC: /* ADC <-> SBC */
2506 new_inst = OPCODE_SBC;
2507 value = inverted;
2508 break;
2510 case OPCODE_SBC:
2511 new_inst = OPCODE_ADC;
2512 value = inverted;
2513 break;
2515 /* We cannot do anything */
2516 default:
2517 return FAIL;
2520 if (value == (unsigned) FAIL)
2521 return FAIL;
2523 *instruction &= OPCODE_MASK;
2524 *instruction |= new_inst << DATA_OP_SHIFT;
2525 return value;
2528 static int
2529 data_op2 (str)
2530 char ** str;
2532 int value;
2533 expressionS expr;
2535 skip_whitespace (* str);
2537 if (reg_required_here (str, 0) != FAIL)
2539 if (skip_past_comma (str) == SUCCESS)
2540 /* Shift operation on register. */
2541 return decode_shift (str, NO_SHIFT_RESTRICT);
2543 return SUCCESS;
2545 else
2547 /* Immediate expression */
2548 if (is_immediate_prefix (**str))
2550 (*str)++;
2551 inst.error = NULL;
2553 if (my_get_expression (&inst.reloc.exp, str))
2554 return FAIL;
2556 if (inst.reloc.exp.X_add_symbol)
2558 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2559 inst.reloc.pc_rel = 0;
2561 else
2563 if (skip_past_comma (str) == SUCCESS)
2565 /* #x, y -- ie explicit rotation by Y */
2566 if (my_get_expression (&expr, str))
2567 return FAIL;
2569 if (expr.X_op != O_constant)
2571 inst.error = _("Constant expression expected");
2572 return FAIL;
2575 /* Rotate must be a multiple of 2 */
2576 if (((unsigned) expr.X_add_number) > 30
2577 || (expr.X_add_number & 1) != 0
2578 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
2580 inst.error = _("Invalid constant");
2581 return FAIL;
2583 inst.instruction |= INST_IMMEDIATE;
2584 inst.instruction |= inst.reloc.exp.X_add_number;
2585 inst.instruction |= expr.X_add_number << 7;
2586 return SUCCESS;
2589 /* Implicit rotation, select a suitable one */
2590 value = validate_immediate (inst.reloc.exp.X_add_number);
2592 if (value == FAIL)
2594 /* Can't be done, perhaps the code reads something like
2595 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2596 if ((value = negate_data_op (&inst.instruction,
2597 inst.reloc.exp.X_add_number))
2598 == FAIL)
2600 inst.error = _("Invalid constant");
2601 return FAIL;
2605 inst.instruction |= value;
2608 inst.instruction |= INST_IMMEDIATE;
2609 return SUCCESS;
2612 (*str)++;
2613 inst.error = _("Register or shift expression expected");
2614 return FAIL;
2618 static int
2619 fp_op2 (str)
2620 char ** str;
2622 skip_whitespace (* str);
2624 if (fp_reg_required_here (str, 0) != FAIL)
2625 return SUCCESS;
2626 else
2628 /* Immediate expression */
2629 if (*((*str)++) == '#')
2631 int i;
2633 inst.error = NULL;
2635 skip_whitespace (* str);
2637 /* First try and match exact strings, this is to guarantee that
2638 some formats will work even for cross assembly */
2640 for (i = 0; fp_const[i]; i++)
2642 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2644 char *start = *str;
2646 *str += strlen (fp_const[i]);
2647 if (is_end_of_line[(unsigned char) **str])
2649 inst.instruction |= i + 8;
2650 return SUCCESS;
2652 *str = start;
2656 /* Just because we didn't get a match doesn't mean that the
2657 constant isn't valid, just that it is in a format that we
2658 don't automatically recognize. Try parsing it with
2659 the standard expression routines. */
2660 if ((i = my_get_float_expression (str)) >= 0)
2662 inst.instruction |= i + 8;
2663 return SUCCESS;
2666 inst.error = _("Invalid floating point immediate expression");
2667 return FAIL;
2669 inst.error = _("Floating point register or immediate expression expected");
2670 return FAIL;
2674 static void
2675 do_arit (str, flags)
2676 char * str;
2677 unsigned long flags;
2679 skip_whitespace (str);
2681 if (reg_required_here (&str, 12) == FAIL
2682 || skip_past_comma (&str) == FAIL
2683 || reg_required_here (&str, 16) == FAIL
2684 || skip_past_comma (&str) == FAIL
2685 || data_op2 (&str) == FAIL)
2687 if (!inst.error)
2688 inst.error = BAD_ARGS;
2689 return;
2692 inst.instruction |= flags;
2693 end_of_line (str);
2694 return;
2697 static void
2698 do_adr (str, flags)
2699 char * str;
2700 unsigned long flags;
2702 /* This is a pseudo-op of the form "adr rd, label" to be converted
2703 into a relative address of the form "add rd, pc, #label-.-8". */
2704 skip_whitespace (str);
2706 if (reg_required_here (&str, 12) == FAIL
2707 || skip_past_comma (&str) == FAIL
2708 || my_get_expression (&inst.reloc.exp, &str))
2710 if (!inst.error)
2711 inst.error = BAD_ARGS;
2712 return;
2715 /* Frag hacking will turn this into a sub instruction if the offset turns
2716 out to be negative. */
2717 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2718 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
2719 inst.reloc.pc_rel = 1;
2720 inst.instruction |= flags;
2722 end_of_line (str);
2725 static void
2726 do_adrl (str, flags)
2727 char * str;
2728 unsigned long flags;
2730 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2731 into a relative address of the form:
2732 add rd, pc, #low(label-.-8)"
2733 add rd, rd, #high(label-.-8)" */
2735 skip_whitespace (str);
2737 if (reg_required_here (& str, 12) == FAIL
2738 || skip_past_comma (& str) == FAIL
2739 || my_get_expression (& inst.reloc.exp, & str))
2741 if (!inst.error)
2742 inst.error = BAD_ARGS;
2743 return;
2746 end_of_line (str);
2748 /* Frag hacking will turn this into a sub instruction if the offset turns
2749 out to be negative. */
2750 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
2751 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2752 inst.reloc.pc_rel = 1;
2753 inst.instruction |= flags;
2754 inst.size = INSN_SIZE * 2;
2756 return;
2759 static void
2760 do_cmp (str, flags)
2761 char * str;
2762 unsigned long flags;
2764 skip_whitespace (str);
2766 if (reg_required_here (&str, 16) == FAIL)
2768 if (!inst.error)
2769 inst.error = BAD_ARGS;
2770 return;
2773 if (skip_past_comma (&str) == FAIL
2774 || data_op2 (&str) == FAIL)
2776 if (!inst.error)
2777 inst.error = BAD_ARGS;
2778 return;
2781 inst.instruction |= flags;
2782 if ((flags & 0x0000f000) == 0)
2783 inst.instruction |= CONDS_BIT;
2785 end_of_line (str);
2786 return;
2789 static void
2790 do_mov (str, flags)
2791 char * str;
2792 unsigned long flags;
2794 skip_whitespace (str);
2796 if (reg_required_here (&str, 12) == FAIL)
2798 if (!inst.error)
2799 inst.error = BAD_ARGS;
2800 return;
2803 if (skip_past_comma (&str) == FAIL
2804 || data_op2 (&str) == FAIL)
2806 if (!inst.error)
2807 inst.error = BAD_ARGS;
2808 return;
2811 inst.instruction |= flags;
2812 end_of_line (str);
2813 return;
2816 static int
2817 ldst_extend (str, hwse)
2818 char ** str;
2819 int hwse;
2821 int add = INDEX_UP;
2823 switch (**str)
2825 case '#':
2826 case '$':
2827 (*str)++;
2828 if (my_get_expression (& inst.reloc.exp, str))
2829 return FAIL;
2831 if (inst.reloc.exp.X_op == O_constant)
2833 int value = inst.reloc.exp.X_add_number;
2835 if ((hwse && (value < -255 || value > 255))
2836 || (value < -4095 || value > 4095))
2838 inst.error = _("address offset too large");
2839 return FAIL;
2842 if (value < 0)
2844 value = -value;
2845 add = 0;
2848 /* Halfword and signextension instructions have the
2849 immediate value split across bits 11..8 and bits 3..0 */
2850 if (hwse)
2851 inst.instruction |= add | HWOFFSET_IMM | ((value >> 4) << 8) | (value & 0xF);
2852 else
2853 inst.instruction |= add | value;
2855 else
2857 if (hwse)
2859 inst.instruction |= HWOFFSET_IMM;
2860 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2862 else
2863 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2864 inst.reloc.pc_rel = 0;
2866 return SUCCESS;
2868 case '-':
2869 add = 0; /* and fall through */
2870 case '+':
2871 (*str)++; /* and fall through */
2872 default:
2873 if (reg_required_here (str, 0) == FAIL)
2874 return FAIL;
2876 if (hwse)
2877 inst.instruction |= add;
2878 else
2880 inst.instruction |= add | OFFSET_REG;
2881 if (skip_past_comma (str) == SUCCESS)
2882 return decode_shift (str, SHIFT_RESTRICT);
2885 return SUCCESS;
2889 static void
2890 do_ldst (str, flags)
2891 char * str;
2892 unsigned long flags;
2894 int halfword = 0;
2895 int pre_inc = 0;
2896 int conflict_reg;
2897 int value;
2899 /* This is not ideal, but it is the simplest way of dealing with the
2900 ARM7T halfword instructions (since they use a different
2901 encoding, but the same mnemonic): */
2902 halfword = (flags & 0x80000000) != 0;
2903 if (halfword)
2905 /* This is actually a load/store of a halfword, or a
2906 signed-extension load */
2907 if ((cpu_variant & ARM_HALFWORD) == 0)
2909 inst.error
2910 = _("Processor does not support halfwords or signed bytes");
2911 return;
2914 inst.instruction = (inst.instruction & COND_MASK)
2915 | (flags & ~COND_MASK);
2917 flags = 0;
2920 skip_whitespace (str);
2922 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
2924 if (!inst.error)
2925 inst.error = BAD_ARGS;
2926 return;
2929 if (skip_past_comma (& str) == FAIL)
2931 inst.error = _("Address expected");
2932 return;
2935 if (*str == '[')
2937 int reg;
2939 str++;
2941 skip_whitespace (str);
2943 if ((reg = reg_required_here (&str, 16)) == FAIL)
2944 return;
2946 /* Conflicts can occur on stores as well as loads. */
2947 conflict_reg = (conflict_reg == reg);
2949 skip_whitespace (str);
2951 if (*str == ']')
2953 str ++;
2955 if (skip_past_comma (&str) == SUCCESS)
2957 /* [Rn],... (post inc) */
2958 if (ldst_extend (&str, halfword) == FAIL)
2959 return;
2960 if (conflict_reg)
2961 as_warn (_("%s register same as write-back base"),
2962 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2964 else
2966 /* [Rn] */
2967 if (halfword)
2968 inst.instruction |= HWOFFSET_IMM;
2970 skip_whitespace (str);
2972 if (*str == '!')
2974 if (conflict_reg)
2975 as_warn (_("%s register same as write-back base"),
2976 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2977 str++;
2978 inst.instruction |= WRITE_BACK;
2981 flags |= INDEX_UP;
2982 if (! (flags & TRANS_BIT))
2983 pre_inc = 1;
2986 else
2988 /* [Rn,...] */
2989 if (skip_past_comma (&str) == FAIL)
2991 inst.error = _("pre-indexed expression expected");
2992 return;
2995 pre_inc = 1;
2996 if (ldst_extend (&str, halfword) == FAIL)
2997 return;
2999 skip_whitespace (str);
3001 if (*str++ != ']')
3003 inst.error = _("missing ]");
3004 return;
3007 skip_whitespace (str);
3009 if (*str == '!')
3011 if (conflict_reg)
3012 as_warn (_("%s register same as write-back base"),
3013 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
3014 str++;
3015 inst.instruction |= WRITE_BACK;
3019 else if (*str == '=')
3021 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
3022 str++;
3024 skip_whitespace (str);
3026 if (my_get_expression (&inst.reloc.exp, &str))
3027 return;
3029 if (inst.reloc.exp.X_op != O_constant
3030 && inst.reloc.exp.X_op != O_symbol)
3032 inst.error = _("Constant expression expected");
3033 return;
3036 if (inst.reloc.exp.X_op == O_constant
3037 && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
3039 /* This can be done with a mov instruction */
3040 inst.instruction &= LITERAL_MASK;
3041 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
3042 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
3043 end_of_line(str);
3044 return;
3046 else
3048 /* Insert into literal pool */
3049 if (add_to_lit_pool () == FAIL)
3051 if (!inst.error)
3052 inst.error = _("literal pool insertion failed");
3053 return;
3056 /* Change the instruction exp to point to the pool */
3057 if (halfword)
3059 inst.instruction |= HWOFFSET_IMM;
3060 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
3062 else
3063 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
3064 inst.reloc.pc_rel = 1;
3065 inst.instruction |= (REG_PC << 16);
3066 pre_inc = 1;
3069 else
3071 if (my_get_expression (&inst.reloc.exp, &str))
3072 return;
3074 if (halfword)
3076 inst.instruction |= HWOFFSET_IMM;
3077 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
3079 else
3080 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
3081 #ifndef TE_WINCE
3082 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
3083 #endif
3084 inst.reloc.pc_rel = 1;
3085 inst.instruction |= (REG_PC << 16);
3086 pre_inc = 1;
3089 if (pre_inc && (flags & TRANS_BIT))
3090 inst.error = _("Pre-increment instruction with translate");
3092 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
3093 end_of_line (str);
3094 return;
3097 static long
3098 reg_list (strp)
3099 char ** strp;
3101 char * str = *strp;
3102 long range = 0;
3103 int another_range;
3105 /* We come back here if we get ranges concatenated by '+' or '|' */
3108 another_range = 0;
3110 if (*str == '{')
3112 int in_range = 0;
3113 int cur_reg = -1;
3115 str++;
3118 int reg;
3120 skip_whitespace (str);
3122 if ((reg = reg_required_here (& str, -1)) == FAIL)
3123 return FAIL;
3125 if (in_range)
3127 int i;
3129 if (reg <= cur_reg)
3131 inst.error = _("Bad range in register list");
3132 return FAIL;
3135 for (i = cur_reg + 1; i < reg; i++)
3137 if (range & (1 << i))
3138 as_tsktsk
3139 (_("Warning: Duplicated register (r%d) in register list"),
3141 else
3142 range |= 1 << i;
3144 in_range = 0;
3147 if (range & (1 << reg))
3148 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3149 reg);
3150 else if (reg <= cur_reg)
3151 as_tsktsk (_("Warning: Register range not in ascending order"));
3153 range |= 1 << reg;
3154 cur_reg = reg;
3155 } while (skip_past_comma (&str) != FAIL
3156 || (in_range = 1, *str++ == '-'));
3157 str--;
3158 skip_whitespace (str);
3160 if (*str++ != '}')
3162 inst.error = _("Missing `}'");
3163 return FAIL;
3166 else
3168 expressionS expr;
3170 if (my_get_expression (&expr, &str))
3171 return FAIL;
3173 if (expr.X_op == O_constant)
3175 if (expr.X_add_number
3176 != (expr.X_add_number & 0x0000ffff))
3178 inst.error = _("invalid register mask");
3179 return FAIL;
3182 if ((range & expr.X_add_number) != 0)
3184 int regno = range & expr.X_add_number;
3186 regno &= -regno;
3187 regno = (1 << regno) - 1;
3188 as_tsktsk
3189 (_("Warning: Duplicated register (r%d) in register list"),
3190 regno);
3193 range |= expr.X_add_number;
3195 else
3197 if (inst.reloc.type != 0)
3199 inst.error = _("expression too complex");
3200 return FAIL;
3203 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
3204 inst.reloc.type = BFD_RELOC_ARM_MULTI;
3205 inst.reloc.pc_rel = 0;
3209 skip_whitespace (str);
3211 if (*str == '|' || *str == '+')
3213 str++;
3214 another_range = 1;
3216 } while (another_range);
3218 *strp = str;
3219 return range;
3222 static void
3223 do_ldmstm (str, flags)
3224 char * str;
3225 unsigned long flags;
3227 int base_reg;
3228 long range;
3230 skip_whitespace (str);
3232 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
3233 return;
3235 if (base_reg == REG_PC)
3237 inst.error = _("r15 not allowed as base register");
3238 return;
3241 skip_whitespace (str);
3243 if (*str == '!')
3245 flags |= WRITE_BACK;
3246 str++;
3249 if (skip_past_comma (&str) == FAIL
3250 || (range = reg_list (&str)) == FAIL)
3252 if (! inst.error)
3253 inst.error = BAD_ARGS;
3254 return;
3257 if (*str == '^')
3259 str++;
3260 flags |= LDM_TYPE_2_OR_3;
3263 inst.instruction |= flags | range;
3264 end_of_line (str);
3265 return;
3268 static void
3269 do_swi (str, flags)
3270 char * str;
3271 unsigned long flags;
3273 skip_whitespace (str);
3275 /* Allow optional leading '#'. */
3276 if (is_immediate_prefix (*str))
3277 str++;
3279 if (my_get_expression (& inst.reloc.exp, & str))
3280 return;
3282 inst.reloc.type = BFD_RELOC_ARM_SWI;
3283 inst.reloc.pc_rel = 0;
3284 inst.instruction |= flags;
3286 end_of_line (str);
3288 return;
3291 static void
3292 do_swap (str, flags)
3293 char * str;
3294 unsigned long flags;
3296 int reg;
3298 skip_whitespace (str);
3300 if ((reg = reg_required_here (&str, 12)) == FAIL)
3301 return;
3303 if (reg == REG_PC)
3305 inst.error = _("r15 not allowed in swap");
3306 return;
3309 if (skip_past_comma (&str) == FAIL
3310 || (reg = reg_required_here (&str, 0)) == FAIL)
3312 if (!inst.error)
3313 inst.error = BAD_ARGS;
3314 return;
3317 if (reg == REG_PC)
3319 inst.error = _("r15 not allowed in swap");
3320 return;
3323 if (skip_past_comma (&str) == FAIL
3324 || *str++ != '[')
3326 inst.error = BAD_ARGS;
3327 return;
3330 skip_whitespace (str);
3332 if ((reg = reg_required_here (&str, 16)) == FAIL)
3333 return;
3335 if (reg == REG_PC)
3337 inst.error = BAD_PC;
3338 return;
3341 skip_whitespace (str);
3343 if (*str++ != ']')
3345 inst.error = _("missing ]");
3346 return;
3349 inst.instruction |= flags;
3350 end_of_line (str);
3351 return;
3354 static void
3355 do_branch (str, flags)
3356 char * str;
3357 unsigned long flags ATTRIBUTE_UNUSED;
3359 if (my_get_expression (&inst.reloc.exp, &str))
3360 return;
3362 #ifdef OBJ_ELF
3364 char * save_in;
3366 /* ScottB: February 5, 1998 */
3367 /* Check to see of PLT32 reloc required for the instruction. */
3369 /* arm_parse_reloc() works on input_line_pointer.
3370 We actually want to parse the operands to the branch instruction
3371 passed in 'str'. Save the input pointer and restore it later. */
3372 save_in = input_line_pointer;
3373 input_line_pointer = str;
3374 if (inst.reloc.exp.X_op == O_symbol
3375 && *str == '('
3376 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3378 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3379 inst.reloc.pc_rel = 0;
3380 /* Modify str to point to after parsed operands, otherwise
3381 end_of_line() will complain about the (PLT) left in str. */
3382 str = input_line_pointer;
3384 else
3386 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3387 inst.reloc.pc_rel = 1;
3389 input_line_pointer = save_in;
3391 #else
3392 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3393 inst.reloc.pc_rel = 1;
3394 #endif /* OBJ_ELF */
3396 end_of_line (str);
3397 return;
3400 static void
3401 do_bx (str, flags)
3402 char * str;
3403 unsigned long flags ATTRIBUTE_UNUSED;
3405 int reg;
3407 skip_whitespace (str);
3409 if ((reg = reg_required_here (&str, 0)) == FAIL)
3411 inst.error = BAD_ARGS;
3412 return;
3415 if (reg == REG_PC)
3416 inst.error = BAD_PC;
3418 end_of_line (str);
3421 static void
3422 do_cdp (str, flags)
3423 char * str;
3424 unsigned long flags ATTRIBUTE_UNUSED;
3426 /* Co-processor data operation.
3427 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3428 skip_whitespace (str);
3430 if (co_proc_number (&str) == FAIL)
3432 if (!inst.error)
3433 inst.error = BAD_ARGS;
3434 return;
3437 if (skip_past_comma (&str) == FAIL
3438 || cp_opc_expr (&str, 20,4) == FAIL)
3440 if (!inst.error)
3441 inst.error = BAD_ARGS;
3442 return;
3445 if (skip_past_comma (&str) == FAIL
3446 || cp_reg_required_here (&str, 12) == FAIL)
3448 if (!inst.error)
3449 inst.error = BAD_ARGS;
3450 return;
3453 if (skip_past_comma (&str) == FAIL
3454 || cp_reg_required_here (&str, 16) == FAIL)
3456 if (!inst.error)
3457 inst.error = BAD_ARGS;
3458 return;
3461 if (skip_past_comma (&str) == FAIL
3462 || cp_reg_required_here (&str, 0) == FAIL)
3464 if (!inst.error)
3465 inst.error = BAD_ARGS;
3466 return;
3469 if (skip_past_comma (&str) == SUCCESS)
3471 if (cp_opc_expr (&str, 5, 3) == FAIL)
3473 if (!inst.error)
3474 inst.error = BAD_ARGS;
3475 return;
3479 end_of_line (str);
3480 return;
3483 static void
3484 do_lstc (str, flags)
3485 char * str;
3486 unsigned long flags;
3488 /* Co-processor register load/store.
3489 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3491 skip_whitespace (str);
3493 if (co_proc_number (&str) == FAIL)
3495 if (!inst.error)
3496 inst.error = BAD_ARGS;
3497 return;
3500 if (skip_past_comma (&str) == FAIL
3501 || cp_reg_required_here (&str, 12) == FAIL)
3503 if (!inst.error)
3504 inst.error = BAD_ARGS;
3505 return;
3508 if (skip_past_comma (&str) == FAIL
3509 || cp_address_required_here (&str) == FAIL)
3511 if (! inst.error)
3512 inst.error = BAD_ARGS;
3513 return;
3516 inst.instruction |= flags;
3517 end_of_line (str);
3518 return;
3521 static void
3522 do_co_reg (str, flags)
3523 char * str;
3524 unsigned long flags;
3526 /* Co-processor register transfer.
3527 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3529 skip_whitespace (str);
3531 if (co_proc_number (&str) == FAIL)
3533 if (!inst.error)
3534 inst.error = BAD_ARGS;
3535 return;
3538 if (skip_past_comma (&str) == FAIL
3539 || cp_opc_expr (&str, 21, 3) == FAIL)
3541 if (!inst.error)
3542 inst.error = BAD_ARGS;
3543 return;
3546 if (skip_past_comma (&str) == FAIL
3547 || reg_required_here (&str, 12) == FAIL)
3549 if (!inst.error)
3550 inst.error = BAD_ARGS;
3551 return;
3554 if (skip_past_comma (&str) == FAIL
3555 || cp_reg_required_here (&str, 16) == FAIL)
3557 if (!inst.error)
3558 inst.error = BAD_ARGS;
3559 return;
3562 if (skip_past_comma (&str) == FAIL
3563 || cp_reg_required_here (&str, 0) == FAIL)
3565 if (!inst.error)
3566 inst.error = BAD_ARGS;
3567 return;
3570 if (skip_past_comma (&str) == SUCCESS)
3572 if (cp_opc_expr (&str, 5, 3) == FAIL)
3574 if (!inst.error)
3575 inst.error = BAD_ARGS;
3576 return;
3579 if (flags)
3581 inst.error = BAD_COND;
3584 end_of_line (str);
3585 return;
3588 static void
3589 do_fp_ctrl (str, flags)
3590 char * str;
3591 unsigned long flags ATTRIBUTE_UNUSED;
3593 /* FP control registers.
3594 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3596 skip_whitespace (str);
3598 if (reg_required_here (&str, 12) == FAIL)
3600 if (!inst.error)
3601 inst.error = BAD_ARGS;
3602 return;
3605 end_of_line (str);
3606 return;
3609 static void
3610 do_fp_ldst (str, flags)
3611 char * str;
3612 unsigned long flags ATTRIBUTE_UNUSED;
3614 skip_whitespace (str);
3616 switch (inst.suffix)
3618 case SUFF_S:
3619 break;
3620 case SUFF_D:
3621 inst.instruction |= CP_T_X;
3622 break;
3623 case SUFF_E:
3624 inst.instruction |= CP_T_Y;
3625 break;
3626 case SUFF_P:
3627 inst.instruction |= CP_T_X | CP_T_Y;
3628 break;
3629 default:
3630 abort ();
3633 if (fp_reg_required_here (&str, 12) == FAIL)
3635 if (!inst.error)
3636 inst.error = BAD_ARGS;
3637 return;
3640 if (skip_past_comma (&str) == FAIL
3641 || cp_address_required_here (&str) == FAIL)
3643 if (!inst.error)
3644 inst.error = BAD_ARGS;
3645 return;
3648 end_of_line (str);
3651 static void
3652 do_fp_ldmstm (str, flags)
3653 char * str;
3654 unsigned long flags;
3656 int num_regs;
3658 skip_whitespace (str);
3660 if (fp_reg_required_here (&str, 12) == FAIL)
3662 if (! inst.error)
3663 inst.error = BAD_ARGS;
3664 return;
3667 /* Get Number of registers to transfer */
3668 if (skip_past_comma (&str) == FAIL
3669 || my_get_expression (&inst.reloc.exp, &str))
3671 if (! inst.error)
3672 inst.error = _("constant expression expected");
3673 return;
3676 if (inst.reloc.exp.X_op != O_constant)
3678 inst.error = _("Constant value required for number of registers");
3679 return;
3682 num_regs = inst.reloc.exp.X_add_number;
3684 if (num_regs < 1 || num_regs > 4)
3686 inst.error = _("number of registers must be in the range [1:4]");
3687 return;
3690 switch (num_regs)
3692 case 1:
3693 inst.instruction |= CP_T_X;
3694 break;
3695 case 2:
3696 inst.instruction |= CP_T_Y;
3697 break;
3698 case 3:
3699 inst.instruction |= CP_T_Y | CP_T_X;
3700 break;
3701 case 4:
3702 break;
3703 default:
3704 abort ();
3707 if (flags)
3709 int reg;
3710 int write_back;
3711 int offset;
3713 /* The instruction specified "ea" or "fd", so we can only accept
3714 [Rn]{!}. The instruction does not really support stacking or
3715 unstacking, so we have to emulate these by setting appropriate
3716 bits and offsets. */
3717 if (skip_past_comma (&str) == FAIL
3718 || *str != '[')
3720 if (! inst.error)
3721 inst.error = BAD_ARGS;
3722 return;
3725 str++;
3726 skip_whitespace (str);
3728 if ((reg = reg_required_here (&str, 16)) == FAIL)
3729 return;
3731 skip_whitespace (str);
3733 if (*str != ']')
3735 inst.error = BAD_ARGS;
3736 return;
3739 str++;
3740 if (*str == '!')
3742 write_back = 1;
3743 str++;
3744 if (reg == REG_PC)
3746 inst.error = _("R15 not allowed as base register with write-back");
3747 return;
3750 else
3751 write_back = 0;
3753 if (flags & CP_T_Pre)
3755 /* Pre-decrement */
3756 offset = 3 * num_regs;
3757 if (write_back)
3758 flags |= CP_T_WB;
3760 else
3762 /* Post-increment */
3763 if (write_back)
3765 flags |= CP_T_WB;
3766 offset = 3 * num_regs;
3768 else
3770 /* No write-back, so convert this into a standard pre-increment
3771 instruction -- aesthetically more pleasing. */
3772 flags = CP_T_Pre | CP_T_UD;
3773 offset = 0;
3777 inst.instruction |= flags | offset;
3779 else if (skip_past_comma (&str) == FAIL
3780 || cp_address_required_here (&str) == FAIL)
3782 if (! inst.error)
3783 inst.error = BAD_ARGS;
3784 return;
3787 end_of_line (str);
3790 static void
3791 do_fp_dyadic (str, flags)
3792 char * str;
3793 unsigned long flags;
3795 skip_whitespace (str);
3797 switch (inst.suffix)
3799 case SUFF_S:
3800 break;
3801 case SUFF_D:
3802 inst.instruction |= 0x00000080;
3803 break;
3804 case SUFF_E:
3805 inst.instruction |= 0x00080000;
3806 break;
3807 default:
3808 abort ();
3811 if (fp_reg_required_here (&str, 12) == FAIL)
3813 if (! inst.error)
3814 inst.error = BAD_ARGS;
3815 return;
3818 if (skip_past_comma (&str) == FAIL
3819 || fp_reg_required_here (&str, 16) == FAIL)
3821 if (! inst.error)
3822 inst.error = BAD_ARGS;
3823 return;
3826 if (skip_past_comma (&str) == FAIL
3827 || fp_op2 (&str) == FAIL)
3829 if (! inst.error)
3830 inst.error = BAD_ARGS;
3831 return;
3834 inst.instruction |= flags;
3835 end_of_line (str);
3836 return;
3839 static void
3840 do_fp_monadic (str, flags)
3841 char * str;
3842 unsigned long flags;
3844 skip_whitespace (str);
3846 switch (inst.suffix)
3848 case SUFF_S:
3849 break;
3850 case SUFF_D:
3851 inst.instruction |= 0x00000080;
3852 break;
3853 case SUFF_E:
3854 inst.instruction |= 0x00080000;
3855 break;
3856 default:
3857 abort ();
3860 if (fp_reg_required_here (&str, 12) == FAIL)
3862 if (! inst.error)
3863 inst.error = BAD_ARGS;
3864 return;
3867 if (skip_past_comma (&str) == FAIL
3868 || fp_op2 (&str) == FAIL)
3870 if (! inst.error)
3871 inst.error = BAD_ARGS;
3872 return;
3875 inst.instruction |= flags;
3876 end_of_line (str);
3877 return;
3880 static void
3881 do_fp_cmp (str, flags)
3882 char * str;
3883 unsigned long flags;
3885 skip_whitespace (str);
3887 if (fp_reg_required_here (&str, 16) == FAIL)
3889 if (! inst.error)
3890 inst.error = BAD_ARGS;
3891 return;
3894 if (skip_past_comma (&str) == FAIL
3895 || fp_op2 (&str) == FAIL)
3897 if (! inst.error)
3898 inst.error = BAD_ARGS;
3899 return;
3902 inst.instruction |= flags;
3903 end_of_line (str);
3904 return;
3907 static void
3908 do_fp_from_reg (str, flags)
3909 char * str;
3910 unsigned long flags;
3912 skip_whitespace (str);
3914 switch (inst.suffix)
3916 case SUFF_S:
3917 break;
3918 case SUFF_D:
3919 inst.instruction |= 0x00000080;
3920 break;
3921 case SUFF_E:
3922 inst.instruction |= 0x00080000;
3923 break;
3924 default:
3925 abort ();
3928 if (fp_reg_required_here (&str, 16) == FAIL)
3930 if (! inst.error)
3931 inst.error = BAD_ARGS;
3932 return;
3935 if (skip_past_comma (&str) == FAIL
3936 || reg_required_here (&str, 12) == FAIL)
3938 if (! inst.error)
3939 inst.error = BAD_ARGS;
3940 return;
3943 inst.instruction |= flags;
3944 end_of_line (str);
3945 return;
3948 static void
3949 do_fp_to_reg (str, flags)
3950 char * str;
3951 unsigned long flags;
3953 skip_whitespace (str);
3955 if (reg_required_here (&str, 12) == FAIL)
3956 return;
3958 if (skip_past_comma (&str) == FAIL
3959 || fp_reg_required_here (&str, 0) == FAIL)
3961 if (! inst.error)
3962 inst.error = BAD_ARGS;
3963 return;
3966 inst.instruction |= flags;
3967 end_of_line (str);
3968 return;
3971 /* Thumb specific routines */
3973 /* Parse and validate that a register is of the right form, this saves
3974 repeated checking of this information in many similar cases.
3975 Unlike the 32-bit case we do not insert the register into the opcode
3976 here, since the position is often unknown until the full instruction
3977 has been parsed. */
3978 static int
3979 thumb_reg (strp, hi_lo)
3980 char ** strp;
3981 int hi_lo;
3983 int reg;
3985 if ((reg = reg_required_here (strp, -1)) == FAIL)
3986 return FAIL;
3988 switch (hi_lo)
3990 case THUMB_REG_LO:
3991 if (reg > 7)
3993 inst.error = _("lo register required");
3994 return FAIL;
3996 break;
3998 case THUMB_REG_HI:
3999 if (reg < 8)
4001 inst.error = _("hi register required");
4002 return FAIL;
4004 break;
4006 default:
4007 break;
4010 return reg;
4013 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
4014 was SUB. */
4015 static void
4016 thumb_add_sub (str, subtract)
4017 char * str;
4018 int subtract;
4020 int Rd, Rs, Rn = FAIL;
4022 skip_whitespace (str);
4024 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4025 || skip_past_comma (&str) == FAIL)
4027 if (! inst.error)
4028 inst.error = BAD_ARGS;
4029 return;
4032 if (is_immediate_prefix (*str))
4034 Rs = Rd;
4035 str++;
4036 if (my_get_expression (&inst.reloc.exp, &str))
4037 return;
4039 else
4041 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4042 return;
4044 if (skip_past_comma (&str) == FAIL)
4046 /* Two operand format, shuffle the registers and pretend there
4047 are 3 */
4048 Rn = Rs;
4049 Rs = Rd;
4051 else if (is_immediate_prefix (*str))
4053 str++;
4054 if (my_get_expression (&inst.reloc.exp, &str))
4055 return;
4057 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4058 return;
4061 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4062 for the latter case, EXPR contains the immediate that was found. */
4063 if (Rn != FAIL)
4065 /* All register format. */
4066 if (Rd > 7 || Rs > 7 || Rn > 7)
4068 if (Rs != Rd)
4070 inst.error = _("dest and source1 must be the same register");
4071 return;
4074 /* Can't do this for SUB */
4075 if (subtract)
4077 inst.error = _("subtract valid only on lo regs");
4078 return;
4081 inst.instruction = (T_OPCODE_ADD_HI
4082 | (Rd > 7 ? THUMB_H1 : 0)
4083 | (Rn > 7 ? THUMB_H2 : 0));
4084 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
4086 else
4088 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
4089 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
4092 else
4094 /* Immediate expression, now things start to get nasty. */
4096 /* First deal with HI regs, only very restricted cases allowed:
4097 Adjusting SP, and using PC or SP to get an address. */
4098 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
4099 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
4101 inst.error = _("invalid Hi register with immediate");
4102 return;
4105 if (inst.reloc.exp.X_op != O_constant)
4107 /* Value isn't known yet, all we can do is store all the fragments
4108 we know about in the instruction and let the reloc hacking
4109 work it all out. */
4110 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
4111 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4113 else
4115 int offset = inst.reloc.exp.X_add_number;
4117 if (subtract)
4118 offset = -offset;
4120 if (offset < 0)
4122 offset = -offset;
4123 subtract = 1;
4125 /* Quick check, in case offset is MIN_INT */
4126 if (offset < 0)
4128 inst.error = _("immediate value out of range");
4129 return;
4132 else
4133 subtract = 0;
4135 if (Rd == REG_SP)
4137 if (offset & ~0x1fc)
4139 inst.error = _("invalid immediate value for stack adjust");
4140 return;
4142 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
4143 inst.instruction |= offset >> 2;
4145 else if (Rs == REG_PC || Rs == REG_SP)
4147 if (subtract
4148 || (offset & ~0x3fc))
4150 inst.error = _("invalid immediate for address calculation");
4151 return;
4153 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
4154 : T_OPCODE_ADD_SP);
4155 inst.instruction |= (Rd << 8) | (offset >> 2);
4157 else if (Rs == Rd)
4159 if (offset & ~0xff)
4161 inst.error = _("immediate value out of range");
4162 return;
4164 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
4165 inst.instruction |= (Rd << 8) | offset;
4167 else
4169 if (offset & ~0x7)
4171 inst.error = _("immediate value out of range");
4172 return;
4174 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
4175 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
4180 end_of_line (str);
4183 static void
4184 thumb_shift (str, shift)
4185 char * str;
4186 int shift;
4188 int Rd, Rs, Rn = FAIL;
4190 skip_whitespace (str);
4192 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4193 || skip_past_comma (&str) == FAIL)
4195 if (! inst.error)
4196 inst.error = BAD_ARGS;
4197 return;
4200 if (is_immediate_prefix (*str))
4202 /* Two operand immediate format, set Rs to Rd. */
4203 Rs = Rd;
4204 str ++;
4205 if (my_get_expression (&inst.reloc.exp, &str))
4206 return;
4208 else
4210 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4211 return;
4213 if (skip_past_comma (&str) == FAIL)
4215 /* Two operand format, shuffle the registers and pretend there
4216 are 3 */
4217 Rn = Rs;
4218 Rs = Rd;
4220 else if (is_immediate_prefix (*str))
4222 str++;
4223 if (my_get_expression (&inst.reloc.exp, &str))
4224 return;
4226 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4227 return;
4230 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4231 for the latter case, EXPR contains the immediate that was found. */
4233 if (Rn != FAIL)
4235 if (Rs != Rd)
4237 inst.error = _("source1 and dest must be same register");
4238 return;
4241 switch (shift)
4243 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
4244 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
4245 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
4248 inst.instruction |= Rd | (Rn << 3);
4250 else
4252 switch (shift)
4254 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
4255 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
4256 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
4259 if (inst.reloc.exp.X_op != O_constant)
4261 /* Value isn't known yet, create a dummy reloc and let reloc
4262 hacking fix it up */
4264 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
4266 else
4268 unsigned shift_value = inst.reloc.exp.X_add_number;
4270 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
4272 inst.error = _("Invalid immediate for shift");
4273 return;
4276 /* Shifts of zero are handled by converting to LSL */
4277 if (shift_value == 0)
4278 inst.instruction = T_OPCODE_LSL_I;
4280 /* Shifts of 32 are encoded as a shift of zero */
4281 if (shift_value == 32)
4282 shift_value = 0;
4284 inst.instruction |= shift_value << 6;
4287 inst.instruction |= Rd | (Rs << 3);
4290 end_of_line (str);
4293 static void
4294 thumb_mov_compare (str, move)
4295 char * str;
4296 int move;
4298 int Rd, Rs = FAIL;
4300 skip_whitespace (str);
4302 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4303 || skip_past_comma (&str) == FAIL)
4305 if (! inst.error)
4306 inst.error = BAD_ARGS;
4307 return;
4310 if (is_immediate_prefix (*str))
4312 str++;
4313 if (my_get_expression (&inst.reloc.exp, &str))
4314 return;
4316 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4317 return;
4319 if (Rs != FAIL)
4321 if (Rs < 8 && Rd < 8)
4323 if (move == THUMB_MOVE)
4324 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4325 since a MOV instruction produces unpredictable results */
4326 inst.instruction = T_OPCODE_ADD_I3;
4327 else
4328 inst.instruction = T_OPCODE_CMP_LR;
4329 inst.instruction |= Rd | (Rs << 3);
4331 else
4333 if (move == THUMB_MOVE)
4334 inst.instruction = T_OPCODE_MOV_HR;
4335 else
4336 inst.instruction = T_OPCODE_CMP_HR;
4338 if (Rd > 7)
4339 inst.instruction |= THUMB_H1;
4341 if (Rs > 7)
4342 inst.instruction |= THUMB_H2;
4344 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4347 else
4349 if (Rd > 7)
4351 inst.error = _("only lo regs allowed with immediate");
4352 return;
4355 if (move == THUMB_MOVE)
4356 inst.instruction = T_OPCODE_MOV_I8;
4357 else
4358 inst.instruction = T_OPCODE_CMP_I8;
4360 inst.instruction |= Rd << 8;
4362 if (inst.reloc.exp.X_op != O_constant)
4363 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4364 else
4366 unsigned value = inst.reloc.exp.X_add_number;
4368 if (value > 255)
4370 inst.error = _("invalid immediate");
4371 return;
4374 inst.instruction |= value;
4378 end_of_line (str);
4381 static void
4382 thumb_load_store (str, load_store, size)
4383 char * str;
4384 int load_store;
4385 int size;
4387 int Rd, Rb, Ro = FAIL;
4389 skip_whitespace (str);
4391 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4392 || skip_past_comma (&str) == FAIL)
4394 if (! inst.error)
4395 inst.error = BAD_ARGS;
4396 return;
4399 if (*str == '[')
4401 str++;
4402 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4403 return;
4405 if (skip_past_comma (&str) != FAIL)
4407 if (is_immediate_prefix (*str))
4409 str++;
4410 if (my_get_expression (&inst.reloc.exp, &str))
4411 return;
4413 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4414 return;
4416 else
4418 inst.reloc.exp.X_op = O_constant;
4419 inst.reloc.exp.X_add_number = 0;
4422 if (*str != ']')
4424 inst.error = _("expected ']'");
4425 return;
4427 str++;
4429 else if (*str == '=')
4431 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4432 str++;
4434 skip_whitespace (str);
4436 if (my_get_expression (& inst.reloc.exp, & str))
4437 return;
4439 end_of_line (str);
4441 if ( inst.reloc.exp.X_op != O_constant
4442 && inst.reloc.exp.X_op != O_symbol)
4444 inst.error = "Constant expression expected";
4445 return;
4448 if (inst.reloc.exp.X_op == O_constant
4449 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
4451 /* This can be done with a mov instruction */
4453 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
4454 inst.instruction |= inst.reloc.exp.X_add_number;
4455 return;
4458 /* Insert into literal pool */
4459 if (add_to_lit_pool () == FAIL)
4461 if (!inst.error)
4462 inst.error = "literal pool insertion failed";
4463 return;
4466 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4467 inst.reloc.pc_rel = 1;
4468 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4469 inst.reloc.exp.X_add_number += 4; /* Adjust ARM pipeline offset to Thumb */
4471 return;
4473 else
4475 if (my_get_expression (&inst.reloc.exp, &str))
4476 return;
4478 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4479 inst.reloc.pc_rel = 1;
4480 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
4481 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4482 end_of_line (str);
4483 return;
4486 if (Rb == REG_PC || Rb == REG_SP)
4488 if (size != THUMB_WORD)
4490 inst.error = _("byte or halfword not valid for base register");
4491 return;
4493 else if (Rb == REG_PC && load_store != THUMB_LOAD)
4495 inst.error = _("R15 based store not allowed");
4496 return;
4498 else if (Ro != FAIL)
4500 inst.error = _("Invalid base register for register offset");
4501 return;
4504 if (Rb == REG_PC)
4505 inst.instruction = T_OPCODE_LDR_PC;
4506 else if (load_store == THUMB_LOAD)
4507 inst.instruction = T_OPCODE_LDR_SP;
4508 else
4509 inst.instruction = T_OPCODE_STR_SP;
4511 inst.instruction |= Rd << 8;
4512 if (inst.reloc.exp.X_op == O_constant)
4514 unsigned offset = inst.reloc.exp.X_add_number;
4516 if (offset & ~0x3fc)
4518 inst.error = _("invalid offset");
4519 return;
4522 inst.instruction |= offset >> 2;
4524 else
4525 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4527 else if (Rb > 7)
4529 inst.error = _("invalid base register in load/store");
4530 return;
4532 else if (Ro == FAIL)
4534 /* Immediate offset */
4535 if (size == THUMB_WORD)
4536 inst.instruction = (load_store == THUMB_LOAD
4537 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
4538 else if (size == THUMB_HALFWORD)
4539 inst.instruction = (load_store == THUMB_LOAD
4540 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
4541 else
4542 inst.instruction = (load_store == THUMB_LOAD
4543 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
4545 inst.instruction |= Rd | (Rb << 3);
4547 if (inst.reloc.exp.X_op == O_constant)
4549 unsigned offset = inst.reloc.exp.X_add_number;
4551 if (offset & ~(0x1f << size))
4553 inst.error = _("Invalid offset");
4554 return;
4556 inst.instruction |= (offset >> size) << 6;
4558 else
4559 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4561 else
4563 /* Register offset */
4564 if (size == THUMB_WORD)
4565 inst.instruction = (load_store == THUMB_LOAD
4566 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
4567 else if (size == THUMB_HALFWORD)
4568 inst.instruction = (load_store == THUMB_LOAD
4569 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
4570 else
4571 inst.instruction = (load_store == THUMB_LOAD
4572 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
4574 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4577 end_of_line (str);
4580 static void
4581 do_t_nop (str)
4582 char * str;
4584 /* Do nothing */
4585 end_of_line (str);
4586 return;
4589 /* Handle the Format 4 instructions that do not have equivalents in other
4590 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4591 BIC and MVN. */
4592 static void
4593 do_t_arit (str)
4594 char * str;
4596 int Rd, Rs, Rn;
4598 skip_whitespace (str);
4600 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4601 || skip_past_comma (&str) == FAIL
4602 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4604 inst.error = BAD_ARGS;
4605 return;
4608 if (skip_past_comma (&str) != FAIL)
4610 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4611 (It isn't allowed for CMP either, but that isn't handled by this
4612 function.) */
4613 if (inst.instruction == T_OPCODE_TST
4614 || inst.instruction == T_OPCODE_CMN
4615 || inst.instruction == T_OPCODE_NEG
4616 || inst.instruction == T_OPCODE_MVN)
4618 inst.error = BAD_ARGS;
4619 return;
4622 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4623 return;
4625 if (Rs != Rd)
4627 inst.error = _("dest and source1 one must be the same register");
4628 return;
4630 Rs = Rn;
4633 if (inst.instruction == T_OPCODE_MUL
4634 && Rs == Rd)
4635 as_tsktsk (_("Rs and Rd must be different in MUL"));
4637 inst.instruction |= Rd | (Rs << 3);
4638 end_of_line (str);
4641 static void
4642 do_t_add (str)
4643 char * str;
4645 thumb_add_sub (str, 0);
4648 static void
4649 do_t_asr (str)
4650 char * str;
4652 thumb_shift (str, THUMB_ASR);
4655 static void
4656 do_t_branch9 (str)
4657 char * str;
4659 if (my_get_expression (&inst.reloc.exp, &str))
4660 return;
4661 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
4662 inst.reloc.pc_rel = 1;
4663 end_of_line (str);
4666 static void
4667 do_t_branch12 (str)
4668 char * str;
4670 if (my_get_expression (&inst.reloc.exp, &str))
4671 return;
4672 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
4673 inst.reloc.pc_rel = 1;
4674 end_of_line (str);
4677 /* Find the real, Thumb encoded start of a Thumb function. */
4679 static symbolS *
4680 find_real_start (symbolP)
4681 symbolS * symbolP;
4683 char * real_start;
4684 const char * name = S_GET_NAME (symbolP);
4685 symbolS * new_target;
4687 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4688 #define STUB_NAME ".real_start_of"
4690 if (name == NULL)
4691 abort();
4693 /* Names that start with '.' are local labels, not function entry points.
4694 The compiler may generate BL instructions to these labels because it
4695 needs to perform a branch to a far away location. */
4696 if (name[0] == '.')
4697 return symbolP;
4699 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
4700 sprintf (real_start, "%s%s", STUB_NAME, name);
4702 new_target = symbol_find (real_start);
4704 if (new_target == NULL)
4706 as_warn ("Failed to find real start of function: %s\n", name);
4707 new_target = symbolP;
4710 free (real_start);
4712 return new_target;
4716 static void
4717 do_t_branch23 (str)
4718 char * str;
4720 if (my_get_expression (& inst.reloc.exp, & str))
4721 return;
4723 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
4724 inst.reloc.pc_rel = 1;
4725 end_of_line (str);
4727 /* If the destination of the branch is a defined symbol which does not have
4728 the THUMB_FUNC attribute, then we must be calling a function which has
4729 the (interfacearm) attribute. We look for the Thumb entry point to that
4730 function and change the branch to refer to that function instead. */
4731 if ( inst.reloc.exp.X_op == O_symbol
4732 && inst.reloc.exp.X_add_symbol != NULL
4733 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
4734 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
4735 inst.reloc.exp.X_add_symbol = find_real_start (inst.reloc.exp.X_add_symbol);
4738 static void
4739 do_t_bx (str)
4740 char * str;
4742 int reg;
4744 skip_whitespace (str);
4746 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4747 return;
4749 /* This sets THUMB_H2 from the top bit of reg. */
4750 inst.instruction |= reg << 3;
4752 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4753 should cause the alignment to be checked once it is known. This is
4754 because BX PC only works if the instruction is word aligned. */
4756 end_of_line (str);
4759 static void
4760 do_t_compare (str)
4761 char * str;
4763 thumb_mov_compare (str, THUMB_COMPARE);
4766 static void
4767 do_t_ldmstm (str)
4768 char * str;
4770 int Rb;
4771 long range;
4773 skip_whitespace (str);
4775 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4776 return;
4778 if (*str != '!')
4779 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4780 else
4781 str++;
4783 if (skip_past_comma (&str) == FAIL
4784 || (range = reg_list (&str)) == FAIL)
4786 if (! inst.error)
4787 inst.error = BAD_ARGS;
4788 return;
4791 if (inst.reloc.type != BFD_RELOC_NONE)
4793 /* This really doesn't seem worth it. */
4794 inst.reloc.type = BFD_RELOC_NONE;
4795 inst.error = _("Expression too complex");
4796 return;
4799 if (range & ~0xff)
4801 inst.error = _("only lo-regs valid in load/store multiple");
4802 return;
4805 inst.instruction |= (Rb << 8) | range;
4806 end_of_line (str);
4809 static void
4810 do_t_ldr (str)
4811 char * str;
4813 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4816 static void
4817 do_t_ldrb (str)
4818 char * str;
4820 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4823 static void
4824 do_t_ldrh (str)
4825 char * str;
4827 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4830 static void
4831 do_t_lds (str)
4832 char * str;
4834 int Rd, Rb, Ro;
4836 skip_whitespace (str);
4838 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4839 || skip_past_comma (&str) == FAIL
4840 || *str++ != '['
4841 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4842 || skip_past_comma (&str) == FAIL
4843 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4844 || *str++ != ']')
4846 if (! inst.error)
4847 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4848 return;
4851 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4852 end_of_line (str);
4855 static void
4856 do_t_lsl (str)
4857 char * str;
4859 thumb_shift (str, THUMB_LSL);
4862 static void
4863 do_t_lsr (str)
4864 char * str;
4866 thumb_shift (str, THUMB_LSR);
4869 static void
4870 do_t_mov (str)
4871 char * str;
4873 thumb_mov_compare (str, THUMB_MOVE);
4876 static void
4877 do_t_push_pop (str)
4878 char * str;
4880 long range;
4882 skip_whitespace (str);
4884 if ((range = reg_list (&str)) == FAIL)
4886 if (! inst.error)
4887 inst.error = BAD_ARGS;
4888 return;
4891 if (inst.reloc.type != BFD_RELOC_NONE)
4893 /* This really doesn't seem worth it. */
4894 inst.reloc.type = BFD_RELOC_NONE;
4895 inst.error = _("Expression too complex");
4896 return;
4899 if (range & ~0xff)
4901 if ((inst.instruction == T_OPCODE_PUSH
4902 && (range & ~0xff) == 1 << REG_LR)
4903 || (inst.instruction == T_OPCODE_POP
4904 && (range & ~0xff) == 1 << REG_PC))
4906 inst.instruction |= THUMB_PP_PC_LR;
4907 range &= 0xff;
4909 else
4911 inst.error = _("invalid register list to push/pop instruction");
4912 return;
4916 inst.instruction |= range;
4917 end_of_line (str);
4920 static void
4921 do_t_str (str)
4922 char * str;
4924 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4927 static void
4928 do_t_strb (str)
4929 char * str;
4931 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4934 static void
4935 do_t_strh (str)
4936 char * str;
4938 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4941 static void
4942 do_t_sub (str)
4943 char * str;
4945 thumb_add_sub (str, 1);
4948 static void
4949 do_t_swi (str)
4950 char * str;
4952 skip_whitespace (str);
4954 if (my_get_expression (&inst.reloc.exp, &str))
4955 return;
4957 inst.reloc.type = BFD_RELOC_ARM_SWI;
4958 end_of_line (str);
4959 return;
4962 static void
4963 do_t_adr (str)
4964 char * str;
4966 int reg;
4968 /* This is a pseudo-op of the form "adr rd, label" to be converted
4969 into a relative address of the form "add rd, pc, #label-.-4". */
4970 skip_whitespace (str);
4972 /* Store Rd in temporary location inside instruction. */
4973 if ((reg = reg_required_here (&str, 4)) == FAIL
4974 || (reg > 7) /* For Thumb reg must be r0..r7. */
4975 || skip_past_comma (&str) == FAIL
4976 || my_get_expression (&inst.reloc.exp, &str))
4978 if (!inst.error)
4979 inst.error = BAD_ARGS;
4980 return;
4983 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4984 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
4985 inst.reloc.pc_rel = 1;
4986 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
4988 end_of_line (str);
4991 static void
4992 insert_reg (entry)
4993 int entry;
4995 int len = strlen (reg_table[entry].name) + 2;
4996 char * buf = (char *) xmalloc (len);
4997 char * buf2 = (char *) xmalloc (len);
4998 int i = 0;
5000 #ifdef REGISTER_PREFIX
5001 buf[i++] = REGISTER_PREFIX;
5002 #endif
5004 strcpy (buf + i, reg_table[entry].name);
5006 for (i = 0; buf[i]; i++)
5007 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
5009 buf2[i] = '\0';
5011 hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
5012 hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
5015 static void
5016 insert_reg_alias (str, regnum)
5017 char *str;
5018 int regnum;
5020 struct reg_entry *new =
5021 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
5022 char *name = xmalloc (strlen (str) + 1);
5023 strcpy (name, str);
5025 new->name = name;
5026 new->number = regnum;
5028 hash_insert (arm_reg_hsh, name, (PTR) new);
5031 static void
5032 set_constant_flonums ()
5034 int i;
5036 for (i = 0; i < NUM_FLOAT_VALS; i++)
5037 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
5038 abort ();
5041 void
5042 md_begin ()
5044 unsigned mach;
5045 unsigned int i;
5047 if ( (arm_ops_hsh = hash_new ()) == NULL
5048 || (arm_tops_hsh = hash_new ()) == NULL
5049 || (arm_cond_hsh = hash_new ()) == NULL
5050 || (arm_shift_hsh = hash_new ()) == NULL
5051 || (arm_reg_hsh = hash_new ()) == NULL
5052 || (arm_psr_hsh = hash_new ()) == NULL)
5053 as_fatal (_("Virtual memory exhausted"));
5055 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
5056 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
5057 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
5058 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
5059 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
5060 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
5061 for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
5062 hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
5063 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
5064 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
5066 for (i = 0; reg_table[i].name; i++)
5067 insert_reg (i);
5069 set_constant_flonums ();
5071 #if defined OBJ_COFF || defined OBJ_ELF
5073 unsigned int flags = 0;
5075 /* Set the flags in the private structure. */
5076 if (uses_apcs_26) flags |= F_APCS26;
5077 if (support_interwork) flags |= F_INTERWORK;
5078 if (uses_apcs_float) flags |= F_APCS_FLOAT;
5079 if (pic_code) flags |= F_PIC;
5080 if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT;
5082 bfd_set_private_flags (stdoutput, flags);
5084 #endif
5086 /* Record the CPU type as well. */
5087 switch (cpu_variant & ARM_CPU_MASK)
5089 case ARM_2:
5090 mach = bfd_mach_arm_2;
5091 break;
5093 case ARM_3: /* Also ARM_250. */
5094 mach = bfd_mach_arm_2a;
5095 break;
5097 default:
5098 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined. */
5099 mach = bfd_mach_arm_4;
5100 break;
5102 case ARM_7: /* Also ARM_6. */
5103 mach = bfd_mach_arm_3;
5104 break;
5107 /* Catch special cases. */
5108 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
5110 if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
5111 mach = bfd_mach_arm_5T;
5112 else if (cpu_variant & ARM_EXT_V5)
5113 mach = bfd_mach_arm_5;
5114 else if (cpu_variant & ARM_THUMB)
5115 mach = bfd_mach_arm_4T;
5116 else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
5117 mach = bfd_mach_arm_4;
5118 else if (cpu_variant & ARM_LONGMUL)
5119 mach = bfd_mach_arm_3M;
5122 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
5125 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5126 for use in the a.out file, and stores them in the array pointed to by buf.
5127 This knows about the endian-ness of the target machine and does
5128 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5129 2 (short) and 4 (long) Floating numbers are put out as a series of
5130 LITTLENUMS (shorts, here at least). */
5131 void
5132 md_number_to_chars (buf, val, n)
5133 char * buf;
5134 valueT val;
5135 int n;
5137 if (target_big_endian)
5138 number_to_chars_bigendian (buf, val, n);
5139 else
5140 number_to_chars_littleendian (buf, val, n);
5143 static valueT
5144 md_chars_to_number (buf, n)
5145 char * buf;
5146 int n;
5148 valueT result = 0;
5149 unsigned char * where = (unsigned char *) buf;
5151 if (target_big_endian)
5153 while (n--)
5155 result <<= 8;
5156 result |= (*where++ & 255);
5159 else
5161 while (n--)
5163 result <<= 8;
5164 result |= (where[n] & 255);
5168 return result;
5171 /* Turn a string in input_line_pointer into a floating point constant
5172 of type TYPE, and store the appropriate bytes in *litP. The number
5173 of LITTLENUMS emitted is stored in *sizeP . An error message is
5174 returned, or NULL on OK.
5176 Note that fp constants aren't represent in the normal way on the ARM.
5177 In big endian mode, things are as expected. However, in little endian
5178 mode fp constants are big-endian word-wise, and little-endian byte-wise
5179 within the words. For example, (double) 1.1 in big endian mode is
5180 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5181 the byte sequence 99 99 f1 3f 9a 99 99 99.
5183 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5185 char *
5186 md_atof (type, litP, sizeP)
5187 char type;
5188 char * litP;
5189 int * sizeP;
5191 int prec;
5192 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5193 char *t;
5194 int i;
5196 switch (type)
5198 case 'f':
5199 case 'F':
5200 case 's':
5201 case 'S':
5202 prec = 2;
5203 break;
5205 case 'd':
5206 case 'D':
5207 case 'r':
5208 case 'R':
5209 prec = 4;
5210 break;
5212 case 'x':
5213 case 'X':
5214 prec = 6;
5215 break;
5217 case 'p':
5218 case 'P':
5219 prec = 6;
5220 break;
5222 default:
5223 *sizeP = 0;
5224 return _("Bad call to MD_ATOF()");
5227 t = atof_ieee (input_line_pointer, type, words);
5228 if (t)
5229 input_line_pointer = t;
5230 *sizeP = prec * 2;
5232 if (target_big_endian)
5234 for (i = 0; i < prec; i++)
5236 md_number_to_chars (litP, (valueT) words[i], 2);
5237 litP += 2;
5240 else
5242 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5243 8 byte float the order is 1 0 3 2. */
5244 for (i = 0; i < prec; i += 2)
5246 md_number_to_chars (litP, (valueT) words[i + 1], 2);
5247 md_number_to_chars (litP + 2, (valueT) words[i], 2);
5248 litP += 4;
5252 return 0;
5255 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5256 long
5257 md_pcrel_from (fixP)
5258 fixS * fixP;
5260 if ( fixP->fx_addsy
5261 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
5262 && fixP->fx_subsy == NULL)
5263 return 0;
5265 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
5267 /* PC relative addressing on the Thumb is slightly odd
5268 as the bottom two bits of the PC are forced to zero
5269 for the calculation. */
5270 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
5273 #ifdef TE_WINCE
5274 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
5275 so we un-adjust here to compensate for the accomodation. */
5276 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
5277 #else
5278 return fixP->fx_where + fixP->fx_frag->fr_address;
5279 #endif
5282 /* Round up a section size to the appropriate boundary. */
5283 valueT
5284 md_section_align (segment, size)
5285 segT segment ATTRIBUTE_UNUSED;
5286 valueT size;
5288 #ifdef OBJ_ELF
5289 return size;
5290 #else
5291 /* Round all sects to multiple of 4 */
5292 return (size + 3) & ~3;
5293 #endif
5296 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5297 we have no need to default values of symbols. */
5299 /* ARGSUSED */
5300 symbolS *
5301 md_undefined_symbol (name)
5302 char * name ATTRIBUTE_UNUSED;
5304 #ifdef OBJ_ELF
5305 if (name[0] == '_' && name[1] == 'G'
5306 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
5308 if (!GOT_symbol)
5310 if (symbol_find (name))
5311 as_bad ("GOT already in the symbol table");
5313 GOT_symbol = symbol_new (name, undefined_section,
5314 (valueT)0, & zero_address_frag);
5317 return GOT_symbol;
5319 #endif
5321 return 0;
5324 /* arm_reg_parse () := if it looks like a register, return its token and
5325 advance the pointer. */
5327 static int
5328 arm_reg_parse (ccp)
5329 register char ** ccp;
5331 char * start = * ccp;
5332 char c;
5333 char * p;
5334 struct reg_entry * reg;
5336 #ifdef REGISTER_PREFIX
5337 if (*start != REGISTER_PREFIX)
5338 return FAIL;
5339 p = start + 1;
5340 #else
5341 p = start;
5342 #ifdef OPTIONAL_REGISTER_PREFIX
5343 if (*p == OPTIONAL_REGISTER_PREFIX)
5344 p++, start++;
5345 #endif
5346 #endif
5347 if (!isalpha (*p) || !is_name_beginner (*p))
5348 return FAIL;
5350 c = *p++;
5351 while (isalpha (c) || isdigit (c) || c == '_')
5352 c = *p++;
5354 *--p = 0;
5355 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
5356 *p = c;
5358 if (reg)
5360 *ccp = p;
5361 return reg->number;
5364 return FAIL;
5368 md_apply_fix3 (fixP, val, seg)
5369 fixS * fixP;
5370 valueT * val;
5371 segT seg;
5373 offsetT value = * val;
5374 offsetT newval;
5375 unsigned int newimm;
5376 unsigned long temp;
5377 int sign;
5378 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5379 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
5381 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5383 /* Note whether this will delete the relocation. */
5384 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5385 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
5386 && !fixP->fx_pcrel)
5387 #else
5388 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5389 #endif
5390 fixP->fx_done = 1;
5392 /* If this symbol is in a different section then we need to leave it for
5393 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5394 so we have to undo it's effects here. */
5395 if (fixP->fx_pcrel)
5397 if (fixP->fx_addsy != NULL
5398 && S_IS_DEFINED (fixP->fx_addsy)
5399 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5401 if (target_oabi
5402 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
5403 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
5405 value = 0;
5406 else
5407 value += md_pcrel_from (fixP);
5411 fixP->fx_addnumber = value; /* Remember value for emit_reloc. */
5413 switch (fixP->fx_r_type)
5415 case BFD_RELOC_ARM_IMMEDIATE:
5416 newimm = validate_immediate (value);
5417 temp = md_chars_to_number (buf, INSN_SIZE);
5419 /* If the instruction will fail, see if we can fix things up by
5420 changing the opcode. */
5421 if (newimm == (unsigned int) FAIL
5422 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5424 as_bad_where (fixP->fx_file, fixP->fx_line,
5425 _("invalid constant (%lx) after fixup"),
5426 (unsigned long) value);
5427 break;
5430 newimm |= (temp & 0xfffff000);
5431 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5432 break;
5434 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5436 unsigned int highpart = 0;
5437 unsigned int newinsn = 0xe1a00000; /* nop */
5438 newimm = validate_immediate (value);
5439 temp = md_chars_to_number (buf, INSN_SIZE);
5441 /* If the instruction will fail, see if we can fix things up by
5442 changing the opcode. */
5443 if (newimm == (unsigned int) FAIL
5444 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
5446 /* No ? OK - try using two ADD instructions to generate the value. */
5447 newimm = validate_immediate_twopart (value, & highpart);
5449 /* Yes - then make sure that the second instruction is also an add. */
5450 if (newimm != (unsigned int) FAIL)
5451 newinsn = temp;
5452 /* Still No ? Try using a negated value. */
5453 else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL)
5454 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
5455 /* Otherwise - give up. */
5456 else
5458 as_bad_where (fixP->fx_file, fixP->fx_line,
5459 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value);
5460 break;
5463 /* Replace the first operand in the 2nd instruction (which is the PC)
5464 with the destination register. We have already added in the PC in the
5465 first instruction and we do not want to do it again. */
5466 newinsn &= ~ 0xf0000;
5467 newinsn |= ((newinsn & 0x0f000) << 4);
5470 newimm |= (temp & 0xfffff000);
5471 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5473 highpart |= (newinsn & 0xfffff000);
5474 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
5476 break;
5478 case BFD_RELOC_ARM_OFFSET_IMM:
5479 sign = value >= 0;
5481 if (value < 0)
5482 value = - value;
5484 if (validate_offset_imm (value, 0) == FAIL)
5486 as_bad_where (fixP->fx_file, fixP->fx_line,
5487 _("bad immediate value for offset (%ld)"), (long) value);
5488 break;
5491 newval = md_chars_to_number (buf, INSN_SIZE);
5492 newval &= 0xff7ff000;
5493 newval |= value | (sign ? INDEX_UP : 0);
5494 md_number_to_chars (buf, newval, INSN_SIZE);
5495 break;
5497 case BFD_RELOC_ARM_OFFSET_IMM8:
5498 case BFD_RELOC_ARM_HWLITERAL:
5499 sign = value >= 0;
5501 if (value < 0)
5502 value = - value;
5504 if (validate_offset_imm (value, 1) == FAIL)
5506 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5507 as_bad_where (fixP->fx_file, fixP->fx_line,
5508 _("invalid literal constant: pool needs to be closer"));
5509 else
5510 as_bad (_("bad immediate value for half-word offset (%ld)"),
5511 (long) value);
5512 break;
5515 newval = md_chars_to_number (buf, INSN_SIZE);
5516 newval &= 0xff7ff0f0;
5517 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
5518 md_number_to_chars (buf, newval, INSN_SIZE);
5519 break;
5521 case BFD_RELOC_ARM_LITERAL:
5522 sign = value >= 0;
5524 if (value < 0)
5525 value = - value;
5527 if (validate_offset_imm (value, 0) == FAIL)
5529 as_bad_where (fixP->fx_file, fixP->fx_line,
5530 _("invalid literal constant: pool needs to be closer"));
5531 break;
5534 newval = md_chars_to_number (buf, INSN_SIZE);
5535 newval &= 0xff7ff000;
5536 newval |= value | (sign ? INDEX_UP : 0);
5537 md_number_to_chars (buf, newval, INSN_SIZE);
5538 break;
5540 case BFD_RELOC_ARM_SHIFT_IMM:
5541 newval = md_chars_to_number (buf, INSN_SIZE);
5542 if (((unsigned long) value) > 32
5543 || (value == 32
5544 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5546 as_bad_where (fixP->fx_file, fixP->fx_line,
5547 _("shift expression is too large"));
5548 break;
5551 if (value == 0)
5552 newval &= ~0x60; /* Shifts of zero must be done as lsl */
5553 else if (value == 32)
5554 value = 0;
5555 newval &= 0xfffff07f;
5556 newval |= (value & 0x1f) << 7;
5557 md_number_to_chars (buf, newval , INSN_SIZE);
5558 break;
5560 case BFD_RELOC_ARM_SWI:
5561 if (arm_data->thumb_mode)
5563 if (((unsigned long) value) > 0xff)
5564 as_bad_where (fixP->fx_file, fixP->fx_line,
5565 _("Invalid swi expression"));
5566 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5567 newval |= value;
5568 md_number_to_chars (buf, newval, THUMB_SIZE);
5570 else
5572 if (((unsigned long) value) > 0x00ffffff)
5573 as_bad_where (fixP->fx_file, fixP->fx_line,
5574 _("Invalid swi expression"));
5575 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5576 newval |= value;
5577 md_number_to_chars (buf, newval , INSN_SIZE);
5579 break;
5581 case BFD_RELOC_ARM_MULTI:
5582 if (((unsigned long) value) > 0xffff)
5583 as_bad_where (fixP->fx_file, fixP->fx_line,
5584 _("Invalid expression in load/store multiple"));
5585 newval = value | md_chars_to_number (buf, INSN_SIZE);
5586 md_number_to_chars (buf, newval, INSN_SIZE);
5587 break;
5589 case BFD_RELOC_ARM_PCREL_BRANCH:
5590 newval = md_chars_to_number (buf, INSN_SIZE);
5592 /* Sign-extend a 24-bit number. */
5593 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
5595 #ifdef OBJ_ELF
5596 if (! target_oabi)
5597 value = fixP->fx_offset;
5598 #endif
5600 /* We are going to store value (shifted right by two) in the
5601 instruction, in a 24 bit, signed field. Thus we need to check
5602 that none of the top 8 bits of the shifted value (top 7 bits of
5603 the unshifted, unsigned value) are set, or that they are all set. */
5604 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
5605 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
5607 #ifdef OBJ_ELF
5608 /* Normally we would be stuck at this point, since we cannot store
5609 the absolute address that is the destination of the branch in the
5610 24 bits of the branch instruction. If however, we happen to know
5611 that the destination of the branch is in the same section as the
5612 branch instruciton itself, then we can compute the relocation for
5613 ourselves and not have to bother the linker with it.
5615 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
5616 because I have not worked out how to do this for OBJ_COFF or
5617 target_oabi. */
5618 if (! target_oabi
5619 && fixP->fx_addsy != NULL
5620 && S_IS_DEFINED (fixP->fx_addsy)
5621 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
5623 /* Get pc relative value to go into the branch. */
5624 value = * val;
5626 /* Permit a backward branch provided that enough bits are set.
5627 Allow a forwards branch, provided that enough bits are clear. */
5628 if ((value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
5629 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
5630 fixP->fx_done = 1;
5633 if (! fixP->fx_done)
5634 #endif
5635 as_bad_where (fixP->fx_file, fixP->fx_line,
5636 _("gas can't handle same-section branch dest >= 0x04000000"));
5639 value >>= 2;
5640 value += SEXT24 (newval);
5642 if ((value & ~ ((offsetT) 0xffffff)) != 0
5643 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
5644 as_bad_where (fixP->fx_file, fixP->fx_line,
5645 _("out of range branch"));
5647 newval = (value & 0x00ffffff) | (newval & 0xff000000);
5648 md_number_to_chars (buf, newval, INSN_SIZE);
5649 break;
5651 case BFD_RELOC_ARM_PCREL_BLX:
5653 offsetT hbit;
5654 newval = md_chars_to_number (buf, INSN_SIZE);
5656 #ifdef OBJ_ELF
5657 if (! target_oabi)
5658 value = fixP->fx_offset;
5659 #endif
5660 hbit = (value >> 1) & 1;
5661 value = (value >> 2) & 0x00ffffff;
5662 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5663 newval = value | (newval & 0xfe000000) | (hbit << 24);
5664 md_number_to_chars (buf, newval, INSN_SIZE);
5666 break;
5668 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5669 newval = md_chars_to_number (buf, THUMB_SIZE);
5671 addressT diff = (newval & 0xff) << 1;
5672 if (diff & 0x100)
5673 diff |= ~0xff;
5675 value += diff;
5676 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5677 as_bad_where (fixP->fx_file, fixP->fx_line,
5678 _("Branch out of range"));
5679 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5681 md_number_to_chars (buf, newval, THUMB_SIZE);
5682 break;
5684 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5685 newval = md_chars_to_number (buf, THUMB_SIZE);
5687 addressT diff = (newval & 0x7ff) << 1;
5688 if (diff & 0x800)
5689 diff |= ~0x7ff;
5691 value += diff;
5692 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5693 as_bad_where (fixP->fx_file, fixP->fx_line,
5694 _("Branch out of range"));
5695 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5697 md_number_to_chars (buf, newval, THUMB_SIZE);
5698 break;
5700 case BFD_RELOC_THUMB_PCREL_BLX:
5701 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5703 offsetT newval2;
5704 addressT diff;
5706 newval = md_chars_to_number (buf, THUMB_SIZE);
5707 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5708 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5709 if (diff & 0x400000)
5710 diff |= ~0x3fffff;
5711 #ifdef OBJ_ELF
5712 value = fixP->fx_offset;
5713 #endif
5714 value += diff;
5715 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5716 as_bad_where (fixP->fx_file, fixP->fx_line,
5717 _("Branch with link out of range"));
5719 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5720 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5721 md_number_to_chars (buf, newval, THUMB_SIZE);
5722 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5724 break;
5726 case BFD_RELOC_8:
5727 if (fixP->fx_done || fixP->fx_pcrel)
5728 md_number_to_chars (buf, value, 1);
5729 #ifdef OBJ_ELF
5730 else if (!target_oabi)
5732 value = fixP->fx_offset;
5733 md_number_to_chars (buf, value, 1);
5735 #endif
5736 break;
5738 case BFD_RELOC_16:
5739 if (fixP->fx_done || fixP->fx_pcrel)
5740 md_number_to_chars (buf, value, 2);
5741 #ifdef OBJ_ELF
5742 else if (!target_oabi)
5744 value = fixP->fx_offset;
5745 md_number_to_chars (buf, value, 2);
5747 #endif
5748 break;
5750 #ifdef OBJ_ELF
5751 case BFD_RELOC_ARM_GOT32:
5752 case BFD_RELOC_ARM_GOTOFF:
5753 md_number_to_chars (buf, 0, 4);
5754 break;
5755 #endif
5757 case BFD_RELOC_RVA:
5758 case BFD_RELOC_32:
5759 if (fixP->fx_done || fixP->fx_pcrel)
5760 md_number_to_chars (buf, value, 4);
5761 #ifdef OBJ_ELF
5762 else if (!target_oabi)
5764 value = fixP->fx_offset;
5765 md_number_to_chars (buf, value, 4);
5767 #endif
5768 break;
5770 #ifdef OBJ_ELF
5771 case BFD_RELOC_ARM_PLT32:
5772 /* It appears the instruction is fully prepared at this point. */
5773 break;
5774 #endif
5776 case BFD_RELOC_ARM_GOTPC:
5777 md_number_to_chars (buf, value, 4);
5778 break;
5780 case BFD_RELOC_ARM_CP_OFF_IMM:
5781 sign = value >= 0;
5782 if (value < -1023 || value > 1023 || (value & 3))
5783 as_bad_where (fixP->fx_file, fixP->fx_line,
5784 _("Illegal value for co-processor offset"));
5785 if (value < 0)
5786 value = -value;
5787 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5788 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5789 md_number_to_chars (buf, newval , INSN_SIZE);
5790 break;
5792 case BFD_RELOC_ARM_THUMB_OFFSET:
5793 newval = md_chars_to_number (buf, THUMB_SIZE);
5794 /* Exactly what ranges, and where the offset is inserted depends on
5795 the type of instruction, we can establish this from the top 4 bits */
5796 switch (newval >> 12)
5798 case 4: /* PC load */
5799 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5800 forced to zero for these loads, so we will need to round
5801 up the offset if the instruction address is not word
5802 aligned (since the final address produced must be, and
5803 we can only describe word-aligned immediate offsets). */
5805 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5806 as_bad_where (fixP->fx_file, fixP->fx_line,
5807 _("Invalid offset, target not word aligned (0x%08X)"),
5808 (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5810 if ((value + 2) & ~0x3fe)
5811 as_bad_where (fixP->fx_file, fixP->fx_line,
5812 _("Invalid offset, value too big (0x%08X)"), value);
5814 /* Round up, since pc will be rounded down. */
5815 newval |= (value + 2) >> 2;
5816 break;
5818 case 9: /* SP load/store */
5819 if (value & ~0x3fc)
5820 as_bad_where (fixP->fx_file, fixP->fx_line,
5821 _("Invalid offset, value too big (0x%08X)"), value);
5822 newval |= value >> 2;
5823 break;
5825 case 6: /* Word load/store */
5826 if (value & ~0x7c)
5827 as_bad_where (fixP->fx_file, fixP->fx_line,
5828 _("Invalid offset, value too big (0x%08X)"), value);
5829 newval |= value << 4; /* 6 - 2 */
5830 break;
5832 case 7: /* Byte load/store */
5833 if (value & ~0x1f)
5834 as_bad_where (fixP->fx_file, fixP->fx_line,
5835 _("Invalid offset, value too big (0x%08X)"), value);
5836 newval |= value << 6;
5837 break;
5839 case 8: /* Halfword load/store */
5840 if (value & ~0x3e)
5841 as_bad_where (fixP->fx_file, fixP->fx_line,
5842 _("Invalid offset, value too big (0x%08X)"), value);
5843 newval |= value << 5; /* 6 - 1 */
5844 break;
5846 default:
5847 as_bad_where (fixP->fx_file, fixP->fx_line,
5848 "Unable to process relocation for thumb opcode: %lx",
5849 (unsigned long) newval);
5850 break;
5852 md_number_to_chars (buf, newval, THUMB_SIZE);
5853 break;
5855 case BFD_RELOC_ARM_THUMB_ADD:
5856 /* This is a complicated relocation, since we use it for all of
5857 the following immediate relocations:
5858 3bit ADD/SUB
5859 8bit ADD/SUB
5860 9bit ADD/SUB SP word-aligned
5861 10bit ADD PC/SP word-aligned
5863 The type of instruction being processed is encoded in the
5864 instruction field:
5865 0x8000 SUB
5866 0x00F0 Rd
5867 0x000F Rs
5869 newval = md_chars_to_number (buf, THUMB_SIZE);
5871 int rd = (newval >> 4) & 0xf;
5872 int rs = newval & 0xf;
5873 int subtract = newval & 0x8000;
5875 if (rd == REG_SP)
5877 if (value & ~0x1fc)
5878 as_bad_where (fixP->fx_file, fixP->fx_line,
5879 _("Invalid immediate for stack address calculation"));
5880 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5881 newval |= value >> 2;
5883 else if (rs == REG_PC || rs == REG_SP)
5885 if (subtract ||
5886 value & ~0x3fc)
5887 as_bad_where (fixP->fx_file, fixP->fx_line,
5888 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5889 (unsigned long) value);
5890 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5891 newval |= rd << 8;
5892 newval |= value >> 2;
5894 else if (rs == rd)
5896 if (value & ~0xff)
5897 as_bad_where (fixP->fx_file, fixP->fx_line,
5898 _("Invalid 8bit immediate"));
5899 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5900 newval |= (rd << 8) | value;
5902 else
5904 if (value & ~0x7)
5905 as_bad_where (fixP->fx_file, fixP->fx_line,
5906 _("Invalid 3bit immediate"));
5907 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5908 newval |= rd | (rs << 3) | (value << 6);
5911 md_number_to_chars (buf, newval , THUMB_SIZE);
5912 break;
5914 case BFD_RELOC_ARM_THUMB_IMM:
5915 newval = md_chars_to_number (buf, THUMB_SIZE);
5916 switch (newval >> 11)
5918 case 0x04: /* 8bit immediate MOV */
5919 case 0x05: /* 8bit immediate CMP */
5920 if (value < 0 || value > 255)
5921 as_bad_where (fixP->fx_file, fixP->fx_line,
5922 _("Invalid immediate: %ld is too large"),
5923 (long) value);
5924 newval |= value;
5925 break;
5927 default:
5928 abort ();
5930 md_number_to_chars (buf, newval , THUMB_SIZE);
5931 break;
5933 case BFD_RELOC_ARM_THUMB_SHIFT:
5934 /* 5bit shift value (0..31) */
5935 if (value < 0 || value > 31)
5936 as_bad_where (fixP->fx_file, fixP->fx_line,
5937 _("Illegal Thumb shift value: %ld"), (long) value);
5938 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5939 newval |= value << 6;
5940 md_number_to_chars (buf, newval , THUMB_SIZE);
5941 break;
5943 case BFD_RELOC_VTABLE_INHERIT:
5944 case BFD_RELOC_VTABLE_ENTRY:
5945 fixP->fx_done = 0;
5946 return 1;
5948 case BFD_RELOC_NONE:
5949 default:
5950 as_bad_where (fixP->fx_file, fixP->fx_line,
5951 _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
5954 return 1;
5957 /* Translate internal representation of relocation info to BFD target
5958 format. */
5959 arelent *
5960 tc_gen_reloc (section, fixp)
5961 asection * section ATTRIBUTE_UNUSED;
5962 fixS * fixp;
5964 arelent * reloc;
5965 bfd_reloc_code_real_type code;
5967 reloc = (arelent *) xmalloc (sizeof (arelent));
5969 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
5970 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5971 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5973 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5974 #ifndef OBJ_ELF
5975 if (fixp->fx_pcrel == 0)
5976 reloc->addend = fixp->fx_offset;
5977 else
5978 reloc->addend = fixp->fx_offset = reloc->address;
5979 #else /* OBJ_ELF */
5980 reloc->addend = fixp->fx_offset;
5981 #endif
5983 switch (fixp->fx_r_type)
5985 case BFD_RELOC_8:
5986 if (fixp->fx_pcrel)
5988 code = BFD_RELOC_8_PCREL;
5989 break;
5992 case BFD_RELOC_16:
5993 if (fixp->fx_pcrel)
5995 code = BFD_RELOC_16_PCREL;
5996 break;
5999 case BFD_RELOC_32:
6000 if (fixp->fx_pcrel)
6002 code = BFD_RELOC_32_PCREL;
6003 break;
6006 case BFD_RELOC_ARM_PCREL_BRANCH:
6007 case BFD_RELOC_ARM_PCREL_BLX:
6008 case BFD_RELOC_RVA:
6009 case BFD_RELOC_THUMB_PCREL_BRANCH9:
6010 case BFD_RELOC_THUMB_PCREL_BRANCH12:
6011 case BFD_RELOC_THUMB_PCREL_BRANCH23:
6012 case BFD_RELOC_THUMB_PCREL_BLX:
6013 case BFD_RELOC_VTABLE_ENTRY:
6014 case BFD_RELOC_VTABLE_INHERIT:
6015 code = fixp->fx_r_type;
6016 break;
6018 case BFD_RELOC_ARM_LITERAL:
6019 case BFD_RELOC_ARM_HWLITERAL:
6020 /* If this is called then the a literal has been referenced across
6021 a section boundary - possibly due to an implicit dump */
6022 as_bad_where (fixp->fx_file, fixp->fx_line,
6023 _("Literal referenced across section boundary (Implicit dump?)"));
6024 return NULL;
6026 #ifdef OBJ_ELF
6027 case BFD_RELOC_ARM_GOT32:
6028 case BFD_RELOC_ARM_GOTOFF:
6029 case BFD_RELOC_ARM_PLT32:
6030 code = fixp->fx_r_type;
6031 break;
6032 #endif
6034 case BFD_RELOC_ARM_IMMEDIATE:
6035 as_bad_where (fixp->fx_file, fixp->fx_line,
6036 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
6037 fixp->fx_r_type);
6038 return NULL;
6040 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
6041 as_bad_where (fixp->fx_file, fixp->fx_line,
6042 _("ADRL used for a symbol not defined in the same file"),
6043 fixp->fx_r_type);
6044 return NULL;
6046 case BFD_RELOC_ARM_OFFSET_IMM:
6047 as_bad_where (fixp->fx_file, fixp->fx_line,
6048 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
6049 fixp->fx_r_type);
6050 return NULL;
6052 default:
6054 char * type;
6055 switch (fixp->fx_r_type)
6057 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
6058 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
6059 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
6060 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
6061 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
6062 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
6063 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
6064 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
6065 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
6066 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
6067 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
6068 default: type = _("<unknown>"); break;
6070 as_bad_where (fixp->fx_file, fixp->fx_line,
6071 _("Can not represent %s relocation in this object file format (%d)"),
6072 type, fixp->fx_pcrel);
6073 return NULL;
6077 #ifdef OBJ_ELF
6078 if (code == BFD_RELOC_32_PCREL
6079 && GOT_symbol
6080 && fixp->fx_addsy == GOT_symbol)
6082 code = BFD_RELOC_ARM_GOTPC;
6083 reloc->addend = fixp->fx_offset = reloc->address;
6085 #endif
6087 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6089 if (reloc->howto == NULL)
6091 as_bad_where (fixp->fx_file, fixp->fx_line,
6092 _("Can not represent %s relocation in this object file format"),
6093 bfd_get_reloc_code_name (code));
6094 return NULL;
6097 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
6098 vtable entry to be used in the relocation's section offset. */
6099 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6100 reloc->address = fixp->fx_offset;
6102 return reloc;
6106 md_estimate_size_before_relax (fragP, segtype)
6107 fragS * fragP ATTRIBUTE_UNUSED;
6108 segT segtype ATTRIBUTE_UNUSED;
6110 as_fatal (_("md_estimate_size_before_relax\n"));
6111 return 1;
6114 static void
6115 output_inst PARAMS ((void))
6117 char * to = NULL;
6119 if (inst.error)
6121 as_bad (inst.error);
6122 return;
6125 to = frag_more (inst.size);
6127 if (thumb_mode && (inst.size > THUMB_SIZE))
6129 assert (inst.size == (2 * THUMB_SIZE));
6130 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
6131 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
6133 else if (inst.size > INSN_SIZE)
6135 assert (inst.size == (2 * INSN_SIZE));
6136 md_number_to_chars (to, inst.instruction, INSN_SIZE);
6137 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
6139 else
6140 md_number_to_chars (to, inst.instruction, inst.size);
6142 if (inst.reloc.type != BFD_RELOC_NONE)
6143 fix_new_arm (frag_now, to - frag_now->fr_literal,
6144 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
6145 inst.reloc.type);
6147 return;
6150 void
6151 md_assemble (str)
6152 char * str;
6154 char c;
6155 char * p;
6156 char * q;
6157 char * start;
6159 /* Align the instruction.
6160 This may not be the right thing to do but ... */
6161 /* arm_align (2, 0); */
6162 listing_prev_line (); /* Defined in listing.h */
6164 /* Align the previous label if needed. */
6165 if (last_label_seen != NULL)
6167 symbol_set_frag (last_label_seen, frag_now);
6168 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
6169 S_SET_SEGMENT (last_label_seen, now_seg);
6172 memset (&inst, '\0', sizeof (inst));
6173 inst.reloc.type = BFD_RELOC_NONE;
6175 skip_whitespace (str);
6177 /* Scan up to the end of the op-code, which must end in white space or
6178 end of string. */
6179 for (start = p = str; *p != '\0'; p++)
6180 if (*p == ' ')
6181 break;
6183 if (p == str)
6185 as_bad (_("No operator -- statement `%s'\n"), str);
6186 return;
6189 if (thumb_mode)
6191 CONST struct thumb_opcode * opcode;
6193 c = *p;
6194 *p = '\0';
6195 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
6196 *p = c;
6198 if (opcode)
6200 /* Check that this instruction is supported for this CPU. */
6201 if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0)
6203 as_bad (_("selected processor does not support this opcode"));
6204 return;
6207 inst.instruction = opcode->value;
6208 inst.size = opcode->size;
6209 (*opcode->parms)(p);
6210 output_inst ();
6211 return;
6214 else
6216 CONST struct asm_opcode * opcode;
6217 unsigned long cond_code;
6219 inst.size = INSN_SIZE;
6220 /* p now points to the end of the opcode, probably white space, but we
6221 have to break the opcode up in case it contains condionals and flags;
6222 keep trying with progressively smaller basic instructions until one
6223 matches, or we run out of opcode. */
6224 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
6226 for (; q != str; q--)
6228 c = *q;
6229 *q = '\0';
6231 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
6232 *q = c;
6234 if (opcode && opcode->template)
6236 unsigned long flag_bits = 0;
6237 char * r;
6239 /* Check that this instruction is supported for this CPU. */
6240 if ((opcode->variants & cpu_variant) == 0)
6241 goto try_shorter;
6243 inst.instruction = opcode->value;
6244 if (q == p) /* Just a simple opcode. */
6246 if (opcode->comp_suffix)
6248 if (*opcode->comp_suffix != '\0')
6249 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
6250 str, opcode->comp_suffix);
6251 else
6252 /* Not a conditional instruction. */
6253 (*opcode->parms)(q, 0);
6255 else
6257 /* A conditional instruction with default condition. */
6258 inst.instruction |= COND_ALWAYS;
6259 (*opcode->parms)(q, 0);
6261 output_inst ();
6262 return;
6265 /* Not just a simple opcode. Check if extra is a conditional. */
6266 r = q;
6267 if (p - r >= 2)
6269 CONST struct asm_cond *cond;
6270 char d = *(r + 2);
6272 *(r + 2) = '\0';
6273 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
6274 *(r + 2) = d;
6275 if (cond)
6277 if (cond->value == 0xf0000000)
6278 as_tsktsk (
6279 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6281 cond_code = cond->value;
6282 r += 2;
6284 else
6285 cond_code = COND_ALWAYS;
6287 else
6288 cond_code = COND_ALWAYS;
6290 /* Apply the conditional, or complain it's not allowed. */
6291 if (opcode->comp_suffix && *opcode->comp_suffix == '\0')
6293 /* Instruction isn't conditional */
6294 if (cond_code != COND_ALWAYS)
6296 as_bad (_("Opcode `%s' is unconditional\n"), str);
6297 return;
6300 else
6301 /* Instruction is conditional: set the condition into it. */
6302 inst.instruction |= cond_code;
6305 /* If there is a compulsory suffix, it should come here, before
6306 any optional flags. */
6307 if (opcode->comp_suffix && *opcode->comp_suffix != '\0')
6309 CONST char *s = opcode->comp_suffix;
6311 while (*s)
6313 inst.suffix++;
6314 if (*r == *s)
6315 break;
6316 s++;
6319 if (*s == '\0')
6321 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6322 opcode->comp_suffix);
6323 return;
6326 r++;
6329 /* The remainder, if any should now be flags for the instruction;
6330 Scan these checking each one found with the opcode. */
6331 if (r != p)
6333 char d;
6334 CONST struct asm_flg *flag = opcode->flags;
6336 if (flag)
6338 int flagno;
6340 d = *p;
6341 *p = '\0';
6343 for (flagno = 0; flag[flagno].template; flagno++)
6345 if (streq (r, flag[flagno].template))
6347 flag_bits |= flag[flagno].set_bits;
6348 break;
6352 *p = d;
6353 if (! flag[flagno].template)
6354 goto try_shorter;
6356 else
6357 goto try_shorter;
6360 (*opcode->parms) (p, flag_bits);
6361 output_inst ();
6362 return;
6365 try_shorter:
6370 /* It wasn't an instruction, but it might be a register alias of the form
6371 alias .req reg */
6372 q = p;
6373 skip_whitespace (q);
6375 c = *p;
6376 *p = '\0';
6378 if (*q && !strncmp (q, ".req ", 4))
6380 int reg;
6381 char * copy_of_str = str;
6382 char * r;
6384 q += 4;
6385 skip_whitespace (q);
6387 for (r = q; *r != '\0'; r++)
6388 if (*r == ' ')
6389 break;
6391 if (r != q)
6393 int regnum;
6394 char d = *r;
6396 *r = '\0';
6397 regnum = arm_reg_parse (& q);
6398 *r = d;
6400 reg = arm_reg_parse (& str);
6402 if (reg == FAIL)
6404 if (regnum != FAIL)
6405 insert_reg_alias (str, regnum);
6406 else
6407 as_warn (_("register '%s' does not exist\n"), q);
6409 else if (regnum != FAIL)
6411 if (reg != regnum)
6412 as_warn (_("ignoring redefinition of register alias '%s'"),
6413 copy_of_str );
6415 /* Do not warn about redefinitions to the same alias. */
6417 else
6418 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6419 copy_of_str, q);
6421 else
6422 as_warn (_("ignoring incomplete .req pseuso op"));
6424 *p = c;
6425 return;
6428 *p = c;
6429 as_bad (_("bad instruction `%s'"), start);
6433 * md_parse_option
6434 * Invocation line includes a switch not recognized by the base assembler.
6435 * See if it's a processor-specific option. These are:
6436 * Cpu variants, the arm part is optional:
6437 * -m[arm]1 Currently not supported.
6438 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6439 * -m[arm]3 Arm 3 processor
6440 * -m[arm]6[xx], Arm 6 processors
6441 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6442 * -m[arm]8[10] Arm 8 processors
6443 * -m[arm]9[20][tdmi] Arm 9 processors
6444 * -mstrongarm[110[0]] StrongARM processors
6445 * -m[arm]v[2345[t]] Arm architectures
6446 * -mall All (except the ARM1)
6447 * FP variants:
6448 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6449 * -mfpe-old (No float load/store multiples)
6450 * -mno-fpu Disable all floating point instructions
6451 * Run-time endian selection:
6452 * -EB big endian cpu
6453 * -EL little endian cpu
6454 * ARM Procedure Calling Standard:
6455 * -mapcs-32 32 bit APCS
6456 * -mapcs-26 26 bit APCS
6457 * -mapcs-float Pass floats in float regs
6458 * -mapcs-reentrant Position independent code
6459 * -mthumb-interwork Code supports Arm/Thumb interworking
6460 * -moabi Old ELF ABI
6463 CONST char * md_shortopts = "m:k";
6464 struct option md_longopts[] =
6466 #ifdef ARM_BI_ENDIAN
6467 #define OPTION_EB (OPTION_MD_BASE + 0)
6468 {"EB", no_argument, NULL, OPTION_EB},
6469 #define OPTION_EL (OPTION_MD_BASE + 1)
6470 {"EL", no_argument, NULL, OPTION_EL},
6471 #ifdef OBJ_ELF
6472 #define OPTION_OABI (OPTION_MD_BASE +2)
6473 {"oabi", no_argument, NULL, OPTION_OABI},
6474 #endif
6475 #endif
6476 {NULL, no_argument, NULL, 0}
6478 size_t md_longopts_size = sizeof (md_longopts);
6481 md_parse_option (c, arg)
6482 int c;
6483 char * arg;
6485 char * str = arg;
6487 switch (c)
6489 #ifdef ARM_BI_ENDIAN
6490 case OPTION_EB:
6491 target_big_endian = 1;
6492 break;
6493 case OPTION_EL:
6494 target_big_endian = 0;
6495 break;
6496 #endif
6498 case 'm':
6499 switch (*str)
6501 case 'f':
6502 if (streq (str, "fpa10"))
6503 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
6504 else if (streq (str, "fpa11"))
6505 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
6506 else if (streq (str, "fpe-old"))
6507 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
6508 else
6509 goto bad;
6510 break;
6512 case 'n':
6513 if (streq (str, "no-fpu"))
6514 cpu_variant &= ~FPU_ALL;
6515 break;
6517 #ifdef OBJ_ELF
6518 case 'o':
6519 if (streq (str, "oabi"))
6520 target_oabi = true;
6521 break;
6522 #endif
6524 case 't':
6525 /* Limit assembler to generating only Thumb instructions: */
6526 if (streq (str, "thumb"))
6528 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
6529 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6530 thumb_mode = 1;
6532 else if (streq (str, "thumb-interwork"))
6534 if ((cpu_variant & ARM_THUMB) == 0)
6535 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T;
6536 #if defined OBJ_COFF || defined OBJ_ELF
6537 support_interwork = true;
6538 #endif
6540 else
6541 goto bad;
6542 break;
6544 default:
6545 if (streq (str, "all"))
6547 cpu_variant = ARM_ALL | FPU_ALL;
6548 return 1;
6550 #if defined OBJ_COFF || defined OBJ_ELF
6551 if (! strncmp (str, "apcs-", 5))
6553 /* GCC passes on all command line options starting "-mapcs-..."
6554 to us, so we must parse them here. */
6556 str += 5;
6558 if (streq (str, "32"))
6560 uses_apcs_26 = false;
6561 return 1;
6563 else if (streq (str, "26"))
6565 uses_apcs_26 = true;
6566 return 1;
6568 else if (streq (str, "frame"))
6570 /* Stack frames are being generated - does not affect
6571 linkage of code. */
6572 return 1;
6574 else if (streq (str, "stack-check"))
6576 /* Stack checking is being performed - does not affect
6577 linkage, but does require that the functions
6578 __rt_stkovf_split_small and __rt_stkovf_split_big be
6579 present in the final link. */
6581 return 1;
6583 else if (streq (str, "float"))
6585 /* Floating point arguments are being passed in the floating
6586 point registers. This does affect linking, since this
6587 version of the APCS is incompatible with the version that
6588 passes floating points in the integer registers. */
6590 uses_apcs_float = true;
6591 return 1;
6593 else if (streq (str, "reentrant"))
6595 /* Reentrant code has been generated. This does affect
6596 linking, since there is no point in linking reentrant/
6597 position independent code with absolute position code. */
6598 pic_code = true;
6599 return 1;
6602 as_bad (_("Unrecognised APCS switch -m%s"), arg);
6603 return 0;
6605 #endif
6606 /* Strip off optional "arm" */
6607 if (! strncmp (str, "arm", 3))
6608 str += 3;
6610 switch (*str)
6612 case '1':
6613 if (streq (str, "1"))
6614 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6615 else
6616 goto bad;
6617 break;
6619 case '2':
6620 if (streq (str, "2"))
6621 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6622 else if (streq (str, "250"))
6623 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6624 else
6625 goto bad;
6626 break;
6628 case '3':
6629 if (streq (str, "3"))
6630 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6631 else
6632 goto bad;
6633 break;
6635 case '6':
6636 switch (strtol (str, NULL, 10))
6638 case 6:
6639 case 60:
6640 case 600:
6641 case 610:
6642 case 620:
6643 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6644 break;
6645 default:
6646 goto bad;
6648 break;
6650 case '7':
6651 switch (strtol (str, & str, 10)) /* Eat the processor name */
6653 case 7:
6654 case 70:
6655 case 700:
6656 case 710:
6657 case 720:
6658 case 7100:
6659 case 7500:
6660 break;
6661 default:
6662 goto bad;
6664 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6665 for (; *str; str++)
6667 switch (* str)
6669 case 't':
6670 cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
6671 break;
6673 case 'm':
6674 cpu_variant |= ARM_LONGMUL;
6675 break;
6677 case 'f': /* fe => fp enabled cpu. */
6678 if (str[1] == 'e')
6679 ++ str;
6680 else
6681 goto bad;
6683 case 'c': /* Left over from 710c processor name. */
6684 case 'd': /* Debug */
6685 case 'i': /* Embedded ICE */
6686 /* Included for completeness in ARM processor naming. */
6687 break;
6689 default:
6690 goto bad;
6693 break;
6695 case '8':
6696 if (streq (str, "8") || streq (str, "810"))
6697 cpu_variant = (cpu_variant & ~ARM_ANY)
6698 | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6699 else
6700 goto bad;
6701 break;
6703 case '9':
6704 if (streq (str, "9"))
6705 cpu_variant = (cpu_variant & ~ARM_ANY)
6706 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6707 else if (streq (str, "920"))
6708 cpu_variant = (cpu_variant & ~ARM_ANY)
6709 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
6710 else if (streq (str, "920t"))
6711 cpu_variant = (cpu_variant & ~ARM_ANY)
6712 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6713 else if (streq (str, "9tdmi"))
6714 cpu_variant = (cpu_variant & ~ARM_ANY)
6715 | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6716 else
6717 goto bad;
6718 break;
6721 case 's':
6722 if (streq (str, "strongarm")
6723 || streq (str, "strongarm110")
6724 || streq (str, "strongarm1100"))
6725 cpu_variant = (cpu_variant & ~ARM_ANY)
6726 | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6727 else
6728 goto bad;
6729 break;
6731 case 'v':
6732 /* Select variant based on architecture rather than processor. */
6733 switch (*++str)
6735 case '2':
6736 switch (*++str)
6738 case 'a':
6739 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6740 break;
6741 case 0:
6742 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6743 break;
6744 default:
6745 as_bad (_("Invalid architecture variant -m%s"), arg);
6746 break;
6748 break;
6750 case '3':
6751 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6753 switch (*++str)
6755 case 'm': cpu_variant |= ARM_LONGMUL; break;
6756 case 0: break;
6757 default:
6758 as_bad (_("Invalid architecture variant -m%s"), arg);
6759 break;
6761 break;
6763 case '4':
6764 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4;
6766 switch (*++str)
6768 case 't': cpu_variant |= ARM_THUMB; break;
6769 case 0: break;
6770 default:
6771 as_bad (_("Invalid architecture variant -m%s"), arg);
6772 break;
6774 break;
6776 case '5':
6777 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
6778 switch (*++str)
6780 case 't': cpu_variant |= ARM_THUMB; break;
6781 case 0: break;
6782 default:
6783 as_bad (_("Invalid architecture variant -m%s"), arg);
6784 break;
6786 break;
6788 default:
6789 as_bad (_("Invalid architecture variant -m%s"), arg);
6790 break;
6792 break;
6794 default:
6795 bad:
6796 as_bad (_("Invalid processor variant -m%s"), arg);
6797 return 0;
6800 break;
6802 #if defined OBJ_ELF || defined OBJ_COFF
6803 case 'k':
6804 pic_code = 1;
6805 break;
6806 #endif
6808 default:
6809 return 0;
6812 return 1;
6815 void
6816 md_show_usage (fp)
6817 FILE * fp;
6819 fprintf (fp, _("\
6820 ARM Specific Assembler Options:\n\
6821 -m[arm][<processor name>] select processor variant\n\
6822 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
6823 -mthumb only allow Thumb instructions\n\
6824 -mthumb-interwork mark the assembled code as supporting interworking\n\
6825 -mall allow any instruction\n\
6826 -mfpa10, -mfpa11 select floating point architecture\n\
6827 -mfpe-old don't allow floating-point multiple instructions\n\
6828 -mno-fpu don't allow any floating-point instructions.\n\
6829 -k generate PIC code.\n"));
6830 #if defined OBJ_COFF || defined OBJ_ELF
6831 fprintf (fp, _("\
6832 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
6833 -mapcs-float floating point args are passed in FP regs\n\
6834 -mapcs-reentrant the code is position independent/reentrant\n"));
6835 #endif
6836 #ifdef OBJ_ELF
6837 fprintf (fp, _("\
6838 -moabi support the old ELF ABI\n"));
6839 #endif
6840 #ifdef ARM_BI_ENDIAN
6841 fprintf (fp, _("\
6842 -EB assemble code for a big endian cpu\n\
6843 -EL assemble code for a little endian cpu\n"));
6844 #endif
6847 /* We need to be able to fix up arbitrary expressions in some statements.
6848 This is so that we can handle symbols that are an arbitrary distance from
6849 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6850 which returns part of an address in a form which will be valid for
6851 a data instruction. We do this by pushing the expression into a symbol
6852 in the expr_section, and creating a fix for that. */
6854 static void
6855 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6856 fragS * frag;
6857 int where;
6858 short int size;
6859 expressionS * exp;
6860 int pc_rel;
6861 int reloc;
6863 fixS * new_fix;
6864 arm_fix_data * arm_data;
6866 switch (exp->X_op)
6868 case O_constant:
6869 case O_symbol:
6870 case O_add:
6871 case O_subtract:
6872 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6873 break;
6875 default:
6876 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6877 pc_rel, reloc);
6878 break;
6881 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6882 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
6883 new_fix->tc_fix_data = (PTR) arm_data;
6884 arm_data->thumb_mode = thumb_mode;
6886 return;
6890 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6891 void
6892 cons_fix_new_arm (frag, where, size, exp)
6893 fragS * frag;
6894 int where;
6895 int size;
6896 expressionS * exp;
6898 bfd_reloc_code_real_type type;
6899 int pcrel = 0;
6901 /* Pick a reloc ...
6903 * @@ Should look at CPU word size.
6905 switch (size)
6907 case 2:
6908 type = BFD_RELOC_16;
6909 break;
6910 case 4:
6911 default:
6912 type = BFD_RELOC_32;
6913 break;
6914 case 8:
6915 type = BFD_RELOC_64;
6916 break;
6919 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
6922 /* A good place to do this, although this was probably not intended
6923 for this kind of use. We need to dump the literal pool before
6924 references are made to a null symbol pointer. */
6925 void
6926 arm_cleanup ()
6928 if (current_poolP == NULL)
6929 return;
6931 subseg_set (text_section, 0); /* Put it at the end of text section. */
6932 s_ltorg (0);
6933 listing_prev_line ();
6936 void
6937 arm_start_line_hook ()
6939 last_label_seen = NULL;
6942 void
6943 arm_frob_label (sym)
6944 symbolS * sym;
6946 last_label_seen = sym;
6948 ARM_SET_THUMB (sym, thumb_mode);
6950 #if defined OBJ_COFF || defined OBJ_ELF
6951 ARM_SET_INTERWORK (sym, support_interwork);
6952 #endif
6954 if (label_is_thumb_function_name)
6956 /* When the address of a Thumb function is taken the bottom
6957 bit of that address should be set. This will allow
6958 interworking between Arm and Thumb functions to work
6959 correctly. */
6961 THUMB_SET_FUNC (sym, 1);
6963 label_is_thumb_function_name = false;
6967 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6968 ARM ones. */
6970 void
6971 arm_adjust_symtab ()
6973 #ifdef OBJ_COFF
6974 symbolS * sym;
6976 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6978 if (ARM_IS_THUMB (sym))
6980 if (THUMB_IS_FUNC (sym))
6982 /* Mark the symbol as a Thumb function. */
6983 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
6984 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6985 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6987 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6988 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6989 else
6990 as_bad (_("%s: unexpected function type: %d"),
6991 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6993 else switch (S_GET_STORAGE_CLASS (sym))
6995 case C_EXT:
6996 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6997 break;
6998 case C_STAT:
6999 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
7000 break;
7001 case C_LABEL:
7002 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
7003 break;
7004 default: /* do nothing */
7005 break;
7009 if (ARM_IS_INTERWORK (sym))
7010 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
7012 #endif
7013 #ifdef OBJ_ELF
7014 symbolS * sym;
7015 char bind;
7017 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
7019 if (ARM_IS_THUMB (sym))
7021 elf_symbol_type * elf_sym;
7023 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
7024 bind = ELF_ST_BIND (elf_sym);
7026 /* If it's a .thumb_func, declare it as so,
7027 otherwise tag label as .code 16. */
7028 if (THUMB_IS_FUNC (sym))
7029 elf_sym->internal_elf_sym.st_info =
7030 ELF_ST_INFO (bind, STT_ARM_TFUNC);
7031 else
7032 elf_sym->internal_elf_sym.st_info =
7033 ELF_ST_INFO (bind, STT_ARM_16BIT);
7036 #endif
7040 arm_data_in_code ()
7042 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
7044 *input_line_pointer = '/';
7045 input_line_pointer += 5;
7046 *input_line_pointer = 0;
7047 return 1;
7050 return 0;
7053 char *
7054 arm_canonicalize_symbol_name (name)
7055 char * name;
7057 int len;
7059 if (thumb_mode && (len = strlen (name)) > 5
7060 && streq (name + len - 5, "/data"))
7061 *(name + len - 5) = 0;
7063 return name;
7066 boolean
7067 arm_validate_fix (fixP)
7068 fixS * fixP;
7070 /* If the destination of the branch is a defined symbol which does not have
7071 the THUMB_FUNC attribute, then we must be calling a function which has
7072 the (interfacearm) attribute. We look for the Thumb entry point to that
7073 function and change the branch to refer to that function instead. */
7074 if ( fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
7075 && fixP->fx_addsy != NULL
7076 && S_IS_DEFINED (fixP->fx_addsy)
7077 && ! THUMB_IS_FUNC (fixP->fx_addsy))
7079 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
7080 return true;
7083 return false;
7086 #ifdef OBJ_ELF
7087 /* Relocations against Thumb function names must be left unadjusted,
7088 so that the linker can use this information to correctly set the
7089 bottom bit of their addresses. The MIPS version of this function
7090 also prevents relocations that are mips-16 specific, but I do not
7091 know why it does this.
7093 FIXME:
7094 There is one other problem that ought to be addressed here, but
7095 which currently is not: Taking the address of a label (rather
7096 than a function) and then later jumping to that address. Such
7097 addresses also ought to have their bottom bit set (assuming that
7098 they reside in Thumb code), but at the moment they will not. */
7100 boolean
7101 arm_fix_adjustable (fixP)
7102 fixS * fixP;
7104 if (fixP->fx_addsy == NULL)
7105 return 1;
7107 /* Prevent all adjustments to global symbols. */
7108 if (S_IS_EXTERN (fixP->fx_addsy))
7109 return 0;
7111 if (S_IS_WEAK (fixP->fx_addsy))
7112 return 0;
7114 if (THUMB_IS_FUNC (fixP->fx_addsy)
7115 && fixP->fx_subsy == NULL)
7116 return 0;
7118 /* We need the symbol name for the VTABLE entries */
7119 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7120 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
7121 return 0;
7123 return 1;
7126 const char *
7127 elf32_arm_target_format ()
7129 if (target_big_endian)
7130 if (target_oabi)
7131 return "elf32-bigarm-oabi";
7132 else
7133 return "elf32-bigarm";
7134 else
7135 if (target_oabi)
7136 return "elf32-littlearm-oabi";
7137 else
7138 return "elf32-littlearm";
7141 void
7142 armelf_frob_symbol (symp, puntp)
7143 symbolS * symp;
7144 int * puntp;
7146 elf_frob_symbol (symp, puntp);
7150 arm_force_relocation (fixp)
7151 struct fix * fixp;
7153 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7154 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
7155 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
7156 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
7157 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
7158 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
7159 return 1;
7161 return 0;
7164 static bfd_reloc_code_real_type
7165 arm_parse_reloc ()
7167 char id[16];
7168 char * ip;
7169 unsigned int i;
7170 static struct
7172 char * str;
7173 int len;
7174 bfd_reloc_code_real_type reloc;
7176 reloc_map[] =
7178 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7179 MAP ("(got)", BFD_RELOC_ARM_GOT32),
7180 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
7181 /* ScottB: Jan 30, 1998 */
7182 /* Added support for parsing "var(PLT)" branch instructions */
7183 /* generated by GCC for PLT relocs */
7184 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
7185 { NULL, 0, BFD_RELOC_UNUSED }
7186 #undef MAP
7189 for (i = 0, ip = input_line_pointer;
7190 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
7191 i++, ip++)
7192 id[i] = tolower (*ip);
7194 for (i = 0; reloc_map[i].str; i++)
7195 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
7196 break;
7198 input_line_pointer += reloc_map[i].len;
7200 return reloc_map[i].reloc;
7203 static void
7204 s_arm_elf_cons (nbytes)
7205 int nbytes;
7207 expressionS exp;
7209 #ifdef md_flush_pending_output
7210 md_flush_pending_output ();
7211 #endif
7213 if (is_it_end_of_statement ())
7215 demand_empty_rest_of_line ();
7216 return;
7219 #ifdef md_cons_align
7220 md_cons_align (nbytes);
7221 #endif
7225 bfd_reloc_code_real_type reloc;
7227 expression (& exp);
7229 if (exp.X_op == O_symbol
7230 && * input_line_pointer == '('
7231 && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
7233 reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
7234 int size = bfd_get_reloc_size (howto);
7236 if (size > nbytes)
7237 as_bad ("%s relocations do not fit in %d bytes",
7238 howto->name, nbytes);
7239 else
7241 register char * p = frag_more ((int) nbytes);
7242 int offset = nbytes - size;
7244 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
7245 & exp, 0, reloc);
7248 else
7249 emit_expr (& exp, (unsigned int) nbytes);
7251 while (*input_line_pointer++ == ',');
7253 input_line_pointer--; /* Put terminator back into stream. */
7254 demand_empty_rest_of_line ();
7257 #endif /* OBJ_ELF */