Add support for -marm720 command line switch
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
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)
5
6 This file is part of GAS, the GNU Assembler.
7
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.
12
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.
17
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. */
22
23 #include <ctype.h>
24 #include <string.h>
25 #define NO_RELOC 0
26 #include "as.h"
27
28 /* need TARGET_CPU */
29 #include "config.h"
30 #include "subsegs.h"
31 #include "obstack.h"
32 #include "symbols.h"
33 #include "listing.h"
34
35 #ifdef OBJ_ELF
36 #include "elf/arm.h"
37 #endif
38
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
49
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 */
55 #define ARM_EXT_V5E 0x00000200 /* "El Segundo" */
56
57 /* Architectures are the sum of the base and extensions */
58 #define ARM_ARCH_V4 (ARM_7 | ARM_LONGMUL | ARM_HALFWORD)
59 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_THUMB)
60 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5 )
61 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_THUMB)
62
63 /* Some useful combinations: */
64 #define ARM_ANY 0x00ffffff
65 #define ARM_2UP (ARM_ANY - ARM_1)
66 #define ARM_ALL ARM_2UP /* Not arm1 only */
67 #define ARM_3UP 0x00fffffc
68 #define ARM_6UP 0x00fffff8 /* Includes ARM7 */
69
70 #define FPU_CORE 0x80000000
71 #define FPU_FPA10 0x40000000
72 #define FPU_FPA11 0x40000000
73 #define FPU_NONE 0
74
75 /* Some useful combinations */
76 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY */
77 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core */
78
79
80 #ifndef CPU_DEFAULT
81 #if defined __thumb__
82 #define CPU_DEFAULT (ARM_ARCH_V4 | ARM_THUMB)
83 #else
84 #define CPU_DEFAULT ARM_ALL
85 #endif
86 #endif
87
88 #ifndef FPU_DEFAULT
89 #define FPU_DEFAULT FPU_ALL
90 #endif
91
92 #define streq(a, b) (strcmp (a, b) == 0)
93 #define skip_whitespace(str) while (* (str) == ' ') ++ (str)
94
95 static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
96 static int target_oabi = 0;
97
98 #if defined OBJ_COFF || defined OBJ_ELF
99 /* Flags stored in private area of BFD structure */
100 static boolean uses_apcs_26 = false;
101 static boolean support_interwork = false;
102 static boolean uses_apcs_float = false;
103 static boolean pic_code = false;
104 #endif
105
106 /* This array holds the chars that always start a comment. If the
107 pre-processor is disabled, these aren't very useful */
108 CONST char comment_chars[] = "@";
109
110 /* This array holds the chars that only start a comment at the beginning of
111 a line. If the line seems to have the form '# 123 filename'
112 .line and .file directives will appear in the pre-processed output */
113 /* Note that input_file.c hand checks for '#' at the beginning of the
114 first line of the input file. This is because the compiler outputs
115 #NO_APP at the beginning of its output. */
116 /* Also note that comments like this one will always work. */
117 CONST char line_comment_chars[] = "#";
118
119 #ifdef TE_LINUX
120 CONST char line_separator_chars[] = ";";
121 #else
122 CONST char line_separator_chars[] = "";
123 #endif
124
125 /* Chars that can be used to separate mant from exp in floating point nums */
126 CONST char EXP_CHARS[] = "eE";
127
128 /* Chars that mean this number is a floating point constant */
129 /* As in 0f12.456 */
130 /* or 0d1.2345e12 */
131
132 CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
133
134 /* Prefix characters that indicate the start of an immediate
135 value. */
136 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
137
138 #ifdef OBJ_ELF
139 symbolS * GOT_symbol; /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
140 #endif
141
142 CONST int md_reloc_size = 8; /* Size of relocation record */
143
144 static int thumb_mode = 0; /* 0: assemble for ARM, 1: assemble for Thumb,
145 2: assemble for Thumb even though target cpu
146 does not support thumb instructions */
147 typedef struct arm_fix
148 {
149 int thumb_mode;
150 } arm_fix_data;
151
152 struct arm_it
153 {
154 CONST char * error;
155 unsigned long instruction;
156 int suffix;
157 int size;
158 struct
159 {
160 bfd_reloc_code_real_type type;
161 expressionS exp;
162 int pc_rel;
163 } reloc;
164 };
165
166 struct arm_it inst;
167
168 struct asm_shift
169 {
170 CONST char * template;
171 unsigned long value;
172 };
173
174 static CONST struct asm_shift shift[] =
175 {
176 {"asl", 0},
177 {"lsl", 0},
178 {"lsr", 0x00000020},
179 {"asr", 0x00000040},
180 {"ror", 0x00000060},
181 {"rrx", 0x00000060},
182 {"ASL", 0},
183 {"LSL", 0},
184 {"LSR", 0x00000020},
185 {"ASR", 0x00000040},
186 {"ROR", 0x00000060},
187 {"RRX", 0x00000060}
188 };
189
190 #define NO_SHIFT_RESTRICT 1
191 #define SHIFT_RESTRICT 0
192
193 #define NUM_FLOAT_VALS 8
194
195 CONST char * fp_const[] =
196 {
197 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
198 };
199
200 /* Number of littlenums required to hold an extended precision number */
201 #define MAX_LITTLENUMS 6
202
203 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
204
205 #define FAIL (-1)
206 #define SUCCESS (0)
207
208 #define SUFF_S 1
209 #define SUFF_D 2
210 #define SUFF_E 3
211 #define SUFF_P 4
212
213 #define CP_T_X 0x00008000
214 #define CP_T_Y 0x00400000
215 #define CP_T_Pre 0x01000000
216 #define CP_T_UD 0x00800000
217 #define CP_T_WB 0x00200000
218
219 #define CONDS_BIT (0x00100000)
220 #define LOAD_BIT (0x00100000)
221 #define TRANS_BIT (0x00200000)
222
223 struct asm_cond
224 {
225 CONST char * template;
226 unsigned long value;
227 };
228
229 /* This is to save a hash look-up in the common case */
230 #define COND_ALWAYS 0xe0000000
231
232 static CONST struct asm_cond conds[] =
233 {
234 {"eq", 0x00000000},
235 {"ne", 0x10000000},
236 {"cs", 0x20000000}, {"hs", 0x20000000},
237 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
238 {"mi", 0x40000000},
239 {"pl", 0x50000000},
240 {"vs", 0x60000000},
241 {"vc", 0x70000000},
242 {"hi", 0x80000000},
243 {"ls", 0x90000000},
244 {"ge", 0xa0000000},
245 {"lt", 0xb0000000},
246 {"gt", 0xc0000000},
247 {"le", 0xd0000000},
248 {"al", 0xe0000000},
249 {"nv", 0xf0000000}
250 };
251
252 /* Warning: If the top bit of the set_bits is set, then the standard
253 instruction bitmask is ignored, and the new bitmask is taken from
254 the set_bits: */
255 struct asm_flg
256 {
257 CONST char * template; /* Basic flag string */
258 unsigned long set_bits; /* Bits to set */
259 };
260
261 static CONST struct asm_flg s_flag[] =
262 {
263 {"s", CONDS_BIT},
264 {NULL, 0}
265 };
266
267 static CONST struct asm_flg ldr_flags[] =
268 {
269 {"b", 0x00400000},
270 {"t", TRANS_BIT},
271 {"bt", 0x00400000 | TRANS_BIT},
272 {"h", 0x801000b0},
273 {"sh", 0x801000f0},
274 {"sb", 0x801000d0},
275 {NULL, 0}
276 };
277
278 static CONST struct asm_flg str_flags[] =
279 {
280 {"b", 0x00400000},
281 {"t", TRANS_BIT},
282 {"bt", 0x00400000 | TRANS_BIT},
283 {"h", 0x800000b0},
284 {NULL, 0}
285 };
286
287 static CONST struct asm_flg byte_flag[] =
288 {
289 {"b", 0x00400000},
290 {NULL, 0}
291 };
292
293 static CONST struct asm_flg cmp_flags[] =
294 {
295 {"s", CONDS_BIT},
296 {"p", 0x0010f000},
297 {NULL, 0}
298 };
299
300 static CONST struct asm_flg ldm_flags[] =
301 {
302 {"ed", 0x01800000},
303 {"fd", 0x00800000},
304 {"ea", 0x01000000},
305 {"fa", 0x08000000},
306 {"ib", 0x01800000},
307 {"ia", 0x00800000},
308 {"db", 0x01000000},
309 {"da", 0x08000000},
310 {NULL, 0}
311 };
312
313 static CONST struct asm_flg stm_flags[] =
314 {
315 {"ed", 0x08000000},
316 {"fd", 0x01000000},
317 {"ea", 0x00800000},
318 {"fa", 0x01800000},
319 {"ib", 0x01800000},
320 {"ia", 0x00800000},
321 {"db", 0x01000000},
322 {"da", 0x08000000},
323 {NULL, 0}
324 };
325
326 static CONST struct asm_flg lfm_flags[] =
327 {
328 {"fd", 0x00800000},
329 {"ea", 0x01000000},
330 {NULL, 0}
331 };
332
333 static CONST struct asm_flg sfm_flags[] =
334 {
335 {"fd", 0x01000000},
336 {"ea", 0x00800000},
337 {NULL, 0}
338 };
339
340 static CONST struct asm_flg round_flags[] =
341 {
342 {"p", 0x00000020},
343 {"m", 0x00000040},
344 {"z", 0x00000060},
345 {NULL, 0}
346 };
347
348 /* The implementation of the FIX instruction is broken on some assemblers,
349 in that it accepts a precision specifier as well as a rounding specifier,
350 despite the fact that this is meaningless. To be more compatible, we
351 accept it as well, though of course it does not set any bits. */
352 static CONST struct asm_flg fix_flags[] =
353 {
354 {"p", 0x00000020},
355 {"m", 0x00000040},
356 {"z", 0x00000060},
357 {"sp", 0x00000020},
358 {"sm", 0x00000040},
359 {"sz", 0x00000060},
360 {"dp", 0x00000020},
361 {"dm", 0x00000040},
362 {"dz", 0x00000060},
363 {"ep", 0x00000020},
364 {"em", 0x00000040},
365 {"ez", 0x00000060},
366 {NULL, 0}
367 };
368
369 static CONST struct asm_flg except_flag[] =
370 {
371 {"e", 0x00400000},
372 {NULL, 0}
373 };
374
375 static CONST struct asm_flg cplong_flag[] =
376 {
377 {"l", 0x00400000},
378 {NULL, 0}
379 };
380
381 struct asm_psr
382 {
383 CONST char * template;
384 unsigned long number;
385 };
386
387 #define PSR_FIELD_MASK 0x000f0000
388
389 #define PSR_FLAGS 0x00080000
390 #define PSR_CONTROL 0x00010000 /* Undocumented instruction, its use is discouraged by ARM */
391 #define PSR_ALL 0x00090000
392
393 #define CPSR_ALL 0
394 #define SPSR_ALL 1
395 #define CPSR_FLG 2
396 #define SPSR_FLG 3
397 #define CPSR_CTL 4
398 #define SPSR_CTL 5
399
400 static CONST struct asm_psr psrs[] =
401 {
402 /* Valid <psr>'s */
403 {"cpsr", CPSR_ALL},
404 {"cpsr_all", CPSR_ALL},
405 {"spsr", SPSR_ALL},
406 {"spsr_all", SPSR_ALL},
407
408 /* Valid <psrf>'s */
409 {"cpsr_flg", CPSR_FLG},
410 {"spsr_flg", SPSR_FLG},
411
412 /* Valid <psrc>'s */
413 {"cpsr_c", CPSR_CTL},
414 {"cpsr_ctl", CPSR_CTL},
415 {"spsr_c", SPSR_CTL},
416 {"spsr_ctl", SPSR_CTL}
417 };
418
419 /* Functions called by parser */
420 /* ARM instructions */
421 static void do_arit PARAMS ((char *, unsigned long));
422 static void do_cmp PARAMS ((char *, unsigned long));
423 static void do_mov PARAMS ((char *, unsigned long));
424 static void do_ldst PARAMS ((char *, unsigned long));
425 static void do_ldmstm PARAMS ((char *, unsigned long));
426 static void do_branch PARAMS ((char *, unsigned long));
427 static void do_swi PARAMS ((char *, unsigned long));
428 /* Pseudo Op codes */
429 static void do_adr PARAMS ((char *, unsigned long));
430 static void do_adrl PARAMS ((char *, unsigned long));
431 static void do_nop PARAMS ((char *, unsigned long));
432 /* ARM 2 */
433 static void do_mul PARAMS ((char *, unsigned long));
434 static void do_mla PARAMS ((char *, unsigned long));
435 /* ARM 3 */
436 static void do_swap PARAMS ((char *, unsigned long));
437 /* ARM 6 */
438 static void do_msr PARAMS ((char *, unsigned long));
439 static void do_mrs PARAMS ((char *, unsigned long));
440 /* ARM 7M */
441 static void do_mull PARAMS ((char *, unsigned long));
442 /* ARM THUMB */
443 static void do_bx PARAMS ((char *, unsigned long));
444
445
446 /* Coprocessor Instructions */
447 static void do_cdp PARAMS ((char *, unsigned long));
448 static void do_lstc PARAMS ((char *, unsigned long));
449 static void do_co_reg PARAMS ((char *, unsigned long));
450 static void do_fp_ctrl PARAMS ((char *, unsigned long));
451 static void do_fp_ldst PARAMS ((char *, unsigned long));
452 static void do_fp_ldmstm PARAMS ((char *, unsigned long));
453 static void do_fp_dyadic PARAMS ((char *, unsigned long));
454 static void do_fp_monadic PARAMS ((char *, unsigned long));
455 static void do_fp_cmp PARAMS ((char *, unsigned long));
456 static void do_fp_from_reg PARAMS ((char *, unsigned long));
457 static void do_fp_to_reg PARAMS ((char *, unsigned long));
458
459 static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *, int, int));
460 static int arm_reg_parse PARAMS ((char **));
461 static int arm_psr_parse PARAMS ((char **));
462 static void symbol_locate PARAMS ((symbolS *, CONST char *, segT, valueT, fragS *));
463 static int add_to_lit_pool PARAMS ((void));
464 static unsigned validate_immediate PARAMS ((unsigned));
465 static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *));
466 static int validate_offset_imm PARAMS ((unsigned int, int));
467 static void opcode_select PARAMS ((int));
468 static void end_of_line PARAMS ((char *));
469 static int reg_required_here PARAMS ((char **, int));
470 static int psr_required_here PARAMS ((char **, int, int));
471 static int co_proc_number PARAMS ((char **));
472 static int cp_opc_expr PARAMS ((char **, int, int));
473 static int cp_reg_required_here PARAMS ((char **, int));
474 static int fp_reg_required_here PARAMS ((char **, int));
475 static int cp_address_offset PARAMS ((char **));
476 static int cp_address_required_here PARAMS ((char **));
477 static int my_get_float_expression PARAMS ((char **));
478 static int skip_past_comma PARAMS ((char **));
479 static int walk_no_bignums PARAMS ((symbolS *));
480 static int negate_data_op PARAMS ((unsigned long *, unsigned long));
481 static int data_op2 PARAMS ((char **));
482 static int fp_op2 PARAMS ((char **));
483 static long reg_list PARAMS ((char **));
484 static void thumb_load_store PARAMS ((char *, int, int));
485 static int decode_shift PARAMS ((char **, int));
486 static int ldst_extend PARAMS ((char **, int));
487 static void thumb_add_sub PARAMS ((char *, int));
488 static void insert_reg PARAMS ((int));
489 static void thumb_shift PARAMS ((char *, int));
490 static void thumb_mov_compare PARAMS ((char *, int));
491 static void set_constant_flonums PARAMS ((void));
492 static valueT md_chars_to_number PARAMS ((char *, int));
493 static void insert_reg_alias PARAMS ((char *, int));
494 static void output_inst PARAMS ((void));
495 #ifdef OBJ_ELF
496 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
497 #endif
498
499 /* ARM instructions take 4bytes in the object file, Thumb instructions
500 take 2: */
501 #define INSN_SIZE 4
502
503 /* LONGEST_INST is the longest basic instruction name without conditions or
504 * flags.
505 * ARM7M has 4 of length 5
506 */
507
508 #define LONGEST_INST 5
509
510
511 struct asm_opcode
512 {
513 CONST char * template; /* Basic string to match */
514 unsigned long value; /* Basic instruction code */
515
516 /* Compulsory suffix that must follow conds. If "", then the
517 instruction is not conditional and must have no suffix. */
518 CONST char * comp_suffix;
519
520 CONST struct asm_flg * flags; /* Bits to toggle if flag 'n' set */
521 unsigned long variants; /* Which CPU variants this exists for */
522 /* Function to call to parse args */
523 void (* parms) PARAMS ((char *, unsigned long));
524 };
525
526 static CONST struct asm_opcode insns[] =
527 {
528 /* ARM Instructions */
529 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
530 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
531 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
532 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
533 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
534 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
535 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
536 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
537 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
538 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
539 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
540 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
541 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
542 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
543 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
544 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
545 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
546 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
547 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
548 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
549 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
550 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
551 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
552
553 /* Pseudo ops */
554 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
555 {"adrl", 0x028f0000, NULL, NULL, ARM_ANY, do_adrl},
556 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
557
558 /* ARM 2 multiplies */
559 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
560 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
561
562 /* ARM 3 - swp instructions */
563 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
564
565 /* ARM 6 Coprocessor instructions */
566 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
567 {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr},
568 /* ScottB: our code uses 0x0128f000 for msr.
569 NickC: but this is wrong because the bits 16 and 19 are handled
570 by the PSR_xxx defines above. */
571
572 /* ARM 7M long multiplies - need signed/unsigned flags! */
573 {"smull", 0x00c00090, NULL, s_flag, ARM_LONGMUL, do_mull},
574 {"umull", 0x00800090, NULL, s_flag, ARM_LONGMUL, do_mull},
575 {"smlal", 0x00e00090, NULL, s_flag, ARM_LONGMUL, do_mull},
576 {"umlal", 0x00a00090, NULL, s_flag, ARM_LONGMUL, do_mull},
577
578 /* ARM THUMB interworking */
579 {"bx", 0x012fff10, NULL, NULL, ARM_THUMB, do_bx},
580
581 /* Floating point instructions */
582 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
583 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
584 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
585 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
586 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
587 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
588 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
589 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
590 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
591 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
592 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
593 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
594 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
595 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
596 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
597 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
598 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
599 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
600 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
601 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
602 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
603 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
604 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
605 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
606 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
607 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
608 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
609 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
610 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
611 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
612 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
613 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
614 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
615 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
616 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
617 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
618 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
619 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
620 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
621 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
622 be an optional suffix, but part of the instruction. To be compatible,
623 we accept either. */
624 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
625 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
626 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
627 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
628
629 /* Generic copressor instructions */
630 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
631 {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc},
632 {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc},
633 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
634 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
635 };
636
637 /* defines for various bits that we will want to toggle */
638
639 #define INST_IMMEDIATE 0x02000000
640 #define OFFSET_REG 0x02000000
641 #define HWOFFSET_IMM 0x00400000
642 #define SHIFT_BY_REG 0x00000010
643 #define PRE_INDEX 0x01000000
644 #define INDEX_UP 0x00800000
645 #define WRITE_BACK 0x00200000
646 #define LDM_TYPE_2_OR_3 0x00400000
647
648 #define LITERAL_MASK 0xf000f000
649 #define COND_MASK 0xf0000000
650 #define OPCODE_MASK 0xfe1fffff
651 #define DATA_OP_SHIFT 21
652
653 /* Codes to distinguish the arithmetic instructions */
654
655 #define OPCODE_AND 0
656 #define OPCODE_EOR 1
657 #define OPCODE_SUB 2
658 #define OPCODE_RSB 3
659 #define OPCODE_ADD 4
660 #define OPCODE_ADC 5
661 #define OPCODE_SBC 6
662 #define OPCODE_RSC 7
663 #define OPCODE_TST 8
664 #define OPCODE_TEQ 9
665 #define OPCODE_CMP 10
666 #define OPCODE_CMN 11
667 #define OPCODE_ORR 12
668 #define OPCODE_MOV 13
669 #define OPCODE_BIC 14
670 #define OPCODE_MVN 15
671
672 static void do_t_nop PARAMS ((char *));
673 static void do_t_arit PARAMS ((char *));
674 static void do_t_add PARAMS ((char *));
675 static void do_t_asr PARAMS ((char *));
676 static void do_t_branch9 PARAMS ((char *));
677 static void do_t_branch12 PARAMS ((char *));
678 static void do_t_branch23 PARAMS ((char *));
679 static void do_t_bx PARAMS ((char *));
680 static void do_t_compare PARAMS ((char *));
681 static void do_t_ldmstm PARAMS ((char *));
682 static void do_t_ldr PARAMS ((char *));
683 static void do_t_ldrb PARAMS ((char *));
684 static void do_t_ldrh PARAMS ((char *));
685 static void do_t_lds PARAMS ((char *));
686 static void do_t_lsl PARAMS ((char *));
687 static void do_t_lsr PARAMS ((char *));
688 static void do_t_mov PARAMS ((char *));
689 static void do_t_push_pop PARAMS ((char *));
690 static void do_t_str PARAMS ((char *));
691 static void do_t_strb PARAMS ((char *));
692 static void do_t_strh PARAMS ((char *));
693 static void do_t_sub PARAMS ((char *));
694 static void do_t_swi PARAMS ((char *));
695 static void do_t_adr PARAMS ((char *));
696
697 #define T_OPCODE_MUL 0x4340
698 #define T_OPCODE_TST 0x4200
699 #define T_OPCODE_CMN 0x42c0
700 #define T_OPCODE_NEG 0x4240
701 #define T_OPCODE_MVN 0x43c0
702
703 #define T_OPCODE_ADD_R3 0x1800
704 #define T_OPCODE_SUB_R3 0x1a00
705 #define T_OPCODE_ADD_HI 0x4400
706 #define T_OPCODE_ADD_ST 0xb000
707 #define T_OPCODE_SUB_ST 0xb080
708 #define T_OPCODE_ADD_SP 0xa800
709 #define T_OPCODE_ADD_PC 0xa000
710 #define T_OPCODE_ADD_I8 0x3000
711 #define T_OPCODE_SUB_I8 0x3800
712 #define T_OPCODE_ADD_I3 0x1c00
713 #define T_OPCODE_SUB_I3 0x1e00
714
715 #define T_OPCODE_ASR_R 0x4100
716 #define T_OPCODE_LSL_R 0x4080
717 #define T_OPCODE_LSR_R 0x40c0
718 #define T_OPCODE_ASR_I 0x1000
719 #define T_OPCODE_LSL_I 0x0000
720 #define T_OPCODE_LSR_I 0x0800
721
722 #define T_OPCODE_MOV_I8 0x2000
723 #define T_OPCODE_CMP_I8 0x2800
724 #define T_OPCODE_CMP_LR 0x4280
725 #define T_OPCODE_MOV_HR 0x4600
726 #define T_OPCODE_CMP_HR 0x4500
727
728 #define T_OPCODE_LDR_PC 0x4800
729 #define T_OPCODE_LDR_SP 0x9800
730 #define T_OPCODE_STR_SP 0x9000
731 #define T_OPCODE_LDR_IW 0x6800
732 #define T_OPCODE_STR_IW 0x6000
733 #define T_OPCODE_LDR_IH 0x8800
734 #define T_OPCODE_STR_IH 0x8000
735 #define T_OPCODE_LDR_IB 0x7800
736 #define T_OPCODE_STR_IB 0x7000
737 #define T_OPCODE_LDR_RW 0x5800
738 #define T_OPCODE_STR_RW 0x5000
739 #define T_OPCODE_LDR_RH 0x5a00
740 #define T_OPCODE_STR_RH 0x5200
741 #define T_OPCODE_LDR_RB 0x5c00
742 #define T_OPCODE_STR_RB 0x5400
743
744 #define T_OPCODE_PUSH 0xb400
745 #define T_OPCODE_POP 0xbc00
746
747 #define T_OPCODE_BRANCH 0xe7fe
748
749 static int thumb_reg PARAMS ((char ** str, int hi_lo));
750
751 #define THUMB_SIZE 2 /* Size of thumb instruction */
752 #define THUMB_REG_LO 0x1
753 #define THUMB_REG_HI 0x2
754 #define THUMB_REG_ANY 0x3
755
756 #define THUMB_H1 0x0080
757 #define THUMB_H2 0x0040
758
759 #define THUMB_ASR 0
760 #define THUMB_LSL 1
761 #define THUMB_LSR 2
762
763 #define THUMB_MOVE 0
764 #define THUMB_COMPARE 1
765
766 #define THUMB_LOAD 0
767 #define THUMB_STORE 1
768
769 #define THUMB_PP_PC_LR 0x0100
770
771 /* These three are used for immediate shifts, do not alter */
772 #define THUMB_WORD 2
773 #define THUMB_HALFWORD 1
774 #define THUMB_BYTE 0
775
776 struct thumb_opcode
777 {
778 CONST char * template; /* Basic string to match */
779 unsigned long value; /* Basic instruction code */
780 int size;
781 unsigned long variants; /* Which CPU variants this exists for */
782 void (* parms) PARAMS ((char *)); /* Function to call to parse args */
783 };
784
785 static CONST struct thumb_opcode tinsns[] =
786 {
787 {"adc", 0x4140, 2, ARM_THUMB, do_t_arit},
788 {"add", 0x0000, 2, ARM_THUMB, do_t_add},
789 {"and", 0x4000, 2, ARM_THUMB, do_t_arit},
790 {"asr", 0x0000, 2, ARM_THUMB, do_t_asr},
791 {"b", T_OPCODE_BRANCH, 2, ARM_THUMB, do_t_branch12},
792 {"beq", 0xd0fe, 2, ARM_THUMB, do_t_branch9},
793 {"bne", 0xd1fe, 2, ARM_THUMB, do_t_branch9},
794 {"bcs", 0xd2fe, 2, ARM_THUMB, do_t_branch9},
795 {"bhs", 0xd2fe, 2, ARM_THUMB, do_t_branch9},
796 {"bcc", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
797 {"bul", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
798 {"blo", 0xd3fe, 2, ARM_THUMB, do_t_branch9},
799 {"bmi", 0xd4fe, 2, ARM_THUMB, do_t_branch9},
800 {"bpl", 0xd5fe, 2, ARM_THUMB, do_t_branch9},
801 {"bvs", 0xd6fe, 2, ARM_THUMB, do_t_branch9},
802 {"bvc", 0xd7fe, 2, ARM_THUMB, do_t_branch9},
803 {"bhi", 0xd8fe, 2, ARM_THUMB, do_t_branch9},
804 {"bls", 0xd9fe, 2, ARM_THUMB, do_t_branch9},
805 {"bge", 0xdafe, 2, ARM_THUMB, do_t_branch9},
806 {"blt", 0xdbfe, 2, ARM_THUMB, do_t_branch9},
807 {"bgt", 0xdcfe, 2, ARM_THUMB, do_t_branch9},
808 {"ble", 0xddfe, 2, ARM_THUMB, do_t_branch9},
809 {"bic", 0x4380, 2, ARM_THUMB, do_t_arit},
810 {"bl", 0xf7fffffe, 4, ARM_THUMB, do_t_branch23},
811 {"bx", 0x4700, 2, ARM_THUMB, do_t_bx},
812 {"cmn", T_OPCODE_CMN, 2, ARM_THUMB, do_t_arit},
813 {"cmp", 0x0000, 2, ARM_THUMB, do_t_compare},
814 {"eor", 0x4040, 2, ARM_THUMB, do_t_arit},
815 {"ldmia", 0xc800, 2, ARM_THUMB, do_t_ldmstm},
816 {"ldr", 0x0000, 2, ARM_THUMB, do_t_ldr},
817 {"ldrb", 0x0000, 2, ARM_THUMB, do_t_ldrb},
818 {"ldrh", 0x0000, 2, ARM_THUMB, do_t_ldrh},
819 {"ldrsb", 0x5600, 2, ARM_THUMB, do_t_lds},
820 {"ldrsh", 0x5e00, 2, ARM_THUMB, do_t_lds},
821 {"ldsb", 0x5600, 2, ARM_THUMB, do_t_lds},
822 {"ldsh", 0x5e00, 2, ARM_THUMB, do_t_lds},
823 {"lsl", 0x0000, 2, ARM_THUMB, do_t_lsl},
824 {"lsr", 0x0000, 2, ARM_THUMB, do_t_lsr},
825 {"mov", 0x0000, 2, ARM_THUMB, do_t_mov},
826 {"mul", T_OPCODE_MUL, 2, ARM_THUMB, do_t_arit},
827 {"mvn", T_OPCODE_MVN, 2, ARM_THUMB, do_t_arit},
828 {"neg", T_OPCODE_NEG, 2, ARM_THUMB, do_t_arit},
829 {"orr", 0x4300, 2, ARM_THUMB, do_t_arit},
830 {"pop", 0xbc00, 2, ARM_THUMB, do_t_push_pop},
831 {"push", 0xb400, 2, ARM_THUMB, do_t_push_pop},
832 {"ror", 0x41c0, 2, ARM_THUMB, do_t_arit},
833 {"sbc", 0x4180, 2, ARM_THUMB, do_t_arit},
834 {"stmia", 0xc000, 2, ARM_THUMB, do_t_ldmstm},
835 {"str", 0x0000, 2, ARM_THUMB, do_t_str},
836 {"strb", 0x0000, 2, ARM_THUMB, do_t_strb},
837 {"strh", 0x0000, 2, ARM_THUMB, do_t_strh},
838 {"swi", 0xdf00, 2, ARM_THUMB, do_t_swi},
839 {"sub", 0x0000, 2, ARM_THUMB, do_t_sub},
840 {"tst", T_OPCODE_TST, 2, ARM_THUMB, do_t_arit},
841 /* Pseudo ops: */
842 {"adr", 0x0000, 2, ARM_THUMB, do_t_adr},
843 {"nop", 0x46C0, 2, ARM_THUMB, do_t_nop}, /* mov r8,r8 */
844 };
845
846 struct reg_entry
847 {
848 CONST char * name;
849 int number;
850 };
851
852 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
853 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
854 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
855
856 #define REG_PC 15
857 #define REG_LR 14
858 #define REG_SP 13
859
860 /* These are the standard names; Users can add aliases with .req */
861 static CONST struct reg_entry reg_table[] =
862 {
863 /* Processor Register Numbers */
864 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
865 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
866 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
867 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
868 /* APCS conventions */
869 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
870 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
871 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
872 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
873 /* FP Registers */
874 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
875 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
876 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
877 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
878 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
879 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
880 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
881 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
882 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
883 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
884 {NULL, 0}
885 };
886
887 #define BAD_ARGS _("Bad arguments to instruction")
888 #define BAD_PC _("r15 not allowed here")
889 #define BAD_FLAGS _("Instruction should not have flags")
890 #define BAD_COND _("Instruction is not conditional")
891
892 static struct hash_control * arm_ops_hsh = NULL;
893 static struct hash_control * arm_tops_hsh = NULL;
894 static struct hash_control * arm_cond_hsh = NULL;
895 static struct hash_control * arm_shift_hsh = NULL;
896 static struct hash_control * arm_reg_hsh = NULL;
897 static struct hash_control * arm_psr_hsh = NULL;
898
899 /* This table describes all the machine specific pseudo-ops the assembler
900 has to support. The fields are:
901 pseudo-op name without dot
902 function to call to execute this pseudo-op
903 Integer arg to pass to the function
904 */
905
906 static void s_req PARAMS ((int));
907 static void s_align PARAMS ((int));
908 static void s_bss PARAMS ((int));
909 static void s_even PARAMS ((int));
910 static void s_ltorg PARAMS ((int));
911 static void s_arm PARAMS ((int));
912 static void s_thumb PARAMS ((int));
913 static void s_code PARAMS ((int));
914 static void s_force_thumb PARAMS ((int));
915 static void s_thumb_func PARAMS ((int));
916 static void s_thumb_set PARAMS ((int));
917 static void arm_s_text PARAMS ((int));
918 static void arm_s_data PARAMS ((int));
919 #ifdef OBJ_ELF
920 static void arm_s_section PARAMS ((int));
921 static void s_arm_elf_cons PARAMS ((int));
922 #endif
923
924 static int my_get_expression PARAMS ((expressionS *, char **));
925
926 CONST pseudo_typeS md_pseudo_table[] =
927 {
928 { "req", s_req, 0 }, /* Never called becasue '.req' does not start line */
929 { "bss", s_bss, 0 },
930 { "align", s_align, 0 },
931 { "arm", s_arm, 0 },
932 { "thumb", s_thumb, 0 },
933 { "code", s_code, 0 },
934 { "force_thumb", s_force_thumb, 0 },
935 { "thumb_func", s_thumb_func, 0 },
936 { "thumb_set", s_thumb_set, 0 },
937 { "even", s_even, 0 },
938 { "ltorg", s_ltorg, 0 },
939 { "pool", s_ltorg, 0 },
940 /* Allow for the effect of section changes. */
941 { "text", arm_s_text, 0 },
942 { "data", arm_s_data, 0 },
943 #ifdef OBJ_ELF
944 { "section", arm_s_section, 0 },
945 { "section.s", arm_s_section, 0 },
946 { "sect", arm_s_section, 0 },
947 { "sect.s", arm_s_section, 0 },
948 { "word", s_arm_elf_cons, 4 },
949 { "long", s_arm_elf_cons, 4 },
950 #else
951 { "word", cons, 4},
952 #endif
953 { "extend", float_cons, 'x' },
954 { "ldouble", float_cons, 'x' },
955 { "packed", float_cons, 'p' },
956 { 0, 0, 0 }
957 };
958
959 /* Stuff needed to resolve the label ambiguity
960 As:
961 ...
962 label: <insn>
963 may differ from:
964 ...
965 label:
966 <insn>
967 */
968
969 symbolS * last_label_seen;
970 static int label_is_thumb_function_name = false;
971
972 /* Literal stuff */
973
974 #define MAX_LITERAL_POOL_SIZE 1024
975
976 typedef struct literalS
977 {
978 struct expressionS exp;
979 struct arm_it * inst;
980 } literalT;
981
982 literalT literals[MAX_LITERAL_POOL_SIZE];
983 int next_literal_pool_place = 0; /* Next free entry in the pool */
984 int lit_pool_num = 1; /* Next literal pool number */
985 symbolS * current_poolP = NULL;
986
987 static int
988 add_to_lit_pool ()
989 {
990 int lit_count = 0;
991
992 if (current_poolP == NULL)
993 current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,
994 (valueT) 0, &zero_address_frag);
995
996 /* Check if this literal value is already in the pool: */
997 while (lit_count < next_literal_pool_place)
998 {
999 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
1000 && inst.reloc.exp.X_op == O_constant
1001 && literals[lit_count].exp.X_add_number == inst.reloc.exp.X_add_number
1002 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
1003 break;
1004 lit_count++;
1005 }
1006
1007 if (lit_count == next_literal_pool_place) /* new entry */
1008 {
1009 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
1010 {
1011 inst.error = _("Literal Pool Overflow");
1012 return FAIL;
1013 }
1014
1015 literals[next_literal_pool_place].exp = inst.reloc.exp;
1016 lit_count = next_literal_pool_place++;
1017 }
1018
1019 inst.reloc.exp.X_op = O_symbol;
1020 inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
1021 inst.reloc.exp.X_add_symbol = current_poolP;
1022
1023 return SUCCESS;
1024 }
1025
1026 /* Can't use symbol_new here, so have to create a symbol and then at
1027 a later date assign it a value. Thats what these functions do. */
1028 static void
1029 symbol_locate (symbolP, name, segment, valu, frag)
1030 symbolS * symbolP;
1031 CONST char * name; /* It is copied, the caller can modify */
1032 segT segment; /* Segment identifier (SEG_<something>) */
1033 valueT valu; /* Symbol value */
1034 fragS * frag; /* Associated fragment */
1035 {
1036 unsigned int name_length;
1037 char * preserved_copy_of_name;
1038
1039 name_length = strlen (name) + 1; /* +1 for \0 */
1040 obstack_grow (&notes, name, name_length);
1041 preserved_copy_of_name = obstack_finish (&notes);
1042 #ifdef STRIP_UNDERSCORE
1043 if (preserved_copy_of_name[0] == '_')
1044 preserved_copy_of_name++;
1045 #endif
1046
1047 #ifdef tc_canonicalize_symbol_name
1048 preserved_copy_of_name =
1049 tc_canonicalize_symbol_name (preserved_copy_of_name);
1050 #endif
1051
1052 S_SET_NAME (symbolP, preserved_copy_of_name);
1053
1054 S_SET_SEGMENT (symbolP, segment);
1055 S_SET_VALUE (symbolP, valu);
1056 symbol_clear_list_pointers(symbolP);
1057
1058 symbol_set_frag (symbolP, frag);
1059
1060 /* Link to end of symbol chain. */
1061 {
1062 extern int symbol_table_frozen;
1063 if (symbol_table_frozen)
1064 abort ();
1065 }
1066
1067 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1068
1069 obj_symbol_new_hook (symbolP);
1070
1071 #ifdef tc_symbol_new_hook
1072 tc_symbol_new_hook (symbolP);
1073 #endif
1074
1075 #ifdef DEBUG_SYMS
1076 verify_symbol_chain (symbol_rootP, symbol_lastP);
1077 #endif /* DEBUG_SYMS */
1078 }
1079
1080 /* Check that an immediate is valid, and if so, convert it to the right format. */
1081
1082 static unsigned int
1083 validate_immediate (val)
1084 unsigned int val;
1085 {
1086 unsigned int a;
1087 unsigned int i;
1088
1089 #define rotate_left(v, n) (v << n | v >> (32 - n))
1090
1091 for (i = 0; i < 32; i += 2)
1092 if ((a = rotate_left (val, i)) <= 0xff)
1093 return a | (i << 7); /* 12-bit pack: [shift-cnt,const] */
1094
1095 return FAIL;
1096 }
1097
1098 /* Check to see if an immediate can be computed as two seperate immediate
1099 values, added together. We already know that this value cannot be
1100 computed by just one ARM instruction. */
1101
1102 static unsigned int
1103 validate_immediate_twopart (val, highpart)
1104 unsigned int val;
1105 unsigned int * highpart;
1106 {
1107 unsigned int a;
1108 unsigned int i;
1109
1110 for (i = 0; i < 32; i += 2)
1111 if (((a = rotate_left (val, i)) & 0xff) != 0)
1112 {
1113 if (a & 0xff00)
1114 {
1115 if (a & ~ 0xffff)
1116 continue;
1117 * highpart = (a >> 8) | ((i + 24) << 7);
1118 }
1119 else if (a & 0xff0000)
1120 {
1121 if (a & 0xff000000)
1122 continue;
1123
1124 * highpart = (a >> 16) | ((i + 16) << 7);
1125 }
1126 else
1127 {
1128 assert (a & 0xff000000);
1129
1130 * highpart = (a >> 24) | ((i + 8) << 7);
1131 }
1132
1133 return (a & 0xff) | (i << 7);
1134 }
1135
1136 return FAIL;
1137 }
1138
1139 static int
1140 validate_offset_imm (val, hwse)
1141 unsigned int val;
1142 int hwse;
1143 {
1144 if ((hwse && val > 255) || val > 4095)
1145 return FAIL;
1146 return val;
1147 }
1148
1149
1150 static void
1151 s_req (a)
1152 int a;
1153 {
1154 as_bad (_("Invalid syntax for .req directive."));
1155 }
1156
1157 static void
1158 s_bss (ignore)
1159 int ignore;
1160 {
1161 /* We don't support putting frags in the BSS segment, we fake it by
1162 marking in_bss, then looking at s_skip for clues?.. */
1163 subseg_set (bss_section, 0);
1164 demand_empty_rest_of_line ();
1165 }
1166
1167 static void
1168 s_even (ignore)
1169 int ignore;
1170 {
1171 if (!need_pass_2) /* Never make frag if expect extra pass. */
1172 frag_align (1, 0, 0);
1173
1174 record_alignment (now_seg, 1);
1175
1176 demand_empty_rest_of_line ();
1177 }
1178
1179 static void
1180 s_ltorg (ignored)
1181 int ignored;
1182 {
1183 int lit_count = 0;
1184 char sym_name[20];
1185
1186 if (current_poolP == NULL)
1187 return;
1188
1189 /* Align pool as you have word accesses */
1190 /* Only make a frag if we have to ... */
1191 if (!need_pass_2)
1192 frag_align (2, 0, 0);
1193
1194 record_alignment (now_seg, 2);
1195
1196 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1197
1198 symbol_locate (current_poolP, sym_name, now_seg,
1199 (valueT) frag_now_fix (), frag_now);
1200 symbol_table_insert (current_poolP);
1201
1202 ARM_SET_THUMB (current_poolP, thumb_mode);
1203
1204 #if defined OBJ_COFF || defined OBJ_ELF
1205 ARM_SET_INTERWORK (current_poolP, support_interwork);
1206 #endif
1207
1208 while (lit_count < next_literal_pool_place)
1209 /* First output the expression in the instruction to the pool */
1210 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1211
1212 next_literal_pool_place = 0;
1213 current_poolP = NULL;
1214 }
1215
1216 static void
1217 s_align (unused) /* Same as s_align_ptwo but align 0 => align 2 */
1218 int unused;
1219 {
1220 register int temp;
1221 register long temp_fill;
1222 long max_alignment = 15;
1223
1224 temp = get_absolute_expression ();
1225 if (temp > max_alignment)
1226 as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
1227 else if (temp < 0)
1228 {
1229 as_bad (_("Alignment negative. 0 assumed."));
1230 temp = 0;
1231 }
1232
1233 if (*input_line_pointer == ',')
1234 {
1235 input_line_pointer++;
1236 temp_fill = get_absolute_expression ();
1237 }
1238 else
1239 temp_fill = 0;
1240
1241 if (!temp)
1242 temp = 2;
1243
1244 /* Only make a frag if we HAVE to. . . */
1245 if (temp && !need_pass_2)
1246 frag_align (temp, (int) temp_fill, 0);
1247 demand_empty_rest_of_line ();
1248
1249 record_alignment (now_seg, temp);
1250 }
1251
1252 static void
1253 s_force_thumb (ignore)
1254 int ignore;
1255 {
1256 /* If we are not already in thumb mode go into it, EVEN if
1257 the target processor does not support thumb instructions.
1258 This is used by gcc/config/arm/lib1funcs.asm for example
1259 to compile interworking support functions even if the
1260 target processor should not support interworking. */
1261
1262 if (! thumb_mode)
1263 {
1264 thumb_mode = 2;
1265
1266 record_alignment (now_seg, 1);
1267 }
1268
1269 demand_empty_rest_of_line ();
1270 }
1271
1272 static void
1273 s_thumb_func (ignore)
1274 int ignore;
1275 {
1276 /* The following label is the name/address of the start of a Thumb function.
1277 We need to know this for the interworking support. */
1278
1279 label_is_thumb_function_name = true;
1280
1281 demand_empty_rest_of_line ();
1282 }
1283
1284 /* Perform a .set directive, but also mark the alias as
1285 being a thumb function. */
1286
1287 static void
1288 s_thumb_set (equiv)
1289 int equiv;
1290 {
1291 /* XXX the following is a duplicate of the code for s_set() in read.c
1292 We cannot just call that code as we need to get at the symbol that
1293 is created. */
1294 register char * name;
1295 register char delim;
1296 register char * end_name;
1297 register symbolS * symbolP;
1298
1299 /*
1300 * Especial apologies for the random logic:
1301 * this just grew, and could be parsed much more simply!
1302 * Dean in haste.
1303 */
1304 name = input_line_pointer;
1305 delim = get_symbol_end ();
1306 end_name = input_line_pointer;
1307 *end_name = delim;
1308
1309 SKIP_WHITESPACE ();
1310
1311 if (*input_line_pointer != ',')
1312 {
1313 *end_name = 0;
1314 as_bad (_("Expected comma after name \"%s\""), name);
1315 *end_name = delim;
1316 ignore_rest_of_line ();
1317 return;
1318 }
1319
1320 input_line_pointer++;
1321 *end_name = 0;
1322
1323 if (name[0] == '.' && name[1] == '\0')
1324 {
1325 /* XXX - this should not happen to .thumb_set */
1326 abort ();
1327 }
1328
1329 if ((symbolP = symbol_find (name)) == NULL
1330 && (symbolP = md_undefined_symbol (name)) == NULL)
1331 {
1332 #ifndef NO_LISTING
1333 /* When doing symbol listings, play games with dummy fragments living
1334 outside the normal fragment chain to record the file and line info
1335 for this symbol. */
1336 if (listing & LISTING_SYMBOLS)
1337 {
1338 extern struct list_info_struct * listing_tail;
1339 fragS * dummy_frag = (fragS *) xmalloc (sizeof(fragS));
1340 memset (dummy_frag, 0, sizeof(fragS));
1341 dummy_frag->fr_type = rs_fill;
1342 dummy_frag->line = listing_tail;
1343 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1344 dummy_frag->fr_symbol = symbolP;
1345 }
1346 else
1347 #endif
1348 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1349
1350 #ifdef OBJ_COFF
1351 /* "set" symbols are local unless otherwise specified. */
1352 SF_SET_LOCAL (symbolP);
1353 #endif /* OBJ_COFF */
1354 } /* make a new symbol */
1355
1356 symbol_table_insert (symbolP);
1357
1358 * end_name = delim;
1359
1360 if (equiv
1361 && S_IS_DEFINED (symbolP)
1362 && S_GET_SEGMENT (symbolP) != reg_section)
1363 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1364
1365 pseudo_set (symbolP);
1366
1367 demand_empty_rest_of_line ();
1368
1369 /* XXX Now we come to the Thumb specific bit of code. */
1370
1371 THUMB_SET_FUNC (symbolP, 1);
1372 ARM_SET_THUMB (symbolP, 1);
1373 #if defined OBJ_ELF || defined OBJ_COFF
1374 ARM_SET_INTERWORK (symbolP, support_interwork);
1375 #endif
1376 }
1377
1378 /* If we change section we must dump the literal pool first. */
1379 static void
1380 arm_s_text (ignore)
1381 int ignore;
1382 {
1383 if (now_seg != text_section)
1384 s_ltorg (0);
1385
1386 s_text (ignore);
1387 }
1388
1389 static void
1390 arm_s_data (ignore)
1391 int ignore;
1392 {
1393 if (flag_readonly_data_in_text)
1394 {
1395 if (now_seg != text_section)
1396 s_ltorg (0);
1397 }
1398 else if (now_seg != data_section)
1399 s_ltorg (0);
1400
1401 s_data (ignore);
1402 }
1403
1404 #ifdef OBJ_ELF
1405 static void
1406 arm_s_section (ignore)
1407 int ignore;
1408 {
1409 s_ltorg (0);
1410
1411 obj_elf_section (ignore);
1412 }
1413 #endif
1414
1415 static void
1416 opcode_select (width)
1417 int width;
1418 {
1419 switch (width)
1420 {
1421 case 16:
1422 if (! thumb_mode)
1423 {
1424 if (! (cpu_variant & ARM_THUMB))
1425 as_bad (_("selected processor does not support THUMB opcodes"));
1426 thumb_mode = 1;
1427 /* No need to force the alignment, since we will have been
1428 coming from ARM mode, which is word-aligned. */
1429 record_alignment (now_seg, 1);
1430 }
1431 break;
1432
1433 case 32:
1434 if (thumb_mode)
1435 {
1436 if ((cpu_variant & ARM_ANY) == ARM_THUMB)
1437 as_bad (_("selected processor does not support ARM opcodes"));
1438 thumb_mode = 0;
1439 if (!need_pass_2)
1440 frag_align (2, 0, 0);
1441 record_alignment (now_seg, 1);
1442 }
1443 break;
1444
1445 default:
1446 as_bad (_("invalid instruction size selected (%d)"), width);
1447 }
1448 }
1449
1450 static void
1451 s_arm (ignore)
1452 int ignore;
1453 {
1454 opcode_select (32);
1455 demand_empty_rest_of_line ();
1456 }
1457
1458 static void
1459 s_thumb (ignore)
1460 int ignore;
1461 {
1462 opcode_select (16);
1463 demand_empty_rest_of_line ();
1464 }
1465
1466 static void
1467 s_code (unused)
1468 int unused;
1469 {
1470 register int temp;
1471
1472 temp = get_absolute_expression ();
1473 switch (temp)
1474 {
1475 case 16:
1476 case 32:
1477 opcode_select (temp);
1478 break;
1479
1480 default:
1481 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1482 }
1483 }
1484
1485 static void
1486 end_of_line (str)
1487 char * str;
1488 {
1489 skip_whitespace (str);
1490
1491 if (* str != '\0')
1492 inst.error = _("Garbage following instruction");
1493 }
1494
1495 static int
1496 skip_past_comma (str)
1497 char ** str;
1498 {
1499 char *p = *str, c;
1500 int comma = 0;
1501
1502 while ((c = *p) == ' ' || c == ',')
1503 {
1504 p++;
1505 if (c == ',' && comma++)
1506 return FAIL;
1507 }
1508
1509 if (c == '\0')
1510 return FAIL;
1511
1512 *str = p;
1513 return comma ? SUCCESS : FAIL;
1514 }
1515
1516 /* A standard register must be given at this point.
1517 Shift is the place to put it in inst.instruction.
1518 Restores input start point on err.
1519 Returns the reg#, or FAIL. */
1520
1521 static int
1522 reg_required_here (str, shift)
1523 char ** str;
1524 int shift;
1525 {
1526 static char buff [128]; /* XXX */
1527 int reg;
1528 char * start = *str;
1529
1530 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1531 {
1532 if (shift >= 0)
1533 inst.instruction |= reg << shift;
1534 return reg;
1535 }
1536
1537 /* Restore the start point, we may have got a reg of the wrong class. */
1538 *str = start;
1539
1540 /* In the few cases where we might be able to accept something else
1541 this error can be overridden. */
1542 sprintf (buff, _("Register expected, not '%.100s'"), start);
1543 inst.error = buff;
1544
1545 return FAIL;
1546 }
1547
1548 static int
1549 psr_required_here (str, cpsr, spsr)
1550 char ** str;
1551 int cpsr;
1552 int spsr;
1553 {
1554 int psr;
1555 char * start = *str;
1556 psr = arm_psr_parse (str);
1557
1558 if (psr == cpsr || psr == spsr)
1559 {
1560 if (psr == spsr)
1561 inst.instruction |= 1 << 22;
1562
1563 return SUCCESS;
1564 }
1565
1566 /* In the few cases where we might be able to accept something else
1567 this error can be overridden. */
1568 inst.error = _("<psr(f)> expected");
1569
1570 /* Restore the start point. */
1571 *str = start;
1572 return FAIL;
1573 }
1574
1575 static int
1576 co_proc_number (str)
1577 char ** str;
1578 {
1579 int processor, pchar;
1580
1581 skip_whitespace (* str);
1582
1583 /* The data sheet seems to imply that just a number on its own is valid
1584 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1585 accept either. */
1586 if (**str == 'p' || **str == 'P')
1587 (*str)++;
1588
1589 pchar = *(*str)++;
1590 if (pchar >= '0' && pchar <= '9')
1591 {
1592 processor = pchar - '0';
1593 if (**str >= '0' && **str <= '9')
1594 {
1595 processor = processor * 10 + *(*str)++ - '0';
1596 if (processor > 15)
1597 {
1598 inst.error = _("Illegal co-processor number");
1599 return FAIL;
1600 }
1601 }
1602 }
1603 else
1604 {
1605 inst.error = _("Bad or missing co-processor number");
1606 return FAIL;
1607 }
1608
1609 inst.instruction |= processor << 8;
1610 return SUCCESS;
1611 }
1612
1613 static int
1614 cp_opc_expr (str, where, length)
1615 char ** str;
1616 int where;
1617 int length;
1618 {
1619 expressionS expr;
1620
1621 skip_whitespace (* str);
1622
1623 memset (&expr, '\0', sizeof (expr));
1624
1625 if (my_get_expression (&expr, str))
1626 return FAIL;
1627 if (expr.X_op != O_constant)
1628 {
1629 inst.error = _("bad or missing expression");
1630 return FAIL;
1631 }
1632
1633 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1634 {
1635 inst.error = _("immediate co-processor expression too large");
1636 return FAIL;
1637 }
1638
1639 inst.instruction |= expr.X_add_number << where;
1640 return SUCCESS;
1641 }
1642
1643 static int
1644 cp_reg_required_here (str, where)
1645 char ** str;
1646 int where;
1647 {
1648 int reg;
1649 char * start = *str;
1650
1651 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1652 {
1653 reg &= 15;
1654 inst.instruction |= reg << where;
1655 return reg;
1656 }
1657
1658 /* In the few cases where we might be able to accept something else
1659 this error can be overridden. */
1660 inst.error = _("Co-processor register expected");
1661
1662 /* Restore the start point. */
1663 *str = start;
1664 return FAIL;
1665 }
1666
1667 static int
1668 fp_reg_required_here (str, where)
1669 char ** str;
1670 int where;
1671 {
1672 int reg;
1673 char * start = *str;
1674
1675 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
1676 {
1677 reg &= 7;
1678 inst.instruction |= reg << where;
1679 return reg;
1680 }
1681
1682 /* In the few cases where we might be able to accept something else
1683 this error can be overridden. */
1684 inst.error = _("Floating point register expected");
1685
1686 /* Restore the start point. */
1687 *str = start;
1688 return FAIL;
1689 }
1690
1691 static int
1692 cp_address_offset (str)
1693 char ** str;
1694 {
1695 int offset;
1696
1697 skip_whitespace (* str);
1698
1699 if (! is_immediate_prefix (**str))
1700 {
1701 inst.error = _("immediate expression expected");
1702 return FAIL;
1703 }
1704
1705 (*str)++;
1706
1707 if (my_get_expression (& inst.reloc.exp, str))
1708 return FAIL;
1709
1710 if (inst.reloc.exp.X_op == O_constant)
1711 {
1712 offset = inst.reloc.exp.X_add_number;
1713
1714 if (offset & 3)
1715 {
1716 inst.error = _("co-processor address must be word aligned");
1717 return FAIL;
1718 }
1719
1720 if (offset > 1023 || offset < -1023)
1721 {
1722 inst.error = _("offset too large");
1723 return FAIL;
1724 }
1725
1726 if (offset >= 0)
1727 inst.instruction |= INDEX_UP;
1728 else
1729 offset = -offset;
1730
1731 inst.instruction |= offset >> 2;
1732 }
1733 else
1734 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1735
1736 return SUCCESS;
1737 }
1738
1739 static int
1740 cp_address_required_here (str)
1741 char ** str;
1742 {
1743 char * p = * str;
1744 int pre_inc = 0;
1745 int write_back = 0;
1746
1747 if (*p == '[')
1748 {
1749 int reg;
1750
1751 p++;
1752 skip_whitespace (p);
1753
1754 if ((reg = reg_required_here (& p, 16)) == FAIL)
1755 return FAIL;
1756
1757 skip_whitespace (p);
1758
1759 if (*p == ']')
1760 {
1761 p++;
1762
1763 if (skip_past_comma (& p) == SUCCESS)
1764 {
1765 /* [Rn], #expr */
1766 write_back = WRITE_BACK;
1767
1768 if (reg == REG_PC)
1769 {
1770 inst.error = _("pc may not be used in post-increment");
1771 return FAIL;
1772 }
1773
1774 if (cp_address_offset (& p) == FAIL)
1775 return FAIL;
1776 }
1777 else
1778 pre_inc = PRE_INDEX | INDEX_UP;
1779 }
1780 else
1781 {
1782 /* '['Rn, #expr']'[!] */
1783
1784 if (skip_past_comma (& p) == FAIL)
1785 {
1786 inst.error = _("pre-indexed expression expected");
1787 return FAIL;
1788 }
1789
1790 pre_inc = PRE_INDEX;
1791
1792 if (cp_address_offset (& p) == FAIL)
1793 return FAIL;
1794
1795 skip_whitespace (p);
1796
1797 if (*p++ != ']')
1798 {
1799 inst.error = _("missing ]");
1800 return FAIL;
1801 }
1802
1803 skip_whitespace (p);
1804
1805 if (*p == '!')
1806 {
1807 if (reg == REG_PC)
1808 {
1809 inst.error = _("pc may not be used with write-back");
1810 return FAIL;
1811 }
1812
1813 p++;
1814 write_back = WRITE_BACK;
1815 }
1816 }
1817 }
1818 else
1819 {
1820 if (my_get_expression (&inst.reloc.exp, &p))
1821 return FAIL;
1822
1823 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
1824 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
1825 inst.reloc.pc_rel = 1;
1826 inst.instruction |= (REG_PC << 16);
1827 pre_inc = PRE_INDEX;
1828 }
1829
1830 inst.instruction |= write_back | pre_inc;
1831 *str = p;
1832 return SUCCESS;
1833 }
1834
1835 static void
1836 do_nop (str, flags)
1837 char * str;
1838 unsigned long flags;
1839 {
1840 /* Do nothing really. */
1841 inst.instruction |= flags; /* This is pointless. */
1842 end_of_line (str);
1843 return;
1844 }
1845
1846 static void
1847 do_mrs (str, flags)
1848 char *str;
1849 unsigned long flags;
1850 {
1851 /* Only one syntax. */
1852 skip_whitespace (str);
1853
1854 if (reg_required_here (&str, 12) == FAIL)
1855 {
1856 inst.error = BAD_ARGS;
1857 return;
1858 }
1859
1860 if (skip_past_comma (&str) == FAIL
1861 || psr_required_here (& str, CPSR_ALL, SPSR_ALL) == FAIL)
1862 {
1863 inst.error = _("<psr> expected");
1864 return;
1865 }
1866
1867 inst.instruction |= flags;
1868 end_of_line (str);
1869 return;
1870 }
1871
1872 /* Three possible forms: "<psr>, Rm", "<psrf>, Rm", "<psrf>, #expression". */
1873 static void
1874 do_msr (str, flags)
1875 char * str;
1876 unsigned long flags;
1877 {
1878 int reg;
1879
1880 skip_whitespace (str);
1881
1882 if (psr_required_here (&str, CPSR_ALL, SPSR_ALL) == SUCCESS)
1883 {
1884 inst.instruction |= PSR_ALL;
1885
1886 /* Sytax should be "<psr>, Rm" */
1887 if (skip_past_comma (&str) == FAIL
1888 || (reg = reg_required_here (&str, 0)) == FAIL)
1889 {
1890 inst.error = BAD_ARGS;
1891 return;
1892 }
1893 }
1894 else
1895 {
1896 if (psr_required_here (& str, CPSR_FLG, SPSR_FLG) == SUCCESS)
1897 inst.instruction |= PSR_FLAGS;
1898 else if (psr_required_here (& str, CPSR_CTL, SPSR_CTL) == SUCCESS)
1899 inst.instruction |= PSR_CONTROL;
1900 else
1901 {
1902 inst.error = BAD_ARGS;
1903 return;
1904 }
1905
1906 if (skip_past_comma (&str) == FAIL)
1907 {
1908 inst.error = BAD_ARGS;
1909 return;
1910 }
1911
1912 /* Syntax could be "<psrf>, rm", "<psrf>, #expression" */
1913
1914 if ((reg = reg_required_here (& str, 0)) != FAIL)
1915 ;
1916 /* Immediate expression. */
1917 else if (is_immediate_prefix (* str))
1918 {
1919 str ++;
1920 inst.error = NULL;
1921
1922 if (my_get_expression (& inst.reloc.exp, & str))
1923 {
1924 inst.error = _("Register or shift expression expected");
1925 return;
1926 }
1927
1928 if (inst.reloc.exp.X_add_symbol)
1929 {
1930 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
1931 inst.reloc.pc_rel = 0;
1932 }
1933 else
1934 {
1935 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
1936 if (value == FAIL)
1937 {
1938 inst.error = _("Invalid constant");
1939 return;
1940 }
1941
1942 inst.instruction |= value;
1943 }
1944
1945 flags |= INST_IMMEDIATE;
1946 }
1947 else
1948 {
1949 inst.error = _("Error: unrecognised syntax for second argument to msr instruction");
1950 return;
1951 }
1952 }
1953
1954 inst.error = NULL;
1955 inst.instruction |= flags;
1956 end_of_line (str);
1957 return;
1958 }
1959
1960 /* Long Multiply Parser
1961 UMULL RdLo, RdHi, Rm, Rs
1962 SMULL RdLo, RdHi, Rm, Rs
1963 UMLAL RdLo, RdHi, Rm, Rs
1964 SMLAL RdLo, RdHi, Rm, Rs
1965 */
1966 static void
1967 do_mull (str, flags)
1968 char * str;
1969 unsigned long flags;
1970 {
1971 int rdlo, rdhi, rm, rs;
1972
1973 /* Only one format "rdlo, rdhi, rm, rs" */
1974 skip_whitespace (str);
1975
1976 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
1977 {
1978 inst.error = BAD_ARGS;
1979 return;
1980 }
1981
1982 if (skip_past_comma (&str) == FAIL
1983 || (rdhi = reg_required_here (&str, 16)) == FAIL)
1984 {
1985 inst.error = BAD_ARGS;
1986 return;
1987 }
1988
1989 if (skip_past_comma (&str) == FAIL
1990 || (rm = reg_required_here (&str, 0)) == FAIL)
1991 {
1992 inst.error = BAD_ARGS;
1993 return;
1994 }
1995
1996 /* rdhi, rdlo and rm must all be different */
1997 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
1998 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
1999
2000 if (skip_past_comma (&str) == FAIL
2001 || (rs = reg_required_here (&str, 8)) == FAIL)
2002 {
2003 inst.error = BAD_ARGS;
2004 return;
2005 }
2006
2007 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2008 {
2009 inst.error = BAD_PC;
2010 return;
2011 }
2012
2013 inst.instruction |= flags;
2014 end_of_line (str);
2015 return;
2016 }
2017
2018 static void
2019 do_mul (str, flags)
2020 char * str;
2021 unsigned long flags;
2022 {
2023 int rd, rm;
2024
2025 /* Only one format "rd, rm, rs" */
2026 skip_whitespace (str);
2027
2028 if ((rd = reg_required_here (&str, 16)) == FAIL)
2029 {
2030 inst.error = BAD_ARGS;
2031 return;
2032 }
2033
2034 if (rd == REG_PC)
2035 {
2036 inst.error = BAD_PC;
2037 return;
2038 }
2039
2040 if (skip_past_comma (&str) == FAIL
2041 || (rm = reg_required_here (&str, 0)) == FAIL)
2042 {
2043 inst.error = BAD_ARGS;
2044 return;
2045 }
2046
2047 if (rm == REG_PC)
2048 {
2049 inst.error = BAD_PC;
2050 return;
2051 }
2052
2053 if (rm == rd)
2054 as_tsktsk (_("rd and rm should be different in mul"));
2055
2056 if (skip_past_comma (&str) == FAIL
2057 || (rm = reg_required_here (&str, 8)) == FAIL)
2058 {
2059 inst.error = BAD_ARGS;
2060 return;
2061 }
2062
2063 if (rm == REG_PC)
2064 {
2065 inst.error = BAD_PC;
2066 return;
2067 }
2068
2069 inst.instruction |= flags;
2070 end_of_line (str);
2071 return;
2072 }
2073
2074 static void
2075 do_mla (str, flags)
2076 char * str;
2077 unsigned long flags;
2078 {
2079 int rd, rm;
2080
2081 /* Only one format "rd, rm, rs, rn" */
2082 skip_whitespace (str);
2083
2084 if ((rd = reg_required_here (&str, 16)) == FAIL)
2085 {
2086 inst.error = BAD_ARGS;
2087 return;
2088 }
2089
2090 if (rd == REG_PC)
2091 {
2092 inst.error = BAD_PC;
2093 return;
2094 }
2095
2096 if (skip_past_comma (&str) == FAIL
2097 || (rm = reg_required_here (&str, 0)) == FAIL)
2098 {
2099 inst.error = BAD_ARGS;
2100 return;
2101 }
2102
2103 if (rm == REG_PC)
2104 {
2105 inst.error = BAD_PC;
2106 return;
2107 }
2108
2109 if (rm == rd)
2110 as_tsktsk (_("rd and rm should be different in mla"));
2111
2112 if (skip_past_comma (&str) == FAIL
2113 || (rd = reg_required_here (&str, 8)) == FAIL
2114 || skip_past_comma (&str) == FAIL
2115 || (rm = reg_required_here (&str, 12)) == FAIL)
2116 {
2117 inst.error = BAD_ARGS;
2118 return;
2119 }
2120
2121 if (rd == REG_PC || rm == REG_PC)
2122 {
2123 inst.error = BAD_PC;
2124 return;
2125 }
2126
2127 inst.instruction |= flags;
2128 end_of_line (str);
2129 return;
2130 }
2131
2132 /* Returns the index into fp_values of a floating point number, or -1 if
2133 not in the table. */
2134 static int
2135 my_get_float_expression (str)
2136 char ** str;
2137 {
2138 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2139 char * save_in;
2140 expressionS exp;
2141 int i;
2142 int j;
2143
2144 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
2145 /* Look for a raw floating point number */
2146 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
2147 && (is_end_of_line [(int)(*save_in)] || *save_in == '\0'))
2148 {
2149 for (i = 0; i < NUM_FLOAT_VALS; i++)
2150 {
2151 for (j = 0; j < MAX_LITTLENUMS; j++)
2152 {
2153 if (words[j] != fp_values[i][j])
2154 break;
2155 }
2156
2157 if (j == MAX_LITTLENUMS)
2158 {
2159 *str = save_in;
2160 return i;
2161 }
2162 }
2163 }
2164
2165 /* Try and parse a more complex expression, this will probably fail
2166 unless the code uses a floating point prefix (eg "0f") */
2167 save_in = input_line_pointer;
2168 input_line_pointer = *str;
2169 if (expression (&exp) == absolute_section
2170 && exp.X_op == O_big
2171 && exp.X_add_number < 0)
2172 {
2173 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
2174 Ditto for 15. */
2175 if (gen_to_words (words, 5, (long)15) == 0)
2176 {
2177 for (i = 0; i < NUM_FLOAT_VALS; i++)
2178 {
2179 for (j = 0; j < MAX_LITTLENUMS; j++)
2180 {
2181 if (words[j] != fp_values[i][j])
2182 break;
2183 }
2184
2185 if (j == MAX_LITTLENUMS)
2186 {
2187 *str = input_line_pointer;
2188 input_line_pointer = save_in;
2189 return i;
2190 }
2191 }
2192 }
2193 }
2194
2195 *str = input_line_pointer;
2196 input_line_pointer = save_in;
2197 return -1;
2198 }
2199
2200 /* Return true if anything in the expression is a bignum */
2201 static int
2202 walk_no_bignums (sp)
2203 symbolS * sp;
2204 {
2205 if (symbol_get_value_expression (sp)->X_op == O_big)
2206 return 1;
2207
2208 if (symbol_get_value_expression (sp)->X_add_symbol)
2209 {
2210 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
2211 || (symbol_get_value_expression (sp)->X_op_symbol
2212 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
2213 }
2214
2215 return 0;
2216 }
2217
2218 static int
2219 my_get_expression (ep, str)
2220 expressionS * ep;
2221 char ** str;
2222 {
2223 char * save_in;
2224 segT seg;
2225
2226 save_in = input_line_pointer;
2227 input_line_pointer = *str;
2228 seg = expression (ep);
2229
2230 #ifdef OBJ_AOUT
2231 if (seg != absolute_section
2232 && seg != text_section
2233 && seg != data_section
2234 && seg != bss_section
2235 && seg != undefined_section)
2236 {
2237 inst.error = _("bad_segment");
2238 *str = input_line_pointer;
2239 input_line_pointer = save_in;
2240 return 1;
2241 }
2242 #endif
2243
2244 /* Get rid of any bignums now, so that we don't generate an error for which
2245 we can't establish a line number later on. Big numbers are never valid
2246 in instructions, which is where this routine is always called. */
2247 if (ep->X_op == O_big
2248 || (ep->X_add_symbol
2249 && (walk_no_bignums (ep->X_add_symbol)
2250 || (ep->X_op_symbol
2251 && walk_no_bignums (ep->X_op_symbol)))))
2252 {
2253 inst.error = _("Invalid constant");
2254 *str = input_line_pointer;
2255 input_line_pointer = save_in;
2256 return 1;
2257 }
2258
2259 *str = input_line_pointer;
2260 input_line_pointer = save_in;
2261 return 0;
2262 }
2263
2264 /* unrestrict should be one if <shift> <register> is permitted for this
2265 instruction */
2266
2267 static int
2268 decode_shift (str, unrestrict)
2269 char ** str;
2270 int unrestrict;
2271 {
2272 struct asm_shift * shft;
2273 char * p;
2274 char c;
2275
2276 skip_whitespace (* str);
2277
2278 for (p = *str; isalpha (*p); p++)
2279 ;
2280
2281 if (p == *str)
2282 {
2283 inst.error = _("Shift expression expected");
2284 return FAIL;
2285 }
2286
2287 c = *p;
2288 *p = '\0';
2289 shft = (struct asm_shift *) hash_find (arm_shift_hsh, *str);
2290 *p = c;
2291 if (shft)
2292 {
2293 if (!strncmp (*str, "rrx", 3)
2294 || !strncmp (*str, "RRX", 3))
2295 {
2296 *str = p;
2297 inst.instruction |= shft->value;
2298 return SUCCESS;
2299 }
2300
2301 skip_whitespace (p);
2302
2303 if (unrestrict && reg_required_here (&p, 8) != FAIL)
2304 {
2305 inst.instruction |= shft->value | SHIFT_BY_REG;
2306 *str = p;
2307 return SUCCESS;
2308 }
2309 else if (is_immediate_prefix (* p))
2310 {
2311 inst.error = NULL;
2312 p++;
2313 if (my_get_expression (&inst.reloc.exp, &p))
2314 return FAIL;
2315
2316 /* Validate some simple #expressions */
2317 if (inst.reloc.exp.X_op == O_constant)
2318 {
2319 unsigned num = inst.reloc.exp.X_add_number;
2320
2321 /* Reject operations greater than 32, or lsl #32 */
2322 if (num > 32 || (num == 32 && shft->value == 0))
2323 {
2324 inst.error = _("Invalid immediate shift");
2325 return FAIL;
2326 }
2327
2328 /* Shifts of zero should be converted to lsl (which is zero)*/
2329 if (num == 0)
2330 {
2331 *str = p;
2332 return SUCCESS;
2333 }
2334
2335 /* Shifts of 32 are encoded as 0, for those shifts that
2336 support it. */
2337 if (num == 32)
2338 num = 0;
2339
2340 inst.instruction |= (num << 7) | shft->value;
2341 *str = p;
2342 return SUCCESS;
2343 }
2344
2345 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
2346 inst.reloc.pc_rel = 0;
2347 inst.instruction |= shft->value;
2348 *str = p;
2349 return SUCCESS;
2350 }
2351 else
2352 {
2353 inst.error = unrestrict ? _("shift requires register or #expression")
2354 : _("shift requires #expression");
2355 *str = p;
2356 return FAIL;
2357 }
2358 }
2359
2360 inst.error = _("Shift expression expected");
2361 return FAIL;
2362 }
2363
2364 /* Do those data_ops which can take a negative immediate constant */
2365 /* by altering the instuction. A bit of a hack really */
2366 /* MOV <-> MVN
2367 AND <-> BIC
2368 ADC <-> SBC
2369 by inverting the second operand, and
2370 ADD <-> SUB
2371 CMP <-> CMN
2372 by negating the second operand.
2373 */
2374 static int
2375 negate_data_op (instruction, value)
2376 unsigned long * instruction;
2377 unsigned long value;
2378 {
2379 int op, new_inst;
2380 unsigned long negated, inverted;
2381
2382 negated = validate_immediate (-value);
2383 inverted = validate_immediate (~value);
2384
2385 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
2386 switch (op)
2387 {
2388 /* First negates */
2389 case OPCODE_SUB: /* ADD <-> SUB */
2390 new_inst = OPCODE_ADD;
2391 value = negated;
2392 break;
2393
2394 case OPCODE_ADD:
2395 new_inst = OPCODE_SUB;
2396 value = negated;
2397 break;
2398
2399 case OPCODE_CMP: /* CMP <-> CMN */
2400 new_inst = OPCODE_CMN;
2401 value = negated;
2402 break;
2403
2404 case OPCODE_CMN:
2405 new_inst = OPCODE_CMP;
2406 value = negated;
2407 break;
2408
2409 /* Now Inverted ops */
2410 case OPCODE_MOV: /* MOV <-> MVN */
2411 new_inst = OPCODE_MVN;
2412 value = inverted;
2413 break;
2414
2415 case OPCODE_MVN:
2416 new_inst = OPCODE_MOV;
2417 value = inverted;
2418 break;
2419
2420 case OPCODE_AND: /* AND <-> BIC */
2421 new_inst = OPCODE_BIC;
2422 value = inverted;
2423 break;
2424
2425 case OPCODE_BIC:
2426 new_inst = OPCODE_AND;
2427 value = inverted;
2428 break;
2429
2430 case OPCODE_ADC: /* ADC <-> SBC */
2431 new_inst = OPCODE_SBC;
2432 value = inverted;
2433 break;
2434
2435 case OPCODE_SBC:
2436 new_inst = OPCODE_ADC;
2437 value = inverted;
2438 break;
2439
2440 /* We cannot do anything */
2441 default:
2442 return FAIL;
2443 }
2444
2445 if (value == FAIL)
2446 return FAIL;
2447
2448 *instruction &= OPCODE_MASK;
2449 *instruction |= new_inst << DATA_OP_SHIFT;
2450 return value;
2451 }
2452
2453 static int
2454 data_op2 (str)
2455 char ** str;
2456 {
2457 int value;
2458 expressionS expr;
2459
2460 skip_whitespace (* str);
2461
2462 if (reg_required_here (str, 0) != FAIL)
2463 {
2464 if (skip_past_comma (str) == SUCCESS)
2465 /* Shift operation on register. */
2466 return decode_shift (str, NO_SHIFT_RESTRICT);
2467
2468 return SUCCESS;
2469 }
2470 else
2471 {
2472 /* Immediate expression */
2473 if (is_immediate_prefix (**str))
2474 {
2475 (*str)++;
2476 inst.error = NULL;
2477
2478 if (my_get_expression (&inst.reloc.exp, str))
2479 return FAIL;
2480
2481 if (inst.reloc.exp.X_add_symbol)
2482 {
2483 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2484 inst.reloc.pc_rel = 0;
2485 }
2486 else
2487 {
2488 if (skip_past_comma (str) == SUCCESS)
2489 {
2490 /* #x, y -- ie explicit rotation by Y */
2491 if (my_get_expression (&expr, str))
2492 return FAIL;
2493
2494 if (expr.X_op != O_constant)
2495 {
2496 inst.error = _("Constant expression expected");
2497 return FAIL;
2498 }
2499
2500 /* Rotate must be a multiple of 2 */
2501 if (((unsigned) expr.X_add_number) > 30
2502 || (expr.X_add_number & 1) != 0
2503 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
2504 {
2505 inst.error = _("Invalid constant");
2506 return FAIL;
2507 }
2508 inst.instruction |= INST_IMMEDIATE;
2509 inst.instruction |= inst.reloc.exp.X_add_number;
2510 inst.instruction |= expr.X_add_number << 7;
2511 return SUCCESS;
2512 }
2513
2514 /* Implicit rotation, select a suitable one */
2515 value = validate_immediate (inst.reloc.exp.X_add_number);
2516
2517 if (value == FAIL)
2518 {
2519 /* Can't be done, perhaps the code reads something like
2520 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be ok */
2521 if ((value = negate_data_op (&inst.instruction,
2522 inst.reloc.exp.X_add_number))
2523 == FAIL)
2524 {
2525 inst.error = _("Invalid constant");
2526 return FAIL;
2527 }
2528 }
2529
2530 inst.instruction |= value;
2531 }
2532
2533 inst.instruction |= INST_IMMEDIATE;
2534 return SUCCESS;
2535 }
2536
2537 (*str)++;
2538 inst.error = _("Register or shift expression expected");
2539 return FAIL;
2540 }
2541 }
2542
2543 static int
2544 fp_op2 (str)
2545 char ** str;
2546 {
2547 skip_whitespace (* str);
2548
2549 if (fp_reg_required_here (str, 0) != FAIL)
2550 return SUCCESS;
2551 else
2552 {
2553 /* Immediate expression */
2554 if (*((*str)++) == '#')
2555 {
2556 int i;
2557
2558 inst.error = NULL;
2559
2560 skip_whitespace (* str);
2561
2562 /* First try and match exact strings, this is to guarantee that
2563 some formats will work even for cross assembly */
2564
2565 for (i = 0; fp_const[i]; i++)
2566 {
2567 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
2568 {
2569 char *start = *str;
2570
2571 *str += strlen (fp_const[i]);
2572 if (is_end_of_line[(int)**str] || **str == '\0')
2573 {
2574 inst.instruction |= i + 8;
2575 return SUCCESS;
2576 }
2577 *str = start;
2578 }
2579 }
2580
2581 /* Just because we didn't get a match doesn't mean that the
2582 constant isn't valid, just that it is in a format that we
2583 don't automatically recognize. Try parsing it with
2584 the standard expression routines. */
2585 if ((i = my_get_float_expression (str)) >= 0)
2586 {
2587 inst.instruction |= i + 8;
2588 return SUCCESS;
2589 }
2590
2591 inst.error = _("Invalid floating point immediate expression");
2592 return FAIL;
2593 }
2594 inst.error = _("Floating point register or immediate expression expected");
2595 return FAIL;
2596 }
2597 }
2598
2599 static void
2600 do_arit (str, flags)
2601 char * str;
2602 unsigned long flags;
2603 {
2604 skip_whitespace (str);
2605
2606 if (reg_required_here (&str, 12) == FAIL
2607 || skip_past_comma (&str) == FAIL
2608 || reg_required_here (&str, 16) == FAIL
2609 || skip_past_comma (&str) == FAIL
2610 || data_op2 (&str) == FAIL)
2611 {
2612 if (!inst.error)
2613 inst.error = BAD_ARGS;
2614 return;
2615 }
2616
2617 inst.instruction |= flags;
2618 end_of_line (str);
2619 return;
2620 }
2621
2622 static void
2623 do_adr (str, flags)
2624 char * str;
2625 unsigned long flags;
2626 {
2627 /* This is a pseudo-op of the form "adr rd, label" to be converted
2628 into a relative address of the form "add rd, pc, #label-.-8" */
2629
2630 skip_whitespace (str);
2631
2632 if (reg_required_here (&str, 12) == FAIL
2633 || skip_past_comma (&str) == FAIL
2634 || my_get_expression (&inst.reloc.exp, &str))
2635 {
2636 if (!inst.error)
2637 inst.error = BAD_ARGS;
2638 return;
2639 }
2640 /* Frag hacking will turn this into a sub instruction if the offset turns
2641 out to be negative. */
2642 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2643 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2644 inst.reloc.pc_rel = 1;
2645 inst.instruction |= flags;
2646 end_of_line (str);
2647 return;
2648 }
2649
2650 static void
2651 do_adrl (str, flags)
2652 char * str;
2653 unsigned long flags;
2654 {
2655 /* This is a pseudo-op of the form "adrl rd, label" to be converted
2656 into a relative address of the form:
2657 add rd, pc, #low(label-.-8)"
2658 add rd, rd, #high(label-.-8)" */
2659
2660 skip_whitespace (str);
2661
2662 if (reg_required_here (& str, 12) == FAIL
2663 || skip_past_comma (& str) == FAIL
2664 || my_get_expression (& inst.reloc.exp, & str))
2665 {
2666 if (!inst.error)
2667 inst.error = BAD_ARGS;
2668 return;
2669 }
2670
2671 end_of_line (str);
2672
2673 /* Frag hacking will turn this into a sub instruction if the offset turns
2674 out to be negative. */
2675 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
2676 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
2677 inst.reloc.pc_rel = 1;
2678 inst.instruction |= flags;
2679 inst.size = INSN_SIZE * 2;
2680
2681 return;
2682 }
2683
2684 static void
2685 do_cmp (str, flags)
2686 char * str;
2687 unsigned long flags;
2688 {
2689 skip_whitespace (str);
2690
2691 if (reg_required_here (&str, 16) == FAIL)
2692 {
2693 if (!inst.error)
2694 inst.error = BAD_ARGS;
2695 return;
2696 }
2697
2698 if (skip_past_comma (&str) == FAIL
2699 || data_op2 (&str) == FAIL)
2700 {
2701 if (!inst.error)
2702 inst.error = BAD_ARGS;
2703 return;
2704 }
2705
2706 inst.instruction |= flags;
2707 if ((flags & 0x0000f000) == 0)
2708 inst.instruction |= CONDS_BIT;
2709
2710 end_of_line (str);
2711 return;
2712 }
2713
2714 static void
2715 do_mov (str, flags)
2716 char * str;
2717 unsigned long flags;
2718 {
2719 skip_whitespace (str);
2720
2721 if (reg_required_here (&str, 12) == FAIL)
2722 {
2723 if (!inst.error)
2724 inst.error = BAD_ARGS;
2725 return;
2726 }
2727
2728 if (skip_past_comma (&str) == FAIL
2729 || data_op2 (&str) == FAIL)
2730 {
2731 if (!inst.error)
2732 inst.error = BAD_ARGS;
2733 return;
2734 }
2735
2736 inst.instruction |= flags;
2737 end_of_line (str);
2738 return;
2739 }
2740
2741 static int
2742 ldst_extend (str, hwse)
2743 char ** str;
2744 int hwse;
2745 {
2746 int add = INDEX_UP;
2747
2748 switch (**str)
2749 {
2750 case '#':
2751 case '$':
2752 (*str)++;
2753 if (my_get_expression (& inst.reloc.exp, str))
2754 return FAIL;
2755
2756 if (inst.reloc.exp.X_op == O_constant)
2757 {
2758 int value = inst.reloc.exp.X_add_number;
2759
2760 if ((hwse && (value < -255 || value > 255))
2761 || (value < -4095 || value > 4095))
2762 {
2763 inst.error = _("address offset too large");
2764 return FAIL;
2765 }
2766
2767 if (value < 0)
2768 {
2769 value = -value;
2770 add = 0;
2771 }
2772
2773 /* Halfword and signextension instructions have the
2774 immediate value split across bits 11..8 and bits 3..0 */
2775 if (hwse)
2776 inst.instruction |= add | HWOFFSET_IMM | ((value >> 4) << 8) | (value & 0xF);
2777 else
2778 inst.instruction |= add | value;
2779 }
2780 else
2781 {
2782 if (hwse)
2783 {
2784 inst.instruction |= HWOFFSET_IMM;
2785 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2786 }
2787 else
2788 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
2789 inst.reloc.pc_rel = 0;
2790 }
2791 return SUCCESS;
2792
2793 case '-':
2794 add = 0; /* and fall through */
2795 case '+':
2796 (*str)++; /* and fall through */
2797 default:
2798 if (reg_required_here (str, 0) == FAIL)
2799 return FAIL;
2800
2801 if (hwse)
2802 inst.instruction |= add;
2803 else
2804 {
2805 inst.instruction |= add | OFFSET_REG;
2806 if (skip_past_comma (str) == SUCCESS)
2807 return decode_shift (str, SHIFT_RESTRICT);
2808 }
2809
2810 return SUCCESS;
2811 }
2812 }
2813
2814 static void
2815 do_ldst (str, flags)
2816 char * str;
2817 unsigned long flags;
2818 {
2819 int halfword = 0;
2820 int pre_inc = 0;
2821 int conflict_reg;
2822 int value;
2823
2824 /* This is not ideal, but it is the simplest way of dealing with the
2825 ARM7T halfword instructions (since they use a different
2826 encoding, but the same mnemonic): */
2827 halfword = (flags & 0x80000000) != 0;
2828 if (halfword)
2829 {
2830 /* This is actually a load/store of a halfword, or a
2831 signed-extension load */
2832 if ((cpu_variant & ARM_HALFWORD) == 0)
2833 {
2834 inst.error
2835 = _("Processor does not support halfwords or signed bytes");
2836 return;
2837 }
2838
2839 inst.instruction = (inst.instruction & COND_MASK)
2840 | (flags & ~COND_MASK);
2841
2842 flags = 0;
2843 }
2844
2845 skip_whitespace (str);
2846
2847 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
2848 {
2849 if (!inst.error)
2850 inst.error = BAD_ARGS;
2851 return;
2852 }
2853
2854 if (skip_past_comma (& str) == FAIL)
2855 {
2856 inst.error = _("Address expected");
2857 return;
2858 }
2859
2860 if (*str == '[')
2861 {
2862 int reg;
2863
2864 str++;
2865
2866 skip_whitespace (str);
2867
2868 if ((reg = reg_required_here (&str, 16)) == FAIL)
2869 return;
2870
2871 /* Conflicts can occur on stores as well as loads. */
2872 conflict_reg = (conflict_reg == reg);
2873
2874 skip_whitespace (str);
2875
2876 if (*str == ']')
2877 {
2878 str ++;
2879
2880 if (skip_past_comma (&str) == SUCCESS)
2881 {
2882 /* [Rn],... (post inc) */
2883 if (ldst_extend (&str, halfword) == FAIL)
2884 return;
2885 if (conflict_reg)
2886 as_warn (_("%s register same as write-back base"),
2887 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2888 }
2889 else
2890 {
2891 /* [Rn] */
2892 if (halfword)
2893 inst.instruction |= HWOFFSET_IMM;
2894
2895 skip_whitespace (str);
2896
2897 if (*str == '!')
2898 {
2899 if (conflict_reg)
2900 as_warn (_("%s register same as write-back base"),
2901 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2902 str++;
2903 inst.instruction |= WRITE_BACK;
2904 }
2905
2906 flags |= INDEX_UP;
2907 if (! (flags & TRANS_BIT))
2908 pre_inc = 1;
2909 }
2910 }
2911 else
2912 {
2913 /* [Rn,...] */
2914 if (skip_past_comma (&str) == FAIL)
2915 {
2916 inst.error = _("pre-indexed expression expected");
2917 return;
2918 }
2919
2920 pre_inc = 1;
2921 if (ldst_extend (&str, halfword) == FAIL)
2922 return;
2923
2924 skip_whitespace (str);
2925
2926 if (*str++ != ']')
2927 {
2928 inst.error = _("missing ]");
2929 return;
2930 }
2931
2932 skip_whitespace (str);
2933
2934 if (*str == '!')
2935 {
2936 if (conflict_reg)
2937 as_warn (_("%s register same as write-back base"),
2938 (inst.instruction & LOAD_BIT) ? _("destination") : _("source") );
2939 str++;
2940 inst.instruction |= WRITE_BACK;
2941 }
2942 }
2943 }
2944 else if (*str == '=')
2945 {
2946 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
2947 str++;
2948
2949 skip_whitespace (str);
2950
2951 if (my_get_expression (&inst.reloc.exp, &str))
2952 return;
2953
2954 if (inst.reloc.exp.X_op != O_constant
2955 && inst.reloc.exp.X_op != O_symbol)
2956 {
2957 inst.error = _("Constant expression expected");
2958 return;
2959 }
2960
2961 if (inst.reloc.exp.X_op == O_constant
2962 && (value = validate_immediate(inst.reloc.exp.X_add_number)) != FAIL)
2963 {
2964 /* This can be done with a mov instruction */
2965 inst.instruction &= LITERAL_MASK;
2966 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
2967 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
2968 end_of_line(str);
2969 return;
2970 }
2971 else
2972 {
2973 /* Insert into literal pool */
2974 if (add_to_lit_pool () == FAIL)
2975 {
2976 if (!inst.error)
2977 inst.error = _("literal pool insertion failed");
2978 return;
2979 }
2980
2981 /* Change the instruction exp to point to the pool */
2982 if (halfword)
2983 {
2984 inst.instruction |= HWOFFSET_IMM;
2985 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
2986 }
2987 else
2988 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
2989 inst.reloc.pc_rel = 1;
2990 inst.instruction |= (REG_PC << 16);
2991 pre_inc = 1;
2992 }
2993 }
2994 else
2995 {
2996 if (my_get_expression (&inst.reloc.exp, &str))
2997 return;
2998
2999 if (halfword)
3000 {
3001 inst.instruction |= HWOFFSET_IMM;
3002 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
3003 }
3004 else
3005 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
3006 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust */
3007 inst.reloc.pc_rel = 1;
3008 inst.instruction |= (REG_PC << 16);
3009 pre_inc = 1;
3010 }
3011
3012 if (pre_inc && (flags & TRANS_BIT))
3013 inst.error = _("Pre-increment instruction with translate");
3014
3015 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
3016 end_of_line (str);
3017 return;
3018 }
3019
3020 static long
3021 reg_list (strp)
3022 char ** strp;
3023 {
3024 char * str = *strp;
3025 long range = 0;
3026 int another_range;
3027
3028 /* We come back here if we get ranges concatenated by '+' or '|' */
3029 do
3030 {
3031 another_range = 0;
3032
3033 if (*str == '{')
3034 {
3035 int in_range = 0;
3036 int cur_reg = -1;
3037
3038 str++;
3039 do
3040 {
3041 int reg;
3042
3043 skip_whitespace (str);
3044
3045 if ((reg = reg_required_here (& str, -1)) == FAIL)
3046 return FAIL;
3047
3048 if (in_range)
3049 {
3050 int i;
3051
3052 if (reg <= cur_reg)
3053 {
3054 inst.error = _("Bad range in register list");
3055 return FAIL;
3056 }
3057
3058 for (i = cur_reg + 1; i < reg; i++)
3059 {
3060 if (range & (1 << i))
3061 as_tsktsk
3062 (_("Warning: Duplicated register (r%d) in register list"),
3063 i);
3064 else
3065 range |= 1 << i;
3066 }
3067 in_range = 0;
3068 }
3069
3070 if (range & (1 << reg))
3071 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
3072 reg);
3073 else if (reg <= cur_reg)
3074 as_tsktsk (_("Warning: Register range not in ascending order"));
3075
3076 range |= 1 << reg;
3077 cur_reg = reg;
3078 } while (skip_past_comma (&str) != FAIL
3079 || (in_range = 1, *str++ == '-'));
3080 str--;
3081 skip_whitespace (str);
3082
3083 if (*str++ != '}')
3084 {
3085 inst.error = _("Missing `}'");
3086 return FAIL;
3087 }
3088 }
3089 else
3090 {
3091 expressionS expr;
3092
3093 if (my_get_expression (&expr, &str))
3094 return FAIL;
3095
3096 if (expr.X_op == O_constant)
3097 {
3098 if (expr.X_add_number
3099 != (expr.X_add_number & 0x0000ffff))
3100 {
3101 inst.error = _("invalid register mask");
3102 return FAIL;
3103 }
3104
3105 if ((range & expr.X_add_number) != 0)
3106 {
3107 int regno = range & expr.X_add_number;
3108
3109 regno &= -regno;
3110 regno = (1 << regno) - 1;
3111 as_tsktsk
3112 (_("Warning: Duplicated register (r%d) in register list"),
3113 regno);
3114 }
3115
3116 range |= expr.X_add_number;
3117 }
3118 else
3119 {
3120 if (inst.reloc.type != 0)
3121 {
3122 inst.error = _("expression too complex");
3123 return FAIL;
3124 }
3125
3126 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
3127 inst.reloc.type = BFD_RELOC_ARM_MULTI;
3128 inst.reloc.pc_rel = 0;
3129 }
3130 }
3131
3132 skip_whitespace (str);
3133
3134 if (*str == '|' || *str == '+')
3135 {
3136 str++;
3137 another_range = 1;
3138 }
3139 } while (another_range);
3140
3141 *strp = str;
3142 return range;
3143 }
3144
3145 static void
3146 do_ldmstm (str, flags)
3147 char * str;
3148 unsigned long flags;
3149 {
3150 int base_reg;
3151 long range;
3152
3153 skip_whitespace (str);
3154
3155 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
3156 return;
3157
3158 if (base_reg == REG_PC)
3159 {
3160 inst.error = _("r15 not allowed as base register");
3161 return;
3162 }
3163
3164 skip_whitespace (str);
3165
3166 if (*str == '!')
3167 {
3168 flags |= WRITE_BACK;
3169 str++;
3170 }
3171
3172 if (skip_past_comma (&str) == FAIL
3173 || (range = reg_list (&str)) == FAIL)
3174 {
3175 if (! inst.error)
3176 inst.error = BAD_ARGS;
3177 return;
3178 }
3179
3180 if (*str == '^')
3181 {
3182 str++;
3183 flags |= LDM_TYPE_2_OR_3;
3184 }
3185
3186 inst.instruction |= flags | range;
3187 end_of_line (str);
3188 return;
3189 }
3190
3191 static void
3192 do_swi (str, flags)
3193 char * str;
3194 unsigned long flags;
3195 {
3196 skip_whitespace (str);
3197
3198 /* Allow optional leading '#'. */
3199 if (is_immediate_prefix (*str))
3200 str++;
3201
3202 if (my_get_expression (& inst.reloc.exp, & str))
3203 return;
3204
3205 inst.reloc.type = BFD_RELOC_ARM_SWI;
3206 inst.reloc.pc_rel = 0;
3207 inst.instruction |= flags;
3208
3209 end_of_line (str);
3210
3211 return;
3212 }
3213
3214 static void
3215 do_swap (str, flags)
3216 char * str;
3217 unsigned long flags;
3218 {
3219 int reg;
3220
3221 skip_whitespace (str);
3222
3223 if ((reg = reg_required_here (&str, 12)) == FAIL)
3224 return;
3225
3226 if (reg == REG_PC)
3227 {
3228 inst.error = _("r15 not allowed in swap");
3229 return;
3230 }
3231
3232 if (skip_past_comma (&str) == FAIL
3233 || (reg = reg_required_here (&str, 0)) == FAIL)
3234 {
3235 if (!inst.error)
3236 inst.error = BAD_ARGS;
3237 return;
3238 }
3239
3240 if (reg == REG_PC)
3241 {
3242 inst.error = _("r15 not allowed in swap");
3243 return;
3244 }
3245
3246 if (skip_past_comma (&str) == FAIL
3247 || *str++ != '[')
3248 {
3249 inst.error = BAD_ARGS;
3250 return;
3251 }
3252
3253 skip_whitespace (str);
3254
3255 if ((reg = reg_required_here (&str, 16)) == FAIL)
3256 return;
3257
3258 if (reg == REG_PC)
3259 {
3260 inst.error = BAD_PC;
3261 return;
3262 }
3263
3264 skip_whitespace (str);
3265
3266 if (*str++ != ']')
3267 {
3268 inst.error = _("missing ]");
3269 return;
3270 }
3271
3272 inst.instruction |= flags;
3273 end_of_line (str);
3274 return;
3275 }
3276
3277 static void
3278 do_branch (str, flags)
3279 char * str;
3280 unsigned long flags;
3281 {
3282 if (my_get_expression (&inst.reloc.exp, &str))
3283 return;
3284
3285 #ifdef OBJ_ELF
3286 {
3287 char * save_in;
3288
3289 /* ScottB: February 5, 1998 */
3290 /* Check to see of PLT32 reloc required for the instruction. */
3291
3292 /* arm_parse_reloc() works on input_line_pointer.
3293 We actually want to parse the operands to the branch instruction
3294 passed in 'str'. Save the input pointer and restore it later. */
3295 save_in = input_line_pointer;
3296 input_line_pointer = str;
3297 if (inst.reloc.exp.X_op == O_symbol
3298 && *str == '('
3299 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3300 {
3301 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3302 inst.reloc.pc_rel = 0;
3303 /* Modify str to point to after parsed operands, otherwise
3304 end_of_line() will complain about the (PLT) left in str. */
3305 str = input_line_pointer;
3306 }
3307 else
3308 {
3309 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3310 inst.reloc.pc_rel = 1;
3311 }
3312 input_line_pointer = save_in;
3313 }
3314 #else
3315 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
3316 inst.reloc.pc_rel = 1;
3317 #endif /* OBJ_ELF */
3318
3319 end_of_line (str);
3320 return;
3321 }
3322
3323 static void
3324 do_bx (str, flags)
3325 char * str;
3326 unsigned long flags;
3327 {
3328 int reg;
3329
3330 skip_whitespace (str);
3331
3332 if ((reg = reg_required_here (&str, 0)) == FAIL)
3333 {
3334 inst.error = BAD_ARGS;
3335 return;
3336 }
3337
3338 if (reg == REG_PC)
3339 inst.error = BAD_PC;
3340
3341 end_of_line (str);
3342 }
3343
3344 static void
3345 do_cdp (str, flags)
3346 char * str;
3347 unsigned long flags;
3348 {
3349 /* Co-processor data operation.
3350 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
3351 skip_whitespace (str);
3352
3353 if (co_proc_number (&str) == FAIL)
3354 {
3355 if (!inst.error)
3356 inst.error = BAD_ARGS;
3357 return;
3358 }
3359
3360 if (skip_past_comma (&str) == FAIL
3361 || cp_opc_expr (&str, 20,4) == FAIL)
3362 {
3363 if (!inst.error)
3364 inst.error = BAD_ARGS;
3365 return;
3366 }
3367
3368 if (skip_past_comma (&str) == FAIL
3369 || cp_reg_required_here (&str, 12) == FAIL)
3370 {
3371 if (!inst.error)
3372 inst.error = BAD_ARGS;
3373 return;
3374 }
3375
3376 if (skip_past_comma (&str) == FAIL
3377 || cp_reg_required_here (&str, 16) == FAIL)
3378 {
3379 if (!inst.error)
3380 inst.error = BAD_ARGS;
3381 return;
3382 }
3383
3384 if (skip_past_comma (&str) == FAIL
3385 || cp_reg_required_here (&str, 0) == FAIL)
3386 {
3387 if (!inst.error)
3388 inst.error = BAD_ARGS;
3389 return;
3390 }
3391
3392 if (skip_past_comma (&str) == SUCCESS)
3393 {
3394 if (cp_opc_expr (&str, 5, 3) == FAIL)
3395 {
3396 if (!inst.error)
3397 inst.error = BAD_ARGS;
3398 return;
3399 }
3400 }
3401
3402 end_of_line (str);
3403 return;
3404 }
3405
3406 static void
3407 do_lstc (str, flags)
3408 char * str;
3409 unsigned long flags;
3410 {
3411 /* Co-processor register load/store.
3412 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
3413
3414 skip_whitespace (str);
3415
3416 if (co_proc_number (&str) == FAIL)
3417 {
3418 if (!inst.error)
3419 inst.error = BAD_ARGS;
3420 return;
3421 }
3422
3423 if (skip_past_comma (&str) == FAIL
3424 || cp_reg_required_here (&str, 12) == FAIL)
3425 {
3426 if (!inst.error)
3427 inst.error = BAD_ARGS;
3428 return;
3429 }
3430
3431 if (skip_past_comma (&str) == FAIL
3432 || cp_address_required_here (&str) == FAIL)
3433 {
3434 if (! inst.error)
3435 inst.error = BAD_ARGS;
3436 return;
3437 }
3438
3439 inst.instruction |= flags;
3440 end_of_line (str);
3441 return;
3442 }
3443
3444 static void
3445 do_co_reg (str, flags)
3446 char * str;
3447 unsigned long flags;
3448 {
3449 /* Co-processor register transfer.
3450 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
3451
3452 skip_whitespace (str);
3453
3454 if (co_proc_number (&str) == FAIL)
3455 {
3456 if (!inst.error)
3457 inst.error = BAD_ARGS;
3458 return;
3459 }
3460
3461 if (skip_past_comma (&str) == FAIL
3462 || cp_opc_expr (&str, 21, 3) == FAIL)
3463 {
3464 if (!inst.error)
3465 inst.error = BAD_ARGS;
3466 return;
3467 }
3468
3469 if (skip_past_comma (&str) == FAIL
3470 || reg_required_here (&str, 12) == FAIL)
3471 {
3472 if (!inst.error)
3473 inst.error = BAD_ARGS;
3474 return;
3475 }
3476
3477 if (skip_past_comma (&str) == FAIL
3478 || cp_reg_required_here (&str, 16) == FAIL)
3479 {
3480 if (!inst.error)
3481 inst.error = BAD_ARGS;
3482 return;
3483 }
3484
3485 if (skip_past_comma (&str) == FAIL
3486 || cp_reg_required_here (&str, 0) == FAIL)
3487 {
3488 if (!inst.error)
3489 inst.error = BAD_ARGS;
3490 return;
3491 }
3492
3493 if (skip_past_comma (&str) == SUCCESS)
3494 {
3495 if (cp_opc_expr (&str, 5, 3) == FAIL)
3496 {
3497 if (!inst.error)
3498 inst.error = BAD_ARGS;
3499 return;
3500 }
3501 }
3502 if (flags)
3503 {
3504 inst.error = BAD_COND;
3505 }
3506
3507 end_of_line (str);
3508 return;
3509 }
3510
3511 static void
3512 do_fp_ctrl (str, flags)
3513 char * str;
3514 unsigned long flags;
3515 {
3516 /* FP control registers.
3517 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
3518
3519 skip_whitespace (str);
3520
3521 if (reg_required_here (&str, 12) == FAIL)
3522 {
3523 if (!inst.error)
3524 inst.error = BAD_ARGS;
3525 return;
3526 }
3527
3528 end_of_line (str);
3529 return;
3530 }
3531
3532 static void
3533 do_fp_ldst (str, flags)
3534 char * str;
3535 unsigned long flags;
3536 {
3537 skip_whitespace (str);
3538
3539 switch (inst.suffix)
3540 {
3541 case SUFF_S:
3542 break;
3543 case SUFF_D:
3544 inst.instruction |= CP_T_X;
3545 break;
3546 case SUFF_E:
3547 inst.instruction |= CP_T_Y;
3548 break;
3549 case SUFF_P:
3550 inst.instruction |= CP_T_X | CP_T_Y;
3551 break;
3552 default:
3553 abort ();
3554 }
3555
3556 if (fp_reg_required_here (&str, 12) == FAIL)
3557 {
3558 if (!inst.error)
3559 inst.error = BAD_ARGS;
3560 return;
3561 }
3562
3563 if (skip_past_comma (&str) == FAIL
3564 || cp_address_required_here (&str) == FAIL)
3565 {
3566 if (!inst.error)
3567 inst.error = BAD_ARGS;
3568 return;
3569 }
3570
3571 end_of_line (str);
3572 }
3573
3574 static void
3575 do_fp_ldmstm (str, flags)
3576 char * str;
3577 unsigned long flags;
3578 {
3579 int num_regs;
3580
3581 skip_whitespace (str);
3582
3583 if (fp_reg_required_here (&str, 12) == FAIL)
3584 {
3585 if (! inst.error)
3586 inst.error = BAD_ARGS;
3587 return;
3588 }
3589
3590 /* Get Number of registers to transfer */
3591 if (skip_past_comma (&str) == FAIL
3592 || my_get_expression (&inst.reloc.exp, &str))
3593 {
3594 if (! inst.error)
3595 inst.error = _("constant expression expected");
3596 return;
3597 }
3598
3599 if (inst.reloc.exp.X_op != O_constant)
3600 {
3601 inst.error = _("Constant value required for number of registers");
3602 return;
3603 }
3604
3605 num_regs = inst.reloc.exp.X_add_number;
3606
3607 if (num_regs < 1 || num_regs > 4)
3608 {
3609 inst.error = _("number of registers must be in the range [1:4]");
3610 return;
3611 }
3612
3613 switch (num_regs)
3614 {
3615 case 1:
3616 inst.instruction |= CP_T_X;
3617 break;
3618 case 2:
3619 inst.instruction |= CP_T_Y;
3620 break;
3621 case 3:
3622 inst.instruction |= CP_T_Y | CP_T_X;
3623 break;
3624 case 4:
3625 break;
3626 default:
3627 abort ();
3628 }
3629
3630 if (flags)
3631 {
3632 int reg;
3633 int write_back;
3634 int offset;
3635
3636 /* The instruction specified "ea" or "fd", so we can only accept
3637 [Rn]{!}. The instruction does not really support stacking or
3638 unstacking, so we have to emulate these by setting appropriate
3639 bits and offsets. */
3640 if (skip_past_comma (&str) == FAIL
3641 || *str != '[')
3642 {
3643 if (! inst.error)
3644 inst.error = BAD_ARGS;
3645 return;
3646 }
3647
3648 str++;
3649 skip_whitespace (str);
3650
3651 if ((reg = reg_required_here (&str, 16)) == FAIL)
3652 return;
3653
3654 skip_whitespace (str);
3655
3656 if (*str != ']')
3657 {
3658 inst.error = BAD_ARGS;
3659 return;
3660 }
3661
3662 str++;
3663 if (*str == '!')
3664 {
3665 write_back = 1;
3666 str++;
3667 if (reg == REG_PC)
3668 {
3669 inst.error = _("R15 not allowed as base register with write-back");
3670 return;
3671 }
3672 }
3673 else
3674 write_back = 0;
3675
3676 if (flags & CP_T_Pre)
3677 {
3678 /* Pre-decrement */
3679 offset = 3 * num_regs;
3680 if (write_back)
3681 flags |= CP_T_WB;
3682 }
3683 else
3684 {
3685 /* Post-increment */
3686 if (write_back)
3687 {
3688 flags |= CP_T_WB;
3689 offset = 3 * num_regs;
3690 }
3691 else
3692 {
3693 /* No write-back, so convert this into a standard pre-increment
3694 instruction -- aesthetically more pleasing. */
3695 flags = CP_T_Pre | CP_T_UD;
3696 offset = 0;
3697 }
3698 }
3699
3700 inst.instruction |= flags | offset;
3701 }
3702 else if (skip_past_comma (&str) == FAIL
3703 || cp_address_required_here (&str) == FAIL)
3704 {
3705 if (! inst.error)
3706 inst.error = BAD_ARGS;
3707 return;
3708 }
3709
3710 end_of_line (str);
3711 }
3712
3713 static void
3714 do_fp_dyadic (str, flags)
3715 char * str;
3716 unsigned long flags;
3717 {
3718 skip_whitespace (str);
3719
3720 switch (inst.suffix)
3721 {
3722 case SUFF_S:
3723 break;
3724 case SUFF_D:
3725 inst.instruction |= 0x00000080;
3726 break;
3727 case SUFF_E:
3728 inst.instruction |= 0x00080000;
3729 break;
3730 default:
3731 abort ();
3732 }
3733
3734 if (fp_reg_required_here (&str, 12) == FAIL)
3735 {
3736 if (! inst.error)
3737 inst.error = BAD_ARGS;
3738 return;
3739 }
3740
3741 if (skip_past_comma (&str) == FAIL
3742 || fp_reg_required_here (&str, 16) == FAIL)
3743 {
3744 if (! inst.error)
3745 inst.error = BAD_ARGS;
3746 return;
3747 }
3748
3749 if (skip_past_comma (&str) == FAIL
3750 || fp_op2 (&str) == FAIL)
3751 {
3752 if (! inst.error)
3753 inst.error = BAD_ARGS;
3754 return;
3755 }
3756
3757 inst.instruction |= flags;
3758 end_of_line (str);
3759 return;
3760 }
3761
3762 static void
3763 do_fp_monadic (str, flags)
3764 char * str;
3765 unsigned long flags;
3766 {
3767 skip_whitespace (str);
3768
3769 switch (inst.suffix)
3770 {
3771 case SUFF_S:
3772 break;
3773 case SUFF_D:
3774 inst.instruction |= 0x00000080;
3775 break;
3776 case SUFF_E:
3777 inst.instruction |= 0x00080000;
3778 break;
3779 default:
3780 abort ();
3781 }
3782
3783 if (fp_reg_required_here (&str, 12) == FAIL)
3784 {
3785 if (! inst.error)
3786 inst.error = BAD_ARGS;
3787 return;
3788 }
3789
3790 if (skip_past_comma (&str) == FAIL
3791 || fp_op2 (&str) == FAIL)
3792 {
3793 if (! inst.error)
3794 inst.error = BAD_ARGS;
3795 return;
3796 }
3797
3798 inst.instruction |= flags;
3799 end_of_line (str);
3800 return;
3801 }
3802
3803 static void
3804 do_fp_cmp (str, flags)
3805 char * str;
3806 unsigned long flags;
3807 {
3808 skip_whitespace (str);
3809
3810 if (fp_reg_required_here (&str, 16) == FAIL)
3811 {
3812 if (! inst.error)
3813 inst.error = BAD_ARGS;
3814 return;
3815 }
3816
3817 if (skip_past_comma (&str) == FAIL
3818 || fp_op2 (&str) == FAIL)
3819 {
3820 if (! inst.error)
3821 inst.error = BAD_ARGS;
3822 return;
3823 }
3824
3825 inst.instruction |= flags;
3826 end_of_line (str);
3827 return;
3828 }
3829
3830 static void
3831 do_fp_from_reg (str, flags)
3832 char * str;
3833 unsigned long flags;
3834 {
3835 skip_whitespace (str);
3836
3837 switch (inst.suffix)
3838 {
3839 case SUFF_S:
3840 break;
3841 case SUFF_D:
3842 inst.instruction |= 0x00000080;
3843 break;
3844 case SUFF_E:
3845 inst.instruction |= 0x00080000;
3846 break;
3847 default:
3848 abort ();
3849 }
3850
3851 if (fp_reg_required_here (&str, 16) == FAIL)
3852 {
3853 if (! inst.error)
3854 inst.error = BAD_ARGS;
3855 return;
3856 }
3857
3858 if (skip_past_comma (&str) == FAIL
3859 || reg_required_here (&str, 12) == FAIL)
3860 {
3861 if (! inst.error)
3862 inst.error = BAD_ARGS;
3863 return;
3864 }
3865
3866 inst.instruction |= flags;
3867 end_of_line (str);
3868 return;
3869 }
3870
3871 static void
3872 do_fp_to_reg (str, flags)
3873 char * str;
3874 unsigned long flags;
3875 {
3876 skip_whitespace (str);
3877
3878 if (reg_required_here (&str, 12) == FAIL)
3879 return;
3880
3881 if (skip_past_comma (&str) == FAIL
3882 || fp_reg_required_here (&str, 0) == FAIL)
3883 {
3884 if (! inst.error)
3885 inst.error = BAD_ARGS;
3886 return;
3887 }
3888
3889 inst.instruction |= flags;
3890 end_of_line (str);
3891 return;
3892 }
3893
3894 /* Thumb specific routines */
3895
3896 /* Parse and validate that a register is of the right form, this saves
3897 repeated checking of this information in many similar cases.
3898 Unlike the 32-bit case we do not insert the register into the opcode
3899 here, since the position is often unknown until the full instruction
3900 has been parsed. */
3901 static int
3902 thumb_reg (strp, hi_lo)
3903 char ** strp;
3904 int hi_lo;
3905 {
3906 int reg;
3907
3908 if ((reg = reg_required_here (strp, -1)) == FAIL)
3909 return FAIL;
3910
3911 switch (hi_lo)
3912 {
3913 case THUMB_REG_LO:
3914 if (reg > 7)
3915 {
3916 inst.error = _("lo register required");
3917 return FAIL;
3918 }
3919 break;
3920
3921 case THUMB_REG_HI:
3922 if (reg < 8)
3923 {
3924 inst.error = _("hi register required");
3925 return FAIL;
3926 }
3927 break;
3928
3929 default:
3930 break;
3931 }
3932
3933 return reg;
3934 }
3935
3936 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
3937 was SUB. */
3938 static void
3939 thumb_add_sub (str, subtract)
3940 char * str;
3941 int subtract;
3942 {
3943 int Rd, Rs, Rn = FAIL;
3944
3945 skip_whitespace (str);
3946
3947 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
3948 || skip_past_comma (&str) == FAIL)
3949 {
3950 if (! inst.error)
3951 inst.error = BAD_ARGS;
3952 return;
3953 }
3954
3955 if (is_immediate_prefix (*str))
3956 {
3957 Rs = Rd;
3958 str++;
3959 if (my_get_expression (&inst.reloc.exp, &str))
3960 return;
3961 }
3962 else
3963 {
3964 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3965 return;
3966
3967 if (skip_past_comma (&str) == FAIL)
3968 {
3969 /* Two operand format, shuffle the registers and pretend there
3970 are 3 */
3971 Rn = Rs;
3972 Rs = Rd;
3973 }
3974 else if (is_immediate_prefix (*str))
3975 {
3976 str++;
3977 if (my_get_expression (&inst.reloc.exp, &str))
3978 return;
3979 }
3980 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
3981 return;
3982 }
3983
3984 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
3985 for the latter case, EXPR contains the immediate that was found. */
3986 if (Rn != FAIL)
3987 {
3988 /* All register format. */
3989 if (Rd > 7 || Rs > 7 || Rn > 7)
3990 {
3991 if (Rs != Rd)
3992 {
3993 inst.error = _("dest and source1 must be the same register");
3994 return;
3995 }
3996
3997 /* Can't do this for SUB */
3998 if (subtract)
3999 {
4000 inst.error = _("subtract valid only on lo regs");
4001 return;
4002 }
4003
4004 inst.instruction = (T_OPCODE_ADD_HI
4005 | (Rd > 7 ? THUMB_H1 : 0)
4006 | (Rn > 7 ? THUMB_H2 : 0));
4007 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
4008 }
4009 else
4010 {
4011 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
4012 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
4013 }
4014 }
4015 else
4016 {
4017 /* Immediate expression, now things start to get nasty. */
4018
4019 /* First deal with HI regs, only very restricted cases allowed:
4020 Adjusting SP, and using PC or SP to get an address. */
4021 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
4022 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
4023 {
4024 inst.error = _("invalid Hi register with immediate");
4025 return;
4026 }
4027
4028 if (inst.reloc.exp.X_op != O_constant)
4029 {
4030 /* Value isn't known yet, all we can do is store all the fragments
4031 we know about in the instruction and let the reloc hacking
4032 work it all out. */
4033 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
4034 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4035 }
4036 else
4037 {
4038 int offset = inst.reloc.exp.X_add_number;
4039
4040 if (subtract)
4041 offset = -offset;
4042
4043 if (offset < 0)
4044 {
4045 offset = -offset;
4046 subtract = 1;
4047
4048 /* Quick check, in case offset is MIN_INT */
4049 if (offset < 0)
4050 {
4051 inst.error = _("immediate value out of range");
4052 return;
4053 }
4054 }
4055 else
4056 subtract = 0;
4057
4058 if (Rd == REG_SP)
4059 {
4060 if (offset & ~0x1fc)
4061 {
4062 inst.error = _("invalid immediate value for stack adjust");
4063 return;
4064 }
4065 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
4066 inst.instruction |= offset >> 2;
4067 }
4068 else if (Rs == REG_PC || Rs == REG_SP)
4069 {
4070 if (subtract
4071 || (offset & ~0x3fc))
4072 {
4073 inst.error = _("invalid immediate for address calculation");
4074 return;
4075 }
4076 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
4077 : T_OPCODE_ADD_SP);
4078 inst.instruction |= (Rd << 8) | (offset >> 2);
4079 }
4080 else if (Rs == Rd)
4081 {
4082 if (offset & ~0xff)
4083 {
4084 inst.error = _("immediate value out of range");
4085 return;
4086 }
4087 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
4088 inst.instruction |= (Rd << 8) | offset;
4089 }
4090 else
4091 {
4092 if (offset & ~0x7)
4093 {
4094 inst.error = _("immediate value out of range");
4095 return;
4096 }
4097 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
4098 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
4099 }
4100 }
4101 }
4102 end_of_line (str);
4103 }
4104
4105 static void
4106 thumb_shift (str, shift)
4107 char * str;
4108 int shift;
4109 {
4110 int Rd, Rs, Rn = FAIL;
4111
4112 skip_whitespace (str);
4113
4114 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4115 || skip_past_comma (&str) == FAIL)
4116 {
4117 if (! inst.error)
4118 inst.error = BAD_ARGS;
4119 return;
4120 }
4121
4122 if (is_immediate_prefix (*str))
4123 {
4124 /* Two operand immediate format, set Rs to Rd. */
4125 Rs = Rd;
4126 str++;
4127 if (my_get_expression (&inst.reloc.exp, &str))
4128 return;
4129 }
4130 else
4131 {
4132 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4133 return;
4134
4135 if (skip_past_comma (&str) == FAIL)
4136 {
4137 /* Two operand format, shuffle the registers and pretend there
4138 are 3 */
4139 Rn = Rs;
4140 Rs = Rd;
4141 }
4142 else if (is_immediate_prefix (*str))
4143 {
4144 str++;
4145 if (my_get_expression (&inst.reloc.exp, &str))
4146 return;
4147 }
4148 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4149 return;
4150 }
4151
4152 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
4153 for the latter case, EXPR contains the immediate that was found. */
4154
4155 if (Rn != FAIL)
4156 {
4157 if (Rs != Rd)
4158 {
4159 inst.error = _("source1 and dest must be same register");
4160 return;
4161 }
4162
4163 switch (shift)
4164 {
4165 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
4166 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
4167 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
4168 }
4169
4170 inst.instruction |= Rd | (Rn << 3);
4171 }
4172 else
4173 {
4174 switch (shift)
4175 {
4176 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
4177 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
4178 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
4179 }
4180
4181 if (inst.reloc.exp.X_op != O_constant)
4182 {
4183 /* Value isn't known yet, create a dummy reloc and let reloc
4184 hacking fix it up */
4185
4186 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
4187 }
4188 else
4189 {
4190 unsigned shift_value = inst.reloc.exp.X_add_number;
4191
4192 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
4193 {
4194 inst.error = _("Invalid immediate for shift");
4195 return;
4196 }
4197
4198 /* Shifts of zero are handled by converting to LSL */
4199 if (shift_value == 0)
4200 inst.instruction = T_OPCODE_LSL_I;
4201
4202 /* Shifts of 32 are encoded as a shift of zero */
4203 if (shift_value == 32)
4204 shift_value = 0;
4205
4206 inst.instruction |= shift_value << 6;
4207 }
4208
4209 inst.instruction |= Rd | (Rs << 3);
4210 }
4211 end_of_line (str);
4212 }
4213
4214 static void
4215 thumb_mov_compare (str, move)
4216 char * str;
4217 int move;
4218 {
4219 int Rd, Rs = FAIL;
4220
4221 skip_whitespace (str);
4222
4223 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
4224 || skip_past_comma (&str) == FAIL)
4225 {
4226 if (! inst.error)
4227 inst.error = BAD_ARGS;
4228 return;
4229 }
4230
4231 if (is_immediate_prefix (*str))
4232 {
4233 str++;
4234 if (my_get_expression (&inst.reloc.exp, &str))
4235 return;
4236 }
4237 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4238 return;
4239
4240 if (Rs != FAIL)
4241 {
4242 if (Rs < 8 && Rd < 8)
4243 {
4244 if (move == THUMB_MOVE)
4245 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
4246 since a MOV instruction produces unpredictable results */
4247 inst.instruction = T_OPCODE_ADD_I3;
4248 else
4249 inst.instruction = T_OPCODE_CMP_LR;
4250 inst.instruction |= Rd | (Rs << 3);
4251 }
4252 else
4253 {
4254 if (move == THUMB_MOVE)
4255 inst.instruction = T_OPCODE_MOV_HR;
4256 else
4257 inst.instruction = T_OPCODE_CMP_HR;
4258
4259 if (Rd > 7)
4260 inst.instruction |= THUMB_H1;
4261
4262 if (Rs > 7)
4263 inst.instruction |= THUMB_H2;
4264
4265 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
4266 }
4267 }
4268 else
4269 {
4270 if (Rd > 7)
4271 {
4272 inst.error = _("only lo regs allowed with immediate");
4273 return;
4274 }
4275
4276 if (move == THUMB_MOVE)
4277 inst.instruction = T_OPCODE_MOV_I8;
4278 else
4279 inst.instruction = T_OPCODE_CMP_I8;
4280
4281 inst.instruction |= Rd << 8;
4282
4283 if (inst.reloc.exp.X_op != O_constant)
4284 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
4285 else
4286 {
4287 unsigned value = inst.reloc.exp.X_add_number;
4288
4289 if (value > 255)
4290 {
4291 inst.error = _("invalid immediate");
4292 return;
4293 }
4294
4295 inst.instruction |= value;
4296 }
4297 }
4298
4299 end_of_line (str);
4300 }
4301
4302 static void
4303 thumb_load_store (str, load_store, size)
4304 char * str;
4305 int load_store;
4306 int size;
4307 {
4308 int Rd, Rb, Ro = FAIL;
4309
4310 skip_whitespace (str);
4311
4312 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4313 || skip_past_comma (&str) == FAIL)
4314 {
4315 if (! inst.error)
4316 inst.error = BAD_ARGS;
4317 return;
4318 }
4319
4320 if (*str == '[')
4321 {
4322 str++;
4323 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4324 return;
4325
4326 if (skip_past_comma (&str) != FAIL)
4327 {
4328 if (is_immediate_prefix (*str))
4329 {
4330 str++;
4331 if (my_get_expression (&inst.reloc.exp, &str))
4332 return;
4333 }
4334 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4335 return;
4336 }
4337 else
4338 {
4339 inst.reloc.exp.X_op = O_constant;
4340 inst.reloc.exp.X_add_number = 0;
4341 }
4342
4343 if (*str != ']')
4344 {
4345 inst.error = _("expected ']'");
4346 return;
4347 }
4348 str++;
4349 }
4350 else if (*str == '=')
4351 {
4352 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op */
4353 str++;
4354
4355 skip_whitespace (str);
4356
4357 if (my_get_expression (& inst.reloc.exp, & str))
4358 return;
4359
4360 end_of_line (str);
4361
4362 if ( inst.reloc.exp.X_op != O_constant
4363 && inst.reloc.exp.X_op != O_symbol)
4364 {
4365 inst.error = "Constant expression expected";
4366 return;
4367 }
4368
4369 if (inst.reloc.exp.X_op == O_constant
4370 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
4371 {
4372 /* This can be done with a mov instruction */
4373
4374 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
4375 inst.instruction |= inst.reloc.exp.X_add_number;
4376 return;
4377 }
4378
4379 /* Insert into literal pool */
4380 if (add_to_lit_pool () == FAIL)
4381 {
4382 if (!inst.error)
4383 inst.error = "literal pool insertion failed";
4384 return;
4385 }
4386
4387 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4388 inst.reloc.pc_rel = 1;
4389 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4390 inst.reloc.exp.X_add_number += 4; /* Adjust ARM pipeline offset to Thumb */
4391
4392 return;
4393 }
4394 else
4395 {
4396 if (my_get_expression (&inst.reloc.exp, &str))
4397 return;
4398
4399 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
4400 inst.reloc.pc_rel = 1;
4401 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset */
4402 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4403 end_of_line (str);
4404 return;
4405 }
4406
4407 if (Rb == REG_PC || Rb == REG_SP)
4408 {
4409 if (size != THUMB_WORD)
4410 {
4411 inst.error = _("byte or halfword not valid for base register");
4412 return;
4413 }
4414 else if (Rb == REG_PC && load_store != THUMB_LOAD)
4415 {
4416 inst.error = _("R15 based store not allowed");
4417 return;
4418 }
4419 else if (Ro != FAIL)
4420 {
4421 inst.error = _("Invalid base register for register offset");
4422 return;
4423 }
4424
4425 if (Rb == REG_PC)
4426 inst.instruction = T_OPCODE_LDR_PC;
4427 else if (load_store == THUMB_LOAD)
4428 inst.instruction = T_OPCODE_LDR_SP;
4429 else
4430 inst.instruction = T_OPCODE_STR_SP;
4431
4432 inst.instruction |= Rd << 8;
4433 if (inst.reloc.exp.X_op == O_constant)
4434 {
4435 unsigned offset = inst.reloc.exp.X_add_number;
4436
4437 if (offset & ~0x3fc)
4438 {
4439 inst.error = _("invalid offset");
4440 return;
4441 }
4442
4443 inst.instruction |= offset >> 2;
4444 }
4445 else
4446 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4447 }
4448 else if (Rb > 7)
4449 {
4450 inst.error = _("invalid base register in load/store");
4451 return;
4452 }
4453 else if (Ro == FAIL)
4454 {
4455 /* Immediate offset */
4456 if (size == THUMB_WORD)
4457 inst.instruction = (load_store == THUMB_LOAD
4458 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
4459 else if (size == THUMB_HALFWORD)
4460 inst.instruction = (load_store == THUMB_LOAD
4461 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
4462 else
4463 inst.instruction = (load_store == THUMB_LOAD
4464 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
4465
4466 inst.instruction |= Rd | (Rb << 3);
4467
4468 if (inst.reloc.exp.X_op == O_constant)
4469 {
4470 unsigned offset = inst.reloc.exp.X_add_number;
4471
4472 if (offset & ~(0x1f << size))
4473 {
4474 inst.error = _("Invalid offset");
4475 return;
4476 }
4477 inst.instruction |= (offset >> size) << 6;
4478 }
4479 else
4480 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
4481 }
4482 else
4483 {
4484 /* Register offset */
4485 if (size == THUMB_WORD)
4486 inst.instruction = (load_store == THUMB_LOAD
4487 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
4488 else if (size == THUMB_HALFWORD)
4489 inst.instruction = (load_store == THUMB_LOAD
4490 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
4491 else
4492 inst.instruction = (load_store == THUMB_LOAD
4493 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
4494
4495 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4496 }
4497
4498 end_of_line (str);
4499 }
4500
4501 static void
4502 do_t_nop (str)
4503 char * str;
4504 {
4505 /* Do nothing */
4506 end_of_line (str);
4507 return;
4508 }
4509
4510 /* Handle the Format 4 instructions that do not have equivalents in other
4511 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
4512 BIC and MVN. */
4513 static void
4514 do_t_arit (str)
4515 char * str;
4516 {
4517 int Rd, Rs, Rn;
4518
4519 skip_whitespace (str);
4520
4521 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4522 || skip_past_comma (&str) == FAIL
4523 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4524 {
4525 inst.error = BAD_ARGS;
4526 return;
4527 }
4528
4529 if (skip_past_comma (&str) != FAIL)
4530 {
4531 /* Three operand format not allowed for TST, CMN, NEG and MVN.
4532 (It isn't allowed for CMP either, but that isn't handled by this
4533 function.) */
4534 if (inst.instruction == T_OPCODE_TST
4535 || inst.instruction == T_OPCODE_CMN
4536 || inst.instruction == T_OPCODE_NEG
4537 || inst.instruction == T_OPCODE_MVN)
4538 {
4539 inst.error = BAD_ARGS;
4540 return;
4541 }
4542
4543 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4544 return;
4545
4546 if (Rs != Rd)
4547 {
4548 inst.error = _("dest and source1 one must be the same register");
4549 return;
4550 }
4551 Rs = Rn;
4552 }
4553
4554 if (inst.instruction == T_OPCODE_MUL
4555 && Rs == Rd)
4556 as_tsktsk (_("Rs and Rd must be different in MUL"));
4557
4558 inst.instruction |= Rd | (Rs << 3);
4559 end_of_line (str);
4560 }
4561
4562 static void
4563 do_t_add (str)
4564 char * str;
4565 {
4566 thumb_add_sub (str, 0);
4567 }
4568
4569 static void
4570 do_t_asr (str)
4571 char * str;
4572 {
4573 thumb_shift (str, THUMB_ASR);
4574 }
4575
4576 static void
4577 do_t_branch9 (str)
4578 char * str;
4579 {
4580 if (my_get_expression (&inst.reloc.exp, &str))
4581 return;
4582 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
4583 inst.reloc.pc_rel = 1;
4584 end_of_line (str);
4585 }
4586
4587 static void
4588 do_t_branch12 (str)
4589 char * str;
4590 {
4591 if (my_get_expression (&inst.reloc.exp, &str))
4592 return;
4593 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
4594 inst.reloc.pc_rel = 1;
4595 end_of_line (str);
4596 }
4597
4598 /* Find the real, Thumb encoded start of a Thumb function. */
4599
4600 static symbolS *
4601 find_real_start (symbolP)
4602 symbolS * symbolP;
4603 {
4604 char * real_start;
4605 const char * name = S_GET_NAME (symbolP);
4606 symbolS * new_target;
4607
4608 /* This definiton must agree with the one in gcc/config/arm/thumb.c */
4609 #define STUB_NAME ".real_start_of"
4610
4611 if (name == NULL)
4612 abort();
4613
4614 /* Names that start with '.' are local labels, not function entry points.
4615 The compiler may generate BL instructions to these labels because it
4616 needs to perform a branch to a far away location. */
4617 if (name[0] == '.')
4618 return symbolP;
4619
4620 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
4621 sprintf (real_start, "%s%s", STUB_NAME, name);
4622
4623 new_target = symbol_find (real_start);
4624
4625 if (new_target == NULL)
4626 {
4627 as_warn ("Failed to find real start of function: %s\n", name);
4628 new_target = symbolP;
4629 }
4630
4631 free (real_start);
4632
4633 return new_target;
4634 }
4635
4636
4637 static void
4638 do_t_branch23 (str)
4639 char * str;
4640 {
4641 if (my_get_expression (& inst.reloc.exp, & str))
4642 return;
4643
4644 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
4645 inst.reloc.pc_rel = 1;
4646 end_of_line (str);
4647
4648 /* If the destination of the branch is a defined symbol which does not have
4649 the THUMB_FUNC attribute, then we must be calling a function which has
4650 the (interfacearm) attribute. We look for the Thumb entry point to that
4651 function and change the branch to refer to that function instead. */
4652 if ( inst.reloc.exp.X_op == O_symbol
4653 && inst.reloc.exp.X_add_symbol != NULL
4654 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
4655 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
4656 inst.reloc.exp.X_add_symbol = find_real_start (inst.reloc.exp.X_add_symbol);
4657 }
4658
4659 static void
4660 do_t_bx (str)
4661 char * str;
4662 {
4663 int reg;
4664
4665 skip_whitespace (str);
4666
4667 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
4668 return;
4669
4670 /* This sets THUMB_H2 from the top bit of reg. */
4671 inst.instruction |= reg << 3;
4672
4673 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
4674 should cause the alignment to be checked once it is known. This is
4675 because BX PC only works if the instruction is word aligned. */
4676
4677 end_of_line (str);
4678 }
4679
4680 static void
4681 do_t_compare (str)
4682 char * str;
4683 {
4684 thumb_mov_compare (str, THUMB_COMPARE);
4685 }
4686
4687 static void
4688 do_t_ldmstm (str)
4689 char * str;
4690 {
4691 int Rb;
4692 long range;
4693
4694 skip_whitespace (str);
4695
4696 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
4697 return;
4698
4699 if (*str != '!')
4700 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
4701 else
4702 str++;
4703
4704 if (skip_past_comma (&str) == FAIL
4705 || (range = reg_list (&str)) == FAIL)
4706 {
4707 if (! inst.error)
4708 inst.error = BAD_ARGS;
4709 return;
4710 }
4711
4712 if (inst.reloc.type != BFD_RELOC_NONE)
4713 {
4714 /* This really doesn't seem worth it. */
4715 inst.reloc.type = BFD_RELOC_NONE;
4716 inst.error = _("Expression too complex");
4717 return;
4718 }
4719
4720 if (range & ~0xff)
4721 {
4722 inst.error = _("only lo-regs valid in load/store multiple");
4723 return;
4724 }
4725
4726 inst.instruction |= (Rb << 8) | range;
4727 end_of_line (str);
4728 }
4729
4730 static void
4731 do_t_ldr (str)
4732 char * str;
4733 {
4734 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
4735 }
4736
4737 static void
4738 do_t_ldrb (str)
4739 char * str;
4740 {
4741 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
4742 }
4743
4744 static void
4745 do_t_ldrh (str)
4746 char * str;
4747 {
4748 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
4749 }
4750
4751 static void
4752 do_t_lds (str)
4753 char * str;
4754 {
4755 int Rd, Rb, Ro;
4756
4757 skip_whitespace (str);
4758
4759 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4760 || skip_past_comma (&str) == FAIL
4761 || *str++ != '['
4762 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4763 || skip_past_comma (&str) == FAIL
4764 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
4765 || *str++ != ']')
4766 {
4767 if (! inst.error)
4768 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
4769 return;
4770 }
4771
4772 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
4773 end_of_line (str);
4774 }
4775
4776 static void
4777 do_t_lsl (str)
4778 char * str;
4779 {
4780 thumb_shift (str, THUMB_LSL);
4781 }
4782
4783 static void
4784 do_t_lsr (str)
4785 char * str;
4786 {
4787 thumb_shift (str, THUMB_LSR);
4788 }
4789
4790 static void
4791 do_t_mov (str)
4792 char * str;
4793 {
4794 thumb_mov_compare (str, THUMB_MOVE);
4795 }
4796
4797 static void
4798 do_t_push_pop (str)
4799 char * str;
4800 {
4801 long range;
4802
4803 skip_whitespace (str);
4804
4805 if ((range = reg_list (&str)) == FAIL)
4806 {
4807 if (! inst.error)
4808 inst.error = BAD_ARGS;
4809 return;
4810 }
4811
4812 if (inst.reloc.type != BFD_RELOC_NONE)
4813 {
4814 /* This really doesn't seem worth it. */
4815 inst.reloc.type = BFD_RELOC_NONE;
4816 inst.error = _("Expression too complex");
4817 return;
4818 }
4819
4820 if (range & ~0xff)
4821 {
4822 if ((inst.instruction == T_OPCODE_PUSH
4823 && (range & ~0xff) == 1 << REG_LR)
4824 || (inst.instruction == T_OPCODE_POP
4825 && (range & ~0xff) == 1 << REG_PC))
4826 {
4827 inst.instruction |= THUMB_PP_PC_LR;
4828 range &= 0xff;
4829 }
4830 else
4831 {
4832 inst.error = _("invalid register list to push/pop instruction");
4833 return;
4834 }
4835 }
4836
4837 inst.instruction |= range;
4838 end_of_line (str);
4839 }
4840
4841 static void
4842 do_t_str (str)
4843 char * str;
4844 {
4845 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
4846 }
4847
4848 static void
4849 do_t_strb (str)
4850 char * str;
4851 {
4852 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
4853 }
4854
4855 static void
4856 do_t_strh (str)
4857 char * str;
4858 {
4859 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
4860 }
4861
4862 static void
4863 do_t_sub (str)
4864 char * str;
4865 {
4866 thumb_add_sub (str, 1);
4867 }
4868
4869 static void
4870 do_t_swi (str)
4871 char * str;
4872 {
4873 skip_whitespace (str);
4874
4875 if (my_get_expression (&inst.reloc.exp, &str))
4876 return;
4877
4878 inst.reloc.type = BFD_RELOC_ARM_SWI;
4879 end_of_line (str);
4880 return;
4881 }
4882
4883 static void
4884 do_t_adr (str)
4885 char * str;
4886 {
4887 /* This is a pseudo-op of the form "adr rd, label" to be converted
4888 into a relative address of the form "add rd, pc, #label-.-4" */
4889 skip_whitespace (str);
4890
4891 if (reg_required_here (&str, 4) == FAIL /* Store Rd in temporary location inside instruction. */
4892 || skip_past_comma (&str) == FAIL
4893 || my_get_expression (&inst.reloc.exp, &str))
4894 {
4895 if (!inst.error)
4896 inst.error = BAD_ARGS;
4897 return;
4898 }
4899
4900 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
4901 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust */
4902 inst.reloc.pc_rel = 1;
4903 inst.instruction |= REG_PC; /* Rd is already placed into the instruction */
4904 end_of_line (str);
4905 }
4906
4907 static void
4908 insert_reg (entry)
4909 int entry;
4910 {
4911 int len = strlen (reg_table[entry].name) + 2;
4912 char * buf = (char *) xmalloc (len);
4913 char * buf2 = (char *) xmalloc (len);
4914 int i = 0;
4915
4916 #ifdef REGISTER_PREFIX
4917 buf[i++] = REGISTER_PREFIX;
4918 #endif
4919
4920 strcpy (buf + i, reg_table[entry].name);
4921
4922 for (i = 0; buf[i]; i++)
4923 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
4924
4925 buf2[i] = '\0';
4926
4927 hash_insert (arm_reg_hsh, buf, (PTR) &reg_table[entry]);
4928 hash_insert (arm_reg_hsh, buf2, (PTR) &reg_table[entry]);
4929 }
4930
4931 static void
4932 insert_reg_alias (str, regnum)
4933 char *str;
4934 int regnum;
4935 {
4936 struct reg_entry *new =
4937 (struct reg_entry *)xmalloc (sizeof (struct reg_entry));
4938 char *name = xmalloc (strlen (str) + 1);
4939 strcpy (name, str);
4940
4941 new->name = name;
4942 new->number = regnum;
4943
4944 hash_insert (arm_reg_hsh, name, (PTR) new);
4945 }
4946
4947 static void
4948 set_constant_flonums ()
4949 {
4950 int i;
4951
4952 for (i = 0; i < NUM_FLOAT_VALS; i++)
4953 if (atof_ieee ((char *)fp_const[i], 'x', fp_values[i]) == NULL)
4954 abort ();
4955 }
4956
4957 void
4958 md_begin ()
4959 {
4960 int i;
4961
4962 if ( (arm_ops_hsh = hash_new ()) == NULL
4963 || (arm_tops_hsh = hash_new ()) == NULL
4964 || (arm_cond_hsh = hash_new ()) == NULL
4965 || (arm_shift_hsh = hash_new ()) == NULL
4966 || (arm_reg_hsh = hash_new ()) == NULL
4967 || (arm_psr_hsh = hash_new ()) == NULL)
4968 as_fatal (_("Virtual memory exhausted"));
4969
4970 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
4971 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
4972 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
4973 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
4974 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
4975 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
4976 for (i = 0; i < sizeof (shift) / sizeof (struct asm_shift); i++)
4977 hash_insert (arm_shift_hsh, shift[i].template, (PTR) (shift + i));
4978 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
4979 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
4980
4981 for (i = 0; reg_table[i].name; i++)
4982 insert_reg (i);
4983
4984 set_constant_flonums ();
4985
4986 #if defined OBJ_COFF || defined OBJ_ELF
4987 {
4988 unsigned int flags = 0;
4989
4990 /* Set the flags in the private structure */
4991 if (uses_apcs_26) flags |= F_APCS26;
4992 if (support_interwork) flags |= F_INTERWORK;
4993 if (uses_apcs_float) flags |= F_APCS_FLOAT;
4994 if (pic_code) flags |= F_PIC;
4995 if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT;
4996
4997 bfd_set_private_flags (stdoutput, flags);
4998 }
4999 #endif
5000
5001 {
5002 unsigned mach;
5003
5004 /* Record the CPU type as well */
5005 switch (cpu_variant & ARM_CPU_MASK)
5006 {
5007 case ARM_2:
5008 mach = bfd_mach_arm_2;
5009 break;
5010
5011 case ARM_3: /* also ARM_250 */
5012 mach = bfd_mach_arm_2a;
5013 break;
5014
5015 default:
5016 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined */
5017 mach = bfd_mach_arm_4;
5018 break;
5019
5020 case ARM_7: /* also ARM_6 */
5021 mach = bfd_mach_arm_3;
5022 break;
5023 }
5024
5025 /* Catch special cases. */
5026 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
5027 {
5028 if (cpu_variant & (ARM_EXT_V5 & ARM_THUMB))
5029 mach = bfd_mach_arm_5T;
5030 else if (cpu_variant & ARM_EXT_V5)
5031 mach = bfd_mach_arm_5;
5032 else if (cpu_variant & ARM_THUMB)
5033 mach = bfd_mach_arm_4T;
5034 else if ((cpu_variant & ARM_ARCH_V4) == ARM_ARCH_V4)
5035 mach = bfd_mach_arm_4;
5036 else if (cpu_variant & ARM_LONGMUL)
5037 mach = bfd_mach_arm_3M;
5038 }
5039
5040 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
5041 }
5042 }
5043
5044 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
5045 for use in the a.out file, and stores them in the array pointed to by buf.
5046 This knows about the endian-ness of the target machine and does
5047 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
5048 2 (short) and 4 (long) Floating numbers are put out as a series of
5049 LITTLENUMS (shorts, here at least). */
5050 void
5051 md_number_to_chars (buf, val, n)
5052 char * buf;
5053 valueT val;
5054 int n;
5055 {
5056 if (target_big_endian)
5057 number_to_chars_bigendian (buf, val, n);
5058 else
5059 number_to_chars_littleendian (buf, val, n);
5060 }
5061
5062 static valueT
5063 md_chars_to_number (buf, n)
5064 char * buf;
5065 int n;
5066 {
5067 valueT result = 0;
5068 unsigned char * where = (unsigned char *) buf;
5069
5070 if (target_big_endian)
5071 {
5072 while (n--)
5073 {
5074 result <<= 8;
5075 result |= (*where++ & 255);
5076 }
5077 }
5078 else
5079 {
5080 while (n--)
5081 {
5082 result <<= 8;
5083 result |= (where[n] & 255);
5084 }
5085 }
5086
5087 return result;
5088 }
5089
5090 /* Turn a string in input_line_pointer into a floating point constant
5091 of type TYPE, and store the appropriate bytes in *litP. The number
5092 of LITTLENUMS emitted is stored in *sizeP . An error message is
5093 returned, or NULL on OK.
5094
5095 Note that fp constants aren't represent in the normal way on the ARM.
5096 In big endian mode, things are as expected. However, in little endian
5097 mode fp constants are big-endian word-wise, and little-endian byte-wise
5098 within the words. For example, (double) 1.1 in big endian mode is
5099 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
5100 the byte sequence 99 99 f1 3f 9a 99 99 99.
5101
5102 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
5103
5104 char *
5105 md_atof (type, litP, sizeP)
5106 char type;
5107 char * litP;
5108 int * sizeP;
5109 {
5110 int prec;
5111 LITTLENUM_TYPE words[MAX_LITTLENUMS];
5112 char *t;
5113 int i;
5114
5115 switch (type)
5116 {
5117 case 'f':
5118 case 'F':
5119 case 's':
5120 case 'S':
5121 prec = 2;
5122 break;
5123
5124 case 'd':
5125 case 'D':
5126 case 'r':
5127 case 'R':
5128 prec = 4;
5129 break;
5130
5131 case 'x':
5132 case 'X':
5133 prec = 6;
5134 break;
5135
5136 case 'p':
5137 case 'P':
5138 prec = 6;
5139 break;
5140
5141 default:
5142 *sizeP = 0;
5143 return _("Bad call to MD_ATOF()");
5144 }
5145
5146 t = atof_ieee (input_line_pointer, type, words);
5147 if (t)
5148 input_line_pointer = t;
5149 *sizeP = prec * 2;
5150
5151 if (target_big_endian)
5152 {
5153 for (i = 0; i < prec; i++)
5154 {
5155 md_number_to_chars (litP, (valueT) words[i], 2);
5156 litP += 2;
5157 }
5158 }
5159 else
5160 {
5161 /* For a 4 byte float the order of elements in `words' is 1 0. For an
5162 8 byte float the order is 1 0 3 2. */
5163 for (i = 0; i < prec; i += 2)
5164 {
5165 md_number_to_chars (litP, (valueT) words[i + 1], 2);
5166 md_number_to_chars (litP + 2, (valueT) words[i], 2);
5167 litP += 4;
5168 }
5169 }
5170
5171 return 0;
5172 }
5173
5174 /* The knowledge of the PC's pipeline offset is built into the insns themselves. */
5175 long
5176 md_pcrel_from (fixP)
5177 fixS * fixP;
5178 {
5179 if ( fixP->fx_addsy
5180 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
5181 && fixP->fx_subsy == NULL)
5182 return 0;
5183
5184 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
5185 {
5186 /* PC relative addressing on the Thumb is slightly odd
5187 as the bottom two bits of the PC are forced to zero
5188 for the calculation. */
5189 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
5190 }
5191
5192 return fixP->fx_where + fixP->fx_frag->fr_address;
5193 }
5194
5195 /* Round up a section size to the appropriate boundary. */
5196 valueT
5197 md_section_align (segment, size)
5198 segT segment;
5199 valueT size;
5200 {
5201 #ifdef OBJ_ELF
5202 return size;
5203 #else
5204 /* Round all sects to multiple of 4 */
5205 return (size + 3) & ~3;
5206 #endif
5207 }
5208
5209 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5210 we have no need to default values of symbols. */
5211
5212 /* ARGSUSED */
5213 symbolS *
5214 md_undefined_symbol (name)
5215 char * name;
5216 {
5217 #ifdef OBJ_ELF
5218 if (name[0] == '_' && name[1] == 'G'
5219 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
5220 {
5221 if (!GOT_symbol)
5222 {
5223 if (symbol_find (name))
5224 as_bad ("GOT already in the symbol table");
5225
5226 GOT_symbol = symbol_new (name, undefined_section,
5227 (valueT)0, & zero_address_frag);
5228 }
5229
5230 return GOT_symbol;
5231 }
5232 #endif
5233
5234 return 0;
5235 }
5236
5237 /* arm_reg_parse () := if it looks like a register, return its token and
5238 advance the pointer. */
5239
5240 static int
5241 arm_reg_parse (ccp)
5242 register char ** ccp;
5243 {
5244 char * start = * ccp;
5245 char c;
5246 char * p;
5247 struct reg_entry * reg;
5248
5249 #ifdef REGISTER_PREFIX
5250 if (*start != REGISTER_PREFIX)
5251 return FAIL;
5252 p = start + 1;
5253 #else
5254 p = start;
5255 #ifdef OPTIONAL_REGISTER_PREFIX
5256 if (*p == OPTIONAL_REGISTER_PREFIX)
5257 p++, start++;
5258 #endif
5259 #endif
5260 if (!isalpha (*p) || !is_name_beginner (*p))
5261 return FAIL;
5262
5263 c = *p++;
5264 while (isalpha (c) || isdigit (c) || c == '_')
5265 c = *p++;
5266
5267 *--p = 0;
5268 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
5269 *p = c;
5270
5271 if (reg)
5272 {
5273 *ccp = p;
5274 return reg->number;
5275 }
5276
5277 return FAIL;
5278 }
5279
5280 static int
5281 arm_psr_parse (ccp)
5282 register char ** ccp;
5283 {
5284 char * start = * ccp;
5285 char c;
5286 char * p;
5287 CONST struct asm_psr * psr;
5288
5289 p = start;
5290 c = *p++;
5291 while (isalpha (c) || c == '_')
5292 c = *p++;
5293
5294 *--p = 0;
5295 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
5296 *p = c;
5297
5298 if (psr)
5299 {
5300 *ccp = p;
5301 return psr->number;
5302 }
5303
5304 return FAIL;
5305 }
5306
5307 int
5308 md_apply_fix3 (fixP, val, seg)
5309 fixS * fixP;
5310 valueT * val;
5311 segT seg;
5312 {
5313 offsetT value = * val;
5314 offsetT newval;
5315 unsigned int newimm;
5316 unsigned long temp;
5317 int sign;
5318 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5319 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
5320
5321 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5322
5323 /* Note whether this will delete the relocation. */
5324 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5325 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
5326 && !fixP->fx_pcrel)
5327 #else
5328 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5329 #endif
5330 fixP->fx_done = 1;
5331
5332 /* If this symbol is in a different section then we need to leave it for
5333 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5334 so we have to undo it's effects here. */
5335 if (fixP->fx_pcrel)
5336 {
5337 if (fixP->fx_addsy != NULL
5338 && S_IS_DEFINED (fixP->fx_addsy)
5339 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5340 {
5341 if (target_oabi
5342 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
5343 ))
5344 value = 0;
5345 else
5346 value += md_pcrel_from (fixP);
5347 }
5348 }
5349
5350 fixP->fx_addnumber = value; /* Remember value for emit_reloc. */
5351
5352 switch (fixP->fx_r_type)
5353 {
5354 case BFD_RELOC_ARM_IMMEDIATE:
5355 newimm = validate_immediate (value);
5356 temp = md_chars_to_number (buf, INSN_SIZE);
5357
5358 /* If the instruction will fail, see if we can fix things up by
5359 changing the opcode. */
5360 if (newimm == (unsigned int) FAIL
5361 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5362 {
5363 as_bad_where (fixP->fx_file, fixP->fx_line,
5364 _("invalid constant (%lx) after fixup"),
5365 (unsigned long) value);
5366 break;
5367 }
5368
5369 newimm |= (temp & 0xfffff000);
5370 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5371 break;
5372
5373 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5374 {
5375 unsigned int highpart = 0;
5376 unsigned int newinsn = 0xe1a00000; /* nop */
5377 newimm = validate_immediate (value);
5378 temp = md_chars_to_number (buf, INSN_SIZE);
5379
5380 /* If the instruction will fail, see if we can fix things up by
5381 changing the opcode. */
5382 if (newimm == (unsigned int) FAIL
5383 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
5384 {
5385 /* No ? OK - try using two ADD instructions to generate the value. */
5386 newimm = validate_immediate_twopart (value, & highpart);
5387
5388 /* Yes - then make sure that the second instruction is also an add. */
5389 if (newimm != (unsigned int) FAIL)
5390 newinsn = temp;
5391 /* Still No ? Try using a negated value. */
5392 else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL)
5393 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
5394 /* Otherwise - give up. */
5395 else
5396 {
5397 as_bad_where (fixP->fx_file, fixP->fx_line,
5398 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value);
5399 break;
5400 }
5401
5402 /* Replace the first operand in the 2nd instruction (which is the PC)
5403 with the destination register. We have already added in the PC in the
5404 first instruction and we do not want to do it again. */
5405 newinsn &= ~ 0xf0000;
5406 newinsn |= ((newinsn & 0x0f000) << 4);
5407 }
5408
5409 newimm |= (temp & 0xfffff000);
5410 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5411
5412 highpart |= (newinsn & 0xfffff000);
5413 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
5414 }
5415 break;
5416
5417 case BFD_RELOC_ARM_OFFSET_IMM:
5418 sign = value >= 0;
5419
5420 if (value < 0)
5421 value = - value;
5422
5423 if (validate_offset_imm (value, 0) == FAIL)
5424 {
5425 as_bad_where (fixP->fx_file, fixP->fx_line,
5426 _("bad immediate value for offset (%ld)"), (long) value);
5427 break;
5428 }
5429
5430 newval = md_chars_to_number (buf, INSN_SIZE);
5431 newval &= 0xff7ff000;
5432 newval |= value | (sign ? INDEX_UP : 0);
5433 md_number_to_chars (buf, newval, INSN_SIZE);
5434 break;
5435
5436 case BFD_RELOC_ARM_OFFSET_IMM8:
5437 case BFD_RELOC_ARM_HWLITERAL:
5438 sign = value >= 0;
5439
5440 if (value < 0)
5441 value = - value;
5442
5443 if (validate_offset_imm (value, 1) == FAIL)
5444 {
5445 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
5446 as_bad_where (fixP->fx_file, fixP->fx_line,
5447 _("invalid literal constant: pool needs to be closer"));
5448 else
5449 as_bad (_("bad immediate value for half-word offset (%ld)"),
5450 (long) value);
5451 break;
5452 }
5453
5454 newval = md_chars_to_number (buf, INSN_SIZE);
5455 newval &= 0xff7ff0f0;
5456 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
5457 md_number_to_chars (buf, newval, INSN_SIZE);
5458 break;
5459
5460 case BFD_RELOC_ARM_LITERAL:
5461 sign = value >= 0;
5462
5463 if (value < 0)
5464 value = - value;
5465
5466 if (validate_offset_imm (value, 0) == FAIL)
5467 {
5468 as_bad_where (fixP->fx_file, fixP->fx_line,
5469 _("invalid literal constant: pool needs to be closer"));
5470 break;
5471 }
5472
5473 newval = md_chars_to_number (buf, INSN_SIZE);
5474 newval &= 0xff7ff000;
5475 newval |= value | (sign ? INDEX_UP : 0);
5476 md_number_to_chars (buf, newval, INSN_SIZE);
5477 break;
5478
5479 case BFD_RELOC_ARM_SHIFT_IMM:
5480 newval = md_chars_to_number (buf, INSN_SIZE);
5481 if (((unsigned long) value) > 32
5482 || (value == 32
5483 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5484 {
5485 as_bad_where (fixP->fx_file, fixP->fx_line,
5486 _("shift expression is too large"));
5487 break;
5488 }
5489
5490 if (value == 0)
5491 newval &= ~0x60; /* Shifts of zero must be done as lsl */
5492 else if (value == 32)
5493 value = 0;
5494 newval &= 0xfffff07f;
5495 newval |= (value & 0x1f) << 7;
5496 md_number_to_chars (buf, newval , INSN_SIZE);
5497 break;
5498
5499 case BFD_RELOC_ARM_SWI:
5500 if (arm_data->thumb_mode)
5501 {
5502 if (((unsigned long) value) > 0xff)
5503 as_bad_where (fixP->fx_file, fixP->fx_line,
5504 _("Invalid swi expression"));
5505 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5506 newval |= value;
5507 md_number_to_chars (buf, newval, THUMB_SIZE);
5508 }
5509 else
5510 {
5511 if (((unsigned long) value) > 0x00ffffff)
5512 as_bad_where (fixP->fx_file, fixP->fx_line,
5513 _("Invalid swi expression"));
5514 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5515 newval |= value;
5516 md_number_to_chars (buf, newval , INSN_SIZE);
5517 }
5518 break;
5519
5520 case BFD_RELOC_ARM_MULTI:
5521 if (((unsigned long) value) > 0xffff)
5522 as_bad_where (fixP->fx_file, fixP->fx_line,
5523 _("Invalid expression in load/store multiple"));
5524 newval = value | md_chars_to_number (buf, INSN_SIZE);
5525 md_number_to_chars (buf, newval, INSN_SIZE);
5526 break;
5527
5528 case BFD_RELOC_ARM_PCREL_BRANCH:
5529 newval = md_chars_to_number (buf, INSN_SIZE);
5530
5531 #ifdef OBJ_ELF
5532 if (! target_oabi)
5533 value = fixP->fx_offset;
5534 #endif
5535 value = (value >> 2) & 0x00ffffff;
5536 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5537 newval = value | (newval & 0xff000000);
5538 md_number_to_chars (buf, newval, INSN_SIZE);
5539 break;
5540
5541
5542 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5543 newval = md_chars_to_number (buf, THUMB_SIZE);
5544 {
5545 addressT diff = (newval & 0xff) << 1;
5546 if (diff & 0x100)
5547 diff |= ~0xff;
5548
5549 value += diff;
5550 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5551 as_bad_where (fixP->fx_file, fixP->fx_line,
5552 _("Branch out of range"));
5553 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5554 }
5555 md_number_to_chars (buf, newval, THUMB_SIZE);
5556 break;
5557
5558 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5559 newval = md_chars_to_number (buf, THUMB_SIZE);
5560 {
5561 addressT diff = (newval & 0x7ff) << 1;
5562 if (diff & 0x800)
5563 diff |= ~0x7ff;
5564
5565 value += diff;
5566 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5567 as_bad_where (fixP->fx_file, fixP->fx_line,
5568 _("Branch out of range"));
5569 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5570 }
5571 md_number_to_chars (buf, newval, THUMB_SIZE);
5572 break;
5573
5574 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5575 {
5576 offsetT newval2;
5577 addressT diff;
5578
5579 newval = md_chars_to_number (buf, THUMB_SIZE);
5580 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5581 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5582 if (diff & 0x400000)
5583 diff |= ~0x3fffff;
5584 #ifdef OBJ_ELF
5585 value = fixP->fx_offset;
5586 #endif
5587 value += diff;
5588 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5589 as_bad_where (fixP->fx_file, fixP->fx_line,
5590 _("Branch with link out of range"));
5591
5592 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5593 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5594 md_number_to_chars (buf, newval, THUMB_SIZE);
5595 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5596 }
5597 break;
5598
5599 case BFD_RELOC_8:
5600 if (fixP->fx_done || fixP->fx_pcrel)
5601 md_number_to_chars (buf, value, 1);
5602 #ifdef OBJ_ELF
5603 else if (!target_oabi)
5604 {
5605 value = fixP->fx_offset;
5606 md_number_to_chars (buf, value, 1);
5607 }
5608 #endif
5609 break;
5610
5611 case BFD_RELOC_16:
5612 if (fixP->fx_done || fixP->fx_pcrel)
5613 md_number_to_chars (buf, value, 2);
5614 #ifdef OBJ_ELF
5615 else if (!target_oabi)
5616 {
5617 value = fixP->fx_offset;
5618 md_number_to_chars (buf, value, 2);
5619 }
5620 #endif
5621 break;
5622
5623 #ifdef OBJ_ELF
5624 case BFD_RELOC_ARM_GOT32:
5625 case BFD_RELOC_ARM_GOTOFF:
5626 md_number_to_chars (buf, 0, 4);
5627 break;
5628 #endif
5629
5630 case BFD_RELOC_RVA:
5631 case BFD_RELOC_32:
5632 if (fixP->fx_done || fixP->fx_pcrel)
5633 md_number_to_chars (buf, value, 4);
5634 #ifdef OBJ_ELF
5635 else if (!target_oabi)
5636 {
5637 value = fixP->fx_offset;
5638 md_number_to_chars (buf, value, 4);
5639 }
5640 #endif
5641 break;
5642
5643 #ifdef OBJ_ELF
5644 case BFD_RELOC_ARM_PLT32:
5645 /* It appears the instruction is fully prepared at this point. */
5646 break;
5647 #endif
5648
5649 case BFD_RELOC_ARM_GOTPC:
5650 md_number_to_chars (buf, value, 4);
5651 break;
5652
5653 case BFD_RELOC_ARM_CP_OFF_IMM:
5654 sign = value >= 0;
5655 if (value < -1023 || value > 1023 || (value & 3))
5656 as_bad_where (fixP->fx_file, fixP->fx_line,
5657 _("Illegal value for co-processor offset"));
5658 if (value < 0)
5659 value = -value;
5660 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5661 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5662 md_number_to_chars (buf, newval , INSN_SIZE);
5663 break;
5664
5665 case BFD_RELOC_ARM_THUMB_OFFSET:
5666 newval = md_chars_to_number (buf, THUMB_SIZE);
5667 /* Exactly what ranges, and where the offset is inserted depends on
5668 the type of instruction, we can establish this from the top 4 bits */
5669 switch (newval >> 12)
5670 {
5671 case 4: /* PC load */
5672 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5673 forced to zero for these loads, so we will need to round
5674 up the offset if the instruction address is not word
5675 aligned (since the final address produced must be, and
5676 we can only describe word-aligned immediate offsets). */
5677
5678 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5679 as_bad_where (fixP->fx_file, fixP->fx_line,
5680 _("Invalid offset, target not word aligned (0x%08X)"),
5681 (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5682
5683 if ((value + 2) & ~0x3fe)
5684 as_bad_where (fixP->fx_file, fixP->fx_line,
5685 _("Invalid offset, value too big (0x%08X)"), value);
5686
5687 /* Round up, since pc will be rounded down. */
5688 newval |= (value + 2) >> 2;
5689 break;
5690
5691 case 9: /* SP load/store */
5692 if (value & ~0x3fc)
5693 as_bad_where (fixP->fx_file, fixP->fx_line,
5694 _("Invalid offset, value too big (0x%08X)"), value);
5695 newval |= value >> 2;
5696 break;
5697
5698 case 6: /* Word load/store */
5699 if (value & ~0x7c)
5700 as_bad_where (fixP->fx_file, fixP->fx_line,
5701 _("Invalid offset, value too big (0x%08X)"), value);
5702 newval |= value << 4; /* 6 - 2 */
5703 break;
5704
5705 case 7: /* Byte load/store */
5706 if (value & ~0x1f)
5707 as_bad_where (fixP->fx_file, fixP->fx_line,
5708 _("Invalid offset, value too big (0x%08X)"), value);
5709 newval |= value << 6;
5710 break;
5711
5712 case 8: /* Halfword load/store */
5713 if (value & ~0x3e)
5714 as_bad_where (fixP->fx_file, fixP->fx_line,
5715 _("Invalid offset, value too big (0x%08X)"), value);
5716 newval |= value << 5; /* 6 - 1 */
5717 break;
5718
5719 default:
5720 as_bad_where (fixP->fx_file, fixP->fx_line,
5721 "Unable to process relocation for thumb opcode: %lx",
5722 (unsigned long) newval);
5723 break;
5724 }
5725 md_number_to_chars (buf, newval, THUMB_SIZE);
5726 break;
5727
5728 case BFD_RELOC_ARM_THUMB_ADD:
5729 /* This is a complicated relocation, since we use it for all of
5730 the following immediate relocations:
5731 3bit ADD/SUB
5732 8bit ADD/SUB
5733 9bit ADD/SUB SP word-aligned
5734 10bit ADD PC/SP word-aligned
5735
5736 The type of instruction being processed is encoded in the
5737 instruction field:
5738 0x8000 SUB
5739 0x00F0 Rd
5740 0x000F Rs
5741 */
5742 newval = md_chars_to_number (buf, THUMB_SIZE);
5743 {
5744 int rd = (newval >> 4) & 0xf;
5745 int rs = newval & 0xf;
5746 int subtract = newval & 0x8000;
5747
5748 if (rd == REG_SP)
5749 {
5750 if (value & ~0x1fc)
5751 as_bad_where (fixP->fx_file, fixP->fx_line,
5752 _("Invalid immediate for stack address calculation"));
5753 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5754 newval |= value >> 2;
5755 }
5756 else if (rs == REG_PC || rs == REG_SP)
5757 {
5758 if (subtract ||
5759 value & ~0x3fc)
5760 as_bad_where (fixP->fx_file, fixP->fx_line,
5761 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5762 (unsigned long) value);
5763 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5764 newval |= rd << 8;
5765 newval |= value >> 2;
5766 }
5767 else if (rs == rd)
5768 {
5769 if (value & ~0xff)
5770 as_bad_where (fixP->fx_file, fixP->fx_line,
5771 _("Invalid 8bit immediate"));
5772 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5773 newval |= (rd << 8) | value;
5774 }
5775 else
5776 {
5777 if (value & ~0x7)
5778 as_bad_where (fixP->fx_file, fixP->fx_line,
5779 _("Invalid 3bit immediate"));
5780 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5781 newval |= rd | (rs << 3) | (value << 6);
5782 }
5783 }
5784 md_number_to_chars (buf, newval , THUMB_SIZE);
5785 break;
5786
5787 case BFD_RELOC_ARM_THUMB_IMM:
5788 newval = md_chars_to_number (buf, THUMB_SIZE);
5789 switch (newval >> 11)
5790 {
5791 case 0x04: /* 8bit immediate MOV */
5792 case 0x05: /* 8bit immediate CMP */
5793 if (value < 0 || value > 255)
5794 as_bad_where (fixP->fx_file, fixP->fx_line,
5795 _("Invalid immediate: %ld is too large"),
5796 (long) value);
5797 newval |= value;
5798 break;
5799
5800 default:
5801 abort ();
5802 }
5803 md_number_to_chars (buf, newval , THUMB_SIZE);
5804 break;
5805
5806 case BFD_RELOC_ARM_THUMB_SHIFT:
5807 /* 5bit shift value (0..31) */
5808 if (value < 0 || value > 31)
5809 as_bad_where (fixP->fx_file, fixP->fx_line,
5810 _("Illegal Thumb shift value: %ld"), (long) value);
5811 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5812 newval |= value << 6;
5813 md_number_to_chars (buf, newval , THUMB_SIZE);
5814 break;
5815
5816 case BFD_RELOC_VTABLE_INHERIT:
5817 case BFD_RELOC_VTABLE_ENTRY:
5818 fixP->fx_done = 0;
5819 return 1;
5820
5821 case BFD_RELOC_NONE:
5822 default:
5823 as_bad_where (fixP->fx_file, fixP->fx_line,
5824 _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
5825 }
5826
5827 return 1;
5828 }
5829
5830 /* Translate internal representation of relocation info to BFD target
5831 format. */
5832 arelent *
5833 tc_gen_reloc (section, fixp)
5834 asection * section;
5835 fixS * fixp;
5836 {
5837 arelent * reloc;
5838 bfd_reloc_code_real_type code;
5839
5840 reloc = (arelent *) xmalloc (sizeof (arelent));
5841
5842 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
5843 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5844 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5845
5846 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5847 #ifndef OBJ_ELF
5848 if (fixp->fx_pcrel == 0)
5849 reloc->addend = fixp->fx_offset;
5850 else
5851 reloc->addend = fixp->fx_offset = reloc->address;
5852 #else /* OBJ_ELF */
5853 reloc->addend = fixp->fx_offset;
5854 #endif
5855
5856 switch (fixp->fx_r_type)
5857 {
5858 case BFD_RELOC_8:
5859 if (fixp->fx_pcrel)
5860 {
5861 code = BFD_RELOC_8_PCREL;
5862 break;
5863 }
5864
5865 case BFD_RELOC_16:
5866 if (fixp->fx_pcrel)
5867 {
5868 code = BFD_RELOC_16_PCREL;
5869 break;
5870 }
5871
5872 case BFD_RELOC_32:
5873 if (fixp->fx_pcrel)
5874 {
5875 code = BFD_RELOC_32_PCREL;
5876 break;
5877 }
5878
5879 case BFD_RELOC_ARM_PCREL_BRANCH:
5880 case BFD_RELOC_RVA:
5881 case BFD_RELOC_THUMB_PCREL_BRANCH9:
5882 case BFD_RELOC_THUMB_PCREL_BRANCH12:
5883 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5884 case BFD_RELOC_VTABLE_ENTRY:
5885 case BFD_RELOC_VTABLE_INHERIT:
5886 code = fixp->fx_r_type;
5887 break;
5888
5889 case BFD_RELOC_ARM_LITERAL:
5890 case BFD_RELOC_ARM_HWLITERAL:
5891 /* If this is called then the a literal has been referenced across
5892 a section boundary - possibly due to an implicit dump */
5893 as_bad_where (fixp->fx_file, fixp->fx_line,
5894 _("Literal referenced across section boundary (Implicit dump?)"));
5895 return NULL;
5896
5897 #ifdef OBJ_ELF
5898 case BFD_RELOC_ARM_GOT32:
5899 case BFD_RELOC_ARM_GOTOFF:
5900 case BFD_RELOC_ARM_PLT32:
5901 code = fixp->fx_r_type;
5902 break;
5903 #endif
5904
5905 case BFD_RELOC_ARM_IMMEDIATE:
5906 as_bad_where (fixp->fx_file, fixp->fx_line,
5907 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5908 fixp->fx_r_type);
5909 return NULL;
5910
5911 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5912 as_bad_where (fixp->fx_file, fixp->fx_line,
5913 _("ADRL used for a symbol not defined in the same file"),
5914 fixp->fx_r_type);
5915 return NULL;
5916
5917 case BFD_RELOC_ARM_OFFSET_IMM:
5918 as_bad_where (fixp->fx_file, fixp->fx_line,
5919 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5920 fixp->fx_r_type);
5921 return NULL;
5922
5923 default:
5924 {
5925 char * type;
5926 switch (fixp->fx_r_type)
5927 {
5928 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
5929 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
5930 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
5931 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
5932 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
5933 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
5934 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
5935 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
5936 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
5937 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
5938 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
5939 default: type = _("<unknown>"); break;
5940 }
5941 as_bad_where (fixp->fx_file, fixp->fx_line,
5942 _("Can not represent %s relocation in this object file format (%d)"),
5943 type, fixp->fx_pcrel);
5944 return NULL;
5945 }
5946 }
5947
5948 #ifdef OBJ_ELF
5949 if (code == BFD_RELOC_32_PCREL
5950 && GOT_symbol
5951 && fixp->fx_addsy == GOT_symbol)
5952 {
5953 code = BFD_RELOC_ARM_GOTPC;
5954 reloc->addend = fixp->fx_offset = reloc->address;
5955 }
5956 #endif
5957
5958 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5959
5960 if (reloc->howto == NULL)
5961 {
5962 as_bad_where (fixp->fx_file, fixp->fx_line,
5963 _("Can not represent %s relocation in this object file format"),
5964 bfd_get_reloc_code_name (code));
5965 return NULL;
5966 }
5967
5968 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5969 vtable entry to be used in the relocation's section offset. */
5970 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5971 reloc->address = fixp->fx_offset;
5972
5973 return reloc;
5974 }
5975
5976 int
5977 md_estimate_size_before_relax (fragP, segtype)
5978 fragS * fragP;
5979 segT segtype;
5980 {
5981 as_fatal (_("md_estimate_size_before_relax\n"));
5982 return 1;
5983 }
5984
5985 static void
5986 output_inst PARAMS ((void))
5987 {
5988 char * to = NULL;
5989
5990 if (inst.error)
5991 {
5992 as_bad (inst.error);
5993 return;
5994 }
5995
5996 to = frag_more (inst.size);
5997
5998 if (thumb_mode && (inst.size > THUMB_SIZE))
5999 {
6000 assert (inst.size == (2 * THUMB_SIZE));
6001 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
6002 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
6003 }
6004 else if (inst.size > INSN_SIZE)
6005 {
6006 assert (inst.size == (2 * INSN_SIZE));
6007 md_number_to_chars (to, inst.instruction, INSN_SIZE);
6008 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
6009 }
6010 else
6011 md_number_to_chars (to, inst.instruction, inst.size);
6012
6013 if (inst.reloc.type != BFD_RELOC_NONE)
6014 fix_new_arm (frag_now, to - frag_now->fr_literal,
6015 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
6016 inst.reloc.type);
6017
6018 return;
6019 }
6020
6021 void
6022 md_assemble (str)
6023 char * str;
6024 {
6025 char c;
6026 char * p;
6027 char * q;
6028 char * start;
6029
6030 /* Align the instruction.
6031 This may not be the right thing to do but ... */
6032 /* arm_align (2, 0); */
6033 listing_prev_line (); /* Defined in listing.h */
6034
6035 /* Align the previous label if needed. */
6036 if (last_label_seen != NULL)
6037 {
6038 symbol_set_frag (last_label_seen, frag_now);
6039 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
6040 S_SET_SEGMENT (last_label_seen, now_seg);
6041 }
6042
6043 memset (&inst, '\0', sizeof (inst));
6044 inst.reloc.type = BFD_RELOC_NONE;
6045
6046 skip_whitespace (str);
6047
6048 /* Scan up to the end of the op-code, which must end in white space or
6049 end of string. */
6050 for (start = p = str; *p != '\0'; p++)
6051 if (*p == ' ')
6052 break;
6053
6054 if (p == str)
6055 {
6056 as_bad (_("No operator -- statement `%s'\n"), str);
6057 return;
6058 }
6059
6060 if (thumb_mode)
6061 {
6062 CONST struct thumb_opcode * opcode;
6063
6064 c = *p;
6065 *p = '\0';
6066 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
6067 *p = c;
6068
6069 if (opcode)
6070 {
6071 /* Check that this instruction is supported for this CPU. */
6072 if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0)
6073 {
6074 as_bad (_("selected processor does not support this opcode"));
6075 return;
6076 }
6077
6078 inst.instruction = opcode->value;
6079 inst.size = opcode->size;
6080 (*opcode->parms)(p);
6081 output_inst ();
6082 return;
6083 }
6084 }
6085 else
6086 {
6087 CONST struct asm_opcode * opcode;
6088 unsigned long cond_code;
6089
6090 inst.size = INSN_SIZE;
6091 /* p now points to the end of the opcode, probably white space, but we
6092 have to break the opcode up in case it contains condionals and flags;
6093 keep trying with progressively smaller basic instructions until one
6094 matches, or we run out of opcode. */
6095 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
6096 for (; q != str; q--)
6097 {
6098 c = *q;
6099 *q = '\0';
6100 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
6101 *q = c;
6102
6103 if (opcode && opcode->template)
6104 {
6105 unsigned long flag_bits = 0;
6106 char * r;
6107
6108 /* Check that this instruction is supported for this CPU. */
6109 if ((opcode->variants & cpu_variant) == 0)
6110 goto try_shorter;
6111
6112 inst.instruction = opcode->value;
6113 if (q == p) /* Just a simple opcode. */
6114 {
6115 if (opcode->comp_suffix)
6116 {
6117 if (*opcode->comp_suffix != '\0')
6118 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
6119 str, opcode->comp_suffix);
6120 else
6121 /* Not a conditional instruction. */
6122 (*opcode->parms)(q, 0);
6123 }
6124 else
6125 {
6126 /* A conditional instruction with default condition. */
6127 inst.instruction |= COND_ALWAYS;
6128 (*opcode->parms)(q, 0);
6129 }
6130 output_inst ();
6131 return;
6132 }
6133
6134 /* Not just a simple opcode. Check if extra is a conditional. */
6135 r = q;
6136 if (p - r >= 2)
6137 {
6138 CONST struct asm_cond *cond;
6139 char d = *(r + 2);
6140
6141 *(r + 2) = '\0';
6142 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
6143 *(r + 2) = d;
6144 if (cond)
6145 {
6146 if (cond->value == 0xf0000000)
6147 as_tsktsk (
6148 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6149
6150 cond_code = cond->value;
6151 r += 2;
6152 }
6153 else
6154 cond_code = COND_ALWAYS;
6155 }
6156 else
6157 cond_code = COND_ALWAYS;
6158
6159
6160 /* Apply the conditional, or complain it's not allowed. */
6161 if (opcode->comp_suffix && *opcode->comp_suffix == '\0')
6162 {
6163 /* Instruction isn't conditional */
6164 if (cond_code != COND_ALWAYS)
6165 {
6166 as_bad (_("Opcode `%s' is unconditional\n"), str);
6167 return;
6168 }
6169 }
6170 else
6171 /* Instruction is conditional: set the condition into it. */
6172 inst.instruction |= cond_code;
6173
6174
6175 /* If there is a compulsory suffix, it should come here, before
6176 any optional flags. */
6177 if (opcode->comp_suffix && *opcode->comp_suffix != '\0')
6178 {
6179 CONST char *s = opcode->comp_suffix;
6180
6181 while (*s)
6182 {
6183 inst.suffix++;
6184 if (*r == *s)
6185 break;
6186 s++;
6187 }
6188
6189 if (*s == '\0')
6190 {
6191 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6192 opcode->comp_suffix);
6193 return;
6194 }
6195
6196 r++;
6197 }
6198
6199 /* The remainder, if any should now be flags for the instruction;
6200 Scan these checking each one found with the opcode. */
6201 if (r != p)
6202 {
6203 char d;
6204 CONST struct asm_flg *flag = opcode->flags;
6205
6206 if (flag)
6207 {
6208 int flagno;
6209
6210 d = *p;
6211 *p = '\0';
6212
6213 for (flagno = 0; flag[flagno].template; flagno++)
6214 {
6215 if (streq (r, flag[flagno].template))
6216 {
6217 flag_bits |= flag[flagno].set_bits;
6218 break;
6219 }
6220 }
6221
6222 *p = d;
6223 if (! flag[flagno].template)
6224 goto try_shorter;
6225 }
6226 else
6227 goto try_shorter;
6228 }
6229
6230 (*opcode->parms) (p, flag_bits);
6231 output_inst ();
6232 return;
6233 }
6234
6235 try_shorter:
6236 ;
6237 }
6238 }
6239
6240 /* It wasn't an instruction, but it might be a register alias of the form
6241 alias .req reg */
6242 q = p;
6243 skip_whitespace (q);
6244
6245 c = *p;
6246 *p = '\0';
6247
6248 if (*q && !strncmp (q, ".req ", 4))
6249 {
6250 int reg;
6251 char * copy_of_str = str;
6252 char * r;
6253
6254 q += 4;
6255 skip_whitespace (q);
6256
6257 for (r = q; *r != '\0'; r++)
6258 if (*r == ' ')
6259 break;
6260
6261 if (r != q)
6262 {
6263 int regnum;
6264 char d = *r;
6265
6266 *r = '\0';
6267 regnum = arm_reg_parse (& q);
6268 *r = d;
6269
6270 reg = arm_reg_parse (& str);
6271
6272 if (reg == FAIL)
6273 {
6274 if (regnum != FAIL)
6275 insert_reg_alias (str, regnum);
6276 else
6277 as_warn (_("register '%s' does not exist\n"), q);
6278 }
6279 else if (regnum != FAIL)
6280 {
6281 if (reg != regnum)
6282 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str );
6283
6284 /* Do not warn about redefinitions to the same alias. */
6285 }
6286 else
6287 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6288 copy_of_str, q);
6289 }
6290 else
6291 as_warn (_("ignoring incomplete .req pseuso op"));
6292
6293 *p = c;
6294 return;
6295 }
6296
6297 *p = c;
6298 as_bad (_("bad instruction `%s'"), start);
6299 }
6300
6301 /*
6302 * md_parse_option
6303 * Invocation line includes a switch not recognized by the base assembler.
6304 * See if it's a processor-specific option. These are:
6305 * Cpu variants, the arm part is optional:
6306 * -m[arm]1 Currently not supported.
6307 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6308 * -m[arm]3 Arm 3 processor
6309 * -m[arm]6[xx], Arm 6 processors
6310 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6311 * -m[arm]8[10] Arm 8 processors
6312 * -m[arm]9[20][tdmi] Arm 9 processors
6313 * -mstrongarm[110[0]] StrongARM processors
6314 * -m[arm]v[2345] Arm architectures
6315 * -mall All (except the ARM1)
6316 * FP variants:
6317 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6318 * -mfpe-old (No float load/store multiples)
6319 * -mno-fpu Disable all floating point instructions
6320 * Run-time endian selection:
6321 * -EB big endian cpu
6322 * -EL little endian cpu
6323 * ARM Procedure Calling Standard:
6324 * -mapcs-32 32 bit APCS
6325 * -mapcs-26 26 bit APCS
6326 * -mapcs-float Pass floats in float regs
6327 * -mapcs-reentrant Position independent code
6328 * -mthumb-interwork Code supports Arm/Thumb interworking
6329 * -moabi Old ELF ABI
6330 */
6331
6332 CONST char * md_shortopts = "m:k";
6333 struct option md_longopts[] =
6334 {
6335 #ifdef ARM_BI_ENDIAN
6336 #define OPTION_EB (OPTION_MD_BASE + 0)
6337 {"EB", no_argument, NULL, OPTION_EB},
6338 #define OPTION_EL (OPTION_MD_BASE + 1)
6339 {"EL", no_argument, NULL, OPTION_EL},
6340 #ifdef OBJ_ELF
6341 #define OPTION_OABI (OPTION_MD_BASE +2)
6342 {"oabi", no_argument, NULL, OPTION_OABI},
6343 #endif
6344 #endif
6345 {NULL, no_argument, NULL, 0}
6346 };
6347 size_t md_longopts_size = sizeof (md_longopts);
6348
6349 int
6350 md_parse_option (c, arg)
6351 int c;
6352 char * arg;
6353 {
6354 char * str = arg;
6355
6356 switch (c)
6357 {
6358 #ifdef ARM_BI_ENDIAN
6359 case OPTION_EB:
6360 target_big_endian = 1;
6361 break;
6362 case OPTION_EL:
6363 target_big_endian = 0;
6364 break;
6365 #endif
6366
6367 case 'm':
6368 switch (*str)
6369 {
6370 case 'f':
6371 if (streq (str, "fpa10"))
6372 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
6373 else if (streq (str, "fpa11"))
6374 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
6375 else if (streq (str, "fpe-old"))
6376 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
6377 else
6378 goto bad;
6379 break;
6380
6381 case 'n':
6382 if (streq (str, "no-fpu"))
6383 cpu_variant &= ~FPU_ALL;
6384 break;
6385
6386 #ifdef OBJ_ELF
6387 case 'o':
6388 if (streq (str, "oabi"))
6389 target_oabi = true;
6390 break;
6391 #endif
6392
6393 case 't':
6394 /* Limit assembler to generating only Thumb instructions: */
6395 if (streq (str, "thumb"))
6396 {
6397 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
6398 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6399 thumb_mode = 1;
6400 }
6401 else if (streq (str, "thumb-interwork"))
6402 {
6403 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCH_V4;
6404 #if defined OBJ_COFF || defined OBJ_ELF
6405 support_interwork = true;
6406 #endif
6407 }
6408 else
6409 goto bad;
6410 break;
6411
6412 default:
6413 if (streq (str, "all"))
6414 {
6415 cpu_variant = ARM_ALL | FPU_ALL;
6416 return 1;
6417 }
6418 #if defined OBJ_COFF || defined OBJ_ELF
6419 if (! strncmp (str, "apcs-", 5))
6420 {
6421 /* GCC passes on all command line options starting "-mapcs-..."
6422 to us, so we must parse them here. */
6423
6424 str += 5;
6425
6426 if (streq (str, "32"))
6427 {
6428 uses_apcs_26 = false;
6429 return 1;
6430 }
6431 else if (streq (str, "26"))
6432 {
6433 uses_apcs_26 = true;
6434 return 1;
6435 }
6436 else if (streq (str, "frame"))
6437 {
6438 /* Stack frames are being generated - does not affect
6439 linkage of code. */
6440 return 1;
6441 }
6442 else if (streq (str, "stack-check"))
6443 {
6444 /* Stack checking is being performed - does not affect
6445 linkage, but does require that the functions
6446 __rt_stkovf_split_small and __rt_stkovf_split_big be
6447 present in the final link. */
6448
6449 return 1;
6450 }
6451 else if (streq (str, "float"))
6452 {
6453 /* Floating point arguments are being passed in the floating
6454 point registers. This does affect linking, since this
6455 version of the APCS is incompatible with the version that
6456 passes floating points in the integer registers. */
6457
6458 uses_apcs_float = true;
6459 return 1;
6460 }
6461 else if (streq (str, "reentrant"))
6462 {
6463 /* Reentrant code has been generated. This does affect
6464 linking, since there is no point in linking reentrant/
6465 position independent code with absolute position code. */
6466 pic_code = true;
6467 return 1;
6468 }
6469
6470 as_bad (_("Unrecognised APCS switch -m%s"), arg);
6471 return 0;
6472 }
6473 #endif
6474 /* Strip off optional "arm" */
6475 if (! strncmp (str, "arm", 3))
6476 str += 3;
6477
6478 switch (*str)
6479 {
6480 case '1':
6481 if (streq (str, "1"))
6482 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6483 else
6484 goto bad;
6485 break;
6486
6487 case '2':
6488 if (streq (str, "2"))
6489 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6490 else if (streq (str, "250"))
6491 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6492 else
6493 goto bad;
6494 break;
6495
6496 case '3':
6497 if (streq (str, "3"))
6498 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6499 else
6500 goto bad;
6501 break;
6502
6503 case '6':
6504 switch (strtol (str, NULL, 10))
6505 {
6506 case 6:
6507 case 60:
6508 case 600:
6509 case 610:
6510 case 620:
6511 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6512 break;
6513 default:
6514 goto bad;
6515 }
6516 break;
6517
6518 case '7':
6519 switch (strtol (str, & str, 10)) /* Eat the processor name */
6520 {
6521 case 7:
6522 case 70:
6523 case 700:
6524 case 710:
6525 case 720:
6526 case 7100:
6527 case 7500:
6528 break;
6529 default:
6530 goto bad;
6531 }
6532 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6533 for (; *str; str++)
6534 {
6535 switch (* str)
6536 {
6537 case 't':
6538 cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
6539 break;
6540
6541 case 'm':
6542 cpu_variant |= ARM_LONGMUL;
6543 break;
6544
6545 case 'f': /* fe => fp enabled cpu. */
6546 if (str[1] == 'e')
6547 ++ str;
6548 else
6549 goto bad;
6550
6551 case 'c': /* Left over from 710c processor name. */
6552 case 'd': /* Debug */
6553 case 'i': /* Embedded ICE */
6554 /* Included for completeness in ARM processor naming. */
6555 break;
6556
6557 default:
6558 goto bad;
6559 }
6560 }
6561 break;
6562
6563 case '8':
6564 if (streq (str, "8") || streq (str, "810"))
6565 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6566 else
6567 goto bad;
6568 break;
6569
6570 case '9':
6571 if (streq (str, "9"))
6572 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6573 else if (streq (str, "920"))
6574 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
6575 else if (streq (str, "920t"))
6576 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6577 else if (streq (str, "9tdmi"))
6578 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6579 else
6580 goto bad;
6581 break;
6582
6583
6584 case 's':
6585 if (streq (str, "strongarm")
6586 || streq (str, "strongarm110")
6587 || streq (str, "strongarm1100"))
6588 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6589 else
6590 goto bad;
6591 break;
6592
6593 case 'v':
6594 /* Select variant based on architecture rather than processor */
6595 switch (*++str)
6596 {
6597 case '2':
6598 switch (*++str)
6599 {
6600 case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
6601 case 0: cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
6602 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6603 }
6604 break;
6605
6606 case '3':
6607 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6608
6609 switch (*++str)
6610 {
6611 case 'm': cpu_variant |= ARM_LONGMUL; break;
6612 case 0: break;
6613 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6614 }
6615 break;
6616
6617 case '4':
6618 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4;
6619
6620 switch (*++str)
6621 {
6622 case 't': cpu_variant |= ARM_THUMB; break;
6623 case 0: break;
6624 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6625 }
6626 break;
6627
6628 case '5':
6629 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
6630 switch (*++str)
6631 {
6632 case 't': cpu_variant |= ARM_THUMB; break;
6633 case 'e': cpu_variant |= ARM_EXT_V5E; break;
6634 case 0: break;
6635 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6636 }
6637 break;
6638
6639
6640 default:
6641 as_bad (_("Invalid architecture variant -m%s"), arg);
6642 break;
6643 }
6644 break;
6645
6646 default:
6647 bad:
6648 as_bad (_("Invalid processor variant -m%s"), arg);
6649 return 0;
6650 }
6651 }
6652 break;
6653
6654 #if defined OBJ_ELF || defined OBJ_COFF
6655 case 'k':
6656 pic_code = 1;
6657 break;
6658 #endif
6659
6660 default:
6661 return 0;
6662 }
6663
6664 return 1;
6665 }
6666
6667 void
6668 md_show_usage (fp)
6669 FILE * fp;
6670 {
6671 fprintf (fp,
6672 _("\
6673 ARM Specific Assembler Options:\n\
6674 -m[arm][<processor name>] select processor variant\n\
6675 -m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\
6676 -mthumb only allow Thumb instructions\n\
6677 -mthumb-interwork mark the assembled code as supporting interworking\n\
6678 -mall allow any instruction\n\
6679 -mfpa10, -mfpa11 select floating point architecture\n\
6680 -mfpe-old don't allow floating-point multiple instructions\n\
6681 -mno-fpu don't allow any floating-point instructions.\n"));
6682 fprintf (fp,
6683 _("\
6684 -k generate PIC code.\n"));
6685 #if defined OBJ_COFF || defined OBJ_ELF
6686 fprintf (fp,
6687 _("\
6688 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6689 fprintf (fp,
6690 _("\
6691 -mapcs-float floating point args are passed in FP regs\n"));
6692 fprintf (fp,
6693 _("\
6694 -mapcs-reentrant the code is position independent/reentrant\n"));
6695 #endif
6696 #ifdef OBJ_ELF
6697 fprintf (fp,
6698 _("\
6699 -moabi support the old ELF ABI\n"));
6700 #endif
6701 #ifdef ARM_BI_ENDIAN
6702 fprintf (fp,
6703 _("\
6704 -EB assemble code for a big endian cpu\n\
6705 -EL assemble code for a little endian cpu\n"));
6706 #endif
6707 }
6708
6709 /* We need to be able to fix up arbitrary expressions in some statements.
6710 This is so that we can handle symbols that are an arbitrary distance from
6711 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6712 which returns part of an address in a form which will be valid for
6713 a data instruction. We do this by pushing the expression into a symbol
6714 in the expr_section, and creating a fix for that. */
6715
6716 static void
6717 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6718 fragS * frag;
6719 int where;
6720 short int size;
6721 expressionS * exp;
6722 int pc_rel;
6723 int reloc;
6724 {
6725 fixS * new_fix;
6726 arm_fix_data * arm_data;
6727
6728 switch (exp->X_op)
6729 {
6730 case O_constant:
6731 case O_symbol:
6732 case O_add:
6733 case O_subtract:
6734 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6735 break;
6736
6737 default:
6738 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6739 pc_rel, reloc);
6740 break;
6741 }
6742
6743 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6744 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
6745 new_fix->tc_fix_data = (PTR) arm_data;
6746 arm_data->thumb_mode = thumb_mode;
6747
6748 return;
6749 }
6750
6751
6752 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6753 void
6754 cons_fix_new_arm (frag, where, size, exp)
6755 fragS * frag;
6756 int where;
6757 int size;
6758 expressionS * exp;
6759 {
6760 bfd_reloc_code_real_type type;
6761 int pcrel = 0;
6762
6763 /* Pick a reloc ...
6764 *
6765 * @@ Should look at CPU word size.
6766 */
6767 switch (size)
6768 {
6769 case 2:
6770 type = BFD_RELOC_16;
6771 break;
6772 case 4:
6773 default:
6774 type = BFD_RELOC_32;
6775 break;
6776 case 8:
6777 type = BFD_RELOC_64;
6778 break;
6779 }
6780
6781 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
6782 }
6783
6784 /* A good place to do this, although this was probably not intended
6785 for this kind of use. We need to dump the literal pool before
6786 references are made to a null symbol pointer. */
6787 void
6788 arm_cleanup ()
6789 {
6790 if (current_poolP == NULL)
6791 return;
6792
6793 subseg_set (text_section, 0); /* Put it at the end of text section. */
6794 s_ltorg (0);
6795 listing_prev_line ();
6796 }
6797
6798 void
6799 arm_start_line_hook ()
6800 {
6801 last_label_seen = NULL;
6802 }
6803
6804 void
6805 arm_frob_label (sym)
6806 symbolS * sym;
6807 {
6808 last_label_seen = sym;
6809
6810 ARM_SET_THUMB (sym, thumb_mode);
6811
6812 #if defined OBJ_COFF || defined OBJ_ELF
6813 ARM_SET_INTERWORK (sym, support_interwork);
6814 #endif
6815
6816 if (label_is_thumb_function_name)
6817 {
6818 /* When the address of a Thumb function is taken the bottom
6819 bit of that address should be set. This will allow
6820 interworking between Arm and Thumb functions to work
6821 correctly. */
6822
6823 THUMB_SET_FUNC (sym, 1);
6824
6825 label_is_thumb_function_name = false;
6826 }
6827 }
6828
6829 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6830 ARM ones. */
6831
6832 void
6833 arm_adjust_symtab ()
6834 {
6835 #ifdef OBJ_COFF
6836 symbolS * sym;
6837
6838 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6839 {
6840 if (ARM_IS_THUMB (sym))
6841 {
6842 if (THUMB_IS_FUNC (sym))
6843 {
6844 /* Mark the symbol as a Thumb function. */
6845 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
6846 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6847 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6848
6849 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6850 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6851 else
6852 as_bad (_("%s: unexpected function type: %d"),
6853 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6854 }
6855 else switch (S_GET_STORAGE_CLASS (sym))
6856 {
6857 case C_EXT:
6858 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6859 break;
6860 case C_STAT:
6861 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6862 break;
6863 case C_LABEL:
6864 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6865 break;
6866 default: /* do nothing */
6867 break;
6868 }
6869 }
6870
6871 if (ARM_IS_INTERWORK (sym))
6872 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
6873 }
6874 #endif
6875 #ifdef OBJ_ELF
6876 symbolS * sym;
6877 elf_symbol_type * elf_sym;
6878 char bind;
6879
6880 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6881 {
6882 if (ARM_IS_THUMB (sym))
6883 {
6884 if (THUMB_IS_FUNC (sym))
6885 {
6886 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
6887 bind = ELF_ST_BIND (elf_sym);
6888 elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC);
6889 }
6890 }
6891 }
6892 #endif
6893 }
6894
6895 int
6896 arm_data_in_code ()
6897 {
6898 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
6899 {
6900 *input_line_pointer = '/';
6901 input_line_pointer += 5;
6902 *input_line_pointer = 0;
6903 return 1;
6904 }
6905
6906 return 0;
6907 }
6908
6909 char *
6910 arm_canonicalize_symbol_name (name)
6911 char * name;
6912 {
6913 int len;
6914
6915 if (thumb_mode && (len = strlen (name)) > 5
6916 && streq (name + len - 5, "/data"))
6917 *(name + len - 5) = 0;
6918
6919 return name;
6920 }
6921
6922 boolean
6923 arm_validate_fix (fixP)
6924 fixS * fixP;
6925 {
6926 /* If the destination of the branch is a defined symbol which does not have
6927 the THUMB_FUNC attribute, then we must be calling a function which has
6928 the (interfacearm) attribute. We look for the Thumb entry point to that
6929 function and change the branch to refer to that function instead. */
6930 if ( fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
6931 && fixP->fx_addsy != NULL
6932 && S_IS_DEFINED (fixP->fx_addsy)
6933 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6934 {
6935 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6936 return true;
6937 }
6938
6939 return false;
6940 }
6941
6942 #ifdef OBJ_ELF
6943 /* Relocations against Thumb function names must be left unadjusted,
6944 so that the linker can use this information to correctly set the
6945 bottom bit of their addresses. The MIPS version of this function
6946 also prevents relocations that are mips-16 specific, but I do not
6947 know why it does this.
6948
6949 FIXME:
6950 There is one other problem that ought to be addressed here, but
6951 which currently is not: Taking the address of a label (rather
6952 than a function) and then later jumping to that address. Such
6953 addresses also ought to have their bottom bit set (assuming that
6954 they reside in Thumb code), but at the moment they will not. */
6955
6956 boolean
6957 arm_fix_adjustable (fixP)
6958 fixS * fixP;
6959 {
6960 if (fixP->fx_addsy == NULL)
6961 return 1;
6962
6963 /* Prevent all adjustments to global symbols. */
6964 if (S_IS_EXTERN (fixP->fx_addsy))
6965 return 0;
6966
6967 if (S_IS_WEAK (fixP->fx_addsy))
6968 return 0;
6969
6970 if (THUMB_IS_FUNC (fixP->fx_addsy)
6971 && fixP->fx_subsy == NULL)
6972 return 0;
6973
6974 /* We need the symbol name for the VTABLE entries */
6975 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6976 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6977 return 0;
6978
6979 return 1;
6980 }
6981
6982 const char *
6983 elf32_arm_target_format ()
6984 {
6985 if (target_big_endian)
6986 if (target_oabi)
6987 return "elf32-bigarm-oabi";
6988 else
6989 return "elf32-bigarm";
6990 else
6991 if (target_oabi)
6992 return "elf32-littlearm-oabi";
6993 else
6994 return "elf32-littlearm";
6995 }
6996
6997 void
6998 armelf_frob_symbol (symp, puntp)
6999 symbolS * symp;
7000 int * puntp;
7001 {
7002 elf_frob_symbol (symp, puntp);
7003 }
7004
7005 int
7006 arm_force_relocation (fixp)
7007 struct fix * fixp;
7008 {
7009 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
7010 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
7011 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
7012 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
7013 return 1;
7014
7015 return 0;
7016 }
7017
7018 static bfd_reloc_code_real_type
7019 arm_parse_reloc ()
7020 {
7021 char id[16];
7022 char * ip;
7023 int i;
7024 static struct
7025 {
7026 char * str;
7027 int len;
7028 bfd_reloc_code_real_type reloc;
7029 }
7030 reloc_map[] =
7031 {
7032 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
7033 MAP ("(got)", BFD_RELOC_ARM_GOT32),
7034 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
7035 /* ScottB: Jan 30, 1998 */
7036 /* Added support for parsing "var(PLT)" branch instructions */
7037 /* generated by GCC for PLT relocs */
7038 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
7039 { NULL, 0, BFD_RELOC_UNUSED }
7040 #undef MAP
7041 };
7042
7043 for (i = 0, ip = input_line_pointer;
7044 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
7045 i++, ip++)
7046 id[i] = tolower (*ip);
7047
7048 for (i = 0; reloc_map[i].str; i++)
7049 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
7050 break;
7051
7052 input_line_pointer += reloc_map[i].len;
7053
7054 return reloc_map[i].reloc;
7055 }
7056
7057 static void
7058 s_arm_elf_cons (nbytes)
7059 int nbytes;
7060 {
7061 expressionS exp;
7062
7063 #ifdef md_flush_pending_output
7064 md_flush_pending_output ();
7065 #endif
7066
7067 if (is_it_end_of_statement ())
7068 {
7069 demand_empty_rest_of_line ();
7070 return;
7071 }
7072
7073 #ifdef md_cons_align
7074 md_cons_align (nbytes);
7075 #endif
7076
7077 do
7078 {
7079 bfd_reloc_code_real_type reloc;
7080
7081 expression (& exp);
7082
7083 if (exp.X_op == O_symbol
7084 && * input_line_pointer == '('
7085 && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
7086 {
7087 reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
7088 int size = bfd_get_reloc_size (howto);
7089
7090 if (size > nbytes)
7091 as_bad ("%s relocations do not fit in %d bytes", howto->name, nbytes);
7092 else
7093 {
7094 register char * p = frag_more ((int) nbytes);
7095 int offset = nbytes - size;
7096
7097 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
7098 & exp, 0, reloc);
7099 }
7100 }
7101 else
7102 emit_expr (& exp, (unsigned int) nbytes);
7103 }
7104 while (*input_line_pointer++ == ',');
7105
7106 input_line_pointer--; /* Put terminator back into stream. */
7107 demand_empty_rest_of_line ();
7108 }
7109
7110 #endif /* OBJ_ELF */
This page took 0.202796 seconds and 5 git commands to generate.