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