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