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