* config/tc-arm.c (reg_required_here): Improve comments.
[binutils.git] / gas / config / tc-arm.c
blobd842941aa4a921bccb9cc0c104febbe3844d187d
1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999 Free Software Foundation, Inc.
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
6 This file is part of GAS, the GNU Assembler.
8 GAS is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GAS is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GAS; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
21 02111-1307, USA. */
23 #include <ctype.h>
24 #include <string.h>
25 #define NO_RELOC 0
26 #include "as.h"
28 /* need TARGET_CPU */
29 #include "config.h"
30 #include "subsegs.h"
31 #include "obstack.h"
32 #include "symbols.h"
33 #include "listing.h"
35 #ifdef OBJ_ELF
36 #include "elf/arm.h"
37 #endif
39 /* Types of processor to assemble for. */
40 #define ARM_1 0x00000001
41 #define ARM_2 0x00000002
42 #define ARM_3 0x00000004
43 #define ARM_250 ARM_3
44 #define ARM_6 0x00000008
45 #define ARM_7 ARM_6 /* same core instruction set */
46 #define ARM_8 ARM_6 /* same core instruction set */
47 #define ARM_9 ARM_6 /* same core instruction set */
48 #define ARM_CPU_MASK 0x0000000f
50 /* The following bitmasks control CPU extensions (ARM7 onwards): */
51 #define ARM_LONGMUL 0x00000010 /* allow long multiplies */
52 #define ARM_HALFWORD 0x00000020 /* allow half word loads */
53 #define ARM_THUMB 0x00000040 /* allow BX instruction */
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 from exp in floating point nums */
125 CONST char EXP_CHARS[] = "eE";
127 /* Chars that mean this number is a floating point constant */
128 /* As in 0f12.456 */
129 /* or 0d1.2345e12 */
131 CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
133 /* Prefix characters that indicate the start of an immediate
134 value. */
135 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
137 #ifdef OBJ_ELF
138 symbolS * GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
139 #endif
141 CONST int md_reloc_size = 8; /* Size of relocation record */
143 static int thumb_mode = 0; /* non-zero if assembling thumb instructions */
145 typedef struct arm_fix
147 int thumb_mode;
148 } arm_fix_data;
150 struct arm_it
152 CONST char * error;
153 unsigned long instruction;
154 int suffix;
155 int size;
156 struct
158 bfd_reloc_code_real_type type;
159 expressionS exp;
160 int pc_rel;
161 } reloc;
164 struct arm_it inst;
166 struct asm_shift
168 CONST char * template;
169 unsigned long value;
172 static CONST struct asm_shift shift[] =
174 {"asl", 0},
175 {"lsl", 0},
176 {"lsr", 0x00000020},
177 {"asr", 0x00000040},
178 {"ror", 0x00000060},
179 {"rrx", 0x00000060},
180 {"ASL", 0},
181 {"LSL", 0},
182 {"LSR", 0x00000020},
183 {"ASR", 0x00000040},
184 {"ROR", 0x00000060},
185 {"RRX", 0x00000060}
188 #define NO_SHIFT_RESTRICT 1
189 #define SHIFT_RESTRICT 0
191 #define NUM_FLOAT_VALS 8
193 CONST char * fp_const[] =
195 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
198 /* Number of littlenums required to hold an extended precision number */
199 #define MAX_LITTLENUMS 6
201 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
203 #define FAIL (-1)
204 #define SUCCESS (0)
206 #define SUFF_S 1
207 #define SUFF_D 2
208 #define SUFF_E 3
209 #define SUFF_P 4
211 #define CP_T_X 0x00008000
212 #define CP_T_Y 0x00400000
213 #define CP_T_Pre 0x01000000
214 #define CP_T_UD 0x00800000
215 #define CP_T_WB 0x00200000
217 #define CONDS_BIT (0x00100000)
218 #define LOAD_BIT (0x00100000)
219 #define TRANS_BIT (0x00200000)
221 struct asm_cond
223 CONST char * template;
224 unsigned long value;
227 /* This is to save a hash look-up in the common case */
228 #define COND_ALWAYS 0xe0000000
230 static CONST struct asm_cond conds[] =
232 {"eq", 0x00000000},
233 {"ne", 0x10000000},
234 {"cs", 0x20000000}, {"hs", 0x20000000},
235 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
236 {"mi", 0x40000000},
237 {"pl", 0x50000000},
238 {"vs", 0x60000000},
239 {"vc", 0x70000000},
240 {"hi", 0x80000000},
241 {"ls", 0x90000000},
242 {"ge", 0xa0000000},
243 {"lt", 0xb0000000},
244 {"gt", 0xc0000000},
245 {"le", 0xd0000000},
246 {"al", 0xe0000000},
247 {"nv", 0xf0000000}
250 /* Warning: If the top bit of the set_bits is set, then the standard
251 instruction bitmask is ignored, and the new bitmask is taken from
252 the set_bits: */
253 struct asm_flg
255 CONST char * template; /* Basic flag string */
256 unsigned long set_bits; /* Bits to set */
259 static CONST struct asm_flg s_flag[] =
261 {"s", CONDS_BIT},
262 {NULL, 0}
265 static CONST struct asm_flg ldr_flags[] =
267 {"b", 0x00400000},
268 {"t", TRANS_BIT},
269 {"bt", 0x00400000 | TRANS_BIT},
270 {"h", 0x801000b0},
271 {"sh", 0x801000f0},
272 {"sb", 0x801000d0},
273 {NULL, 0}
276 static CONST struct asm_flg str_flags[] =
278 {"b", 0x00400000},
279 {"t", TRANS_BIT},
280 {"bt", 0x00400000 | TRANS_BIT},
281 {"h", 0x800000b0},
282 {NULL, 0}
285 static CONST struct asm_flg byte_flag[] =
287 {"b", 0x00400000},
288 {NULL, 0}
291 static CONST struct asm_flg cmp_flags[] =
293 {"s", CONDS_BIT},
294 {"p", 0x0010f000},
295 {NULL, 0}
298 static CONST struct asm_flg ldm_flags[] =
300 {"ed", 0x01800000},
301 {"fd", 0x00800000},
302 {"ea", 0x01000000},
303 {"fa", 0x08000000},
304 {"ib", 0x01800000},
305 {"ia", 0x00800000},
306 {"db", 0x01000000},
307 {"da", 0x08000000},
308 {NULL, 0}
311 static CONST struct asm_flg stm_flags[] =
313 {"ed", 0x08000000},
314 {"fd", 0x01000000},
315 {"ea", 0x00800000},
316 {"fa", 0x01800000},
317 {"ib", 0x01800000},
318 {"ia", 0x00800000},
319 {"db", 0x01000000},
320 {"da", 0x08000000},
321 {NULL, 0}
324 static CONST struct asm_flg lfm_flags[] =
326 {"fd", 0x00800000},
327 {"ea", 0x01000000},
328 {NULL, 0}
331 static CONST struct asm_flg sfm_flags[] =
333 {"fd", 0x01000000},
334 {"ea", 0x00800000},
335 {NULL, 0}
338 static CONST struct asm_flg round_flags[] =
340 {"p", 0x00000020},
341 {"m", 0x00000040},
342 {"z", 0x00000060},
343 {NULL, 0}
346 /* The implementation of the FIX instruction is broken on some assemblers,
347 in that it accepts a precision specifier as well as a rounding specifier,
348 despite the fact that this is meaningless. To be more compatible, we
349 accept it as well, though of course it does not set any bits. */
350 static CONST struct asm_flg fix_flags[] =
352 {"p", 0x00000020},
353 {"m", 0x00000040},
354 {"z", 0x00000060},
355 {"sp", 0x00000020},
356 {"sm", 0x00000040},
357 {"sz", 0x00000060},
358 {"dp", 0x00000020},
359 {"dm", 0x00000040},
360 {"dz", 0x00000060},
361 {"ep", 0x00000020},
362 {"em", 0x00000040},
363 {"ez", 0x00000060},
364 {NULL, 0}
367 static CONST struct asm_flg except_flag[] =
369 {"e", 0x00400000},
370 {NULL, 0}
373 static CONST struct asm_flg cplong_flag[] =
375 {"l", 0x00400000},
376 {NULL, 0}
379 struct asm_psr
381 CONST char * template;
382 unsigned long number;
385 #define PSR_FIELD_MASK 0x000f0000
387 #define PSR_FLAGS 0x00080000
388 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
389 #define PSR_ALL 0x00090000
391 #define CPSR_ALL 0
392 #define SPSR_ALL 1
393 #define CPSR_FLG 2
394 #define SPSR_FLG 3
395 #define CPSR_CTL 4
396 #define SPSR_CTL 5
398 static CONST struct asm_psr psrs[] =
400 /* Valid <psr>'s */
401 {"cpsr", CPSR_ALL},
402 {"cpsr_all", CPSR_ALL},
403 {"spsr", SPSR_ALL},
404 {"spsr_all", SPSR_ALL},
406 /* Valid <psrf>'s */
407 {"cpsr_flg", CPSR_FLG},
408 {"spsr_flg", SPSR_FLG},
410 /* Valid <psrc>'s */
411 {"cpsr_c", CPSR_CTL},
412 {"cpsr_ctl", CPSR_CTL},
413 {"spsr_c", SPSR_CTL},
414 {"spsr_ctl", SPSR_CTL}
417 /* Functions called by parser */
418 /* ARM instructions */
419 static void do_arit PARAMS ((char *, unsigned long));
420 static void do_cmp PARAMS ((char *, unsigned long));
421 static void do_mov PARAMS ((char *, unsigned long));
422 static void do_ldst PARAMS ((char *, unsigned long));
423 static void do_ldmstm PARAMS ((char *, unsigned long));
424 static void do_branch PARAMS ((char *, unsigned long));
425 static void do_swi PARAMS ((char *, unsigned long));
426 /* Pseudo Op codes */
427 static void do_adr PARAMS ((char *, unsigned long));
428 static void do_adrl PARAMS ((char *, unsigned long));
429 static void do_nop PARAMS ((char *, unsigned long));
430 /* ARM 2 */
431 static void do_mul PARAMS ((char *, unsigned long));
432 static void do_mla PARAMS ((char *, unsigned long));
433 /* ARM 3 */
434 static void do_swap PARAMS ((char *, unsigned long));
435 /* ARM 6 */
436 static void do_msr PARAMS ((char *, unsigned long));
437 static void do_mrs PARAMS ((char *, unsigned long));
438 /* ARM 7M */
439 static void do_mull PARAMS ((char *, unsigned long));
440 /* ARM THUMB */
441 static void do_bx PARAMS ((char *, unsigned long));
443 /* Coprocessor Instructions */
444 static void do_cdp PARAMS ((char *, unsigned long));
445 static void do_lstc PARAMS ((char *, unsigned long));
446 static void do_co_reg PARAMS ((char *, unsigned long));
447 static void do_fp_ctrl PARAMS ((char *, unsigned long));
448 static void do_fp_ldst PARAMS ((char *, unsigned long));
449 static void do_fp_ldmstm PARAMS ((char *, unsigned long));
450 static void do_fp_dyadic PARAMS ((char *, unsigned long));
451 static void do_fp_monadic PARAMS ((char *, unsigned long));
452 static void do_fp_cmp PARAMS ((char *, unsigned long));
453 static void do_fp_from_reg PARAMS ((char *, unsigned long));
454 static void do_fp_to_reg PARAMS ((char *, unsigned long));
456 static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *, int, int));
457 static int arm_reg_parse PARAMS ((char **));
458 static int arm_psr_parse PARAMS ((char **));
459 static void symbol_locate PARAMS ((symbolS *, CONST char *, segT, valueT, fragS *));
460 static int add_to_lit_pool PARAMS ((void));
461 static unsigned validate_immediate PARAMS ((unsigned));
462 static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *));
463 static int validate_offset_imm PARAMS ((unsigned int, int));
464 static void opcode_select PARAMS ((int));
465 static void end_of_line PARAMS ((char *));
466 static int reg_required_here PARAMS ((char **, int));
467 static int psr_required_here PARAMS ((char **, int, int));
468 static int co_proc_number PARAMS ((char **));
469 static int cp_opc_expr PARAMS ((char **, int, int));
470 static int cp_reg_required_here PARAMS ((char **, int));
471 static int fp_reg_required_here PARAMS ((char **, int));
472 static int cp_address_offset PARAMS ((char **));
473 static int cp_address_required_here PARAMS ((char **));
474 static int my_get_float_expression PARAMS ((char **));
475 static int skip_past_comma PARAMS ((char **));
476 static int walk_no_bignums PARAMS ((symbolS *));
477 static int negate_data_op PARAMS ((unsigned long *, unsigned long));
478 static int data_op2 PARAMS ((char **));
479 static int fp_op2 PARAMS ((char **));
480 static long reg_list PARAMS ((char **));
481 static void thumb_load_store PARAMS ((char *, int, int));
482 static int decode_shift PARAMS ((char **, int));
483 static int ldst_extend PARAMS ((char **, int));
484 static void thumb_add_sub PARAMS ((char *, int));
485 static void insert_reg PARAMS ((int));
486 static void thumb_shift PARAMS ((char *, int));
487 static void thumb_mov_compare PARAMS ((char *, int));
488 static void set_constant_flonums PARAMS ((void));
489 static valueT md_chars_to_number PARAMS ((char *, int));
490 static void insert_reg_alias PARAMS ((char *, int));
491 static void output_inst PARAMS ((void));
492 #ifdef OBJ_ELF
493 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
494 #endif
496 /* ARM instructions take 4bytes in the object file, Thumb instructions
497 take 2: */
498 #define INSN_SIZE 4
500 /* LONGEST_INST is the longest basic instruction name without conditions or
501 * flags.
502 * ARM7M has 4 of length 5
505 #define LONGEST_INST 5
507 struct asm_opcode
509 CONST char * template; /* Basic string to match */
510 unsigned long value; /* Basic instruction code */
511 CONST char * comp_suffix; /* Compulsory suffix that must follow conds */
512 CONST struct asm_flg * flags; /* Bits to toggle if flag 'n' set */
513 unsigned long variants; /* Which CPU variants this exists for */
514 /* Function to call to parse args */
515 void (* parms) PARAMS ((char *, unsigned long));
518 static CONST struct asm_opcode insns[] =
520 /* ARM Instructions */
521 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
522 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
523 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
524 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
525 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
526 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
527 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
528 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
529 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
530 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
531 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
532 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
533 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
534 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
535 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
536 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
537 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
538 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
539 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
540 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
541 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
542 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
543 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
545 /* Pseudo ops */
546 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
547 {"adrl", 0x028f0000, NULL, NULL, ARM_ANY, do_adrl},
548 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
550 /* ARM 2 multiplies */
551 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
552 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
554 /* ARM 3 - swp instructions */
555 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
557 /* ARM 6 Coprocessor instructions */
558 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
559 {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr},
560 /* ScottB: our code uses 0x0128f000 for msr.
561 NickC: but this is wrong because the bits 16 and 19 are handled
562 by the PSR_xxx defines above. */
564 /* ARM 7M long multiplies - need signed/unsigned flags! */
565 {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull},
566 {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull},
567 {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull},
568 {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull},
570 /* ARM THUMB interworking */
571 {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx},
573 /* Floating point instructions */
574 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
575 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
576 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
577 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
578 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
579 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
580 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
581 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
582 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
583 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
584 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
585 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
586 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
587 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
588 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
589 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
590 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
591 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
592 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
593 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
594 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
595 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
596 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
597 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
598 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
599 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
600 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
601 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
602 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
603 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
604 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
605 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
606 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
607 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
608 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
609 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
610 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
611 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
612 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
613 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
614 be an optional suffix, but part of the instruction. To be compatible,
615 we accept either. */
616 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
617 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
618 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
619 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
621 /* Generic copressor instructions */
622 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
623 {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc},
624 {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc},
625 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
626 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
629 /* defines for various bits that we will want to toggle */
631 #define INST_IMMEDIATE 0x02000000
632 #define OFFSET_REG 0x02000000
633 #define HWOFFSET_IMM 0x00400000
634 #define SHIFT_BY_REG 0x00000010
635 #define PRE_INDEX 0x01000000
636 #define INDEX_UP 0x00800000
637 #define WRITE_BACK 0x00200000
638 #define LDM_TYPE_2_OR_3 0x00400000
640 #define LITERAL_MASK 0xf000f000
641 #define COND_MASK 0xf0000000
642 #define OPCODE_MASK 0xfe1fffff
643 #define DATA_OP_SHIFT 21
645 /* Codes to distinguish the arithmetic instructions */
647 #define OPCODE_AND 0
648 #define OPCODE_EOR 1
649 #define OPCODE_SUB 2
650 #define OPCODE_RSB 3
651 #define OPCODE_ADD 4
652 #define OPCODE_ADC 5
653 #define OPCODE_SBC 6
654 #define OPCODE_RSC 7
655 #define OPCODE_TST 8
656 #define OPCODE_TEQ 9
657 #define OPCODE_CMP 10
658 #define OPCODE_CMN 11
659 #define OPCODE_ORR 12
660 #define OPCODE_MOV 13
661 #define OPCODE_BIC 14
662 #define OPCODE_MVN 15
664 static void do_t_nop PARAMS ((char *));
665 static void do_t_arit PARAMS ((char *));
666 static void do_t_add PARAMS ((char *));
667 static void do_t_asr PARAMS ((char *));
668 static void do_t_branch9 PARAMS ((char *));
669 static void do_t_branch12 PARAMS ((char *));
670 static void do_t_branch23 PARAMS ((char *));
671 static void do_t_bx PARAMS ((char *));
672 static void do_t_compare PARAMS ((char *));
673 static void do_t_ldmstm PARAMS ((char *));
674 static void do_t_ldr PARAMS ((char *));
675 static void do_t_ldrb PARAMS ((char *));
676 static void do_t_ldrh PARAMS ((char *));
677 static void do_t_lds PARAMS ((char *));
678 static void do_t_lsl PARAMS ((char *));
679 static void do_t_lsr PARAMS ((char *));
680 static void do_t_mov PARAMS ((char *));
681 static void do_t_push_pop PARAMS ((char *));
682 static void do_t_str PARAMS ((char *));
683 static void do_t_strb PARAMS ((char *));
684 static void do_t_strh PARAMS ((char *));
685 static void do_t_sub PARAMS ((char *));
686 static void do_t_swi PARAMS ((char *));
687 static void do_t_adr PARAMS ((char *));
689 #define T_OPCODE_MUL 0x4340
690 #define T_OPCODE_TST 0x4200
691 #define T_OPCODE_CMN 0x42c0
692 #define T_OPCODE_NEG 0x4240
693 #define T_OPCODE_MVN 0x43c0
695 #define T_OPCODE_ADD_R3 0x1800
696 #define T_OPCODE_SUB_R3 0x1a00
697 #define T_OPCODE_ADD_HI 0x4400
698 #define T_OPCODE_ADD_ST 0xb000
699 #define T_OPCODE_SUB_ST 0xb080
700 #define T_OPCODE_ADD_SP 0xa800
701 #define T_OPCODE_ADD_PC 0xa000
702 #define T_OPCODE_ADD_I8 0x3000
703 #define T_OPCODE_SUB_I8 0x3800
704 #define T_OPCODE_ADD_I3 0x1c00
705 #define T_OPCODE_SUB_I3 0x1e00
707 #define T_OPCODE_ASR_R 0x4100
708 #define T_OPCODE_LSL_R 0x4080
709 #define T_OPCODE_LSR_R 0x40c0
710 #define T_OPCODE_ASR_I 0x1000
711 #define T_OPCODE_LSL_I 0x0000
712 #define T_OPCODE_LSR_I 0x0800
714 #define T_OPCODE_MOV_I8 0x2000
715 #define T_OPCODE_CMP_I8 0x2800
716 #define T_OPCODE_CMP_LR 0x4280
717 #define T_OPCODE_MOV_HR 0x4600
718 #define T_OPCODE_CMP_HR 0x4500
720 #define T_OPCODE_LDR_PC 0x4800
721 #define T_OPCODE_LDR_SP 0x9800
722 #define T_OPCODE_STR_SP 0x9000
723 #define T_OPCODE_LDR_IW 0x6800
724 #define T_OPCODE_STR_IW 0x6000
725 #define T_OPCODE_LDR_IH 0x8800
726 #define T_OPCODE_STR_IH 0x8000
727 #define T_OPCODE_LDR_IB 0x7800
728 #define T_OPCODE_STR_IB 0x7000
729 #define T_OPCODE_LDR_RW 0x5800
730 #define T_OPCODE_STR_RW 0x5000
731 #define T_OPCODE_LDR_RH 0x5a00
732 #define T_OPCODE_STR_RH 0x5200
733 #define T_OPCODE_LDR_RB 0x5c00
734 #define T_OPCODE_STR_RB 0x5400
736 #define T_OPCODE_PUSH 0xb400
737 #define T_OPCODE_POP 0xbc00
739 #define T_OPCODE_BRANCH 0xe7fe
741 static int thumb_reg PARAMS ((char ** str, int hi_lo));
743 #define THUMB_SIZE 2 /* Size of thumb instruction */
744 #define THUMB_REG_LO 0x1
745 #define THUMB_REG_HI 0x2
746 #define THUMB_REG_ANY 0x3
748 #define THUMB_H1 0x0080
749 #define THUMB_H2 0x0040
751 #define THUMB_ASR 0
752 #define THUMB_LSL 1
753 #define THUMB_LSR 2
755 #define THUMB_MOVE 0
756 #define THUMB_COMPARE 1
758 #define THUMB_LOAD 0
759 #define THUMB_STORE 1
761 #define THUMB_PP_PC_LR 0x0100
763 /* These three are used for immediate shifts, do not alter */
764 #define THUMB_WORD 2
765 #define THUMB_HALFWORD 1
766 #define THUMB_BYTE 0
768 struct thumb_opcode
770 CONST char * template; /* Basic string to match */
771 unsigned long value; /* Basic instruction code */
772 int size;
773 unsigned long variants; /* Which CPU variants this exists for */
774 void (* parms) PARAMS ((char *)); /* Function to call to parse args */
777 static CONST struct thumb_opcode tinsns[] =
779 {"adc", 0x4140, 2, ARM_THUMB, do_t_arit},
780 {"add", 0x0000, 2, ARM_THUMB, do_t_add},
781 {"and", 0x4000, 2, ARM_THUMB, do_t_arit},
782 {"asr", 0x0000, 2, ARM_THUMB, do_t_asr},
783 {"b", T_OPCODE_BRANCH, 2, ARM_THUMB, do_t_branch12},
784 {"beq", 0xd0fe, 2, ARM_THUMB, do_t_branch9},
785 {"bne", 0xd1fe, 2, ARM_THUMB, do_t_branch9},
786 {"bcs", 0xd2fe, 2, ARM_THUMB, do_t_branch9},
787 {"bhs", 0xd2fe, 2, ARM_THUMB, do_t_branch9},
788 {"bcc", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
789 {"bul", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
790 {"blo", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
791 {"bmi", 0xd4fe, 2, ARM_THUMB, do_t_branch9},
792 {"bpl", 0xd5fe, 2, ARM_THUMB, do_t_branch9},
793 {"bvs", 0xd6fe, 2, ARM_THUMB, do_t_branch9},
794 {"bvc", 0xd7fe, 2, ARM_THUMB, do_t_branch9},
795 {"bhi", 0xd8fe, 2, ARM_THUMB, do_t_branch9},
796 {"bls", 0xd9fe, 2, ARM_THUMB, do_t_branch9},
797 {"bge", 0xdafe, 2, ARM_THUMB, do_t_branch9},
798 {"blt", 0xdbfe, 2, ARM_THUMB, do_t_branch9},
799 {"bgt", 0xdcfe, 2, ARM_THUMB, do_t_branch9},
800 {"ble", 0xddfe, 2, ARM_THUMB, do_t_branch9},
801 {"bic", 0x4380, 2, ARM_THUMB, do_t_arit},
802 {"bl", 0xf7fffffe, 4, ARM_THUMB, do_t_branch23},
803 {"bx", 0x4700, 2, ARM_THUMB, do_t_bx},
804 {"cmn", T_OPCODE_CMN, 2, ARM_THUMB, do_t_arit},
805 {"cmp", 0x0000, 2, ARM_THUMB, do_t_compare},
806 {"eor", 0x4040, 2, ARM_THUMB, do_t_arit},
807 {"ldmia", 0xc800, 2, ARM_THUMB, do_t_ldmstm},
808 {"ldr", 0x0000, 2, ARM_THUMB, do_t_ldr},
809 {"ldrb", 0x0000, 2, ARM_THUMB, do_t_ldrb},
810 {"ldrh", 0x0000, 2, ARM_THUMB, do_t_ldrh},
811 {"ldrsb", 0x5600, 2, ARM_THUMB, do_t_lds},
812 {"ldrsh", 0x5e00, 2, ARM_THUMB, do_t_lds},
813 {"ldsb", 0x5600, 2, ARM_THUMB, do_t_lds},
814 {"ldsh", 0x5e00, 2, ARM_THUMB, do_t_lds},
815 {"lsl", 0x0000, 2, ARM_THUMB, do_t_lsl},
816 {"lsr", 0x0000, 2, ARM_THUMB, do_t_lsr},
817 {"mov", 0x0000, 2, ARM_THUMB, do_t_mov},
818 {"mul", T_OPCODE_MUL, 2, ARM_THUMB, do_t_arit},
819 {"mvn", T_OPCODE_MVN, 2, ARM_THUMB, do_t_arit},
820 {"neg", T_OPCODE_NEG, 2, ARM_THUMB, do_t_arit},
821 {"orr", 0x4300, 2, ARM_THUMB, do_t_arit},
822 {"pop", 0xbc00, 2, ARM_THUMB, do_t_push_pop},
823 {"push", 0xb400, 2, ARM_THUMB, do_t_push_pop},
824 {"ror", 0x41c0, 2, ARM_THUMB, do_t_arit},
825 {"sbc", 0x4180, 2, ARM_THUMB, do_t_arit},
826 {"stmia", 0xc000, 2, ARM_THUMB, do_t_ldmstm},
827 {"str", 0x0000, 2, ARM_THUMB, do_t_str},
828 {"strb", 0x0000, 2, ARM_THUMB, do_t_strb},
829 {"strh", 0x0000, 2, ARM_THUMB, do_t_strh},
830 {"swi", 0xdf00, 2, ARM_THUMB, do_t_swi},
831 {"sub", 0x0000, 2, ARM_THUMB, do_t_sub},
832 {"tst", T_OPCODE_TST, 2, ARM_THUMB, do_t_arit},
833 /* Pseudo ops: */
834 {"adr", 0x0000, 2, ARM_THUMB, do_t_adr},
835 {"nop", 0x46C0, 2, ARM_THUMB, do_t_nop}, /* mov r8,r8 */
838 struct reg_entry
840 CONST char * name;
841 int number;
844 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
845 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
846 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
848 #define REG_PC 15
849 #define REG_LR 14
850 #define REG_SP 13
852 /* These are the standard names; Users can add aliases with .req */
853 static CONST struct reg_entry reg_table[] =
855 /* Processor Register Numbers */
856 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
857 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
858 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
859 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
860 /* APCS conventions */
861 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
862 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
863 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
864 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
865 /* FP Registers */
866 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
867 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
868 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
869 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
870 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
871 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
872 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
873 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
874 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
875 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
876 {NULL, 0}
879 #define BAD_ARGS _("Bad arguments to instruction");
880 #define BAD_PC _("r15 not allowed here");
882 static struct hash_control * arm_ops_hsh = NULL;
883 static struct hash_control * arm_tops_hsh = NULL;
884 static struct hash_control * arm_cond_hsh = NULL;
885 static struct hash_control * arm_shift_hsh = NULL;
886 static struct hash_control * arm_reg_hsh = NULL;
887 static struct hash_control * arm_psr_hsh = NULL;
889 /* This table describes all the machine specific pseudo-ops the assembler
890 has to support. The fields are:
891 pseudo-op name without dot
892 function to call to execute this pseudo-op
893 Integer arg to pass to the function
896 static void s_req PARAMS ((int));
897 static void s_align PARAMS ((int));
898 static void s_bss PARAMS ((int));
899 static void s_even PARAMS ((int));
900 static void s_ltorg PARAMS ((int));
901 static void s_arm PARAMS ((int));
902 static void s_thumb PARAMS ((int));
903 static void s_code PARAMS ((int));
904 static void s_force_thumb PARAMS ((int));
905 static void s_thumb_func PARAMS ((int));
906 static void s_thumb_set PARAMS ((int));
907 static void arm_s_text PARAMS ((int));
908 static void arm_s_data PARAMS ((int));
909 #ifdef OBJ_ELF
910 static void arm_s_section PARAMS ((int));
911 static void s_arm_elf_cons PARAMS ((int));
912 #endif
914 static int my_get_expression PARAMS ((expressionS *, char **));
916 CONST pseudo_typeS md_pseudo_table[] =
918 { "req", s_req, 0 }, /* Never called becasue '.req' does not start line */
919 { "bss", s_bss, 0 },
920 { "align", s_align, 0 },
921 { "arm", s_arm, 0 },
922 { "thumb", s_thumb, 0 },
923 { "code", s_code, 0 },
924 { "force_thumb", s_force_thumb, 0 },
925 { "thumb_func", s_thumb_func, 0 },
926 { "thumb_set", s_thumb_set, 0 },
927 { "even", s_even, 0 },
928 { "ltorg", s_ltorg, 0 },
929 { "pool", s_ltorg, 0 },
930 /* Allow for the effect of section changes. */
931 { "text", arm_s_text, 0 },
932 { "data", arm_s_data, 0 },
933 #ifdef OBJ_ELF
934 { "section", arm_s_section, 0 },
935 { "section.s", arm_s_section, 0 },
936 { "sect", arm_s_section, 0 },
937 { "sect.s", arm_s_section, 0 },
938 { "word", s_arm_elf_cons, 4 },
939 { "long", s_arm_elf_cons, 4 },
940 #else
941 { "word", cons, 4},
942 #endif
943 { "extend", float_cons, 'x' },
944 { "ldouble", float_cons, 'x' },
945 { "packed", float_cons, 'p' },
946 { 0, 0, 0 }
949 /* Stuff needed to resolve the label ambiguity
952 label: <insn>
953 may differ from:
955 label:
956 <insn>
959 symbolS * last_label_seen;
960 static int label_is_thumb_function_name = false;
962 /* Literal stuff */
964 #define MAX_LITERAL_POOL_SIZE 1024
966 typedef struct literalS
968 struct expressionS exp;
969 struct arm_it * inst;
970 } literalT;
972 literalT literals[MAX_LITERAL_POOL_SIZE];
973 int next_literal_pool_place = 0; /* Next free entry in the pool */
974 int lit_pool_num = 1; /* Next literal pool number */
975 symbolS * current_poolP = NULL;
977 static int
978 add_to_lit_pool ()
980 int lit_count = 0;
982 if (current_poolP == NULL)
983 current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,
984 (valueT) 0, &zero_address_frag);
986 /* Check if this literal value is already in the pool: */
987 while (lit_count < next_literal_pool_place)
989 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
990 && inst.reloc.exp.X_op == O_constant
991 && literals[lit_count].exp.X_add_number == inst.reloc.exp.X_add_number
992 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
993 break;
994 lit_count++;
997 if (lit_count == next_literal_pool_place) /* new entry */
999 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
1001 inst.error = _("Literal Pool Overflow");
1002 return FAIL;
1005 literals[next_literal_pool_place].exp = inst.reloc.exp;
1006 lit_count = next_literal_pool_place++;
1009 inst.reloc.exp.X_op = O_symbol;
1010 inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
1011 inst.reloc.exp.X_add_symbol = current_poolP;
1013 return SUCCESS;
1016 /* Can't use symbol_new here, so have to create a symbol and then at
1017 a later date assign it a value. Thats what these functions do. */
1018 static void
1019 symbol_locate (symbolP, name, segment, valu, frag)
1020 symbolS * symbolP;
1021 CONST char * name; /* It is copied, the caller can modify */
1022 segT segment; /* Segment identifier (SEG_<something>) */
1023 valueT valu; /* Symbol value */
1024 fragS * frag; /* Associated fragment */
1026 unsigned int name_length;
1027 char * preserved_copy_of_name;
1029 name_length = strlen (name) + 1; /* +1 for \0 */
1030 obstack_grow (&notes, name, name_length);
1031 preserved_copy_of_name = obstack_finish (&notes);
1032 #ifdef STRIP_UNDERSCORE
1033 if (preserved_copy_of_name[0] == '_')
1034 preserved_copy_of_name++;
1035 #endif
1037 #ifdef tc_canonicalize_symbol_name
1038 preserved_copy_of_name =
1039 tc_canonicalize_symbol_name (preserved_copy_of_name);
1040 #endif
1042 S_SET_NAME (symbolP, preserved_copy_of_name);
1044 S_SET_SEGMENT (symbolP, segment);
1045 S_SET_VALUE (symbolP, valu);
1046 symbol_clear_list_pointers(symbolP);
1048 symbol_set_frag (symbolP, frag);
1050 /* Link to end of symbol chain. */
1052 extern int symbol_table_frozen;
1053 if (symbol_table_frozen)
1054 abort ();
1057 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1059 obj_symbol_new_hook (symbolP);
1061 #ifdef tc_symbol_new_hook
1062 tc_symbol_new_hook (symbolP);
1063 #endif
1065 #ifdef DEBUG_SYMS
1066 verify_symbol_chain (symbol_rootP, symbol_lastP);
1067 #endif /* DEBUG_SYMS */
1070 /* Check that an immediate is valid, and if so, convert it to the right format. */
1072 static unsigned int
1073 validate_immediate (val)
1074 unsigned int val;
1076 unsigned int a;
1077 unsigned int i;
1079 #define rotate_left(v, n) (v << n | v >> (32 - n))
1081 for (i = 0; i < 32; i += 2)
1082 if ((a = rotate_left (val, i)) <= 0xff)
1083 return a | (i << 7); /* 12-bit pack: [shift-cnt,const] */
1085 return FAIL;
1088 /* Check to see if an immediate can be computed as two seperate immediate
1089 values, added together. We already know that this value cannot be
1090 computed by just one ARM instruction. */
1092 static unsigned int
1093 validate_immediate_twopart (val, highpart)
1094 unsigned int val;
1095 unsigned int * highpart;
1097 unsigned int a;
1098 unsigned int i;
1100 for (i = 0; i < 32; i += 2)
1101 if (((a = rotate_left (val, i)) & 0xff) != 0)
1103 if (a & 0xff00)
1105 if (a & ~ 0xffff)
1106 continue;
1107 * highpart = (a >> 8) | ((i + 24) << 7);
1109 else if (a & 0xff0000)
1111 if (a & 0xff000000)
1112 continue;
1114 * highpart = (a >> 16) | ((i + 16) << 7);
1116 else
1118 assert (a & 0xff000000);
1120 * highpart = (a >> 24) | ((i + 8) << 7);
1123 return (a & 0xff) | (i << 7);
1126 return FAIL;
1129 static int
1130 validate_offset_imm (val, hwse)
1131 unsigned int val;
1132 int hwse;
1134 if ((hwse && val > 255) || val > 4095)
1135 return FAIL;
1136 return val;
1140 static void
1141 s_req (a)
1142 int a;
1144 as_bad (_("Invalid syntax for .req directive."));
1147 static void
1148 s_bss (ignore)
1149 int ignore;
1151 /* We don't support putting frags in the BSS segment, we fake it by
1152 marking in_bss, then looking at s_skip for clues?.. */
1153 subseg_set (bss_section, 0);
1154 demand_empty_rest_of_line ();
1157 static void
1158 s_even (ignore)
1159 int ignore;
1161 if (!need_pass_2) /* Never make frag if expect extra pass. */
1162 frag_align (1, 0, 0);
1164 record_alignment (now_seg, 1);
1166 demand_empty_rest_of_line ();
1169 static void
1170 s_ltorg (ignored)
1171 int ignored;
1173 int lit_count = 0;
1174 char sym_name[20];
1176 if (current_poolP == NULL)
1177 return;
1179 /* Align pool as you have word accesses */
1180 /* Only make a frag if we have to ... */
1181 if (!need_pass_2)
1182 frag_align (2, 0, 0);
1184 record_alignment (now_seg, 2);
1186 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1188 symbol_locate (current_poolP, sym_name, now_seg,
1189 (valueT) frag_now_fix (), frag_now);
1190 symbol_table_insert (current_poolP);
1192 ARM_SET_THUMB (current_poolP, thumb_mode);
1194 #if defined OBJ_COFF || defined OBJ_ELF
1195 ARM_SET_INTERWORK (current_poolP, support_interwork);
1196 #endif
1198 while (lit_count < next_literal_pool_place)
1199 /* First output the expression in the instruction to the pool */
1200 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1202 next_literal_pool_place = 0;
1203 current_poolP = NULL;
1206 static void
1207 s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */
1208 int unused;
1210 register int temp;
1211 register long temp_fill;
1212 long max_alignment = 15;
1214 temp = get_absolute_expression ();
1215 if (temp > max_alignment)
1216 as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
1217 else if (temp < 0)
1219 as_bad (_("Alignment negative. 0 assumed."));
1220 temp = 0;
1223 if (*input_line_pointer == ',')
1225 input_line_pointer++;
1226 temp_fill = get_absolute_expression ();
1228 else
1229 temp_fill = 0;
1231 if (!temp)
1232 temp = 2;
1234 /* Only make a frag if we HAVE to. . . */
1235 if (temp && !need_pass_2)
1236 frag_align (temp, (int) temp_fill, 0);
1237 demand_empty_rest_of_line ();
1239 record_alignment (now_seg, temp);
1242 static void
1243 s_force_thumb (ignore)
1244 int ignore;
1246 /* If we are not already in thumb mode go into it, EVEN if
1247 the target processor does not support thumb instructions.
1248 This is used by gcc/config/arm/lib1funcs.asm for example
1249 to compile interworking support functions even if the
1250 target processor should not support interworking. */
1252 if (! thumb_mode)
1254 thumb_mode = 1;
1256 record_alignment (now_seg, 1);
1259 demand_empty_rest_of_line ();
1262 static void
1263 s_thumb_func (ignore)
1264 int ignore;
1266 /* The following label is the name/address of the start of a Thumb function.
1267 We need to know this for the interworking support. */
1269 label_is_thumb_function_name = true;
1271 demand_empty_rest_of_line ();
1274 /* Perform a .set directive, but also mark the alias as
1275 being a thumb function. */
1277 static void
1278 s_thumb_set (equiv)
1279 int equiv;
1281 /* XXX the following is a duplicate of the code for s_set() in read.c
1282 We cannot just call that code as we need to get at the symbol that
1283 is created. */
1284 register char * name;
1285 register char delim;
1286 register char * end_name;
1287 register symbolS * symbolP;
1290 * Especial apologies for the random logic:
1291 * this just grew, and could be parsed much more simply!
1292 * Dean in haste.
1294 name = input_line_pointer;
1295 delim = get_symbol_end ();
1296 end_name = input_line_pointer;
1297 *end_name = delim;
1299 SKIP_WHITESPACE ();
1301 if (*input_line_pointer != ',')
1303 *end_name = 0;
1304 as_bad (_("Expected comma after name \"%s\""), name);
1305 *end_name = delim;
1306 ignore_rest_of_line ();
1307 return;
1310 input_line_pointer++;
1311 *end_name = 0;
1313 if (name[0] == '.' && name[1] == '\0')
1315 /* XXX - this should not happen to .thumb_set */
1316 abort ();
1319 if ((symbolP = symbol_find (name)) == NULL
1320 && (symbolP = md_undefined_symbol (name)) == NULL)
1322 #ifndef NO_LISTING
1323 /* When doing symbol listings, play games with dummy fragments living
1324 outside the normal fragment chain to record the file and line info
1325 for this symbol. */
1326 if (listing & LISTING_SYMBOLS)
1328 extern struct list_info_struct * listing_tail;
1329 fragS * dummy_frag = (fragS *) xmalloc (sizeof(fragS));
1330 memset (dummy_frag, 0, sizeof(fragS));
1331 dummy_frag->fr_type = rs_fill;
1332 dummy_frag->line = listing_tail;
1333 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1334 dummy_frag->fr_symbol = symbolP;
1336 else
1337 #endif
1338 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1340 #ifdef OBJ_COFF
1341 /* "set" symbols are local unless otherwise specified. */
1342 SF_SET_LOCAL (symbolP);
1343 #endif /* OBJ_COFF */
1344 } /* make a new symbol */
1346 symbol_table_insert (symbolP);
1348 * end_name = delim;
1350 if (equiv
1351 && S_IS_DEFINED (symbolP)
1352 && S_GET_SEGMENT (symbolP) != reg_section)
1353 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1355 pseudo_set (symbolP);
1357 demand_empty_rest_of_line ();
1359 /* XXX Now we come to the Thumb specific bit of code. */
1361 THUMB_SET_FUNC (symbolP, 1);
1362 ARM_SET_THUMB (symbolP, 1);
1363 #if defined OBJ_COFF || defined OBJ_ELF
1364 ARM_SET_INTERWORK (symbolP, support_interwork);
1365 #endif
1368 /* If we change section we must dump the literal pool first. */
1369 static void
1370 arm_s_text (ignore)
1371 int ignore;
1373 if (now_seg != text_section)
1374 s_ltorg (0);
1376 s_text (ignore);
1379 static void
1380 arm_s_data (ignore)
1381 int ignore;
1383 if (flag_readonly_data_in_text)
1385 if (now_seg != text_section)
1386 s_ltorg (0);
1388 else if (now_seg != data_section)
1389 s_ltorg (0);
1391 s_data (ignore);
1394 #ifdef OBJ_ELF
1395 static void
1396 arm_s_section (ignore)
1397 int ignore;
1399 s_ltorg (0);
1401 obj_elf_section (ignore);
1403 #endif
1405 static void
1406 opcode_select (width)
1407 int width;
1409 switch (width)
1411 case 16:
1412 if (! thumb_mode)
1414 if (! (cpu_variant & ARM_THUMB))
1415 as_bad (_("selected processor does not support THUMB opcodes"));
1416 thumb_mode = 1;
1417 /* No need to force the alignment, since we will have been
1418 coming from ARM mode, which is word-aligned. */
1419 record_alignment (now_seg, 1);
1421 break;
1423 case 32:
1424 if (thumb_mode)
1426 if ((cpu_variant & ARM_ANY) == ARM_THUMB)
1427 as_bad (_("selected processor does not support ARM opcodes"));
1428 thumb_mode = 0;
1429 if (!need_pass_2)
1430 frag_align (2, 0, 0);
1431 record_alignment (now_seg, 1);
1433 break;
1435 default:
1436 as_bad (_("invalid instruction size selected (%d)"), width);
1440 static void
1441 s_arm (ignore)
1442 int ignore;
1444 opcode_select (32);
1445 demand_empty_rest_of_line ();
1448 static void
1449 s_thumb (ignore)
1450 int ignore;
1452 opcode_select (16);
1453 demand_empty_rest_of_line ();
1456 static void
1457 s_code (unused)
1458 int unused;
1460 register int temp;
1462 temp = get_absolute_expression ();
1463 switch (temp)
1465 case 16:
1466 case 32:
1467 opcode_select (temp);
1468 break;
1470 default:
1471 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1475 static void
1476 end_of_line (str)
1477 char * str;
1479 skip_whitespace (str);
1481 if (* str != '\0')
1482 inst.error = _("Garbage following instruction");
1485 static int
1486 skip_past_comma (str)
1487 char ** str;
1489 char *p = *str, c;
1490 int comma = 0;
1492 while ((c = *p) == ' ' || c == ',')
1494 p++;
1495 if (c == ',' && comma++)
1496 return FAIL;
1499 if (c == '\0')
1500 return FAIL;
1502 *str = p;
1503 return comma ? SUCCESS : FAIL;
1506 /* A standard register must be given at this point.
1507 Shift is the place to put it in inst.instruction.
1508 Restores input start point on err.
1509 Returns the reg#, or FAIL. */
1511 static int
1512 reg_required_here (str, shift)
1513 char ** str;
1514 int shift;
1516 static char buff [128]; /* XXX */
1517 int reg;
1518 char * start = *str;
1520 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1522 if (shift >= 0)
1523 inst.instruction |= reg << shift;
1524 return reg;
1527 /* Restore the start point, we may have got a reg of the wrong class. */
1528 *str = start;
1530 /* In the few cases where we might be able to accept something else
1531 this error can be overridden. */
1532 sprintf (buff, _("Register expected, not '%.100s'"), start);
1533 inst.error = buff;
1535 return FAIL;
1538 static int
1539 psr_required_here (str, cpsr, spsr)
1540 char ** str;
1541 int cpsr;
1542 int spsr;
1544 int psr;
1545 char * start = *str;
1546 psr = arm_psr_parse (str);
1548 if (psr == cpsr || psr == spsr)
1550 if (psr == spsr)
1551 inst.instruction |= 1 << 22;
1553 return SUCCESS;
1556 /* In the few cases where we might be able to accept something else
1557 this error can be overridden. */
1558 inst.error = _("<psr(f)> expected");
1560 /* Restore the start point. */
1561 *str = start;
1562 return FAIL;
1565 static int
1566 co_proc_number (str)
1567 char ** str;
1569 int processor, pchar;
1571 skip_whitespace (* str);
1573 /* The data sheet seems to imply that just a number on its own is valid
1574 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1575 accept either. */
1576 if (**str == 'p' || **str == 'P')
1577 (*str)++;
1579 pchar = *(*str)++;
1580 if (pchar >= '0' && pchar <= '9')
1582 processor = pchar - '0';
1583 if (**str >= '0' && **str <= '9')
1585 processor = processor * 10 + *(*str)++ - '0';
1586 if (processor > 15)
1588 inst.error = _("Illegal co-processor number");
1589 return FAIL;
1593 else
1595 inst.error = _("Bad or missing co-processor number");
1596 return FAIL;
1599 inst.instruction |= processor << 8;
1600 return SUCCESS;
1603 static int
1604 cp_opc_expr (str, where, length)
1605 char ** str;
1606 int where;
1607 int length;
1609 expressionS expr;
1611 skip_whitespace (* str);
1613 memset (&expr, '\0', sizeof (expr));
1615 if (my_get_expression (&expr, str))
1616 return FAIL;
1617 if (expr.X_op != O_constant)
1619 inst.error = _("bad or missing expression");
1620 return FAIL;
1623 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1625 inst.error = _("immediate co-processor expression too large");
1626 return FAIL;
1629 inst.instruction |= expr.X_add_number << where;
1630 return SUCCESS;
1633 static int
1634 cp_reg_required_here (str, where)
1635 char ** str;
1636 int where;
1638 int reg;
1639 char * start = *str;
1641 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1643 reg &= 15;
1644 inst.instruction |= reg << where;
1645 return reg;
1648 /* In the few cases where we might be able to accept something else
1649 this error can be overridden. */
1650 inst.error = _("Co-processor register expected");
1652 /* Restore the start point. */
1653 *str = start;
1654 return FAIL;
1657 static int
1658 fp_reg_required_here (str, where)
1659 char ** str;
1660 int where;
1662 int reg;
1663 char * start = *str;
1665 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1667 reg &= 7;
1668 inst.instruction |= reg << where;
1669 return reg;
1672 /* In the few cases where we might be able to accept something else
1673 this error can be overridden. */
1674 inst.error = _("Floating point register expected");
1676 /* Restore the start point. */
1677 *str = start;
1678 return FAIL;
1681 static int
1682 cp_address_offset (str)
1683 char ** str;
1685 int offset;
1687 skip_whitespace (* str);
1689 if (! is_immediate_prefix (**str))
1691 inst.error = _("immediate expression expected");
1692 return FAIL;
1695 (*str)++;
1697 if (my_get_expression (& inst.reloc.exp, str))
1698 return FAIL;
1700 if (inst.reloc.exp.X_op == O_constant)
1702 offset = inst.reloc.exp.X_add_number;
1704 if (offset & 3)
1706 inst.error = _("co-processor address must be word aligned");
1707 return FAIL;
1710 if (offset > 1023 || offset < -1023)
1712 inst.error = _("offset too large");
1713 return FAIL;
1716 if (offset >= 0)
1717 inst.instruction |= INDEX_UP;
1718 else
1719 offset = -offset;
1721 inst.instruction |= offset >> 2;
1723 else
1724 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1726 return SUCCESS;
1729 static int
1730 cp_address_required_here (str)
1731 char ** str;
1733 char * p = * str;
1734 int pre_inc = 0;
1735 int write_back = 0;
1737 if (*p == '[')
1739 int reg;
1741 p++;
1742 skip_whitespace (p);
1744 if ((reg = reg_required_here (& p, 16)) == FAIL)
1745 return FAIL;
1747 skip_whitespace (p);
1749 if (*p == ']')
1751 p++;
1753 if (skip_past_comma (& p) == SUCCESS)
1755 /* [Rn], #expr */
1756 write_back = WRITE_BACK;
1758 if (reg == REG_PC)
1760 inst.error = _("pc may not be used in post-increment");
1761 return FAIL;
1764 if (cp_address_offset (& p) == FAIL)
1765 return FAIL;
1767 else
1768 pre_inc = PRE_INDEX | INDEX_UP;
1770 else
1772 /* '['Rn, #expr']'[!] */
1774 if (skip_past_comma (& p) == FAIL)
1776 inst.error = _("pre-indexed expression expected");
1777 return FAIL;
1780 pre_inc = PRE_INDEX;
1782 if (cp_address_offset (& p) == FAIL)
1783 return FAIL;
1785 skip_whitespace (p);
1787 if (*p++ != ']')
1789 inst.error = _("missing ]");
1790 return FAIL;
1793 skip_whitespace (p);
1795 if (*p == '!')
1797 if (reg == REG_PC)
1799 inst.error = _("pc may not be used with write-back");
1800 return FAIL;
1803 p++;
1804 write_back = WRITE_BACK;
1808 else
1810 if (my_get_expression (&inst.reloc.exp, &p))
1811 return FAIL;
1813 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1814 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
1815 inst.reloc.pc_rel = 1;
1816 inst.instruction |= (REG_PC << 16);
1817 pre_inc = PRE_INDEX;
1820 inst.instruction |= write_back | pre_inc;
1821 *str = p;
1822 return SUCCESS;
1825 static void
1826 do_nop (str, flags)
1827 char * str;
1828 unsigned long flags;
1830 /* Do nothing really. */
1831 inst.instruction |= flags; /* This is pointless. */
1832 end_of_line (str);
1833 return;
1836 static void
1837 do_mrs (str, flags)
1838 char *str;
1839 unsigned long flags;
1841 /* Only one syntax. */
1842 skip_whitespace (str);
1844 if (reg_required_here (&str, 12) == FAIL)
1846 inst.error = BAD_ARGS;
1847 return;
1850 if (skip_past_comma (&str) == FAIL
1851 || psr_required_here (& str, CPSR_ALL, SPSR_ALL) == FAIL)
1853 inst.error = _("<psr> expected");
1854 return;
1857 inst.instruction |= flags;
1858 end_of_line (str);
1859 return;
1862 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression". */
1863 static void
1864 do_msr (str, flags)
1865 char * str;
1866 unsigned long flags;
1868 int reg;
1870 skip_whitespace (str);
1872 if (psr_required_here (&str, CPSR_ALL, SPSR_ALL) == SUCCESS)
1874 inst.instruction |= PSR_ALL;
1876 /* Sytax should be "<psr>, Rm" */
1877 if (skip_past_comma (&str) == FAIL
1878 || (reg = reg_required_here (&str, 0)) == FAIL)
1880 inst.error = BAD_ARGS;
1881 return;
1884 else
1886 if (psr_required_here (& str, CPSR_FLG, SPSR_FLG) == SUCCESS)
1887 inst.instruction |= PSR_FLAGS;
1888 else if (psr_required_here (& str, CPSR_CTL, SPSR_CTL) == SUCCESS)
1889 inst.instruction |= PSR_CONTROL;
1890 else
1892 inst.error = BAD_ARGS;
1893 return;
1896 if (skip_past_comma (&str) == FAIL)
1898 inst.error = BAD_ARGS;
1899 return;
1902 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1904 if ((reg = reg_required_here (& str, 0)) != FAIL)
1906 /* Immediate expression. */
1907 else if (is_immediate_prefix (* str))
1909 str ++;
1910 inst.error = NULL;
1912 if (my_get_expression (& inst.reloc.exp, & str))
1914 inst.error = _("Register or shift expression expected");
1915 return;
1918 if (inst.reloc.exp.X_add_symbol)
1920 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
1921 inst.reloc.pc_rel = 0;
1923 else
1925 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
1926 if (value == FAIL)
1928 inst.error = _("Invalid constant");
1929 return;
1932 inst.instruction |= value;
1935 flags |= INST_IMMEDIATE;
1937 else
1939 inst.error = _("Error: unrecognised syntax for second argument to msr instruction");
1940 return;
1944 inst.error = NULL;
1945 inst.instruction |= flags;
1946 end_of_line (str);
1947 return;
1950 /* Long Multiply Parser
1951 UMULL RdLo, RdHi, Rm, Rs
1952 SMULL RdLo, RdHi, Rm, Rs
1953 UMLAL RdLo, RdHi, Rm, Rs
1954 SMLAL RdLo, RdHi, Rm, Rs
1956 static void
1957 do_mull (str, flags)
1958 char * str;
1959 unsigned long flags;
1961 int rdlo, rdhi, rm, rs;
1963 /* Only one format "rdlo, rdhi, rm, rs" */
1964 skip_whitespace (str);
1966 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
1968 inst.error = BAD_ARGS;
1969 return;
1972 if (skip_past_comma (&str) == FAIL
1973 || (rdhi = reg_required_here (&str, 16)) == FAIL)
1975 inst.error = BAD_ARGS;
1976 return;
1979 if (skip_past_comma (&str) == FAIL
1980 || (rm = reg_required_here (&str, 0)) == FAIL)
1982 inst.error = BAD_ARGS;
1983 return;
1986 /* rdhi, rdlo and rm must all be different */
1987 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
1988 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1990 if (skip_past_comma (&str) == FAIL
1991 || (rs = reg_required_here (&str, 8)) == FAIL)
1993 inst.error = BAD_ARGS;
1994 return;
1997 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
1999 inst.error = BAD_PC;
2000 return;
2003 inst.instruction |= flags;
2004 end_of_line (str);
2005 return;
2008 static void
2009 do_mul (str, flags)
2010 char * str;
2011 unsigned long flags;
2013 int rd, rm;
2015 /* Only one format "rd, rm, rs" */
2016 skip_whitespace (str);
2018 if ((rd = reg_required_here (&str, 16)) == FAIL)
2020 inst.error = BAD_ARGS;
2021 return;
2024 if (rd == REG_PC)
2026 inst.error = BAD_PC;
2027 return;
2030 if (skip_past_comma (&str) == FAIL
2031 || (rm = reg_required_here (&str, 0)) == FAIL)
2033 inst.error = BAD_ARGS;
2034 return;
2037 if (rm == REG_PC)
2039 inst.error = BAD_PC;
2040 return;
2043 if (rm == rd)
2044 as_tsktsk (_("rd and rm should be different in mul"));
2046 if (skip_past_comma (&str) == FAIL
2047 || (rm = reg_required_here (&str, 8)) == FAIL)
2049 inst.error = BAD_ARGS;
2050 return;
2053 if (rm == REG_PC)
2055 inst.error = BAD_PC;
2056 return;
2059 inst.instruction |= flags;
2060 end_of_line (str);
2061 return;
2064 static void
2065 do_mla (str, flags)
2066 char * str;
2067 unsigned long flags;
2069 int rd, rm;
2071 /* Only one format "rd, rm, rs, rn" */
2072 skip_whitespace (str);
2074 if ((rd = reg_required_here (&str, 16)) == FAIL)
2076 inst.error = BAD_ARGS;
2077 return;
2080 if (rd == REG_PC)
2082 inst.error = BAD_PC;
2083 return;
2086 if (skip_past_comma (&str) == FAIL
2087 || (rm = reg_required_here (&str, 0)) == FAIL)
2089 inst.error = BAD_ARGS;
2090 return;
2093 if (rm == REG_PC)
2095 inst.error = BAD_PC;
2096 return;
2099 if (rm == rd)
2100 as_tsktsk (_("rd and rm should be different in mla"));
2102 if (skip_past_comma (&str) == FAIL
2103 || (rd = reg_required_here (&str, 8)) == FAIL
2104 || skip_past_comma (&str) == FAIL
2105 || (rm = reg_required_here (&str, 12)) == FAIL)
2107 inst.error = BAD_ARGS;
2108 return;
2111 if (rd == REG_PC || rm == REG_PC)
2113 inst.error = BAD_PC;
2114 return;
2117 inst.instruction |= flags;
2118 end_of_line (str);
2119 return;
2122 /* Returns the index into fp_values of a floating point number, or -1 if
2123 not in the table. */
2124 static int
2125 my_get_float_expression (str)
2126 char ** str;
2128 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2129 char * save_in;
2130 expressionS exp;
2131 int i;
2132 int j;
2134 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
2135 /* Look for a raw floating point number */
2136 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
2137 && (is_end_of_line [(int)(*save_in)] || *save_in == '\0'))
2139 for (i = 0; i < NUM_FLOAT_VALS; i++)
2141 for (j = 0; j < MAX_LITTLENUMS; j++)
2143 if (words[j] != fp_values[i][j])
2144 break;
2147 if (j == MAX_LITTLENUMS)
2149 *str = save_in;
2150 return i;
2155 /* Try and parse a more complex expression, this will probably fail
2156 unless the code uses a floating point prefix (eg "0f") */
2157 save_in = input_line_pointer;
2158 input_line_pointer = *str;
2159 if (expression (&exp) == absolute_section
2160 && exp.X_op == O_big
2161 && exp.X_add_number < 0)
2163 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2164 Ditto for 15. */
2165 if (gen_to_words (words, 5, (long)15) == 0)
2167 for (i = 0; i < NUM_FLOAT_VALS; i++)
2169 for (j = 0; j < MAX_LITTLENUMS; j++)
2171 if (words[j] != fp_values[i][j])
2172 break;
2175 if (j == MAX_LITTLENUMS)
2177 *str = input_line_pointer;
2178 input_line_pointer = save_in;
2179 return i;
2185 *str = input_line_pointer;
2186 input_line_pointer = save_in;
2187 return -1;
2190 /* Return true if anything in the expression is a bignum */
2191 static int
2192 walk_no_bignums (sp)
2193 symbolS * sp;
2195 if (symbol_get_value_expression (sp)->X_op == O_big)
2196 return 1;
2198 if (symbol_get_value_expression (sp)->X_add_symbol)
2200 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
2201 || (symbol_get_value_expression (sp)->X_op_symbol
2202 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
2205 return 0;
2208 static int
2209 my_get_expression (ep, str)
2210 expressionS * ep;
2211 char ** str;
2213 char * save_in;
2214 segT seg;
2216 save_in = input_line_pointer;
2217 input_line_pointer = *str;
2218 seg = expression (ep);
2220 #ifdef OBJ_AOUT
2221 if (seg != absolute_section
2222 && seg != text_section
2223 && seg != data_section
2224 && seg != bss_section
2225 && seg != undefined_section)
2227 inst.error = _("bad_segment");
2228 *str = input_line_pointer;
2229 input_line_pointer = save_in;
2230 return 1;
2232 #endif
2234 /* Get rid of any bignums now, so that we don't generate an error for which
2235 we can't establish a line number later on. Big numbers are never valid
2236 in instructions, which is where this routine is always called. */
2237 if (ep->X_op == O_big
2238 || (ep->X_add_symbol
2239 && (walk_no_bignums (ep->X_add_symbol)
2240 || (ep->X_op_symbol
2241 && walk_no_bignums (ep->X_op_symbol)))))
2243 inst.error = _("Invalid constant");
2244 *str = input_line_pointer;
2245 input_line_pointer = save_in;
2246 return 1;
2249 *str = input_line_pointer;
2250 input_line_pointer = save_in;
2251 return 0;
2254 /* unrestrict should be one if <shift> <register> is permitted for this
2255 instruction */
2257 static int
2258 decode_shift (str, unrestrict)
2259 char ** str;
2260 int unrestrict;
2262 struct asm_shift * shft;
2263 char * p;
2264 char c;
2266 skip_whitespace (* str);
2268 for (p = *str; isalpha (*p); p++)
2271 if (p == *str)
2273 inst.error = _("Shift expression expected");
2274 return FAIL;
2277 c = *p;
2278 *p = '\0';
2279 shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
2280 *p = c;
2281 if (shft)
2283 if (!strncmp (*str, "rrx", 3)
2284 || !strncmp (*str, "RRX", 3))
2286 *str = p;
2287 inst.instruction |= shft->value;
2288 return SUCCESS;
2291 skip_whitespace (p);
2293 if (unrestrict && reg_required_here (&p, 8) != FAIL)
2295 inst.instruction |= shft->value | SHIFT_BY_REG;
2296 *str = p;
2297 return SUCCESS;
2299 else if (is_immediate_prefix (* p))
2301 inst.error = NULL;
2302 p++;
2303 if (my_get_expression (&inst.reloc.exp, &p))
2304 return FAIL;
2306 /* Validate some simple #expressions */
2307 if (inst.reloc.exp.X_op == O_constant)
2309 unsigned num = inst.reloc.exp.X_add_number;
2311 /* Reject operations greater than 32, or lsl #32 */
2312 if (num > 32 || (num == 32 && shft->value == 0))
2314 inst.error = _("Invalid immediate shift");
2315 return FAIL;
2318 /* Shifts of zero should be converted to lsl (which is zero)*/
2319 if (num == 0)
2321 *str = p;
2322 return SUCCESS;
2325 /* Shifts of 32 are encoded as 0, for those shifts that
2326 support it. */
2327 if (num == 32)
2328 num = 0;
2330 inst.instruction |= (num << 7) | shft->value;
2331 *str = p;
2332 return SUCCESS;
2335 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
2336 inst.reloc.pc_rel = 0;
2337 inst.instruction |= shft->value;
2338 *str = p;
2339 return SUCCESS;
2341 else
2343 inst.error = unrestrict ? _("shift requires register or #expression")
2344 : _("shift requires #expression");
2345 *str = p;
2346 return FAIL;
2350 inst.error = _("Shift expression expected");
2351 return FAIL;
2354 /* Do those data_ops which can take a negative immediate constant */
2355 /* by altering the instuction. A bit of a hack really */
2356 /* MOV <-> MVN
2357 AND <-> BIC
2358 ADC <-> SBC
2359 by inverting the second operand, and
2360 ADD <-> SUB
2361 CMP <-> CMN
2362 by negating the second operand.
2364 static int
2365 negate_data_op (instruction, value)
2366 unsigned long * instruction;
2367 unsigned long value;
2369 int op, new_inst;
2370 unsigned long negated, inverted;
2372 negated = validate_immediate (-value);
2373 inverted = validate_immediate (~value);
2375 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
2376 switch (op)
2378 /* First negates */
2379 case OPCODE_SUB: /* ADD <-> SUB */
2380 new_inst = OPCODE_ADD;
2381 value = negated;
2382 break;
2384 case OPCODE_ADD:
2385 new_inst = OPCODE_SUB;
2386 value = negated;
2387 break;
2389 case OPCODE_CMP: /* CMP <-> CMN */
2390 new_inst = OPCODE_CMN;
2391 value = negated;
2392 break;
2394 case OPCODE_CMN:
2395 new_inst = OPCODE_CMP;
2396 value = negated;
2397 break;
2399 /* Now Inverted ops */
2400 case OPCODE_MOV: /* MOV <-> MVN */
2401 new_inst = OPCODE_MVN;
2402 value = inverted;
2403 break;
2405 case OPCODE_MVN:
2406 new_inst = OPCODE_MOV;
2407 value = inverted;
2408 break;
2410 case OPCODE_AND: /* AND <-> BIC */
2411 new_inst = OPCODE_BIC;
2412 value = inverted;
2413 break;
2415 case OPCODE_BIC:
2416 new_inst = OPCODE_AND;
2417 value = inverted;
2418 break;
2420 case OPCODE_ADC: /* ADC <-> SBC */
2421 new_inst = OPCODE_SBC;
2422 value = inverted;
2423 break;
2425 case OPCODE_SBC:
2426 new_inst = OPCODE_ADC;
2427 value = inverted;
2428 break;
2430 /* We cannot do anything */
2431 default:
2432 return FAIL;
2435 if (value == FAIL)
2436 return FAIL;
2438 *instruction &= OPCODE_MASK;
2439 *instruction |= new_inst << DATA_OP_SHIFT;
2440 return value;
2443 static int
2444 data_op2 (str)
2445 char ** str;
2447 int value;
2448 expressionS expr;
2450 skip_whitespace (* str);
2452 if (reg_required_here (str, 0) != FAIL)
2454 if (skip_past_comma (str) == SUCCESS)
2455 /* Shift operation on register. */
2456 return decode_shift (str, NO_SHIFT_RESTRICT);
2458 return SUCCESS;
2460 else
2462 /* Immediate expression */
2463 if (is_immediate_prefix (**str))
2465 (*str)++;
2466 inst.error = NULL;
2468 if (my_get_expression (&inst.reloc.exp, str))
2469 return FAIL;
2471 if (inst.reloc.exp.X_add_symbol)
2473 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2474 inst.reloc.pc_rel = 0;
2476 else
2478 if (skip_past_comma (str) == SUCCESS)
2480 /* #x, y -- ie explicit rotation by Y */
2481 if (my_get_expression (&expr, str))
2482 return FAIL;
2484 if (expr.X_op != O_constant)
2486 inst.error = _("Constant expression expected");
2487 return FAIL;
2490 /* Rotate must be a multiple of 2 */
2491 if (((unsigned) expr.X_add_number) > 30
2492 || (expr.X_add_number & 1) != 0
2493 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
2495 inst.error = _("Invalid constant");
2496 return FAIL;
2498 inst.instruction |= INST_IMMEDIATE;
2499 inst.instruction |= inst.reloc.exp.X_add_number;
2500 inst.instruction |= expr.X_add_number << 7;
2501 return SUCCESS;
2504 /* Implicit rotation, select a suitable one */
2505 value = validate_immediate (inst.reloc.exp.X_add_number);
2507 if (value == FAIL)
2509 /* Can't be done, perhaps the code reads something like
2510 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2511 if ((value = negate_data_op (&inst.instruction,
2512 inst.reloc.exp.X_add_number))
2513 == FAIL)
2515 inst.error = _("Invalid constant");
2516 return FAIL;
2520 inst.instruction |= value;
2523 inst.instruction |= INST_IMMEDIATE;
2524 return SUCCESS;
2527 (*str)++;
2528 inst.error = _("Register or shift expression expected");
2529 return FAIL;
2533 static int
2534 fp_op2 (str)
2535 char ** str;
2537 skip_whitespace (* str);
2539 if (fp_reg_required_here (str, 0) != FAIL)
2540 return SUCCESS;
2541 else
2543 /* Immediate expression */
2544 if (*((*str)++) == '#')
2546 int i;
2548 inst.error = NULL;
2550 skip_whitespace (* str);
2552 /* First try and match exact strings, this is to guarantee that
2553 some formats will work even for cross assembly */
2555 for (i = 0; fp_const[i]; i++)
2557 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2559 char *start = *str;
2561 *str += strlen (fp_const[i]);
2562 if (is_end_of_line[(int)**str] || **str == '\0')
2564 inst.instruction |= i + 8;
2565 return SUCCESS;
2567 *str = start;
2571 /* Just because we didn't get a match doesn't mean that the
2572 constant isn't valid, just that it is in a format that we
2573 don't automatically recognize. Try parsing it with
2574 the standard expression routines. */
2575 if ((i = my_get_float_expression (str)) >= 0)
2577 inst.instruction |= i + 8;
2578 return SUCCESS;
2581 inst.error = _("Invalid floating point immediate expression");
2582 return FAIL;
2584 inst.error = _("Floating point register or immediate expression expected");
2585 return FAIL;
2589 static void
2590 do_arit (str, flags)
2591 char * str;
2592 unsigned long flags;
2594 skip_whitespace (str);
2596 if (reg_required_here (&str, 12) == FAIL
2597 || skip_past_comma (&str) == FAIL
2598 || reg_required_here (&str, 16) == FAIL
2599 || skip_past_comma (&str) == FAIL
2600 || data_op2 (&str) == FAIL)
2602 if (!inst.error)
2603 inst.error = BAD_ARGS;
2604 return;
2607 inst.instruction |= flags;
2608 end_of_line (str);
2609 return;
2612 static void
2613 do_adr (str, flags)
2614 char * str;
2615 unsigned long flags;
2617 /* This is a pseudo-op of the form "adr rd, label" to be converted
2618 into a relative address of the form "add rd, pc, #label-.-8" */
2620 skip_whitespace (str);
2622 if (reg_required_here (&str, 12) == FAIL
2623 || skip_past_comma (&str) == FAIL
2624 || my_get_expression (&inst.reloc.exp, &str))
2626 if (!inst.error)
2627 inst.error = BAD_ARGS;
2628 return;
2630 /* Frag hacking will turn this into a sub instruction if the offset turns
2631 out to be negative. */
2632 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2633 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2634 inst.reloc.pc_rel = 1;
2635 inst.instruction |= flags;
2636 end_of_line (str);
2637 return;
2640 static void
2641 do_adrl (str, flags)
2642 char * str;
2643 unsigned long flags;
2645 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2646 into a relative address of the form:
2647 add rd, pc, #low(label-.-8)"
2648 add rd, rd, #high(label-.-8)" */
2650 skip_whitespace (str);
2652 if (reg_required_here (& str, 12) == FAIL
2653 || skip_past_comma (& str) == FAIL
2654 || my_get_expression (& inst.reloc.exp, & str))
2656 if (!inst.error)
2657 inst.error = BAD_ARGS;
2658 return;
2661 end_of_line (str);
2663 /* Frag hacking will turn this into a sub instruction if the offset turns
2664 out to be negative. */
2665 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
2666 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2667 inst.reloc.pc_rel = 1;
2668 inst.instruction |= flags;
2669 inst.size = INSN_SIZE * 2;
2671 return;
2674 static void
2675 do_cmp (str, flags)
2676 char * str;
2677 unsigned long flags;
2679 skip_whitespace (str);
2681 if (reg_required_here (&str, 16) == FAIL)
2683 if (!inst.error)
2684 inst.error = BAD_ARGS;
2685 return;
2688 if (skip_past_comma (&str) == FAIL
2689 || data_op2 (&str) == FAIL)
2691 if (!inst.error)
2692 inst.error = BAD_ARGS;
2693 return;
2696 inst.instruction |= flags;
2697 if ((flags & 0x0000f000) == 0)
2698 inst.instruction |= CONDS_BIT;
2700 end_of_line (str);
2701 return;
2704 static void
2705 do_mov (str, flags)
2706 char * str;
2707 unsigned long flags;
2709 skip_whitespace (str);
2711 if (reg_required_here (&str, 12) == FAIL)
2713 if (!inst.error)
2714 inst.error = BAD_ARGS;
2715 return;
2718 if (skip_past_comma (&str) == FAIL
2719 || data_op2 (&str) == FAIL)
2721 if (!inst.error)
2722 inst.error = BAD_ARGS;
2723 return;
2726 inst.instruction |= flags;
2727 end_of_line (str);
2728 return;
2731 static int
2732 ldst_extend (str, hwse)
2733 char ** str;
2734 int hwse;
2736 int add = INDEX_UP;
2738 switch (**str)
2740 case '#':
2741 case '$':
2742 (*str)++;
2743 if (my_get_expression (& inst.reloc.exp, str))
2744 return FAIL;
2746 if (inst.reloc.exp.X_op == O_constant)
2748 int value = inst.reloc.exp.X_add_number;
2750 if ((hwse && (value < -255 || value > 255))
2751 || (value < -4095 || value > 4095))
2753 inst.error = _("address offset too large");
2754 return FAIL;
2757 if (value < 0)
2759 value = -value;
2760 add = 0;
2763 /* Halfword and signextension instructions have the
2764 immediate value split across bits 11..8 and bits 3..0 */
2765 if (hwse)
2766 inst.instruction |= add | HWOFFSET_IMM | ((value >> 4) << 8) | (value & 0xF);
2767 else
2768 inst.instruction |= add | value;
2770 else
2772 if (hwse)
2774 inst.instruction |= HWOFFSET_IMM;
2775 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2777 else
2778 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2779 inst.reloc.pc_rel = 0;
2781 return SUCCESS;
2783 case '-':
2784 add = 0; /* and fall through */
2785 case '+':
2786 (*str)++; /* and fall through */
2787 default:
2788 if (reg_required_here (str, 0) == FAIL)
2789 return FAIL;
2791 if (hwse)
2792 inst.instruction |= add;
2793 else
2795 inst.instruction |= add | OFFSET_REG;
2796 if (skip_past_comma (str) == SUCCESS)
2797 return decode_shift (str, SHIFT_RESTRICT);
2800 return SUCCESS;
2804 static void
2805 do_ldst (str, flags)
2806 char * str;
2807 unsigned long flags;
2809 int halfword = 0;
2810 int pre_inc = 0;
2811 int conflict_reg;
2812 int value;
2814 /* This is not ideal, but it is the simplest way of dealing with the
2815 ARM7T halfword instructions (since they use a different
2816 encoding, but the same mnemonic): */
2817 halfword = (flags & 0x80000000) != 0;
2818 if (halfword)
2820 /* This is actually a load/store of a halfword, or a
2821 signed-extension load */
2822 if ((cpu_variant & ARM_HALFWORD) == 0)
2824 inst.error
2825 = _("Processor does not support halfwords or signed bytes");
2826 return;
2829 inst.instruction = (inst.instruction & COND_MASK)
2830 | (flags & ~COND_MASK);
2832 flags = 0;
2835 skip_whitespace (str);
2837 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
2839 if (!inst.error)
2840 inst.error = BAD_ARGS;
2841 return;
2844 if (skip_past_comma (& str) == FAIL)
2846 inst.error = _("Address expected");
2847 return;
2850 if (*str == '[')
2852 int reg;
2854 str++;
2856 skip_whitespace (str);
2858 if ((reg = reg_required_here (&str, 16)) == FAIL)
2859 return;
2861 /* Conflicts can occur on stores as well as loads. */
2862 conflict_reg = (conflict_reg == reg);
2864 skip_whitespace (str);
2866 if (*str == ']')
2868 str ++;
2870 if (skip_past_comma (&str) == SUCCESS)
2872 /* [Rn],... (post inc) */
2873 if (ldst_extend (&str, halfword) == FAIL)
2874 return;
2875 if (conflict_reg)
2876 as_warn (_("%s register same as write-back base"),
2877 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2879 else
2881 /* [Rn] */
2882 if (halfword)
2883 inst.instruction |= HWOFFSET_IMM;
2885 skip_whitespace (str);
2887 if (*str == '!')
2889 if (conflict_reg)
2890 as_warn (_("%s register same as write-back base"),
2891 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2892 str++;
2893 inst.instruction |= WRITE_BACK;
2896 flags |= INDEX_UP;
2897 if (! (flags & TRANS_BIT))
2898 pre_inc = 1;
2901 else
2903 /* [Rn,...] */
2904 if (skip_past_comma (&str) == FAIL)
2906 inst.error = _("pre-indexed expression expected");
2907 return;
2910 pre_inc = 1;
2911 if (ldst_extend (&str, halfword) == FAIL)
2912 return;
2914 skip_whitespace (str);
2916 if (*str++ != ']')
2918 inst.error = _("missing ]");
2919 return;
2922 skip_whitespace (str);
2924 if (*str == '!')
2926 if (conflict_reg)
2927 as_warn (_("%s register same as write-back base"),
2928 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2929 str++;
2930 inst.instruction |= WRITE_BACK;
2934 else if (*str == '=')
2936 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2937 str++;
2939 skip_whitespace (str);
2941 if (my_get_expression (&inst.reloc.exp, &str))
2942 return;
2944 if (inst.reloc.exp.X_op != O_constant
2945 && inst.reloc.exp.X_op != O_symbol)
2947 inst.error = _("Constant expression expected");
2948 return;
2951 if (inst.reloc.exp.X_op == O_constant
2952 && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
2954 /* This can be done with a mov instruction */
2955 inst.instruction &= LITERAL_MASK;
2956 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
2957 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
2958 end_of_line(str);
2959 return;
2961 else
2963 /* Insert into literal pool */
2964 if (add_to_lit_pool () == FAIL)
2966 if (!inst.error)
2967 inst.error = _("literal pool insertion failed");
2968 return;
2971 /* Change the instruction exp to point to the pool */
2972 if (halfword)
2974 inst.instruction |= HWOFFSET_IMM;
2975 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
2977 else
2978 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
2979 inst.reloc.pc_rel = 1;
2980 inst.instruction |= (REG_PC << 16);
2981 pre_inc = 1;
2984 else
2986 if (my_get_expression (&inst.reloc.exp, &str))
2987 return;
2989 if (halfword)
2991 inst.instruction |= HWOFFSET_IMM;
2992 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2994 else
2995 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2996 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
2997 inst.reloc.pc_rel = 1;
2998 inst.instruction |= (REG_PC << 16);
2999 pre_inc = 1;
3002 if (pre_inc && (flags & TRANS_BIT))
3003 inst.error = _("Pre-increment instruction with translate");
3005 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
3006 end_of_line (str);
3007 return;
3010 static long
3011 reg_list (strp)
3012 char ** strp;
3014 char * str = *strp;
3015 long range = 0;
3016 int another_range;
3018 /* We come back here if we get ranges concatenated by '+' or '|' */
3021 another_range = 0;
3023 if (*str == '{')
3025 int in_range = 0;
3026 int cur_reg = -1;
3028 str++;
3031 int reg;
3033 skip_whitespace (str);
3035 if ((reg = reg_required_here (& str, -1)) == FAIL)
3036 return FAIL;
3038 if (in_range)
3040 int i;
3042 if (reg <= cur_reg)
3044 inst.error = _("Bad range in register list");
3045 return FAIL;
3048 for (i = cur_reg + 1; i < reg; i++)
3050 if (range & (1 << i))
3051 as_tsktsk
3052 (_("Warning: Duplicated register (r%d) in register list"),
3054 else
3055 range |= 1 << i;
3057 in_range = 0;
3060 if (range & (1 << reg))
3061 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3062 reg);
3063 else if (reg <= cur_reg)
3064 as_tsktsk (_("Warning: Register range not in ascending order"));
3066 range |= 1 << reg;
3067 cur_reg = reg;
3068 } while (skip_past_comma (&str) != FAIL
3069 || (in_range = 1, *str++ == '-'));
3070 str--;
3071 skip_whitespace (str);
3073 if (*str++ != '}')
3075 inst.error = _("Missing `}'");
3076 return FAIL;
3079 else
3081 expressionS expr;
3083 if (my_get_expression (&expr, &str))
3084 return FAIL;
3086 if (expr.X_op == O_constant)
3088 if (expr.X_add_number
3089 != (expr.X_add_number & 0x0000ffff))
3091 inst.error = _("invalid register mask");
3092 return FAIL;
3095 if ((range & expr.X_add_number) != 0)
3097 int regno = range & expr.X_add_number;
3099 regno &= -regno;
3100 regno = (1 << regno) - 1;
3101 as_tsktsk
3102 (_("Warning: Duplicated register (r%d) in register list"),
3103 regno);
3106 range |= expr.X_add_number;
3108 else
3110 if (inst.reloc.type != 0)
3112 inst.error = _("expression too complex");
3113 return FAIL;
3116 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
3117 inst.reloc.type = BFD_RELOC_ARM_MULTI;
3118 inst.reloc.pc_rel = 0;
3122 skip_whitespace (str);
3124 if (*str == '|' || *str == '+')
3126 str++;
3127 another_range = 1;
3129 } while (another_range);
3131 *strp = str;
3132 return range;
3135 static void
3136 do_ldmstm (str, flags)
3137 char * str;
3138 unsigned long flags;
3140 int base_reg;
3141 long range;
3143 skip_whitespace (str);
3145 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
3146 return;
3148 if (base_reg == REG_PC)
3150 inst.error = _("r15 not allowed as base register");
3151 return;
3154 skip_whitespace (str);
3156 if (*str == '!')
3158 flags |= WRITE_BACK;
3159 str++;
3162 if (skip_past_comma (&str) == FAIL
3163 || (range = reg_list (&str)) == FAIL)
3165 if (! inst.error)
3166 inst.error = BAD_ARGS;
3167 return;
3170 if (*str == '^')
3172 str++;
3173 flags |= LDM_TYPE_2_OR_3;
3176 inst.instruction |= flags | range;
3177 end_of_line (str);
3178 return;
3181 static void
3182 do_swi (str, flags)
3183 char * str;
3184 unsigned long flags;
3186 skip_whitespace (str);
3188 /* Allow optional leading '#'. */
3189 if (is_immediate_prefix (*str))
3190 str++;
3192 if (my_get_expression (& inst.reloc.exp, & str))
3193 return;
3195 inst.reloc.type = BFD_RELOC_ARM_SWI;
3196 inst.reloc.pc_rel = 0;
3197 inst.instruction |= flags;
3199 end_of_line (str);
3201 return;
3204 static void
3205 do_swap (str, flags)
3206 char * str;
3207 unsigned long flags;
3209 int reg;
3211 skip_whitespace (str);
3213 if ((reg = reg_required_here (&str, 12)) == FAIL)
3214 return;
3216 if (reg == REG_PC)
3218 inst.error = _("r15 not allowed in swap");
3219 return;
3222 if (skip_past_comma (&str) == FAIL
3223 || (reg = reg_required_here (&str, 0)) == FAIL)
3225 if (!inst.error)
3226 inst.error = BAD_ARGS;
3227 return;
3230 if (reg == REG_PC)
3232 inst.error = _("r15 not allowed in swap");
3233 return;
3236 if (skip_past_comma (&str) == FAIL
3237 || *str++ != '[')
3239 inst.error = BAD_ARGS;
3240 return;
3243 skip_whitespace (str);
3245 if ((reg = reg_required_here (&str, 16)) == FAIL)
3246 return;
3248 if (reg == REG_PC)
3250 inst.error = BAD_PC;
3251 return;
3254 skip_whitespace (str);
3256 if (*str++ != ']')
3258 inst.error = _("missing ]");
3259 return;
3262 inst.instruction |= flags;
3263 end_of_line (str);
3264 return;
3267 static void
3268 do_branch (str, flags)
3269 char * str;
3270 unsigned long flags;
3272 if (my_get_expression (&inst.reloc.exp, &str))
3273 return;
3275 #ifdef OBJ_ELF
3277 char * save_in;
3279 /* ScottB: February 5, 1998 */
3280 /* Check to see of PLT32 reloc required for the instruction. */
3282 /* arm_parse_reloc() works on input_line_pointer.
3283 We actually want to parse the operands to the branch instruction
3284 passed in 'str'. Save the input pointer and restore it later. */
3285 save_in = input_line_pointer;
3286 input_line_pointer = str;
3287 if (inst.reloc.exp.X_op == O_symbol
3288 && *str == '('
3289 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3291 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3292 inst.reloc.pc_rel = 0;
3293 /* Modify str to point to after parsed operands, otherwise
3294 end_of_line() will complain about the (PLT) left in str. */
3295 str = input_line_pointer;
3297 else
3299 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3300 inst.reloc.pc_rel = 1;
3302 input_line_pointer = save_in;
3304 #else
3305 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3306 inst.reloc.pc_rel = 1;
3307 #endif /* OBJ_ELF */
3309 end_of_line (str);
3310 return;
3313 static void
3314 do_bx (str, flags)
3315 char * str;
3316 unsigned long flags;
3318 int reg;
3320 skip_whitespace (str);
3322 if ((reg = reg_required_here (&str, 0)) == FAIL)
3323 return;
3325 if (reg == REG_PC)
3326 as_tsktsk (_("Use of r15 in bx has undefined behaviour"));
3328 end_of_line (str);
3329 return;
3332 static void
3333 do_cdp (str, flags)
3334 char * str;
3335 unsigned long flags;
3337 /* Co-processor data operation.
3338 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3339 skip_whitespace (str);
3341 if (co_proc_number (&str) == FAIL)
3343 if (!inst.error)
3344 inst.error = BAD_ARGS;
3345 return;
3348 if (skip_past_comma (&str) == FAIL
3349 || cp_opc_expr (&str, 20,4) == FAIL)
3351 if (!inst.error)
3352 inst.error = BAD_ARGS;
3353 return;
3356 if (skip_past_comma (&str) == FAIL
3357 || cp_reg_required_here (&str, 12) == FAIL)
3359 if (!inst.error)
3360 inst.error = BAD_ARGS;
3361 return;
3364 if (skip_past_comma (&str) == FAIL
3365 || cp_reg_required_here (&str, 16) == FAIL)
3367 if (!inst.error)
3368 inst.error = BAD_ARGS;
3369 return;
3372 if (skip_past_comma (&str) == FAIL
3373 || cp_reg_required_here (&str, 0) == FAIL)
3375 if (!inst.error)
3376 inst.error = BAD_ARGS;
3377 return;
3380 if (skip_past_comma (&str) == SUCCESS)
3382 if (cp_opc_expr (&str, 5, 3) == FAIL)
3384 if (!inst.error)
3385 inst.error = BAD_ARGS;
3386 return;
3390 end_of_line (str);
3391 return;
3394 static void
3395 do_lstc (str, flags)
3396 char * str;
3397 unsigned long flags;
3399 /* Co-processor register load/store.
3400 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3402 skip_whitespace (str);
3404 if (co_proc_number (&str) == FAIL)
3406 if (!inst.error)
3407 inst.error = BAD_ARGS;
3408 return;
3411 if (skip_past_comma (&str) == FAIL
3412 || cp_reg_required_here (&str, 12) == FAIL)
3414 if (!inst.error)
3415 inst.error = BAD_ARGS;
3416 return;
3419 if (skip_past_comma (&str) == FAIL
3420 || cp_address_required_here (&str) == FAIL)
3422 if (! inst.error)
3423 inst.error = BAD_ARGS;
3424 return;
3427 inst.instruction |= flags;
3428 end_of_line (str);
3429 return;
3432 static void
3433 do_co_reg (str, flags)
3434 char * str;
3435 unsigned long flags;
3437 /* Co-processor register transfer.
3438 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3440 skip_whitespace (str);
3442 if (co_proc_number (&str) == FAIL)
3444 if (!inst.error)
3445 inst.error = BAD_ARGS;
3446 return;
3449 if (skip_past_comma (&str) == FAIL
3450 || cp_opc_expr (&str, 21, 3) == FAIL)
3452 if (!inst.error)
3453 inst.error = BAD_ARGS;
3454 return;
3457 if (skip_past_comma (&str) == FAIL
3458 || reg_required_here (&str, 12) == FAIL)
3460 if (!inst.error)
3461 inst.error = BAD_ARGS;
3462 return;
3465 if (skip_past_comma (&str) == FAIL
3466 || cp_reg_required_here (&str, 16) == FAIL)
3468 if (!inst.error)
3469 inst.error = BAD_ARGS;
3470 return;
3473 if (skip_past_comma (&str) == FAIL
3474 || cp_reg_required_here (&str, 0) == FAIL)
3476 if (!inst.error)
3477 inst.error = BAD_ARGS;
3478 return;
3481 if (skip_past_comma (&str) == SUCCESS)
3483 if (cp_opc_expr (&str, 5, 3) == FAIL)
3485 if (!inst.error)
3486 inst.error = BAD_ARGS;
3487 return;
3491 end_of_line (str);
3492 return;
3495 static void
3496 do_fp_ctrl (str, flags)
3497 char * str;
3498 unsigned long flags;
3500 /* FP control registers.
3501 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3503 skip_whitespace (str);
3505 if (reg_required_here (&str, 12) == FAIL)
3507 if (!inst.error)
3508 inst.error = BAD_ARGS;
3509 return;
3512 end_of_line (str);
3513 return;
3516 static void
3517 do_fp_ldst (str, flags)
3518 char * str;
3519 unsigned long flags;
3521 skip_whitespace (str);
3523 switch (inst.suffix)
3525 case SUFF_S:
3526 break;
3527 case SUFF_D:
3528 inst.instruction |= CP_T_X;
3529 break;
3530 case SUFF_E:
3531 inst.instruction |= CP_T_Y;
3532 break;
3533 case SUFF_P:
3534 inst.instruction |= CP_T_X | CP_T_Y;
3535 break;
3536 default:
3537 abort ();
3540 if (fp_reg_required_here (&str, 12) == FAIL)
3542 if (!inst.error)
3543 inst.error = BAD_ARGS;
3544 return;
3547 if (skip_past_comma (&str) == FAIL
3548 || cp_address_required_here (&str) == FAIL)
3550 if (!inst.error)
3551 inst.error = BAD_ARGS;
3552 return;
3555 end_of_line (str);
3558 static void
3559 do_fp_ldmstm (str, flags)
3560 char * str;
3561 unsigned long flags;
3563 int num_regs;
3565 skip_whitespace (str);
3567 if (fp_reg_required_here (&str, 12) == FAIL)
3569 if (! inst.error)
3570 inst.error = BAD_ARGS;
3571 return;
3574 /* Get Number of registers to transfer */
3575 if (skip_past_comma (&str) == FAIL
3576 || my_get_expression (&inst.reloc.exp, &str))
3578 if (! inst.error)
3579 inst.error = _("constant expression expected");
3580 return;
3583 if (inst.reloc.exp.X_op != O_constant)
3585 inst.error = _("Constant value required for number of registers");
3586 return;
3589 num_regs = inst.reloc.exp.X_add_number;
3591 if (num_regs < 1 || num_regs > 4)
3593 inst.error = _("number of registers must be in the range [1:4]");
3594 return;
3597 switch (num_regs)
3599 case 1:
3600 inst.instruction |= CP_T_X;
3601 break;
3602 case 2:
3603 inst.instruction |= CP_T_Y;
3604 break;
3605 case 3:
3606 inst.instruction |= CP_T_Y | CP_T_X;
3607 break;
3608 case 4:
3609 break;
3610 default:
3611 abort ();
3614 if (flags)
3616 int reg;
3617 int write_back;
3618 int offset;
3620 /* The instruction specified "ea" or "fd", so we can only accept
3621 [Rn]{!}. The instruction does not really support stacking or
3622 unstacking, so we have to emulate these by setting appropriate
3623 bits and offsets. */
3624 if (skip_past_comma (&str) == FAIL
3625 || *str != '[')
3627 if (! inst.error)
3628 inst.error = BAD_ARGS;
3629 return;
3632 str++;
3633 skip_whitespace (str);
3635 if ((reg = reg_required_here (&str, 16)) == FAIL)
3636 return;
3638 skip_whitespace (str);
3640 if (*str != ']')
3642 inst.error = BAD_ARGS;
3643 return;
3646 str++;
3647 if (*str == '!')
3649 write_back = 1;
3650 str++;
3651 if (reg == REG_PC)
3653 inst.error = _("R15 not allowed as base register with write-back");
3654 return;
3657 else
3658 write_back = 0;
3660 if (flags & CP_T_Pre)
3662 /* Pre-decrement */
3663 offset = 3 * num_regs;
3664 if (write_back)
3665 flags |= CP_T_WB;
3667 else
3669 /* Post-increment */
3670 if (write_back)
3672 flags |= CP_T_WB;
3673 offset = 3 * num_regs;
3675 else
3677 /* No write-back, so convert this into a standard pre-increment
3678 instruction -- aesthetically more pleasing. */
3679 flags = CP_T_Pre | CP_T_UD;
3680 offset = 0;
3684 inst.instruction |= flags | offset;
3686 else if (skip_past_comma (&str) == FAIL
3687 || cp_address_required_here (&str) == FAIL)
3689 if (! inst.error)
3690 inst.error = BAD_ARGS;
3691 return;
3694 end_of_line (str);
3697 static void
3698 do_fp_dyadic (str, flags)
3699 char * str;
3700 unsigned long flags;
3702 skip_whitespace (str);
3704 switch (inst.suffix)
3706 case SUFF_S:
3707 break;
3708 case SUFF_D:
3709 inst.instruction |= 0x00000080;
3710 break;
3711 case SUFF_E:
3712 inst.instruction |= 0x00080000;
3713 break;
3714 default:
3715 abort ();
3718 if (fp_reg_required_here (&str, 12) == FAIL)
3720 if (! inst.error)
3721 inst.error = BAD_ARGS;
3722 return;
3725 if (skip_past_comma (&str) == FAIL
3726 || fp_reg_required_here (&str, 16) == FAIL)
3728 if (! inst.error)
3729 inst.error = BAD_ARGS;
3730 return;
3733 if (skip_past_comma (&str) == FAIL
3734 || fp_op2 (&str) == FAIL)
3736 if (! inst.error)
3737 inst.error = BAD_ARGS;
3738 return;
3741 inst.instruction |= flags;
3742 end_of_line (str);
3743 return;
3746 static void
3747 do_fp_monadic (str, flags)
3748 char * str;
3749 unsigned long flags;
3751 skip_whitespace (str);
3753 switch (inst.suffix)
3755 case SUFF_S:
3756 break;
3757 case SUFF_D:
3758 inst.instruction |= 0x00000080;
3759 break;
3760 case SUFF_E:
3761 inst.instruction |= 0x00080000;
3762 break;
3763 default:
3764 abort ();
3767 if (fp_reg_required_here (&str, 12) == FAIL)
3769 if (! inst.error)
3770 inst.error = BAD_ARGS;
3771 return;
3774 if (skip_past_comma (&str) == FAIL
3775 || fp_op2 (&str) == FAIL)
3777 if (! inst.error)
3778 inst.error = BAD_ARGS;
3779 return;
3782 inst.instruction |= flags;
3783 end_of_line (str);
3784 return;
3787 static void
3788 do_fp_cmp (str, flags)
3789 char * str;
3790 unsigned long flags;
3792 skip_whitespace (str);
3794 if (fp_reg_required_here (&str, 16) == FAIL)
3796 if (! inst.error)
3797 inst.error = BAD_ARGS;
3798 return;
3801 if (skip_past_comma (&str) == FAIL
3802 || fp_op2 (&str) == FAIL)
3804 if (! inst.error)
3805 inst.error = BAD_ARGS;
3806 return;
3809 inst.instruction |= flags;
3810 end_of_line (str);
3811 return;
3814 static void
3815 do_fp_from_reg (str, flags)
3816 char * str;
3817 unsigned long flags;
3819 skip_whitespace (str);
3821 switch (inst.suffix)
3823 case SUFF_S:
3824 break;
3825 case SUFF_D:
3826 inst.instruction |= 0x00000080;
3827 break;
3828 case SUFF_E:
3829 inst.instruction |= 0x00080000;
3830 break;
3831 default:
3832 abort ();
3835 if (fp_reg_required_here (&str, 16) == FAIL)
3837 if (! inst.error)
3838 inst.error = BAD_ARGS;
3839 return;
3842 if (skip_past_comma (&str) == FAIL
3843 || reg_required_here (&str, 12) == FAIL)
3845 if (! inst.error)
3846 inst.error = BAD_ARGS;
3847 return;
3850 inst.instruction |= flags;
3851 end_of_line (str);
3852 return;
3855 static void
3856 do_fp_to_reg (str, flags)
3857 char * str;
3858 unsigned long flags;
3860 skip_whitespace (str);
3862 if (reg_required_here (&str, 12) == FAIL)
3863 return;
3865 if (skip_past_comma (&str) == FAIL
3866 || fp_reg_required_here (&str, 0) == FAIL)
3868 if (! inst.error)
3869 inst.error = BAD_ARGS;
3870 return;
3873 inst.instruction |= flags;
3874 end_of_line (str);
3875 return;
3878 /* Thumb specific routines */
3880 /* Parse and validate that a register is of the right form, this saves
3881 repeated checking of this information in many similar cases.
3882 Unlike the 32-bit case we do not insert the register into the opcode
3883 here, since the position is often unknown until the full instruction
3884 has been parsed. */
3885 static int
3886 thumb_reg (strp, hi_lo)
3887 char ** strp;
3888 int hi_lo;
3890 int reg;
3892 if ((reg = reg_required_here (strp, -1)) == FAIL)
3893 return FAIL;
3895 switch (hi_lo)
3897 case THUMB_REG_LO:
3898 if (reg > 7)
3900 inst.error = _("lo register required");
3901 return FAIL;
3903 break;
3905 case THUMB_REG_HI:
3906 if (reg < 8)
3908 inst.error = _("hi register required");
3909 return FAIL;
3911 break;
3913 default:
3914 break;
3917 return reg;
3920 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3921 was SUB. */
3922 static void
3923 thumb_add_sub (str, subtract)
3924 char * str;
3925 int subtract;
3927 int Rd, Rs, Rn = FAIL;
3929 skip_whitespace (str);
3931 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
3932 || skip_past_comma (&str) == FAIL)
3934 if (! inst.error)
3935 inst.error = BAD_ARGS;
3936 return;
3939 if (is_immediate_prefix (*str))
3941 Rs = Rd;
3942 str++;
3943 if (my_get_expression (&inst.reloc.exp, &str))
3944 return;
3946 else
3948 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3949 return;
3951 if (skip_past_comma (&str) == FAIL)
3953 /* Two operand format, shuffle the registers and pretend there
3954 are 3 */
3955 Rn = Rs;
3956 Rs = Rd;
3958 else if (is_immediate_prefix (*str))
3960 str++;
3961 if (my_get_expression (&inst.reloc.exp, &str))
3962 return;
3964 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3965 return;
3968 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3969 for the latter case, EXPR contains the immediate that was found. */
3970 if (Rn != FAIL)
3972 /* All register format. */
3973 if (Rd > 7 || Rs > 7 || Rn > 7)
3975 if (Rs != Rd)
3977 inst.error = _("dest and source1 must be the same register");
3978 return;
3981 /* Can't do this for SUB */
3982 if (subtract)
3984 inst.error = _("subtract valid only on lo regs");
3985 return;
3988 inst.instruction = (T_OPCODE_ADD_HI
3989 | (Rd > 7 ? THUMB_H1 : 0)
3990 | (Rn > 7 ? THUMB_H2 : 0));
3991 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
3993 else
3995 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
3996 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
3999 else
4001 /* Immediate expression, now things start to get nasty. */
4003 /* First deal with HI regs, only very restricted cases allowed:
4004 Adjusting SP, and using PC or SP to get an address. */
4005 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
4006 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
4008 inst.error = _("invalid Hi register with immediate");
4009 return;
4012 if (inst.reloc.exp.X_op != O_constant)
4014 /* Value isn't known yet, all we can do is store all the fragments
4015 we know about in the instruction and let the reloc hacking
4016 work it all out. */
4017 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
4018 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4020 else
4022 int offset = inst.reloc.exp.X_add_number;
4024 if (subtract)
4025 offset = -offset;
4027 if (offset < 0)
4029 offset = -offset;
4030 subtract = 1;
4032 /* Quick check, in case offset is MIN_INT */
4033 if (offset < 0)
4035 inst.error = _("immediate value out of range");
4036 return;
4039 else
4040 subtract = 0;
4042 if (Rd == REG_SP)
4044 if (offset & ~0x1fc)
4046 inst.error = _("invalid immediate value for stack adjust");
4047 return;
4049 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
4050 inst.instruction |= offset >> 2;
4052 else if (Rs == REG_PC || Rs == REG_SP)
4054 if (subtract
4055 || (offset & ~0x3fc))
4057 inst.error = _("invalid immediate for address calculation");
4058 return;
4060 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
4061 : T_OPCODE_ADD_SP);
4062 inst.instruction |= (Rd << 8) | (offset >> 2);
4064 else if (Rs == Rd)
4066 if (offset & ~0xff)
4068 inst.error = _("immediate value out of range");
4069 return;
4071 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
4072 inst.instruction |= (Rd << 8) | offset;
4074 else
4076 if (offset & ~0x7)
4078 inst.error = _("immediate value out of range");
4079 return;
4081 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
4082 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
4086 end_of_line (str);
4089 static void
4090 thumb_shift (str, shift)
4091 char * str;
4092 int shift;
4094 int Rd, Rs, Rn = FAIL;
4096 skip_whitespace (str);
4098 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4099 || skip_past_comma (&str) == FAIL)
4101 if (! inst.error)
4102 inst.error = BAD_ARGS;
4103 return;
4106 if (is_immediate_prefix (*str))
4108 /* Two operand immediate format, set Rs to Rd. */
4109 Rs = Rd;
4110 str++;
4111 if (my_get_expression (&inst.reloc.exp, &str))
4112 return;
4114 else
4116 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4117 return;
4119 if (skip_past_comma (&str) == FAIL)
4121 /* Two operand format, shuffle the registers and pretend there
4122 are 3 */
4123 Rn = Rs;
4124 Rs = Rd;
4126 else if (is_immediate_prefix (*str))
4128 str++;
4129 if (my_get_expression (&inst.reloc.exp, &str))
4130 return;
4132 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4133 return;
4136 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4137 for the latter case, EXPR contains the immediate that was found. */
4139 if (Rn != FAIL)
4141 if (Rs != Rd)
4143 inst.error = _("source1 and dest must be same register");
4144 return;
4147 switch (shift)
4149 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
4150 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
4151 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
4154 inst.instruction |= Rd | (Rn << 3);
4156 else
4158 switch (shift)
4160 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
4161 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
4162 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
4165 if (inst.reloc.exp.X_op != O_constant)
4167 /* Value isn't known yet, create a dummy reloc and let reloc
4168 hacking fix it up */
4170 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
4172 else
4174 unsigned shift_value = inst.reloc.exp.X_add_number;
4176 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
4178 inst.error = _("Invalid immediate for shift");
4179 return;
4182 /* Shifts of zero are handled by converting to LSL */
4183 if (shift_value == 0)
4184 inst.instruction = T_OPCODE_LSL_I;
4186 /* Shifts of 32 are encoded as a shift of zero */
4187 if (shift_value == 32)
4188 shift_value = 0;
4190 inst.instruction |= shift_value << 6;
4193 inst.instruction |= Rd | (Rs << 3);
4195 end_of_line (str);
4198 static void
4199 thumb_mov_compare (str, move)
4200 char * str;
4201 int move;
4203 int Rd, Rs = FAIL;
4205 skip_whitespace (str);
4207 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4208 || skip_past_comma (&str) == FAIL)
4210 if (! inst.error)
4211 inst.error = BAD_ARGS;
4212 return;
4215 if (is_immediate_prefix (*str))
4217 str++;
4218 if (my_get_expression (&inst.reloc.exp, &str))
4219 return;
4221 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4222 return;
4224 if (Rs != FAIL)
4226 if (Rs < 8 && Rd < 8)
4228 if (move == THUMB_MOVE)
4229 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4230 since a MOV instruction produces unpredictable results */
4231 inst.instruction = T_OPCODE_ADD_I3;
4232 else
4233 inst.instruction = T_OPCODE_CMP_LR;
4234 inst.instruction |= Rd | (Rs << 3);
4236 else
4238 if (move == THUMB_MOVE)
4239 inst.instruction = T_OPCODE_MOV_HR;
4240 else
4241 inst.instruction = T_OPCODE_CMP_HR;
4243 if (Rd > 7)
4244 inst.instruction |= THUMB_H1;
4246 if (Rs > 7)
4247 inst.instruction |= THUMB_H2;
4249 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4252 else
4254 if (Rd > 7)
4256 inst.error = _("only lo regs allowed with immediate");
4257 return;
4260 if (move == THUMB_MOVE)
4261 inst.instruction = T_OPCODE_MOV_I8;
4262 else
4263 inst.instruction = T_OPCODE_CMP_I8;
4265 inst.instruction |= Rd << 8;
4267 if (inst.reloc.exp.X_op != O_constant)
4268 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4269 else
4271 unsigned value = inst.reloc.exp.X_add_number;
4273 if (value > 255)
4275 inst.error = _("invalid immediate");
4276 return;
4279 inst.instruction |= value;
4283 end_of_line (str);
4286 static void
4287 thumb_load_store (str, load_store, size)
4288 char * str;
4289 int load_store;
4290 int size;
4292 int Rd, Rb, Ro = FAIL;
4294 skip_whitespace (str);
4296 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4297 || skip_past_comma (&str) == FAIL)
4299 if (! inst.error)
4300 inst.error = BAD_ARGS;
4301 return;
4304 if (*str == '[')
4306 str++;
4307 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4308 return;
4310 if (skip_past_comma (&str) != FAIL)
4312 if (is_immediate_prefix (*str))
4314 str++;
4315 if (my_get_expression (&inst.reloc.exp, &str))
4316 return;
4318 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4319 return;
4321 else
4323 inst.reloc.exp.X_op = O_constant;
4324 inst.reloc.exp.X_add_number = 0;
4327 if (*str != ']')
4329 inst.error = _("expected ']'");
4330 return;
4332 str++;
4334 else if (*str == '=')
4336 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4337 str++;
4339 skip_whitespace (str);
4341 if (my_get_expression (& inst.reloc.exp, & str))
4342 return;
4344 end_of_line (str);
4346 if ( inst.reloc.exp.X_op != O_constant
4347 && inst.reloc.exp.X_op != O_symbol)
4349 inst.error = "Constant expression expected";
4350 return;
4353 if (inst.reloc.exp.X_op == O_constant
4354 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
4356 /* This can be done with a mov instruction */
4358 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
4359 inst.instruction |= inst.reloc.exp.X_add_number;
4360 return;
4363 /* Insert into literal pool */
4364 if (add_to_lit_pool () == FAIL)
4366 if (!inst.error)
4367 inst.error = "literal pool insertion failed";
4368 return;
4371 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4372 inst.reloc.pc_rel = 1;
4373 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4374 inst.reloc.exp.X_add_number += 4; /* Adjust ARM pipeline offset to Thumb */
4376 return;
4378 else
4380 if (my_get_expression (&inst.reloc.exp, &str))
4381 return;
4383 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4384 inst.reloc.pc_rel = 1;
4385 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
4386 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4387 end_of_line (str);
4388 return;
4391 if (Rb == REG_PC || Rb == REG_SP)
4393 if (size != THUMB_WORD)
4395 inst.error = _("byte or halfword not valid for base register");
4396 return;
4398 else if (Rb == REG_PC && load_store != THUMB_LOAD)
4400 inst.error = _("R15 based store not allowed");
4401 return;
4403 else if (Ro != FAIL)
4405 inst.error = _("Invalid base register for register offset");
4406 return;
4409 if (Rb == REG_PC)
4410 inst.instruction = T_OPCODE_LDR_PC;
4411 else if (load_store == THUMB_LOAD)
4412 inst.instruction = T_OPCODE_LDR_SP;
4413 else
4414 inst.instruction = T_OPCODE_STR_SP;
4416 inst.instruction |= Rd << 8;
4417 if (inst.reloc.exp.X_op == O_constant)
4419 unsigned offset = inst.reloc.exp.X_add_number;
4421 if (offset & ~0x3fc)
4423 inst.error = _("invalid offset");
4424 return;
4427 inst.instruction |= offset >> 2;
4429 else
4430 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4432 else if (Rb > 7)
4434 inst.error = _("invalid base register in load/store");
4435 return;
4437 else if (Ro == FAIL)
4439 /* Immediate offset */
4440 if (size == THUMB_WORD)
4441 inst.instruction = (load_store == THUMB_LOAD
4442 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
4443 else if (size == THUMB_HALFWORD)
4444 inst.instruction = (load_store == THUMB_LOAD
4445 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
4446 else
4447 inst.instruction = (load_store == THUMB_LOAD
4448 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
4450 inst.instruction |= Rd | (Rb << 3);
4452 if (inst.reloc.exp.X_op == O_constant)
4454 unsigned offset = inst.reloc.exp.X_add_number;
4456 if (offset & ~(0x1f << size))
4458 inst.error = _("Invalid offset");
4459 return;
4461 inst.instruction |= (offset >> size) << 6;
4463 else
4464 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4466 else
4468 /* Register offset */
4469 if (size == THUMB_WORD)
4470 inst.instruction = (load_store == THUMB_LOAD
4471 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
4472 else if (size == THUMB_HALFWORD)
4473 inst.instruction = (load_store == THUMB_LOAD
4474 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
4475 else
4476 inst.instruction = (load_store == THUMB_LOAD
4477 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
4479 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4482 end_of_line (str);
4485 static void
4486 do_t_nop (str)
4487 char * str;
4489 /* Do nothing */
4490 end_of_line (str);
4491 return;
4494 /* Handle the Format 4 instructions that do not have equivalents in other
4495 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4496 BIC and MVN. */
4497 static void
4498 do_t_arit (str)
4499 char * str;
4501 int Rd, Rs, Rn;
4503 skip_whitespace (str);
4505 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4506 return;
4508 if (skip_past_comma (&str) == FAIL
4509 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4511 if (! inst.error)
4512 inst.error = BAD_ARGS;
4513 return;
4516 if (skip_past_comma (&str) != FAIL)
4518 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4519 (It isn't allowed for CMP either, but that isn't handled by this
4520 function.) */
4521 if (inst.instruction == T_OPCODE_TST
4522 || inst.instruction == T_OPCODE_CMN
4523 || inst.instruction == T_OPCODE_NEG
4524 || inst.instruction == T_OPCODE_MVN)
4526 inst.error = BAD_ARGS;
4527 return;
4530 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4531 return;
4533 if (Rs != Rd)
4535 inst.error = _("dest and source1 one must be the same register");
4536 return;
4538 Rs = Rn;
4541 if (inst.instruction == T_OPCODE_MUL
4542 && Rs == Rd)
4543 as_tsktsk (_("Rs and Rd must be different in MUL"));
4545 inst.instruction |= Rd | (Rs << 3);
4546 end_of_line (str);
4549 static void
4550 do_t_add (str)
4551 char * str;
4553 thumb_add_sub (str, 0);
4556 static void
4557 do_t_asr (str)
4558 char * str;
4560 thumb_shift (str, THUMB_ASR);
4563 static void
4564 do_t_branch9 (str)
4565 char * str;
4567 if (my_get_expression (&inst.reloc.exp, &str))
4568 return;
4569 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
4570 inst.reloc.pc_rel = 1;
4571 end_of_line (str);
4574 static void
4575 do_t_branch12 (str)
4576 char * str;
4578 if (my_get_expression (&inst.reloc.exp, &str))
4579 return;
4580 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
4581 inst.reloc.pc_rel = 1;
4582 end_of_line (str);
4585 /* Find the real, Thumb encoded start of a Thumb function. */
4587 static symbolS *
4588 find_real_start (symbolP)
4589 symbolS * symbolP;
4591 char * real_start;
4592 const char * name = S_GET_NAME (symbolP);
4593 symbolS * new_target;
4595 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4596 #define STUB_NAME ".real_start_of"
4598 if (name == NULL)
4599 abort();
4601 /* Names that start with '.' are local labels, not function entry points.
4602 The compiler may generate BL instructions to these labels because it
4603 needs to perform a branch to a far away location. */
4604 if (name[0] == '.')
4605 return symbolP;
4607 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
4608 sprintf (real_start, "%s%s", STUB_NAME, name);
4610 new_target = symbol_find (real_start);
4612 if (new_target == NULL)
4614 as_warn ("Failed to find real start of function: %s\n", name);
4615 new_target = symbolP;
4618 free (real_start);
4620 return new_target;
4624 static void
4625 do_t_branch23 (str)
4626 char * str;
4628 if (my_get_expression (& inst.reloc.exp, & str))
4629 return;
4631 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
4632 inst.reloc.pc_rel = 1;
4633 end_of_line (str);
4635 /* If the destination of the branch is a defined symbol which does not have
4636 the THUMB_FUNC attribute, then we must be calling a function which has
4637 the (interfacearm) attribute. We look for the Thumb entry point to that
4638 function and change the branch to refer to that function instead. */
4639 if ( inst.reloc.exp.X_op == O_symbol
4640 && inst.reloc.exp.X_add_symbol != NULL
4641 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
4642 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
4643 inst.reloc.exp.X_add_symbol = find_real_start (inst.reloc.exp.X_add_symbol);
4646 static void
4647 do_t_bx (str)
4648 char * str;
4650 int reg;
4652 skip_whitespace (str);
4654 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4655 return;
4657 /* This sets THUMB_H2 from the top bit of reg. */
4658 inst.instruction |= reg << 3;
4660 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4661 should cause the alignment to be checked once it is known. This is
4662 because BX PC only works if the instruction is word aligned. */
4664 end_of_line (str);
4667 static void
4668 do_t_compare (str)
4669 char * str;
4671 thumb_mov_compare (str, THUMB_COMPARE);
4674 static void
4675 do_t_ldmstm (str)
4676 char * str;
4678 int Rb;
4679 long range;
4681 skip_whitespace (str);
4683 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4684 return;
4686 if (*str != '!')
4687 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4688 else
4689 str++;
4691 if (skip_past_comma (&str) == FAIL
4692 || (range = reg_list (&str)) == FAIL)
4694 if (! inst.error)
4695 inst.error = BAD_ARGS;
4696 return;
4699 if (inst.reloc.type != BFD_RELOC_NONE)
4701 /* This really doesn't seem worth it. */
4702 inst.reloc.type = BFD_RELOC_NONE;
4703 inst.error = _("Expression too complex");
4704 return;
4707 if (range & ~0xff)
4709 inst.error = _("only lo-regs valid in load/store multiple");
4710 return;
4713 inst.instruction |= (Rb << 8) | range;
4714 end_of_line (str);
4717 static void
4718 do_t_ldr (str)
4719 char * str;
4721 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4724 static void
4725 do_t_ldrb (str)
4726 char * str;
4728 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4731 static void
4732 do_t_ldrh (str)
4733 char * str;
4735 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4738 static void
4739 do_t_lds (str)
4740 char * str;
4742 int Rd, Rb, Ro;
4744 skip_whitespace (str);
4746 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4747 || skip_past_comma (&str) == FAIL
4748 || *str++ != '['
4749 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4750 || skip_past_comma (&str) == FAIL
4751 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4752 || *str++ != ']')
4754 if (! inst.error)
4755 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4756 return;
4759 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4760 end_of_line (str);
4763 static void
4764 do_t_lsl (str)
4765 char * str;
4767 thumb_shift (str, THUMB_LSL);
4770 static void
4771 do_t_lsr (str)
4772 char * str;
4774 thumb_shift (str, THUMB_LSR);
4777 static void
4778 do_t_mov (str)
4779 char * str;
4781 thumb_mov_compare (str, THUMB_MOVE);
4784 static void
4785 do_t_push_pop (str)
4786 char * str;
4788 long range;
4790 skip_whitespace (str);
4792 if ((range = reg_list (&str)) == FAIL)
4794 if (! inst.error)
4795 inst.error = BAD_ARGS;
4796 return;
4799 if (inst.reloc.type != BFD_RELOC_NONE)
4801 /* This really doesn't seem worth it. */
4802 inst.reloc.type = BFD_RELOC_NONE;
4803 inst.error = _("Expression too complex");
4804 return;
4807 if (range & ~0xff)
4809 if ((inst.instruction == T_OPCODE_PUSH
4810 && (range & ~0xff) == 1 << REG_LR)
4811 || (inst.instruction == T_OPCODE_POP
4812 && (range & ~0xff) == 1 << REG_PC))
4814 inst.instruction |= THUMB_PP_PC_LR;
4815 range &= 0xff;
4817 else
4819 inst.error = _("invalid register list to push/pop instruction");
4820 return;
4824 inst.instruction |= range;
4825 end_of_line (str);
4828 static void
4829 do_t_str (str)
4830 char * str;
4832 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4835 static void
4836 do_t_strb (str)
4837 char * str;
4839 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4842 static void
4843 do_t_strh (str)
4844 char * str;
4846 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4849 static void
4850 do_t_sub (str)
4851 char * str;
4853 thumb_add_sub (str, 1);
4856 static void
4857 do_t_swi (str)
4858 char * str;
4860 skip_whitespace (str);
4862 if (my_get_expression (&inst.reloc.exp, &str))
4863 return;
4865 inst.reloc.type = BFD_RELOC_ARM_SWI;
4866 end_of_line (str);
4867 return;
4870 static void
4871 do_t_adr (str)
4872 char * str;
4874 /* This is a pseudo-op of the form "adr rd, label" to be converted
4875 into a relative address of the form "add rd, pc, #label-.-4" */
4876 skip_whitespace (str);
4878 if (reg_required_here (&str, 4) == FAIL /* Store Rd in temporary location inside instruction. */
4879 || skip_past_comma (&str) == FAIL
4880 || my_get_expression (&inst.reloc.exp, &str))
4882 if (!inst.error)
4883 inst.error = BAD_ARGS;
4884 return;
4887 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4888 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
4889 inst.reloc.pc_rel = 1;
4890 inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
4891 end_of_line (str);
4894 static void
4895 insert_reg (entry)
4896 int entry;
4898 int len = strlen (reg_table[entry].name) + 2;
4899 char * buf = (char *) xmalloc (len);
4900 char * buf2 = (char *) xmalloc (len);
4901 int i = 0;
4903 #ifdef REGISTER_PREFIX
4904 buf[i++] = REGISTER_PREFIX;
4905 #endif
4907 strcpy (buf + i, reg_table[entry].name);
4909 for (i = 0; buf[i]; i++)
4910 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
4912 buf2[i] = '\0';
4914 hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
4915 hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
4918 static void
4919 insert_reg_alias (str, regnum)
4920 char *str;
4921 int regnum;
4923 struct reg_entry *new =
4924 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
4925 char *name = xmalloc (strlen (str) + 1);
4926 strcpy (name, str);
4928 new->name = name;
4929 new->number = regnum;
4931 hash_insert (arm_reg_hsh, name, (PTR) new);
4934 static void
4935 set_constant_flonums ()
4937 int i;
4939 for (i = 0; i < NUM_FLOAT_VALS; i++)
4940 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
4941 abort ();
4944 void
4945 md_begin ()
4947 int i;
4949 if ( (arm_ops_hsh = hash_new ()) == NULL
4950 || (arm_tops_hsh = hash_new ()) == NULL
4951 || (arm_cond_hsh = hash_new ()) == NULL
4952 || (arm_shift_hsh = hash_new ()) == NULL
4953 || (arm_reg_hsh = hash_new ()) == NULL
4954 || (arm_psr_hsh = hash_new ()) == NULL)
4955 as_fatal (_("Virtual memory exhausted"));
4957 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
4958 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
4959 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
4960 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
4961 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
4962 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
4963 for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
4964 hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
4965 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
4966 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
4968 for (i = 0; reg_table[i].name; i++)
4969 insert_reg (i);
4971 set_constant_flonums ();
4973 #if defined OBJ_COFF || defined OBJ_ELF
4975 unsigned int flags = 0;
4977 /* Set the flags in the private structure */
4978 if (uses_apcs_26) flags |= F_APCS26;
4979 if (support_interwork) flags |= F_INTERWORK;
4980 if (uses_apcs_float) flags |= F_APCS_FLOAT;
4981 if (pic_code) flags |= F_PIC;
4982 if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT;
4984 bfd_set_private_flags (stdoutput, flags);
4986 #endif
4989 unsigned mach;
4991 /* Record the CPU type as well */
4992 switch (cpu_variant & ARM_CPU_MASK)
4994 case ARM_2:
4995 mach = bfd_mach_arm_2;
4996 break;
4998 case ARM_3: /* also ARM_250 */
4999 mach = bfd_mach_arm_2a;
5000 break;
5002 default:
5003 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined */
5004 mach = bfd_mach_arm_4;
5005 break;
5007 case ARM_7: /* also ARM_6 */
5008 mach = bfd_mach_arm_3;
5009 break;
5012 /* Catch special cases. */
5013 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
5015 if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
5016 mach = bfd_mach_arm_5T;
5017 else if (cpu_variant & ARM_EXT_V5)
5018 mach = bfd_mach_arm_5;
5019 else if (cpu_variant & ARM_THUMB)
5020 mach = bfd_mach_arm_4T;
5021 else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
5022 mach = bfd_mach_arm_4;
5023 else if (cpu_variant & ARM_LONGMUL)
5024 mach = bfd_mach_arm_3M;
5027 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
5031 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5032 for use in the a.out file, and stores them in the array pointed to by buf.
5033 This knows about the endian-ness of the target machine and does
5034 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5035 2 (short) and 4 (long) Floating numbers are put out as a series of
5036 LITTLENUMS (shorts, here at least). */
5037 void
5038 md_number_to_chars (buf, val, n)
5039 char * buf;
5040 valueT val;
5041 int n;
5043 if (target_big_endian)
5044 number_to_chars_bigendian (buf, val, n);
5045 else
5046 number_to_chars_littleendian (buf, val, n);
5049 static valueT
5050 md_chars_to_number (buf, n)
5051 char * buf;
5052 int n;
5054 valueT result = 0;
5055 unsigned char * where = (unsigned char *) buf;
5057 if (target_big_endian)
5059 while (n--)
5061 result <<= 8;
5062 result |= (*where++ & 255);
5065 else
5067 while (n--)
5069 result <<= 8;
5070 result |= (where[n] & 255);
5074 return result;
5077 /* Turn a string in input_line_pointer into a floating point constant
5078 of type TYPE, and store the appropriate bytes in *litP. The number
5079 of LITTLENUMS emitted is stored in *sizeP . An error message is
5080 returned, or NULL on OK.
5082 Note that fp constants aren't represent in the normal way on the ARM.
5083 In big endian mode, things are as expected. However, in little endian
5084 mode fp constants are big-endian word-wise, and little-endian byte-wise
5085 within the words. For example, (double) 1.1 in big endian mode is
5086 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5087 the byte sequence 99 99 f1 3f 9a 99 99 99.
5089 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5091 char *
5092 md_atof (type, litP, sizeP)
5093 char type;
5094 char * litP;
5095 int * sizeP;
5097 int prec;
5098 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5099 char *t;
5100 int i;
5102 switch (type)
5104 case 'f':
5105 case 'F':
5106 case 's':
5107 case 'S':
5108 prec = 2;
5109 break;
5111 case 'd':
5112 case 'D':
5113 case 'r':
5114 case 'R':
5115 prec = 4;
5116 break;
5118 case 'x':
5119 case 'X':
5120 prec = 6;
5121 break;
5123 case 'p':
5124 case 'P':
5125 prec = 6;
5126 break;
5128 default:
5129 *sizeP = 0;
5130 return _("Bad call to MD_ATOF()");
5133 t = atof_ieee (input_line_pointer, type, words);
5134 if (t)
5135 input_line_pointer = t;
5136 *sizeP = prec * 2;
5138 if (target_big_endian)
5140 for (i = 0; i < prec; i++)
5142 md_number_to_chars (litP, (valueT) words[i], 2);
5143 litP += 2;
5146 else
5148 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5149 8 byte float the order is 1 0 3 2. */
5150 for (i = 0; i < prec; i += 2)
5152 md_number_to_chars (litP, (valueT) words[i + 1], 2);
5153 md_number_to_chars (litP + 2, (valueT) words[i], 2);
5154 litP += 4;
5158 return 0;
5161 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5162 long
5163 md_pcrel_from (fixP)
5164 fixS * fixP;
5166 if ( fixP->fx_addsy
5167 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
5168 && fixP->fx_subsy == NULL)
5169 return 0;
5171 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
5173 /* PC relative addressing on the Thumb is slightly odd
5174 as the bottom two bits of the PC are forced to zero
5175 for the calculation. */
5176 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
5179 return fixP->fx_where + fixP->fx_frag->fr_address;
5182 /* Round up a section size to the appropriate boundary. */
5183 valueT
5184 md_section_align (segment, size)
5185 segT segment;
5186 valueT size;
5188 #ifdef OBJ_ELF
5189 return size;
5190 #else
5191 /* Round all sects to multiple of 4 */
5192 return (size + 3) & ~3;
5193 #endif
5196 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5197 we have no need to default values of symbols. */
5199 /* ARGSUSED */
5200 symbolS *
5201 md_undefined_symbol (name)
5202 char * name;
5204 #ifdef OBJ_ELF
5205 if (name[0] == '_' && name[1] == 'G'
5206 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
5208 if (!GOT_symbol)
5210 if (symbol_find (name))
5211 as_bad ("GOT already in the symbol table");
5213 GOT_symbol = symbol_new (name, undefined_section,
5214 (valueT)0, & zero_address_frag);
5217 return GOT_symbol;
5219 #endif
5221 return 0;
5224 /* arm_reg_parse () := if it looks like a register, return its token and
5225 advance the pointer. */
5227 static int
5228 arm_reg_parse (ccp)
5229 register char ** ccp;
5231 char * start = * ccp;
5232 char c;
5233 char * p;
5234 struct reg_entry * reg;
5236 #ifdef REGISTER_PREFIX
5237 if (*start != REGISTER_PREFIX)
5238 return FAIL;
5239 p = start + 1;
5240 #else
5241 p = start;
5242 #ifdef OPTIONAL_REGISTER_PREFIX
5243 if (*p == OPTIONAL_REGISTER_PREFIX)
5244 p++, start++;
5245 #endif
5246 #endif
5247 if (!isalpha (*p) || !is_name_beginner (*p))
5248 return FAIL;
5250 c = *p++;
5251 while (isalpha (c) || isdigit (c) || c == '_')
5252 c = *p++;
5254 *--p = 0;
5255 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
5256 *p = c;
5258 if (reg)
5260 *ccp = p;
5261 return reg->number;
5264 return FAIL;
5267 static int
5268 arm_psr_parse (ccp)
5269 register char ** ccp;
5271 char * start = * ccp;
5272 char c;
5273 char * p;
5274 CONST struct asm_psr * psr;
5276 p = start;
5277 c = *p++;
5278 while (isalpha (c) || c == '_')
5279 c = *p++;
5281 *--p = 0;
5282 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
5283 *p = c;
5285 if (psr)
5287 *ccp = p;
5288 return psr->number;
5291 return FAIL;
5295 md_apply_fix3 (fixP, val, seg)
5296 fixS * fixP;
5297 valueT * val;
5298 segT seg;
5300 offsetT value = * val;
5301 offsetT newval;
5302 unsigned int newimm;
5303 unsigned long temp;
5304 int sign;
5305 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5306 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
5308 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5310 /* Note whether this will delete the relocation. */
5311 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5312 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
5313 && !fixP->fx_pcrel)
5314 #else
5315 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5316 #endif
5317 fixP->fx_done = 1;
5319 /* If this symbol is in a different section then we need to leave it for
5320 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5321 so we have to undo it's effects here. */
5322 if (fixP->fx_pcrel)
5324 if (fixP->fx_addsy != NULL
5325 && S_IS_DEFINED (fixP->fx_addsy)
5326 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5328 if (target_oabi
5329 && fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
5330 value = 0;
5331 else
5332 value += md_pcrel_from (fixP);
5336 fixP->fx_addnumber = value; /* Remember value for emit_reloc. */
5338 switch (fixP->fx_r_type)
5340 case BFD_RELOC_ARM_IMMEDIATE:
5341 newimm = validate_immediate (value);
5342 temp = md_chars_to_number (buf, INSN_SIZE);
5344 /* If the instruction will fail, see if we can fix things up by
5345 changing the opcode. */
5346 if (newimm == (unsigned int) FAIL
5347 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5349 as_bad_where (fixP->fx_file, fixP->fx_line,
5350 _("invalid constant (%lx) after fixup"),
5351 (unsigned long) value);
5352 break;
5355 newimm |= (temp & 0xfffff000);
5356 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5357 break;
5359 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5361 unsigned int highpart = 0;
5362 unsigned int newinsn = 0xe1a00000; /* nop */
5363 newimm = validate_immediate (value);
5364 temp = md_chars_to_number (buf, INSN_SIZE);
5366 /* If the instruction will fail, see if we can fix things up by
5367 changing the opcode. */
5368 if (newimm == (unsigned int) FAIL
5369 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
5371 /* No ? OK - try using two ADD instructions to generate the value. */
5372 newimm = validate_immediate_twopart (value, & highpart);
5374 /* Yes - then make sure that the second instruction is also an add. */
5375 if (newimm != (unsigned int) FAIL)
5376 newinsn = temp;
5377 /* Still No ? Try using a negated value. */
5378 else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL)
5379 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
5380 /* Otherwise - give up. */
5381 else
5383 as_bad_where (fixP->fx_file, fixP->fx_line,
5384 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value);
5385 break;
5388 /* Replace the first operand in the 2nd instruction (which is the PC)
5389 with the destination register. We have already added in the PC in the
5390 first instruction and we do not want to do it again. */
5391 newinsn &= ~ 0xf0000;
5392 newinsn |= ((newinsn & 0x0f000) << 4);
5395 newimm |= (temp & 0xfffff000);
5396 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5398 highpart |= (newinsn & 0xfffff000);
5399 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
5401 break;
5403 case BFD_RELOC_ARM_OFFSET_IMM:
5404 sign = value >= 0;
5406 if (value < 0)
5407 value = - value;
5409 if (validate_offset_imm (value, 0) == FAIL)
5411 as_bad_where (fixP->fx_file, fixP->fx_line,
5412 _("bad immediate value for offset (%ld)"), (long) value);
5413 break;
5416 newval = md_chars_to_number (buf, INSN_SIZE);
5417 newval &= 0xff7ff000;
5418 newval |= value | (sign ? INDEX_UP : 0);
5419 md_number_to_chars (buf, newval, INSN_SIZE);
5420 break;
5422 case BFD_RELOC_ARM_OFFSET_IMM8:
5423 case BFD_RELOC_ARM_HWLITERAL:
5424 sign = value >= 0;
5426 if (value < 0)
5427 value = - value;
5429 if (validate_offset_imm (value, 1) == FAIL)
5431 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5432 as_bad_where (fixP->fx_file, fixP->fx_line,
5433 _("invalid literal constant: pool needs to be closer"));
5434 else
5435 as_bad (_("bad immediate value for half-word offset (%ld)"),
5436 (long) value);
5437 break;
5440 newval = md_chars_to_number (buf, INSN_SIZE);
5441 newval &= 0xff7ff0f0;
5442 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
5443 md_number_to_chars (buf, newval, INSN_SIZE);
5444 break;
5446 case BFD_RELOC_ARM_LITERAL:
5447 sign = value >= 0;
5449 if (value < 0)
5450 value = - value;
5452 if (validate_offset_imm (value, 0) == FAIL)
5454 as_bad_where (fixP->fx_file, fixP->fx_line,
5455 _("invalid literal constant: pool needs to be closer"));
5456 break;
5459 newval = md_chars_to_number (buf, INSN_SIZE);
5460 newval &= 0xff7ff000;
5461 newval |= value | (sign ? INDEX_UP : 0);
5462 md_number_to_chars (buf, newval, INSN_SIZE);
5463 break;
5465 case BFD_RELOC_ARM_SHIFT_IMM:
5466 newval = md_chars_to_number (buf, INSN_SIZE);
5467 if (((unsigned long) value) > 32
5468 || (value == 32
5469 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5471 as_bad_where (fixP->fx_file, fixP->fx_line,
5472 _("shift expression is too large"));
5473 break;
5476 if (value == 0)
5477 newval &= ~0x60; /* Shifts of zero must be done as lsl */
5478 else if (value == 32)
5479 value = 0;
5480 newval &= 0xfffff07f;
5481 newval |= (value & 0x1f) << 7;
5482 md_number_to_chars (buf, newval , INSN_SIZE);
5483 break;
5485 case BFD_RELOC_ARM_SWI:
5486 if (arm_data->thumb_mode)
5488 if (((unsigned long) value) > 0xff)
5489 as_bad_where (fixP->fx_file, fixP->fx_line,
5490 _("Invalid swi expression"));
5491 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5492 newval |= value;
5493 md_number_to_chars (buf, newval, THUMB_SIZE);
5495 else
5497 if (((unsigned long) value) > 0x00ffffff)
5498 as_bad_where (fixP->fx_file, fixP->fx_line,
5499 _("Invalid swi expression"));
5500 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5501 newval |= value;
5502 md_number_to_chars (buf, newval , INSN_SIZE);
5504 break;
5506 case BFD_RELOC_ARM_MULTI:
5507 if (((unsigned long) value) > 0xffff)
5508 as_bad_where (fixP->fx_file, fixP->fx_line,
5509 _("Invalid expression in load/store multiple"));
5510 newval = value | md_chars_to_number (buf, INSN_SIZE);
5511 md_number_to_chars (buf, newval, INSN_SIZE);
5512 break;
5514 case BFD_RELOC_ARM_PCREL_BRANCH:
5515 newval = md_chars_to_number (buf, INSN_SIZE);
5517 #ifdef OBJ_ELF
5518 if (! target_oabi)
5519 value = fixP->fx_offset;
5520 #endif
5521 value = (value >> 2) & 0x00ffffff;
5522 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5523 newval = value | (newval & 0xff000000);
5524 md_number_to_chars (buf, newval, INSN_SIZE);
5525 break;
5527 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5528 newval = md_chars_to_number (buf, THUMB_SIZE);
5530 addressT diff = (newval & 0xff) << 1;
5531 if (diff & 0x100)
5532 diff |= ~0xff;
5534 value += diff;
5535 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5536 as_bad_where (fixP->fx_file, fixP->fx_line,
5537 _("Branch out of range"));
5538 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5540 md_number_to_chars (buf, newval, THUMB_SIZE);
5541 break;
5543 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5544 newval = md_chars_to_number (buf, THUMB_SIZE);
5546 addressT diff = (newval & 0x7ff) << 1;
5547 if (diff & 0x800)
5548 diff |= ~0x7ff;
5550 value += diff;
5551 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5552 as_bad_where (fixP->fx_file, fixP->fx_line,
5553 _("Branch out of range"));
5554 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5556 md_number_to_chars (buf, newval, THUMB_SIZE);
5557 break;
5559 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5561 offsetT newval2;
5562 addressT diff;
5564 newval = md_chars_to_number (buf, THUMB_SIZE);
5565 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5566 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5567 if (diff & 0x400000)
5568 diff |= ~0x3fffff;
5569 #ifdef OBJ_ELF
5570 value = fixP->fx_offset;
5571 #endif
5572 value += diff;
5573 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5574 as_bad_where (fixP->fx_file, fixP->fx_line,
5575 _("Branch with link out of range"));
5577 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5578 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5579 md_number_to_chars (buf, newval, THUMB_SIZE);
5580 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5582 break;
5584 case BFD_RELOC_8:
5585 if (fixP->fx_done || fixP->fx_pcrel)
5586 md_number_to_chars (buf, value, 1);
5587 #ifdef OBJ_ELF
5588 else if (!target_oabi)
5590 value = fixP->fx_offset;
5591 md_number_to_chars (buf, value, 1);
5593 #endif
5594 break;
5596 case BFD_RELOC_16:
5597 if (fixP->fx_done || fixP->fx_pcrel)
5598 md_number_to_chars (buf, value, 2);
5599 #ifdef OBJ_ELF
5600 else if (!target_oabi)
5602 value = fixP->fx_offset;
5603 md_number_to_chars (buf, value, 2);
5605 #endif
5606 break;
5608 #ifdef OBJ_ELF
5609 case BFD_RELOC_ARM_GOT32:
5610 case BFD_RELOC_ARM_GOTOFF:
5611 md_number_to_chars (buf, 0, 4);
5612 break;
5613 #endif
5615 case BFD_RELOC_RVA:
5616 case BFD_RELOC_32:
5617 if (fixP->fx_done || fixP->fx_pcrel)
5618 md_number_to_chars (buf, value, 4);
5619 #ifdef OBJ_ELF
5620 else if (!target_oabi)
5622 value = fixP->fx_offset;
5623 md_number_to_chars (buf, value, 4);
5625 #endif
5626 break;
5628 #ifdef OBJ_ELF
5629 case BFD_RELOC_ARM_PLT32:
5630 /* It appears the instruction is fully prepared at this point. */
5631 break;
5632 #endif
5634 case BFD_RELOC_ARM_GOTPC:
5635 md_number_to_chars (buf, value, 4);
5636 break;
5638 case BFD_RELOC_ARM_CP_OFF_IMM:
5639 sign = value >= 0;
5640 if (value < -1023 || value > 1023 || (value & 3))
5641 as_bad_where (fixP->fx_file, fixP->fx_line,
5642 _("Illegal value for co-processor offset"));
5643 if (value < 0)
5644 value = -value;
5645 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5646 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5647 md_number_to_chars (buf, newval , INSN_SIZE);
5648 break;
5650 case BFD_RELOC_ARM_THUMB_OFFSET:
5651 newval = md_chars_to_number (buf, THUMB_SIZE);
5652 /* Exactly what ranges, and where the offset is inserted depends on
5653 the type of instruction, we can establish this from the top 4 bits */
5654 switch (newval >> 12)
5656 case 4: /* PC load */
5657 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5658 forced to zero for these loads, so we will need to round
5659 up the offset if the instruction address is not word
5660 aligned (since the final address produced must be, and
5661 we can only describe word-aligned immediate offsets). */
5663 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5664 as_bad_where (fixP->fx_file, fixP->fx_line,
5665 _("Invalid offset, target not word aligned (0x%08X)"),
5666 (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5668 if ((value + 2) & ~0x3fe)
5669 as_bad_where (fixP->fx_file, fixP->fx_line,
5670 _("Invalid offset, value too big (0x%08X)"), value);
5672 /* Round up, since pc will be rounded down. */
5673 newval |= (value + 2) >> 2;
5674 break;
5676 case 9: /* SP load/store */
5677 if (value & ~0x3fc)
5678 as_bad_where (fixP->fx_file, fixP->fx_line,
5679 _("Invalid offset, value too big (0x%08X)"), value);
5680 newval |= value >> 2;
5681 break;
5683 case 6: /* Word load/store */
5684 if (value & ~0x7c)
5685 as_bad_where (fixP->fx_file, fixP->fx_line,
5686 _("Invalid offset, value too big (0x%08X)"), value);
5687 newval |= value << 4; /* 6 - 2 */
5688 break;
5690 case 7: /* Byte load/store */
5691 if (value & ~0x1f)
5692 as_bad_where (fixP->fx_file, fixP->fx_line,
5693 _("Invalid offset, value too big (0x%08X)"), value);
5694 newval |= value << 6;
5695 break;
5697 case 8: /* Halfword load/store */
5698 if (value & ~0x3e)
5699 as_bad_where (fixP->fx_file, fixP->fx_line,
5700 _("Invalid offset, value too big (0x%08X)"), value);
5701 newval |= value << 5; /* 6 - 1 */
5702 break;
5704 default:
5705 as_bad_where (fixP->fx_file, fixP->fx_line,
5706 "Unable to process relocation for thumb opcode: %lx",
5707 (unsigned long) newval);
5708 break;
5710 md_number_to_chars (buf, newval, THUMB_SIZE);
5711 break;
5713 case BFD_RELOC_ARM_THUMB_ADD:
5714 /* This is a complicated relocation, since we use it for all of
5715 the following immediate relocations:
5716 3bit ADD/SUB
5717 8bit ADD/SUB
5718 9bit ADD/SUB SP word-aligned
5719 10bit ADD PC/SP word-aligned
5721 The type of instruction being processed is encoded in the
5722 instruction field:
5723 0x8000 SUB
5724 0x00F0 Rd
5725 0x000F Rs
5727 newval = md_chars_to_number (buf, THUMB_SIZE);
5729 int rd = (newval >> 4) & 0xf;
5730 int rs = newval & 0xf;
5731 int subtract = newval & 0x8000;
5733 if (rd == REG_SP)
5735 if (value & ~0x1fc)
5736 as_bad_where (fixP->fx_file, fixP->fx_line,
5737 _("Invalid immediate for stack address calculation"));
5738 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5739 newval |= value >> 2;
5741 else if (rs == REG_PC || rs == REG_SP)
5743 if (subtract ||
5744 value & ~0x3fc)
5745 as_bad_where (fixP->fx_file, fixP->fx_line,
5746 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5747 (unsigned long) value);
5748 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5749 newval |= rd << 8;
5750 newval |= value >> 2;
5752 else if (rs == rd)
5754 if (value & ~0xff)
5755 as_bad_where (fixP->fx_file, fixP->fx_line,
5756 _("Invalid 8bit immediate"));
5757 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5758 newval |= (rd << 8) | value;
5760 else
5762 if (value & ~0x7)
5763 as_bad_where (fixP->fx_file, fixP->fx_line,
5764 _("Invalid 3bit immediate"));
5765 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5766 newval |= rd | (rs << 3) | (value << 6);
5769 md_number_to_chars (buf, newval , THUMB_SIZE);
5770 break;
5772 case BFD_RELOC_ARM_THUMB_IMM:
5773 newval = md_chars_to_number (buf, THUMB_SIZE);
5774 switch (newval >> 11)
5776 case 0x04: /* 8bit immediate MOV */
5777 case 0x05: /* 8bit immediate CMP */
5778 if (value < 0 || value > 255)
5779 as_bad_where (fixP->fx_file, fixP->fx_line,
5780 _("Invalid immediate: %ld is too large"),
5781 (long) value);
5782 newval |= value;
5783 break;
5785 default:
5786 abort ();
5788 md_number_to_chars (buf, newval , THUMB_SIZE);
5789 break;
5791 case BFD_RELOC_ARM_THUMB_SHIFT:
5792 /* 5bit shift value (0..31) */
5793 if (value < 0 || value > 31)
5794 as_bad_where (fixP->fx_file, fixP->fx_line,
5795 _("Illegal Thumb shift value: %ld"), (long) value);
5796 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5797 newval |= value << 6;
5798 md_number_to_chars (buf, newval , THUMB_SIZE);
5799 break;
5801 case BFD_RELOC_VTABLE_INHERIT:
5802 case BFD_RELOC_VTABLE_ENTRY:
5803 fixP->fx_done = 0;
5804 return 1;
5806 case BFD_RELOC_NONE:
5807 default:
5808 as_bad_where (fixP->fx_file, fixP->fx_line,
5809 _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
5812 return 1;
5815 /* Translate internal representation of relocation info to BFD target
5816 format. */
5817 arelent *
5818 tc_gen_reloc (section, fixp)
5819 asection * section;
5820 fixS * fixp;
5822 arelent * reloc;
5823 bfd_reloc_code_real_type code;
5825 reloc = (arelent *) xmalloc (sizeof (arelent));
5827 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
5828 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5829 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5831 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5832 #ifndef OBJ_ELF
5833 if (fixp->fx_pcrel == 0)
5834 reloc->addend = fixp->fx_offset;
5835 else
5836 reloc->addend = fixp->fx_offset = reloc->address;
5837 #else /* OBJ_ELF */
5838 reloc->addend = fixp->fx_offset;
5839 #endif
5841 switch (fixp->fx_r_type)
5843 case BFD_RELOC_8:
5844 if (fixp->fx_pcrel)
5846 code = BFD_RELOC_8_PCREL;
5847 break;
5850 case BFD_RELOC_16:
5851 if (fixp->fx_pcrel)
5853 code = BFD_RELOC_16_PCREL;
5854 break;
5857 case BFD_RELOC_32:
5858 if (fixp->fx_pcrel)
5860 code = BFD_RELOC_32_PCREL;
5861 break;
5864 case BFD_RELOC_ARM_PCREL_BRANCH:
5865 case BFD_RELOC_RVA:
5866 case BFD_RELOC_THUMB_PCREL_BRANCH9:
5867 case BFD_RELOC_THUMB_PCREL_BRANCH12:
5868 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5869 case BFD_RELOC_VTABLE_ENTRY:
5870 case BFD_RELOC_VTABLE_INHERIT:
5871 code = fixp->fx_r_type;
5872 break;
5874 case BFD_RELOC_ARM_LITERAL:
5875 case BFD_RELOC_ARM_HWLITERAL:
5876 /* If this is called then the a literal has been referenced across
5877 a section boundary - possibly due to an implicit dump */
5878 as_bad_where (fixp->fx_file, fixp->fx_line,
5879 _("Literal referenced across section boundary (Implicit dump?)"));
5880 return NULL;
5882 #ifdef OBJ_ELF
5883 case BFD_RELOC_ARM_GOT32:
5884 case BFD_RELOC_ARM_GOTOFF:
5885 case BFD_RELOC_ARM_PLT32:
5886 code = fixp->fx_r_type;
5887 break;
5888 #endif
5890 case BFD_RELOC_ARM_IMMEDIATE:
5891 as_bad_where (fixp->fx_file, fixp->fx_line,
5892 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5893 fixp->fx_r_type);
5894 return NULL;
5896 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5897 as_bad_where (fixp->fx_file, fixp->fx_line,
5898 _("ADRL used for a symbol not defined in the same file"),
5899 fixp->fx_r_type);
5900 return NULL;
5902 case BFD_RELOC_ARM_OFFSET_IMM:
5903 as_bad_where (fixp->fx_file, fixp->fx_line,
5904 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5905 fixp->fx_r_type);
5906 return NULL;
5908 default:
5910 char * type;
5911 switch (fixp->fx_r_type)
5913 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
5914 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
5915 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
5916 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
5917 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
5918 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
5919 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
5920 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
5921 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
5922 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
5923 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
5924 default: type = _("<unknown>"); break;
5926 as_bad_where (fixp->fx_file, fixp->fx_line,
5927 _("Can not represent %s relocation in this object file format (%d)"),
5928 type, fixp->fx_pcrel);
5929 return NULL;
5933 #ifdef OBJ_ELF
5934 if (code == BFD_RELOC_32_PCREL
5935 && GOT_symbol
5936 && fixp->fx_addsy == GOT_symbol)
5938 code = BFD_RELOC_ARM_GOTPC;
5939 reloc->addend = fixp->fx_offset = reloc->address;
5941 #endif
5943 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5945 if (reloc->howto == NULL)
5947 as_bad_where (fixp->fx_file, fixp->fx_line,
5948 _("Can not represent %s relocation in this object file format"),
5949 bfd_get_reloc_code_name (code));
5950 return NULL;
5953 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5954 vtable entry to be used in the relocation's section offset. */
5955 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5956 reloc->address = fixp->fx_offset;
5958 return reloc;
5962 md_estimate_size_before_relax (fragP, segtype)
5963 fragS * fragP;
5964 segT segtype;
5966 as_fatal (_("md_estimate_size_before_relax\n"));
5967 return 1;
5970 static void
5971 output_inst PARAMS ((void))
5973 char * to = NULL;
5975 if (inst.error)
5977 as_bad (inst.error);
5978 return;
5981 to = frag_more (inst.size);
5983 if (thumb_mode && (inst.size > THUMB_SIZE))
5985 assert (inst.size == (2 * THUMB_SIZE));
5986 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
5987 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
5989 else if (inst.size > INSN_SIZE)
5991 assert (inst.size == (2 * INSN_SIZE));
5992 md_number_to_chars (to, inst.instruction, INSN_SIZE);
5993 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
5995 else
5996 md_number_to_chars (to, inst.instruction, inst.size);
5998 if (inst.reloc.type != BFD_RELOC_NONE)
5999 fix_new_arm (frag_now, to - frag_now->fr_literal,
6000 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
6001 inst.reloc.type);
6003 return;
6006 void
6007 md_assemble (str)
6008 char * str;
6010 char c;
6011 char * p;
6012 char * q;
6013 char * start;
6015 /* Align the instruction.
6016 This may not be the right thing to do but ... */
6017 /* arm_align (2, 0); */
6018 listing_prev_line (); /* Defined in listing.h */
6020 /* Align the previous label if needed. */
6021 if (last_label_seen != NULL)
6023 symbol_set_frag (last_label_seen, frag_now);
6024 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
6025 S_SET_SEGMENT (last_label_seen, now_seg);
6028 memset (&inst, '\0', sizeof (inst));
6029 inst.reloc.type = BFD_RELOC_NONE;
6031 skip_whitespace (str);
6033 /* Scan up to the end of the op-code, which must end in white space or
6034 end of string. */
6035 for (start = p = str; *p != '\0'; p++)
6036 if (*p == ' ')
6037 break;
6039 if (p == str)
6041 as_bad (_("No operator -- statement `%s'\n"), str);
6042 return;
6045 if (thumb_mode)
6047 CONST struct thumb_opcode * opcode;
6049 c = *p;
6050 *p = '\0';
6051 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
6052 *p = c;
6054 if (opcode)
6056 inst.instruction = opcode->value;
6057 inst.size = opcode->size;
6058 (*opcode->parms)(p);
6059 output_inst ();
6060 return;
6063 else
6065 CONST struct asm_opcode * opcode;
6067 inst.size = INSN_SIZE;
6068 /* p now points to the end of the opcode, probably white space, but we
6069 have to break the opcode up in case it contains condionals and flags;
6070 keep trying with progressively smaller basic instructions until one
6071 matches, or we run out of opcode. */
6072 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
6073 for (; q != str; q--)
6075 c = *q;
6076 *q = '\0';
6077 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
6078 *q = c;
6080 if (opcode && opcode->template)
6082 unsigned long flag_bits = 0;
6083 char * r;
6085 /* Check that this instruction is supported for this CPU. */
6086 if ((opcode->variants & cpu_variant) == 0)
6087 goto try_shorter;
6089 inst.instruction = opcode->value;
6090 if (q == p) /* Just a simple opcode. */
6092 if (opcode->comp_suffix != 0)
6093 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6094 opcode->comp_suffix);
6095 else
6097 inst.instruction |= COND_ALWAYS;
6098 (*opcode->parms)(q, 0);
6100 output_inst ();
6101 return;
6104 /* Now check for a conditional. */
6105 r = q;
6106 if (p - r >= 2)
6108 CONST struct asm_cond *cond;
6109 char d = *(r + 2);
6111 *(r + 2) = '\0';
6112 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
6113 *(r + 2) = d;
6114 if (cond)
6116 if (cond->value == 0xf0000000)
6117 as_tsktsk (
6118 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6120 inst.instruction |= cond->value;
6121 r += 2;
6123 else
6124 inst.instruction |= COND_ALWAYS;
6126 else
6127 inst.instruction |= COND_ALWAYS;
6129 /* If there is a compulsory suffix, it should come here, before
6130 any optional flags. */
6131 if (opcode->comp_suffix)
6133 CONST char *s = opcode->comp_suffix;
6135 while (*s)
6137 inst.suffix++;
6138 if (*r == *s)
6139 break;
6140 s++;
6143 if (*s == '\0')
6145 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6146 opcode->comp_suffix);
6147 return;
6150 r++;
6153 /* The remainder, if any should now be flags for the instruction;
6154 Scan these checking each one found with the opcode. */
6155 if (r != p)
6157 char d;
6158 CONST struct asm_flg *flag = opcode->flags;
6160 if (flag)
6162 int flagno;
6164 d = *p;
6165 *p = '\0';
6167 for (flagno = 0; flag[flagno].template; flagno++)
6169 if (streq (r, flag[flagno].template))
6171 flag_bits |= flag[flagno].set_bits;
6172 break;
6176 *p = d;
6177 if (! flag[flagno].template)
6178 goto try_shorter;
6180 else
6181 goto try_shorter;
6184 (*opcode->parms) (p, flag_bits);
6185 output_inst ();
6186 return;
6189 try_shorter:
6194 /* It wasn't an instruction, but it might be a register alias of the form
6195 alias .req reg */
6196 q = p;
6197 skip_whitespace (q);
6199 c = *p;
6200 *p = '\0';
6202 if (*q && !strncmp (q, ".req ", 4))
6204 int reg;
6205 char * copy_of_str = str;
6206 char * r;
6208 q += 4;
6209 skip_whitespace (q);
6211 for (r = q; *r != '\0'; r++)
6212 if (*r == ' ')
6213 break;
6215 if (r != q)
6217 int regnum;
6218 char d = *r;
6220 *r = '\0';
6221 regnum = arm_reg_parse (& q);
6222 *r = d;
6224 reg = arm_reg_parse (& str);
6226 if (reg == FAIL)
6228 if (regnum != FAIL)
6229 insert_reg_alias (str, regnum);
6230 else
6231 as_warn (_("register '%s' does not exist"), q);
6233 else if (regnum != FAIL)
6235 if (reg != regnum)
6236 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str );
6238 /* Do not warn about redefinitions to the same alias. */
6240 else
6241 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6242 copy_of_str, q);
6244 else
6245 as_warn (_("ignoring incomplete .req pseuso op"));
6247 *p = c;
6248 return;
6251 *p = c;
6252 as_bad (_("bad instruction `%s'"), start);
6256 * md_parse_option
6257 * Invocation line includes a switch not recognized by the base assembler.
6258 * See if it's a processor-specific option. These are:
6259 * Cpu variants, the arm part is optional:
6260 * -m[arm]1 Currently not supported.
6261 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6262 * -m[arm]3 Arm 3 processor
6263 * -m[arm]6[xx], Arm 6 processors
6264 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6265 * -m[arm]8[10] Arm 8 processors
6266 * -m[arm]9[20][tdmi] Arm 9 processors
6267 * -mstrongarm[110[0]] StrongARM processors
6268 * -m[arm]v[2345] Arm architecures
6269 * -mall All (except the ARM1)
6270 * FP variants:
6271 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6272 * -mfpe-old (No float load/store multiples)
6273 * -mno-fpu Disable all floating point instructions
6274 * Run-time endian selection:
6275 * -EB big endian cpu
6276 * -EL little endian cpu
6277 * ARM Procedure Calling Standard:
6278 * -mapcs-32 32 bit APCS
6279 * -mapcs-26 26 bit APCS
6280 * -mapcs-float Pass floats in float regs
6281 * -mapcs-reentrant Position independent code
6282 * -mthumb-interwork Code supports Arm/Thumb interworking
6283 * -moabi Old ELF ABI
6286 CONST char * md_shortopts = "m:k";
6287 struct option md_longopts[] =
6289 #ifdef ARM_BI_ENDIAN
6290 #define OPTION_EB (OPTION_MD_BASE + 0)
6291 {"EB", no_argument, NULL, OPTION_EB},
6292 #define OPTION_EL (OPTION_MD_BASE + 1)
6293 {"EL", no_argument, NULL, OPTION_EL},
6294 #ifdef OBJ_ELF
6295 #define OPTION_OABI (OPTION_MD_BASE +2)
6296 {"oabi", no_argument, NULL, OPTION_OABI},
6297 #endif
6298 #endif
6299 {NULL, no_argument, NULL, 0}
6301 size_t md_longopts_size = sizeof (md_longopts);
6304 md_parse_option (c, arg)
6305 int c;
6306 char * arg;
6308 char * str = arg;
6310 switch (c)
6312 #ifdef ARM_BI_ENDIAN
6313 case OPTION_EB:
6314 target_big_endian = 1;
6315 break;
6316 case OPTION_EL:
6317 target_big_endian = 0;
6318 break;
6319 #endif
6321 case 'm':
6322 switch (*str)
6324 case 'f':
6325 if (streq (str, "fpa10"))
6326 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
6327 else if (streq (str, "fpa11"))
6328 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
6329 else if (streq (str, "fpe-old"))
6330 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
6331 else
6332 goto bad;
6333 break;
6335 case 'n':
6336 if (streq (str, "no-fpu"))
6337 cpu_variant &= ~FPU_ALL;
6338 break;
6340 #ifdef OBJ_ELF
6341 case 'o':
6342 if (streq (str, "oabi"))
6343 target_oabi = true;
6344 break;
6345 #endif
6347 case 't':
6348 /* Limit assembler to generating only Thumb instructions: */
6349 if (streq (str, "thumb"))
6351 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
6352 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6353 thumb_mode = 1;
6355 else if (streq (str, "thumb-interwork"))
6357 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCH_V4;
6358 #if defined OBJ_COFF || defined OBJ_ELF
6359 support_interwork = true;
6360 #endif
6362 else
6363 goto bad;
6364 break;
6366 default:
6367 if (streq (str, "all"))
6369 cpu_variant = ARM_ALL | FPU_ALL;
6370 return 1;
6372 #if defined OBJ_COFF || defined OBJ_ELF
6373 if (! strncmp (str, "apcs-", 5))
6375 /* GCC passes on all command line options starting "-mapcs-..."
6376 to us, so we must parse them here. */
6378 str += 5;
6380 if (streq (str, "32"))
6382 uses_apcs_26 = false;
6383 return 1;
6385 else if (streq (str, "26"))
6387 uses_apcs_26 = true;
6388 return 1;
6390 else if (streq (str, "frame"))
6392 /* Stack frames are being generated - does not affect
6393 linkage of code. */
6394 return 1;
6396 else if (streq (str, "stack-check"))
6398 /* Stack checking is being performed - does not affect
6399 linkage, but does require that the functions
6400 __rt_stkovf_split_small and __rt_stkovf_split_big be
6401 present in the final link. */
6403 return 1;
6405 else if (streq (str, "float"))
6407 /* Floating point arguments are being passed in the floating
6408 point registers. This does affect linking, since this
6409 version of the APCS is incompatible with the version that
6410 passes floating points in the integer registers. */
6412 uses_apcs_float = true;
6413 return 1;
6415 else if (streq (str, "reentrant"))
6417 /* Reentrant code has been generated. This does affect
6418 linking, since there is no point in linking reentrant/
6419 position independent code with absolute position code. */
6420 pic_code = true;
6421 return 1;
6424 as_bad (_("Unrecognised APCS switch -m%s"), arg);
6425 return 0;
6427 #endif
6428 /* Strip off optional "arm" */
6429 if (! strncmp (str, "arm", 3))
6430 str += 3;
6432 switch (*str)
6434 case '1':
6435 if (streq (str, "1"))
6436 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6437 else
6438 goto bad;
6439 break;
6441 case '2':
6442 if (streq (str, "2"))
6443 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6444 else if (streq (str, "250"))
6445 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6446 else
6447 goto bad;
6448 break;
6450 case '3':
6451 if (streq (str, "3"))
6452 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6453 else
6454 goto bad;
6455 break;
6457 case '6':
6458 switch (strtol (str, NULL, 10))
6460 case 6:
6461 case 60:
6462 case 600:
6463 case 610:
6464 case 620:
6465 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6466 break;
6467 default:
6468 goto bad;
6470 break;
6472 case '7':
6473 switch (strtol (str, & str, 10)) /* Eat the processor name */
6475 case 7:
6476 case 70:
6477 case 700:
6478 case 710:
6479 case 7100:
6480 case 7500:
6481 break;
6482 default:
6483 goto bad;
6485 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6486 for (; *str; str++)
6488 switch (* str)
6490 case 't':
6491 cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
6492 break;
6494 case 'm':
6495 cpu_variant |= ARM_LONGMUL;
6496 break;
6498 case 'f': /* fe => fp enabled cpu. */
6499 if (str[1] == 'e')
6500 ++ str;
6501 else
6502 goto bad;
6504 case 'c': /* Left over from 710c processor name. */
6505 case 'd': /* Debug */
6506 case 'i': /* Embedded ICE */
6507 /* Included for completeness in ARM processor naming. */
6508 break;
6510 default:
6511 goto bad;
6514 break;
6516 case '8':
6517 if (streq (str, "8") || streq (str, "810"))
6518 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6519 else
6520 goto bad;
6521 break;
6523 case '9':
6524 if (streq (str, "9"))
6525 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6526 else if (streq (str, "920"))
6527 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
6528 else if (streq (str, "920t"))
6529 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6530 else if (streq (str, "9tdmi"))
6531 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6532 else
6533 goto bad;
6534 break;
6536 case 's':
6537 if (streq (str, "strongarm")
6538 || streq (str, "strongarm110")
6539 || streq (str, "strongarm1100"))
6540 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6541 else
6542 goto bad;
6543 break;
6545 case 'v':
6546 /* Select variant based on architecture rather than processor */
6547 switch (*++str)
6549 case '2':
6550 switch (*++str)
6552 case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
6553 case 0: cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
6554 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6556 break;
6558 case '3':
6559 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6561 switch (*++str)
6563 case 'm': cpu_variant |= ARM_LONGMUL; break;
6564 case 0: break;
6565 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6567 break;
6569 case '4':
6570 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4;
6572 switch (*++str)
6574 case 't': cpu_variant |= ARM_THUMB; break;
6575 case 0: break;
6576 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6578 break;
6580 case '5':
6581 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
6583 switch (*++str)
6585 case 't': cpu_variant |= ARM_THUMB; break;
6586 case 0: break;
6587 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6589 break;
6591 default:
6592 as_bad (_("Invalid architecture variant -m%s"), arg);
6593 break;
6595 break;
6597 default:
6598 bad:
6599 as_bad (_("Invalid processor variant -m%s"), arg);
6600 return 0;
6603 break;
6605 #if defined OBJ_ELF || defined OBJ_COFF
6606 case 'k':
6607 pic_code = 1;
6608 break;
6609 #endif
6611 default:
6612 return 0;
6615 return 1;
6618 void
6619 md_show_usage (fp)
6620 FILE * fp;
6622 fprintf (fp,
6623 _("\
6624 ARM Specific Assembler Options:\n\
6625 -m[arm][<processor name>] select processor variant\n\
6626 -m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\
6627 -mthumb only allow Thumb instructions\n\
6628 -mthumb-interwork mark the assembled code as supporting interworking\n\
6629 -mall allow any instruction\n\
6630 -mfpa10, -mfpa11 select floating point architecture\n\
6631 -mfpe-old don't allow floating-point multiple instructions\n\
6632 -mno-fpu don't allow any floating-point instructions.\n"));
6633 fprintf (fp,
6634 _("\
6635 -k generate PIC code.\n"));
6636 #if defined OBJ_COFF || defined OBJ_ELF
6637 fprintf (fp,
6638 _("\
6639 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6640 fprintf (fp,
6641 _("\
6642 -mapcs-float floating point args are passed in FP regs\n"));
6643 fprintf (fp,
6644 _("\
6645 -mapcs-reentrant the code is position independent/reentrant\n"));
6646 #endif
6647 #ifdef OBJ_ELF
6648 fprintf (fp,
6649 _("\
6650 -moabi support the old ELF ABI\n"));
6651 #endif
6652 #ifdef ARM_BI_ENDIAN
6653 fprintf (fp,
6654 _("\
6655 -EB assemble code for a big endian cpu\n\
6656 -EL assemble code for a little endian cpu\n"));
6657 #endif
6660 /* We need to be able to fix up arbitrary expressions in some statements.
6661 This is so that we can handle symbols that are an arbitrary distance from
6662 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6663 which returns part of an address in a form which will be valid for
6664 a data instruction. We do this by pushing the expression into a symbol
6665 in the expr_section, and creating a fix for that. */
6667 static void
6668 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6669 fragS * frag;
6670 int where;
6671 short int size;
6672 expressionS * exp;
6673 int pc_rel;
6674 int reloc;
6676 fixS * new_fix;
6677 arm_fix_data * arm_data;
6679 switch (exp->X_op)
6681 case O_constant:
6682 case O_symbol:
6683 case O_add:
6684 case O_subtract:
6685 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6686 break;
6688 default:
6689 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6690 pc_rel, reloc);
6691 break;
6694 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6695 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
6696 new_fix->tc_fix_data = (PTR) arm_data;
6697 arm_data->thumb_mode = thumb_mode;
6699 return;
6703 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6704 void
6705 cons_fix_new_arm (frag, where, size, exp)
6706 fragS * frag;
6707 int where;
6708 int size;
6709 expressionS * exp;
6711 bfd_reloc_code_real_type type;
6712 int pcrel = 0;
6714 /* Pick a reloc ...
6716 * @@ Should look at CPU word size.
6718 switch (size)
6720 case 2:
6721 type = BFD_RELOC_16;
6722 break;
6723 case 4:
6724 default:
6725 type = BFD_RELOC_32;
6726 break;
6727 case 8:
6728 type = BFD_RELOC_64;
6729 break;
6732 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
6735 /* A good place to do this, although this was probably not intended
6736 for this kind of use. We need to dump the literal pool before
6737 references are made to a null symbol pointer. */
6738 void
6739 arm_cleanup ()
6741 if (current_poolP == NULL)
6742 return;
6744 subseg_set (text_section, 0); /* Put it at the end of text section. */
6745 s_ltorg (0);
6746 listing_prev_line ();
6749 void
6750 arm_start_line_hook ()
6752 last_label_seen = NULL;
6755 void
6756 arm_frob_label (sym)
6757 symbolS * sym;
6759 last_label_seen = sym;
6761 ARM_SET_THUMB (sym, thumb_mode);
6763 #if defined OBJ_COFF || defined OBJ_ELF
6764 ARM_SET_INTERWORK (sym, support_interwork);
6765 #endif
6767 if (label_is_thumb_function_name)
6769 /* When the address of a Thumb function is taken the bottom
6770 bit of that address should be set. This will allow
6771 interworking between Arm and Thumb functions to work
6772 correctly. */
6774 THUMB_SET_FUNC (sym, 1);
6776 label_is_thumb_function_name = false;
6780 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6781 ARM ones. */
6783 void
6784 arm_adjust_symtab ()
6786 #ifdef OBJ_COFF
6787 symbolS * sym;
6789 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6791 if (ARM_IS_THUMB (sym))
6793 if (THUMB_IS_FUNC (sym))
6795 /* Mark the symbol as a Thumb function. */
6796 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
6797 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6798 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6800 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6801 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6802 else
6803 as_bad (_("%s: unexpected function type: %d"),
6804 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6806 else switch (S_GET_STORAGE_CLASS (sym))
6808 case C_EXT:
6809 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6810 break;
6811 case C_STAT:
6812 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6813 break;
6814 case C_LABEL:
6815 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6816 break;
6817 default: /* do nothing */
6818 break;
6822 if (ARM_IS_INTERWORK (sym))
6823 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
6825 #endif
6826 #ifdef OBJ_ELF
6827 symbolS * sym;
6828 elf_symbol_type * elf_sym;
6829 char bind;
6831 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6833 if (ARM_IS_THUMB (sym))
6835 if (THUMB_IS_FUNC (sym))
6837 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
6838 bind = ELF_ST_BIND (elf_sym);
6839 elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC);
6843 #endif
6847 arm_data_in_code ()
6849 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
6851 *input_line_pointer = '/';
6852 input_line_pointer += 5;
6853 *input_line_pointer = 0;
6854 return 1;
6857 return 0;
6860 char *
6861 arm_canonicalize_symbol_name (name)
6862 char * name;
6864 int len;
6866 if (thumb_mode && (len = strlen (name)) > 5
6867 && streq (name + len - 5, "/data"))
6868 *(name + len - 5) = 0;
6870 return name;
6873 boolean
6874 arm_validate_fix (fixP)
6875 fixS * fixP;
6877 /* If the destination of the branch is a defined symbol which does not have
6878 the THUMB_FUNC attribute, then we must be calling a function which has
6879 the (interfacearm) attribute. We look for the Thumb entry point to that
6880 function and change the branch to refer to that function instead. */
6881 if ( fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
6882 && fixP->fx_addsy != NULL
6883 && S_IS_DEFINED (fixP->fx_addsy)
6884 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6886 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6887 return true;
6890 return false;
6893 #ifdef OBJ_ELF
6894 /* Relocations against Thumb function names must be left unadjusted,
6895 so that the linker can use this information to correctly set the
6896 bottom bit of their addresses. The MIPS version of this function
6897 also prevents relocations that are mips-16 specific, but I do not
6898 know why it does this.
6900 FIXME:
6901 There is one other problem that ought to be addressed here, but
6902 which currently is not: Taking the address of a label (rather
6903 than a function) and then later jumping to that address. Such
6904 addresses also ought to have their bottom bit set (assuming that
6905 they reside in Thumb code), but at the moment they will not. */
6907 boolean
6908 arm_fix_adjustable (fixP)
6909 fixS * fixP;
6911 if (fixP->fx_addsy == NULL)
6912 return 1;
6914 /* Prevent all adjustments to global symbols. */
6915 if (S_IS_EXTERN (fixP->fx_addsy))
6916 return 0;
6918 if (S_IS_WEAK (fixP->fx_addsy))
6919 return 0;
6921 if (THUMB_IS_FUNC (fixP->fx_addsy)
6922 && fixP->fx_subsy == NULL)
6923 return 0;
6925 /* We need the symbol name for the VTABLE entries */
6926 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6927 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6928 return 0;
6930 return 1;
6933 const char *
6934 elf32_arm_target_format ()
6936 if (target_big_endian)
6937 if (target_oabi)
6938 return "elf32-bigarm-oabi";
6939 else
6940 return "elf32-bigarm";
6941 else
6942 if (target_oabi)
6943 return "elf32-littlearm-oabi";
6944 else
6945 return "elf32-littlearm";
6948 void
6949 armelf_frob_symbol (symp, puntp)
6950 symbolS * symp;
6951 int * puntp;
6953 elf_frob_symbol (symp, puntp);
6957 arm_force_relocation (fixp)
6958 struct fix * fixp;
6960 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6961 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
6962 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
6963 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
6964 return 1;
6966 return 0;
6969 static bfd_reloc_code_real_type
6970 arm_parse_reloc ()
6972 char id[16];
6973 char * ip;
6974 int i;
6975 static struct
6977 char * str;
6978 int len;
6979 bfd_reloc_code_real_type reloc;
6981 reloc_map[] =
6983 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
6984 MAP ("(got)", BFD_RELOC_ARM_GOT32),
6985 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
6986 /* ScottB: Jan 30, 1998 */
6987 /* Added support for parsing "var(PLT)" branch instructions */
6988 /* generated by GCC for PLT relocs */
6989 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
6990 { NULL, 0, BFD_RELOC_UNUSED }
6991 #undef MAP
6994 for (i = 0, ip = input_line_pointer;
6995 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
6996 i++, ip++)
6997 id[i] = tolower (*ip);
6999 for (i = 0; reloc_map[i].str; i++)
7000 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
7001 break;
7003 input_line_pointer += reloc_map[i].len;
7005 return reloc_map[i].reloc;
7008 static void
7009 s_arm_elf_cons (nbytes)
7010 int nbytes;
7012 expressionS exp;
7014 #ifdef md_flush_pending_output
7015 md_flush_pending_output ();
7016 #endif
7018 if (is_it_end_of_statement ())
7020 demand_empty_rest_of_line ();
7021 return;
7024 #ifdef md_cons_align
7025 md_cons_align (nbytes);
7026 #endif
7030 bfd_reloc_code_real_type reloc;
7032 expression (& exp);
7034 if (exp.X_op == O_symbol
7035 && * input_line_pointer == '('
7036 && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
7038 reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
7039 int size = bfd_get_reloc_size (howto);
7041 if (size > nbytes)
7042 as_bad ("%s relocations do not fit in %d bytes", howto->name, nbytes);
7043 else
7045 register char * p = frag_more ((int) nbytes);
7046 int offset = nbytes - size;
7048 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
7049 & exp, 0, reloc);
7052 else
7053 emit_expr (& exp, (unsigned int) nbytes);
7055 while (*input_line_pointer++ == ',');
7057 input_line_pointer--; /* Put terminator back into stream. */
7058 demand_empty_rest_of_line ();
7061 #endif /* OBJ_ELF */