slight code improvement over previous delta
[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 return size;
5185 #else
5186 /* Round all sects to multiple of 4 */
5187 return (size + 3) & ~3;
5188 #endif
5189 }
5190
5191 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE. Otherwise
5192 we have no need to default values of symbols. */
5193
5194 /* ARGSUSED */
5195 symbolS *
5196 md_undefined_symbol (name)
5197 char * name;
5198 {
5199 #ifdef OBJ_ELF
5200 if (name[0] == '_' && name[1] == 'G'
5201 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
5202 {
5203 if (!GOT_symbol)
5204 {
5205 if (symbol_find (name))
5206 as_bad ("GOT already in the symbol table");
5207
5208 GOT_symbol = symbol_new (name, undefined_section,
5209 (valueT)0, & zero_address_frag);
5210 }
5211
5212 return GOT_symbol;
5213 }
5214 #endif
5215
5216 return 0;
5217 }
5218
5219 /* arm_reg_parse () := if it looks like a register, return its token and
5220 advance the pointer. */
5221
5222 static int
5223 arm_reg_parse (ccp)
5224 register char ** ccp;
5225 {
5226 char * start = * ccp;
5227 char c;
5228 char * p;
5229 struct reg_entry * reg;
5230
5231 #ifdef REGISTER_PREFIX
5232 if (*start != REGISTER_PREFIX)
5233 return FAIL;
5234 p = start + 1;
5235 #else
5236 p = start;
5237 #ifdef OPTIONAL_REGISTER_PREFIX
5238 if (*p == OPTIONAL_REGISTER_PREFIX)
5239 p++, start++;
5240 #endif
5241 #endif
5242 if (!isalpha (*p) || !is_name_beginner (*p))
5243 return FAIL;
5244
5245 c = *p++;
5246 while (isalpha (c) || isdigit (c) || c == '_')
5247 c = *p++;
5248
5249 *--p = 0;
5250 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
5251 *p = c;
5252
5253 if (reg)
5254 {
5255 *ccp = p;
5256 return reg->number;
5257 }
5258
5259 return FAIL;
5260 }
5261
5262 static int
5263 arm_psr_parse (ccp)
5264 register char ** ccp;
5265 {
5266 char * start = * ccp;
5267 char c;
5268 char * p;
5269 CONST struct asm_psr * psr;
5270
5271 p = start;
5272 c = *p++;
5273 while (isalpha (c) || c == '_')
5274 c = *p++;
5275
5276 *--p = 0;
5277 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
5278 *p = c;
5279
5280 if (psr)
5281 {
5282 *ccp = p;
5283 return psr->number;
5284 }
5285
5286 return FAIL;
5287 }
5288
5289 int
5290 md_apply_fix3 (fixP, val, seg)
5291 fixS * fixP;
5292 valueT * val;
5293 segT seg;
5294 {
5295 offsetT value = * val;
5296 offsetT newval;
5297 unsigned int newimm;
5298 unsigned long temp;
5299 int sign;
5300 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
5301 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
5302
5303 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
5304
5305 /* Note whether this will delete the relocation. */
5306 #if 0 /* patch from REarnshaw to JDavis (disabled for the moment, since it doesn't work fully) */
5307 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
5308 && !fixP->fx_pcrel)
5309 #else
5310 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
5311 #endif
5312 fixP->fx_done = 1;
5313
5314 /* If this symbol is in a different section then we need to leave it for
5315 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
5316 so we have to undo it's effects here. */
5317 if (fixP->fx_pcrel)
5318 {
5319 if (fixP->fx_addsy != NULL
5320 && S_IS_DEFINED (fixP->fx_addsy)
5321 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
5322 {
5323 if (target_oabi
5324 && fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH)
5325 value = 0;
5326 else
5327 value += md_pcrel_from (fixP);
5328 }
5329 }
5330
5331 fixP->fx_addnumber = value; /* Remember value for emit_reloc. */
5332
5333 switch (fixP->fx_r_type)
5334 {
5335 case BFD_RELOC_ARM_IMMEDIATE:
5336 newimm = validate_immediate (value);
5337 temp = md_chars_to_number (buf, INSN_SIZE);
5338
5339 /* If the instruction will fail, see if we can fix things up by
5340 changing the opcode. */
5341 if (newimm == (unsigned int) FAIL
5342 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
5343 {
5344 as_bad_where (fixP->fx_file, fixP->fx_line,
5345 _("invalid constant (%lx) after fixup"),
5346 (unsigned long) value);
5347 break;
5348 }
5349
5350 newimm |= (temp & 0xfffff000);
5351 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5352 break;
5353
5354 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5355 {
5356 unsigned int highpart = 0;
5357 unsigned int newinsn = 0xe1a00000; /* nop */
5358 newimm = validate_immediate (value);
5359 temp = md_chars_to_number (buf, INSN_SIZE);
5360
5361 /* If the instruction will fail, see if we can fix things up by
5362 changing the opcode. */
5363 if (newimm == (unsigned int) FAIL
5364 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
5365 {
5366 /* No ? OK - try using two ADD instructions to generate the value. */
5367 newimm = validate_immediate_twopart (value, & highpart);
5368
5369 /* Yes - then make sure that the second instruction is also an add. */
5370 if (newimm != (unsigned int) FAIL)
5371 newinsn = temp;
5372 /* Still No ? Try using a negated value. */
5373 else if (validate_immediate_twopart (- value, & highpart) != (unsigned int) FAIL)
5374 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
5375 /* Otherwise - give up. */
5376 else
5377 {
5378 as_bad_where (fixP->fx_file, fixP->fx_line,
5379 _("Unable to compute ADRL instructions for PC offset of 0x%x"), value);
5380 break;
5381 }
5382
5383 /* Replace the first operand in the 2nd instruction (which is the PC)
5384 with the destination register. We have already added in the PC in the
5385 first instruction and we do not want to do it again. */
5386 newinsn &= ~ 0xf0000;
5387 newinsn |= ((newinsn & 0x0f000) << 4);
5388 }
5389
5390 newimm |= (temp & 0xfffff000);
5391 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
5392
5393 highpart |= (newinsn & 0xfffff000);
5394 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
5395 }
5396 break;
5397
5398 case BFD_RELOC_ARM_OFFSET_IMM:
5399 sign = value >= 0;
5400
5401 if (value < 0)
5402 value = - value;
5403
5404 if (validate_offset_imm (value, 0) == FAIL)
5405 {
5406 as_bad_where (fixP->fx_file, fixP->fx_line,
5407 _("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)"),
5431 (long) value);
5432 break;
5433 }
5434
5435 newval = md_chars_to_number (buf, INSN_SIZE);
5436 newval &= 0xff7ff0f0;
5437 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
5438 md_number_to_chars (buf, newval, INSN_SIZE);
5439 break;
5440
5441 case BFD_RELOC_ARM_LITERAL:
5442 sign = value >= 0;
5443
5444 if (value < 0)
5445 value = - value;
5446
5447 if (validate_offset_imm (value, 0) == FAIL)
5448 {
5449 as_bad_where (fixP->fx_file, fixP->fx_line,
5450 _("invalid literal constant: pool needs to be closer"));
5451 break;
5452 }
5453
5454 newval = md_chars_to_number (buf, INSN_SIZE);
5455 newval &= 0xff7ff000;
5456 newval |= value | (sign ? INDEX_UP : 0);
5457 md_number_to_chars (buf, newval, INSN_SIZE);
5458 break;
5459
5460 case BFD_RELOC_ARM_SHIFT_IMM:
5461 newval = md_chars_to_number (buf, INSN_SIZE);
5462 if (((unsigned long) value) > 32
5463 || (value == 32
5464 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
5465 {
5466 as_bad_where (fixP->fx_file, fixP->fx_line,
5467 _("shift expression is too large"));
5468 break;
5469 }
5470
5471 if (value == 0)
5472 newval &= ~0x60; /* Shifts of zero must be done as lsl */
5473 else if (value == 32)
5474 value = 0;
5475 newval &= 0xfffff07f;
5476 newval |= (value & 0x1f) << 7;
5477 md_number_to_chars (buf, newval , INSN_SIZE);
5478 break;
5479
5480 case BFD_RELOC_ARM_SWI:
5481 if (arm_data->thumb_mode)
5482 {
5483 if (((unsigned long) value) > 0xff)
5484 as_bad_where (fixP->fx_file, fixP->fx_line,
5485 _("Invalid swi expression"));
5486 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
5487 newval |= value;
5488 md_number_to_chars (buf, newval, THUMB_SIZE);
5489 }
5490 else
5491 {
5492 if (((unsigned long) value) > 0x00ffffff)
5493 as_bad_where (fixP->fx_file, fixP->fx_line,
5494 _("Invalid swi expression"));
5495 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
5496 newval |= value;
5497 md_number_to_chars (buf, newval , INSN_SIZE);
5498 }
5499 break;
5500
5501 case BFD_RELOC_ARM_MULTI:
5502 if (((unsigned long) value) > 0xffff)
5503 as_bad_where (fixP->fx_file, fixP->fx_line,
5504 _("Invalid expression in load/store multiple"));
5505 newval = value | md_chars_to_number (buf, INSN_SIZE);
5506 md_number_to_chars (buf, newval, INSN_SIZE);
5507 break;
5508
5509 case BFD_RELOC_ARM_PCREL_BRANCH:
5510 newval = md_chars_to_number (buf, INSN_SIZE);
5511
5512 #ifdef OBJ_ELF
5513 if (! target_oabi)
5514 value = fixP->fx_offset;
5515 #endif
5516 value = (value >> 2) & 0x00ffffff;
5517 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
5518 newval = value | (newval & 0xff000000);
5519 md_number_to_chars (buf, newval, INSN_SIZE);
5520 break;
5521
5522 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* conditional branch */
5523 newval = md_chars_to_number (buf, THUMB_SIZE);
5524 {
5525 addressT diff = (newval & 0xff) << 1;
5526 if (diff & 0x100)
5527 diff |= ~0xff;
5528
5529 value += diff;
5530 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
5531 as_bad_where (fixP->fx_file, fixP->fx_line,
5532 _("Branch out of range"));
5533 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
5534 }
5535 md_number_to_chars (buf, newval, THUMB_SIZE);
5536 break;
5537
5538 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* unconditional branch */
5539 newval = md_chars_to_number (buf, THUMB_SIZE);
5540 {
5541 addressT diff = (newval & 0x7ff) << 1;
5542 if (diff & 0x800)
5543 diff |= ~0x7ff;
5544
5545 value += diff;
5546 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
5547 as_bad_where (fixP->fx_file, fixP->fx_line,
5548 _("Branch out of range"));
5549 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
5550 }
5551 md_number_to_chars (buf, newval, THUMB_SIZE);
5552 break;
5553
5554 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5555 {
5556 offsetT newval2;
5557 addressT diff;
5558
5559 newval = md_chars_to_number (buf, THUMB_SIZE);
5560 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
5561 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
5562 if (diff & 0x400000)
5563 diff |= ~0x3fffff;
5564 #ifdef OBJ_ELF
5565 value = fixP->fx_offset;
5566 #endif
5567 value += diff;
5568 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
5569 as_bad_where (fixP->fx_file, fixP->fx_line,
5570 _("Branch with link out of range"));
5571
5572 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
5573 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
5574 md_number_to_chars (buf, newval, THUMB_SIZE);
5575 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
5576 }
5577 break;
5578
5579 case BFD_RELOC_8:
5580 if (fixP->fx_done || fixP->fx_pcrel)
5581 md_number_to_chars (buf, value, 1);
5582 #ifdef OBJ_ELF
5583 else if (!target_oabi)
5584 {
5585 value = fixP->fx_offset;
5586 md_number_to_chars (buf, value, 1);
5587 }
5588 #endif
5589 break;
5590
5591 case BFD_RELOC_16:
5592 if (fixP->fx_done || fixP->fx_pcrel)
5593 md_number_to_chars (buf, value, 2);
5594 #ifdef OBJ_ELF
5595 else if (!target_oabi)
5596 {
5597 value = fixP->fx_offset;
5598 md_number_to_chars (buf, value, 2);
5599 }
5600 #endif
5601 break;
5602
5603 #ifdef OBJ_ELF
5604 case BFD_RELOC_ARM_GOT32:
5605 case BFD_RELOC_ARM_GOTOFF:
5606 md_number_to_chars (buf, 0, 4);
5607 break;
5608 #endif
5609
5610 case BFD_RELOC_RVA:
5611 case BFD_RELOC_32:
5612 if (fixP->fx_done || fixP->fx_pcrel)
5613 md_number_to_chars (buf, value, 4);
5614 #ifdef OBJ_ELF
5615 else if (!target_oabi)
5616 {
5617 value = fixP->fx_offset;
5618 md_number_to_chars (buf, value, 4);
5619 }
5620 #endif
5621 break;
5622
5623 #ifdef OBJ_ELF
5624 case BFD_RELOC_ARM_PLT32:
5625 /* It appears the instruction is fully prepared at this point. */
5626 break;
5627 #endif
5628
5629 case BFD_RELOC_ARM_GOTPC:
5630 md_number_to_chars (buf, value, 4);
5631 break;
5632
5633 case BFD_RELOC_ARM_CP_OFF_IMM:
5634 sign = value >= 0;
5635 if (value < -1023 || value > 1023 || (value & 3))
5636 as_bad_where (fixP->fx_file, fixP->fx_line,
5637 _("Illegal value for co-processor offset"));
5638 if (value < 0)
5639 value = -value;
5640 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
5641 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
5642 md_number_to_chars (buf, newval , INSN_SIZE);
5643 break;
5644
5645 case BFD_RELOC_ARM_THUMB_OFFSET:
5646 newval = md_chars_to_number (buf, THUMB_SIZE);
5647 /* Exactly what ranges, and where the offset is inserted depends on
5648 the type of instruction, we can establish this from the top 4 bits */
5649 switch (newval >> 12)
5650 {
5651 case 4: /* PC load */
5652 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
5653 forced to zero for these loads, so we will need to round
5654 up the offset if the instruction address is not word
5655 aligned (since the final address produced must be, and
5656 we can only describe word-aligned immediate offsets). */
5657
5658 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
5659 as_bad_where (fixP->fx_file, fixP->fx_line,
5660 _("Invalid offset, target not word aligned (0x%08X)"),
5661 (unsigned int)(fixP->fx_frag->fr_address + fixP->fx_where + value));
5662
5663 if ((value + 2) & ~0x3fe)
5664 as_bad_where (fixP->fx_file, fixP->fx_line,
5665 _("Invalid offset, value too big (0x%08X)"), value);
5666
5667 /* Round up, since pc will be rounded down. */
5668 newval |= (value + 2) >> 2;
5669 break;
5670
5671 case 9: /* SP load/store */
5672 if (value & ~0x3fc)
5673 as_bad_where (fixP->fx_file, fixP->fx_line,
5674 _("Invalid offset, value too big (0x%08X)"), value);
5675 newval |= value >> 2;
5676 break;
5677
5678 case 6: /* Word load/store */
5679 if (value & ~0x7c)
5680 as_bad_where (fixP->fx_file, fixP->fx_line,
5681 _("Invalid offset, value too big (0x%08X)"), value);
5682 newval |= value << 4; /* 6 - 2 */
5683 break;
5684
5685 case 7: /* Byte load/store */
5686 if (value & ~0x1f)
5687 as_bad_where (fixP->fx_file, fixP->fx_line,
5688 _("Invalid offset, value too big (0x%08X)"), value);
5689 newval |= value << 6;
5690 break;
5691
5692 case 8: /* Halfword load/store */
5693 if (value & ~0x3e)
5694 as_bad_where (fixP->fx_file, fixP->fx_line,
5695 _("Invalid offset, value too big (0x%08X)"), value);
5696 newval |= value << 5; /* 6 - 1 */
5697 break;
5698
5699 default:
5700 as_bad_where (fixP->fx_file, fixP->fx_line,
5701 "Unable to process relocation for thumb opcode: %lx",
5702 (unsigned long) newval);
5703 break;
5704 }
5705 md_number_to_chars (buf, newval, THUMB_SIZE);
5706 break;
5707
5708 case BFD_RELOC_ARM_THUMB_ADD:
5709 /* This is a complicated relocation, since we use it for all of
5710 the following immediate relocations:
5711 3bit ADD/SUB
5712 8bit ADD/SUB
5713 9bit ADD/SUB SP word-aligned
5714 10bit ADD PC/SP word-aligned
5715
5716 The type of instruction being processed is encoded in the
5717 instruction field:
5718 0x8000 SUB
5719 0x00F0 Rd
5720 0x000F Rs
5721 */
5722 newval = md_chars_to_number (buf, THUMB_SIZE);
5723 {
5724 int rd = (newval >> 4) & 0xf;
5725 int rs = newval & 0xf;
5726 int subtract = newval & 0x8000;
5727
5728 if (rd == REG_SP)
5729 {
5730 if (value & ~0x1fc)
5731 as_bad_where (fixP->fx_file, fixP->fx_line,
5732 _("Invalid immediate for stack address calculation"));
5733 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5734 newval |= value >> 2;
5735 }
5736 else if (rs == REG_PC || rs == REG_SP)
5737 {
5738 if (subtract ||
5739 value & ~0x3fc)
5740 as_bad_where (fixP->fx_file, fixP->fx_line,
5741 _("Invalid immediate for address calculation (value = 0x%08lX)"),
5742 (unsigned long) value);
5743 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
5744 newval |= rd << 8;
5745 newval |= value >> 2;
5746 }
5747 else if (rs == rd)
5748 {
5749 if (value & ~0xff)
5750 as_bad_where (fixP->fx_file, fixP->fx_line,
5751 _("Invalid 8bit immediate"));
5752 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5753 newval |= (rd << 8) | value;
5754 }
5755 else
5756 {
5757 if (value & ~0x7)
5758 as_bad_where (fixP->fx_file, fixP->fx_line,
5759 _("Invalid 3bit immediate"));
5760 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5761 newval |= rd | (rs << 3) | (value << 6);
5762 }
5763 }
5764 md_number_to_chars (buf, newval , THUMB_SIZE);
5765 break;
5766
5767 case BFD_RELOC_ARM_THUMB_IMM:
5768 newval = md_chars_to_number (buf, THUMB_SIZE);
5769 switch (newval >> 11)
5770 {
5771 case 0x04: /* 8bit immediate MOV */
5772 case 0x05: /* 8bit immediate CMP */
5773 if (value < 0 || value > 255)
5774 as_bad_where (fixP->fx_file, fixP->fx_line,
5775 _("Invalid immediate: %ld is too large"),
5776 (long) value);
5777 newval |= value;
5778 break;
5779
5780 default:
5781 abort ();
5782 }
5783 md_number_to_chars (buf, newval , THUMB_SIZE);
5784 break;
5785
5786 case BFD_RELOC_ARM_THUMB_SHIFT:
5787 /* 5bit shift value (0..31) */
5788 if (value < 0 || value > 31)
5789 as_bad_where (fixP->fx_file, fixP->fx_line,
5790 _("Illegal Thumb shift value: %ld"), (long) value);
5791 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
5792 newval |= value << 6;
5793 md_number_to_chars (buf, newval , THUMB_SIZE);
5794 break;
5795
5796 case BFD_RELOC_VTABLE_INHERIT:
5797 case BFD_RELOC_VTABLE_ENTRY:
5798 fixP->fx_done = 0;
5799 return 1;
5800
5801 case BFD_RELOC_NONE:
5802 default:
5803 as_bad_where (fixP->fx_file, fixP->fx_line,
5804 _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
5805 }
5806
5807 return 1;
5808 }
5809
5810 /* Translate internal representation of relocation info to BFD target
5811 format. */
5812 arelent *
5813 tc_gen_reloc (section, fixp)
5814 asection * section;
5815 fixS * fixp;
5816 {
5817 arelent * reloc;
5818 bfd_reloc_code_real_type code;
5819
5820 reloc = (arelent *) xmalloc (sizeof (arelent));
5821
5822 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
5823 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
5824 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
5825
5826 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
5827 #ifndef OBJ_ELF
5828 if (fixp->fx_pcrel == 0)
5829 reloc->addend = fixp->fx_offset;
5830 else
5831 reloc->addend = fixp->fx_offset = reloc->address;
5832 #else /* OBJ_ELF */
5833 reloc->addend = fixp->fx_offset;
5834 #endif
5835
5836 switch (fixp->fx_r_type)
5837 {
5838 case BFD_RELOC_8:
5839 if (fixp->fx_pcrel)
5840 {
5841 code = BFD_RELOC_8_PCREL;
5842 break;
5843 }
5844
5845 case BFD_RELOC_16:
5846 if (fixp->fx_pcrel)
5847 {
5848 code = BFD_RELOC_16_PCREL;
5849 break;
5850 }
5851
5852 case BFD_RELOC_32:
5853 if (fixp->fx_pcrel)
5854 {
5855 code = BFD_RELOC_32_PCREL;
5856 break;
5857 }
5858
5859 case BFD_RELOC_ARM_PCREL_BRANCH:
5860 case BFD_RELOC_RVA:
5861 case BFD_RELOC_THUMB_PCREL_BRANCH9:
5862 case BFD_RELOC_THUMB_PCREL_BRANCH12:
5863 case BFD_RELOC_THUMB_PCREL_BRANCH23:
5864 case BFD_RELOC_VTABLE_ENTRY:
5865 case BFD_RELOC_VTABLE_INHERIT:
5866 code = fixp->fx_r_type;
5867 break;
5868
5869 case BFD_RELOC_ARM_LITERAL:
5870 case BFD_RELOC_ARM_HWLITERAL:
5871 /* If this is called then the a literal has been referenced across
5872 a section boundary - possibly due to an implicit dump */
5873 as_bad_where (fixp->fx_file, fixp->fx_line,
5874 _("Literal referenced across section boundary (Implicit dump?)"));
5875 return NULL;
5876
5877 #ifdef OBJ_ELF
5878 case BFD_RELOC_ARM_GOT32:
5879 case BFD_RELOC_ARM_GOTOFF:
5880 case BFD_RELOC_ARM_PLT32:
5881 code = fixp->fx_r_type;
5882 break;
5883 #endif
5884
5885 case BFD_RELOC_ARM_IMMEDIATE:
5886 as_bad_where (fixp->fx_file, fixp->fx_line,
5887 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
5888 fixp->fx_r_type);
5889 return NULL;
5890
5891 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
5892 as_bad_where (fixp->fx_file, fixp->fx_line,
5893 _("ADRL used for a symbol not defined in the same file"),
5894 fixp->fx_r_type);
5895 return NULL;
5896
5897 case BFD_RELOC_ARM_OFFSET_IMM:
5898 as_bad_where (fixp->fx_file, fixp->fx_line,
5899 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
5900 fixp->fx_r_type);
5901 return NULL;
5902
5903 default:
5904 {
5905 char * type;
5906 switch (fixp->fx_r_type)
5907 {
5908 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
5909 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
5910 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
5911 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
5912 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
5913 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
5914 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
5915 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
5916 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
5917 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
5918 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
5919 default: type = _("<unknown>"); break;
5920 }
5921 as_bad_where (fixp->fx_file, fixp->fx_line,
5922 _("Can not represent %s relocation in this object file format (%d)"),
5923 type, fixp->fx_pcrel);
5924 return NULL;
5925 }
5926 }
5927
5928 #ifdef OBJ_ELF
5929 if (code == BFD_RELOC_32_PCREL
5930 && GOT_symbol
5931 && fixp->fx_addsy == GOT_symbol)
5932 {
5933 code = BFD_RELOC_ARM_GOTPC;
5934 reloc->addend = fixp->fx_offset = reloc->address;
5935 }
5936 #endif
5937
5938 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
5939
5940 if (reloc->howto == NULL)
5941 {
5942 as_bad_where (fixp->fx_file, fixp->fx_line,
5943 _("Can not represent %s relocation in this object file format"),
5944 bfd_get_reloc_code_name (code));
5945 return NULL;
5946 }
5947
5948 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
5949 vtable entry to be used in the relocation's section offset. */
5950 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
5951 reloc->address = fixp->fx_offset;
5952
5953 return reloc;
5954 }
5955
5956 int
5957 md_estimate_size_before_relax (fragP, segtype)
5958 fragS * fragP;
5959 segT segtype;
5960 {
5961 as_fatal (_("md_estimate_size_before_relax\n"));
5962 return 1;
5963 }
5964
5965 static void
5966 output_inst PARAMS ((void))
5967 {
5968 char * to = NULL;
5969
5970 if (inst.error)
5971 {
5972 as_bad (inst.error);
5973 return;
5974 }
5975
5976 to = frag_more (inst.size);
5977
5978 if (thumb_mode && (inst.size > THUMB_SIZE))
5979 {
5980 assert (inst.size == (2 * THUMB_SIZE));
5981 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
5982 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
5983 }
5984 else if (inst.size > INSN_SIZE)
5985 {
5986 assert (inst.size == (2 * INSN_SIZE));
5987 md_number_to_chars (to, inst.instruction, INSN_SIZE);
5988 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
5989 }
5990 else
5991 md_number_to_chars (to, inst.instruction, inst.size);
5992
5993 if (inst.reloc.type != BFD_RELOC_NONE)
5994 fix_new_arm (frag_now, to - frag_now->fr_literal,
5995 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
5996 inst.reloc.type);
5997
5998 return;
5999 }
6000
6001 void
6002 md_assemble (str)
6003 char * str;
6004 {
6005 char c;
6006 char * p;
6007 char * q;
6008 char * start;
6009
6010 /* Align the instruction.
6011 This may not be the right thing to do but ... */
6012 /* arm_align (2, 0); */
6013 listing_prev_line (); /* Defined in listing.h */
6014
6015 /* Align the previous label if needed. */
6016 if (last_label_seen != NULL)
6017 {
6018 symbol_set_frag (last_label_seen, frag_now);
6019 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
6020 S_SET_SEGMENT (last_label_seen, now_seg);
6021 }
6022
6023 memset (&inst, '\0', sizeof (inst));
6024 inst.reloc.type = BFD_RELOC_NONE;
6025
6026 skip_whitespace (str);
6027
6028 /* Scan up to the end of the op-code, which must end in white space or
6029 end of string. */
6030 for (start = p = str; *p != '\0'; p++)
6031 if (*p == ' ')
6032 break;
6033
6034 if (p == str)
6035 {
6036 as_bad (_("No operator -- statement `%s'\n"), str);
6037 return;
6038 }
6039
6040 if (thumb_mode)
6041 {
6042 CONST struct thumb_opcode * opcode;
6043
6044 c = *p;
6045 *p = '\0';
6046 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
6047 *p = c;
6048
6049 if (opcode)
6050 {
6051 inst.instruction = opcode->value;
6052 inst.size = opcode->size;
6053 (*opcode->parms)(p);
6054 output_inst ();
6055 return;
6056 }
6057 }
6058 else
6059 {
6060 CONST struct asm_opcode * opcode;
6061
6062 inst.size = INSN_SIZE;
6063 /* p now points to the end of the opcode, probably white space, but we
6064 have to break the opcode up in case it contains condionals and flags;
6065 keep trying with progressively smaller basic instructions until one
6066 matches, or we run out of opcode. */
6067 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
6068 for (; q != str; q--)
6069 {
6070 c = *q;
6071 *q = '\0';
6072 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
6073 *q = c;
6074
6075 if (opcode && opcode->template)
6076 {
6077 unsigned long flag_bits = 0;
6078 char * r;
6079
6080 /* Check that this instruction is supported for this CPU. */
6081 if ((opcode->variants & cpu_variant) == 0)
6082 goto try_shorter;
6083
6084 inst.instruction = opcode->value;
6085 if (q == p) /* Just a simple opcode. */
6086 {
6087 if (opcode->comp_suffix != 0)
6088 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6089 opcode->comp_suffix);
6090 else
6091 {
6092 inst.instruction |= COND_ALWAYS;
6093 (*opcode->parms)(q, 0);
6094 }
6095 output_inst ();
6096 return;
6097 }
6098
6099 /* Now check for a conditional. */
6100 r = q;
6101 if (p - r >= 2)
6102 {
6103 CONST struct asm_cond *cond;
6104 char d = *(r + 2);
6105
6106 *(r + 2) = '\0';
6107 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
6108 *(r + 2) = d;
6109 if (cond)
6110 {
6111 if (cond->value == 0xf0000000)
6112 as_tsktsk (
6113 _("Warning: Use of the 'nv' conditional is deprecated\n"));
6114
6115 inst.instruction |= cond->value;
6116 r += 2;
6117 }
6118 else
6119 inst.instruction |= COND_ALWAYS;
6120 }
6121 else
6122 inst.instruction |= COND_ALWAYS;
6123
6124 /* If there is a compulsory suffix, it should come here, before
6125 any optional flags. */
6126 if (opcode->comp_suffix)
6127 {
6128 CONST char *s = opcode->comp_suffix;
6129
6130 while (*s)
6131 {
6132 inst.suffix++;
6133 if (*r == *s)
6134 break;
6135 s++;
6136 }
6137
6138 if (*s == '\0')
6139 {
6140 as_bad (_("Opcode `%s' must have suffix from <%s>\n"), str,
6141 opcode->comp_suffix);
6142 return;
6143 }
6144
6145 r++;
6146 }
6147
6148 /* The remainder, if any should now be flags for the instruction;
6149 Scan these checking each one found with the opcode. */
6150 if (r != p)
6151 {
6152 char d;
6153 CONST struct asm_flg *flag = opcode->flags;
6154
6155 if (flag)
6156 {
6157 int flagno;
6158
6159 d = *p;
6160 *p = '\0';
6161
6162 for (flagno = 0; flag[flagno].template; flagno++)
6163 {
6164 if (streq (r, flag[flagno].template))
6165 {
6166 flag_bits |= flag[flagno].set_bits;
6167 break;
6168 }
6169 }
6170
6171 *p = d;
6172 if (! flag[flagno].template)
6173 goto try_shorter;
6174 }
6175 else
6176 goto try_shorter;
6177 }
6178
6179 (*opcode->parms) (p, flag_bits);
6180 output_inst ();
6181 return;
6182 }
6183
6184 try_shorter:
6185 ;
6186 }
6187 }
6188
6189 /* It wasn't an instruction, but it might be a register alias of the form
6190 alias .req reg */
6191 q = p;
6192 skip_whitespace (q);
6193
6194 c = *p;
6195 *p = '\0';
6196
6197 if (*q && !strncmp (q, ".req ", 4))
6198 {
6199 int reg;
6200 char * copy_of_str = str;
6201 char * r;
6202
6203 q += 4;
6204 skip_whitespace (q);
6205
6206 for (r = q; *r != '\0'; r++)
6207 if (*r == ' ')
6208 break;
6209
6210 if (r != q)
6211 {
6212 int regnum;
6213 char d = *r;
6214
6215 *r = '\0';
6216 regnum = arm_reg_parse (& q);
6217 *r = d;
6218
6219 reg = arm_reg_parse (& str);
6220
6221 if (reg == FAIL)
6222 {
6223 if (regnum != FAIL)
6224 insert_reg_alias (str, regnum);
6225 else
6226 as_warn (_("register '%s' does not exist"), q);
6227 }
6228 else if (regnum != FAIL)
6229 {
6230 if (reg != regnum)
6231 as_warn (_("ignoring redefinition of register alias '%s'"), copy_of_str );
6232
6233 /* Do not warn about redefinitions to the same alias. */
6234 }
6235 else
6236 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
6237 copy_of_str, q);
6238 }
6239 else
6240 as_warn (_("ignoring incomplete .req pseuso op"));
6241
6242 *p = c;
6243 return;
6244 }
6245
6246 *p = c;
6247 as_bad (_("bad instruction `%s'"), start);
6248 }
6249
6250 /*
6251 * md_parse_option
6252 * Invocation line includes a switch not recognized by the base assembler.
6253 * See if it's a processor-specific option. These are:
6254 * Cpu variants, the arm part is optional:
6255 * -m[arm]1 Currently not supported.
6256 * -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
6257 * -m[arm]3 Arm 3 processor
6258 * -m[arm]6[xx], Arm 6 processors
6259 * -m[arm]7[xx][t][[d]m] Arm 7 processors
6260 * -m[arm]8[10] Arm 8 processors
6261 * -m[arm]9[20][tdmi] Arm 9 processors
6262 * -mstrongarm[110[0]] StrongARM processors
6263 * -m[arm]v[2345] Arm architecures
6264 * -mall All (except the ARM1)
6265 * FP variants:
6266 * -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
6267 * -mfpe-old (No float load/store multiples)
6268 * -mno-fpu Disable all floating point instructions
6269 * Run-time endian selection:
6270 * -EB big endian cpu
6271 * -EL little endian cpu
6272 * ARM Procedure Calling Standard:
6273 * -mapcs-32 32 bit APCS
6274 * -mapcs-26 26 bit APCS
6275 * -mapcs-float Pass floats in float regs
6276 * -mapcs-reentrant Position independent code
6277 * -mthumb-interwork Code supports Arm/Thumb interworking
6278 * -moabi Old ELF ABI
6279 */
6280
6281 CONST char * md_shortopts = "m:k";
6282 struct option md_longopts[] =
6283 {
6284 #ifdef ARM_BI_ENDIAN
6285 #define OPTION_EB (OPTION_MD_BASE + 0)
6286 {"EB", no_argument, NULL, OPTION_EB},
6287 #define OPTION_EL (OPTION_MD_BASE + 1)
6288 {"EL", no_argument, NULL, OPTION_EL},
6289 #ifdef OBJ_ELF
6290 #define OPTION_OABI (OPTION_MD_BASE +2)
6291 {"oabi", no_argument, NULL, OPTION_OABI},
6292 #endif
6293 #endif
6294 {NULL, no_argument, NULL, 0}
6295 };
6296 size_t md_longopts_size = sizeof (md_longopts);
6297
6298 int
6299 md_parse_option (c, arg)
6300 int c;
6301 char * arg;
6302 {
6303 char * str = arg;
6304
6305 switch (c)
6306 {
6307 #ifdef ARM_BI_ENDIAN
6308 case OPTION_EB:
6309 target_big_endian = 1;
6310 break;
6311 case OPTION_EL:
6312 target_big_endian = 0;
6313 break;
6314 #endif
6315
6316 case 'm':
6317 switch (*str)
6318 {
6319 case 'f':
6320 if (streq (str, "fpa10"))
6321 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
6322 else if (streq (str, "fpa11"))
6323 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
6324 else if (streq (str, "fpe-old"))
6325 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
6326 else
6327 goto bad;
6328 break;
6329
6330 case 'n':
6331 if (streq (str, "no-fpu"))
6332 cpu_variant &= ~FPU_ALL;
6333 break;
6334
6335 #ifdef OBJ_ELF
6336 case 'o':
6337 if (streq (str, "oabi"))
6338 target_oabi = true;
6339 break;
6340 #endif
6341
6342 case 't':
6343 /* Limit assembler to generating only Thumb instructions: */
6344 if (streq (str, "thumb"))
6345 {
6346 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB;
6347 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
6348 thumb_mode = 1;
6349 }
6350 else if (streq (str, "thumb-interwork"))
6351 {
6352 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_THUMB | ARM_ARCH_V4;
6353 #if defined OBJ_COFF || defined OBJ_ELF
6354 support_interwork = true;
6355 #endif
6356 }
6357 else
6358 goto bad;
6359 break;
6360
6361 default:
6362 if (streq (str, "all"))
6363 {
6364 cpu_variant = ARM_ALL | FPU_ALL;
6365 return 1;
6366 }
6367 #if defined OBJ_COFF || defined OBJ_ELF
6368 if (! strncmp (str, "apcs-", 5))
6369 {
6370 /* GCC passes on all command line options starting "-mapcs-..."
6371 to us, so we must parse them here. */
6372
6373 str += 5;
6374
6375 if (streq (str, "32"))
6376 {
6377 uses_apcs_26 = false;
6378 return 1;
6379 }
6380 else if (streq (str, "26"))
6381 {
6382 uses_apcs_26 = true;
6383 return 1;
6384 }
6385 else if (streq (str, "frame"))
6386 {
6387 /* Stack frames are being generated - does not affect
6388 linkage of code. */
6389 return 1;
6390 }
6391 else if (streq (str, "stack-check"))
6392 {
6393 /* Stack checking is being performed - does not affect
6394 linkage, but does require that the functions
6395 __rt_stkovf_split_small and __rt_stkovf_split_big be
6396 present in the final link. */
6397
6398 return 1;
6399 }
6400 else if (streq (str, "float"))
6401 {
6402 /* Floating point arguments are being passed in the floating
6403 point registers. This does affect linking, since this
6404 version of the APCS is incompatible with the version that
6405 passes floating points in the integer registers. */
6406
6407 uses_apcs_float = true;
6408 return 1;
6409 }
6410 else if (streq (str, "reentrant"))
6411 {
6412 /* Reentrant code has been generated. This does affect
6413 linking, since there is no point in linking reentrant/
6414 position independent code with absolute position code. */
6415 pic_code = true;
6416 return 1;
6417 }
6418
6419 as_bad (_("Unrecognised APCS switch -m%s"), arg);
6420 return 0;
6421 }
6422 #endif
6423 /* Strip off optional "arm" */
6424 if (! strncmp (str, "arm", 3))
6425 str += 3;
6426
6427 switch (*str)
6428 {
6429 case '1':
6430 if (streq (str, "1"))
6431 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
6432 else
6433 goto bad;
6434 break;
6435
6436 case '2':
6437 if (streq (str, "2"))
6438 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
6439 else if (streq (str, "250"))
6440 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
6441 else
6442 goto bad;
6443 break;
6444
6445 case '3':
6446 if (streq (str, "3"))
6447 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
6448 else
6449 goto bad;
6450 break;
6451
6452 case '6':
6453 switch (strtol (str, NULL, 10))
6454 {
6455 case 6:
6456 case 60:
6457 case 600:
6458 case 610:
6459 case 620:
6460 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
6461 break;
6462 default:
6463 goto bad;
6464 }
6465 break;
6466
6467 case '7':
6468 switch (strtol (str, & str, 10)) /* Eat the processor name */
6469 {
6470 case 7:
6471 case 70:
6472 case 700:
6473 case 710:
6474 case 7100:
6475 case 7500:
6476 break;
6477 default:
6478 goto bad;
6479 }
6480 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6481 for (; *str; str++)
6482 {
6483 switch (* str)
6484 {
6485 case 't':
6486 cpu_variant |= (ARM_THUMB | ARM_ARCH_V4);
6487 break;
6488
6489 case 'm':
6490 cpu_variant |= ARM_LONGMUL;
6491 break;
6492
6493 case 'f': /* fe => fp enabled cpu. */
6494 if (str[1] == 'e')
6495 ++ str;
6496 else
6497 goto bad;
6498
6499 case 'c': /* Left over from 710c processor name. */
6500 case 'd': /* Debug */
6501 case 'i': /* Embedded ICE */
6502 /* Included for completeness in ARM processor naming. */
6503 break;
6504
6505 default:
6506 goto bad;
6507 }
6508 }
6509 break;
6510
6511 case '8':
6512 if (streq (str, "8") || streq (str, "810"))
6513 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6514 else
6515 goto bad;
6516 break;
6517
6518 case '9':
6519 if (streq (str, "9"))
6520 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6521 else if (streq (str, "920"))
6522 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL;
6523 else if (streq (str, "920t"))
6524 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6525 else if (streq (str, "9tdmi"))
6526 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V4 | ARM_LONGMUL | ARM_THUMB;
6527 else
6528 goto bad;
6529 break;
6530
6531 case 's':
6532 if (streq (str, "strongarm")
6533 || streq (str, "strongarm110")
6534 || streq (str, "strongarm1100"))
6535 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_8 | ARM_ARCH_V4 | ARM_LONGMUL;
6536 else
6537 goto bad;
6538 break;
6539
6540 case 'v':
6541 /* Select variant based on architecture rather than processor */
6542 switch (*++str)
6543 {
6544 case '2':
6545 switch (*++str)
6546 {
6547 case 'a': cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3; break;
6548 case 0: cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2; break;
6549 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6550 }
6551 break;
6552
6553 case '3':
6554 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
6555
6556 switch (*++str)
6557 {
6558 case 'm': cpu_variant |= ARM_LONGMUL; break;
6559 case 0: break;
6560 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6561 }
6562 break;
6563
6564 case '4':
6565 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4;
6566
6567 switch (*++str)
6568 {
6569 case 't': cpu_variant |= ARM_THUMB; break;
6570 case 0: break;
6571 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6572 }
6573 break;
6574
6575 case '5':
6576 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V5;
6577
6578 switch (*++str)
6579 {
6580 case 't': cpu_variant |= ARM_THUMB; break;
6581 case 0: break;
6582 default: as_bad (_("Invalid architecture variant -m%s"), arg); break;
6583 }
6584 break;
6585
6586 default:
6587 as_bad (_("Invalid architecture variant -m%s"), arg);
6588 break;
6589 }
6590 break;
6591
6592 default:
6593 bad:
6594 as_bad (_("Invalid processor variant -m%s"), arg);
6595 return 0;
6596 }
6597 }
6598 break;
6599
6600 case 'k':
6601 pic_code = 1;
6602 break;
6603
6604 default:
6605 return 0;
6606 }
6607
6608 return 1;
6609 }
6610
6611 void
6612 md_show_usage (fp)
6613 FILE * fp;
6614 {
6615 fprintf (fp,
6616 _("\
6617 ARM Specific Assembler Options:\n\
6618 -m[arm][<processor name>] select processor variant\n\
6619 -m[arm]v[2|2a|3|3m|4|4t|5]select architecture variant\n\
6620 -mthumb only allow Thumb instructions\n\
6621 -mthumb-interwork mark the assembled code as supporting interworking\n\
6622 -mall allow any instruction\n\
6623 -mfpa10, -mfpa11 select floating point architecture\n\
6624 -mfpe-old don't allow floating-point multiple instructions\n\
6625 -mno-fpu don't allow any floating-point instructions.\n"));
6626 fprintf (fp,
6627 _("\
6628 -k generate PIC code.\n"));
6629 #if defined OBJ_COFF || defined OBJ_ELF
6630 fprintf (fp,
6631 _("\
6632 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n"));
6633 fprintf (fp,
6634 _("\
6635 -mapcs-float floating point args are passed in FP regs\n"));
6636 fprintf (fp,
6637 _("\
6638 -mapcs-reentrant the code is position independent/reentrant\n"));
6639 #endif
6640 #ifdef OBJ_ELF
6641 fprintf (fp,
6642 _("\
6643 -moabi support the old ELF ABI\n"));
6644 #endif
6645 #ifdef ARM_BI_ENDIAN
6646 fprintf (fp,
6647 _("\
6648 -EB assemble code for a big endian cpu\n\
6649 -EL assemble code for a little endian cpu\n"));
6650 #endif
6651 }
6652
6653 /* We need to be able to fix up arbitrary expressions in some statements.
6654 This is so that we can handle symbols that are an arbitrary distance from
6655 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
6656 which returns part of an address in a form which will be valid for
6657 a data instruction. We do this by pushing the expression into a symbol
6658 in the expr_section, and creating a fix for that. */
6659
6660 static void
6661 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
6662 fragS * frag;
6663 int where;
6664 short int size;
6665 expressionS * exp;
6666 int pc_rel;
6667 int reloc;
6668 {
6669 fixS * new_fix;
6670 arm_fix_data * arm_data;
6671
6672 switch (exp->X_op)
6673 {
6674 case O_constant:
6675 case O_symbol:
6676 case O_add:
6677 case O_subtract:
6678 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
6679 break;
6680
6681 default:
6682 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
6683 pc_rel, reloc);
6684 break;
6685 }
6686
6687 /* Mark whether the fix is to a THUMB instruction, or an ARM instruction */
6688 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
6689 new_fix->tc_fix_data = (PTR) arm_data;
6690 arm_data->thumb_mode = thumb_mode;
6691
6692 return;
6693 }
6694
6695
6696 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6697 void
6698 cons_fix_new_arm (frag, where, size, exp)
6699 fragS * frag;
6700 int where;
6701 int size;
6702 expressionS * exp;
6703 {
6704 bfd_reloc_code_real_type type;
6705 int pcrel = 0;
6706
6707 /* Pick a reloc ...
6708 *
6709 * @@ Should look at CPU word size.
6710 */
6711 switch (size)
6712 {
6713 case 2:
6714 type = BFD_RELOC_16;
6715 break;
6716 case 4:
6717 default:
6718 type = BFD_RELOC_32;
6719 break;
6720 case 8:
6721 type = BFD_RELOC_64;
6722 break;
6723 }
6724
6725 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
6726 }
6727
6728 /* A good place to do this, although this was probably not intended
6729 for this kind of use. We need to dump the literal pool before
6730 references are made to a null symbol pointer. */
6731 void
6732 arm_cleanup ()
6733 {
6734 if (current_poolP == NULL)
6735 return;
6736
6737 subseg_set (text_section, 0); /* Put it at the end of text section. */
6738 s_ltorg (0);
6739 listing_prev_line ();
6740 }
6741
6742 void
6743 arm_start_line_hook ()
6744 {
6745 last_label_seen = NULL;
6746 }
6747
6748 void
6749 arm_frob_label (sym)
6750 symbolS * sym;
6751 {
6752 last_label_seen = sym;
6753
6754 ARM_SET_THUMB (sym, thumb_mode);
6755
6756 #if defined OBJ_COFF || defined OBJ_ELF
6757 ARM_SET_INTERWORK (sym, support_interwork);
6758 #endif
6759
6760 if (label_is_thumb_function_name)
6761 {
6762 /* When the address of a Thumb function is taken the bottom
6763 bit of that address should be set. This will allow
6764 interworking between Arm and Thumb functions to work
6765 correctly. */
6766
6767 THUMB_SET_FUNC (sym, 1);
6768
6769 label_is_thumb_function_name = false;
6770 }
6771 }
6772
6773 /* Adjust the symbol table. This marks Thumb symbols as distinct from
6774 ARM ones. */
6775
6776 void
6777 arm_adjust_symtab ()
6778 {
6779 #ifdef OBJ_COFF
6780 symbolS * sym;
6781
6782 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6783 {
6784 if (ARM_IS_THUMB (sym))
6785 {
6786 if (THUMB_IS_FUNC (sym))
6787 {
6788 /* Mark the symbol as a Thumb function. */
6789 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
6790 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
6791 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
6792
6793 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
6794 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
6795 else
6796 as_bad (_("%s: unexpected function type: %d"),
6797 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
6798 }
6799 else switch (S_GET_STORAGE_CLASS (sym))
6800 {
6801 case C_EXT:
6802 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
6803 break;
6804 case C_STAT:
6805 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
6806 break;
6807 case C_LABEL:
6808 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
6809 break;
6810 default: /* do nothing */
6811 break;
6812 }
6813 }
6814
6815 if (ARM_IS_INTERWORK (sym))
6816 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
6817 }
6818 #endif
6819 #ifdef OBJ_ELF
6820 symbolS * sym;
6821 elf_symbol_type * elf_sym;
6822 char bind;
6823
6824 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
6825 {
6826 if (ARM_IS_THUMB (sym))
6827 {
6828 if (THUMB_IS_FUNC (sym))
6829 {
6830 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
6831 bind = ELF_ST_BIND (elf_sym);
6832 elf_sym->internal_elf_sym.st_info = ELF_ST_INFO (bind, STT_ARM_TFUNC);
6833 }
6834 }
6835 }
6836 #endif
6837 }
6838
6839 int
6840 arm_data_in_code ()
6841 {
6842 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
6843 {
6844 *input_line_pointer = '/';
6845 input_line_pointer += 5;
6846 *input_line_pointer = 0;
6847 return 1;
6848 }
6849
6850 return 0;
6851 }
6852
6853 char *
6854 arm_canonicalize_symbol_name (name)
6855 char * name;
6856 {
6857 int len;
6858
6859 if (thumb_mode && (len = strlen (name)) > 5
6860 && streq (name + len - 5, "/data"))
6861 *(name + len - 5) = 0;
6862
6863 return name;
6864 }
6865
6866 boolean
6867 arm_validate_fix (fixP)
6868 fixS * fixP;
6869 {
6870 /* If the destination of the branch is a defined symbol which does not have
6871 the THUMB_FUNC attribute, then we must be calling a function which has
6872 the (interfacearm) attribute. We look for the Thumb entry point to that
6873 function and change the branch to refer to that function instead. */
6874 if ( fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
6875 && fixP->fx_addsy != NULL
6876 && S_IS_DEFINED (fixP->fx_addsy)
6877 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6878 {
6879 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6880 return true;
6881 }
6882
6883 return false;
6884 }
6885
6886 #ifdef OBJ_ELF
6887 /* Relocations against Thumb function names must be left unadjusted,
6888 so that the linker can use this information to correctly set the
6889 bottom bit of their addresses. The MIPS version of this function
6890 also prevents relocations that are mips-16 specific, but I do not
6891 know why it does this.
6892
6893 FIXME:
6894 There is one other problem that ought to be addressed here, but
6895 which currently is not: Taking the address of a label (rather
6896 than a function) and then later jumping to that address. Such
6897 addresses also ought to have their bottom bit set (assuming that
6898 they reside in Thumb code), but at the moment they will not. */
6899
6900 boolean
6901 arm_fix_adjustable (fixP)
6902 fixS * fixP;
6903 {
6904 if (fixP->fx_addsy == NULL)
6905 return 1;
6906
6907 /* Prevent all adjustments to global symbols. */
6908 if (S_IS_EXTERN (fixP->fx_addsy))
6909 return 0;
6910
6911 if (S_IS_WEAK (fixP->fx_addsy))
6912 return 0;
6913
6914 if (THUMB_IS_FUNC (fixP->fx_addsy)
6915 && fixP->fx_subsy == NULL)
6916 return 0;
6917
6918 /* We need the symbol name for the VTABLE entries */
6919 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6920 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
6921 return 0;
6922
6923 return 1;
6924 }
6925
6926 const char *
6927 elf32_arm_target_format ()
6928 {
6929 if (target_big_endian)
6930 if (target_oabi)
6931 return "elf32-bigarm-oabi";
6932 else
6933 return "elf32-bigarm";
6934 else
6935 if (target_oabi)
6936 return "elf32-littlearm-oabi";
6937 else
6938 return "elf32-littlearm";
6939 }
6940
6941 void
6942 armelf_frob_symbol (symp, puntp)
6943 symbolS * symp;
6944 int * puntp;
6945 {
6946 elf_frob_symbol (symp, puntp);
6947 }
6948
6949 int
6950 arm_force_relocation (fixp)
6951 struct fix * fixp;
6952 {
6953 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
6954 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
6955 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
6956 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
6957 return 1;
6958
6959 return 0;
6960 }
6961
6962 static bfd_reloc_code_real_type
6963 arm_parse_reloc ()
6964 {
6965 char id[16];
6966 char * ip;
6967 int i;
6968 static struct
6969 {
6970 char * str;
6971 int len;
6972 bfd_reloc_code_real_type reloc;
6973 }
6974 reloc_map[] =
6975 {
6976 #define MAP(str,reloc) { str, sizeof (str)-1, reloc }
6977 MAP ("(got)", BFD_RELOC_ARM_GOT32),
6978 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
6979 /* ScottB: Jan 30, 1998 */
6980 /* Added support for parsing "var(PLT)" branch instructions */
6981 /* generated by GCC for PLT relocs */
6982 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
6983 NULL, 0, BFD_RELOC_UNUSED
6984 #undef MAP
6985 };
6986
6987 for (i = 0, ip = input_line_pointer;
6988 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
6989 i++, ip++)
6990 id[i] = tolower (*ip);
6991
6992 for (i = 0; reloc_map[i].str; i++)
6993 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
6994 break;
6995
6996 input_line_pointer += reloc_map[i].len;
6997
6998 return reloc_map[i].reloc;
6999 }
7000
7001 static void
7002 s_arm_elf_cons (nbytes)
7003 int nbytes;
7004 {
7005 expressionS exp;
7006
7007 #ifdef md_flush_pending_output
7008 md_flush_pending_output ();
7009 #endif
7010
7011 if (is_it_end_of_statement ())
7012 {
7013 demand_empty_rest_of_line ();
7014 return;
7015 }
7016
7017 #ifdef md_cons_align
7018 md_cons_align (nbytes);
7019 #endif
7020
7021 do
7022 {
7023 bfd_reloc_code_real_type reloc;
7024
7025 expression (& exp);
7026
7027 if (exp.X_op == O_symbol
7028 && * input_line_pointer == '('
7029 && (reloc = arm_parse_reloc()) != BFD_RELOC_UNUSED)
7030 {
7031 reloc_howto_type * howto = bfd_reloc_type_lookup (stdoutput, reloc);
7032 int size = bfd_get_reloc_size (howto);
7033
7034 if (size > nbytes)
7035 as_bad ("%s relocations do not fit in %d bytes", howto->name, nbytes);
7036 else
7037 {
7038 register char * p = frag_more ((int) nbytes);
7039 int offset = nbytes - size;
7040
7041 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
7042 & exp, 0, reloc);
7043 }
7044 }
7045 else
7046 emit_expr (& exp, (unsigned int) nbytes);
7047 }
7048 while (*input_line_pointer++ == ',');
7049
7050 input_line_pointer--; /* Put terminator back into stream. */
7051 demand_empty_rest_of_line ();
7052 }
7053
7054 #endif /* OBJ_ELF */
This page took 0.171085 seconds and 5 git commands to generate.