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