Add ARM v5t, v5te and XScale support
[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, 2000
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modified by David Taylor (dtaylor@armltd.co.uk)
6
7 This file is part of GAS, the GNU Assembler.
8
9 GAS is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2, or (at your option)
12 any later version.
13
14 GAS is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with GAS; see the file COPYING. If not, write to the Free
21 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 02111-1307, USA. */
23
24 #include <ctype.h>
25 #include <string.h>
26 #define NO_RELOC 0
27 #include "as.h"
28
29 /* Need TARGET_CPU. */
30 #include "config.h"
31 #include "subsegs.h"
32 #include "obstack.h"
33 #include "symbols.h"
34 #include "listing.h"
35
36 #ifdef OBJ_ELF
37 #include "elf/arm.h"
38 #include "dwarf2dbg.h"
39 #endif
40
41 /* Types of processor to assemble for. */
42 #define ARM_1 0x00000001
43 #define ARM_2 0x00000002
44 #define ARM_3 0x00000004
45 #define ARM_250 ARM_3
46 #define ARM_6 0x00000008
47 #define ARM_7 ARM_6 /* Same core instruction set. */
48 #define ARM_8 ARM_6 /* Same core instruction set. */
49 #define ARM_9 ARM_6 /* Same core instruction set. */
50 #define ARM_CPU_MASK 0x0000000f
51
52 /* The following bitmasks control CPU extensions (ARM7 onwards): */
53 #define ARM_EXT_LONGMUL 0x00000010 /* Allow long multiplies. */
54 #define ARM_EXT_HALFWORD 0x00000020 /* Allow half word loads. */
55 #define ARM_EXT_THUMB 0x00000040 /* Allow BX instruction. */
56 #define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
57 #define ARM_EXT_V5E 0x00000100 /* "El Segundo". */
58 #define ARM_EXT_XSCALE 0x00000200 /* Allow MIA etc. */
59
60 /* Architectures are the sum of the base and extensions. */
61 #define ARM_ARCH_V3M ARM_EXT_LONGMUL
62 #define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_HALFWORD)
63 #define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_THUMB)
64 #define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
65 #define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_THUMB)
66 #define ARM_ARCH_V5TE (ARM_ARCH_V5T | ARM_EXT_V5E)
67 #define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_EXT_XSCALE)
68
69 /* Some useful combinations: */
70 #define ARM_ANY 0x00ffffff
71 #define ARM_2UP (ARM_ANY - ARM_1)
72 #define ARM_ALL ARM_2UP /* Not arm1 only. */
73 #define ARM_3UP 0x00fffffc
74 #define ARM_6UP 0x00fffff8 /* Includes ARM7. */
75
76 #define FPU_CORE 0x80000000
77 #define FPU_FPA10 0x40000000
78 #define FPU_FPA11 0x40000000
79 #define FPU_NONE 0
80
81 /* Some useful combinations. */
82 #define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY. */
83 #define FPU_MEMMULTI 0x7f000000 /* Not fpu_core. */
84
85 #ifndef CPU_DEFAULT
86 #if defined __XSCALE__
87 #define CPU_DEFAULT (ARM_9 | ARM_ARCH_XSCALE)
88 #else
89 #if defined __thumb__
90 #define CPU_DEFAULT (ARM_7 | ARM_ARCH_V4T)
91 #else
92 #define CPU_DEFAULT ARM_ALL
93 #endif
94 #endif
95 #endif
96
97 #ifndef FPU_DEFAULT
98 #define FPU_DEFAULT FPU_ALL
99 #endif
100
101 #define streq(a, b) (strcmp (a, b) == 0)
102 #define skip_whitespace(str) while (*(str) == ' ') ++(str)
103
104 static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
105 static int target_oabi = 0;
106
107 #if defined OBJ_COFF || defined OBJ_ELF
108 /* Flags stored in private area of BFD structure. */
109 static boolean uses_apcs_26 = false;
110 static boolean atpcs = false;
111 static boolean support_interwork = false;
112 static boolean uses_apcs_float = false;
113 static boolean pic_code = false;
114 #endif
115
116 /* This array holds the chars that always start a comment. If the
117 pre-processor is disabled, these aren't very useful. */
118 CONST char comment_chars[] = "@";
119
120 /* This array holds the chars that only start a comment at the beginning of
121 a line. If the line seems to have the form '# 123 filename'
122 .line and .file directives will appear in the pre-processed output. */
123 /* Note that input_file.c hand checks for '#' at the beginning of the
124 first line of the input file. This is because the compiler outputs
125 #NO_APP at the beginning of its output. */
126 /* Also note that comments like this one will always work. */
127 CONST char line_comment_chars[] = "#";
128
129 CONST char line_separator_chars[] = ";";
130
131 /* Chars that can be used to separate mant
132 from exp in floating point numbers. */
133 CONST char EXP_CHARS[] = "eE";
134
135 /* Chars that mean this number is a floating point constant. */
136 /* As in 0f12.456 */
137 /* or 0d1.2345e12 */
138
139 CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
140
141 /* Prefix characters that indicate the start of an immediate
142 value. */
143 #define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
144
145 #ifdef OBJ_ELF
146 /* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
147 symbolS * GOT_symbol;
148 #endif
149
150 /* Size of relocation record. */
151 CONST int md_reloc_size = 8;
152
153 /* 0: assemble for ARM,
154 1: assemble for Thumb,
155 2: assemble for Thumb even though target CPU does not support thumb
156 instructions. */
157 static int thumb_mode = 0;
158
159 typedef struct arm_fix
160 {
161 int thumb_mode;
162 } arm_fix_data;
163
164 struct arm_it
165 {
166 CONST char * error;
167 unsigned long instruction;
168 int suffix;
169 int size;
170 struct
171 {
172 bfd_reloc_code_real_type type;
173 expressionS exp;
174 int pc_rel;
175 } reloc;
176 };
177
178 struct arm_it inst;
179
180 enum asm_shift_index
181 {
182 SHIFT_LSL = 0,
183 SHIFT_LSR,
184 SHIFT_ASR,
185 SHIFT_ROR,
186 SHIFT_RRX
187 };
188
189 struct asm_shift_properties
190 {
191 enum asm_shift_index index;
192 unsigned long bit_field;
193 unsigned int allows_0 : 1;
194 unsigned int allows_32 : 1;
195 };
196
197 static const struct asm_shift_properties shift_properties [] =
198 {
199 { SHIFT_LSL, 0, 1, 0},
200 { SHIFT_LSR, 0x20, 0, 1},
201 { SHIFT_ASR, 0x40, 0, 1},
202 { SHIFT_ROR, 0x60, 0, 0},
203 { SHIFT_RRX, 0x60, 0, 0}
204 };
205
206 struct asm_shift_name
207 {
208 const char * name;
209 const struct asm_shift_properties * properties;
210 };
211
212 static const struct asm_shift_name shift_names [] =
213 {
214 { "asl", shift_properties + SHIFT_LSL },
215 { "lsl", shift_properties + SHIFT_LSL },
216 { "lsr", shift_properties + SHIFT_LSR },
217 { "asr", shift_properties + SHIFT_ASR },
218 { "ror", shift_properties + SHIFT_ROR },
219 { "rrx", shift_properties + SHIFT_RRX },
220 { "ASL", shift_properties + SHIFT_LSL },
221 { "LSL", shift_properties + SHIFT_LSL },
222 { "LSR", shift_properties + SHIFT_LSR },
223 { "ASR", shift_properties + SHIFT_ASR },
224 { "ROR", shift_properties + SHIFT_ROR },
225 { "RRX", shift_properties + SHIFT_RRX }
226 };
227
228 #define NO_SHIFT_RESTRICT 1
229 #define SHIFT_RESTRICT 0
230
231 #define NUM_FLOAT_VALS 8
232
233 CONST char * fp_const[] =
234 {
235 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
236 };
237
238 /* Number of littlenums required to hold an extended precision number. */
239 #define MAX_LITTLENUMS 6
240
241 LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
242
243 #define FAIL (-1)
244 #define SUCCESS (0)
245
246 #define SUFF_S 1
247 #define SUFF_D 2
248 #define SUFF_E 3
249 #define SUFF_P 4
250
251 #define CP_T_X 0x00008000
252 #define CP_T_Y 0x00400000
253 #define CP_T_Pre 0x01000000
254 #define CP_T_UD 0x00800000
255 #define CP_T_WB 0x00200000
256
257 #define CONDS_BIT 0x00100000
258 #define LOAD_BIT 0x00100000
259 #define TRANS_BIT 0x00200000
260
261 #define DOUBLE_LOAD_FLAG 0x00000001
262
263 struct asm_cond
264 {
265 CONST char * template;
266 unsigned long value;
267 };
268
269 /* This is to save a hash look-up in the common case. */
270 #define COND_ALWAYS 0xe0000000
271
272 static CONST struct asm_cond conds[] =
273 {
274 {"eq", 0x00000000},
275 {"ne", 0x10000000},
276 {"cs", 0x20000000}, {"hs", 0x20000000},
277 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
278 {"mi", 0x40000000},
279 {"pl", 0x50000000},
280 {"vs", 0x60000000},
281 {"vc", 0x70000000},
282 {"hi", 0x80000000},
283 {"ls", 0x90000000},
284 {"ge", 0xa0000000},
285 {"lt", 0xb0000000},
286 {"gt", 0xc0000000},
287 {"le", 0xd0000000},
288 {"al", 0xe0000000},
289 {"nv", 0xf0000000}
290 };
291
292 /* Warning: If the top bit of the set_bits is set, then the standard
293 instruction bitmask is ignored, and the new bitmask is taken from
294 the set_bits: */
295 struct asm_flg
296 {
297 CONST char * template; /* Basic flag string. */
298 unsigned long set_bits; /* Bits to set. */
299 };
300
301 static CONST struct asm_flg s_flag[] =
302 {
303 {"s", CONDS_BIT},
304 {NULL, 0}
305 };
306
307 static CONST struct asm_flg ldr_flags[] =
308 {
309 {"d", DOUBLE_LOAD_FLAG},
310 {"b", 0x00400000},
311 {"t", TRANS_BIT},
312 {"bt", 0x00400000 | TRANS_BIT},
313 {"h", 0x801000b0},
314 {"sh", 0x801000f0},
315 {"sb", 0x801000d0},
316 {NULL, 0}
317 };
318
319 static CONST struct asm_flg str_flags[] =
320 {
321 {"d", DOUBLE_LOAD_FLAG},
322 {"b", 0x00400000},
323 {"t", TRANS_BIT},
324 {"bt", 0x00400000 | TRANS_BIT},
325 {"h", 0x800000b0},
326 {NULL, 0}
327 };
328
329 static CONST struct asm_flg byte_flag[] =
330 {
331 {"b", 0x00400000},
332 {NULL, 0}
333 };
334
335 static CONST struct asm_flg cmp_flags[] =
336 {
337 {"s", CONDS_BIT},
338 {"p", 0x0010f000},
339 {NULL, 0}
340 };
341
342 static CONST struct asm_flg ldm_flags[] =
343 {
344 {"ed", 0x01800000},
345 {"fd", 0x00800000},
346 {"ea", 0x01000000},
347 {"fa", 0x08000000},
348 {"ib", 0x01800000},
349 {"ia", 0x00800000},
350 {"db", 0x01000000},
351 {"da", 0x08000000},
352 {NULL, 0}
353 };
354
355 static CONST struct asm_flg stm_flags[] =
356 {
357 {"ed", 0x08000000},
358 {"fd", 0x01000000},
359 {"ea", 0x00800000},
360 {"fa", 0x01800000},
361 {"ib", 0x01800000},
362 {"ia", 0x00800000},
363 {"db", 0x01000000},
364 {"da", 0x08000000},
365 {NULL, 0}
366 };
367
368 static CONST struct asm_flg lfm_flags[] =
369 {
370 {"fd", 0x00800000},
371 {"ea", 0x01000000},
372 {NULL, 0}
373 };
374
375 static CONST struct asm_flg sfm_flags[] =
376 {
377 {"fd", 0x01000000},
378 {"ea", 0x00800000},
379 {NULL, 0}
380 };
381
382 static CONST struct asm_flg round_flags[] =
383 {
384 {"p", 0x00000020},
385 {"m", 0x00000040},
386 {"z", 0x00000060},
387 {NULL, 0}
388 };
389
390 /* The implementation of the FIX instruction is broken on some assemblers,
391 in that it accepts a precision specifier as well as a rounding specifier,
392 despite the fact that this is meaningless. To be more compatible, we
393 accept it as well, though of course it does not set any bits. */
394 static CONST struct asm_flg fix_flags[] =
395 {
396 {"p", 0x00000020},
397 {"m", 0x00000040},
398 {"z", 0x00000060},
399 {"sp", 0x00000020},
400 {"sm", 0x00000040},
401 {"sz", 0x00000060},
402 {"dp", 0x00000020},
403 {"dm", 0x00000040},
404 {"dz", 0x00000060},
405 {"ep", 0x00000020},
406 {"em", 0x00000040},
407 {"ez", 0x00000060},
408 {NULL, 0}
409 };
410
411 static CONST struct asm_flg except_flag[] =
412 {
413 {"e", 0x00400000},
414 {NULL, 0}
415 };
416
417 static CONST struct asm_flg cplong_flag[] =
418 {
419 {"l", 0x00400000},
420 {NULL, 0}
421 };
422
423 struct asm_psr
424 {
425 CONST char * template;
426 boolean cpsr;
427 unsigned long field;
428 };
429
430 /* The bit that distnguishes CPSR and SPSR. */
431 #define SPSR_BIT (1 << 22)
432
433 /* How many bits to shift the PSR_xxx bits up by. */
434 #define PSR_SHIFT 16
435
436 #define PSR_c (1 << 0)
437 #define PSR_x (1 << 1)
438 #define PSR_s (1 << 2)
439 #define PSR_f (1 << 3)
440
441 static CONST struct asm_psr psrs[] =
442 {
443 {"CPSR", true, PSR_c | PSR_f},
444 {"CPSR_all", true, PSR_c | PSR_f},
445 {"SPSR", false, PSR_c | PSR_f},
446 {"SPSR_all", false, PSR_c | PSR_f},
447 {"CPSR_flg", true, PSR_f},
448 {"CPSR_f", true, PSR_f},
449 {"SPSR_flg", false, PSR_f},
450 {"SPSR_f", false, PSR_f},
451 {"CPSR_c", true, PSR_c},
452 {"CPSR_ctl", true, PSR_c},
453 {"SPSR_c", false, PSR_c},
454 {"SPSR_ctl", false, PSR_c},
455 {"CPSR_x", true, PSR_x},
456 {"CPSR_s", true, PSR_s},
457 {"SPSR_x", false, PSR_x},
458 {"SPSR_s", false, PSR_s},
459 /* Combinations of flags. */
460 {"CPSR_fs", true, PSR_f | PSR_s},
461 {"CPSR_fx", true, PSR_f | PSR_x},
462 {"CPSR_fc", true, PSR_f | PSR_c},
463 {"CPSR_sf", true, PSR_s | PSR_f},
464 {"CPSR_sx", true, PSR_s | PSR_x},
465 {"CPSR_sc", true, PSR_s | PSR_c},
466 {"CPSR_xf", true, PSR_x | PSR_f},
467 {"CPSR_xs", true, PSR_x | PSR_s},
468 {"CPSR_xc", true, PSR_x | PSR_c},
469 {"CPSR_cf", true, PSR_c | PSR_f},
470 {"CPSR_cs", true, PSR_c | PSR_s},
471 {"CPSR_cx", true, PSR_c | PSR_x},
472 {"CPSR_fsx", true, PSR_f | PSR_s | PSR_x},
473 {"CPSR_fsc", true, PSR_f | PSR_s | PSR_c},
474 {"CPSR_fxs", true, PSR_f | PSR_x | PSR_s},
475 {"CPSR_fxc", true, PSR_f | PSR_x | PSR_c},
476 {"CPSR_fcs", true, PSR_f | PSR_c | PSR_s},
477 {"CPSR_fcx", true, PSR_f | PSR_c | PSR_x},
478 {"CPSR_sfx", true, PSR_s | PSR_f | PSR_x},
479 {"CPSR_sfc", true, PSR_s | PSR_f | PSR_c},
480 {"CPSR_sxf", true, PSR_s | PSR_x | PSR_f},
481 {"CPSR_sxc", true, PSR_s | PSR_x | PSR_c},
482 {"CPSR_scf", true, PSR_s | PSR_c | PSR_f},
483 {"CPSR_scx", true, PSR_s | PSR_c | PSR_x},
484 {"CPSR_xfs", true, PSR_x | PSR_f | PSR_s},
485 {"CPSR_xfc", true, PSR_x | PSR_f | PSR_c},
486 {"CPSR_xsf", true, PSR_x | PSR_s | PSR_f},
487 {"CPSR_xsc", true, PSR_x | PSR_s | PSR_c},
488 {"CPSR_xcf", true, PSR_x | PSR_c | PSR_f},
489 {"CPSR_xcs", true, PSR_x | PSR_c | PSR_s},
490 {"CPSR_cfs", true, PSR_c | PSR_f | PSR_s},
491 {"CPSR_cfx", true, PSR_c | PSR_f | PSR_x},
492 {"CPSR_csf", true, PSR_c | PSR_s | PSR_f},
493 {"CPSR_csx", true, PSR_c | PSR_s | PSR_x},
494 {"CPSR_cxf", true, PSR_c | PSR_x | PSR_f},
495 {"CPSR_cxs", true, PSR_c | PSR_x | PSR_s},
496 {"CPSR_fsxc", true, PSR_f | PSR_s | PSR_x | PSR_c},
497 {"CPSR_fscx", true, PSR_f | PSR_s | PSR_c | PSR_x},
498 {"CPSR_fxsc", true, PSR_f | PSR_x | PSR_s | PSR_c},
499 {"CPSR_fxcs", true, PSR_f | PSR_x | PSR_c | PSR_s},
500 {"CPSR_fcsx", true, PSR_f | PSR_c | PSR_s | PSR_x},
501 {"CPSR_fcxs", true, PSR_f | PSR_c | PSR_x | PSR_s},
502 {"CPSR_sfxc", true, PSR_s | PSR_f | PSR_x | PSR_c},
503 {"CPSR_sfcx", true, PSR_s | PSR_f | PSR_c | PSR_x},
504 {"CPSR_sxfc", true, PSR_s | PSR_x | PSR_f | PSR_c},
505 {"CPSR_sxcf", true, PSR_s | PSR_x | PSR_c | PSR_f},
506 {"CPSR_scfx", true, PSR_s | PSR_c | PSR_f | PSR_x},
507 {"CPSR_scxf", true, PSR_s | PSR_c | PSR_x | PSR_f},
508 {"CPSR_xfsc", true, PSR_x | PSR_f | PSR_s | PSR_c},
509 {"CPSR_xfcs", true, PSR_x | PSR_f | PSR_c | PSR_s},
510 {"CPSR_xsfc", true, PSR_x | PSR_s | PSR_f | PSR_c},
511 {"CPSR_xscf", true, PSR_x | PSR_s | PSR_c | PSR_f},
512 {"CPSR_xcfs", true, PSR_x | PSR_c | PSR_f | PSR_s},
513 {"CPSR_xcsf", true, PSR_x | PSR_c | PSR_s | PSR_f},
514 {"CPSR_cfsx", true, PSR_c | PSR_f | PSR_s | PSR_x},
515 {"CPSR_cfxs", true, PSR_c | PSR_f | PSR_x | PSR_s},
516 {"CPSR_csfx", true, PSR_c | PSR_s | PSR_f | PSR_x},
517 {"CPSR_csxf", true, PSR_c | PSR_s | PSR_x | PSR_f},
518 {"CPSR_cxfs", true, PSR_c | PSR_x | PSR_f | PSR_s},
519 {"CPSR_cxsf", true, PSR_c | PSR_x | PSR_s | PSR_f},
520 {"SPSR_fs", false, PSR_f | PSR_s},
521 {"SPSR_fx", false, PSR_f | PSR_x},
522 {"SPSR_fc", false, PSR_f | PSR_c},
523 {"SPSR_sf", false, PSR_s | PSR_f},
524 {"SPSR_sx", false, PSR_s | PSR_x},
525 {"SPSR_sc", false, PSR_s | PSR_c},
526 {"SPSR_xf", false, PSR_x | PSR_f},
527 {"SPSR_xs", false, PSR_x | PSR_s},
528 {"SPSR_xc", false, PSR_x | PSR_c},
529 {"SPSR_cf", false, PSR_c | PSR_f},
530 {"SPSR_cs", false, PSR_c | PSR_s},
531 {"SPSR_cx", false, PSR_c | PSR_x},
532 {"SPSR_fsx", false, PSR_f | PSR_s | PSR_x},
533 {"SPSR_fsc", false, PSR_f | PSR_s | PSR_c},
534 {"SPSR_fxs", false, PSR_f | PSR_x | PSR_s},
535 {"SPSR_fxc", false, PSR_f | PSR_x | PSR_c},
536 {"SPSR_fcs", false, PSR_f | PSR_c | PSR_s},
537 {"SPSR_fcx", false, PSR_f | PSR_c | PSR_x},
538 {"SPSR_sfx", false, PSR_s | PSR_f | PSR_x},
539 {"SPSR_sfc", false, PSR_s | PSR_f | PSR_c},
540 {"SPSR_sxf", false, PSR_s | PSR_x | PSR_f},
541 {"SPSR_sxc", false, PSR_s | PSR_x | PSR_c},
542 {"SPSR_scf", false, PSR_s | PSR_c | PSR_f},
543 {"SPSR_scx", false, PSR_s | PSR_c | PSR_x},
544 {"SPSR_xfs", false, PSR_x | PSR_f | PSR_s},
545 {"SPSR_xfc", false, PSR_x | PSR_f | PSR_c},
546 {"SPSR_xsf", false, PSR_x | PSR_s | PSR_f},
547 {"SPSR_xsc", false, PSR_x | PSR_s | PSR_c},
548 {"SPSR_xcf", false, PSR_x | PSR_c | PSR_f},
549 {"SPSR_xcs", false, PSR_x | PSR_c | PSR_s},
550 {"SPSR_cfs", false, PSR_c | PSR_f | PSR_s},
551 {"SPSR_cfx", false, PSR_c | PSR_f | PSR_x},
552 {"SPSR_csf", false, PSR_c | PSR_s | PSR_f},
553 {"SPSR_csx", false, PSR_c | PSR_s | PSR_x},
554 {"SPSR_cxf", false, PSR_c | PSR_x | PSR_f},
555 {"SPSR_cxs", false, PSR_c | PSR_x | PSR_s},
556 {"SPSR_fsxc", false, PSR_f | PSR_s | PSR_x | PSR_c},
557 {"SPSR_fscx", false, PSR_f | PSR_s | PSR_c | PSR_x},
558 {"SPSR_fxsc", false, PSR_f | PSR_x | PSR_s | PSR_c},
559 {"SPSR_fxcs", false, PSR_f | PSR_x | PSR_c | PSR_s},
560 {"SPSR_fcsx", false, PSR_f | PSR_c | PSR_s | PSR_x},
561 {"SPSR_fcxs", false, PSR_f | PSR_c | PSR_x | PSR_s},
562 {"SPSR_sfxc", false, PSR_s | PSR_f | PSR_x | PSR_c},
563 {"SPSR_sfcx", false, PSR_s | PSR_f | PSR_c | PSR_x},
564 {"SPSR_sxfc", false, PSR_s | PSR_x | PSR_f | PSR_c},
565 {"SPSR_sxcf", false, PSR_s | PSR_x | PSR_c | PSR_f},
566 {"SPSR_scfx", false, PSR_s | PSR_c | PSR_f | PSR_x},
567 {"SPSR_scxf", false, PSR_s | PSR_c | PSR_x | PSR_f},
568 {"SPSR_xfsc", false, PSR_x | PSR_f | PSR_s | PSR_c},
569 {"SPSR_xfcs", false, PSR_x | PSR_f | PSR_c | PSR_s},
570 {"SPSR_xsfc", false, PSR_x | PSR_s | PSR_f | PSR_c},
571 {"SPSR_xscf", false, PSR_x | PSR_s | PSR_c | PSR_f},
572 {"SPSR_xcfs", false, PSR_x | PSR_c | PSR_f | PSR_s},
573 {"SPSR_xcsf", false, PSR_x | PSR_c | PSR_s | PSR_f},
574 {"SPSR_cfsx", false, PSR_c | PSR_f | PSR_s | PSR_x},
575 {"SPSR_cfxs", false, PSR_c | PSR_f | PSR_x | PSR_s},
576 {"SPSR_csfx", false, PSR_c | PSR_s | PSR_f | PSR_x},
577 {"SPSR_csxf", false, PSR_c | PSR_s | PSR_x | PSR_f},
578 {"SPSR_cxfs", false, PSR_c | PSR_x | PSR_f | PSR_s},
579 {"SPSR_cxsf", false, PSR_c | PSR_x | PSR_s | PSR_f},
580 };
581
582 /* Functions called by parser. */
583 /* ARM instructions. */
584 static void do_arit PARAMS ((char *, unsigned long));
585 static void do_cmp PARAMS ((char *, unsigned long));
586 static void do_mov PARAMS ((char *, unsigned long));
587 static void do_ldst PARAMS ((char *, unsigned long));
588 static void do_ldmstm PARAMS ((char *, unsigned long));
589 static void do_branch PARAMS ((char *, unsigned long));
590 static void do_swi PARAMS ((char *, unsigned long));
591 /* Pseudo Op codes. */
592 static void do_adr PARAMS ((char *, unsigned long));
593 static void do_adrl PARAMS ((char *, unsigned long));
594 static void do_nop PARAMS ((char *, unsigned long));
595 /* ARM 2. */
596 static void do_mul PARAMS ((char *, unsigned long));
597 static void do_mla PARAMS ((char *, unsigned long));
598 /* ARM 3. */
599 static void do_swap PARAMS ((char *, unsigned long));
600 /* ARM 6. */
601 static void do_msr PARAMS ((char *, unsigned long));
602 static void do_mrs PARAMS ((char *, unsigned long));
603 /* ARM 7M. */
604 static void do_mull PARAMS ((char *, unsigned long));
605 /* ARM THUMB. */
606 static void do_bx PARAMS ((char *, unsigned long));
607
608 /* ARM_EXT_XScale. */
609 static void do_mia PARAMS ((char *, unsigned long));
610 static void do_mar PARAMS ((char *, unsigned long));
611 static void do_mra PARAMS ((char *, unsigned long));
612 static void do_pld PARAMS ((char *, unsigned long));
613 static void do_ldrd PARAMS ((char *, unsigned long));
614
615 /* ARM_EXT_V5. */
616 static void do_blx PARAMS ((char *, unsigned long));
617 static void do_bkpt PARAMS ((char *, unsigned long));
618 static void do_clz PARAMS ((char *, unsigned long));
619 static void do_lstc2 PARAMS ((char *, unsigned long));
620 static void do_cdp2 PARAMS ((char *, unsigned long));
621 static void do_co_reg2 PARAMS ((char *, unsigned long));
622
623 static void do_t_blx PARAMS ((char *));
624 static void do_t_bkpt PARAMS ((char *));
625
626 /* ARM_EXT_V5E. */
627 static void do_smla PARAMS ((char *, unsigned long));
628 static void do_smlal PARAMS ((char *, unsigned long));
629 static void do_smul PARAMS ((char *, unsigned long));
630 static void do_qadd PARAMS ((char *, unsigned long));
631 static void do_co_reg2c PARAMS ((char *, unsigned long));
632
633 /* Coprocessor Instructions. */
634 static void do_cdp PARAMS ((char *, unsigned long));
635 static void do_lstc PARAMS ((char *, unsigned long));
636 static void do_co_reg PARAMS ((char *, unsigned long));
637 static void do_fp_ctrl PARAMS ((char *, unsigned long));
638 static void do_fp_ldst PARAMS ((char *, unsigned long));
639 static void do_fp_ldmstm PARAMS ((char *, unsigned long));
640 static void do_fp_dyadic PARAMS ((char *, unsigned long));
641 static void do_fp_monadic PARAMS ((char *, unsigned long));
642 static void do_fp_cmp PARAMS ((char *, unsigned long));
643 static void do_fp_from_reg PARAMS ((char *, unsigned long));
644 static void do_fp_to_reg PARAMS ((char *, unsigned long));
645
646 static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *, int, int));
647 static int arm_reg_parse PARAMS ((char **));
648 static CONST struct asm_psr * arm_psr_parse PARAMS ((char **));
649 static void symbol_locate PARAMS ((symbolS *, CONST char *, segT, valueT, fragS *));
650 static int add_to_lit_pool PARAMS ((void));
651 static unsigned validate_immediate PARAMS ((unsigned));
652 static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *));
653 static int validate_offset_imm PARAMS ((unsigned int, int));
654 static void opcode_select PARAMS ((int));
655 static void end_of_line PARAMS ((char *));
656 static int reg_required_here PARAMS ((char **, int));
657 static int psr_required_here PARAMS ((char **));
658 static int co_proc_number PARAMS ((char **));
659 static int cp_opc_expr PARAMS ((char **, int, int));
660 static int cp_reg_required_here PARAMS ((char **, int));
661 static int fp_reg_required_here PARAMS ((char **, int));
662 static int cp_address_offset PARAMS ((char **));
663 static int cp_address_required_here PARAMS ((char **));
664 static int my_get_float_expression PARAMS ((char **));
665 static int skip_past_comma PARAMS ((char **));
666 static int walk_no_bignums PARAMS ((symbolS *));
667 static int negate_data_op PARAMS ((unsigned long *, unsigned long));
668 static int data_op2 PARAMS ((char **));
669 static int fp_op2 PARAMS ((char **));
670 static long reg_list PARAMS ((char **));
671 static void thumb_load_store PARAMS ((char *, int, int));
672 static int decode_shift PARAMS ((char **, int));
673 static int ldst_extend PARAMS ((char **, int));
674 static void thumb_add_sub PARAMS ((char *, int));
675 static void insert_reg PARAMS ((int));
676 static void thumb_shift PARAMS ((char *, int));
677 static void thumb_mov_compare PARAMS ((char *, int));
678 static void set_constant_flonums PARAMS ((void));
679 static valueT md_chars_to_number PARAMS ((char *, int));
680 static void insert_reg_alias PARAMS ((char *, int));
681 static void output_inst PARAMS ((void));
682 #ifdef OBJ_ELF
683 static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
684 #endif
685
686 /* ARM instructions take 4bytes in the object file, Thumb instructions
687 take 2: */
688 #define INSN_SIZE 4
689
690 /* LONGEST_INST is the longest basic instruction name without
691 conditions or flags. ARM7M has 4 of length 5. El Segundo
692 has one basic instruction name of length 7 (SMLALxy). */
693 #define LONGEST_INST 7
694
695 struct asm_opcode
696 {
697 /* Basic string to match. */
698 CONST char * template;
699
700 /* Basic instruction code. */
701 unsigned long value;
702
703 /* Compulsory suffix that must follow conds. If "", then the
704 instruction is not conditional and must have no suffix. */
705 CONST char * comp_suffix;
706
707 /* Bits to toggle if flag 'n' set. */
708 CONST struct asm_flg * flags;
709
710 /* Which CPU variants this exists for. */
711 unsigned long variants;
712
713 /* Function to call to parse args. */
714 void (* parms) PARAMS ((char *, unsigned long));
715 };
716
717 static CONST struct asm_opcode insns[] =
718 {
719 /* Intel XScale extensions to ARM V5 ISA. */
720 {"mia", 0x0e200010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
721 {"miaph", 0x0e280010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
722 {"miabb", 0x0e2c0010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
723 {"miabt", 0x0e2d0010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
724 {"miatb", 0x0e2e0010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
725 {"miatt", 0x0e2f0010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
726 {"mar", 0x0c400000, NULL, NULL, ARM_EXT_XSCALE, do_mar},
727 {"mra", 0x0c500000, NULL, NULL, ARM_EXT_XSCALE, do_mra},
728 {"pld", 0xf450f000, "", NULL, ARM_EXT_XSCALE, do_pld},
729 {"ldr", 0x000000d0, NULL, ldr_flags, ARM_ANY, do_ldrd},
730 {"str", 0x000000f0, NULL, str_flags, ARM_ANY, do_ldrd},
731
732 /* ARM Instructions. */
733 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
734 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
735 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
736 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
737 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
738 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
739 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
740 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
741 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
742 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
743 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
744 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
745 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
746 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
747 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
748 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
749 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
750 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
751 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
752 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
753 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
754 #ifdef TE_WINCE
755 {"bl", 0x0b000000, NULL, NULL, ARM_ANY, do_branch},
756 {"b", 0x0a000000, NULL, NULL, ARM_ANY, do_branch},
757 #else
758 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
759 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
760 #endif
761
762 /* Pseudo ops. */
763 {"adr", 0x028f0000, NULL, NULL, ARM_ANY, do_adr},
764 {"adrl", 0x028f0000, NULL, NULL, ARM_ANY, do_adrl},
765 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
766
767 /* ARM 2 multiplies. */
768 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
769 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
770
771 /* ARM 3 - swp instructions. */
772 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
773
774 /* ARM 6 Coprocessor instructions. */
775 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
776 {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr},
777 /* ScottB: our code uses 0x0128f000 for msr.
778 NickC: but this is wrong because the bits 16 through 19 are
779 handled by the PSR_xxx defines above. */
780
781 /* ARM 7M long multiplies - need signed/unsigned flags! */
782 {"smull", 0x00c00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull},
783 {"umull", 0x00800090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull},
784 {"smlal", 0x00e00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull},
785 {"umlal", 0x00a00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull},
786
787 /* ARM THUMB interworking. */
788 {"bx", 0x012fff10, NULL, NULL, ARM_EXT_THUMB, do_bx},
789
790 /* Floating point instructions. */
791 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
792 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
793 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
794 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
795 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
796 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
797 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
798 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
799 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
800 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
801 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
802 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
803 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
804 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
805 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
806 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
807 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
808 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
809 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
810 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
811 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
812 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
813 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
814 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
815 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
816 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
817 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
818 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
819 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
820 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
821 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
822 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
823 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
824 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
825 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
826 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
827 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
828 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
829 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
830 /* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
831 be an optional suffix, but part of the instruction. To be compatible,
832 we accept either. */
833 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
834 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
835 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
836 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
837
838 /* Generic copressor instructions. */
839 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
840 {"ldc", 0x0c100000, NULL, cplong_flag, ARM_2UP, do_lstc},
841 {"stc", 0x0c000000, NULL, cplong_flag, ARM_2UP, do_lstc},
842 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
843 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
844
845 /* ARM ISA extension 5. */
846 /* Note: blx is actually 2 opcodes, so the .value is set dynamically.
847 And it's sometimes conditional and sometimes not. */
848 {"blx", 0, NULL, NULL, ARM_EXT_V5, do_blx},
849 {"clz", 0x016f0f10, NULL, NULL, ARM_EXT_V5, do_clz},
850 {"bkpt", 0xe1200070, "", NULL, ARM_EXT_V5, do_bkpt},
851 {"ldc2", 0xfc100000, "", cplong_flag, ARM_EXT_V5, do_lstc2},
852 {"stc2", 0xfc000000, "", cplong_flag, ARM_EXT_V5, do_lstc2},
853 {"cdp2", 0xfe000000, "", NULL, ARM_EXT_V5, do_cdp2},
854 {"mcr2", 0xfe000010, "", NULL, ARM_EXT_V5, do_co_reg2},
855 {"mrc2", 0xfe100010, "", NULL, ARM_EXT_V5, do_co_reg2},
856
857 /* ARM ISA extension 5E, El Segundo. */
858 {"smlabb", 0x01000080, NULL, NULL, ARM_EXT_V5E, do_smla},
859 {"smlatb", 0x010000a0, NULL, NULL, ARM_EXT_V5E, do_smla},
860 {"smlabt", 0x010000c0, NULL, NULL, ARM_EXT_V5E, do_smla},
861 {"smlatt", 0x010000e0, NULL, NULL, ARM_EXT_V5E, do_smla},
862
863 {"smlawb", 0x01200080, NULL, NULL, ARM_EXT_V5E, do_smla},
864 {"smlawt", 0x012000c0, NULL, NULL, ARM_EXT_V5E, do_smla},
865
866 {"smlalbb",0x01400080, NULL, NULL, ARM_EXT_V5E, do_smlal},
867 {"smlaltb",0x014000a0, NULL, NULL, ARM_EXT_V5E, do_smlal},
868 {"smlalbt",0x014000c0, NULL, NULL, ARM_EXT_V5E, do_smlal},
869 {"smlaltt",0x014000e0, NULL, NULL, ARM_EXT_V5E, do_smlal},
870
871 {"smulbb", 0x01600080, NULL, NULL, ARM_EXT_V5E, do_smul},
872 {"smultb", 0x016000a0, NULL, NULL, ARM_EXT_V5E, do_smul},
873 {"smulbt", 0x016000c0, NULL, NULL, ARM_EXT_V5E, do_smul},
874 {"smultt", 0x016000e0, NULL, NULL, ARM_EXT_V5E, do_smul},
875
876 {"smulwb", 0x012000a0, NULL, NULL, ARM_EXT_V5E, do_smul},
877 {"smulwt", 0x012000e0, NULL, NULL, ARM_EXT_V5E, do_smul},
878
879 {"qadd", 0x01000050, NULL, NULL, ARM_EXT_V5E, do_qadd},
880 {"qdadd", 0x01400050, NULL, NULL, ARM_EXT_V5E, do_qadd},
881 {"qsub", 0x01200050, NULL, NULL, ARM_EXT_V5E, do_qadd},
882 {"qdsub", 0x01600050, NULL, NULL, ARM_EXT_V5E, do_qadd},
883
884 {"mcrr", 0x0c400000, NULL, NULL, ARM_EXT_V5E, do_co_reg2c},
885 {"mrrc", 0x0c500000, NULL, NULL, ARM_EXT_V5E, do_co_reg2c},
886 };
887
888 /* Defines for various bits that we will want to toggle. */
889 #define INST_IMMEDIATE 0x02000000
890 #define OFFSET_REG 0x02000000
891 #define HWOFFSET_IMM 0x00400000
892 #define SHIFT_BY_REG 0x00000010
893 #define PRE_INDEX 0x01000000
894 #define INDEX_UP 0x00800000
895 #define WRITE_BACK 0x00200000
896 #define LDM_TYPE_2_OR_3 0x00400000
897
898 #define LITERAL_MASK 0xf000f000
899 #define COND_MASK 0xf0000000
900 #define OPCODE_MASK 0xfe1fffff
901 #define DATA_OP_SHIFT 21
902
903 /* Codes to distinguish the arithmetic instructions. */
904 #define OPCODE_AND 0
905 #define OPCODE_EOR 1
906 #define OPCODE_SUB 2
907 #define OPCODE_RSB 3
908 #define OPCODE_ADD 4
909 #define OPCODE_ADC 5
910 #define OPCODE_SBC 6
911 #define OPCODE_RSC 7
912 #define OPCODE_TST 8
913 #define OPCODE_TEQ 9
914 #define OPCODE_CMP 10
915 #define OPCODE_CMN 11
916 #define OPCODE_ORR 12
917 #define OPCODE_MOV 13
918 #define OPCODE_BIC 14
919 #define OPCODE_MVN 15
920
921 static void do_t_nop PARAMS ((char *));
922 static void do_t_arit PARAMS ((char *));
923 static void do_t_add PARAMS ((char *));
924 static void do_t_asr PARAMS ((char *));
925 static void do_t_branch9 PARAMS ((char *));
926 static void do_t_branch12 PARAMS ((char *));
927 static void do_t_branch23 PARAMS ((char *));
928 static void do_t_bx PARAMS ((char *));
929 static void do_t_compare PARAMS ((char *));
930 static void do_t_ldmstm PARAMS ((char *));
931 static void do_t_ldr PARAMS ((char *));
932 static void do_t_ldrb PARAMS ((char *));
933 static void do_t_ldrh PARAMS ((char *));
934 static void do_t_lds PARAMS ((char *));
935 static void do_t_lsl PARAMS ((char *));
936 static void do_t_lsr PARAMS ((char *));
937 static void do_t_mov PARAMS ((char *));
938 static void do_t_push_pop PARAMS ((char *));
939 static void do_t_str PARAMS ((char *));
940 static void do_t_strb PARAMS ((char *));
941 static void do_t_strh PARAMS ((char *));
942 static void do_t_sub PARAMS ((char *));
943 static void do_t_swi PARAMS ((char *));
944 static void do_t_adr PARAMS ((char *));
945
946 #define T_OPCODE_MUL 0x4340
947 #define T_OPCODE_TST 0x4200
948 #define T_OPCODE_CMN 0x42c0
949 #define T_OPCODE_NEG 0x4240
950 #define T_OPCODE_MVN 0x43c0
951
952 #define T_OPCODE_ADD_R3 0x1800
953 #define T_OPCODE_SUB_R3 0x1a00
954 #define T_OPCODE_ADD_HI 0x4400
955 #define T_OPCODE_ADD_ST 0xb000
956 #define T_OPCODE_SUB_ST 0xb080
957 #define T_OPCODE_ADD_SP 0xa800
958 #define T_OPCODE_ADD_PC 0xa000
959 #define T_OPCODE_ADD_I8 0x3000
960 #define T_OPCODE_SUB_I8 0x3800
961 #define T_OPCODE_ADD_I3 0x1c00
962 #define T_OPCODE_SUB_I3 0x1e00
963
964 #define T_OPCODE_ASR_R 0x4100
965 #define T_OPCODE_LSL_R 0x4080
966 #define T_OPCODE_LSR_R 0x40c0
967 #define T_OPCODE_ASR_I 0x1000
968 #define T_OPCODE_LSL_I 0x0000
969 #define T_OPCODE_LSR_I 0x0800
970
971 #define T_OPCODE_MOV_I8 0x2000
972 #define T_OPCODE_CMP_I8 0x2800
973 #define T_OPCODE_CMP_LR 0x4280
974 #define T_OPCODE_MOV_HR 0x4600
975 #define T_OPCODE_CMP_HR 0x4500
976
977 #define T_OPCODE_LDR_PC 0x4800
978 #define T_OPCODE_LDR_SP 0x9800
979 #define T_OPCODE_STR_SP 0x9000
980 #define T_OPCODE_LDR_IW 0x6800
981 #define T_OPCODE_STR_IW 0x6000
982 #define T_OPCODE_LDR_IH 0x8800
983 #define T_OPCODE_STR_IH 0x8000
984 #define T_OPCODE_LDR_IB 0x7800
985 #define T_OPCODE_STR_IB 0x7000
986 #define T_OPCODE_LDR_RW 0x5800
987 #define T_OPCODE_STR_RW 0x5000
988 #define T_OPCODE_LDR_RH 0x5a00
989 #define T_OPCODE_STR_RH 0x5200
990 #define T_OPCODE_LDR_RB 0x5c00
991 #define T_OPCODE_STR_RB 0x5400
992
993 #define T_OPCODE_PUSH 0xb400
994 #define T_OPCODE_POP 0xbc00
995
996 #define T_OPCODE_BRANCH 0xe7fe
997
998 static int thumb_reg PARAMS ((char ** str, int hi_lo));
999
1000 #define THUMB_SIZE 2 /* Size of thumb instruction. */
1001 #define THUMB_REG_LO 0x1
1002 #define THUMB_REG_HI 0x2
1003 #define THUMB_REG_ANY 0x3
1004
1005 #define THUMB_H1 0x0080
1006 #define THUMB_H2 0x0040
1007
1008 #define THUMB_ASR 0
1009 #define THUMB_LSL 1
1010 #define THUMB_LSR 2
1011
1012 #define THUMB_MOVE 0
1013 #define THUMB_COMPARE 1
1014
1015 #define THUMB_LOAD 0
1016 #define THUMB_STORE 1
1017
1018 #define THUMB_PP_PC_LR 0x0100
1019
1020 /* These three are used for immediate shifts, do not alter. */
1021 #define THUMB_WORD 2
1022 #define THUMB_HALFWORD 1
1023 #define THUMB_BYTE 0
1024
1025 struct thumb_opcode
1026 {
1027 /* Basic string to match. */
1028 CONST char * template;
1029
1030 /* Basic instruction code. */
1031 unsigned long value;
1032
1033 int size;
1034
1035 /* Which CPU variants this exists for. */
1036 unsigned long variants;
1037
1038 /* Function to call to parse args. */
1039 void (* parms) PARAMS ((char *));
1040 };
1041
1042 static CONST struct thumb_opcode tinsns[] =
1043 {
1044 {"adc", 0x4140, 2, ARM_EXT_THUMB, do_t_arit},
1045 {"add", 0x0000, 2, ARM_EXT_THUMB, do_t_add},
1046 {"and", 0x4000, 2, ARM_EXT_THUMB, do_t_arit},
1047 {"asr", 0x0000, 2, ARM_EXT_THUMB, do_t_asr},
1048 {"b", T_OPCODE_BRANCH, 2, ARM_EXT_THUMB, do_t_branch12},
1049 {"beq", 0xd0fe, 2, ARM_EXT_THUMB, do_t_branch9},
1050 {"bne", 0xd1fe, 2, ARM_EXT_THUMB, do_t_branch9},
1051 {"bcs", 0xd2fe, 2, ARM_EXT_THUMB, do_t_branch9},
1052 {"bhs", 0xd2fe, 2, ARM_EXT_THUMB, do_t_branch9},
1053 {"bcc", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9},
1054 {"bul", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9},
1055 {"blo", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9},
1056 {"bmi", 0xd4fe, 2, ARM_EXT_THUMB, do_t_branch9},
1057 {"bpl", 0xd5fe, 2, ARM_EXT_THUMB, do_t_branch9},
1058 {"bvs", 0xd6fe, 2, ARM_EXT_THUMB, do_t_branch9},
1059 {"bvc", 0xd7fe, 2, ARM_EXT_THUMB, do_t_branch9},
1060 {"bhi", 0xd8fe, 2, ARM_EXT_THUMB, do_t_branch9},
1061 {"bls", 0xd9fe, 2, ARM_EXT_THUMB, do_t_branch9},
1062 {"bge", 0xdafe, 2, ARM_EXT_THUMB, do_t_branch9},
1063 {"blt", 0xdbfe, 2, ARM_EXT_THUMB, do_t_branch9},
1064 {"bgt", 0xdcfe, 2, ARM_EXT_THUMB, do_t_branch9},
1065 {"ble", 0xddfe, 2, ARM_EXT_THUMB, do_t_branch9},
1066 {"bal", 0xdefe, 2, ARM_EXT_THUMB, do_t_branch9},
1067 {"bic", 0x4380, 2, ARM_EXT_THUMB, do_t_arit},
1068 {"bl", 0xf7fffffe, 4, ARM_EXT_THUMB, do_t_branch23},
1069 {"blx", 0, 0, ARM_EXT_V5, do_t_blx},
1070 {"bkpt", 0xbe00, 2, ARM_EXT_V5, do_t_bkpt},
1071 {"bx", 0x4700, 2, ARM_EXT_THUMB, do_t_bx},
1072 {"cmn", T_OPCODE_CMN, 2, ARM_EXT_THUMB, do_t_arit},
1073 {"cmp", 0x0000, 2, ARM_EXT_THUMB, do_t_compare},
1074 {"eor", 0x4040, 2, ARM_EXT_THUMB, do_t_arit},
1075 {"ldmia", 0xc800, 2, ARM_EXT_THUMB, do_t_ldmstm},
1076 {"ldr", 0x0000, 2, ARM_EXT_THUMB, do_t_ldr},
1077 {"ldrb", 0x0000, 2, ARM_EXT_THUMB, do_t_ldrb},
1078 {"ldrh", 0x0000, 2, ARM_EXT_THUMB, do_t_ldrh},
1079 {"ldrsb", 0x5600, 2, ARM_EXT_THUMB, do_t_lds},
1080 {"ldrsh", 0x5e00, 2, ARM_EXT_THUMB, do_t_lds},
1081 {"ldsb", 0x5600, 2, ARM_EXT_THUMB, do_t_lds},
1082 {"ldsh", 0x5e00, 2, ARM_EXT_THUMB, do_t_lds},
1083 {"lsl", 0x0000, 2, ARM_EXT_THUMB, do_t_lsl},
1084 {"lsr", 0x0000, 2, ARM_EXT_THUMB, do_t_lsr},
1085 {"mov", 0x0000, 2, ARM_EXT_THUMB, do_t_mov},
1086 {"mul", T_OPCODE_MUL, 2, ARM_EXT_THUMB, do_t_arit},
1087 {"mvn", T_OPCODE_MVN, 2, ARM_EXT_THUMB, do_t_arit},
1088 {"neg", T_OPCODE_NEG, 2, ARM_EXT_THUMB, do_t_arit},
1089 {"orr", 0x4300, 2, ARM_EXT_THUMB, do_t_arit},
1090 {"pop", 0xbc00, 2, ARM_EXT_THUMB, do_t_push_pop},
1091 {"push", 0xb400, 2, ARM_EXT_THUMB, do_t_push_pop},
1092 {"ror", 0x41c0, 2, ARM_EXT_THUMB, do_t_arit},
1093 {"sbc", 0x4180, 2, ARM_EXT_THUMB, do_t_arit},
1094 {"stmia", 0xc000, 2, ARM_EXT_THUMB, do_t_ldmstm},
1095 {"str", 0x0000, 2, ARM_EXT_THUMB, do_t_str},
1096 {"strb", 0x0000, 2, ARM_EXT_THUMB, do_t_strb},
1097 {"strh", 0x0000, 2, ARM_EXT_THUMB, do_t_strh},
1098 {"swi", 0xdf00, 2, ARM_EXT_THUMB, do_t_swi},
1099 {"sub", 0x0000, 2, ARM_EXT_THUMB, do_t_sub},
1100 {"tst", T_OPCODE_TST, 2, ARM_EXT_THUMB, do_t_arit},
1101 /* Pseudo ops: */
1102 {"adr", 0x0000, 2, ARM_EXT_THUMB, do_t_adr},
1103 {"nop", 0x46C0, 2, ARM_EXT_THUMB, do_t_nop}, /* mov r8,r8 */
1104 };
1105
1106 struct reg_entry
1107 {
1108 CONST char * name;
1109 int number;
1110 };
1111
1112 #define int_register(reg) ((reg) >= 0 && (reg) <= 15)
1113 #define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
1114 #define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
1115
1116 #define REG_PC 15
1117 #define REG_LR 14
1118 #define REG_SP 13
1119
1120 /* These are the standard names. Users can add aliases with .req. */
1121 static CONST struct reg_entry reg_table[] =
1122 {
1123 /* Processor Register Numbers. */
1124 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
1125 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
1126 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
1127 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
1128 /* APCS conventions. */
1129 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
1130 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
1131 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
1132 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
1133 /* ATPCS additions to APCS conventions. */
1134 {"wr", 7}, {"v8", 11},
1135 /* FP Registers. */
1136 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
1137 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
1138 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
1139 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
1140 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
1141 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
1142 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
1143 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
1144 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
1145 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1146 /* ATPCS additions to float register names. */
1147 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
1148 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
1149 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
1150 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
1151 /* FIXME: At some point we need to add VFP register names. */
1152 /* Array terminator. */
1153 {NULL, 0}
1154 };
1155
1156 #define BAD_ARGS _("Bad arguments to instruction")
1157 #define BAD_PC _("r15 not allowed here")
1158 #define BAD_FLAGS _("Instruction should not have flags")
1159 #define BAD_COND _("Instruction is not conditional")
1160 #define ERR_NO_ACCUM _("acc0 expected")
1161
1162 static struct hash_control * arm_ops_hsh = NULL;
1163 static struct hash_control * arm_tops_hsh = NULL;
1164 static struct hash_control * arm_cond_hsh = NULL;
1165 static struct hash_control * arm_shift_hsh = NULL;
1166 static struct hash_control * arm_reg_hsh = NULL;
1167 static struct hash_control * arm_psr_hsh = NULL;
1168
1169 /* This table describes all the machine specific pseudo-ops the assembler
1170 has to support. The fields are:
1171 pseudo-op name without dot
1172 function to call to execute this pseudo-op
1173 Integer arg to pass to the function. */
1174
1175 static void s_req PARAMS ((int));
1176 static void s_align PARAMS ((int));
1177 static void s_bss PARAMS ((int));
1178 static void s_even PARAMS ((int));
1179 static void s_ltorg PARAMS ((int));
1180 static void s_arm PARAMS ((int));
1181 static void s_thumb PARAMS ((int));
1182 static void s_code PARAMS ((int));
1183 static void s_force_thumb PARAMS ((int));
1184 static void s_thumb_func PARAMS ((int));
1185 static void s_thumb_set PARAMS ((int));
1186 static void arm_s_text PARAMS ((int));
1187 static void arm_s_data PARAMS ((int));
1188 #ifdef OBJ_ELF
1189 static void arm_s_section PARAMS ((int));
1190 static void s_arm_elf_cons PARAMS ((int));
1191 #endif
1192
1193 static int my_get_expression PARAMS ((expressionS *, char **));
1194
1195 CONST pseudo_typeS md_pseudo_table[] =
1196 {
1197 /* Never called becasue '.req' does not start line. */
1198 { "req", s_req, 0 },
1199 { "bss", s_bss, 0 },
1200 { "align", s_align, 0 },
1201 { "arm", s_arm, 0 },
1202 { "thumb", s_thumb, 0 },
1203 { "code", s_code, 0 },
1204 { "force_thumb", s_force_thumb, 0 },
1205 { "thumb_func", s_thumb_func, 0 },
1206 { "thumb_set", s_thumb_set, 0 },
1207 { "even", s_even, 0 },
1208 { "ltorg", s_ltorg, 0 },
1209 { "pool", s_ltorg, 0 },
1210 /* Allow for the effect of section changes. */
1211 { "text", arm_s_text, 0 },
1212 { "data", arm_s_data, 0 },
1213 #ifdef OBJ_ELF
1214 { "section", arm_s_section, 0 },
1215 { "section.s", arm_s_section, 0 },
1216 { "sect", arm_s_section, 0 },
1217 { "sect.s", arm_s_section, 0 },
1218 { "word", s_arm_elf_cons, 4 },
1219 { "long", s_arm_elf_cons, 4 },
1220 { "file", dwarf2_directive_file, 0 },
1221 { "loc", dwarf2_directive_loc, 0 },
1222 #else
1223 { "word", cons, 4},
1224 #endif
1225 { "extend", float_cons, 'x' },
1226 { "ldouble", float_cons, 'x' },
1227 { "packed", float_cons, 'p' },
1228 { 0, 0, 0 }
1229 };
1230
1231 /* Stuff needed to resolve the label ambiguity
1232 As:
1233 ...
1234 label: <insn>
1235 may differ from:
1236 ...
1237 label:
1238 <insn>
1239 */
1240
1241 symbolS * last_label_seen;
1242 static int label_is_thumb_function_name = false;
1243
1244 /* Literal stuff. */
1245
1246 #define MAX_LITERAL_POOL_SIZE 1024
1247
1248 typedef struct literalS
1249 {
1250 struct expressionS exp;
1251 struct arm_it * inst;
1252 } literalT;
1253
1254 literalT literals[MAX_LITERAL_POOL_SIZE];
1255
1256 /* Next free entry in the pool. */
1257 int next_literal_pool_place = 0;
1258
1259 /* Next literal pool number. */
1260 int lit_pool_num = 1;
1261
1262 symbolS * current_poolP = NULL;
1263
1264 static int
1265 add_to_lit_pool ()
1266 {
1267 int lit_count = 0;
1268
1269 if (current_poolP == NULL)
1270 current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,
1271 (valueT) 0, &zero_address_frag);
1272
1273 /* Check if this literal value is already in the pool: */
1274 while (lit_count < next_literal_pool_place)
1275 {
1276 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
1277 && inst.reloc.exp.X_op == O_constant
1278 && (literals[lit_count].exp.X_add_number
1279 == inst.reloc.exp.X_add_number)
1280 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
1281 break;
1282 lit_count++;
1283 }
1284
1285 if (lit_count == next_literal_pool_place) /* New entry. */
1286 {
1287 if (next_literal_pool_place > MAX_LITERAL_POOL_SIZE)
1288 {
1289 inst.error = _("Literal Pool Overflow");
1290 return FAIL;
1291 }
1292
1293 literals[next_literal_pool_place].exp = inst.reloc.exp;
1294 lit_count = next_literal_pool_place++;
1295 }
1296
1297 inst.reloc.exp.X_op = O_symbol;
1298 inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
1299 inst.reloc.exp.X_add_symbol = current_poolP;
1300
1301 return SUCCESS;
1302 }
1303
1304 /* Can't use symbol_new here, so have to create a symbol and then at
1305 a later date assign it a value. Thats what these functions do. */
1306
1307 static void
1308 symbol_locate (symbolP, name, segment, valu, frag)
1309 symbolS * symbolP;
1310 CONST char * name; /* It is copied, the caller can modify. */
1311 segT segment; /* Segment identifier (SEG_<something>). */
1312 valueT valu; /* Symbol value. */
1313 fragS * frag; /* Associated fragment. */
1314 {
1315 unsigned int name_length;
1316 char * preserved_copy_of_name;
1317
1318 name_length = strlen (name) + 1; /* +1 for \0. */
1319 obstack_grow (&notes, name, name_length);
1320 preserved_copy_of_name = obstack_finish (&notes);
1321 #ifdef STRIP_UNDERSCORE
1322 if (preserved_copy_of_name[0] == '_')
1323 preserved_copy_of_name++;
1324 #endif
1325
1326 #ifdef tc_canonicalize_symbol_name
1327 preserved_copy_of_name =
1328 tc_canonicalize_symbol_name (preserved_copy_of_name);
1329 #endif
1330
1331 S_SET_NAME (symbolP, preserved_copy_of_name);
1332
1333 S_SET_SEGMENT (symbolP, segment);
1334 S_SET_VALUE (symbolP, valu);
1335 symbol_clear_list_pointers(symbolP);
1336
1337 symbol_set_frag (symbolP, frag);
1338
1339 /* Link to end of symbol chain. */
1340 {
1341 extern int symbol_table_frozen;
1342 if (symbol_table_frozen)
1343 abort ();
1344 }
1345
1346 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1347
1348 obj_symbol_new_hook (symbolP);
1349
1350 #ifdef tc_symbol_new_hook
1351 tc_symbol_new_hook (symbolP);
1352 #endif
1353
1354 #ifdef DEBUG_SYMS
1355 verify_symbol_chain (symbol_rootP, symbol_lastP);
1356 #endif /* DEBUG_SYMS */
1357 }
1358
1359 /* Check that an immediate is valid.
1360 If so, convert it to the right format. */
1361
1362 static unsigned int
1363 validate_immediate (val)
1364 unsigned int val;
1365 {
1366 unsigned int a;
1367 unsigned int i;
1368
1369 #define rotate_left(v, n) (v << n | v >> (32 - n))
1370
1371 for (i = 0; i < 32; i += 2)
1372 if ((a = rotate_left (val, i)) <= 0xff)
1373 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
1374
1375 return FAIL;
1376 }
1377
1378 /* Check to see if an immediate can be computed as two seperate immediate
1379 values, added together. We already know that this value cannot be
1380 computed by just one ARM instruction. */
1381
1382 static unsigned int
1383 validate_immediate_twopart (val, highpart)
1384 unsigned int val;
1385 unsigned int * highpart;
1386 {
1387 unsigned int a;
1388 unsigned int i;
1389
1390 for (i = 0; i < 32; i += 2)
1391 if (((a = rotate_left (val, i)) & 0xff) != 0)
1392 {
1393 if (a & 0xff00)
1394 {
1395 if (a & ~ 0xffff)
1396 continue;
1397 * highpart = (a >> 8) | ((i + 24) << 7);
1398 }
1399 else if (a & 0xff0000)
1400 {
1401 if (a & 0xff000000)
1402 continue;
1403 * highpart = (a >> 16) | ((i + 16) << 7);
1404 }
1405 else
1406 {
1407 assert (a & 0xff000000);
1408 * highpart = (a >> 24) | ((i + 8) << 7);
1409 }
1410
1411 return (a & 0xff) | (i << 7);
1412 }
1413
1414 return FAIL;
1415 }
1416
1417 static int
1418 validate_offset_imm (val, hwse)
1419 unsigned int val;
1420 int hwse;
1421 {
1422 if ((hwse && val > 255) || val > 4095)
1423 return FAIL;
1424 return val;
1425 }
1426
1427 static void
1428 s_req (a)
1429 int a ATTRIBUTE_UNUSED;
1430 {
1431 as_bad (_("Invalid syntax for .req directive."));
1432 }
1433
1434 static void
1435 s_bss (ignore)
1436 int ignore ATTRIBUTE_UNUSED;
1437 {
1438 /* We don't support putting frags in the BSS segment, we fake it by
1439 marking in_bss, then looking at s_skip for clues. */
1440 subseg_set (bss_section, 0);
1441 demand_empty_rest_of_line ();
1442 }
1443
1444 static void
1445 s_even (ignore)
1446 int ignore ATTRIBUTE_UNUSED;
1447 {
1448 /* Never make frag if expect extra pass. */
1449 if (!need_pass_2)
1450 frag_align (1, 0, 0);
1451
1452 record_alignment (now_seg, 1);
1453
1454 demand_empty_rest_of_line ();
1455 }
1456
1457 static void
1458 s_ltorg (ignored)
1459 int ignored ATTRIBUTE_UNUSED;
1460 {
1461 int lit_count = 0;
1462 char sym_name[20];
1463
1464 if (current_poolP == NULL)
1465 return;
1466
1467 /* Align pool as you have word accesses.
1468 Only make a frag if we have to. */
1469 if (!need_pass_2)
1470 frag_align (2, 0, 0);
1471
1472 record_alignment (now_seg, 2);
1473
1474 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1475
1476 symbol_locate (current_poolP, sym_name, now_seg,
1477 (valueT) frag_now_fix (), frag_now);
1478 symbol_table_insert (current_poolP);
1479
1480 ARM_SET_THUMB (current_poolP, thumb_mode);
1481
1482 #if defined OBJ_COFF || defined OBJ_ELF
1483 ARM_SET_INTERWORK (current_poolP, support_interwork);
1484 #endif
1485
1486 while (lit_count < next_literal_pool_place)
1487 /* First output the expression in the instruction to the pool. */
1488 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1489
1490 next_literal_pool_place = 0;
1491 current_poolP = NULL;
1492 }
1493
1494 /* Same as s_align_ptwo but align 0 => align 2. */
1495
1496 static void
1497 s_align (unused)
1498 int unused ATTRIBUTE_UNUSED;
1499 {
1500 register int temp;
1501 register long temp_fill;
1502 long max_alignment = 15;
1503
1504 temp = get_absolute_expression ();
1505 if (temp > max_alignment)
1506 as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
1507 else if (temp < 0)
1508 {
1509 as_bad (_("Alignment negative. 0 assumed."));
1510 temp = 0;
1511 }
1512
1513 if (*input_line_pointer == ',')
1514 {
1515 input_line_pointer++;
1516 temp_fill = get_absolute_expression ();
1517 }
1518 else
1519 temp_fill = 0;
1520
1521 if (!temp)
1522 temp = 2;
1523
1524 /* Only make a frag if we HAVE to. */
1525 if (temp && !need_pass_2)
1526 frag_align (temp, (int) temp_fill, 0);
1527 demand_empty_rest_of_line ();
1528
1529 record_alignment (now_seg, temp);
1530 }
1531
1532 static void
1533 s_force_thumb (ignore)
1534 int ignore ATTRIBUTE_UNUSED;
1535 {
1536 /* If we are not already in thumb mode go into it, EVEN if
1537 the target processor does not support thumb instructions.
1538 This is used by gcc/config/arm/lib1funcs.asm for example
1539 to compile interworking support functions even if the
1540 target processor should not support interworking. */
1541 if (! thumb_mode)
1542 {
1543 thumb_mode = 2;
1544
1545 record_alignment (now_seg, 1);
1546 }
1547
1548 demand_empty_rest_of_line ();
1549 }
1550
1551 static void
1552 s_thumb_func (ignore)
1553 int ignore ATTRIBUTE_UNUSED;
1554 {
1555 if (! thumb_mode)
1556 opcode_select (16);
1557
1558 /* The following label is the name/address of the start of a Thumb function.
1559 We need to know this for the interworking support. */
1560 label_is_thumb_function_name = true;
1561
1562 demand_empty_rest_of_line ();
1563 }
1564
1565 /* Perform a .set directive, but also mark the alias as
1566 being a thumb function. */
1567
1568 static void
1569 s_thumb_set (equiv)
1570 int equiv;
1571 {
1572 /* XXX the following is a duplicate of the code for s_set() in read.c
1573 We cannot just call that code as we need to get at the symbol that
1574 is created. */
1575 register char * name;
1576 register char delim;
1577 register char * end_name;
1578 register symbolS * symbolP;
1579
1580 /* Especial apologies for the random logic:
1581 This just grew, and could be parsed much more simply!
1582 Dean - in haste. */
1583 name = input_line_pointer;
1584 delim = get_symbol_end ();
1585 end_name = input_line_pointer;
1586 *end_name = delim;
1587
1588 SKIP_WHITESPACE ();
1589
1590 if (*input_line_pointer != ',')
1591 {
1592 *end_name = 0;
1593 as_bad (_("Expected comma after name \"%s\""), name);
1594 *end_name = delim;
1595 ignore_rest_of_line ();
1596 return;
1597 }
1598
1599 input_line_pointer++;
1600 *end_name = 0;
1601
1602 if (name[0] == '.' && name[1] == '\0')
1603 {
1604 /* XXX - this should not happen to .thumb_set. */
1605 abort ();
1606 }
1607
1608 if ((symbolP = symbol_find (name)) == NULL
1609 && (symbolP = md_undefined_symbol (name)) == NULL)
1610 {
1611 #ifndef NO_LISTING
1612 /* When doing symbol listings, play games with dummy fragments living
1613 outside the normal fragment chain to record the file and line info
1614 for this symbol. */
1615 if (listing & LISTING_SYMBOLS)
1616 {
1617 extern struct list_info_struct * listing_tail;
1618 fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
1619
1620 memset (dummy_frag, 0, sizeof (fragS));
1621 dummy_frag->fr_type = rs_fill;
1622 dummy_frag->line = listing_tail;
1623 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1624 dummy_frag->fr_symbol = symbolP;
1625 }
1626 else
1627 #endif
1628 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1629
1630 #ifdef OBJ_COFF
1631 /* "set" symbols are local unless otherwise specified. */
1632 SF_SET_LOCAL (symbolP);
1633 #endif /* OBJ_COFF */
1634 } /* Make a new symbol. */
1635
1636 symbol_table_insert (symbolP);
1637
1638 * end_name = delim;
1639
1640 if (equiv
1641 && S_IS_DEFINED (symbolP)
1642 && S_GET_SEGMENT (symbolP) != reg_section)
1643 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1644
1645 pseudo_set (symbolP);
1646
1647 demand_empty_rest_of_line ();
1648
1649 /* XXX Now we come to the Thumb specific bit of code. */
1650
1651 THUMB_SET_FUNC (symbolP, 1);
1652 ARM_SET_THUMB (symbolP, 1);
1653 #if defined OBJ_ELF || defined OBJ_COFF
1654 ARM_SET_INTERWORK (symbolP, support_interwork);
1655 #endif
1656 }
1657
1658 /* If we change section we must dump the literal pool first. */
1659
1660 static void
1661 arm_s_text (ignore)
1662 int ignore;
1663 {
1664 if (now_seg != text_section)
1665 s_ltorg (0);
1666
1667 #ifdef OBJ_ELF
1668 obj_elf_text (ignore);
1669 #else
1670 s_text (ignore);
1671 #endif
1672 }
1673
1674 static void
1675 arm_s_data (ignore)
1676 int ignore;
1677 {
1678 if (flag_readonly_data_in_text)
1679 {
1680 if (now_seg != text_section)
1681 s_ltorg (0);
1682 }
1683 else if (now_seg != data_section)
1684 s_ltorg (0);
1685
1686 #ifdef OBJ_ELF
1687 obj_elf_data (ignore);
1688 #else
1689 s_data (ignore);
1690 #endif
1691 }
1692
1693 #ifdef OBJ_ELF
1694 static void
1695 arm_s_section (ignore)
1696 int ignore;
1697 {
1698 s_ltorg (0);
1699
1700 obj_elf_section (ignore);
1701 }
1702 #endif
1703
1704 static void
1705 opcode_select (width)
1706 int width;
1707 {
1708 switch (width)
1709 {
1710 case 16:
1711 if (! thumb_mode)
1712 {
1713 if (! (cpu_variant & ARM_EXT_THUMB))
1714 as_bad (_("selected processor does not support THUMB opcodes"));
1715
1716 thumb_mode = 1;
1717 /* No need to force the alignment, since we will have been
1718 coming from ARM mode, which is word-aligned. */
1719 record_alignment (now_seg, 1);
1720 }
1721 break;
1722
1723 case 32:
1724 if (thumb_mode)
1725 {
1726 if ((cpu_variant & ARM_ANY) == ARM_EXT_THUMB)
1727 as_bad (_("selected processor does not support ARM opcodes"));
1728
1729 thumb_mode = 0;
1730
1731 if (!need_pass_2)
1732 frag_align (2, 0, 0);
1733
1734 record_alignment (now_seg, 1);
1735 }
1736 break;
1737
1738 default:
1739 as_bad (_("invalid instruction size selected (%d)"), width);
1740 }
1741 }
1742
1743 static void
1744 s_arm (ignore)
1745 int ignore ATTRIBUTE_UNUSED;
1746 {
1747 opcode_select (32);
1748 demand_empty_rest_of_line ();
1749 }
1750
1751 static void
1752 s_thumb (ignore)
1753 int ignore ATTRIBUTE_UNUSED;
1754 {
1755 opcode_select (16);
1756 demand_empty_rest_of_line ();
1757 }
1758
1759 static void
1760 s_code (unused)
1761 int unused ATTRIBUTE_UNUSED;
1762 {
1763 register int temp;
1764
1765 temp = get_absolute_expression ();
1766 switch (temp)
1767 {
1768 case 16:
1769 case 32:
1770 opcode_select (temp);
1771 break;
1772
1773 default:
1774 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1775 }
1776 }
1777
1778 static void
1779 end_of_line (str)
1780 char * str;
1781 {
1782 skip_whitespace (str);
1783
1784 if (* str != '\0')
1785 inst.error = _("Garbage following instruction");
1786 }
1787
1788 static int
1789 skip_past_comma (str)
1790 char ** str;
1791 {
1792 char * p = * str, c;
1793 int comma = 0;
1794
1795 while ((c = *p) == ' ' || c == ',')
1796 {
1797 p++;
1798 if (c == ',' && comma++)
1799 return FAIL;
1800 }
1801
1802 if (c == '\0')
1803 return FAIL;
1804
1805 *str = p;
1806 return comma ? SUCCESS : FAIL;
1807 }
1808
1809 /* A standard register must be given at this point.
1810 SHIFT is the place to put it in inst.instruction.
1811 Restores input start point on error.
1812 Returns the reg#, or FAIL. */
1813
1814 static int
1815 reg_required_here (str, shift)
1816 char ** str;
1817 int shift;
1818 {
1819 static char buff [128]; /* XXX */
1820 int reg;
1821 char * start = * str;
1822
1823 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1824 {
1825 if (shift >= 0)
1826 inst.instruction |= reg << shift;
1827 return reg;
1828 }
1829
1830 /* Restore the start point, we may have got a reg of the wrong class. */
1831 *str = start;
1832
1833 /* In the few cases where we might be able to accept something else
1834 this error can be overridden. */
1835 sprintf (buff, _("Register expected, not '%.100s'"), start);
1836 inst.error = buff;
1837
1838 return FAIL;
1839 }
1840
1841 static CONST struct asm_psr *
1842 arm_psr_parse (ccp)
1843 register char ** ccp;
1844 {
1845 char * start = * ccp;
1846 char c;
1847 char * p;
1848 CONST struct asm_psr * psr;
1849
1850 p = start;
1851
1852 /* Skip to the end of the next word in the input stream. */
1853 do
1854 {
1855 c = *p++;
1856 }
1857 while (isalpha (c) || c == '_');
1858
1859 /* Terminate the word. */
1860 *--p = 0;
1861
1862 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
1863 feature for ease of use and backwards compatibility. */
1864 if (!strncmp (start, "cpsr", 4))
1865 strncpy (start, "CPSR", 4);
1866 else if (!strncmp (start, "spsr", 4))
1867 strncpy (start, "SPSR", 4);
1868
1869 /* Now locate the word in the psr hash table. */
1870 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
1871
1872 /* Restore the input stream. */
1873 *p = c;
1874
1875 /* If we found a valid match, advance the
1876 stream pointer past the end of the word. */
1877 *ccp = p;
1878
1879 return psr;
1880 }
1881
1882 /* Parse the input looking for a PSR flag. */
1883
1884 static int
1885 psr_required_here (str)
1886 char ** str;
1887 {
1888 char * start = * str;
1889 CONST struct asm_psr * psr;
1890
1891 psr = arm_psr_parse (str);
1892
1893 if (psr)
1894 {
1895 /* If this is the SPSR that is being modified, set the R bit. */
1896 if (! psr->cpsr)
1897 inst.instruction |= SPSR_BIT;
1898
1899 /* Set the psr flags in the MSR instruction. */
1900 inst.instruction |= psr->field << PSR_SHIFT;
1901
1902 return SUCCESS;
1903 }
1904
1905 /* In the few cases where we might be able to accept
1906 something else this error can be overridden. */
1907 inst.error = _("flag for {c}psr instruction expected");
1908
1909 /* Restore the start point. */
1910 *str = start;
1911 return FAIL;
1912 }
1913
1914 static int
1915 co_proc_number (str)
1916 char ** str;
1917 {
1918 int processor, pchar;
1919
1920 skip_whitespace (* str);
1921
1922 /* The data sheet seems to imply that just a number on its own is valid
1923 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
1924 accept either. */
1925 if (**str == 'p' || **str == 'P')
1926 (*str)++;
1927
1928 pchar = *(*str)++;
1929 if (pchar >= '0' && pchar <= '9')
1930 {
1931 processor = pchar - '0';
1932 if (**str >= '0' && **str <= '9')
1933 {
1934 processor = processor * 10 + *(*str)++ - '0';
1935 if (processor > 15)
1936 {
1937 inst.error = _("Illegal co-processor number");
1938 return FAIL;
1939 }
1940 }
1941 }
1942 else
1943 {
1944 inst.error = _("Bad or missing co-processor number");
1945 return FAIL;
1946 }
1947
1948 inst.instruction |= processor << 8;
1949 return SUCCESS;
1950 }
1951
1952 static int
1953 cp_opc_expr (str, where, length)
1954 char ** str;
1955 int where;
1956 int length;
1957 {
1958 expressionS expr;
1959
1960 skip_whitespace (* str);
1961
1962 memset (&expr, '\0', sizeof (expr));
1963
1964 if (my_get_expression (&expr, str))
1965 return FAIL;
1966 if (expr.X_op != O_constant)
1967 {
1968 inst.error = _("bad or missing expression");
1969 return FAIL;
1970 }
1971
1972 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
1973 {
1974 inst.error = _("immediate co-processor expression too large");
1975 return FAIL;
1976 }
1977
1978 inst.instruction |= expr.X_add_number << where;
1979 return SUCCESS;
1980 }
1981
1982 static int
1983 cp_reg_required_here (str, where)
1984 char ** str;
1985 int where;
1986 {
1987 int reg;
1988 char * start = *str;
1989
1990 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
1991 {
1992 reg &= 15;
1993 inst.instruction |= reg << where;
1994 return reg;
1995 }
1996
1997 /* In the few cases where we might be able to accept something else
1998 this error can be overridden. */
1999 inst.error = _("Co-processor register expected");
2000
2001 /* Restore the start point. */
2002 *str = start;
2003 return FAIL;
2004 }
2005
2006 static int
2007 fp_reg_required_here (str, where)
2008 char ** str;
2009 int where;
2010 {
2011 int reg;
2012 char * start = * str;
2013
2014 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
2015 {
2016 reg &= 7;
2017 inst.instruction |= reg << where;
2018 return reg;
2019 }
2020
2021 /* In the few cases where we might be able to accept something else
2022 this error can be overridden. */
2023 inst.error = _("Floating point register expected");
2024
2025 /* Restore the start point. */
2026 *str = start;
2027 return FAIL;
2028 }
2029
2030 static int
2031 cp_address_offset (str)
2032 char ** str;
2033 {
2034 int offset;
2035
2036 skip_whitespace (* str);
2037
2038 if (! is_immediate_prefix (**str))
2039 {
2040 inst.error = _("immediate expression expected");
2041 return FAIL;
2042 }
2043
2044 (*str)++;
2045
2046 if (my_get_expression (& inst.reloc.exp, str))
2047 return FAIL;
2048
2049 if (inst.reloc.exp.X_op == O_constant)
2050 {
2051 offset = inst.reloc.exp.X_add_number;
2052
2053 if (offset & 3)
2054 {
2055 inst.error = _("co-processor address must be word aligned");
2056 return FAIL;
2057 }
2058
2059 if (offset > 1023 || offset < -1023)
2060 {
2061 inst.error = _("offset too large");
2062 return FAIL;
2063 }
2064
2065 if (offset >= 0)
2066 inst.instruction |= INDEX_UP;
2067 else
2068 offset = -offset;
2069
2070 inst.instruction |= offset >> 2;
2071 }
2072 else
2073 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2074
2075 return SUCCESS;
2076 }
2077
2078 static int
2079 cp_address_required_here (str)
2080 char ** str;
2081 {
2082 char * p = * str;
2083 int pre_inc = 0;
2084 int write_back = 0;
2085
2086 if (*p == '[')
2087 {
2088 int reg;
2089
2090 p++;
2091 skip_whitespace (p);
2092
2093 if ((reg = reg_required_here (& p, 16)) == FAIL)
2094 return FAIL;
2095
2096 skip_whitespace (p);
2097
2098 if (*p == ']')
2099 {
2100 p++;
2101
2102 if (skip_past_comma (& p) == SUCCESS)
2103 {
2104 /* [Rn], #expr */
2105 write_back = WRITE_BACK;
2106
2107 if (reg == REG_PC)
2108 {
2109 inst.error = _("pc may not be used in post-increment");
2110 return FAIL;
2111 }
2112
2113 if (cp_address_offset (& p) == FAIL)
2114 return FAIL;
2115 }
2116 else
2117 pre_inc = PRE_INDEX | INDEX_UP;
2118 }
2119 else
2120 {
2121 /* '['Rn, #expr']'[!] */
2122
2123 if (skip_past_comma (& p) == FAIL)
2124 {
2125 inst.error = _("pre-indexed expression expected");
2126 return FAIL;
2127 }
2128
2129 pre_inc = PRE_INDEX;
2130
2131 if (cp_address_offset (& p) == FAIL)
2132 return FAIL;
2133
2134 skip_whitespace (p);
2135
2136 if (*p++ != ']')
2137 {
2138 inst.error = _("missing ]");
2139 return FAIL;
2140 }
2141
2142 skip_whitespace (p);
2143
2144 if (*p == '!')
2145 {
2146 if (reg == REG_PC)
2147 {
2148 inst.error = _("pc may not be used with write-back");
2149 return FAIL;
2150 }
2151
2152 p++;
2153 write_back = WRITE_BACK;
2154 }
2155 }
2156 }
2157 else
2158 {
2159 if (my_get_expression (&inst.reloc.exp, &p))
2160 return FAIL;
2161
2162 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2163 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
2164 inst.reloc.pc_rel = 1;
2165 inst.instruction |= (REG_PC << 16);
2166 pre_inc = PRE_INDEX;
2167 }
2168
2169 inst.instruction |= write_back | pre_inc;
2170 *str = p;
2171 return SUCCESS;
2172 }
2173
2174 static void
2175 do_nop (str, flags)
2176 char * str;
2177 unsigned long flags;
2178 {
2179 /* Do nothing really. */
2180 inst.instruction |= flags; /* This is pointless. */
2181 end_of_line (str);
2182 return;
2183 }
2184
2185 static void
2186 do_mrs (str, flags)
2187 char *str;
2188 unsigned long flags;
2189 {
2190 int skip = 0;
2191
2192 /* Only one syntax. */
2193 skip_whitespace (str);
2194
2195 if (reg_required_here (&str, 12) == FAIL)
2196 {
2197 inst.error = BAD_ARGS;
2198 return;
2199 }
2200
2201 if (skip_past_comma (&str) == FAIL)
2202 {
2203 inst.error = _("comma expected after register name");
2204 return;
2205 }
2206
2207 skip_whitespace (str);
2208
2209 if ( strcmp (str, "CPSR") == 0
2210 || strcmp (str, "SPSR") == 0
2211 /* Lower case versions for backwards compatability. */
2212 || strcmp (str, "cpsr") == 0
2213 || strcmp (str, "spsr") == 0)
2214 skip = 4;
2215
2216 /* This is for backwards compatability with older toolchains. */
2217 else if ( strcmp (str, "cpsr_all") == 0
2218 || strcmp (str, "spsr_all") == 0)
2219 skip = 8;
2220 else
2221 {
2222 inst.error = _("{C|S}PSR expected");
2223 return;
2224 }
2225
2226 if (* str == 's' || * str == 'S')
2227 inst.instruction |= SPSR_BIT;
2228 str += skip;
2229
2230 inst.instruction |= flags;
2231 end_of_line (str);
2232 }
2233
2234 /* Two possible forms:
2235 "{C|S}PSR_<field>, Rm",
2236 "{C|S}PSR_f, #expression". */
2237
2238 static void
2239 do_msr (str, flags)
2240 char * str;
2241 unsigned long flags;
2242 {
2243 skip_whitespace (str);
2244
2245 if (psr_required_here (& str) == FAIL)
2246 return;
2247
2248 if (skip_past_comma (& str) == FAIL)
2249 {
2250 inst.error = _("comma missing after psr flags");
2251 return;
2252 }
2253
2254 skip_whitespace (str);
2255
2256 if (reg_required_here (& str, 0) != FAIL)
2257 {
2258 inst.error = NULL;
2259 inst.instruction |= flags;
2260 end_of_line (str);
2261 return;
2262 }
2263
2264 if (! is_immediate_prefix (* str))
2265 {
2266 inst.error =
2267 _("only a register or immediate value can follow a psr flag");
2268 return;
2269 }
2270
2271 str ++;
2272 inst.error = NULL;
2273
2274 if (my_get_expression (& inst.reloc.exp, & str))
2275 {
2276 inst.error =
2277 _("only a register or immediate value can follow a psr flag");
2278 return;
2279 }
2280
2281 if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
2282 && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
2283 {
2284 inst.error = _("immediate value cannot be used to set this field");
2285 return;
2286 }
2287
2288 flags |= INST_IMMEDIATE;
2289
2290 if (inst.reloc.exp.X_add_symbol)
2291 {
2292 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2293 inst.reloc.pc_rel = 0;
2294 }
2295 else
2296 {
2297 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
2298
2299 if (value == (unsigned) FAIL)
2300 {
2301 inst.error = _("Invalid constant");
2302 return;
2303 }
2304
2305 inst.instruction |= value;
2306 }
2307
2308 inst.error = NULL;
2309 inst.instruction |= flags;
2310 end_of_line (str);
2311 }
2312
2313 /* Long Multiply Parser
2314 UMULL RdLo, RdHi, Rm, Rs
2315 SMULL RdLo, RdHi, Rm, Rs
2316 UMLAL RdLo, RdHi, Rm, Rs
2317 SMLAL RdLo, RdHi, Rm, Rs. */
2318
2319 static void
2320 do_mull (str, flags)
2321 char * str;
2322 unsigned long flags;
2323 {
2324 int rdlo, rdhi, rm, rs;
2325
2326 /* Only one format "rdlo, rdhi, rm, rs". */
2327 skip_whitespace (str);
2328
2329 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
2330 {
2331 inst.error = BAD_ARGS;
2332 return;
2333 }
2334
2335 if (skip_past_comma (&str) == FAIL
2336 || (rdhi = reg_required_here (&str, 16)) == FAIL)
2337 {
2338 inst.error = BAD_ARGS;
2339 return;
2340 }
2341
2342 if (skip_past_comma (&str) == FAIL
2343 || (rm = reg_required_here (&str, 0)) == FAIL)
2344 {
2345 inst.error = BAD_ARGS;
2346 return;
2347 }
2348
2349 /* rdhi, rdlo and rm must all be different. */
2350 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
2351 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2352
2353 if (skip_past_comma (&str) == FAIL
2354 || (rs = reg_required_here (&str, 8)) == FAIL)
2355 {
2356 inst.error = BAD_ARGS;
2357 return;
2358 }
2359
2360 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2361 {
2362 inst.error = BAD_PC;
2363 return;
2364 }
2365
2366 inst.instruction |= flags;
2367 end_of_line (str);
2368 return;
2369 }
2370
2371 static void
2372 do_mul (str, flags)
2373 char * str;
2374 unsigned long flags;
2375 {
2376 int rd, rm;
2377
2378 /* Only one format "rd, rm, rs". */
2379 skip_whitespace (str);
2380
2381 if ((rd = reg_required_here (&str, 16)) == FAIL)
2382 {
2383 inst.error = BAD_ARGS;
2384 return;
2385 }
2386
2387 if (rd == REG_PC)
2388 {
2389 inst.error = BAD_PC;
2390 return;
2391 }
2392
2393 if (skip_past_comma (&str) == FAIL
2394 || (rm = reg_required_here (&str, 0)) == FAIL)
2395 {
2396 inst.error = BAD_ARGS;
2397 return;
2398 }
2399
2400 if (rm == REG_PC)
2401 {
2402 inst.error = BAD_PC;
2403 return;
2404 }
2405
2406 if (rm == rd)
2407 as_tsktsk (_("rd and rm should be different in mul"));
2408
2409 if (skip_past_comma (&str) == FAIL
2410 || (rm = reg_required_here (&str, 8)) == FAIL)
2411 {
2412 inst.error = BAD_ARGS;
2413 return;
2414 }
2415
2416 if (rm == REG_PC)
2417 {
2418 inst.error = BAD_PC;
2419 return;
2420 }
2421
2422 inst.instruction |= flags;
2423 end_of_line (str);
2424 return;
2425 }
2426
2427 static void
2428 do_mla (str, flags)
2429 char * str;
2430 unsigned long flags;
2431 {
2432 int rd, rm;
2433
2434 /* Only one format "rd, rm, rs, rn". */
2435 skip_whitespace (str);
2436
2437 if ((rd = reg_required_here (&str, 16)) == FAIL)
2438 {
2439 inst.error = BAD_ARGS;
2440 return;
2441 }
2442
2443 if (rd == REG_PC)
2444 {
2445 inst.error = BAD_PC;
2446 return;
2447 }
2448
2449 if (skip_past_comma (&str) == FAIL
2450 || (rm = reg_required_here (&str, 0)) == FAIL)
2451 {
2452 inst.error = BAD_ARGS;
2453 return;
2454 }
2455
2456 if (rm == REG_PC)
2457 {
2458 inst.error = BAD_PC;
2459 return;
2460 }
2461
2462 if (rm == rd)
2463 as_tsktsk (_("rd and rm should be different in mla"));
2464
2465 if (skip_past_comma (&str) == FAIL
2466 || (rd = reg_required_here (&str, 8)) == FAIL
2467 || skip_past_comma (&str) == FAIL
2468 || (rm = reg_required_here (&str, 12)) == FAIL)
2469 {
2470 inst.error = BAD_ARGS;
2471 return;
2472 }
2473
2474 if (rd == REG_PC || rm == REG_PC)
2475 {
2476 inst.error = BAD_PC;
2477 return;
2478 }
2479
2480 inst.instruction |= flags;
2481 end_of_line (str);
2482 return;
2483 }
2484
2485 /* Expects *str -> the characters "acc0", possibly with leading blanks.
2486 Advances *str to the next non-alphanumeric.
2487 Returns 0, or else FAIL (in which case sets inst.error).
2488
2489 (In a future XScale, there may be accumulators other than zero.
2490 At that time this routine and its callers can be upgraded to suit.) */
2491
2492 static int
2493 accum0_required_here (str)
2494 char ** str;
2495 {
2496 static char buff [128]; /* Note the address is taken. Hence, static. */
2497 char * p = * str;
2498 char c;
2499 int result = 0; /* The accum number. */
2500
2501 skip_whitespace (p);
2502
2503 *str = p; /* Advance caller's string pointer too. */
2504 c = *p++;
2505 while (isalnum (c))
2506 c = *p++;
2507
2508 *--p = 0; /* Aap nul into input buffer at non-alnum. */
2509
2510 if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
2511 {
2512 sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
2513 inst.error = buff;
2514 result = FAIL;
2515 }
2516
2517 *p = c; /* Unzap. */
2518 *str = p; /* Caller's string pointer to after match. */
2519 return result;
2520 }
2521
2522 /* Expects **str -> after a comma. May be leading blanks.
2523 Advances *str, recognizing a load mode, and setting inst.instruction.
2524 Returns rn, or else FAIL (in which case may set inst.error
2525 and not advance str)
2526
2527 Note: doesn't know Rd, so no err checks that require such knowledge. */
2528
2529 static int
2530 ld_mode_required_here (string)
2531 char ** string;
2532 {
2533 char * str = * string;
2534 int rn;
2535 int pre_inc = 0;
2536
2537 skip_whitespace (str);
2538
2539 if (* str == '[')
2540 {
2541 str++;
2542
2543 skip_whitespace (str);
2544
2545 if ((rn = reg_required_here (& str, 16)) == FAIL)
2546 return FAIL;
2547
2548 skip_whitespace (str);
2549
2550 if (* str == ']')
2551 {
2552 str ++;
2553
2554 if (skip_past_comma (& str) == SUCCESS)
2555 {
2556 /* [Rn],... (post inc) */
2557 if (ldst_extend (& str, 1) == FAIL)
2558 return FAIL;
2559 }
2560 else /* [Rn] */
2561 {
2562 skip_whitespace (str);
2563
2564 if (* str == '!')
2565 {
2566 str ++;
2567 inst.instruction |= WRITE_BACK;
2568 }
2569
2570 inst.instruction |= INDEX_UP | HWOFFSET_IMM;
2571 pre_inc = 1;
2572 }
2573 }
2574 else /* [Rn,...] */
2575 {
2576 if (skip_past_comma (& str) == FAIL)
2577 {
2578 inst.error = _("pre-indexed expression expected");
2579 return FAIL;
2580 }
2581
2582 pre_inc = 1;
2583
2584 if (ldst_extend (& str, 1) == FAIL)
2585 return FAIL;
2586
2587 skip_whitespace (str);
2588
2589 if (* str ++ != ']')
2590 {
2591 inst.error = _("missing ]");
2592 return FAIL;
2593 }
2594
2595 skip_whitespace (str);
2596
2597 if (* str == '!')
2598 {
2599 str ++;
2600 inst.instruction |= WRITE_BACK;
2601 }
2602 }
2603 }
2604 else if (* str == '=') /* ldr's "r,=label" syntax */
2605 /* We should never reach here, because <text> = <expression> is
2606 caught gas/read.c read_a_source_file() as a .set operation. */
2607 return FAIL;
2608 else /* PC +- 8 bit immediate offset. */
2609 {
2610 if (my_get_expression (& inst.reloc.exp, & str))
2611 return FAIL;
2612
2613 inst.instruction |= HWOFFSET_IMM; /* The I bit. */
2614 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2615 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
2616 inst.reloc.pc_rel = 1;
2617 inst.instruction |= (REG_PC << 16);
2618
2619 rn = REG_PC;
2620 pre_inc = 1;
2621 }
2622
2623 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
2624 * string = str;
2625
2626 return rn;
2627 }
2628
2629 /* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
2630 SMLAxy{cond} Rd,Rm,Rs,Rn
2631 SMLAWy{cond} Rd,Rm,Rs,Rn
2632 Error if any register is R15. */
2633
2634 static void
2635 do_smla (str, flags)
2636 char * str;
2637 unsigned long flags;
2638 {
2639 int rd, rm, rs, rn;
2640
2641 skip_whitespace (str);
2642
2643 if ((rd = reg_required_here (& str, 16)) == FAIL
2644 || skip_past_comma (& str) == FAIL
2645 || (rm = reg_required_here (& str, 0)) == FAIL
2646 || skip_past_comma (& str) == FAIL
2647 || (rs = reg_required_here (& str, 8)) == FAIL
2648 || skip_past_comma (& str) == FAIL
2649 || (rn = reg_required_here (& str, 12)) == FAIL)
2650 inst.error = BAD_ARGS;
2651
2652 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
2653 inst.error = BAD_PC;
2654
2655 else if (flags)
2656 inst.error = BAD_FLAGS;
2657
2658 else
2659 end_of_line (str);
2660 }
2661
2662 /* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
2663 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
2664 Error if any register is R15.
2665 Warning if Rdlo == Rdhi. */
2666
2667 static void
2668 do_smlal (str, flags)
2669 char * str;
2670 unsigned long flags;
2671 {
2672 int rdlo, rdhi, rm, rs;
2673
2674 skip_whitespace (str);
2675
2676 if ((rdlo = reg_required_here (& str, 12)) == FAIL
2677 || skip_past_comma (& str) == FAIL
2678 || (rdhi = reg_required_here (& str, 16)) == FAIL
2679 || skip_past_comma (& str) == FAIL
2680 || (rm = reg_required_here (& str, 0)) == FAIL
2681 || skip_past_comma (& str) == FAIL
2682 || (rs = reg_required_here (& str, 8)) == FAIL)
2683 {
2684 inst.error = BAD_ARGS;
2685 return;
2686 }
2687
2688 if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
2689 {
2690 inst.error = BAD_PC;
2691 return;
2692 }
2693
2694 if (rdlo == rdhi)
2695 as_tsktsk (_("rdhi and rdlo must be different"));
2696
2697 if (flags)
2698 inst.error = BAD_FLAGS;
2699 else
2700 end_of_line (str);
2701 }
2702
2703 /* ARM V5E (El Segundo) signed-multiply (argument parse)
2704 SMULxy{cond} Rd,Rm,Rs
2705 Error if any register is R15. */
2706
2707 static void
2708 do_smul (str, flags)
2709 char * str;
2710 unsigned long flags;
2711 {
2712 int rd, rm, rs;
2713
2714 skip_whitespace (str);
2715
2716 if ((rd = reg_required_here (& str, 16)) == FAIL
2717 || skip_past_comma (& str) == FAIL
2718 || (rm = reg_required_here (& str, 0)) == FAIL
2719 || skip_past_comma (& str) == FAIL
2720 || (rs = reg_required_here (& str, 8)) == FAIL)
2721 inst.error = BAD_ARGS;
2722
2723 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
2724 inst.error = BAD_PC;
2725
2726 else if (flags)
2727 inst.error = BAD_FLAGS;
2728
2729 else
2730 end_of_line (str);
2731 }
2732
2733 /* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
2734 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
2735 Error if any register is R15. */
2736
2737 static void
2738 do_qadd (str, flags)
2739 char * str;
2740 unsigned long flags;
2741 {
2742 int rd, rm, rn;
2743
2744 skip_whitespace (str);
2745
2746 if ((rd = reg_required_here (& str, 12)) == FAIL
2747 || skip_past_comma (& str) == FAIL
2748 || (rm = reg_required_here (& str, 0)) == FAIL
2749 || skip_past_comma (& str) == FAIL
2750 || (rn = reg_required_here (& str, 16)) == FAIL)
2751 inst.error = BAD_ARGS;
2752
2753 else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
2754 inst.error = BAD_PC;
2755
2756 else if (flags)
2757 inst.error = BAD_FLAGS;
2758
2759 else
2760 end_of_line (str);
2761 }
2762
2763 /* ARM V5E (el Segundo)
2764 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2765 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2766
2767 These are equivalent to the XScale instructions MAR and MRA,
2768 respectively, when coproc == 0, opcode == 0, and CRm == 0.
2769
2770 Result unpredicatable if Rd or Rn is R15. */
2771
2772 static void
2773 do_co_reg2c (str, flags)
2774 char * str;
2775 unsigned long flags;
2776 {
2777 int rd, rn;
2778
2779 skip_whitespace (str);
2780
2781 if (co_proc_number (& str) == FAIL)
2782 {
2783 if (!inst.error)
2784 inst.error = BAD_ARGS;
2785 return;
2786 }
2787
2788 if (skip_past_comma (& str) == FAIL
2789 || cp_opc_expr (& str, 4, 4) == FAIL)
2790 {
2791 if (!inst.error)
2792 inst.error = BAD_ARGS;
2793 return;
2794 }
2795
2796 if (skip_past_comma (& str) == FAIL
2797 || (rd = reg_required_here (& str, 12)) == FAIL)
2798 {
2799 if (!inst.error)
2800 inst.error = BAD_ARGS;
2801 return;
2802 }
2803
2804 if (skip_past_comma (& str) == FAIL
2805 || (rn = reg_required_here (& str, 16)) == FAIL)
2806 {
2807 if (!inst.error)
2808 inst.error = BAD_ARGS;
2809 return;
2810 }
2811
2812 /* Unpredictable result if rd or rn is R15. */
2813 if (rd == REG_PC || rn == REG_PC)
2814 as_tsktsk
2815 (_("Warning: Instruction unpredictable when using r15"));
2816
2817 if (skip_past_comma (& str) == FAIL
2818 || cp_reg_required_here (& str, 0) == FAIL)
2819 {
2820 if (!inst.error)
2821 inst.error = BAD_ARGS;
2822 return;
2823 }
2824
2825 if (flags)
2826 inst.error = BAD_COND;
2827
2828 end_of_line (str);
2829 }
2830
2831
2832 /* ARM V5 count-leading-zeroes instruction (argument parse)
2833 CLZ{<cond>} <Rd>, <Rm>
2834 Condition defaults to COND_ALWAYS.
2835 Error if Rd or Rm are R15. */
2836
2837 static void
2838 do_clz (str, flags)
2839 char * str;
2840 unsigned long flags;
2841 {
2842 int rd, rm;
2843
2844 if (flags)
2845 {
2846 as_bad (BAD_FLAGS);
2847 return;
2848 }
2849
2850 skip_whitespace (str);
2851
2852 if (((rd = reg_required_here (& str, 12)) == FAIL)
2853 || (skip_past_comma (& str) == FAIL)
2854 || ((rm = reg_required_here (& str, 0)) == FAIL))
2855 inst.error = BAD_ARGS;
2856
2857 else if (rd == REG_PC || rm == REG_PC )
2858 inst.error = BAD_PC;
2859
2860 else
2861 end_of_line (str);
2862 }
2863
2864 /* ARM V5 (argument parse)
2865 LDC2{L} <coproc>, <CRd>, <addressing mode>
2866 STC2{L} <coproc>, <CRd>, <addressing mode>
2867 Instruction is not conditional, and has 0xf in the codition field.
2868 Otherwise, it's the same as LDC/STC. */
2869
2870 static void
2871 do_lstc2 (str, flags)
2872 char * str;
2873 unsigned long flags;
2874 {
2875 if (flags)
2876 inst.error = BAD_COND;
2877
2878 skip_whitespace (str);
2879
2880 if (co_proc_number (& str) == FAIL)
2881 {
2882 if (!inst.error)
2883 inst.error = BAD_ARGS;
2884 }
2885 else if (skip_past_comma (& str) == FAIL
2886 || cp_reg_required_here (& str, 12) == FAIL)
2887 {
2888 if (!inst.error)
2889 inst.error = BAD_ARGS;
2890 }
2891 else if (skip_past_comma (& str) == FAIL
2892 || cp_address_required_here (& str) == FAIL)
2893 {
2894 if (! inst.error)
2895 inst.error = BAD_ARGS;
2896 }
2897 else
2898 end_of_line (str);
2899 }
2900
2901 /* ARM V5 (argument parse)
2902 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
2903 Instruction is not conditional, and has 0xf in the condition field.
2904 Otherwise, it's the same as CDP. */
2905
2906 static void
2907 do_cdp2 (str, flags)
2908 char * str;
2909 unsigned long flags;
2910 {
2911 skip_whitespace (str);
2912
2913 if (co_proc_number (& str) == FAIL)
2914 {
2915 if (!inst.error)
2916 inst.error = BAD_ARGS;
2917 return;
2918 }
2919
2920 if (skip_past_comma (& str) == FAIL
2921 || cp_opc_expr (& str, 20,4) == FAIL)
2922 {
2923 if (!inst.error)
2924 inst.error = BAD_ARGS;
2925 return;
2926 }
2927
2928 if (skip_past_comma (& str) == FAIL
2929 || cp_reg_required_here (& str, 12) == FAIL)
2930 {
2931 if (!inst.error)
2932 inst.error = BAD_ARGS;
2933 return;
2934 }
2935
2936 if (skip_past_comma (& str) == FAIL
2937 || cp_reg_required_here (& str, 16) == FAIL)
2938 {
2939 if (!inst.error)
2940 inst.error = BAD_ARGS;
2941 return;
2942 }
2943
2944 if (skip_past_comma (& str) == FAIL
2945 || cp_reg_required_here (& str, 0) == FAIL)
2946 {
2947 if (!inst.error)
2948 inst.error = BAD_ARGS;
2949 return;
2950 }
2951
2952 if (skip_past_comma (& str) == SUCCESS)
2953 {
2954 if (cp_opc_expr (& str, 5, 3) == FAIL)
2955 {
2956 if (!inst.error)
2957 inst.error = BAD_ARGS;
2958 return;
2959 }
2960 }
2961
2962 if (flags)
2963 inst.error = BAD_FLAGS;
2964
2965 end_of_line (str);
2966 }
2967
2968 /* ARM V5 (argument parse)
2969 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
2970 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
2971 Instruction is not conditional, and has 0xf in the condition field.
2972 Otherwise, it's the same as MCR/MRC. */
2973
2974 static void
2975 do_co_reg2 (str, flags)
2976 char * str;
2977 unsigned long flags;
2978 {
2979 skip_whitespace (str);
2980
2981 if (co_proc_number (& str) == FAIL)
2982 {
2983 if (!inst.error)
2984 inst.error = BAD_ARGS;
2985 return;
2986 }
2987
2988 if (skip_past_comma (& str) == FAIL
2989 || cp_opc_expr (& str, 21, 3) == FAIL)
2990 {
2991 if (!inst.error)
2992 inst.error = BAD_ARGS;
2993 return;
2994 }
2995
2996 if (skip_past_comma (& str) == FAIL
2997 || reg_required_here (& str, 12) == FAIL)
2998 {
2999 if (!inst.error)
3000 inst.error = BAD_ARGS;
3001 return;
3002 }
3003
3004 if (skip_past_comma (& str) == FAIL
3005 || cp_reg_required_here (& str, 16) == FAIL)
3006 {
3007 if (!inst.error)
3008 inst.error = BAD_ARGS;
3009 return;
3010 }
3011
3012 if (skip_past_comma (& str) == FAIL
3013 || cp_reg_required_here (& str, 0) == FAIL)
3014 {
3015 if (!inst.error)
3016 inst.error = BAD_ARGS;
3017 return;
3018 }
3019
3020 if (skip_past_comma (& str) == SUCCESS)
3021 {
3022 if (cp_opc_expr (& str, 5, 3) == FAIL)
3023 {
3024 if (!inst.error)
3025 inst.error = BAD_ARGS;
3026 return;
3027 }
3028 }
3029
3030 if (flags)
3031 inst.error = BAD_COND;
3032
3033 end_of_line (str);
3034 }
3035
3036 /* THUMB V5 breakpoint instruction (argument parse)
3037 BKPT <immed_8>. */
3038
3039 static void
3040 do_t_bkpt (str)
3041 char * str;
3042 {
3043 expressionS expr;
3044 unsigned long number;
3045
3046 skip_whitespace (str);
3047
3048 /* Allow optional leading '#'. */
3049 if (is_immediate_prefix (*str))
3050 str ++;
3051
3052 memset (& expr, '\0', sizeof (expr));
3053 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
3054 {
3055 inst.error = _("bad or missing expression");
3056 return;
3057 }
3058
3059 number = expr.X_add_number;
3060
3061 /* Check it fits an 8 bit unsigned. */
3062 if (number != (number & 0xff))
3063 {
3064 inst.error = _("immediate value out of range");
3065 return;
3066 }
3067
3068 inst.instruction |= number;
3069
3070 end_of_line (str);
3071 }
3072
3073 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3074 Expects inst.instruction is set for BLX(1).
3075 Note: this is cloned from do_branch, and the reloc changed to be a
3076 new one that can cope with setting one extra bit (the H bit). */
3077
3078 static void
3079 do_branch25 (str, flags)
3080 char * str;
3081 unsigned long flags ATTRIBUTE_UNUSED;
3082 {
3083 if (my_get_expression (& inst.reloc.exp, & str))
3084 return;
3085
3086 #ifdef OBJ_ELF
3087 {
3088 char * save_in;
3089
3090 /* ScottB: February 5, 1998 */
3091 /* Check to see of PLT32 reloc required for the instruction. */
3092
3093 /* arm_parse_reloc() works on input_line_pointer.
3094 We actually want to parse the operands to the branch instruction
3095 passed in 'str'. Save the input pointer and restore it later. */
3096 save_in = input_line_pointer;
3097 input_line_pointer = str;
3098
3099 if (inst.reloc.exp.X_op == O_symbol
3100 && *str == '('
3101 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3102 {
3103 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3104 inst.reloc.pc_rel = 0;
3105 /* Modify str to point to after parsed operands, otherwise
3106 end_of_line() will complain about the (PLT) left in str. */
3107 str = input_line_pointer;
3108 }
3109 else
3110 {
3111 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
3112 inst.reloc.pc_rel = 1;
3113 }
3114
3115 input_line_pointer = save_in;
3116 }
3117 #else
3118 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
3119 inst.reloc.pc_rel = 1;
3120 #endif /* OBJ_ELF */
3121
3122 end_of_line (str);
3123 }
3124
3125 /* ARM V5 branch-link-exchange instruction (argument parse)
3126 BLX <target_addr> ie BLX(1)
3127 BLX{<condition>} <Rm> ie BLX(2)
3128 Unfortunately, there are two different opcodes for this mnemonic.
3129 So, the insns[].value is not used, and the code here zaps values
3130 into inst.instruction.
3131 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
3132
3133 static void
3134 do_blx (str, flags)
3135 char * str;
3136 unsigned long flags;
3137 {
3138 char * mystr = str;
3139 int rm;
3140
3141 if (flags)
3142 {
3143 as_bad (BAD_FLAGS);
3144 return;
3145 }
3146
3147 skip_whitespace (mystr);
3148 rm = reg_required_here (& mystr, 0);
3149
3150 /* The above may set inst.error. Ignore his opinion. */
3151 inst.error = 0;
3152
3153 if (rm != FAIL)
3154 {
3155 /* Arg is a register.
3156 Use the condition code our caller put in inst.instruction.
3157 Pass ourselves off as a BX with a funny opcode. */
3158 inst.instruction |= 0x012fff30;
3159 do_bx (str, flags);
3160 }
3161 else
3162 {
3163 /* This must be is BLX <target address>, no condition allowed. */
3164 if (inst.instruction != COND_ALWAYS)
3165 {
3166 inst.error = BAD_COND;
3167 return;
3168 }
3169
3170 inst.instruction = 0xfafffffe;
3171
3172 /* Process like a B/BL, but with a different reloc.
3173 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
3174 do_branch25 (str, flags);
3175 }
3176 }
3177
3178 /* ARM V5 Thumb BLX (argument parse)
3179 BLX <target_addr> which is BLX(1)
3180 BLX <Rm> which is BLX(2)
3181 Unfortunately, there are two different opcodes for this mnemonic.
3182 So, the tinsns[].value is not used, and the code here zaps values
3183 into inst.instruction. */
3184
3185 static void
3186 do_t_blx (str)
3187 char * str;
3188 {
3189 char * mystr = str;
3190 int rm;
3191
3192 skip_whitespace (mystr);
3193 inst.instruction = 0x4780;
3194
3195 /* Note that this call is to the ARM register recognizer. BLX(2)
3196 uses the ARM register space, not the Thumb one, so a call to
3197 thumb_reg() would be wrong. */
3198 rm = reg_required_here (& mystr, 3);
3199 inst.error = 0;
3200
3201 if (rm != FAIL)
3202 {
3203 /* It's BLX(2). The .instruction was zapped with rm & is final. */
3204 inst.size = 2;
3205 }
3206 else
3207 {
3208 /* No ARM register. This must be BLX(1). Change the .instruction. */
3209 inst.instruction = 0xf7ffeffe;
3210 inst.size = 4;
3211
3212 if (my_get_expression (& inst.reloc.exp, & mystr))
3213 return;
3214
3215 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
3216 inst.reloc.pc_rel = 1;
3217 }
3218
3219 end_of_line (mystr);
3220 }
3221
3222 /* ARM V5 breakpoint instruction (argument parse)
3223 BKPT <16 bit unsigned immediate>
3224 Instruction is not conditional.
3225 The bit pattern given in insns[] has the COND_ALWAYS condition,
3226 and it is an error if the caller tried to override that.
3227 Note "flags" is nonzero if a flag was supplied (which is an error). */
3228
3229 static void
3230 do_bkpt (str, flags)
3231 char * str;
3232 unsigned long flags;
3233 {
3234 expressionS expr;
3235 unsigned long number;
3236
3237 skip_whitespace (str);
3238
3239 /* Allow optional leading '#'. */
3240 if (is_immediate_prefix (* str))
3241 str++;
3242
3243 memset (& expr, '\0', sizeof (expr));
3244
3245 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
3246 {
3247 inst.error = _("bad or missing expression");
3248 return;
3249 }
3250
3251 number = expr.X_add_number;
3252
3253 /* Check it fits a 16 bit unsigned. */
3254 if (number != (number & 0xffff))
3255 {
3256 inst.error = _("immediate value out of range");
3257 return;
3258 }
3259
3260 /* Top 12 of 16 bits to bits 19:8. */
3261 inst.instruction |= (number & 0xfff0) << 4;
3262
3263 /* Bottom 4 of 16 bits to bits 3:0. */
3264 inst.instruction |= number & 0xf;
3265
3266 end_of_line (str);
3267
3268 if (flags)
3269 inst.error = BAD_FLAGS;
3270 }
3271
3272 /* Xscale multiply-accumulate (argument parse)
3273 MIAcc acc0,Rm,Rs
3274 MIAPHcc acc0,Rm,Rs
3275 MIAxycc acc0,Rm,Rs. */
3276
3277 static void
3278 do_mia (str, flags)
3279 char * str;
3280 unsigned long flags;
3281 {
3282 int rs;
3283 int rm;
3284
3285 if (flags)
3286 as_bad (BAD_FLAGS);
3287
3288 else if (accum0_required_here (& str) == FAIL)
3289 inst.error = ERR_NO_ACCUM;
3290
3291 else if (skip_past_comma (& str) == FAIL
3292 || (rm = reg_required_here (& str, 0)) == FAIL)
3293 inst.error = BAD_ARGS;
3294
3295 else if (skip_past_comma (& str) == FAIL
3296 || (rs = reg_required_here (& str, 12)) == FAIL)
3297 inst.error = BAD_ARGS;
3298
3299 /* inst.instruction has now been zapped with both rm and rs. */
3300 else if (rm == REG_PC || rs == REG_PC)
3301 inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */
3302
3303 else
3304 end_of_line (str);
3305 }
3306
3307 /* Xscale move-accumulator-register (argument parse)
3308
3309 MARcc acc0,RdLo,RdHi. */
3310
3311 static void
3312 do_mar (str, flags)
3313 char * str;
3314 unsigned long flags;
3315 {
3316 int rdlo, rdhi;
3317
3318 if (flags)
3319 as_bad (BAD_FLAGS);
3320
3321 else if (accum0_required_here (& str) == FAIL)
3322 inst.error = ERR_NO_ACCUM;
3323
3324 else if (skip_past_comma (& str) == FAIL
3325 || (rdlo = reg_required_here (& str, 12)) == FAIL)
3326 inst.error = BAD_ARGS;
3327
3328 else if (skip_past_comma (& str) == FAIL
3329 || (rdhi = reg_required_here (& str, 16)) == FAIL)
3330 inst.error = BAD_ARGS;
3331
3332 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3333 else if (rdlo == REG_PC || rdhi == REG_PC)
3334 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
3335
3336 else
3337 end_of_line (str);
3338 }
3339
3340 /* Xscale move-register-accumulator (argument parse)
3341
3342 MRAcc RdLo,RdHi,acc0. */
3343
3344 static void
3345 do_mra (str, flags)
3346 char * str;
3347 unsigned long flags;
3348 {
3349 int rdlo;
3350 int rdhi;
3351
3352 if (flags)
3353 {
3354 as_bad (BAD_FLAGS);
3355 return;
3356 }
3357
3358 skip_whitespace (str);
3359
3360 if ((rdlo = reg_required_here (& str, 12)) == FAIL)
3361 inst.error = BAD_ARGS;
3362
3363 else if (skip_past_comma (& str) == FAIL
3364 || (rdhi = reg_required_here (& str, 16)) == FAIL)
3365 inst.error = BAD_ARGS;
3366
3367 else if (skip_past_comma (& str) == FAIL
3368 || accum0_required_here (& str) == FAIL)
3369 inst.error = ERR_NO_ACCUM;
3370
3371 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3372 else if (rdlo == rdhi)
3373 inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */
3374
3375 else if (rdlo == REG_PC || rdhi == REG_PC)
3376 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
3377 else
3378 end_of_line (str);
3379 }
3380
3381 /* Xscale: Preload-Cache
3382
3383 PLD <addr_mode>
3384
3385 Syntactically, like LDR with B=1, W=0, L=1. */
3386
3387 static void
3388 do_pld (str, flags)
3389 char * str;
3390 unsigned long flags;
3391 {
3392 int rd;
3393
3394 if (flags)
3395 {
3396 as_bad (BAD_FLAGS);
3397 return;
3398 }
3399
3400 skip_whitespace (str);
3401
3402 if (* str != '[')
3403 {
3404 inst.error = _("'[' expected after PLD mnemonic");
3405 return;
3406 }
3407
3408 ++ str;
3409 skip_whitespace (str);
3410
3411 if ((rd = reg_required_here (& str, 16)) == FAIL)
3412 return;
3413
3414 skip_whitespace (str);
3415
3416 if (* str == ']')
3417 {
3418 /* [Rn], ... ? */
3419 ++ str;
3420 skip_whitespace (str);
3421
3422 if (skip_past_comma (& str) == SUCCESS)
3423 {
3424 if (ldst_extend (& str, 0) == FAIL)
3425 return;
3426 }
3427 else if (* str == '!') /* [Rn]! */
3428 {
3429 inst.error = _("writeback used in preload instruction");
3430 ++ str;
3431 }
3432 else /* [Rn] */
3433 inst.instruction |= INDEX_UP | PRE_INDEX;
3434 }
3435 else /* [Rn, ...] */
3436 {
3437 if (skip_past_comma (& str) == FAIL)
3438 {
3439 inst.error = _("pre-indexed expression expected");
3440 return;
3441 }
3442
3443 if (ldst_extend (& str, 0) == FAIL)
3444 return;
3445
3446 skip_whitespace (str);
3447
3448 if (* str != ']')
3449 {
3450 inst.error = _("missing ]");
3451 return;
3452 }
3453
3454 ++ str;
3455 skip_whitespace (str);
3456
3457 if (* str == '!') /* [Rn]! */
3458 {
3459 inst.error = _("writeback used in preload instruction");
3460 ++ str;
3461 }
3462
3463 inst.instruction |= PRE_INDEX;
3464 }
3465
3466 end_of_line (str);
3467 }
3468
3469 /* Xscale load-consecutive (argument parse)
3470 Mode is like LDRH.
3471
3472 LDRccD R, mode
3473 STRccD R, mode. */
3474
3475 static void
3476 do_ldrd (str, flags)
3477 char * str;
3478 unsigned long flags;
3479 {
3480 int rd;
3481 int rn;
3482
3483 if (flags != DOUBLE_LOAD_FLAG)
3484 {
3485 /* Change instruction pattern to normal ldr/str. */
3486 if (inst.instruction & 0x20)
3487 inst.instruction = (inst.instruction & COND_MASK) | 0x04000000; /* str */
3488 else
3489 inst.instruction = (inst.instruction & COND_MASK) | 0x04100000; /* ldr */
3490
3491 /* Perform a normal load/store instruction parse. */
3492 do_ldst (str, flags);
3493
3494 return;
3495 }
3496
3497 if ((cpu_variant & ARM_EXT_XSCALE) != ARM_EXT_XSCALE)
3498 {
3499 static char buff[128];
3500
3501 --str;
3502 while (isspace (*str))
3503 --str;
3504 str -= 4;
3505
3506 /* Deny all knowledge. */
3507 sprintf (buff, _("bad instruction '%.100s'"), str);
3508 inst.error = buff;
3509 return;
3510 }
3511
3512 skip_whitespace (str);
3513
3514 if ((rd = reg_required_here (& str, 12)) == FAIL)
3515 {
3516 inst.error = BAD_ARGS;
3517 return;
3518 }
3519
3520 if (skip_past_comma (& str) == FAIL
3521 || (rn = ld_mode_required_here (& str)) == FAIL)
3522 {
3523 if (!inst.error)
3524 inst.error = BAD_ARGS;
3525 return;
3526 }
3527
3528 /* inst.instruction has now been zapped with Rd and the addressing mode. */
3529 if (rd & 1) /* Unpredictable result if Rd is odd. */
3530 {
3531 inst.error = _("Destination register must be even");
3532 return;
3533 }
3534
3535 if (rd == REG_LR || rd == 12)
3536 {
3537 inst.error = _("r12 or r14 not allowed here");
3538 return;
3539 }
3540
3541 if (((rd == rn) || (rd + 1 == rn))
3542 &&
3543 ((inst.instruction & WRITE_BACK)
3544 || (!(inst.instruction & PRE_INDEX))))
3545 as_warn (_("pre/post-indexing used when modified address register is destination"));
3546
3547 end_of_line (str);
3548 }
3549
3550 /* Returns the index into fp_values of a floating point number,
3551 or -1 if not in the table. */
3552
3553 static int
3554 my_get_float_expression (str)
3555 char ** str;
3556 {
3557 LITTLENUM_TYPE words[MAX_LITTLENUMS];
3558 char * save_in;
3559 expressionS exp;
3560 int i;
3561 int j;
3562
3563 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
3564
3565 /* Look for a raw floating point number. */
3566 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
3567 && is_end_of_line[(unsigned char) *save_in])
3568 {
3569 for (i = 0; i < NUM_FLOAT_VALS; i++)
3570 {
3571 for (j = 0; j < MAX_LITTLENUMS; j++)
3572 {
3573 if (words[j] != fp_values[i][j])
3574 break;
3575 }
3576
3577 if (j == MAX_LITTLENUMS)
3578 {
3579 *str = save_in;
3580 return i;
3581 }
3582 }
3583 }
3584
3585 /* Try and parse a more complex expression, this will probably fail
3586 unless the code uses a floating point prefix (eg "0f"). */
3587 save_in = input_line_pointer;
3588 input_line_pointer = *str;
3589 if (expression (&exp) == absolute_section
3590 && exp.X_op == O_big
3591 && exp.X_add_number < 0)
3592 {
3593 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
3594 Ditto for 15. */
3595 if (gen_to_words (words, 5, (long) 15) == 0)
3596 {
3597 for (i = 0; i < NUM_FLOAT_VALS; i++)
3598 {
3599 for (j = 0; j < MAX_LITTLENUMS; j++)
3600 {
3601 if (words[j] != fp_values[i][j])
3602 break;
3603 }
3604
3605 if (j == MAX_LITTLENUMS)
3606 {
3607 *str = input_line_pointer;
3608 input_line_pointer = save_in;
3609 return i;
3610 }
3611 }
3612 }
3613 }
3614
3615 *str = input_line_pointer;
3616 input_line_pointer = save_in;
3617 return -1;
3618 }
3619
3620 /* Return true if anything in the expression is a bignum. */
3621
3622 static int
3623 walk_no_bignums (sp)
3624 symbolS * sp;
3625 {
3626 if (symbol_get_value_expression (sp)->X_op == O_big)
3627 return 1;
3628
3629 if (symbol_get_value_expression (sp)->X_add_symbol)
3630 {
3631 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
3632 || (symbol_get_value_expression (sp)->X_op_symbol
3633 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
3634 }
3635
3636 return 0;
3637 }
3638
3639 static int
3640 my_get_expression (ep, str)
3641 expressionS * ep;
3642 char ** str;
3643 {
3644 char * save_in;
3645 segT seg;
3646
3647 save_in = input_line_pointer;
3648 input_line_pointer = *str;
3649 seg = expression (ep);
3650
3651 #ifdef OBJ_AOUT
3652 if (seg != absolute_section
3653 && seg != text_section
3654 && seg != data_section
3655 && seg != bss_section
3656 && seg != undefined_section)
3657 {
3658 inst.error = _("bad_segment");
3659 *str = input_line_pointer;
3660 input_line_pointer = save_in;
3661 return 1;
3662 }
3663 #endif
3664
3665 /* Get rid of any bignums now, so that we don't generate an error for which
3666 we can't establish a line number later on. Big numbers are never valid
3667 in instructions, which is where this routine is always called. */
3668 if (ep->X_op == O_big
3669 || (ep->X_add_symbol
3670 && (walk_no_bignums (ep->X_add_symbol)
3671 || (ep->X_op_symbol
3672 && walk_no_bignums (ep->X_op_symbol)))))
3673 {
3674 inst.error = _("Invalid constant");
3675 *str = input_line_pointer;
3676 input_line_pointer = save_in;
3677 return 1;
3678 }
3679
3680 *str = input_line_pointer;
3681 input_line_pointer = save_in;
3682 return 0;
3683 }
3684
3685 /* UNRESTRICT should be one if <shift> <register> is permitted for this
3686 instruction. */
3687
3688 static int
3689 decode_shift (str, unrestrict)
3690 char ** str;
3691 int unrestrict;
3692 {
3693 const struct asm_shift_name * shift;
3694 char * p;
3695 char c;
3696
3697 skip_whitespace (* str);
3698
3699 for (p = * str; isalpha (* p); p ++)
3700 ;
3701
3702 if (p == * str)
3703 {
3704 inst.error = _("Shift expression expected");
3705 return FAIL;
3706 }
3707
3708 c = * p;
3709 * p = '\0';
3710 shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
3711 * p = c;
3712
3713 if (shift == NULL)
3714 {
3715 inst.error = _("Shift expression expected");
3716 return FAIL;
3717 }
3718
3719 assert (shift->properties->index == shift_properties[shift->properties->index].index);
3720
3721 if (shift->properties->index == SHIFT_RRX)
3722 {
3723 * str = p;
3724 inst.instruction |= shift->properties->bit_field;
3725 return SUCCESS;
3726 }
3727
3728 skip_whitespace (p);
3729
3730 if (unrestrict && reg_required_here (& p, 8) != FAIL)
3731 {
3732 inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
3733 * str = p;
3734 return SUCCESS;
3735 }
3736 else if (! is_immediate_prefix (* p))
3737 {
3738 inst.error = (unrestrict
3739 ? _("shift requires register or #expression")
3740 : _("shift requires #expression"));
3741 * str = p;
3742 return FAIL;
3743 }
3744
3745 inst.error = NULL;
3746 p ++;
3747
3748 if (my_get_expression (& inst.reloc.exp, & p))
3749 return FAIL;
3750
3751 /* Validate some simple #expressions. */
3752 if (inst.reloc.exp.X_op == O_constant)
3753 {
3754 unsigned num = inst.reloc.exp.X_add_number;
3755
3756 /* Reject operations greater than 32. */
3757 if (num > 32
3758 /* Reject a shift of 0 unless the mode allows it. */
3759 || (num == 0 && shift->properties->allows_0 == 0)
3760 /* Reject a shift of 32 unless the mode allows it. */
3761 || (num == 32 && shift->properties->allows_32 == 0)
3762 )
3763 {
3764 /* As a special case we allow a shift of zero for
3765 modes that do not support it to be recoded as an
3766 logical shift left of zero (ie nothing). We warn
3767 about this though. */
3768 if (num == 0)
3769 {
3770 as_warn (_("Shift of 0 ignored."));
3771 shift = & shift_names[0];
3772 assert (shift->properties->index == SHIFT_LSL);
3773 }
3774 else
3775 {
3776 inst.error = _("Invalid immediate shift");
3777 return FAIL;
3778 }
3779 }
3780
3781 /* Shifts of 32 are encoded as 0, for those shifts that
3782 support it. */
3783 if (num == 32)
3784 num = 0;
3785
3786 inst.instruction |= (num << 7) | shift->properties->bit_field;
3787 }
3788 else
3789 {
3790 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
3791 inst.reloc.pc_rel = 0;
3792 inst.instruction |= shift->properties->bit_field;
3793 }
3794
3795 * str = p;
3796 return SUCCESS;
3797 }
3798
3799 /* Do those data_ops which can take a negative immediate constant
3800 by altering the instuction. A bit of a hack really.
3801 MOV <-> MVN
3802 AND <-> BIC
3803 ADC <-> SBC
3804 by inverting the second operand, and
3805 ADD <-> SUB
3806 CMP <-> CMN
3807 by negating the second operand. */
3808
3809 static int
3810 negate_data_op (instruction, value)
3811 unsigned long * instruction;
3812 unsigned long value;
3813 {
3814 int op, new_inst;
3815 unsigned long negated, inverted;
3816
3817 negated = validate_immediate (-value);
3818 inverted = validate_immediate (~value);
3819
3820 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
3821 switch (op)
3822 {
3823 /* First negates. */
3824 case OPCODE_SUB: /* ADD <-> SUB */
3825 new_inst = OPCODE_ADD;
3826 value = negated;
3827 break;
3828
3829 case OPCODE_ADD:
3830 new_inst = OPCODE_SUB;
3831 value = negated;
3832 break;
3833
3834 case OPCODE_CMP: /* CMP <-> CMN */
3835 new_inst = OPCODE_CMN;
3836 value = negated;
3837 break;
3838
3839 case OPCODE_CMN:
3840 new_inst = OPCODE_CMP;
3841 value = negated;
3842 break;
3843
3844 /* Now Inverted ops. */
3845 case OPCODE_MOV: /* MOV <-> MVN */
3846 new_inst = OPCODE_MVN;
3847 value = inverted;
3848 break;
3849
3850 case OPCODE_MVN:
3851 new_inst = OPCODE_MOV;
3852 value = inverted;
3853 break;
3854
3855 case OPCODE_AND: /* AND <-> BIC */
3856 new_inst = OPCODE_BIC;
3857 value = inverted;
3858 break;
3859
3860 case OPCODE_BIC:
3861 new_inst = OPCODE_AND;
3862 value = inverted;
3863 break;
3864
3865 case OPCODE_ADC: /* ADC <-> SBC */
3866 new_inst = OPCODE_SBC;
3867 value = inverted;
3868 break;
3869
3870 case OPCODE_SBC:
3871 new_inst = OPCODE_ADC;
3872 value = inverted;
3873 break;
3874
3875 /* We cannot do anything. */
3876 default:
3877 return FAIL;
3878 }
3879
3880 if (value == (unsigned) FAIL)
3881 return FAIL;
3882
3883 *instruction &= OPCODE_MASK;
3884 *instruction |= new_inst << DATA_OP_SHIFT;
3885 return value;
3886 }
3887
3888 static int
3889 data_op2 (str)
3890 char ** str;
3891 {
3892 int value;
3893 expressionS expr;
3894
3895 skip_whitespace (* str);
3896
3897 if (reg_required_here (str, 0) != FAIL)
3898 {
3899 if (skip_past_comma (str) == SUCCESS)
3900 /* Shift operation on register. */
3901 return decode_shift (str, NO_SHIFT_RESTRICT);
3902
3903 return SUCCESS;
3904 }
3905 else
3906 {
3907 /* Immediate expression. */
3908 if (is_immediate_prefix (**str))
3909 {
3910 (*str)++;
3911 inst.error = NULL;
3912
3913 if (my_get_expression (&inst.reloc.exp, str))
3914 return FAIL;
3915
3916 if (inst.reloc.exp.X_add_symbol)
3917 {
3918 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
3919 inst.reloc.pc_rel = 0;
3920 }
3921 else
3922 {
3923 if (skip_past_comma (str) == SUCCESS)
3924 {
3925 /* #x, y -- ie explicit rotation by Y. */
3926 if (my_get_expression (&expr, str))
3927 return FAIL;
3928
3929 if (expr.X_op != O_constant)
3930 {
3931 inst.error = _("Constant expression expected");
3932 return FAIL;
3933 }
3934
3935 /* Rotate must be a multiple of 2. */
3936 if (((unsigned) expr.X_add_number) > 30
3937 || (expr.X_add_number & 1) != 0
3938 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
3939 {
3940 inst.error = _("Invalid constant");
3941 return FAIL;
3942 }
3943 inst.instruction |= INST_IMMEDIATE;
3944 inst.instruction |= inst.reloc.exp.X_add_number;
3945 inst.instruction |= expr.X_add_number << 7;
3946 return SUCCESS;
3947 }
3948
3949 /* Implicit rotation, select a suitable one. */
3950 value = validate_immediate (inst.reloc.exp.X_add_number);
3951
3952 if (value == FAIL)
3953 {
3954 /* Can't be done. Perhaps the code reads something like
3955 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
3956 if ((value = negate_data_op (&inst.instruction,
3957 inst.reloc.exp.X_add_number))
3958 == FAIL)
3959 {
3960 inst.error = _("Invalid constant");
3961 return FAIL;
3962 }
3963 }
3964
3965 inst.instruction |= value;
3966 }
3967
3968 inst.instruction |= INST_IMMEDIATE;
3969 return SUCCESS;
3970 }
3971
3972 (*str)++;
3973 inst.error = _("Register or shift expression expected");
3974 return FAIL;
3975 }
3976 }
3977
3978 static int
3979 fp_op2 (str)
3980 char ** str;
3981 {
3982 skip_whitespace (* str);
3983
3984 if (fp_reg_required_here (str, 0) != FAIL)
3985 return SUCCESS;
3986 else
3987 {
3988 /* Immediate expression. */
3989 if (*((*str)++) == '#')
3990 {
3991 int i;
3992
3993 inst.error = NULL;
3994
3995 skip_whitespace (* str);
3996
3997 /* First try and match exact strings, this is to guarantee
3998 that some formats will work even for cross assembly. */
3999
4000 for (i = 0; fp_const[i]; i++)
4001 {
4002 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
4003 {
4004 char *start = *str;
4005
4006 *str += strlen (fp_const[i]);
4007 if (is_end_of_line[(unsigned char) **str])
4008 {
4009 inst.instruction |= i + 8;
4010 return SUCCESS;
4011 }
4012 *str = start;
4013 }
4014 }
4015
4016 /* Just because we didn't get a match doesn't mean that the
4017 constant isn't valid, just that it is in a format that we
4018 don't automatically recognize. Try parsing it with
4019 the standard expression routines. */
4020 if ((i = my_get_float_expression (str)) >= 0)
4021 {
4022 inst.instruction |= i + 8;
4023 return SUCCESS;
4024 }
4025
4026 inst.error = _("Invalid floating point immediate expression");
4027 return FAIL;
4028 }
4029 inst.error =
4030 _("Floating point register or immediate expression expected");
4031 return FAIL;
4032 }
4033 }
4034
4035 static void
4036 do_arit (str, flags)
4037 char * str;
4038 unsigned long flags;
4039 {
4040 skip_whitespace (str);
4041
4042 if (reg_required_here (&str, 12) == FAIL
4043 || skip_past_comma (&str) == FAIL
4044 || reg_required_here (&str, 16) == FAIL
4045 || skip_past_comma (&str) == FAIL
4046 || data_op2 (&str) == FAIL)
4047 {
4048 if (!inst.error)
4049 inst.error = BAD_ARGS;
4050 return;
4051 }
4052
4053 inst.instruction |= flags;
4054 end_of_line (str);
4055 return;
4056 }
4057
4058 static void
4059 do_adr (str, flags)
4060 char * str;
4061 unsigned long flags;
4062 {
4063 /* This is a pseudo-op of the form "adr rd, label" to be converted
4064 into a relative address of the form "add rd, pc, #label-.-8". */
4065 skip_whitespace (str);
4066
4067 if (reg_required_here (&str, 12) == FAIL
4068 || skip_past_comma (&str) == FAIL
4069 || my_get_expression (&inst.reloc.exp, &str))
4070 {
4071 if (!inst.error)
4072 inst.error = BAD_ARGS;
4073 return;
4074 }
4075
4076 /* Frag hacking will turn this into a sub instruction if the offset turns
4077 out to be negative. */
4078 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4079 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
4080 inst.reloc.pc_rel = 1;
4081 inst.instruction |= flags;
4082
4083 end_of_line (str);
4084 }
4085
4086 static void
4087 do_adrl (str, flags)
4088 char * str;
4089 unsigned long flags;
4090 {
4091 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4092 into a relative address of the form:
4093 add rd, pc, #low(label-.-8)"
4094 add rd, rd, #high(label-.-8)" */
4095
4096 skip_whitespace (str);
4097
4098 if (reg_required_here (& str, 12) == FAIL
4099 || skip_past_comma (& str) == FAIL
4100 || my_get_expression (& inst.reloc.exp, & str))
4101 {
4102 if (!inst.error)
4103 inst.error = BAD_ARGS;
4104 return;
4105 }
4106
4107 end_of_line (str);
4108
4109 /* Frag hacking will turn this into a sub instruction if the offset turns
4110 out to be negative. */
4111 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
4112 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
4113 inst.reloc.pc_rel = 1;
4114 inst.instruction |= flags;
4115 inst.size = INSN_SIZE * 2;
4116
4117 return;
4118 }
4119
4120 static void
4121 do_cmp (str, flags)
4122 char * str;
4123 unsigned long flags;
4124 {
4125 skip_whitespace (str);
4126
4127 if (reg_required_here (&str, 16) == FAIL)
4128 {
4129 if (!inst.error)
4130 inst.error = BAD_ARGS;
4131 return;
4132 }
4133
4134 if (skip_past_comma (&str) == FAIL
4135 || data_op2 (&str) == FAIL)
4136 {
4137 if (!inst.error)
4138 inst.error = BAD_ARGS;
4139 return;
4140 }
4141
4142 inst.instruction |= flags;
4143 if ((flags & 0x0000f000) == 0)
4144 inst.instruction |= CONDS_BIT;
4145
4146 end_of_line (str);
4147 return;
4148 }
4149
4150 static void
4151 do_mov (str, flags)
4152 char * str;
4153 unsigned long flags;
4154 {
4155 skip_whitespace (str);
4156
4157 if (reg_required_here (&str, 12) == FAIL)
4158 {
4159 if (!inst.error)
4160 inst.error = BAD_ARGS;
4161 return;
4162 }
4163
4164 if (skip_past_comma (&str) == FAIL
4165 || data_op2 (&str) == FAIL)
4166 {
4167 if (!inst.error)
4168 inst.error = BAD_ARGS;
4169 return;
4170 }
4171
4172 inst.instruction |= flags;
4173 end_of_line (str);
4174 return;
4175 }
4176
4177 static int
4178 ldst_extend (str, hwse)
4179 char ** str;
4180 int hwse;
4181 {
4182 int add = INDEX_UP;
4183
4184 switch (**str)
4185 {
4186 case '#':
4187 case '$':
4188 (*str)++;
4189 if (my_get_expression (& inst.reloc.exp, str))
4190 return FAIL;
4191
4192 if (inst.reloc.exp.X_op == O_constant)
4193 {
4194 int value = inst.reloc.exp.X_add_number;
4195
4196 if ((hwse && (value < -255 || value > 255))
4197 || (value < -4095 || value > 4095))
4198 {
4199 inst.error = _("address offset too large");
4200 return FAIL;
4201 }
4202
4203 if (value < 0)
4204 {
4205 value = -value;
4206 add = 0;
4207 }
4208
4209 /* Halfword and signextension instructions have the
4210 immediate value split across bits 11..8 and bits 3..0. */
4211 if (hwse)
4212 inst.instruction |= (add | HWOFFSET_IMM
4213 | ((value >> 4) << 8) | (value & 0xF));
4214 else
4215 inst.instruction |= add | value;
4216 }
4217 else
4218 {
4219 if (hwse)
4220 {
4221 inst.instruction |= HWOFFSET_IMM;
4222 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
4223 }
4224 else
4225 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
4226 inst.reloc.pc_rel = 0;
4227 }
4228 return SUCCESS;
4229
4230 case '-':
4231 add = 0;
4232 /* Fall through. */
4233
4234 case '+':
4235 (*str)++;
4236 /* Fall through. */
4237
4238 default:
4239 if (reg_required_here (str, 0) == FAIL)
4240 return FAIL;
4241
4242 if (hwse)
4243 inst.instruction |= add;
4244 else
4245 {
4246 inst.instruction |= add | OFFSET_REG;
4247 if (skip_past_comma (str) == SUCCESS)
4248 return decode_shift (str, SHIFT_RESTRICT);
4249 }
4250
4251 return SUCCESS;
4252 }
4253 }
4254
4255 static void
4256 do_ldst (str, flags)
4257 char * str;
4258 unsigned long flags;
4259 {
4260 int halfword = 0;
4261 int pre_inc = 0;
4262 int conflict_reg;
4263 int value;
4264
4265 /* This is not ideal, but it is the simplest way of dealing with the
4266 ARM7T halfword instructions (since they use a different
4267 encoding, but the same mnemonic): */
4268 halfword = (flags & 0x80000000) != 0;
4269 if (halfword)
4270 {
4271 /* This is actually a load/store of a halfword, or a
4272 signed-extension load. */
4273 if ((cpu_variant & ARM_EXT_HALFWORD) == 0)
4274 {
4275 inst.error
4276 = _("Processor does not support halfwords or signed bytes");
4277 return;
4278 }
4279
4280 inst.instruction = ((inst.instruction & COND_MASK)
4281 | (flags & ~COND_MASK));
4282
4283 flags = 0;
4284 }
4285
4286 skip_whitespace (str);
4287
4288 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
4289 {
4290 if (!inst.error)
4291 inst.error = BAD_ARGS;
4292 return;
4293 }
4294
4295 if (skip_past_comma (& str) == FAIL)
4296 {
4297 inst.error = _("Address expected");
4298 return;
4299 }
4300
4301 if (*str == '[')
4302 {
4303 int reg;
4304
4305 str++;
4306
4307 skip_whitespace (str);
4308
4309 if ((reg = reg_required_here (&str, 16)) == FAIL)
4310 return;
4311
4312 /* Conflicts can occur on stores as well as loads. */
4313 conflict_reg = (conflict_reg == reg);
4314
4315 skip_whitespace (str);
4316
4317 if (*str == ']')
4318 {
4319 str ++;
4320
4321 if (skip_past_comma (&str) == SUCCESS)
4322 {
4323 /* [Rn],... (post inc) */
4324 if (ldst_extend (&str, halfword) == FAIL)
4325 return;
4326 if (conflict_reg)
4327 as_warn (_("%s register same as write-back base"),
4328 ((inst.instruction & LOAD_BIT)
4329 ? _("destination") : _("source")));
4330 }
4331 else
4332 {
4333 /* [Rn] */
4334 if (halfword)
4335 inst.instruction |= HWOFFSET_IMM;
4336
4337 skip_whitespace (str);
4338
4339 if (*str == '!')
4340 {
4341 if (conflict_reg)
4342 as_warn (_("%s register same as write-back base"),
4343 ((inst.instruction & LOAD_BIT)
4344 ? _("destination") : _("source")));
4345 str++;
4346 inst.instruction |= WRITE_BACK;
4347 }
4348
4349 flags |= INDEX_UP;
4350 if (! (flags & TRANS_BIT))
4351 pre_inc = 1;
4352 }
4353 }
4354 else
4355 {
4356 /* [Rn,...] */
4357 if (skip_past_comma (&str) == FAIL)
4358 {
4359 inst.error = _("pre-indexed expression expected");
4360 return;
4361 }
4362
4363 pre_inc = 1;
4364 if (ldst_extend (&str, halfword) == FAIL)
4365 return;
4366
4367 skip_whitespace (str);
4368
4369 if (*str++ != ']')
4370 {
4371 inst.error = _("missing ]");
4372 return;
4373 }
4374
4375 skip_whitespace (str);
4376
4377 if (*str == '!')
4378 {
4379 if (conflict_reg)
4380 as_warn (_("%s register same as write-back base"),
4381 ((inst.instruction & LOAD_BIT)
4382 ? _("destination") : _("source")));
4383 str++;
4384 inst.instruction |= WRITE_BACK;
4385 }
4386 }
4387 }
4388 else if (*str == '=')
4389 {
4390 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4391 str++;
4392
4393 skip_whitespace (str);
4394
4395 if (my_get_expression (&inst.reloc.exp, &str))
4396 return;
4397
4398 if (inst.reloc.exp.X_op != O_constant
4399 && inst.reloc.exp.X_op != O_symbol)
4400 {
4401 inst.error = _("Constant expression expected");
4402 return;
4403 }
4404
4405 if (inst.reloc.exp.X_op == O_constant
4406 && (value = validate_immediate (inst.reloc.exp.X_add_number)) != FAIL)
4407 {
4408 /* This can be done with a mov instruction. */
4409 inst.instruction &= LITERAL_MASK;
4410 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
4411 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
4412 end_of_line (str);
4413 return;
4414 }
4415 else
4416 {
4417 /* Insert into literal pool. */
4418 if (add_to_lit_pool () == FAIL)
4419 {
4420 if (!inst.error)
4421 inst.error = _("literal pool insertion failed");
4422 return;
4423 }
4424
4425 /* Change the instruction exp to point to the pool. */
4426 if (halfword)
4427 {
4428 inst.instruction |= HWOFFSET_IMM;
4429 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
4430 }
4431 else
4432 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
4433 inst.reloc.pc_rel = 1;
4434 inst.instruction |= (REG_PC << 16);
4435 pre_inc = 1;
4436 }
4437 }
4438 else
4439 {
4440 if (my_get_expression (&inst.reloc.exp, &str))
4441 return;
4442
4443 if (halfword)
4444 {
4445 inst.instruction |= HWOFFSET_IMM;
4446 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
4447 }
4448 else
4449 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
4450 #ifndef TE_WINCE
4451 /* PC rel adjust. */
4452 inst.reloc.exp.X_add_number -= 8;
4453 #endif
4454 inst.reloc.pc_rel = 1;
4455 inst.instruction |= (REG_PC << 16);
4456 pre_inc = 1;
4457 }
4458
4459 if (pre_inc && (flags & TRANS_BIT))
4460 inst.error = _("Pre-increment instruction with translate");
4461
4462 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
4463 end_of_line (str);
4464 return;
4465 }
4466
4467 static long
4468 reg_list (strp)
4469 char ** strp;
4470 {
4471 char * str = * strp;
4472 long range = 0;
4473 int another_range;
4474
4475 /* We come back here if we get ranges concatenated by '+' or '|'. */
4476 do
4477 {
4478 another_range = 0;
4479
4480 if (*str == '{')
4481 {
4482 int in_range = 0;
4483 int cur_reg = -1;
4484
4485 str++;
4486 do
4487 {
4488 int reg;
4489
4490 skip_whitespace (str);
4491
4492 if ((reg = reg_required_here (& str, -1)) == FAIL)
4493 return FAIL;
4494
4495 if (in_range)
4496 {
4497 int i;
4498
4499 if (reg <= cur_reg)
4500 {
4501 inst.error = _("Bad range in register list");
4502 return FAIL;
4503 }
4504
4505 for (i = cur_reg + 1; i < reg; i++)
4506 {
4507 if (range & (1 << i))
4508 as_tsktsk
4509 (_("Warning: Duplicated register (r%d) in register list"),
4510 i);
4511 else
4512 range |= 1 << i;
4513 }
4514 in_range = 0;
4515 }
4516
4517 if (range & (1 << reg))
4518 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
4519 reg);
4520 else if (reg <= cur_reg)
4521 as_tsktsk (_("Warning: Register range not in ascending order"));
4522
4523 range |= 1 << reg;
4524 cur_reg = reg;
4525 }
4526 while (skip_past_comma (&str) != FAIL
4527 || (in_range = 1, *str++ == '-'));
4528 str--;
4529 skip_whitespace (str);
4530
4531 if (*str++ != '}')
4532 {
4533 inst.error = _("Missing `}'");
4534 return FAIL;
4535 }
4536 }
4537 else
4538 {
4539 expressionS expr;
4540
4541 if (my_get_expression (&expr, &str))
4542 return FAIL;
4543
4544 if (expr.X_op == O_constant)
4545 {
4546 if (expr.X_add_number
4547 != (expr.X_add_number & 0x0000ffff))
4548 {
4549 inst.error = _("invalid register mask");
4550 return FAIL;
4551 }
4552
4553 if ((range & expr.X_add_number) != 0)
4554 {
4555 int regno = range & expr.X_add_number;
4556
4557 regno &= -regno;
4558 regno = (1 << regno) - 1;
4559 as_tsktsk
4560 (_("Warning: Duplicated register (r%d) in register list"),
4561 regno);
4562 }
4563
4564 range |= expr.X_add_number;
4565 }
4566 else
4567 {
4568 if (inst.reloc.type != 0)
4569 {
4570 inst.error = _("expression too complex");
4571 return FAIL;
4572 }
4573
4574 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
4575 inst.reloc.type = BFD_RELOC_ARM_MULTI;
4576 inst.reloc.pc_rel = 0;
4577 }
4578 }
4579
4580 skip_whitespace (str);
4581
4582 if (*str == '|' || *str == '+')
4583 {
4584 str++;
4585 another_range = 1;
4586 }
4587 }
4588 while (another_range);
4589
4590 *strp = str;
4591 return range;
4592 }
4593
4594 static void
4595 do_ldmstm (str, flags)
4596 char * str;
4597 unsigned long flags;
4598 {
4599 int base_reg;
4600 long range;
4601
4602 skip_whitespace (str);
4603
4604 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
4605 return;
4606
4607 if (base_reg == REG_PC)
4608 {
4609 inst.error = _("r15 not allowed as base register");
4610 return;
4611 }
4612
4613 skip_whitespace (str);
4614
4615 if (*str == '!')
4616 {
4617 flags |= WRITE_BACK;
4618 str++;
4619 }
4620
4621 if (skip_past_comma (&str) == FAIL
4622 || (range = reg_list (&str)) == FAIL)
4623 {
4624 if (! inst.error)
4625 inst.error = BAD_ARGS;
4626 return;
4627 }
4628
4629 if (*str == '^')
4630 {
4631 str++;
4632 flags |= LDM_TYPE_2_OR_3;
4633 }
4634
4635 inst.instruction |= flags | range;
4636 end_of_line (str);
4637 return;
4638 }
4639
4640 static void
4641 do_swi (str, flags)
4642 char * str;
4643 unsigned long flags;
4644 {
4645 skip_whitespace (str);
4646
4647 /* Allow optional leading '#'. */
4648 if (is_immediate_prefix (*str))
4649 str++;
4650
4651 if (my_get_expression (& inst.reloc.exp, & str))
4652 return;
4653
4654 inst.reloc.type = BFD_RELOC_ARM_SWI;
4655 inst.reloc.pc_rel = 0;
4656 inst.instruction |= flags;
4657
4658 end_of_line (str);
4659
4660 return;
4661 }
4662
4663 static void
4664 do_swap (str, flags)
4665 char * str;
4666 unsigned long flags;
4667 {
4668 int reg;
4669
4670 skip_whitespace (str);
4671
4672 if ((reg = reg_required_here (&str, 12)) == FAIL)
4673 return;
4674
4675 if (reg == REG_PC)
4676 {
4677 inst.error = _("r15 not allowed in swap");
4678 return;
4679 }
4680
4681 if (skip_past_comma (&str) == FAIL
4682 || (reg = reg_required_here (&str, 0)) == FAIL)
4683 {
4684 if (!inst.error)
4685 inst.error = BAD_ARGS;
4686 return;
4687 }
4688
4689 if (reg == REG_PC)
4690 {
4691 inst.error = _("r15 not allowed in swap");
4692 return;
4693 }
4694
4695 if (skip_past_comma (&str) == FAIL
4696 || *str++ != '[')
4697 {
4698 inst.error = BAD_ARGS;
4699 return;
4700 }
4701
4702 skip_whitespace (str);
4703
4704 if ((reg = reg_required_here (&str, 16)) == FAIL)
4705 return;
4706
4707 if (reg == REG_PC)
4708 {
4709 inst.error = BAD_PC;
4710 return;
4711 }
4712
4713 skip_whitespace (str);
4714
4715 if (*str++ != ']')
4716 {
4717 inst.error = _("missing ]");
4718 return;
4719 }
4720
4721 inst.instruction |= flags;
4722 end_of_line (str);
4723 return;
4724 }
4725
4726 static void
4727 do_branch (str, flags)
4728 char * str;
4729 unsigned long flags ATTRIBUTE_UNUSED;
4730 {
4731 if (my_get_expression (&inst.reloc.exp, &str))
4732 return;
4733
4734 #ifdef OBJ_ELF
4735 {
4736 char * save_in;
4737
4738 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
4739 required for the instruction. */
4740
4741 /* arm_parse_reloc () works on input_line_pointer.
4742 We actually want to parse the operands to the branch instruction
4743 passed in 'str'. Save the input pointer and restore it later. */
4744 save_in = input_line_pointer;
4745 input_line_pointer = str;
4746 if (inst.reloc.exp.X_op == O_symbol
4747 && *str == '('
4748 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4749 {
4750 inst.reloc.type = BFD_RELOC_ARM_PLT32;
4751 inst.reloc.pc_rel = 0;
4752 /* Modify str to point to after parsed operands, otherwise
4753 end_of_line() will complain about the (PLT) left in str. */
4754 str = input_line_pointer;
4755 }
4756 else
4757 {
4758 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
4759 inst.reloc.pc_rel = 1;
4760 }
4761 input_line_pointer = save_in;
4762 }
4763 #else
4764 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
4765 inst.reloc.pc_rel = 1;
4766 #endif /* OBJ_ELF */
4767
4768 end_of_line (str);
4769 return;
4770 }
4771
4772 static void
4773 do_bx (str, flags)
4774 char * str;
4775 unsigned long flags ATTRIBUTE_UNUSED;
4776 {
4777 int reg;
4778
4779 skip_whitespace (str);
4780
4781 if ((reg = reg_required_here (&str, 0)) == FAIL)
4782 {
4783 inst.error = BAD_ARGS;
4784 return;
4785 }
4786
4787 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
4788 if (reg == REG_PC)
4789 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
4790
4791 end_of_line (str);
4792 }
4793
4794 static void
4795 do_cdp (str, flags)
4796 char * str;
4797 unsigned long flags ATTRIBUTE_UNUSED;
4798 {
4799 /* Co-processor data operation.
4800 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
4801 skip_whitespace (str);
4802
4803 if (co_proc_number (&str) == FAIL)
4804 {
4805 if (!inst.error)
4806 inst.error = BAD_ARGS;
4807 return;
4808 }
4809
4810 if (skip_past_comma (&str) == FAIL
4811 || cp_opc_expr (&str, 20,4) == FAIL)
4812 {
4813 if (!inst.error)
4814 inst.error = BAD_ARGS;
4815 return;
4816 }
4817
4818 if (skip_past_comma (&str) == FAIL
4819 || cp_reg_required_here (&str, 12) == FAIL)
4820 {
4821 if (!inst.error)
4822 inst.error = BAD_ARGS;
4823 return;
4824 }
4825
4826 if (skip_past_comma (&str) == FAIL
4827 || cp_reg_required_here (&str, 16) == FAIL)
4828 {
4829 if (!inst.error)
4830 inst.error = BAD_ARGS;
4831 return;
4832 }
4833
4834 if (skip_past_comma (&str) == FAIL
4835 || cp_reg_required_here (&str, 0) == FAIL)
4836 {
4837 if (!inst.error)
4838 inst.error = BAD_ARGS;
4839 return;
4840 }
4841
4842 if (skip_past_comma (&str) == SUCCESS)
4843 {
4844 if (cp_opc_expr (&str, 5, 3) == FAIL)
4845 {
4846 if (!inst.error)
4847 inst.error = BAD_ARGS;
4848 return;
4849 }
4850 }
4851
4852 end_of_line (str);
4853 return;
4854 }
4855
4856 static void
4857 do_lstc (str, flags)
4858 char * str;
4859 unsigned long flags;
4860 {
4861 /* Co-processor register load/store.
4862 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
4863
4864 skip_whitespace (str);
4865
4866 if (co_proc_number (&str) == FAIL)
4867 {
4868 if (!inst.error)
4869 inst.error = BAD_ARGS;
4870 return;
4871 }
4872
4873 if (skip_past_comma (&str) == FAIL
4874 || cp_reg_required_here (&str, 12) == FAIL)
4875 {
4876 if (!inst.error)
4877 inst.error = BAD_ARGS;
4878 return;
4879 }
4880
4881 if (skip_past_comma (&str) == FAIL
4882 || cp_address_required_here (&str) == FAIL)
4883 {
4884 if (! inst.error)
4885 inst.error = BAD_ARGS;
4886 return;
4887 }
4888
4889 inst.instruction |= flags;
4890 end_of_line (str);
4891 return;
4892 }
4893
4894 static void
4895 do_co_reg (str, flags)
4896 char * str;
4897 unsigned long flags;
4898 {
4899 /* Co-processor register transfer.
4900 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
4901
4902 skip_whitespace (str);
4903
4904 if (co_proc_number (&str) == FAIL)
4905 {
4906 if (!inst.error)
4907 inst.error = BAD_ARGS;
4908 return;
4909 }
4910
4911 if (skip_past_comma (&str) == FAIL
4912 || cp_opc_expr (&str, 21, 3) == FAIL)
4913 {
4914 if (!inst.error)
4915 inst.error = BAD_ARGS;
4916 return;
4917 }
4918
4919 if (skip_past_comma (&str) == FAIL
4920 || reg_required_here (&str, 12) == FAIL)
4921 {
4922 if (!inst.error)
4923 inst.error = BAD_ARGS;
4924 return;
4925 }
4926
4927 if (skip_past_comma (&str) == FAIL
4928 || cp_reg_required_here (&str, 16) == FAIL)
4929 {
4930 if (!inst.error)
4931 inst.error = BAD_ARGS;
4932 return;
4933 }
4934
4935 if (skip_past_comma (&str) == FAIL
4936 || cp_reg_required_here (&str, 0) == FAIL)
4937 {
4938 if (!inst.error)
4939 inst.error = BAD_ARGS;
4940 return;
4941 }
4942
4943 if (skip_past_comma (&str) == SUCCESS)
4944 {
4945 if (cp_opc_expr (&str, 5, 3) == FAIL)
4946 {
4947 if (!inst.error)
4948 inst.error = BAD_ARGS;
4949 return;
4950 }
4951 }
4952 if (flags)
4953 {
4954 inst.error = BAD_COND;
4955 }
4956
4957 end_of_line (str);
4958 return;
4959 }
4960
4961 static void
4962 do_fp_ctrl (str, flags)
4963 char * str;
4964 unsigned long flags ATTRIBUTE_UNUSED;
4965 {
4966 /* FP control registers.
4967 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
4968
4969 skip_whitespace (str);
4970
4971 if (reg_required_here (&str, 12) == FAIL)
4972 {
4973 if (!inst.error)
4974 inst.error = BAD_ARGS;
4975 return;
4976 }
4977
4978 end_of_line (str);
4979 return;
4980 }
4981
4982 static void
4983 do_fp_ldst (str, flags)
4984 char * str;
4985 unsigned long flags ATTRIBUTE_UNUSED;
4986 {
4987 skip_whitespace (str);
4988
4989 switch (inst.suffix)
4990 {
4991 case SUFF_S:
4992 break;
4993 case SUFF_D:
4994 inst.instruction |= CP_T_X;
4995 break;
4996 case SUFF_E:
4997 inst.instruction |= CP_T_Y;
4998 break;
4999 case SUFF_P:
5000 inst.instruction |= CP_T_X | CP_T_Y;
5001 break;
5002 default:
5003 abort ();
5004 }
5005
5006 if (fp_reg_required_here (&str, 12) == FAIL)
5007 {
5008 if (!inst.error)
5009 inst.error = BAD_ARGS;
5010 return;
5011 }
5012
5013 if (skip_past_comma (&str) == FAIL
5014 || cp_address_required_here (&str) == FAIL)
5015 {
5016 if (!inst.error)
5017 inst.error = BAD_ARGS;
5018 return;
5019 }
5020
5021 end_of_line (str);
5022 }
5023
5024 static void
5025 do_fp_ldmstm (str, flags)
5026 char * str;
5027 unsigned long flags;
5028 {
5029 int num_regs;
5030
5031 skip_whitespace (str);
5032
5033 if (fp_reg_required_here (&str, 12) == FAIL)
5034 {
5035 if (! inst.error)
5036 inst.error = BAD_ARGS;
5037 return;
5038 }
5039
5040 /* Get Number of registers to transfer. */
5041 if (skip_past_comma (&str) == FAIL
5042 || my_get_expression (&inst.reloc.exp, &str))
5043 {
5044 if (! inst.error)
5045 inst.error = _("constant expression expected");
5046 return;
5047 }
5048
5049 if (inst.reloc.exp.X_op != O_constant)
5050 {
5051 inst.error = _("Constant value required for number of registers");
5052 return;
5053 }
5054
5055 num_regs = inst.reloc.exp.X_add_number;
5056
5057 if (num_regs < 1 || num_regs > 4)
5058 {
5059 inst.error = _("number of registers must be in the range [1:4]");
5060 return;
5061 }
5062
5063 switch (num_regs)
5064 {
5065 case 1:
5066 inst.instruction |= CP_T_X;
5067 break;
5068 case 2:
5069 inst.instruction |= CP_T_Y;
5070 break;
5071 case 3:
5072 inst.instruction |= CP_T_Y | CP_T_X;
5073 break;
5074 case 4:
5075 break;
5076 default:
5077 abort ();
5078 }
5079
5080 if (flags)
5081 {
5082 int reg;
5083 int write_back;
5084 int offset;
5085
5086 /* The instruction specified "ea" or "fd", so we can only accept
5087 [Rn]{!}. The instruction does not really support stacking or
5088 unstacking, so we have to emulate these by setting appropriate
5089 bits and offsets. */
5090 if (skip_past_comma (&str) == FAIL
5091 || *str != '[')
5092 {
5093 if (! inst.error)
5094 inst.error = BAD_ARGS;
5095 return;
5096 }
5097
5098 str++;
5099 skip_whitespace (str);
5100
5101 if ((reg = reg_required_here (&str, 16)) == FAIL)
5102 return;
5103
5104 skip_whitespace (str);
5105
5106 if (*str != ']')
5107 {
5108 inst.error = BAD_ARGS;
5109 return;
5110 }
5111
5112 str++;
5113 if (*str == '!')
5114 {
5115 write_back = 1;
5116 str++;
5117 if (reg == REG_PC)
5118 {
5119 inst.error =
5120 _("R15 not allowed as base register with write-back");
5121 return;
5122 }
5123 }
5124 else
5125 write_back = 0;
5126
5127 if (flags & CP_T_Pre)
5128 {
5129 /* Pre-decrement. */
5130 offset = 3 * num_regs;
5131 if (write_back)
5132 flags |= CP_T_WB;
5133 }
5134 else
5135 {
5136 /* Post-increment. */
5137 if (write_back)
5138 {
5139 flags |= CP_T_WB;
5140 offset = 3 * num_regs;
5141 }
5142 else
5143 {
5144 /* No write-back, so convert this into a standard pre-increment
5145 instruction -- aesthetically more pleasing. */
5146 flags = CP_T_Pre | CP_T_UD;
5147 offset = 0;
5148 }
5149 }
5150
5151 inst.instruction |= flags | offset;
5152 }
5153 else if (skip_past_comma (&str) == FAIL
5154 || cp_address_required_here (&str) == FAIL)
5155 {
5156 if (! inst.error)
5157 inst.error = BAD_ARGS;
5158 return;
5159 }
5160
5161 end_of_line (str);
5162 }
5163
5164 static void
5165 do_fp_dyadic (str, flags)
5166 char * str;
5167 unsigned long flags;
5168 {
5169 skip_whitespace (str);
5170
5171 switch (inst.suffix)
5172 {
5173 case SUFF_S:
5174 break;
5175 case SUFF_D:
5176 inst.instruction |= 0x00000080;
5177 break;
5178 case SUFF_E:
5179 inst.instruction |= 0x00080000;
5180 break;
5181 default:
5182 abort ();
5183 }
5184
5185 if (fp_reg_required_here (&str, 12) == FAIL)
5186 {
5187 if (! inst.error)
5188 inst.error = BAD_ARGS;
5189 return;
5190 }
5191
5192 if (skip_past_comma (&str) == FAIL
5193 || fp_reg_required_here (&str, 16) == FAIL)
5194 {
5195 if (! inst.error)
5196 inst.error = BAD_ARGS;
5197 return;
5198 }
5199
5200 if (skip_past_comma (&str) == FAIL
5201 || fp_op2 (&str) == FAIL)
5202 {
5203 if (! inst.error)
5204 inst.error = BAD_ARGS;
5205 return;
5206 }
5207
5208 inst.instruction |= flags;
5209 end_of_line (str);
5210 return;
5211 }
5212
5213 static void
5214 do_fp_monadic (str, flags)
5215 char * str;
5216 unsigned long flags;
5217 {
5218 skip_whitespace (str);
5219
5220 switch (inst.suffix)
5221 {
5222 case SUFF_S:
5223 break;
5224 case SUFF_D:
5225 inst.instruction |= 0x00000080;
5226 break;
5227 case SUFF_E:
5228 inst.instruction |= 0x00080000;
5229 break;
5230 default:
5231 abort ();
5232 }
5233
5234 if (fp_reg_required_here (&str, 12) == FAIL)
5235 {
5236 if (! inst.error)
5237 inst.error = BAD_ARGS;
5238 return;
5239 }
5240
5241 if (skip_past_comma (&str) == FAIL
5242 || fp_op2 (&str) == FAIL)
5243 {
5244 if (! inst.error)
5245 inst.error = BAD_ARGS;
5246 return;
5247 }
5248
5249 inst.instruction |= flags;
5250 end_of_line (str);
5251 return;
5252 }
5253
5254 static void
5255 do_fp_cmp (str, flags)
5256 char * str;
5257 unsigned long flags;
5258 {
5259 skip_whitespace (str);
5260
5261 if (fp_reg_required_here (&str, 16) == FAIL)
5262 {
5263 if (! inst.error)
5264 inst.error = BAD_ARGS;
5265 return;
5266 }
5267
5268 if (skip_past_comma (&str) == FAIL
5269 || fp_op2 (&str) == FAIL)
5270 {
5271 if (! inst.error)
5272 inst.error = BAD_ARGS;
5273 return;
5274 }
5275
5276 inst.instruction |= flags;
5277 end_of_line (str);
5278 return;
5279 }
5280
5281 static void
5282 do_fp_from_reg (str, flags)
5283 char * str;
5284 unsigned long flags;
5285 {
5286 skip_whitespace (str);
5287
5288 switch (inst.suffix)
5289 {
5290 case SUFF_S:
5291 break;
5292 case SUFF_D:
5293 inst.instruction |= 0x00000080;
5294 break;
5295 case SUFF_E:
5296 inst.instruction |= 0x00080000;
5297 break;
5298 default:
5299 abort ();
5300 }
5301
5302 if (fp_reg_required_here (&str, 16) == FAIL)
5303 {
5304 if (! inst.error)
5305 inst.error = BAD_ARGS;
5306 return;
5307 }
5308
5309 if (skip_past_comma (&str) == FAIL
5310 || reg_required_here (&str, 12) == FAIL)
5311 {
5312 if (! inst.error)
5313 inst.error = BAD_ARGS;
5314 return;
5315 }
5316
5317 inst.instruction |= flags;
5318 end_of_line (str);
5319 return;
5320 }
5321
5322 static void
5323 do_fp_to_reg (str, flags)
5324 char * str;
5325 unsigned long flags;
5326 {
5327 skip_whitespace (str);
5328
5329 if (reg_required_here (&str, 12) == FAIL)
5330 return;
5331
5332 if (skip_past_comma (&str) == FAIL
5333 || fp_reg_required_here (&str, 0) == FAIL)
5334 {
5335 if (! inst.error)
5336 inst.error = BAD_ARGS;
5337 return;
5338 }
5339
5340 inst.instruction |= flags;
5341 end_of_line (str);
5342 return;
5343 }
5344
5345 /* Thumb specific routines. */
5346
5347 /* Parse and validate that a register is of the right form, this saves
5348 repeated checking of this information in many similar cases.
5349 Unlike the 32-bit case we do not insert the register into the opcode
5350 here, since the position is often unknown until the full instruction
5351 has been parsed. */
5352
5353 static int
5354 thumb_reg (strp, hi_lo)
5355 char ** strp;
5356 int hi_lo;
5357 {
5358 int reg;
5359
5360 if ((reg = reg_required_here (strp, -1)) == FAIL)
5361 return FAIL;
5362
5363 switch (hi_lo)
5364 {
5365 case THUMB_REG_LO:
5366 if (reg > 7)
5367 {
5368 inst.error = _("lo register required");
5369 return FAIL;
5370 }
5371 break;
5372
5373 case THUMB_REG_HI:
5374 if (reg < 8)
5375 {
5376 inst.error = _("hi register required");
5377 return FAIL;
5378 }
5379 break;
5380
5381 default:
5382 break;
5383 }
5384
5385 return reg;
5386 }
5387
5388 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
5389 was SUB. */
5390
5391 static void
5392 thumb_add_sub (str, subtract)
5393 char * str;
5394 int subtract;
5395 {
5396 int Rd, Rs, Rn = FAIL;
5397
5398 skip_whitespace (str);
5399
5400 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
5401 || skip_past_comma (&str) == FAIL)
5402 {
5403 if (! inst.error)
5404 inst.error = BAD_ARGS;
5405 return;
5406 }
5407
5408 if (is_immediate_prefix (*str))
5409 {
5410 Rs = Rd;
5411 str++;
5412 if (my_get_expression (&inst.reloc.exp, &str))
5413 return;
5414 }
5415 else
5416 {
5417 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5418 return;
5419
5420 if (skip_past_comma (&str) == FAIL)
5421 {
5422 /* Two operand format, shuffle the registers
5423 and pretend there are 3. */
5424 Rn = Rs;
5425 Rs = Rd;
5426 }
5427 else if (is_immediate_prefix (*str))
5428 {
5429 str++;
5430 if (my_get_expression (&inst.reloc.exp, &str))
5431 return;
5432 }
5433 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5434 return;
5435 }
5436
5437 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5438 for the latter case, EXPR contains the immediate that was found. */
5439 if (Rn != FAIL)
5440 {
5441 /* All register format. */
5442 if (Rd > 7 || Rs > 7 || Rn > 7)
5443 {
5444 if (Rs != Rd)
5445 {
5446 inst.error = _("dest and source1 must be the same register");
5447 return;
5448 }
5449
5450 /* Can't do this for SUB. */
5451 if (subtract)
5452 {
5453 inst.error = _("subtract valid only on lo regs");
5454 return;
5455 }
5456
5457 inst.instruction = (T_OPCODE_ADD_HI
5458 | (Rd > 7 ? THUMB_H1 : 0)
5459 | (Rn > 7 ? THUMB_H2 : 0));
5460 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
5461 }
5462 else
5463 {
5464 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
5465 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
5466 }
5467 }
5468 else
5469 {
5470 /* Immediate expression, now things start to get nasty. */
5471
5472 /* First deal with HI regs, only very restricted cases allowed:
5473 Adjusting SP, and using PC or SP to get an address. */
5474 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
5475 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
5476 {
5477 inst.error = _("invalid Hi register with immediate");
5478 return;
5479 }
5480
5481 if (inst.reloc.exp.X_op != O_constant)
5482 {
5483 /* Value isn't known yet, all we can do is store all the fragments
5484 we know about in the instruction and let the reloc hacking
5485 work it all out. */
5486 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
5487 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
5488 }
5489 else
5490 {
5491 int offset = inst.reloc.exp.X_add_number;
5492
5493 if (subtract)
5494 offset = -offset;
5495
5496 if (offset < 0)
5497 {
5498 offset = -offset;
5499 subtract = 1;
5500
5501 /* Quick check, in case offset is MIN_INT. */
5502 if (offset < 0)
5503 {
5504 inst.error = _("immediate value out of range");
5505 return;
5506 }
5507 }
5508 else
5509 subtract = 0;
5510
5511 if (Rd == REG_SP)
5512 {
5513 if (offset & ~0x1fc)
5514 {
5515 inst.error = _("invalid immediate value for stack adjust");
5516 return;
5517 }
5518 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5519 inst.instruction |= offset >> 2;
5520 }
5521 else if (Rs == REG_PC || Rs == REG_SP)
5522 {
5523 if (subtract
5524 || (offset & ~0x3fc))
5525 {
5526 inst.error = _("invalid immediate for address calculation");
5527 return;
5528 }
5529 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
5530 : T_OPCODE_ADD_SP);
5531 inst.instruction |= (Rd << 8) | (offset >> 2);
5532 }
5533 else if (Rs == Rd)
5534 {
5535 if (offset & ~0xff)
5536 {
5537 inst.error = _("immediate value out of range");
5538 return;
5539 }
5540 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5541 inst.instruction |= (Rd << 8) | offset;
5542 }
5543 else
5544 {
5545 if (offset & ~0x7)
5546 {
5547 inst.error = _("immediate value out of range");
5548 return;
5549 }
5550 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5551 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
5552 }
5553 }
5554 }
5555
5556 end_of_line (str);
5557 }
5558
5559 static void
5560 thumb_shift (str, shift)
5561 char * str;
5562 int shift;
5563 {
5564 int Rd, Rs, Rn = FAIL;
5565
5566 skip_whitespace (str);
5567
5568 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
5569 || skip_past_comma (&str) == FAIL)
5570 {
5571 if (! inst.error)
5572 inst.error = BAD_ARGS;
5573 return;
5574 }
5575
5576 if (is_immediate_prefix (*str))
5577 {
5578 /* Two operand immediate format, set Rs to Rd. */
5579 Rs = Rd;
5580 str ++;
5581 if (my_get_expression (&inst.reloc.exp, &str))
5582 return;
5583 }
5584 else
5585 {
5586 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5587 return;
5588
5589 if (skip_past_comma (&str) == FAIL)
5590 {
5591 /* Two operand format, shuffle the registers
5592 and pretend there are 3. */
5593 Rn = Rs;
5594 Rs = Rd;
5595 }
5596 else if (is_immediate_prefix (*str))
5597 {
5598 str++;
5599 if (my_get_expression (&inst.reloc.exp, &str))
5600 return;
5601 }
5602 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5603 return;
5604 }
5605
5606 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5607 for the latter case, EXPR contains the immediate that was found. */
5608
5609 if (Rn != FAIL)
5610 {
5611 if (Rs != Rd)
5612 {
5613 inst.error = _("source1 and dest must be same register");
5614 return;
5615 }
5616
5617 switch (shift)
5618 {
5619 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
5620 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
5621 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
5622 }
5623
5624 inst.instruction |= Rd | (Rn << 3);
5625 }
5626 else
5627 {
5628 switch (shift)
5629 {
5630 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
5631 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
5632 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
5633 }
5634
5635 if (inst.reloc.exp.X_op != O_constant)
5636 {
5637 /* Value isn't known yet, create a dummy reloc and let reloc
5638 hacking fix it up. */
5639 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
5640 }
5641 else
5642 {
5643 unsigned shift_value = inst.reloc.exp.X_add_number;
5644
5645 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
5646 {
5647 inst.error = _("Invalid immediate for shift");
5648 return;
5649 }
5650
5651 /* Shifts of zero are handled by converting to LSL. */
5652 if (shift_value == 0)
5653 inst.instruction = T_OPCODE_LSL_I;
5654
5655 /* Shifts of 32 are encoded as a shift of zero. */
5656 if (shift_value == 32)
5657 shift_value = 0;
5658
5659 inst.instruction |= shift_value << 6;
5660 }
5661
5662 inst.instruction |= Rd | (Rs << 3);
5663 }
5664
5665 end_of_line (str);
5666 }
5667
5668 static void
5669 thumb_mov_compare (str, move)
5670 char * str;
5671 int move;
5672 {
5673 int Rd, Rs = FAIL;
5674
5675 skip_whitespace (str);
5676
5677 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
5678 || skip_past_comma (&str) == FAIL)
5679 {
5680 if (! inst.error)
5681 inst.error = BAD_ARGS;
5682 return;
5683 }
5684
5685 if (is_immediate_prefix (*str))
5686 {
5687 str++;
5688 if (my_get_expression (&inst.reloc.exp, &str))
5689 return;
5690 }
5691 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5692 return;
5693
5694 if (Rs != FAIL)
5695 {
5696 if (Rs < 8 && Rd < 8)
5697 {
5698 if (move == THUMB_MOVE)
5699 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
5700 since a MOV instruction produces unpredictable results. */
5701 inst.instruction = T_OPCODE_ADD_I3;
5702 else
5703 inst.instruction = T_OPCODE_CMP_LR;
5704 inst.instruction |= Rd | (Rs << 3);
5705 }
5706 else
5707 {
5708 if (move == THUMB_MOVE)
5709 inst.instruction = T_OPCODE_MOV_HR;
5710 else
5711 inst.instruction = T_OPCODE_CMP_HR;
5712
5713 if (Rd > 7)
5714 inst.instruction |= THUMB_H1;
5715
5716 if (Rs > 7)
5717 inst.instruction |= THUMB_H2;
5718
5719 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
5720 }
5721 }
5722 else
5723 {
5724 if (Rd > 7)
5725 {
5726 inst.error = _("only lo regs allowed with immediate");
5727 return;
5728 }
5729
5730 if (move == THUMB_MOVE)
5731 inst.instruction = T_OPCODE_MOV_I8;
5732 else
5733 inst.instruction = T_OPCODE_CMP_I8;
5734
5735 inst.instruction |= Rd << 8;
5736
5737 if (inst.reloc.exp.X_op != O_constant)
5738 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
5739 else
5740 {
5741 unsigned value = inst.reloc.exp.X_add_number;
5742
5743 if (value > 255)
5744 {
5745 inst.error = _("invalid immediate");
5746 return;
5747 }
5748
5749 inst.instruction |= value;
5750 }
5751 }
5752
5753 end_of_line (str);
5754 }
5755
5756 static void
5757 thumb_load_store (str, load_store, size)
5758 char * str;
5759 int load_store;
5760 int size;
5761 {
5762 int Rd, Rb, Ro = FAIL;
5763
5764 skip_whitespace (str);
5765
5766 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
5767 || skip_past_comma (&str) == FAIL)
5768 {
5769 if (! inst.error)
5770 inst.error = BAD_ARGS;
5771 return;
5772 }
5773
5774 if (*str == '[')
5775 {
5776 str++;
5777 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5778 return;
5779
5780 if (skip_past_comma (&str) != FAIL)
5781 {
5782 if (is_immediate_prefix (*str))
5783 {
5784 str++;
5785 if (my_get_expression (&inst.reloc.exp, &str))
5786 return;
5787 }
5788 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5789 return;
5790 }
5791 else
5792 {
5793 inst.reloc.exp.X_op = O_constant;
5794 inst.reloc.exp.X_add_number = 0;
5795 }
5796
5797 if (*str != ']')
5798 {
5799 inst.error = _("expected ']'");
5800 return;
5801 }
5802 str++;
5803 }
5804 else if (*str == '=')
5805 {
5806 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5807 str++;
5808
5809 skip_whitespace (str);
5810
5811 if (my_get_expression (& inst.reloc.exp, & str))
5812 return;
5813
5814 end_of_line (str);
5815
5816 if ( inst.reloc.exp.X_op != O_constant
5817 && inst.reloc.exp.X_op != O_symbol)
5818 {
5819 inst.error = "Constant expression expected";
5820 return;
5821 }
5822
5823 if (inst.reloc.exp.X_op == O_constant
5824 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
5825 {
5826 /* This can be done with a mov instruction. */
5827
5828 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
5829 inst.instruction |= inst.reloc.exp.X_add_number;
5830 return;
5831 }
5832
5833 /* Insert into literal pool. */
5834 if (add_to_lit_pool () == FAIL)
5835 {
5836 if (!inst.error)
5837 inst.error = "literal pool insertion failed";
5838 return;
5839 }
5840
5841 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
5842 inst.reloc.pc_rel = 1;
5843 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
5844 /* Adjust ARM pipeline offset to Thumb. */
5845 inst.reloc.exp.X_add_number += 4;
5846
5847 return;
5848 }
5849 else
5850 {
5851 if (my_get_expression (&inst.reloc.exp, &str))
5852 return;
5853
5854 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
5855 inst.reloc.pc_rel = 1;
5856 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
5857 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
5858 end_of_line (str);
5859 return;
5860 }
5861
5862 if (Rb == REG_PC || Rb == REG_SP)
5863 {
5864 if (size != THUMB_WORD)
5865 {
5866 inst.error = _("byte or halfword not valid for base register");
5867 return;
5868 }
5869 else if (Rb == REG_PC && load_store != THUMB_LOAD)
5870 {
5871 inst.error = _("R15 based store not allowed");
5872 return;
5873 }
5874 else if (Ro != FAIL)
5875 {
5876 inst.error = _("Invalid base register for register offset");
5877 return;
5878 }
5879
5880 if (Rb == REG_PC)
5881 inst.instruction = T_OPCODE_LDR_PC;
5882 else if (load_store == THUMB_LOAD)
5883 inst.instruction = T_OPCODE_LDR_SP;
5884 else
5885 inst.instruction = T_OPCODE_STR_SP;
5886
5887 inst.instruction |= Rd << 8;
5888 if (inst.reloc.exp.X_op == O_constant)
5889 {
5890 unsigned offset = inst.reloc.exp.X_add_number;
5891
5892 if (offset & ~0x3fc)
5893 {
5894 inst.error = _("invalid offset");
5895 return;
5896 }
5897
5898 inst.instruction |= offset >> 2;
5899 }
5900 else
5901 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
5902 }
5903 else if (Rb > 7)
5904 {
5905 inst.error = _("invalid base register in load/store");
5906 return;
5907 }
5908 else if (Ro == FAIL)
5909 {
5910 /* Immediate offset. */
5911 if (size == THUMB_WORD)
5912 inst.instruction = (load_store == THUMB_LOAD
5913 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
5914 else if (size == THUMB_HALFWORD)
5915 inst.instruction = (load_store == THUMB_LOAD
5916 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
5917 else
5918 inst.instruction = (load_store == THUMB_LOAD
5919 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
5920
5921 inst.instruction |= Rd | (Rb << 3);
5922
5923 if (inst.reloc.exp.X_op == O_constant)
5924 {
5925 unsigned offset = inst.reloc.exp.X_add_number;
5926
5927 if (offset & ~(0x1f << size))
5928 {
5929 inst.error = _("Invalid offset");
5930 return;
5931 }
5932 inst.instruction |= (offset >> size) << 6;
5933 }
5934 else
5935 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
5936 }
5937 else
5938 {
5939 /* Register offset. */
5940 if (size == THUMB_WORD)
5941 inst.instruction = (load_store == THUMB_LOAD
5942 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
5943 else if (size == THUMB_HALFWORD)
5944 inst.instruction = (load_store == THUMB_LOAD
5945 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
5946 else
5947 inst.instruction = (load_store == THUMB_LOAD
5948 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
5949
5950 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
5951 }
5952
5953 end_of_line (str);
5954 }
5955
5956 static void
5957 do_t_nop (str)
5958 char * str;
5959 {
5960 /* Do nothing. */
5961 end_of_line (str);
5962 return;
5963 }
5964
5965 /* Handle the Format 4 instructions that do not have equivalents in other
5966 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
5967 BIC and MVN. */
5968
5969 static void
5970 do_t_arit (str)
5971 char * str;
5972 {
5973 int Rd, Rs, Rn;
5974
5975 skip_whitespace (str);
5976
5977 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
5978 || skip_past_comma (&str) == FAIL
5979 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5980 {
5981 inst.error = BAD_ARGS;
5982 return;
5983 }
5984
5985 if (skip_past_comma (&str) != FAIL)
5986 {
5987 /* Three operand format not allowed for TST, CMN, NEG and MVN.
5988 (It isn't allowed for CMP either, but that isn't handled by this
5989 function.) */
5990 if (inst.instruction == T_OPCODE_TST
5991 || inst.instruction == T_OPCODE_CMN
5992 || inst.instruction == T_OPCODE_NEG
5993 || inst.instruction == T_OPCODE_MVN)
5994 {
5995 inst.error = BAD_ARGS;
5996 return;
5997 }
5998
5999 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
6000 return;
6001
6002 if (Rs != Rd)
6003 {
6004 inst.error = _("dest and source1 one must be the same register");
6005 return;
6006 }
6007 Rs = Rn;
6008 }
6009
6010 if (inst.instruction == T_OPCODE_MUL
6011 && Rs == Rd)
6012 as_tsktsk (_("Rs and Rd must be different in MUL"));
6013
6014 inst.instruction |= Rd | (Rs << 3);
6015 end_of_line (str);
6016 }
6017
6018 static void
6019 do_t_add (str)
6020 char * str;
6021 {
6022 thumb_add_sub (str, 0);
6023 }
6024
6025 static void
6026 do_t_asr (str)
6027 char * str;
6028 {
6029 thumb_shift (str, THUMB_ASR);
6030 }
6031
6032 static void
6033 do_t_branch9 (str)
6034 char * str;
6035 {
6036 if (my_get_expression (&inst.reloc.exp, &str))
6037 return;
6038 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
6039 inst.reloc.pc_rel = 1;
6040 end_of_line (str);
6041 }
6042
6043 static void
6044 do_t_branch12 (str)
6045 char * str;
6046 {
6047 if (my_get_expression (&inst.reloc.exp, &str))
6048 return;
6049 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
6050 inst.reloc.pc_rel = 1;
6051 end_of_line (str);
6052 }
6053
6054 /* Find the real, Thumb encoded start of a Thumb function. */
6055
6056 static symbolS *
6057 find_real_start (symbolP)
6058 symbolS * symbolP;
6059 {
6060 char * real_start;
6061 const char * name = S_GET_NAME (symbolP);
6062 symbolS * new_target;
6063
6064 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
6065 #define STUB_NAME ".real_start_of"
6066
6067 if (name == NULL)
6068 abort ();
6069
6070 /* Names that start with '.' are local labels, not function entry points.
6071 The compiler may generate BL instructions to these labels because it
6072 needs to perform a branch to a far away location. */
6073 if (name[0] == '.')
6074 return symbolP;
6075
6076 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
6077 sprintf (real_start, "%s%s", STUB_NAME, name);
6078
6079 new_target = symbol_find (real_start);
6080
6081 if (new_target == NULL)
6082 {
6083 as_warn ("Failed to find real start of function: %s\n", name);
6084 new_target = symbolP;
6085 }
6086
6087 free (real_start);
6088
6089 return new_target;
6090 }
6091
6092 static void
6093 do_t_branch23 (str)
6094 char * str;
6095 {
6096 if (my_get_expression (& inst.reloc.exp, & str))
6097 return;
6098
6099 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
6100 inst.reloc.pc_rel = 1;
6101 end_of_line (str);
6102
6103 /* If the destination of the branch is a defined symbol which does not have
6104 the THUMB_FUNC attribute, then we must be calling a function which has
6105 the (interfacearm) attribute. We look for the Thumb entry point to that
6106 function and change the branch to refer to that function instead. */
6107 if ( inst.reloc.exp.X_op == O_symbol
6108 && inst.reloc.exp.X_add_symbol != NULL
6109 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
6110 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
6111 inst.reloc.exp.X_add_symbol =
6112 find_real_start (inst.reloc.exp.X_add_symbol);
6113 }
6114
6115 static void
6116 do_t_bx (str)
6117 char * str;
6118 {
6119 int reg;
6120
6121 skip_whitespace (str);
6122
6123 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
6124 return;
6125
6126 /* This sets THUMB_H2 from the top bit of reg. */
6127 inst.instruction |= reg << 3;
6128
6129 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
6130 should cause the alignment to be checked once it is known. This is
6131 because BX PC only works if the instruction is word aligned. */
6132
6133 end_of_line (str);
6134 }
6135
6136 static void
6137 do_t_compare (str)
6138 char * str;
6139 {
6140 thumb_mov_compare (str, THUMB_COMPARE);
6141 }
6142
6143 static void
6144 do_t_ldmstm (str)
6145 char * str;
6146 {
6147 int Rb;
6148 long range;
6149
6150 skip_whitespace (str);
6151
6152 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
6153 return;
6154
6155 if (*str != '!')
6156 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
6157 else
6158 str++;
6159
6160 if (skip_past_comma (&str) == FAIL
6161 || (range = reg_list (&str)) == FAIL)
6162 {
6163 if (! inst.error)
6164 inst.error = BAD_ARGS;
6165 return;
6166 }
6167
6168 if (inst.reloc.type != BFD_RELOC_NONE)
6169 {
6170 /* This really doesn't seem worth it. */
6171 inst.reloc.type = BFD_RELOC_NONE;
6172 inst.error = _("Expression too complex");
6173 return;
6174 }
6175
6176 if (range & ~0xff)
6177 {
6178 inst.error = _("only lo-regs valid in load/store multiple");
6179 return;
6180 }
6181
6182 inst.instruction |= (Rb << 8) | range;
6183 end_of_line (str);
6184 }
6185
6186 static void
6187 do_t_ldr (str)
6188 char * str;
6189 {
6190 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
6191 }
6192
6193 static void
6194 do_t_ldrb (str)
6195 char * str;
6196 {
6197 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
6198 }
6199
6200 static void
6201 do_t_ldrh (str)
6202 char * str;
6203 {
6204 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
6205 }
6206
6207 static void
6208 do_t_lds (str)
6209 char * str;
6210 {
6211 int Rd, Rb, Ro;
6212
6213 skip_whitespace (str);
6214
6215 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
6216 || skip_past_comma (&str) == FAIL
6217 || *str++ != '['
6218 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
6219 || skip_past_comma (&str) == FAIL
6220 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
6221 || *str++ != ']')
6222 {
6223 if (! inst.error)
6224 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
6225 return;
6226 }
6227
6228 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
6229 end_of_line (str);
6230 }
6231
6232 static void
6233 do_t_lsl (str)
6234 char * str;
6235 {
6236 thumb_shift (str, THUMB_LSL);
6237 }
6238
6239 static void
6240 do_t_lsr (str)
6241 char * str;
6242 {
6243 thumb_shift (str, THUMB_LSR);
6244 }
6245
6246 static void
6247 do_t_mov (str)
6248 char * str;
6249 {
6250 thumb_mov_compare (str, THUMB_MOVE);
6251 }
6252
6253 static void
6254 do_t_push_pop (str)
6255 char * str;
6256 {
6257 long range;
6258
6259 skip_whitespace (str);
6260
6261 if ((range = reg_list (&str)) == FAIL)
6262 {
6263 if (! inst.error)
6264 inst.error = BAD_ARGS;
6265 return;
6266 }
6267
6268 if (inst.reloc.type != BFD_RELOC_NONE)
6269 {
6270 /* This really doesn't seem worth it. */
6271 inst.reloc.type = BFD_RELOC_NONE;
6272 inst.error = _("Expression too complex");
6273 return;
6274 }
6275
6276 if (range & ~0xff)
6277 {
6278 if ((inst.instruction == T_OPCODE_PUSH
6279 && (range & ~0xff) == 1 << REG_LR)
6280 || (inst.instruction == T_OPCODE_POP
6281 && (range & ~0xff) == 1 << REG_PC))
6282 {
6283 inst.instruction |= THUMB_PP_PC_LR;
6284 range &= 0xff;
6285 }
6286 else
6287 {
6288 inst.error = _("invalid register list to push/pop instruction");
6289 return;
6290 }
6291 }
6292
6293 inst.instruction |= range;
6294 end_of_line (str);
6295 }
6296
6297 static void
6298 do_t_str (str)
6299 char * str;
6300 {
6301 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
6302 }
6303
6304 static void
6305 do_t_strb (str)
6306 char * str;
6307 {
6308 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
6309 }
6310
6311 static void
6312 do_t_strh (str)
6313 char * str;
6314 {
6315 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
6316 }
6317
6318 static void
6319 do_t_sub (str)
6320 char * str;
6321 {
6322 thumb_add_sub (str, 1);
6323 }
6324
6325 static void
6326 do_t_swi (str)
6327 char * str;
6328 {
6329 skip_whitespace (str);
6330
6331 if (my_get_expression (&inst.reloc.exp, &str))
6332 return;
6333
6334 inst.reloc.type = BFD_RELOC_ARM_SWI;
6335 end_of_line (str);
6336 return;
6337 }
6338
6339 static void
6340 do_t_adr (str)
6341 char * str;
6342 {
6343 int reg;
6344
6345 /* This is a pseudo-op of the form "adr rd, label" to be converted
6346 into a relative address of the form "add rd, pc, #label-.-4". */
6347 skip_whitespace (str);
6348
6349 /* Store Rd in temporary location inside instruction. */
6350 if ((reg = reg_required_here (&str, 4)) == FAIL
6351 || (reg > 7) /* For Thumb reg must be r0..r7. */
6352 || skip_past_comma (&str) == FAIL
6353 || my_get_expression (&inst.reloc.exp, &str))
6354 {
6355 if (!inst.error)
6356 inst.error = BAD_ARGS;
6357 return;
6358 }
6359
6360 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
6361 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
6362 inst.reloc.pc_rel = 1;
6363 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
6364
6365 end_of_line (str);
6366 }
6367
6368 static void
6369 insert_reg (entry)
6370 int entry;
6371 {
6372 int len = strlen (reg_table[entry].name) + 2;
6373 char * buf = (char *) xmalloc (len);
6374 char * buf2 = (char *) xmalloc (len);
6375 int i = 0;
6376
6377 #ifdef REGISTER_PREFIX
6378 buf[i++] = REGISTER_PREFIX;
6379 #endif
6380
6381 strcpy (buf + i, reg_table[entry].name);
6382
6383 for (i = 0; buf[i]; i++)
6384 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
6385
6386 buf2[i] = '\0';
6387
6388 hash_insert (arm_reg_hsh, buf, (PTR) & reg_table[entry]);
6389 hash_insert (arm_reg_hsh, buf2, (PTR) & reg_table[entry]);
6390 }
6391
6392 static void
6393 insert_reg_alias (str, regnum)
6394 char *str;
6395 int regnum;
6396 {
6397 struct reg_entry *new =
6398 (struct reg_entry *) xmalloc (sizeof (struct reg_entry));
6399 char *name = xmalloc (strlen (str) + 1);
6400 strcpy (name, str);
6401
6402 new->name = name;
6403 new->number = regnum;
6404
6405 hash_insert (arm_reg_hsh, name, (PTR) new);
6406 }
6407
6408 static void
6409 set_constant_flonums ()
6410 {
6411 int i;
6412
6413 for (i = 0; i < NUM_FLOAT_VALS; i++)
6414 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
6415 abort ();
6416 }
6417
6418 void
6419 md_begin ()
6420 {
6421 unsigned mach;
6422 unsigned int i;
6423
6424 if ( (arm_ops_hsh = hash_new ()) == NULL
6425 || (arm_tops_hsh = hash_new ()) == NULL
6426 || (arm_cond_hsh = hash_new ()) == NULL
6427 || (arm_shift_hsh = hash_new ()) == NULL
6428 || (arm_reg_hsh = hash_new ()) == NULL
6429 || (arm_psr_hsh = hash_new ()) == NULL)
6430 as_fatal (_("Virtual memory exhausted"));
6431
6432 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
6433 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
6434 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
6435 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
6436 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
6437 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
6438 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
6439 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
6440 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
6441 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
6442
6443 for (i = 0; reg_table[i].name; i++)
6444 insert_reg (i);
6445
6446 set_constant_flonums ();
6447
6448 #if defined OBJ_COFF || defined OBJ_ELF
6449 {
6450 unsigned int flags = 0;
6451
6452 /* Set the flags in the private structure. */
6453 if (uses_apcs_26) flags |= F_APCS26;
6454 if (support_interwork) flags |= F_INTERWORK;
6455 if (uses_apcs_float) flags |= F_APCS_FLOAT;
6456 if (pic_code) flags |= F_PIC;
6457 if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT;
6458
6459 bfd_set_private_flags (stdoutput, flags);
6460
6461 /* We have run out flags in the COFF header to encode the
6462 status of ATPCS support, so instead we create a dummy,
6463 empty, debug section called .arm.atpcs. */
6464 if (atpcs)
6465 {
6466 asection * sec;
6467
6468 sec = bfd_make_section (stdoutput, ".arm.atpcs");
6469
6470 if (sec != NULL)
6471 {
6472 bfd_set_section_flags
6473 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
6474 bfd_set_section_size (stdoutput, sec, 0);
6475 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
6476 }
6477 }
6478 }
6479 #endif
6480
6481 /* Record the CPU type as well. */
6482 switch (cpu_variant & ARM_CPU_MASK)
6483 {
6484 case ARM_2:
6485 mach = bfd_mach_arm_2;
6486 break;
6487
6488 case ARM_3: /* Also ARM_250. */
6489 mach = bfd_mach_arm_2a;
6490 break;
6491
6492 default:
6493 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined. */
6494 mach = bfd_mach_arm_4;
6495 break;
6496
6497 case ARM_7: /* Also ARM_6. */
6498 mach = bfd_mach_arm_3;
6499 break;
6500 }
6501
6502 /* Catch special cases. */
6503 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
6504 {
6505 if (cpu_variant & ARM_EXT_XSCALE)
6506 mach = bfd_mach_arm_XScale;
6507 else if (cpu_variant & ARM_EXT_V5E)
6508 mach = bfd_mach_arm_5TE;
6509 else if (cpu_variant & ARM_EXT_V5)
6510 {
6511 if (cpu_variant & ARM_EXT_THUMB)
6512 mach = bfd_mach_arm_5T;
6513 else
6514 mach = bfd_mach_arm_5;
6515 }
6516 else if (cpu_variant & ARM_EXT_HALFWORD)
6517 {
6518 if (cpu_variant & ARM_EXT_THUMB)
6519 mach = bfd_mach_arm_4T;
6520 else
6521 mach = bfd_mach_arm_4;
6522 }
6523 else if (cpu_variant & ARM_EXT_LONGMUL)
6524 mach = bfd_mach_arm_3M;
6525 }
6526
6527 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
6528 }
6529
6530 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
6531 for use in the a.out file, and stores them in the array pointed to by buf.
6532 This knows about the endian-ness of the target machine and does
6533 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
6534 2 (short) and 4 (long) Floating numbers are put out as a series of
6535 LITTLENUMS (shorts, here at least). */
6536
6537 void
6538 md_number_to_chars (buf, val, n)
6539 char * buf;
6540 valueT val;
6541 int n;
6542 {
6543 if (target_big_endian)
6544 number_to_chars_bigendian (buf, val, n);
6545 else
6546 number_to_chars_littleendian (buf, val, n);
6547 }
6548
6549 static valueT
6550 md_chars_to_number (buf, n)
6551 char * buf;
6552 int n;
6553 {
6554 valueT result = 0;
6555 unsigned char * where = (unsigned char *) buf;
6556
6557 if (target_big_endian)
6558 {
6559 while (n--)
6560 {
6561 result <<= 8;
6562 result |= (*where++ & 255);
6563 }
6564 }
6565 else
6566 {
6567 while (n--)
6568 {
6569 result <<= 8;
6570 result |= (where[n] & 255);
6571 }
6572 }
6573
6574 return result;
6575 }
6576
6577 /* Turn a string in input_line_pointer into a floating point constant
6578 of type TYPE, and store the appropriate bytes in *LITP. The number
6579 of LITTLENUMS emitted is stored in *SIZEP. An error message is
6580 returned, or NULL on OK.
6581
6582 Note that fp constants aren't represent in the normal way on the ARM.
6583 In big endian mode, things are as expected. However, in little endian
6584 mode fp constants are big-endian word-wise, and little-endian byte-wise
6585 within the words. For example, (double) 1.1 in big endian mode is
6586 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
6587 the byte sequence 99 99 f1 3f 9a 99 99 99.
6588
6589 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
6590
6591 char *
6592 md_atof (type, litP, sizeP)
6593 char type;
6594 char * litP;
6595 int * sizeP;
6596 {
6597 int prec;
6598 LITTLENUM_TYPE words[MAX_LITTLENUMS];
6599 char *t;
6600 int i;
6601
6602 switch (type)
6603 {
6604 case 'f':
6605 case 'F':
6606 case 's':
6607 case 'S':
6608 prec = 2;
6609 break;
6610
6611 case 'd':
6612 case 'D':
6613 case 'r':
6614 case 'R':
6615 prec = 4;
6616 break;
6617
6618 case 'x':
6619 case 'X':
6620 prec = 6;
6621 break;
6622
6623 case 'p':
6624 case 'P':
6625 prec = 6;
6626 break;
6627
6628 default:
6629 *sizeP = 0;
6630 return _("Bad call to MD_ATOF()");
6631 }
6632
6633 t = atof_ieee (input_line_pointer, type, words);
6634 if (t)
6635 input_line_pointer = t;
6636 *sizeP = prec * 2;
6637
6638 if (target_big_endian)
6639 {
6640 for (i = 0; i < prec; i++)
6641 {
6642 md_number_to_chars (litP, (valueT) words[i], 2);
6643 litP += 2;
6644 }
6645 }
6646 else
6647 {
6648 /* For a 4 byte float the order of elements in `words' is 1 0. For an
6649 8 byte float the order is 1 0 3 2. */
6650 for (i = 0; i < prec; i += 2)
6651 {
6652 md_number_to_chars (litP, (valueT) words[i + 1], 2);
6653 md_number_to_chars (litP + 2, (valueT) words[i], 2);
6654 litP += 4;
6655 }
6656 }
6657
6658 return 0;
6659 }
6660
6661 /* The knowledge of the PC's pipeline offset is built into the insns
6662 themselves. */
6663
6664 long
6665 md_pcrel_from (fixP)
6666 fixS * fixP;
6667 {
6668 if (fixP->fx_addsy
6669 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
6670 && fixP->fx_subsy == NULL)
6671 return 0;
6672
6673 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
6674 {
6675 /* PC relative addressing on the Thumb is slightly odd
6676 as the bottom two bits of the PC are forced to zero
6677 for the calculation. */
6678 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
6679 }
6680
6681 #ifdef TE_WINCE
6682 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
6683 so we un-adjust here to compensate for the accomodation. */
6684 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
6685 #else
6686 return fixP->fx_where + fixP->fx_frag->fr_address;
6687 #endif
6688 }
6689
6690 /* Round up a section size to the appropriate boundary. */
6691
6692 valueT
6693 md_section_align (segment, size)
6694 segT segment ATTRIBUTE_UNUSED;
6695 valueT size;
6696 {
6697 #ifdef OBJ_ELF
6698 return size;
6699 #else
6700 /* Round all sects to multiple of 4. */
6701 return (size + 3) & ~3;
6702 #endif
6703 }
6704
6705 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
6706 Otherwise we have no need to default values of symbols. */
6707
6708 symbolS *
6709 md_undefined_symbol (name)
6710 char * name ATTRIBUTE_UNUSED;
6711 {
6712 #ifdef OBJ_ELF
6713 if (name[0] == '_' && name[1] == 'G'
6714 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
6715 {
6716 if (!GOT_symbol)
6717 {
6718 if (symbol_find (name))
6719 as_bad ("GOT already in the symbol table");
6720
6721 GOT_symbol = symbol_new (name, undefined_section,
6722 (valueT) 0, & zero_address_frag);
6723 }
6724
6725 return GOT_symbol;
6726 }
6727 #endif
6728
6729 return 0;
6730 }
6731
6732 /* arm_reg_parse () := if it looks like a register, return its token and
6733 advance the pointer. */
6734
6735 static int
6736 arm_reg_parse (ccp)
6737 register char ** ccp;
6738 {
6739 char * start = * ccp;
6740 char c;
6741 char * p;
6742 struct reg_entry * reg;
6743
6744 #ifdef REGISTER_PREFIX
6745 if (*start != REGISTER_PREFIX)
6746 return FAIL;
6747 p = start + 1;
6748 #else
6749 p = start;
6750 #ifdef OPTIONAL_REGISTER_PREFIX
6751 if (*p == OPTIONAL_REGISTER_PREFIX)
6752 p++, start++;
6753 #endif
6754 #endif
6755 if (!isalpha (*p) || !is_name_beginner (*p))
6756 return FAIL;
6757
6758 c = *p++;
6759 while (isalpha (c) || isdigit (c) || c == '_')
6760 c = *p++;
6761
6762 *--p = 0;
6763 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
6764 *p = c;
6765
6766 if (reg)
6767 {
6768 *ccp = p;
6769 return reg->number;
6770 }
6771
6772 return FAIL;
6773 }
6774
6775 int
6776 md_apply_fix3 (fixP, val, seg)
6777 fixS * fixP;
6778 valueT * val;
6779 segT seg;
6780 {
6781 offsetT value = * val;
6782 offsetT newval;
6783 unsigned int newimm;
6784 unsigned long temp;
6785 int sign;
6786 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
6787 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
6788
6789 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
6790
6791 /* Note whether this will delete the relocation. */
6792 #if 0
6793 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
6794 doesn't work fully.) */
6795 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
6796 && !fixP->fx_pcrel)
6797 #else
6798 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
6799 #endif
6800 fixP->fx_done = 1;
6801
6802 /* If this symbol is in a different section then we need to leave it for
6803 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
6804 so we have to undo it's effects here. */
6805 if (fixP->fx_pcrel)
6806 {
6807 if (fixP->fx_addsy != NULL
6808 && S_IS_DEFINED (fixP->fx_addsy)
6809 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
6810 {
6811 if (target_oabi
6812 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
6813 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
6814 ))
6815 value = 0;
6816 else
6817 value += md_pcrel_from (fixP);
6818 }
6819 }
6820
6821 /* Remember value for emit_reloc. */
6822 fixP->fx_addnumber = value;
6823
6824 switch (fixP->fx_r_type)
6825 {
6826 case BFD_RELOC_ARM_IMMEDIATE:
6827 newimm = validate_immediate (value);
6828 temp = md_chars_to_number (buf, INSN_SIZE);
6829
6830 /* If the instruction will fail, see if we can fix things up by
6831 changing the opcode. */
6832 if (newimm == (unsigned int) FAIL
6833 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
6834 {
6835 as_bad_where (fixP->fx_file, fixP->fx_line,
6836 _("invalid constant (%lx) after fixup"),
6837 (unsigned long) value);
6838 break;
6839 }
6840
6841 newimm |= (temp & 0xfffff000);
6842 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
6843 break;
6844
6845 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
6846 {
6847 unsigned int highpart = 0;
6848 unsigned int newinsn = 0xe1a00000; /* nop. */
6849 newimm = validate_immediate (value);
6850 temp = md_chars_to_number (buf, INSN_SIZE);
6851
6852 /* If the instruction will fail, see if we can fix things up by
6853 changing the opcode. */
6854 if (newimm == (unsigned int) FAIL
6855 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
6856 {
6857 /* No ? OK - try using two ADD instructions to generate
6858 the value. */
6859 newimm = validate_immediate_twopart (value, & highpart);
6860
6861 /* Yes - then make sure that the second instruction is
6862 also an add. */
6863 if (newimm != (unsigned int) FAIL)
6864 newinsn = temp;
6865 /* Still No ? Try using a negated value. */
6866 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
6867 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
6868 /* Otherwise - give up. */
6869 else
6870 {
6871 as_bad_where (fixP->fx_file, fixP->fx_line,
6872 _("Unable to compute ADRL instructions for PC offset of 0x%lx"),
6873 value);
6874 break;
6875 }
6876
6877 /* Replace the first operand in the 2nd instruction (which
6878 is the PC) with the destination register. We have
6879 already added in the PC in the first instruction and we
6880 do not want to do it again. */
6881 newinsn &= ~ 0xf0000;
6882 newinsn |= ((newinsn & 0x0f000) << 4);
6883 }
6884
6885 newimm |= (temp & 0xfffff000);
6886 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
6887
6888 highpart |= (newinsn & 0xfffff000);
6889 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
6890 }
6891 break;
6892
6893 case BFD_RELOC_ARM_OFFSET_IMM:
6894 sign = value >= 0;
6895
6896 if (value < 0)
6897 value = - value;
6898
6899 if (validate_offset_imm (value, 0) == FAIL)
6900 {
6901 as_bad_where (fixP->fx_file, fixP->fx_line,
6902 _("bad immediate value for offset (%ld)"),
6903 (long) value);
6904 break;
6905 }
6906
6907 newval = md_chars_to_number (buf, INSN_SIZE);
6908 newval &= 0xff7ff000;
6909 newval |= value | (sign ? INDEX_UP : 0);
6910 md_number_to_chars (buf, newval, INSN_SIZE);
6911 break;
6912
6913 case BFD_RELOC_ARM_OFFSET_IMM8:
6914 case BFD_RELOC_ARM_HWLITERAL:
6915 sign = value >= 0;
6916
6917 if (value < 0)
6918 value = - value;
6919
6920 if (validate_offset_imm (value, 1) == FAIL)
6921 {
6922 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
6923 as_bad_where (fixP->fx_file, fixP->fx_line,
6924 _("invalid literal constant: pool needs to be closer"));
6925 else
6926 as_bad (_("bad immediate value for half-word offset (%ld)"),
6927 (long) value);
6928 break;
6929 }
6930
6931 newval = md_chars_to_number (buf, INSN_SIZE);
6932 newval &= 0xff7ff0f0;
6933 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
6934 md_number_to_chars (buf, newval, INSN_SIZE);
6935 break;
6936
6937 case BFD_RELOC_ARM_LITERAL:
6938 sign = value >= 0;
6939
6940 if (value < 0)
6941 value = - value;
6942
6943 if (validate_offset_imm (value, 0) == FAIL)
6944 {
6945 as_bad_where (fixP->fx_file, fixP->fx_line,
6946 _("invalid literal constant: pool needs to be closer"));
6947 break;
6948 }
6949
6950 newval = md_chars_to_number (buf, INSN_SIZE);
6951 newval &= 0xff7ff000;
6952 newval |= value | (sign ? INDEX_UP : 0);
6953 md_number_to_chars (buf, newval, INSN_SIZE);
6954 break;
6955
6956 case BFD_RELOC_ARM_SHIFT_IMM:
6957 newval = md_chars_to_number (buf, INSN_SIZE);
6958 if (((unsigned long) value) > 32
6959 || (value == 32
6960 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
6961 {
6962 as_bad_where (fixP->fx_file, fixP->fx_line,
6963 _("shift expression is too large"));
6964 break;
6965 }
6966
6967 if (value == 0)
6968 /* Shifts of zero must be done as lsl. */
6969 newval &= ~0x60;
6970 else if (value == 32)
6971 value = 0;
6972 newval &= 0xfffff07f;
6973 newval |= (value & 0x1f) << 7;
6974 md_number_to_chars (buf, newval, INSN_SIZE);
6975 break;
6976
6977 case BFD_RELOC_ARM_SWI:
6978 if (arm_data->thumb_mode)
6979 {
6980 if (((unsigned long) value) > 0xff)
6981 as_bad_where (fixP->fx_file, fixP->fx_line,
6982 _("Invalid swi expression"));
6983 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
6984 newval |= value;
6985 md_number_to_chars (buf, newval, THUMB_SIZE);
6986 }
6987 else
6988 {
6989 if (((unsigned long) value) > 0x00ffffff)
6990 as_bad_where (fixP->fx_file, fixP->fx_line,
6991 _("Invalid swi expression"));
6992 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
6993 newval |= value;
6994 md_number_to_chars (buf, newval, INSN_SIZE);
6995 }
6996 break;
6997
6998 case BFD_RELOC_ARM_MULTI:
6999 if (((unsigned long) value) > 0xffff)
7000 as_bad_where (fixP->fx_file, fixP->fx_line,
7001 _("Invalid expression in load/store multiple"));
7002 newval = value | md_chars_to_number (buf, INSN_SIZE);
7003 md_number_to_chars (buf, newval, INSN_SIZE);
7004 break;
7005
7006 case BFD_RELOC_ARM_PCREL_BRANCH:
7007 newval = md_chars_to_number (buf, INSN_SIZE);
7008
7009 /* Sign-extend a 24-bit number. */
7010 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
7011
7012 #ifdef OBJ_ELF
7013 if (! target_oabi)
7014 value = fixP->fx_offset;
7015 #endif
7016
7017 /* We are going to store value (shifted right by two) in the
7018 instruction, in a 24 bit, signed field. Thus we need to check
7019 that none of the top 8 bits of the shifted value (top 7 bits of
7020 the unshifted, unsigned value) are set, or that they are all set. */
7021 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
7022 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
7023 {
7024 #ifdef OBJ_ELF
7025 /* Normally we would be stuck at this point, since we cannot store
7026 the absolute address that is the destination of the branch in the
7027 24 bits of the branch instruction. If however, we happen to know
7028 that the destination of the branch is in the same section as the
7029 branch instruciton itself, then we can compute the relocation for
7030 ourselves and not have to bother the linker with it.
7031
7032 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
7033 because I have not worked out how to do this for OBJ_COFF or
7034 target_oabi. */
7035 if (! target_oabi
7036 && fixP->fx_addsy != NULL
7037 && S_IS_DEFINED (fixP->fx_addsy)
7038 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
7039 {
7040 /* Get pc relative value to go into the branch. */
7041 value = * val;
7042
7043 /* Permit a backward branch provided that enough bits
7044 are set. Allow a forwards branch, provided that
7045 enough bits are clear. */
7046 if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
7047 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
7048 fixP->fx_done = 1;
7049 }
7050
7051 if (! fixP->fx_done)
7052 #endif
7053 as_bad_where (fixP->fx_file, fixP->fx_line,
7054 _("gas can't handle same-section branch dest >= 0x04000000"));
7055 }
7056
7057 value >>= 2;
7058 value += SEXT24 (newval);
7059
7060 if ( (value & ~ ((offsetT) 0xffffff)) != 0
7061 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
7062 as_bad_where (fixP->fx_file, fixP->fx_line,
7063 _("out of range branch"));
7064
7065 newval = (value & 0x00ffffff) | (newval & 0xff000000);
7066 md_number_to_chars (buf, newval, INSN_SIZE);
7067 break;
7068
7069 case BFD_RELOC_ARM_PCREL_BLX:
7070 {
7071 offsetT hbit;
7072 newval = md_chars_to_number (buf, INSN_SIZE);
7073
7074 #ifdef OBJ_ELF
7075 if (! target_oabi)
7076 value = fixP->fx_offset;
7077 #endif
7078 hbit = (value >> 1) & 1;
7079 value = (value >> 2) & 0x00ffffff;
7080 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
7081 newval = value | (newval & 0xfe000000) | (hbit << 24);
7082 md_number_to_chars (buf, newval, INSN_SIZE);
7083 }
7084 break;
7085
7086 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
7087 newval = md_chars_to_number (buf, THUMB_SIZE);
7088 {
7089 addressT diff = (newval & 0xff) << 1;
7090 if (diff & 0x100)
7091 diff |= ~0xff;
7092
7093 value += diff;
7094 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
7095 as_bad_where (fixP->fx_file, fixP->fx_line,
7096 _("Branch out of range"));
7097 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
7098 }
7099 md_number_to_chars (buf, newval, THUMB_SIZE);
7100 break;
7101
7102 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
7103 newval = md_chars_to_number (buf, THUMB_SIZE);
7104 {
7105 addressT diff = (newval & 0x7ff) << 1;
7106 if (diff & 0x800)
7107 diff |= ~0x7ff;
7108
7109 value += diff;
7110 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
7111 as_bad_where (fixP->fx_file, fixP->fx_line,
7112 _("Branch out of range"));
7113 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
7114 }
7115 md_number_to_chars (buf, newval, THUMB_SIZE);
7116 break;
7117
7118 case BFD_RELOC_THUMB_PCREL_BLX:
7119 case BFD_RELOC_THUMB_PCREL_BRANCH23:
7120 {
7121 offsetT newval2;
7122 addressT diff;
7123
7124 newval = md_chars_to_number (buf, THUMB_SIZE);
7125 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
7126 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
7127 if (diff & 0x400000)
7128 diff |= ~0x3fffff;
7129 #ifdef OBJ_ELF
7130 value = fixP->fx_offset;
7131 #endif
7132 value += diff;
7133 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
7134 as_bad_where (fixP->fx_file, fixP->fx_line,
7135 _("Branch with link out of range"));
7136
7137 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
7138 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
7139 md_number_to_chars (buf, newval, THUMB_SIZE);
7140 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
7141 }
7142 break;
7143
7144 case BFD_RELOC_8:
7145 if (fixP->fx_done || fixP->fx_pcrel)
7146 md_number_to_chars (buf, value, 1);
7147 #ifdef OBJ_ELF
7148 else if (!target_oabi)
7149 {
7150 value = fixP->fx_offset;
7151 md_number_to_chars (buf, value, 1);
7152 }
7153 #endif
7154 break;
7155
7156 case BFD_RELOC_16:
7157 if (fixP->fx_done || fixP->fx_pcrel)
7158 md_number_to_chars (buf, value, 2);
7159 #ifdef OBJ_ELF
7160 else if (!target_oabi)
7161 {
7162 value = fixP->fx_offset;
7163 md_number_to_chars (buf, value, 2);
7164 }
7165 #endif
7166 break;
7167
7168 #ifdef OBJ_ELF
7169 case BFD_RELOC_ARM_GOT32:
7170 case BFD_RELOC_ARM_GOTOFF:
7171 md_number_to_chars (buf, 0, 4);
7172 break;
7173 #endif
7174
7175 case BFD_RELOC_RVA:
7176 case BFD_RELOC_32:
7177 if (fixP->fx_done || fixP->fx_pcrel)
7178 md_number_to_chars (buf, value, 4);
7179 #ifdef OBJ_ELF
7180 else if (!target_oabi)
7181 {
7182 value = fixP->fx_offset;
7183 md_number_to_chars (buf, value, 4);
7184 }
7185 #endif
7186 break;
7187
7188 #ifdef OBJ_ELF
7189 case BFD_RELOC_ARM_PLT32:
7190 /* It appears the instruction is fully prepared at this point. */
7191 break;
7192 #endif
7193
7194 case BFD_RELOC_ARM_GOTPC:
7195 md_number_to_chars (buf, value, 4);
7196 break;
7197
7198 case BFD_RELOC_ARM_CP_OFF_IMM:
7199 sign = value >= 0;
7200 if (value < -1023 || value > 1023 || (value & 3))
7201 as_bad_where (fixP->fx_file, fixP->fx_line,
7202 _("Illegal value for co-processor offset"));
7203 if (value < 0)
7204 value = -value;
7205 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
7206 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
7207 md_number_to_chars (buf, newval, INSN_SIZE);
7208 break;
7209
7210 case BFD_RELOC_ARM_THUMB_OFFSET:
7211 newval = md_chars_to_number (buf, THUMB_SIZE);
7212 /* Exactly what ranges, and where the offset is inserted depends
7213 on the type of instruction, we can establish this from the
7214 top 4 bits. */
7215 switch (newval >> 12)
7216 {
7217 case 4: /* PC load. */
7218 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
7219 forced to zero for these loads, so we will need to round
7220 up the offset if the instruction address is not word
7221 aligned (since the final address produced must be, and
7222 we can only describe word-aligned immediate offsets). */
7223
7224 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
7225 as_bad_where (fixP->fx_file, fixP->fx_line,
7226 _("Invalid offset, target not word aligned (0x%08X)"),
7227 (unsigned int) (fixP->fx_frag->fr_address
7228 + fixP->fx_where + value));
7229
7230 if ((value + 2) & ~0x3fe)
7231 as_bad_where (fixP->fx_file, fixP->fx_line,
7232 _("Invalid offset, value too big (0x%08lX)"), value);
7233
7234 /* Round up, since pc will be rounded down. */
7235 newval |= (value + 2) >> 2;
7236 break;
7237
7238 case 9: /* SP load/store. */
7239 if (value & ~0x3fc)
7240 as_bad_where (fixP->fx_file, fixP->fx_line,
7241 _("Invalid offset, value too big (0x%08lX)"), value);
7242 newval |= value >> 2;
7243 break;
7244
7245 case 6: /* Word load/store. */
7246 if (value & ~0x7c)
7247 as_bad_where (fixP->fx_file, fixP->fx_line,
7248 _("Invalid offset, value too big (0x%08lX)"), value);
7249 newval |= value << 4; /* 6 - 2. */
7250 break;
7251
7252 case 7: /* Byte load/store. */
7253 if (value & ~0x1f)
7254 as_bad_where (fixP->fx_file, fixP->fx_line,
7255 _("Invalid offset, value too big (0x%08lX)"), value);
7256 newval |= value << 6;
7257 break;
7258
7259 case 8: /* Halfword load/store. */
7260 if (value & ~0x3e)
7261 as_bad_where (fixP->fx_file, fixP->fx_line,
7262 _("Invalid offset, value too big (0x%08lX)"), value);
7263 newval |= value << 5; /* 6 - 1. */
7264 break;
7265
7266 default:
7267 as_bad_where (fixP->fx_file, fixP->fx_line,
7268 "Unable to process relocation for thumb opcode: %lx",
7269 (unsigned long) newval);
7270 break;
7271 }
7272 md_number_to_chars (buf, newval, THUMB_SIZE);
7273 break;
7274
7275 case BFD_RELOC_ARM_THUMB_ADD:
7276 /* This is a complicated relocation, since we use it for all of
7277 the following immediate relocations:
7278
7279 3bit ADD/SUB
7280 8bit ADD/SUB
7281 9bit ADD/SUB SP word-aligned
7282 10bit ADD PC/SP word-aligned
7283
7284 The type of instruction being processed is encoded in the
7285 instruction field:
7286
7287 0x8000 SUB
7288 0x00F0 Rd
7289 0x000F Rs
7290 */
7291 newval = md_chars_to_number (buf, THUMB_SIZE);
7292 {
7293 int rd = (newval >> 4) & 0xf;
7294 int rs = newval & 0xf;
7295 int subtract = newval & 0x8000;
7296
7297 if (rd == REG_SP)
7298 {
7299 if (value & ~0x1fc)
7300 as_bad_where (fixP->fx_file, fixP->fx_line,
7301 _("Invalid immediate for stack address calculation"));
7302 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
7303 newval |= value >> 2;
7304 }
7305 else if (rs == REG_PC || rs == REG_SP)
7306 {
7307 if (subtract ||
7308 value & ~0x3fc)
7309 as_bad_where (fixP->fx_file, fixP->fx_line,
7310 _("Invalid immediate for address calculation (value = 0x%08lX)"),
7311 (unsigned long) value);
7312 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
7313 newval |= rd << 8;
7314 newval |= value >> 2;
7315 }
7316 else if (rs == rd)
7317 {
7318 if (value & ~0xff)
7319 as_bad_where (fixP->fx_file, fixP->fx_line,
7320 _("Invalid 8bit immediate"));
7321 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
7322 newval |= (rd << 8) | value;
7323 }
7324 else
7325 {
7326 if (value & ~0x7)
7327 as_bad_where (fixP->fx_file, fixP->fx_line,
7328 _("Invalid 3bit immediate"));
7329 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
7330 newval |= rd | (rs << 3) | (value << 6);
7331 }
7332 }
7333 md_number_to_chars (buf, newval, THUMB_SIZE);
7334 break;
7335
7336 case BFD_RELOC_ARM_THUMB_IMM:
7337 newval = md_chars_to_number (buf, THUMB_SIZE);
7338 switch (newval >> 11)
7339 {
7340 case 0x04: /* 8bit immediate MOV. */
7341 case 0x05: /* 8bit immediate CMP. */
7342 if (value < 0 || value > 255)
7343 as_bad_where (fixP->fx_file, fixP->fx_line,
7344 _("Invalid immediate: %ld is too large"),
7345 (long) value);
7346 newval |= value;
7347 break;
7348
7349 default:
7350 abort ();
7351 }
7352 md_number_to_chars (buf, newval, THUMB_SIZE);
7353 break;
7354
7355 case BFD_RELOC_ARM_THUMB_SHIFT:
7356 /* 5bit shift value (0..31). */
7357 if (value < 0 || value > 31)
7358 as_bad_where (fixP->fx_file, fixP->fx_line,
7359 _("Illegal Thumb shift value: %ld"), (long) value);
7360 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
7361 newval |= value << 6;
7362 md_number_to_chars (buf, newval, THUMB_SIZE);
7363 break;
7364
7365 case BFD_RELOC_VTABLE_INHERIT:
7366 case BFD_RELOC_VTABLE_ENTRY:
7367 fixP->fx_done = 0;
7368 return 1;
7369
7370 case BFD_RELOC_NONE:
7371 default:
7372 as_bad_where (fixP->fx_file, fixP->fx_line,
7373 _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
7374 }
7375
7376 return 1;
7377 }
7378
7379 /* Translate internal representation of relocation info to BFD target
7380 format. */
7381
7382 arelent *
7383 tc_gen_reloc (section, fixp)
7384 asection * section ATTRIBUTE_UNUSED;
7385 fixS * fixp;
7386 {
7387 arelent * reloc;
7388 bfd_reloc_code_real_type code;
7389
7390 reloc = (arelent *) xmalloc (sizeof (arelent));
7391
7392 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
7393 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
7394 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
7395
7396 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
7397 #ifndef OBJ_ELF
7398 if (fixp->fx_pcrel == 0)
7399 reloc->addend = fixp->fx_offset;
7400 else
7401 reloc->addend = fixp->fx_offset = reloc->address;
7402 #else /* OBJ_ELF */
7403 reloc->addend = fixp->fx_offset;
7404 #endif
7405
7406 switch (fixp->fx_r_type)
7407 {
7408 case BFD_RELOC_8:
7409 if (fixp->fx_pcrel)
7410 {
7411 code = BFD_RELOC_8_PCREL;
7412 break;
7413 }
7414
7415 case BFD_RELOC_16:
7416 if (fixp->fx_pcrel)
7417 {
7418 code = BFD_RELOC_16_PCREL;
7419 break;
7420 }
7421
7422 case BFD_RELOC_32:
7423 if (fixp->fx_pcrel)
7424 {
7425 code = BFD_RELOC_32_PCREL;
7426 break;
7427 }
7428
7429 case BFD_RELOC_ARM_PCREL_BRANCH:
7430 case BFD_RELOC_ARM_PCREL_BLX:
7431 case BFD_RELOC_RVA:
7432 case BFD_RELOC_THUMB_PCREL_BRANCH9:
7433 case BFD_RELOC_THUMB_PCREL_BRANCH12:
7434 case BFD_RELOC_THUMB_PCREL_BRANCH23:
7435 case BFD_RELOC_THUMB_PCREL_BLX:
7436 case BFD_RELOC_VTABLE_ENTRY:
7437 case BFD_RELOC_VTABLE_INHERIT:
7438 code = fixp->fx_r_type;
7439 break;
7440
7441 case BFD_RELOC_ARM_LITERAL:
7442 case BFD_RELOC_ARM_HWLITERAL:
7443 /* If this is called then the a literal has been referenced across
7444 a section boundary - possibly due to an implicit dump. */
7445 as_bad_where (fixp->fx_file, fixp->fx_line,
7446 _("Literal referenced across section boundary (Implicit dump?)"));
7447 return NULL;
7448
7449 #ifdef OBJ_ELF
7450 case BFD_RELOC_ARM_GOT32:
7451 case BFD_RELOC_ARM_GOTOFF:
7452 case BFD_RELOC_ARM_PLT32:
7453 code = fixp->fx_r_type;
7454 break;
7455 #endif
7456
7457 case BFD_RELOC_ARM_IMMEDIATE:
7458 as_bad_where (fixp->fx_file, fixp->fx_line,
7459 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
7460 fixp->fx_r_type);
7461 return NULL;
7462
7463 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
7464 as_bad_where (fixp->fx_file, fixp->fx_line,
7465 _("ADRL used for a symbol not defined in the same file"));
7466 return NULL;
7467
7468 case BFD_RELOC_ARM_OFFSET_IMM:
7469 as_bad_where (fixp->fx_file, fixp->fx_line,
7470 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
7471 fixp->fx_r_type);
7472 return NULL;
7473
7474 default:
7475 {
7476 char * type;
7477
7478 switch (fixp->fx_r_type)
7479 {
7480 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
7481 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
7482 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
7483 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
7484 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
7485 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
7486 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
7487 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
7488 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
7489 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
7490 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
7491 default: type = _("<unknown>"); break;
7492 }
7493 as_bad_where (fixp->fx_file, fixp->fx_line,
7494 _("Cannot represent %s relocation in this object file format"),
7495 type);
7496 return NULL;
7497 }
7498 }
7499
7500 #ifdef OBJ_ELF
7501 if (code == BFD_RELOC_32_PCREL
7502 && GOT_symbol
7503 && fixp->fx_addsy == GOT_symbol)
7504 {
7505 code = BFD_RELOC_ARM_GOTPC;
7506 reloc->addend = fixp->fx_offset = reloc->address;
7507 }
7508 #endif
7509
7510 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
7511
7512 if (reloc->howto == NULL)
7513 {
7514 as_bad_where (fixp->fx_file, fixp->fx_line,
7515 _("Can not represent %s relocation in this object file format"),
7516 bfd_get_reloc_code_name (code));
7517 return NULL;
7518 }
7519
7520 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
7521 vtable entry to be used in the relocation's section offset. */
7522 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
7523 reloc->address = fixp->fx_offset;
7524
7525 return reloc;
7526 }
7527
7528 int
7529 md_estimate_size_before_relax (fragP, segtype)
7530 fragS * fragP ATTRIBUTE_UNUSED;
7531 segT segtype ATTRIBUTE_UNUSED;
7532 {
7533 as_fatal (_("md_estimate_size_before_relax\n"));
7534 return 1;
7535 }
7536
7537 static void
7538 output_inst PARAMS ((void))
7539 {
7540 char * to = NULL;
7541
7542 if (inst.error)
7543 {
7544 as_bad (inst.error);
7545 return;
7546 }
7547
7548 to = frag_more (inst.size);
7549
7550 if (thumb_mode && (inst.size > THUMB_SIZE))
7551 {
7552 assert (inst.size == (2 * THUMB_SIZE));
7553 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
7554 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
7555 }
7556 else if (inst.size > INSN_SIZE)
7557 {
7558 assert (inst.size == (2 * INSN_SIZE));
7559 md_number_to_chars (to, inst.instruction, INSN_SIZE);
7560 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
7561 }
7562 else
7563 md_number_to_chars (to, inst.instruction, inst.size);
7564
7565 if (inst.reloc.type != BFD_RELOC_NONE)
7566 fix_new_arm (frag_now, to - frag_now->fr_literal,
7567 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
7568 inst.reloc.type);
7569
7570 #ifdef OBJ_ELF
7571 dwarf2_emit_insn (inst.size);
7572 #endif
7573 }
7574
7575 void
7576 md_assemble (str)
7577 char * str;
7578 {
7579 char c;
7580 char * p;
7581 char * q;
7582 char * start;
7583
7584 /* Align the instruction.
7585 This may not be the right thing to do but ... */
7586 #if 0
7587 arm_align (2, 0);
7588 #endif
7589 listing_prev_line (); /* Defined in listing.h. */
7590
7591 /* Align the previous label if needed. */
7592 if (last_label_seen != NULL)
7593 {
7594 symbol_set_frag (last_label_seen, frag_now);
7595 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
7596 S_SET_SEGMENT (last_label_seen, now_seg);
7597 }
7598
7599 memset (&inst, '\0', sizeof (inst));
7600 inst.reloc.type = BFD_RELOC_NONE;
7601
7602 skip_whitespace (str);
7603
7604 /* Scan up to the end of the op-code, which must end in white space or
7605 end of string. */
7606 for (start = p = str; *p != '\0'; p++)
7607 if (*p == ' ')
7608 break;
7609
7610 if (p == str)
7611 {
7612 as_bad (_("No operator -- statement `%s'\n"), str);
7613 return;
7614 }
7615
7616 if (thumb_mode)
7617 {
7618 CONST struct thumb_opcode * opcode;
7619
7620 c = *p;
7621 *p = '\0';
7622 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
7623 *p = c;
7624
7625 if (opcode)
7626 {
7627 /* Check that this instruction is supported for this CPU. */
7628 if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0)
7629 {
7630 as_bad (_("selected processor does not support this opcode"));
7631 return;
7632 }
7633
7634 inst.instruction = opcode->value;
7635 inst.size = opcode->size;
7636 (*opcode->parms) (p);
7637 output_inst ();
7638 return;
7639 }
7640 }
7641 else
7642 {
7643 CONST struct asm_opcode * opcode;
7644 unsigned long cond_code;
7645
7646 inst.size = INSN_SIZE;
7647 /* P now points to the end of the opcode, probably white space, but we
7648 have to break the opcode up in case it contains condionals and flags;
7649 keep trying with progressively smaller basic instructions until one
7650 matches, or we run out of opcode. */
7651 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
7652
7653 for (; q != str; q--)
7654 {
7655 c = *q;
7656 *q = '\0';
7657
7658 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
7659 *q = c;
7660
7661 if (opcode && opcode->template)
7662 {
7663 unsigned long flag_bits = 0;
7664 char * r;
7665
7666 /* Check that this instruction is supported for this CPU. */
7667 if ((opcode->variants & cpu_variant) == 0)
7668 goto try_shorter;
7669
7670 inst.instruction = opcode->value;
7671 if (q == p) /* Just a simple opcode. */
7672 {
7673 if (opcode->comp_suffix)
7674 {
7675 if (*opcode->comp_suffix != '\0')
7676 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
7677 str, opcode->comp_suffix);
7678 else
7679 /* Not a conditional instruction. */
7680 (*opcode->parms) (q, 0);
7681 }
7682 else
7683 {
7684 /* A conditional instruction with default condition. */
7685 inst.instruction |= COND_ALWAYS;
7686 (*opcode->parms) (q, 0);
7687 }
7688 output_inst ();
7689 return;
7690 }
7691
7692 /* Not just a simple opcode. Check if extra is a
7693 conditional. */
7694 r = q;
7695 if (p - r >= 2)
7696 {
7697 CONST struct asm_cond *cond;
7698 char d = *(r + 2);
7699
7700 *(r + 2) = '\0';
7701 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
7702 *(r + 2) = d;
7703 if (cond)
7704 {
7705 if (cond->value == 0xf0000000)
7706 as_tsktsk (
7707 _("Warning: Use of the 'nv' conditional is deprecated\n"));
7708
7709 cond_code = cond->value;
7710 r += 2;
7711 }
7712 else
7713 cond_code = COND_ALWAYS;
7714 }
7715 else
7716 cond_code = COND_ALWAYS;
7717
7718 /* Apply the conditional, or complain it's not allowed. */
7719 if (opcode->comp_suffix && *opcode->comp_suffix == '\0')
7720 {
7721 /* Instruction isn't conditional. */
7722 if (cond_code != COND_ALWAYS)
7723 {
7724 as_bad (_("Opcode `%s' is unconditional\n"), str);
7725 return;
7726 }
7727 }
7728 else
7729 /* Instruction is conditional: set the condition into it. */
7730 inst.instruction |= cond_code;
7731
7732 /* If there is a compulsory suffix, it should come here
7733 before any optional flags. */
7734 if (opcode->comp_suffix && *opcode->comp_suffix != '\0')
7735 {
7736 CONST char *s = opcode->comp_suffix;
7737
7738 while (*s)
7739 {
7740 inst.suffix++;
7741 if (*r == *s)
7742 break;
7743 s++;
7744 }
7745
7746 if (*s == '\0')
7747 {
7748 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
7749 str, opcode->comp_suffix);
7750 return;
7751 }
7752
7753 r++;
7754 }
7755
7756 /* The remainder, if any should now be flags for the instruction;
7757 Scan these checking each one found with the opcode. */
7758 if (r != p)
7759 {
7760 char d;
7761 CONST struct asm_flg *flag = opcode->flags;
7762
7763 if (flag)
7764 {
7765 int flagno;
7766
7767 d = *p;
7768 *p = '\0';
7769
7770 for (flagno = 0; flag[flagno].template; flagno++)
7771 {
7772 if (streq (r, flag[flagno].template))
7773 {
7774 flag_bits |= flag[flagno].set_bits;
7775 break;
7776 }
7777 }
7778
7779 *p = d;
7780 if (! flag[flagno].template)
7781 goto try_shorter;
7782 }
7783 else
7784 goto try_shorter;
7785 }
7786
7787 (*opcode->parms) (p, flag_bits);
7788 output_inst ();
7789 return;
7790 }
7791
7792 try_shorter:
7793 ;
7794 }
7795 }
7796
7797 /* It wasn't an instruction, but it might be a register alias of the form
7798 alias .req reg. */
7799 q = p;
7800 skip_whitespace (q);
7801
7802 c = *p;
7803 *p = '\0';
7804
7805 if (*q && !strncmp (q, ".req ", 4))
7806 {
7807 int reg;
7808 char * copy_of_str;
7809 char * r;
7810
7811 #ifdef IGNORE_OPCODE_CASE
7812 str = original_case_string;
7813 #endif
7814 copy_of_str = str;
7815
7816 q += 4;
7817 skip_whitespace (q);
7818
7819 for (r = q; *r != '\0'; r++)
7820 if (*r == ' ')
7821 break;
7822
7823 if (r != q)
7824 {
7825 int regnum;
7826 char d = *r;
7827
7828 *r = '\0';
7829 regnum = arm_reg_parse (& q);
7830 *r = d;
7831
7832 reg = arm_reg_parse (& str);
7833
7834 if (reg == FAIL)
7835 {
7836 if (regnum != FAIL)
7837 insert_reg_alias (str, regnum);
7838 else
7839 as_warn (_("register '%s' does not exist\n"), q);
7840 }
7841 else if (regnum != FAIL)
7842 {
7843 if (reg != regnum)
7844 as_warn (_("ignoring redefinition of register alias '%s'"),
7845 copy_of_str);
7846
7847 /* Do not warn about redefinitions to the same alias. */
7848 }
7849 else
7850 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
7851 copy_of_str, q);
7852 }
7853 else
7854 as_warn (_("ignoring incomplete .req pseuso op"));
7855
7856 *p = c;
7857 return;
7858 }
7859
7860 *p = c;
7861 as_bad (_("bad instruction `%s'"), start);
7862 }
7863
7864 /* md_parse_option
7865 Invocation line includes a switch not recognized by the base assembler.
7866 See if it's a processor-specific option. These are:
7867 Cpu variants, the arm part is optional:
7868 -m[arm]1 Currently not supported.
7869 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
7870 -m[arm]3 Arm 3 processor
7871 -m[arm]6[xx], Arm 6 processors
7872 -m[arm]7[xx][t][[d]m] Arm 7 processors
7873 -m[arm]8[10] Arm 8 processors
7874 -m[arm]9[20][tdmi] Arm 9 processors
7875 -mstrongarm[110[0]] StrongARM processors
7876 -mxscale XScale processors
7877 -m[arm]v[2345[t[e]]] Arm architectures
7878 -mall All (except the ARM1)
7879 FP variants:
7880 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
7881 -mfpe-old (No float load/store multiples)
7882 -mno-fpu Disable all floating point instructions
7883 Run-time endian selection:
7884 -EB big endian cpu
7885 -EL little endian cpu
7886 ARM Procedure Calling Standard:
7887 -mapcs-32 32 bit APCS
7888 -mapcs-26 26 bit APCS
7889 -mapcs-float Pass floats in float regs
7890 -mapcs-reentrant Position independent code
7891 -mthumb-interwork Code supports Arm/Thumb interworking
7892 -matpcs ARM/Thumb Procedure Call Standard
7893 -moabi Old ELF ABI */
7894
7895 CONST char * md_shortopts = "m:k";
7896
7897 struct option md_longopts[] =
7898 {
7899 #ifdef ARM_BI_ENDIAN
7900 #define OPTION_EB (OPTION_MD_BASE + 0)
7901 {"EB", no_argument, NULL, OPTION_EB},
7902 #define OPTION_EL (OPTION_MD_BASE + 1)
7903 {"EL", no_argument, NULL, OPTION_EL},
7904 #ifdef OBJ_ELF
7905 #define OPTION_OABI (OPTION_MD_BASE +2)
7906 {"oabi", no_argument, NULL, OPTION_OABI},
7907 #endif
7908 #endif
7909 {NULL, no_argument, NULL, 0}
7910 };
7911
7912 size_t md_longopts_size = sizeof (md_longopts);
7913
7914 int
7915 md_parse_option (c, arg)
7916 int c;
7917 char * arg;
7918 {
7919 char * str = arg;
7920
7921 switch (c)
7922 {
7923 #ifdef ARM_BI_ENDIAN
7924 case OPTION_EB:
7925 target_big_endian = 1;
7926 break;
7927 case OPTION_EL:
7928 target_big_endian = 0;
7929 break;
7930 #endif
7931
7932 case 'm':
7933 switch (*str)
7934 {
7935 case 'f':
7936 if (streq (str, "fpa10"))
7937 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
7938 else if (streq (str, "fpa11"))
7939 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
7940 else if (streq (str, "fpe-old"))
7941 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
7942 else
7943 goto bad;
7944 break;
7945
7946 case 'n':
7947 if (streq (str, "no-fpu"))
7948 cpu_variant &= ~FPU_ALL;
7949 break;
7950
7951 #ifdef OBJ_ELF
7952 case 'o':
7953 if (streq (str, "oabi"))
7954 target_oabi = true;
7955 break;
7956 #endif
7957
7958 case 't':
7959 /* Limit assembler to generating only Thumb instructions: */
7960 if (streq (str, "thumb"))
7961 {
7962 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_EXT_THUMB;
7963 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
7964 thumb_mode = 1;
7965 }
7966 else if (streq (str, "thumb-interwork"))
7967 {
7968 if ((cpu_variant & ARM_EXT_THUMB) == 0)
7969 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T;
7970 #if defined OBJ_COFF || defined OBJ_ELF
7971 support_interwork = true;
7972 #endif
7973 }
7974 else
7975 goto bad;
7976 break;
7977
7978 default:
7979 if (streq (str, "all"))
7980 {
7981 cpu_variant = ARM_ALL | FPU_ALL;
7982 return 1;
7983 }
7984 #if defined OBJ_COFF || defined OBJ_ELF
7985 if (! strncmp (str, "apcs-", 5))
7986 {
7987 /* GCC passes on all command line options starting "-mapcs-..."
7988 to us, so we must parse them here. */
7989
7990 str += 5;
7991
7992 if (streq (str, "32"))
7993 {
7994 uses_apcs_26 = false;
7995 return 1;
7996 }
7997 else if (streq (str, "26"))
7998 {
7999 uses_apcs_26 = true;
8000 return 1;
8001 }
8002 else if (streq (str, "frame"))
8003 {
8004 /* Stack frames are being generated - does not affect
8005 linkage of code. */
8006 return 1;
8007 }
8008 else if (streq (str, "stack-check"))
8009 {
8010 /* Stack checking is being performed - does not affect
8011 linkage, but does require that the functions
8012 __rt_stkovf_split_small and __rt_stkovf_split_big be
8013 present in the final link. */
8014
8015 return 1;
8016 }
8017 else if (streq (str, "float"))
8018 {
8019 /* Floating point arguments are being passed in the floating
8020 point registers. This does affect linking, since this
8021 version of the APCS is incompatible with the version that
8022 passes floating points in the integer registers. */
8023
8024 uses_apcs_float = true;
8025 return 1;
8026 }
8027 else if (streq (str, "reentrant"))
8028 {
8029 /* Reentrant code has been generated. This does affect
8030 linking, since there is no point in linking reentrant/
8031 position independent code with absolute position code. */
8032 pic_code = true;
8033 return 1;
8034 }
8035
8036 as_bad (_("Unrecognised APCS switch -m%s"), arg);
8037 return 0;
8038 }
8039
8040 if (! strcmp (str, "atpcs"))
8041 {
8042 atpcs = true;
8043 return 1;
8044 }
8045 #endif
8046 /* Strip off optional "arm". */
8047 if (! strncmp (str, "arm", 3))
8048 str += 3;
8049
8050 switch (*str)
8051 {
8052 case '1':
8053 if (streq (str, "1"))
8054 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
8055 else
8056 goto bad;
8057 break;
8058
8059 case '2':
8060 if (streq (str, "2"))
8061 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
8062 else if (streq (str, "250"))
8063 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
8064 else
8065 goto bad;
8066 break;
8067
8068 case '3':
8069 if (streq (str, "3"))
8070 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
8071 else
8072 goto bad;
8073 break;
8074
8075 case '6':
8076 switch (strtol (str, NULL, 10))
8077 {
8078 case 6:
8079 case 60:
8080 case 600:
8081 case 610:
8082 case 620:
8083 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
8084 break;
8085 default:
8086 goto bad;
8087 }
8088 break;
8089
8090 case '7':
8091 /* Eat the processor name. */
8092 switch (strtol (str, & str, 10))
8093 {
8094 case 7:
8095 case 70:
8096 case 700:
8097 case 710:
8098 case 720:
8099 case 7100:
8100 case 7500:
8101 break;
8102 default:
8103 goto bad;
8104 }
8105 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
8106 for (; *str; str++)
8107 {
8108 switch (*str)
8109 {
8110 case 't':
8111 cpu_variant |= ARM_ARCH_V4T;
8112 break;
8113
8114 case 'm':
8115 cpu_variant |= ARM_EXT_LONGMUL;
8116 break;
8117
8118 case 'f': /* fe => fp enabled cpu. */
8119 if (str[1] == 'e')
8120 ++ str;
8121 else
8122 goto bad;
8123
8124 case 'c': /* Left over from 710c processor name. */
8125 case 'd': /* Debug. */
8126 case 'i': /* Embedded ICE. */
8127 /* Included for completeness in ARM processor naming. */
8128 break;
8129
8130 default:
8131 goto bad;
8132 }
8133 }
8134 break;
8135
8136 case '8':
8137 if (streq (str, "8") || streq (str, "810"))
8138 cpu_variant = (cpu_variant & ~ARM_ANY)
8139 | ARM_8 | ARM_ARCH_V4;
8140 else
8141 goto bad;
8142 break;
8143
8144 case '9':
8145 if (streq (str, "9"))
8146 cpu_variant = (cpu_variant & ~ARM_ANY)
8147 | ARM_9 | ARM_ARCH_V4T;
8148 else if (streq (str, "920"))
8149 cpu_variant = (cpu_variant & ~ARM_ANY)
8150 | ARM_9 | ARM_ARCH_V4;
8151 else if (streq (str, "920t"))
8152 cpu_variant = (cpu_variant & ~ARM_ANY)
8153 | ARM_9 | ARM_ARCH_V4T;
8154 else if (streq (str, "9tdmi"))
8155 cpu_variant = (cpu_variant & ~ARM_ANY)
8156 | ARM_9 | ARM_ARCH_V4T;
8157 else
8158 goto bad;
8159 break;
8160
8161 case 's':
8162 if (streq (str, "strongarm")
8163 || streq (str, "strongarm110")
8164 || streq (str, "strongarm1100"))
8165 cpu_variant = (cpu_variant & ~ARM_ANY)
8166 | ARM_8 | ARM_ARCH_V4;
8167 else
8168 goto bad;
8169 break;
8170
8171 case 'x':
8172 if (streq (str, "xscale"))
8173 cpu_variant = ARM_9 | ARM_ARCH_XSCALE;
8174 else
8175 goto bad;
8176 break;
8177
8178 case 'v':
8179 /* Select variant based on architecture rather than
8180 processor. */
8181 switch (*++str)
8182 {
8183 case '2':
8184 switch (*++str)
8185 {
8186 case 'a':
8187 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
8188 break;
8189 case 0:
8190 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
8191 break;
8192 default:
8193 as_bad (_("Invalid architecture variant -m%s"), arg);
8194 break;
8195 }
8196 break;
8197
8198 case '3':
8199 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
8200
8201 switch (*++str)
8202 {
8203 case 'm': cpu_variant |= ARM_EXT_LONGMUL; break;
8204 case 0: break;
8205 default:
8206 as_bad (_("Invalid architecture variant -m%s"), arg);
8207 break;
8208 }
8209 break;
8210
8211 case '4':
8212 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCH_V4;
8213
8214 switch (*++str)
8215 {
8216 case 't': cpu_variant |= ARM_EXT_THUMB; break;
8217 case 0: break;
8218 default:
8219 as_bad (_("Invalid architecture variant -m%s"), arg);
8220 break;
8221 }
8222 break;
8223
8224 case '5':
8225 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V5;
8226 switch (*++str)
8227 {
8228 case 't': cpu_variant |= ARM_EXT_THUMB; break;
8229 case 'e': cpu_variant |= ARM_EXT_V5E; break;
8230 case 0: break;
8231 default:
8232 as_bad (_("Invalid architecture variant -m%s"), arg);
8233 break;
8234 }
8235 break;
8236
8237 default:
8238 as_bad (_("Invalid architecture variant -m%s"), arg);
8239 break;
8240 }
8241 break;
8242
8243 default:
8244 bad:
8245 as_bad (_("Invalid processor variant -m%s"), arg);
8246 return 0;
8247 }
8248 }
8249 break;
8250
8251 #if defined OBJ_ELF || defined OBJ_COFF
8252 case 'k':
8253 pic_code = 1;
8254 break;
8255 #endif
8256
8257 default:
8258 return 0;
8259 }
8260
8261 return 1;
8262 }
8263
8264 void
8265 md_show_usage (fp)
8266 FILE * fp;
8267 {
8268 fprintf (fp, _("\
8269 ARM Specific Assembler Options:\n\
8270 -m[arm][<processor name>] select processor variant\n\
8271 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
8272 -mthumb only allow Thumb instructions\n\
8273 -mthumb-interwork mark the assembled code as supporting interworking\n\
8274 -mall allow any instruction\n\
8275 -mfpa10, -mfpa11 select floating point architecture\n\
8276 -mfpe-old don't allow floating-point multiple instructions\n\
8277 -mno-fpu don't allow any floating-point instructions.\n\
8278 -k generate PIC code.\n"));
8279 #if defined OBJ_COFF || defined OBJ_ELF
8280 fprintf (fp, _("\
8281 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
8282 -matpcs use ARM/Thumb Procedure Calling Standard\n\
8283 -mapcs-float floating point args are passed in FP regs\n\
8284 -mapcs-reentrant the code is position independent/reentrant\n"));
8285 #endif
8286 #ifdef OBJ_ELF
8287 fprintf (fp, _("\
8288 -moabi support the old ELF ABI\n"));
8289 #endif
8290 #ifdef ARM_BI_ENDIAN
8291 fprintf (fp, _("\
8292 -EB assemble code for a big endian cpu\n\
8293 -EL assemble code for a little endian cpu\n"));
8294 #endif
8295 }
8296
8297 /* We need to be able to fix up arbitrary expressions in some statements.
8298 This is so that we can handle symbols that are an arbitrary distance from
8299 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
8300 which returns part of an address in a form which will be valid for
8301 a data instruction. We do this by pushing the expression into a symbol
8302 in the expr_section, and creating a fix for that. */
8303
8304 static void
8305 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
8306 fragS * frag;
8307 int where;
8308 short int size;
8309 expressionS * exp;
8310 int pc_rel;
8311 int reloc;
8312 {
8313 fixS * new_fix;
8314 arm_fix_data * arm_data;
8315
8316 switch (exp->X_op)
8317 {
8318 case O_constant:
8319 case O_symbol:
8320 case O_add:
8321 case O_subtract:
8322 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
8323 break;
8324
8325 default:
8326 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
8327 pc_rel, reloc);
8328 break;
8329 }
8330
8331 /* Mark whether the fix is to a THUMB instruction, or an ARM
8332 instruction. */
8333 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
8334 new_fix->tc_fix_data = (PTR) arm_data;
8335 arm_data->thumb_mode = thumb_mode;
8336
8337 return;
8338 }
8339
8340 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
8341
8342 void
8343 cons_fix_new_arm (frag, where, size, exp)
8344 fragS * frag;
8345 int where;
8346 int size;
8347 expressionS * exp;
8348 {
8349 bfd_reloc_code_real_type type;
8350 int pcrel = 0;
8351
8352 /* Pick a reloc.
8353 FIXME: @@ Should look at CPU word size. */
8354 switch (size)
8355 {
8356 case 1:
8357 type = BFD_RELOC_8;
8358 break;
8359 case 2:
8360 type = BFD_RELOC_16;
8361 break;
8362 case 4:
8363 default:
8364 type = BFD_RELOC_32;
8365 break;
8366 case 8:
8367 type = BFD_RELOC_64;
8368 break;
8369 }
8370
8371 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
8372 }
8373
8374 /* A good place to do this, although this was probably not intended
8375 for this kind of use. We need to dump the literal pool before
8376 references are made to a null symbol pointer. */
8377
8378 void
8379 arm_cleanup ()
8380 {
8381 if (current_poolP == NULL)
8382 return;
8383
8384 /* Put it at the end of text section. */
8385 subseg_set (text_section, 0);
8386 s_ltorg (0);
8387 listing_prev_line ();
8388 }
8389
8390 void
8391 arm_start_line_hook ()
8392 {
8393 last_label_seen = NULL;
8394 }
8395
8396 void
8397 arm_frob_label (sym)
8398 symbolS * sym;
8399 {
8400 last_label_seen = sym;
8401
8402 ARM_SET_THUMB (sym, thumb_mode);
8403
8404 #if defined OBJ_COFF || defined OBJ_ELF
8405 ARM_SET_INTERWORK (sym, support_interwork);
8406 #endif
8407
8408 if (label_is_thumb_function_name)
8409 {
8410 /* When the address of a Thumb function is taken the bottom
8411 bit of that address should be set. This will allow
8412 interworking between Arm and Thumb functions to work
8413 correctly. */
8414
8415 THUMB_SET_FUNC (sym, 1);
8416
8417 label_is_thumb_function_name = false;
8418 }
8419 }
8420
8421 /* Adjust the symbol table. This marks Thumb symbols as distinct from
8422 ARM ones. */
8423
8424 void
8425 arm_adjust_symtab ()
8426 {
8427 #ifdef OBJ_COFF
8428 symbolS * sym;
8429
8430 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
8431 {
8432 if (ARM_IS_THUMB (sym))
8433 {
8434 if (THUMB_IS_FUNC (sym))
8435 {
8436 /* Mark the symbol as a Thumb function. */
8437 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
8438 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
8439 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
8440
8441 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
8442 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
8443 else
8444 as_bad (_("%s: unexpected function type: %d"),
8445 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
8446 }
8447 else switch (S_GET_STORAGE_CLASS (sym))
8448 {
8449 case C_EXT:
8450 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
8451 break;
8452 case C_STAT:
8453 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
8454 break;
8455 case C_LABEL:
8456 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
8457 break;
8458 default:
8459 /* Do nothing. */
8460 break;
8461 }
8462 }
8463
8464 if (ARM_IS_INTERWORK (sym))
8465 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
8466 }
8467 #endif
8468 #ifdef OBJ_ELF
8469 symbolS * sym;
8470 char bind;
8471
8472 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
8473 {
8474 if (ARM_IS_THUMB (sym))
8475 {
8476 elf_symbol_type * elf_sym;
8477
8478 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
8479 bind = ELF_ST_BIND (elf_sym);
8480
8481 /* If it's a .thumb_func, declare it as so,
8482 otherwise tag label as .code 16. */
8483 if (THUMB_IS_FUNC (sym))
8484 elf_sym->internal_elf_sym.st_info =
8485 ELF_ST_INFO (bind, STT_ARM_TFUNC);
8486 else
8487 elf_sym->internal_elf_sym.st_info =
8488 ELF_ST_INFO (bind, STT_ARM_16BIT);
8489 }
8490 }
8491 #endif
8492 }
8493
8494 int
8495 arm_data_in_code ()
8496 {
8497 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
8498 {
8499 *input_line_pointer = '/';
8500 input_line_pointer += 5;
8501 *input_line_pointer = 0;
8502 return 1;
8503 }
8504
8505 return 0;
8506 }
8507
8508 char *
8509 arm_canonicalize_symbol_name (name)
8510 char * name;
8511 {
8512 int len;
8513
8514 if (thumb_mode && (len = strlen (name)) > 5
8515 && streq (name + len - 5, "/data"))
8516 *(name + len - 5) = 0;
8517
8518 return name;
8519 }
8520
8521 boolean
8522 arm_validate_fix (fixP)
8523 fixS * fixP;
8524 {
8525 /* If the destination of the branch is a defined symbol which does not have
8526 the THUMB_FUNC attribute, then we must be calling a function which has
8527 the (interfacearm) attribute. We look for the Thumb entry point to that
8528 function and change the branch to refer to that function instead. */
8529 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
8530 && fixP->fx_addsy != NULL
8531 && S_IS_DEFINED (fixP->fx_addsy)
8532 && ! THUMB_IS_FUNC (fixP->fx_addsy))
8533 {
8534 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
8535 return true;
8536 }
8537
8538 return false;
8539 }
8540
8541 #ifdef OBJ_ELF
8542 /* Relocations against Thumb function names must be left unadjusted,
8543 so that the linker can use this information to correctly set the
8544 bottom bit of their addresses. The MIPS version of this function
8545 also prevents relocations that are mips-16 specific, but I do not
8546 know why it does this.
8547
8548 FIXME:
8549 There is one other problem that ought to be addressed here, but
8550 which currently is not: Taking the address of a label (rather
8551 than a function) and then later jumping to that address. Such
8552 addresses also ought to have their bottom bit set (assuming that
8553 they reside in Thumb code), but at the moment they will not. */
8554
8555 boolean
8556 arm_fix_adjustable (fixP)
8557 fixS * fixP;
8558 {
8559 if (fixP->fx_addsy == NULL)
8560 return 1;
8561
8562 /* Prevent all adjustments to global symbols. */
8563 if (S_IS_EXTERN (fixP->fx_addsy))
8564 return 0;
8565
8566 if (S_IS_WEAK (fixP->fx_addsy))
8567 return 0;
8568
8569 if (THUMB_IS_FUNC (fixP->fx_addsy)
8570 && fixP->fx_subsy == NULL)
8571 return 0;
8572
8573 /* We need the symbol name for the VTABLE entries. */
8574 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
8575 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
8576 return 0;
8577
8578 return 1;
8579 }
8580
8581 const char *
8582 elf32_arm_target_format ()
8583 {
8584 if (target_big_endian)
8585 {
8586 if (target_oabi)
8587 return "elf32-bigarm-oabi";
8588 else
8589 return "elf32-bigarm";
8590 }
8591 else
8592 {
8593 if (target_oabi)
8594 return "elf32-littlearm-oabi";
8595 else
8596 return "elf32-littlearm";
8597 }
8598 }
8599
8600 void
8601 armelf_frob_symbol (symp, puntp)
8602 symbolS * symp;
8603 int * puntp;
8604 {
8605 elf_frob_symbol (symp, puntp);
8606 }
8607
8608 int
8609 arm_force_relocation (fixp)
8610 struct fix * fixp;
8611 {
8612 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
8613 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
8614 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
8615 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
8616 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
8617 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
8618 return 1;
8619
8620 return 0;
8621 }
8622
8623 static bfd_reloc_code_real_type
8624 arm_parse_reloc ()
8625 {
8626 char id [16];
8627 char * ip;
8628 unsigned int i;
8629 static struct
8630 {
8631 char * str;
8632 int len;
8633 bfd_reloc_code_real_type reloc;
8634 }
8635 reloc_map[] =
8636 {
8637 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
8638 MAP ("(got)", BFD_RELOC_ARM_GOT32),
8639 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
8640 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
8641 branch instructions generated by GCC for PLT relocs. */
8642 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
8643 { NULL, 0, BFD_RELOC_UNUSED }
8644 #undef MAP
8645 };
8646
8647 for (i = 0, ip = input_line_pointer;
8648 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
8649 i++, ip++)
8650 id[i] = tolower (*ip);
8651
8652 for (i = 0; reloc_map[i].str; i++)
8653 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
8654 break;
8655
8656 input_line_pointer += reloc_map[i].len;
8657
8658 return reloc_map[i].reloc;
8659 }
8660
8661 static void
8662 s_arm_elf_cons (nbytes)
8663 int nbytes;
8664 {
8665 expressionS exp;
8666
8667 #ifdef md_flush_pending_output
8668 md_flush_pending_output ();
8669 #endif
8670
8671 if (is_it_end_of_statement ())
8672 {
8673 demand_empty_rest_of_line ();
8674 return;
8675 }
8676
8677 #ifdef md_cons_align
8678 md_cons_align (nbytes);
8679 #endif
8680
8681 do
8682 {
8683 bfd_reloc_code_real_type reloc;
8684
8685 expression (& exp);
8686
8687 if (exp.X_op == O_symbol
8688 && * input_line_pointer == '('
8689 && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
8690 {
8691 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
8692 int size = bfd_get_reloc_size (howto);
8693
8694 if (size > nbytes)
8695 as_bad ("%s relocations do not fit in %d bytes",
8696 howto->name, nbytes);
8697 else
8698 {
8699 register char *p = frag_more ((int) nbytes);
8700 int offset = nbytes - size;
8701
8702 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
8703 &exp, 0, reloc);
8704 }
8705 }
8706 else
8707 emit_expr (&exp, (unsigned int) nbytes);
8708 }
8709 while (*input_line_pointer++ == ',');
8710
8711 /* Put terminator back into stream. */
8712 input_line_pointer --;
8713 demand_empty_rest_of_line ();
8714 }
8715
8716 #endif /* OBJ_ELF */