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