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