2000-12-03 Kazu Hirata <kazu@hxi.com>
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
1 /* tc-arm.c -- Assemble for the ARM
2 Copyright (C) 1994, 95, 96, 97, 98, 1999, 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 /* ARM V5 count-leading-zeroes instruction (argument parse)
2832 CLZ{<cond>} <Rd>, <Rm>
2833 Condition defaults to COND_ALWAYS.
2834 Error if Rd or Rm are R15. */
2835
2836 static void
2837 do_clz (str, flags)
2838 char * str;
2839 unsigned long flags;
2840 {
2841 int rd, rm;
2842
2843 if (flags)
2844 {
2845 as_bad (BAD_FLAGS);
2846 return;
2847 }
2848
2849 skip_whitespace (str);
2850
2851 if (((rd = reg_required_here (& str, 12)) == FAIL)
2852 || (skip_past_comma (& str) == FAIL)
2853 || ((rm = reg_required_here (& str, 0)) == FAIL))
2854 inst.error = BAD_ARGS;
2855
2856 else if (rd == REG_PC || rm == REG_PC )
2857 inst.error = BAD_PC;
2858
2859 else
2860 end_of_line (str);
2861 }
2862
2863 /* ARM V5 (argument parse)
2864 LDC2{L} <coproc>, <CRd>, <addressing mode>
2865 STC2{L} <coproc>, <CRd>, <addressing mode>
2866 Instruction is not conditional, and has 0xf in the codition field.
2867 Otherwise, it's the same as LDC/STC. */
2868
2869 static void
2870 do_lstc2 (str, flags)
2871 char * str;
2872 unsigned long flags;
2873 {
2874 if (flags)
2875 inst.error = BAD_COND;
2876
2877 skip_whitespace (str);
2878
2879 if (co_proc_number (& str) == FAIL)
2880 {
2881 if (!inst.error)
2882 inst.error = BAD_ARGS;
2883 }
2884 else if (skip_past_comma (& str) == FAIL
2885 || cp_reg_required_here (& str, 12) == FAIL)
2886 {
2887 if (!inst.error)
2888 inst.error = BAD_ARGS;
2889 }
2890 else if (skip_past_comma (& str) == FAIL
2891 || cp_address_required_here (& str) == FAIL)
2892 {
2893 if (! inst.error)
2894 inst.error = BAD_ARGS;
2895 }
2896 else
2897 end_of_line (str);
2898 }
2899
2900 /* ARM V5 (argument parse)
2901 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
2902 Instruction is not conditional, and has 0xf in the condition field.
2903 Otherwise, it's the same as CDP. */
2904
2905 static void
2906 do_cdp2 (str, flags)
2907 char * str;
2908 unsigned long flags;
2909 {
2910 skip_whitespace (str);
2911
2912 if (co_proc_number (& str) == FAIL)
2913 {
2914 if (!inst.error)
2915 inst.error = BAD_ARGS;
2916 return;
2917 }
2918
2919 if (skip_past_comma (& str) == FAIL
2920 || cp_opc_expr (& str, 20,4) == FAIL)
2921 {
2922 if (!inst.error)
2923 inst.error = BAD_ARGS;
2924 return;
2925 }
2926
2927 if (skip_past_comma (& str) == FAIL
2928 || cp_reg_required_here (& str, 12) == FAIL)
2929 {
2930 if (!inst.error)
2931 inst.error = BAD_ARGS;
2932 return;
2933 }
2934
2935 if (skip_past_comma (& str) == FAIL
2936 || cp_reg_required_here (& str, 16) == FAIL)
2937 {
2938 if (!inst.error)
2939 inst.error = BAD_ARGS;
2940 return;
2941 }
2942
2943 if (skip_past_comma (& str) == FAIL
2944 || cp_reg_required_here (& str, 0) == FAIL)
2945 {
2946 if (!inst.error)
2947 inst.error = BAD_ARGS;
2948 return;
2949 }
2950
2951 if (skip_past_comma (& str) == SUCCESS)
2952 {
2953 if (cp_opc_expr (& str, 5, 3) == FAIL)
2954 {
2955 if (!inst.error)
2956 inst.error = BAD_ARGS;
2957 return;
2958 }
2959 }
2960
2961 if (flags)
2962 inst.error = BAD_FLAGS;
2963
2964 end_of_line (str);
2965 }
2966
2967 /* ARM V5 (argument parse)
2968 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
2969 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
2970 Instruction is not conditional, and has 0xf in the condition field.
2971 Otherwise, it's the same as MCR/MRC. */
2972
2973 static void
2974 do_co_reg2 (str, flags)
2975 char * str;
2976 unsigned long flags;
2977 {
2978 skip_whitespace (str);
2979
2980 if (co_proc_number (& str) == FAIL)
2981 {
2982 if (!inst.error)
2983 inst.error = BAD_ARGS;
2984 return;
2985 }
2986
2987 if (skip_past_comma (& str) == FAIL
2988 || cp_opc_expr (& str, 21, 3) == FAIL)
2989 {
2990 if (!inst.error)
2991 inst.error = BAD_ARGS;
2992 return;
2993 }
2994
2995 if (skip_past_comma (& str) == FAIL
2996 || reg_required_here (& str, 12) == FAIL)
2997 {
2998 if (!inst.error)
2999 inst.error = BAD_ARGS;
3000 return;
3001 }
3002
3003 if (skip_past_comma (& str) == FAIL
3004 || cp_reg_required_here (& str, 16) == FAIL)
3005 {
3006 if (!inst.error)
3007 inst.error = BAD_ARGS;
3008 return;
3009 }
3010
3011 if (skip_past_comma (& str) == FAIL
3012 || cp_reg_required_here (& str, 0) == FAIL)
3013 {
3014 if (!inst.error)
3015 inst.error = BAD_ARGS;
3016 return;
3017 }
3018
3019 if (skip_past_comma (& str) == SUCCESS)
3020 {
3021 if (cp_opc_expr (& str, 5, 3) == FAIL)
3022 {
3023 if (!inst.error)
3024 inst.error = BAD_ARGS;
3025 return;
3026 }
3027 }
3028
3029 if (flags)
3030 inst.error = BAD_COND;
3031
3032 end_of_line (str);
3033 }
3034
3035 /* THUMB V5 breakpoint instruction (argument parse)
3036 BKPT <immed_8>. */
3037
3038 static void
3039 do_t_bkpt (str)
3040 char * str;
3041 {
3042 expressionS expr;
3043 unsigned long number;
3044
3045 skip_whitespace (str);
3046
3047 /* Allow optional leading '#'. */
3048 if (is_immediate_prefix (*str))
3049 str ++;
3050
3051 memset (& expr, '\0', sizeof (expr));
3052 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
3053 {
3054 inst.error = _("bad or missing expression");
3055 return;
3056 }
3057
3058 number = expr.X_add_number;
3059
3060 /* Check it fits an 8 bit unsigned. */
3061 if (number != (number & 0xff))
3062 {
3063 inst.error = _("immediate value out of range");
3064 return;
3065 }
3066
3067 inst.instruction |= number;
3068
3069 end_of_line (str);
3070 }
3071
3072 /* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3073 Expects inst.instruction is set for BLX(1).
3074 Note: this is cloned from do_branch, and the reloc changed to be a
3075 new one that can cope with setting one extra bit (the H bit). */
3076
3077 static void
3078 do_branch25 (str, flags)
3079 char * str;
3080 unsigned long flags ATTRIBUTE_UNUSED;
3081 {
3082 if (my_get_expression (& inst.reloc.exp, & str))
3083 return;
3084
3085 #ifdef OBJ_ELF
3086 {
3087 char * save_in;
3088
3089 /* ScottB: February 5, 1998 */
3090 /* Check to see of PLT32 reloc required for the instruction. */
3091
3092 /* arm_parse_reloc() works on input_line_pointer.
3093 We actually want to parse the operands to the branch instruction
3094 passed in 'str'. Save the input pointer and restore it later. */
3095 save_in = input_line_pointer;
3096 input_line_pointer = str;
3097
3098 if (inst.reloc.exp.X_op == O_symbol
3099 && *str == '('
3100 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3101 {
3102 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3103 inst.reloc.pc_rel = 0;
3104 /* Modify str to point to after parsed operands, otherwise
3105 end_of_line() will complain about the (PLT) left in str. */
3106 str = input_line_pointer;
3107 }
3108 else
3109 {
3110 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
3111 inst.reloc.pc_rel = 1;
3112 }
3113
3114 input_line_pointer = save_in;
3115 }
3116 #else
3117 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
3118 inst.reloc.pc_rel = 1;
3119 #endif /* OBJ_ELF */
3120
3121 end_of_line (str);
3122 }
3123
3124 /* ARM V5 branch-link-exchange instruction (argument parse)
3125 BLX <target_addr> ie BLX(1)
3126 BLX{<condition>} <Rm> ie BLX(2)
3127 Unfortunately, there are two different opcodes for this mnemonic.
3128 So, the insns[].value is not used, and the code here zaps values
3129 into inst.instruction.
3130 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
3131
3132 static void
3133 do_blx (str, flags)
3134 char * str;
3135 unsigned long flags;
3136 {
3137 char * mystr = str;
3138 int rm;
3139
3140 if (flags)
3141 {
3142 as_bad (BAD_FLAGS);
3143 return;
3144 }
3145
3146 skip_whitespace (mystr);
3147 rm = reg_required_here (& mystr, 0);
3148
3149 /* The above may set inst.error. Ignore his opinion. */
3150 inst.error = 0;
3151
3152 if (rm != FAIL)
3153 {
3154 /* Arg is a register.
3155 Use the condition code our caller put in inst.instruction.
3156 Pass ourselves off as a BX with a funny opcode. */
3157 inst.instruction |= 0x012fff30;
3158 do_bx (str, flags);
3159 }
3160 else
3161 {
3162 /* This must be is BLX <target address>, no condition allowed. */
3163 if (inst.instruction != COND_ALWAYS)
3164 {
3165 inst.error = BAD_COND;
3166 return;
3167 }
3168
3169 inst.instruction = 0xfafffffe;
3170
3171 /* Process like a B/BL, but with a different reloc.
3172 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
3173 do_branch25 (str, flags);
3174 }
3175 }
3176
3177 /* ARM V5 Thumb BLX (argument parse)
3178 BLX <target_addr> which is BLX(1)
3179 BLX <Rm> which is BLX(2)
3180 Unfortunately, there are two different opcodes for this mnemonic.
3181 So, the tinsns[].value is not used, and the code here zaps values
3182 into inst.instruction. */
3183
3184 static void
3185 do_t_blx (str)
3186 char * str;
3187 {
3188 char * mystr = str;
3189 int rm;
3190
3191 skip_whitespace (mystr);
3192 inst.instruction = 0x4780;
3193
3194 /* Note that this call is to the ARM register recognizer. BLX(2)
3195 uses the ARM register space, not the Thumb one, so a call to
3196 thumb_reg() would be wrong. */
3197 rm = reg_required_here (& mystr, 3);
3198 inst.error = 0;
3199
3200 if (rm != FAIL)
3201 {
3202 /* It's BLX(2). The .instruction was zapped with rm & is final. */
3203 inst.size = 2;
3204 }
3205 else
3206 {
3207 /* No ARM register. This must be BLX(1). Change the .instruction. */
3208 inst.instruction = 0xf7ffeffe;
3209 inst.size = 4;
3210
3211 if (my_get_expression (& inst.reloc.exp, & mystr))
3212 return;
3213
3214 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
3215 inst.reloc.pc_rel = 1;
3216 }
3217
3218 end_of_line (mystr);
3219 }
3220
3221 /* ARM V5 breakpoint instruction (argument parse)
3222 BKPT <16 bit unsigned immediate>
3223 Instruction is not conditional.
3224 The bit pattern given in insns[] has the COND_ALWAYS condition,
3225 and it is an error if the caller tried to override that.
3226 Note "flags" is nonzero if a flag was supplied (which is an error). */
3227
3228 static void
3229 do_bkpt (str, flags)
3230 char * str;
3231 unsigned long flags;
3232 {
3233 expressionS expr;
3234 unsigned long number;
3235
3236 skip_whitespace (str);
3237
3238 /* Allow optional leading '#'. */
3239 if (is_immediate_prefix (* str))
3240 str++;
3241
3242 memset (& expr, '\0', sizeof (expr));
3243
3244 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
3245 {
3246 inst.error = _("bad or missing expression");
3247 return;
3248 }
3249
3250 number = expr.X_add_number;
3251
3252 /* Check it fits a 16 bit unsigned. */
3253 if (number != (number & 0xffff))
3254 {
3255 inst.error = _("immediate value out of range");
3256 return;
3257 }
3258
3259 /* Top 12 of 16 bits to bits 19:8. */
3260 inst.instruction |= (number & 0xfff0) << 4;
3261
3262 /* Bottom 4 of 16 bits to bits 3:0. */
3263 inst.instruction |= number & 0xf;
3264
3265 end_of_line (str);
3266
3267 if (flags)
3268 inst.error = BAD_FLAGS;
3269 }
3270
3271 /* Xscale multiply-accumulate (argument parse)
3272 MIAcc acc0,Rm,Rs
3273 MIAPHcc acc0,Rm,Rs
3274 MIAxycc acc0,Rm,Rs. */
3275
3276 static void
3277 do_mia (str, flags)
3278 char * str;
3279 unsigned long flags;
3280 {
3281 int rs;
3282 int rm;
3283
3284 if (flags)
3285 as_bad (BAD_FLAGS);
3286
3287 else if (accum0_required_here (& str) == FAIL)
3288 inst.error = ERR_NO_ACCUM;
3289
3290 else if (skip_past_comma (& str) == FAIL
3291 || (rm = reg_required_here (& str, 0)) == FAIL)
3292 inst.error = BAD_ARGS;
3293
3294 else if (skip_past_comma (& str) == FAIL
3295 || (rs = reg_required_here (& str, 12)) == FAIL)
3296 inst.error = BAD_ARGS;
3297
3298 /* inst.instruction has now been zapped with both rm and rs. */
3299 else if (rm == REG_PC || rs == REG_PC)
3300 inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */
3301
3302 else
3303 end_of_line (str);
3304 }
3305
3306 /* Xscale move-accumulator-register (argument parse)
3307
3308 MARcc acc0,RdLo,RdHi. */
3309
3310 static void
3311 do_mar (str, flags)
3312 char * str;
3313 unsigned long flags;
3314 {
3315 int rdlo, rdhi;
3316
3317 if (flags)
3318 as_bad (BAD_FLAGS);
3319
3320 else if (accum0_required_here (& str) == FAIL)
3321 inst.error = ERR_NO_ACCUM;
3322
3323 else if (skip_past_comma (& str) == FAIL
3324 || (rdlo = reg_required_here (& str, 12)) == FAIL)
3325 inst.error = BAD_ARGS;
3326
3327 else if (skip_past_comma (& str) == FAIL
3328 || (rdhi = reg_required_here (& str, 16)) == FAIL)
3329 inst.error = BAD_ARGS;
3330
3331 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3332 else if (rdlo == REG_PC || rdhi == REG_PC)
3333 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
3334
3335 else
3336 end_of_line (str);
3337 }
3338
3339 /* Xscale move-register-accumulator (argument parse)
3340
3341 MRAcc RdLo,RdHi,acc0. */
3342
3343 static void
3344 do_mra (str, flags)
3345 char * str;
3346 unsigned long flags;
3347 {
3348 int rdlo;
3349 int rdhi;
3350
3351 if (flags)
3352 {
3353 as_bad (BAD_FLAGS);
3354 return;
3355 }
3356
3357 skip_whitespace (str);
3358
3359 if ((rdlo = reg_required_here (& str, 12)) == FAIL)
3360 inst.error = BAD_ARGS;
3361
3362 else if (skip_past_comma (& str) == FAIL
3363 || (rdhi = reg_required_here (& str, 16)) == FAIL)
3364 inst.error = BAD_ARGS;
3365
3366 else if (skip_past_comma (& str) == FAIL
3367 || accum0_required_here (& str) == FAIL)
3368 inst.error = ERR_NO_ACCUM;
3369
3370 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3371 else if (rdlo == rdhi)
3372 inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */
3373
3374 else if (rdlo == REG_PC || rdhi == REG_PC)
3375 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
3376 else
3377 end_of_line (str);
3378 }
3379
3380 /* Xscale: Preload-Cache
3381
3382 PLD <addr_mode>
3383
3384 Syntactically, like LDR with B=1, W=0, L=1. */
3385
3386 static void
3387 do_pld (str, flags)
3388 char * str;
3389 unsigned long flags;
3390 {
3391 int rd;
3392
3393 if (flags)
3394 {
3395 as_bad (BAD_FLAGS);
3396 return;
3397 }
3398
3399 skip_whitespace (str);
3400
3401 if (* str != '[')
3402 {
3403 inst.error = _("'[' expected after PLD mnemonic");
3404 return;
3405 }
3406
3407 ++ str;
3408 skip_whitespace (str);
3409
3410 if ((rd = reg_required_here (& str, 16)) == FAIL)
3411 return;
3412
3413 skip_whitespace (str);
3414
3415 if (* str == ']')
3416 {
3417 /* [Rn], ... ? */
3418 ++ str;
3419 skip_whitespace (str);
3420
3421 if (skip_past_comma (& str) == SUCCESS)
3422 {
3423 if (ldst_extend (& str, 0) == FAIL)
3424 return;
3425 }
3426 else if (* str == '!') /* [Rn]! */
3427 {
3428 inst.error = _("writeback used in preload instruction");
3429 ++ str;
3430 }
3431 else /* [Rn] */
3432 inst.instruction |= INDEX_UP | PRE_INDEX;
3433 }
3434 else /* [Rn, ...] */
3435 {
3436 if (skip_past_comma (& str) == FAIL)
3437 {
3438 inst.error = _("pre-indexed expression expected");
3439 return;
3440 }
3441
3442 if (ldst_extend (& str, 0) == FAIL)
3443 return;
3444
3445 skip_whitespace (str);
3446
3447 if (* str != ']')
3448 {
3449 inst.error = _("missing ]");
3450 return;
3451 }
3452
3453 ++ str;
3454 skip_whitespace (str);
3455
3456 if (* str == '!') /* [Rn]! */
3457 {
3458 inst.error = _("writeback used in preload instruction");
3459 ++ str;
3460 }
3461
3462 inst.instruction |= PRE_INDEX;
3463 }
3464
3465 end_of_line (str);
3466 }
3467
3468 /* Xscale load-consecutive (argument parse)
3469 Mode is like LDRH.
3470
3471 LDRccD R, mode
3472 STRccD R, mode. */
3473
3474 static void
3475 do_ldrd (str, flags)
3476 char * str;
3477 unsigned long flags;
3478 {
3479 int rd;
3480 int rn;
3481
3482 if (flags != DOUBLE_LOAD_FLAG)
3483 {
3484 /* Change instruction pattern to normal ldr/str. */
3485 if (inst.instruction & 0x20)
3486 inst.instruction = (inst.instruction & COND_MASK) | 0x04000000; /* str */
3487 else
3488 inst.instruction = (inst.instruction & COND_MASK) | 0x04100000; /* ldr */
3489
3490 /* Perform a normal load/store instruction parse. */
3491 do_ldst (str, flags);
3492
3493 return;
3494 }
3495
3496 if ((cpu_variant & ARM_EXT_XSCALE) != ARM_EXT_XSCALE)
3497 {
3498 static char buff[128];
3499
3500 --str;
3501 while (isspace (*str))
3502 --str;
3503 str -= 4;
3504
3505 /* Deny all knowledge. */
3506 sprintf (buff, _("bad instruction '%.100s'"), str);
3507 inst.error = buff;
3508 return;
3509 }
3510
3511 skip_whitespace (str);
3512
3513 if ((rd = reg_required_here (& str, 12)) == FAIL)
3514 {
3515 inst.error = BAD_ARGS;
3516 return;
3517 }
3518
3519 if (skip_past_comma (& str) == FAIL
3520 || (rn = ld_mode_required_here (& str)) == FAIL)
3521 {
3522 if (!inst.error)
3523 inst.error = BAD_ARGS;
3524 return;
3525 }
3526
3527 /* inst.instruction has now been zapped with Rd and the addressing mode. */
3528 if (rd & 1) /* Unpredictable result if Rd is odd. */
3529 {
3530 inst.error = _("Destination register must be even");
3531 return;
3532 }
3533
3534 if (rd == REG_LR || rd == 12)
3535 {
3536 inst.error = _("r12 or r14 not allowed here");
3537 return;
3538 }
3539
3540 if (((rd == rn) || (rd + 1 == rn))
3541 &&
3542 ((inst.instruction & WRITE_BACK)
3543 || (!(inst.instruction & PRE_INDEX))))
3544 as_warn (_("pre/post-indexing used when modified address register is destination"));
3545
3546 end_of_line (str);
3547 }
3548
3549 /* Returns the index into fp_values of a floating point number,
3550 or -1 if not in the table. */
3551
3552 static int
3553 my_get_float_expression (str)
3554 char ** str;
3555 {
3556 LITTLENUM_TYPE words[MAX_LITTLENUMS];
3557 char * save_in;
3558 expressionS exp;
3559 int i;
3560 int j;
3561
3562 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
3563
3564 /* Look for a raw floating point number. */
3565 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
3566 && is_end_of_line[(unsigned char) *save_in])
3567 {
3568 for (i = 0; i < NUM_FLOAT_VALS; i++)
3569 {
3570 for (j = 0; j < MAX_LITTLENUMS; j++)
3571 {
3572 if (words[j] != fp_values[i][j])
3573 break;
3574 }
3575
3576 if (j == MAX_LITTLENUMS)
3577 {
3578 *str = save_in;
3579 return i;
3580 }
3581 }
3582 }
3583
3584 /* Try and parse a more complex expression, this will probably fail
3585 unless the code uses a floating point prefix (eg "0f"). */
3586 save_in = input_line_pointer;
3587 input_line_pointer = *str;
3588 if (expression (&exp) == absolute_section
3589 && exp.X_op == O_big
3590 && exp.X_add_number < 0)
3591 {
3592 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
3593 Ditto for 15. */
3594 if (gen_to_words (words, 5, (long) 15) == 0)
3595 {
3596 for (i = 0; i < NUM_FLOAT_VALS; i++)
3597 {
3598 for (j = 0; j < MAX_LITTLENUMS; j++)
3599 {
3600 if (words[j] != fp_values[i][j])
3601 break;
3602 }
3603
3604 if (j == MAX_LITTLENUMS)
3605 {
3606 *str = input_line_pointer;
3607 input_line_pointer = save_in;
3608 return i;
3609 }
3610 }
3611 }
3612 }
3613
3614 *str = input_line_pointer;
3615 input_line_pointer = save_in;
3616 return -1;
3617 }
3618
3619 /* Return true if anything in the expression is a bignum. */
3620
3621 static int
3622 walk_no_bignums (sp)
3623 symbolS * sp;
3624 {
3625 if (symbol_get_value_expression (sp)->X_op == O_big)
3626 return 1;
3627
3628 if (symbol_get_value_expression (sp)->X_add_symbol)
3629 {
3630 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
3631 || (symbol_get_value_expression (sp)->X_op_symbol
3632 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
3633 }
3634
3635 return 0;
3636 }
3637
3638 static int
3639 my_get_expression (ep, str)
3640 expressionS * ep;
3641 char ** str;
3642 {
3643 char * save_in;
3644 segT seg;
3645
3646 save_in = input_line_pointer;
3647 input_line_pointer = *str;
3648 seg = expression (ep);
3649
3650 #ifdef OBJ_AOUT
3651 if (seg != absolute_section
3652 && seg != text_section
3653 && seg != data_section
3654 && seg != bss_section
3655 && seg != undefined_section)
3656 {
3657 inst.error = _("bad_segment");
3658 *str = input_line_pointer;
3659 input_line_pointer = save_in;
3660 return 1;
3661 }
3662 #endif
3663
3664 /* Get rid of any bignums now, so that we don't generate an error for which
3665 we can't establish a line number later on. Big numbers are never valid
3666 in instructions, which is where this routine is always called. */
3667 if (ep->X_op == O_big
3668 || (ep->X_add_symbol
3669 && (walk_no_bignums (ep->X_add_symbol)
3670 || (ep->X_op_symbol
3671 && walk_no_bignums (ep->X_op_symbol)))))
3672 {
3673 inst.error = _("Invalid constant");
3674 *str = input_line_pointer;
3675 input_line_pointer = save_in;
3676 return 1;
3677 }
3678
3679 *str = input_line_pointer;
3680 input_line_pointer = save_in;
3681 return 0;
3682 }
3683
3684 /* UNRESTRICT should be one if <shift> <register> is permitted for this
3685 instruction. */
3686
3687 static int
3688 decode_shift (str, unrestrict)
3689 char ** str;
3690 int unrestrict;
3691 {
3692 const struct asm_shift_name * shift;
3693 char * p;
3694 char c;
3695
3696 skip_whitespace (* str);
3697
3698 for (p = * str; isalpha (* p); p ++)
3699 ;
3700
3701 if (p == * str)
3702 {
3703 inst.error = _("Shift expression expected");
3704 return FAIL;
3705 }
3706
3707 c = * p;
3708 * p = '\0';
3709 shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
3710 * p = c;
3711
3712 if (shift == NULL)
3713 {
3714 inst.error = _("Shift expression expected");
3715 return FAIL;
3716 }
3717
3718 assert (shift->properties->index == shift_properties[shift->properties->index].index);
3719
3720 if (shift->properties->index == SHIFT_RRX)
3721 {
3722 * str = p;
3723 inst.instruction |= shift->properties->bit_field;
3724 return SUCCESS;
3725 }
3726
3727 skip_whitespace (p);
3728
3729 if (unrestrict && reg_required_here (& p, 8) != FAIL)
3730 {
3731 inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
3732 * str = p;
3733 return SUCCESS;
3734 }
3735 else if (! is_immediate_prefix (* p))
3736 {
3737 inst.error = (unrestrict
3738 ? _("shift requires register or #expression")
3739 : _("shift requires #expression"));
3740 * str = p;
3741 return FAIL;
3742 }
3743
3744 inst.error = NULL;
3745 p ++;
3746
3747 if (my_get_expression (& inst.reloc.exp, & p))
3748 return FAIL;
3749
3750 /* Validate some simple #expressions. */
3751 if (inst.reloc.exp.X_op == O_constant)
3752 {
3753 unsigned num = inst.reloc.exp.X_add_number;
3754
3755 /* Reject operations greater than 32. */
3756 if (num > 32
3757 /* Reject a shift of 0 unless the mode allows it. */
3758 || (num == 0 && shift->properties->allows_0 == 0)
3759 /* Reject a shift of 32 unless the mode allows it. */
3760 || (num == 32 && shift->properties->allows_32 == 0)
3761 )
3762 {
3763 /* As a special case we allow a shift of zero for
3764 modes that do not support it to be recoded as an
3765 logical shift left of zero (ie nothing). We warn
3766 about this though. */
3767 if (num == 0)
3768 {
3769 as_warn (_("Shift of 0 ignored."));
3770 shift = & shift_names[0];
3771 assert (shift->properties->index == SHIFT_LSL);
3772 }
3773 else
3774 {
3775 inst.error = _("Invalid immediate shift");
3776 return FAIL;
3777 }
3778 }
3779
3780 /* Shifts of 32 are encoded as 0, for those shifts that
3781 support it. */
3782 if (num == 32)
3783 num = 0;
3784
3785 inst.instruction |= (num << 7) | shift->properties->bit_field;
3786 }
3787 else
3788 {
3789 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
3790 inst.reloc.pc_rel = 0;
3791 inst.instruction |= shift->properties->bit_field;
3792 }
3793
3794 * str = p;
3795 return SUCCESS;
3796 }
3797
3798 /* Do those data_ops which can take a negative immediate constant
3799 by altering the instuction. A bit of a hack really.
3800 MOV <-> MVN
3801 AND <-> BIC
3802 ADC <-> SBC
3803 by inverting the second operand, and
3804 ADD <-> SUB
3805 CMP <-> CMN
3806 by negating the second operand. */
3807
3808 static int
3809 negate_data_op (instruction, value)
3810 unsigned long * instruction;
3811 unsigned long value;
3812 {
3813 int op, new_inst;
3814 unsigned long negated, inverted;
3815
3816 negated = validate_immediate (-value);
3817 inverted = validate_immediate (~value);
3818
3819 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
3820 switch (op)
3821 {
3822 /* First negates. */
3823 case OPCODE_SUB: /* ADD <-> SUB */
3824 new_inst = OPCODE_ADD;
3825 value = negated;
3826 break;
3827
3828 case OPCODE_ADD:
3829 new_inst = OPCODE_SUB;
3830 value = negated;
3831 break;
3832
3833 case OPCODE_CMP: /* CMP <-> CMN */
3834 new_inst = OPCODE_CMN;
3835 value = negated;
3836 break;
3837
3838 case OPCODE_CMN:
3839 new_inst = OPCODE_CMP;
3840 value = negated;
3841 break;
3842
3843 /* Now Inverted ops. */
3844 case OPCODE_MOV: /* MOV <-> MVN */
3845 new_inst = OPCODE_MVN;
3846 value = inverted;
3847 break;
3848
3849 case OPCODE_MVN:
3850 new_inst = OPCODE_MOV;
3851 value = inverted;
3852 break;
3853
3854 case OPCODE_AND: /* AND <-> BIC */
3855 new_inst = OPCODE_BIC;
3856 value = inverted;
3857 break;
3858
3859 case OPCODE_BIC:
3860 new_inst = OPCODE_AND;
3861 value = inverted;
3862 break;
3863
3864 case OPCODE_ADC: /* ADC <-> SBC */
3865 new_inst = OPCODE_SBC;
3866 value = inverted;
3867 break;
3868
3869 case OPCODE_SBC:
3870 new_inst = OPCODE_ADC;
3871 value = inverted;
3872 break;
3873
3874 /* We cannot do anything. */
3875 default:
3876 return FAIL;
3877 }
3878
3879 if (value == (unsigned) FAIL)
3880 return FAIL;
3881
3882 *instruction &= OPCODE_MASK;
3883 *instruction |= new_inst << DATA_OP_SHIFT;
3884 return value;
3885 }
3886
3887 static int
3888 data_op2 (str)
3889 char ** str;
3890 {
3891 int value;
3892 expressionS expr;
3893
3894 skip_whitespace (* str);
3895
3896 if (reg_required_here (str, 0) != FAIL)
3897 {
3898 if (skip_past_comma (str) == SUCCESS)
3899 /* Shift operation on register. */
3900 return decode_shift (str, NO_SHIFT_RESTRICT);
3901
3902 return SUCCESS;
3903 }
3904 else
3905 {
3906 /* Immediate expression. */
3907 if (is_immediate_prefix (**str))
3908 {
3909 (*str)++;
3910 inst.error = NULL;
3911
3912 if (my_get_expression (&inst.reloc.exp, str))
3913 return FAIL;
3914
3915 if (inst.reloc.exp.X_add_symbol)
3916 {
3917 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
3918 inst.reloc.pc_rel = 0;
3919 }
3920 else
3921 {
3922 if (skip_past_comma (str) == SUCCESS)
3923 {
3924 /* #x, y -- ie explicit rotation by Y. */
3925 if (my_get_expression (&expr, str))
3926 return FAIL;
3927
3928 if (expr.X_op != O_constant)
3929 {
3930 inst.error = _("Constant expression expected");
3931 return FAIL;
3932 }
3933
3934 /* Rotate must be a multiple of 2. */
3935 if (((unsigned) expr.X_add_number) > 30
3936 || (expr.X_add_number & 1) != 0
3937 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
3938 {
3939 inst.error = _("Invalid constant");
3940 return FAIL;
3941 }
3942 inst.instruction |= INST_IMMEDIATE;
3943 inst.instruction |= inst.reloc.exp.X_add_number;
3944 inst.instruction |= expr.X_add_number << 7;
3945 return SUCCESS;
3946 }
3947
3948 /* Implicit rotation, select a suitable one. */
3949 value = validate_immediate (inst.reloc.exp.X_add_number);
3950
3951 if (value == FAIL)
3952 {
3953 /* Can't be done. Perhaps the code reads something like
3954 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
3955 if ((value = negate_data_op (&inst.instruction,
3956 inst.reloc.exp.X_add_number))
3957 == FAIL)
3958 {
3959 inst.error = _("Invalid constant");
3960 return FAIL;
3961 }
3962 }
3963
3964 inst.instruction |= value;
3965 }
3966
3967 inst.instruction |= INST_IMMEDIATE;
3968 return SUCCESS;
3969 }
3970
3971 (*str)++;
3972 inst.error = _("Register or shift expression expected");
3973 return FAIL;
3974 }
3975 }
3976
3977 static int
3978 fp_op2 (str)
3979 char ** str;
3980 {
3981 skip_whitespace (* str);
3982
3983 if (fp_reg_required_here (str, 0) != FAIL)
3984 return SUCCESS;
3985 else
3986 {
3987 /* Immediate expression. */
3988 if (*((*str)++) == '#')
3989 {
3990 int i;
3991
3992 inst.error = NULL;
3993
3994 skip_whitespace (* str);
3995
3996 /* First try and match exact strings, this is to guarantee
3997 that some formats will work even for cross assembly. */
3998
3999 for (i = 0; fp_const[i]; i++)
4000 {
4001 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
4002 {
4003 char *start = *str;
4004
4005 *str += strlen (fp_const[i]);
4006 if (is_end_of_line[(unsigned char) **str])
4007 {
4008 inst.instruction |= i + 8;
4009 return SUCCESS;
4010 }
4011 *str = start;
4012 }
4013 }
4014
4015 /* Just because we didn't get a match doesn't mean that the
4016 constant isn't valid, just that it is in a format that we
4017 don't automatically recognize. Try parsing it with
4018 the standard expression routines. */
4019 if ((i = my_get_float_expression (str)) >= 0)
4020 {
4021 inst.instruction |= i + 8;
4022 return SUCCESS;
4023 }
4024
4025 inst.error = _("Invalid floating point immediate expression");
4026 return FAIL;
4027 }
4028 inst.error =
4029 _("Floating point register or immediate expression expected");
4030 return FAIL;
4031 }
4032 }
4033
4034 static void
4035 do_arit (str, flags)
4036 char * str;
4037 unsigned long flags;
4038 {
4039 skip_whitespace (str);
4040
4041 if (reg_required_here (&str, 12) == FAIL
4042 || skip_past_comma (&str) == FAIL
4043 || reg_required_here (&str, 16) == FAIL
4044 || skip_past_comma (&str) == FAIL
4045 || data_op2 (&str) == FAIL)
4046 {
4047 if (!inst.error)
4048 inst.error = BAD_ARGS;
4049 return;
4050 }
4051
4052 inst.instruction |= flags;
4053 end_of_line (str);
4054 return;
4055 }
4056
4057 static void
4058 do_adr (str, flags)
4059 char * str;
4060 unsigned long flags;
4061 {
4062 /* This is a pseudo-op of the form "adr rd, label" to be converted
4063 into a relative address of the form "add rd, pc, #label-.-8". */
4064 skip_whitespace (str);
4065
4066 if (reg_required_here (&str, 12) == FAIL
4067 || skip_past_comma (&str) == FAIL
4068 || my_get_expression (&inst.reloc.exp, &str))
4069 {
4070 if (!inst.error)
4071 inst.error = BAD_ARGS;
4072 return;
4073 }
4074
4075 /* Frag hacking will turn this into a sub instruction if the offset turns
4076 out to be negative. */
4077 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4078 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
4079 inst.reloc.pc_rel = 1;
4080 inst.instruction |= flags;
4081
4082 end_of_line (str);
4083 }
4084
4085 static void
4086 do_adrl (str, flags)
4087 char * str;
4088 unsigned long flags;
4089 {
4090 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4091 into a relative address of the form:
4092 add rd, pc, #low(label-.-8)"
4093 add rd, rd, #high(label-.-8)" */
4094
4095 skip_whitespace (str);
4096
4097 if (reg_required_here (& str, 12) == FAIL
4098 || skip_past_comma (& str) == FAIL
4099 || my_get_expression (& inst.reloc.exp, & str))
4100 {
4101 if (!inst.error)
4102 inst.error = BAD_ARGS;
4103 return;
4104 }
4105
4106 end_of_line (str);
4107
4108 /* Frag hacking will turn this into a sub instruction if the offset turns
4109 out to be negative. */
4110 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
4111 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
4112 inst.reloc.pc_rel = 1;
4113 inst.instruction |= flags;
4114 inst.size = INSN_SIZE * 2;
4115
4116 return;
4117 }
4118
4119 static void
4120 do_cmp (str, flags)
4121 char * str;
4122 unsigned long flags;
4123 {
4124 skip_whitespace (str);
4125
4126 if (reg_required_here (&str, 16) == FAIL)
4127 {
4128 if (!inst.error)
4129 inst.error = BAD_ARGS;
4130 return;
4131 }
4132
4133 if (skip_past_comma (&str) == FAIL
4134 || data_op2 (&str) == FAIL)
4135 {
4136 if (!inst.error)
4137 inst.error = BAD_ARGS;
4138 return;
4139 }
4140
4141 inst.instruction |= flags;
4142 if ((flags & 0x0000f000) == 0)
4143 inst.instruction |= CONDS_BIT;
4144
4145 end_of_line (str);
4146 return;
4147 }
4148
4149 static void
4150 do_mov (str, flags)
4151 char * str;
4152 unsigned long flags;
4153 {
4154 skip_whitespace (str);
4155
4156 if (reg_required_here (&str, 12) == FAIL)
4157 {
4158 if (!inst.error)
4159 inst.error = BAD_ARGS;
4160 return;
4161 }
4162
4163 if (skip_past_comma (&str) == FAIL
4164 || data_op2 (&str) == FAIL)
4165 {
4166 if (!inst.error)
4167 inst.error = BAD_ARGS;
4168 return;
4169 }
4170
4171 inst.instruction |= flags;
4172 end_of_line (str);
4173 return;
4174 }
4175
4176 static int
4177 ldst_extend (str, hwse)
4178 char ** str;
4179 int hwse;
4180 {
4181 int add = INDEX_UP;
4182
4183 switch (**str)
4184 {
4185 case '#':
4186 case '$':
4187 (*str)++;
4188 if (my_get_expression (& inst.reloc.exp, str))
4189 return FAIL;
4190
4191 if (inst.reloc.exp.X_op == O_constant)
4192 {
4193 int value = inst.reloc.exp.X_add_number;
4194
4195 if ((hwse && (value < -255 || value > 255))
4196 || (value < -4095 || value > 4095))
4197 {
4198 inst.error = _("address offset too large");
4199 return FAIL;
4200 }
4201
4202 if (value < 0)
4203 {
4204 value = -value;
4205 add = 0;
4206 }
4207
4208 /* Halfword and signextension instructions have the
4209 immediate value split across bits 11..8 and bits 3..0. */
4210 if (hwse)
4211 inst.instruction |= (add | HWOFFSET_IMM
4212 | ((value >> 4) << 8) | (value & 0xF));
4213 else
4214 inst.instruction |= add | value;
4215 }
4216 else
4217 {
4218 if (hwse)
4219 {
4220 inst.instruction |= HWOFFSET_IMM;
4221 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
4222 }
4223 else
4224 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
4225 inst.reloc.pc_rel = 0;
4226 }
4227 return SUCCESS;
4228
4229 case '-':
4230 add = 0;
4231 /* Fall through. */
4232
4233 case '+':
4234 (*str)++;
4235 /* Fall through. */
4236
4237 default:
4238 if (reg_required_here (str, 0) == FAIL)
4239 return FAIL;
4240
4241 if (hwse)
4242 inst.instruction |= add;
4243 else
4244 {
4245 inst.instruction |= add | OFFSET_REG;
4246 if (skip_past_comma (str) == SUCCESS)
4247 return decode_shift (str, SHIFT_RESTRICT);
4248 }
4249
4250 return SUCCESS;
4251 }
4252 }
4253
4254 static void
4255 do_ldst (str, flags)
4256 char * str;
4257 unsigned long flags;
4258 {
4259 int halfword = 0;
4260 int pre_inc = 0;
4261 int conflict_reg;
4262 int value;
4263
4264 /* This is not ideal, but it is the simplest way of dealing with the
4265 ARM7T halfword instructions (since they use a different
4266 encoding, but the same mnemonic): */
4267 halfword = (flags & 0x80000000) != 0;
4268 if (halfword)
4269 {
4270 /* This is actually a load/store of a halfword, or a
4271 signed-extension load. */
4272 if ((cpu_variant & ARM_EXT_HALFWORD) == 0)
4273 {
4274 inst.error
4275 = _("Processor does not support halfwords or signed bytes");
4276 return;
4277 }
4278
4279 inst.instruction = ((inst.instruction & COND_MASK)
4280 | (flags & ~COND_MASK));
4281
4282 flags = 0;
4283 }
4284
4285 skip_whitespace (str);
4286
4287 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
4288 {
4289 if (!inst.error)
4290 inst.error = BAD_ARGS;
4291 return;
4292 }
4293
4294 if (skip_past_comma (& str) == FAIL)
4295 {
4296 inst.error = _("Address expected");
4297 return;
4298 }
4299
4300 if (*str == '[')
4301 {
4302 int reg;
4303
4304 str++;
4305
4306 skip_whitespace (str);
4307
4308 if ((reg = reg_required_here (&str, 16)) == FAIL)
4309 return;
4310
4311 /* Conflicts can occur on stores as well as loads. */
4312 conflict_reg = (conflict_reg == reg);
4313
4314 skip_whitespace (str);
4315
4316 if (*str == ']')
4317 {
4318 str ++;
4319
4320 if (skip_past_comma (&str) == SUCCESS)
4321 {
4322 /* [Rn],... (post inc) */
4323 if (ldst_extend (&str, halfword) == FAIL)
4324 return;
4325 if (conflict_reg)
4326 as_warn (_("%s register same as write-back base"),
4327 ((inst.instruction & LOAD_BIT)
4328 ? _("destination") : _("source")));
4329 }
4330 else
4331 {
4332 /* [Rn] */
4333 if (halfword)
4334 inst.instruction |= HWOFFSET_IMM;
4335
4336 skip_whitespace (str);
4337
4338 if (*str == '!')
4339 {
4340 if (conflict_reg)
4341 as_warn (_("%s register same as write-back base"),
4342 ((inst.instruction & LOAD_BIT)
4343 ? _("destination") : _("source")));
4344 str++;
4345 inst.instruction |= WRITE_BACK;
4346 }
4347
4348 flags |= INDEX_UP;
4349 if (! (flags & TRANS_BIT))
4350 pre_inc = 1;
4351 }
4352 }
4353 else
4354 {
4355 /* [Rn,...] */
4356 if (skip_past_comma (&str) == FAIL)
4357 {
4358 inst.error = _("pre-indexed expression expected");
4359 return;
4360 }
4361
4362 pre_inc = 1;
4363 if (ldst_extend (&str, halfword) == FAIL)
4364 return;
4365
4366 skip_whitespace (str);
4367
4368 if (*str++ != ']')
4369 {
4370 inst.error = _("missing ]");
4371 return;
4372 }
4373
4374 skip_whitespace (str);
4375
4376 if (*str == '!')
4377 {
4378 if (conflict_reg)
4379 as_warn (_("%s register same as write-back base"),
4380 ((inst.instruction & LOAD_BIT)
4381 ? _("destination") : _("source")));
4382 str++;
4383 inst.instruction |= WRITE_BACK;
4384 }
4385 }
4386 }
4387 else if (*str == '=')
4388 {
4389 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4390 str++;
4391
4392 skip_whitespace (str);
4393
4394 if (my_get_expression (&inst.reloc.exp, &str))
4395 return;
4396
4397 if (inst.reloc.exp.X_op != O_constant
4398 && inst.reloc.exp.X_op != O_symbol)
4399 {
4400 inst.error = _("Constant expression expected");
4401 return;
4402 }
4403
4404 if (inst.reloc.exp.X_op == O_constant
4405 && (value = validate_immediate (inst.reloc.exp.X_add_number)) != FAIL)
4406 {
4407 /* This can be done with a mov instruction. */
4408 inst.instruction &= LITERAL_MASK;
4409 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
4410 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
4411 end_of_line (str);
4412 return;
4413 }
4414 else
4415 {
4416 /* Insert into literal pool. */
4417 if (add_to_lit_pool () == FAIL)
4418 {
4419 if (!inst.error)
4420 inst.error = _("literal pool insertion failed");
4421 return;
4422 }
4423
4424 /* Change the instruction exp to point to the pool. */
4425 if (halfword)
4426 {
4427 inst.instruction |= HWOFFSET_IMM;
4428 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
4429 }
4430 else
4431 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
4432 inst.reloc.pc_rel = 1;
4433 inst.instruction |= (REG_PC << 16);
4434 pre_inc = 1;
4435 }
4436 }
4437 else
4438 {
4439 if (my_get_expression (&inst.reloc.exp, &str))
4440 return;
4441
4442 if (halfword)
4443 {
4444 inst.instruction |= HWOFFSET_IMM;
4445 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
4446 }
4447 else
4448 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
4449 #ifndef TE_WINCE
4450 /* PC rel adjust. */
4451 inst.reloc.exp.X_add_number -= 8;
4452 #endif
4453 inst.reloc.pc_rel = 1;
4454 inst.instruction |= (REG_PC << 16);
4455 pre_inc = 1;
4456 }
4457
4458 if (pre_inc && (flags & TRANS_BIT))
4459 inst.error = _("Pre-increment instruction with translate");
4460
4461 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
4462 end_of_line (str);
4463 return;
4464 }
4465
4466 static long
4467 reg_list (strp)
4468 char ** strp;
4469 {
4470 char * str = * strp;
4471 long range = 0;
4472 int another_range;
4473
4474 /* We come back here if we get ranges concatenated by '+' or '|'. */
4475 do
4476 {
4477 another_range = 0;
4478
4479 if (*str == '{')
4480 {
4481 int in_range = 0;
4482 int cur_reg = -1;
4483
4484 str++;
4485 do
4486 {
4487 int reg;
4488
4489 skip_whitespace (str);
4490
4491 if ((reg = reg_required_here (& str, -1)) == FAIL)
4492 return FAIL;
4493
4494 if (in_range)
4495 {
4496 int i;
4497
4498 if (reg <= cur_reg)
4499 {
4500 inst.error = _("Bad range in register list");
4501 return FAIL;
4502 }
4503
4504 for (i = cur_reg + 1; i < reg; i++)
4505 {
4506 if (range & (1 << i))
4507 as_tsktsk
4508 (_("Warning: Duplicated register (r%d) in register list"),
4509 i);
4510 else
4511 range |= 1 << i;
4512 }
4513 in_range = 0;
4514 }
4515
4516 if (range & (1 << reg))
4517 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
4518 reg);
4519 else if (reg <= cur_reg)
4520 as_tsktsk (_("Warning: Register range not in ascending order"));
4521
4522 range |= 1 << reg;
4523 cur_reg = reg;
4524 }
4525 while (skip_past_comma (&str) != FAIL
4526 || (in_range = 1, *str++ == '-'));
4527 str--;
4528 skip_whitespace (str);
4529
4530 if (*str++ != '}')
4531 {
4532 inst.error = _("Missing `}'");
4533 return FAIL;
4534 }
4535 }
4536 else
4537 {
4538 expressionS expr;
4539
4540 if (my_get_expression (&expr, &str))
4541 return FAIL;
4542
4543 if (expr.X_op == O_constant)
4544 {
4545 if (expr.X_add_number
4546 != (expr.X_add_number & 0x0000ffff))
4547 {
4548 inst.error = _("invalid register mask");
4549 return FAIL;
4550 }
4551
4552 if ((range & expr.X_add_number) != 0)
4553 {
4554 int regno = range & expr.X_add_number;
4555
4556 regno &= -regno;
4557 regno = (1 << regno) - 1;
4558 as_tsktsk
4559 (_("Warning: Duplicated register (r%d) in register list"),
4560 regno);
4561 }
4562
4563 range |= expr.X_add_number;
4564 }
4565 else
4566 {
4567 if (inst.reloc.type != 0)
4568 {
4569 inst.error = _("expression too complex");
4570 return FAIL;
4571 }
4572
4573 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
4574 inst.reloc.type = BFD_RELOC_ARM_MULTI;
4575 inst.reloc.pc_rel = 0;
4576 }
4577 }
4578
4579 skip_whitespace (str);
4580
4581 if (*str == '|' || *str == '+')
4582 {
4583 str++;
4584 another_range = 1;
4585 }
4586 }
4587 while (another_range);
4588
4589 *strp = str;
4590 return range;
4591 }
4592
4593 static void
4594 do_ldmstm (str, flags)
4595 char * str;
4596 unsigned long flags;
4597 {
4598 int base_reg;
4599 long range;
4600
4601 skip_whitespace (str);
4602
4603 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
4604 return;
4605
4606 if (base_reg == REG_PC)
4607 {
4608 inst.error = _("r15 not allowed as base register");
4609 return;
4610 }
4611
4612 skip_whitespace (str);
4613
4614 if (*str == '!')
4615 {
4616 flags |= WRITE_BACK;
4617 str++;
4618 }
4619
4620 if (skip_past_comma (&str) == FAIL
4621 || (range = reg_list (&str)) == FAIL)
4622 {
4623 if (! inst.error)
4624 inst.error = BAD_ARGS;
4625 return;
4626 }
4627
4628 if (*str == '^')
4629 {
4630 str++;
4631 flags |= LDM_TYPE_2_OR_3;
4632 }
4633
4634 inst.instruction |= flags | range;
4635 end_of_line (str);
4636 return;
4637 }
4638
4639 static void
4640 do_swi (str, flags)
4641 char * str;
4642 unsigned long flags;
4643 {
4644 skip_whitespace (str);
4645
4646 /* Allow optional leading '#'. */
4647 if (is_immediate_prefix (*str))
4648 str++;
4649
4650 if (my_get_expression (& inst.reloc.exp, & str))
4651 return;
4652
4653 inst.reloc.type = BFD_RELOC_ARM_SWI;
4654 inst.reloc.pc_rel = 0;
4655 inst.instruction |= flags;
4656
4657 end_of_line (str);
4658
4659 return;
4660 }
4661
4662 static void
4663 do_swap (str, flags)
4664 char * str;
4665 unsigned long flags;
4666 {
4667 int reg;
4668
4669 skip_whitespace (str);
4670
4671 if ((reg = reg_required_here (&str, 12)) == FAIL)
4672 return;
4673
4674 if (reg == REG_PC)
4675 {
4676 inst.error = _("r15 not allowed in swap");
4677 return;
4678 }
4679
4680 if (skip_past_comma (&str) == FAIL
4681 || (reg = reg_required_here (&str, 0)) == FAIL)
4682 {
4683 if (!inst.error)
4684 inst.error = BAD_ARGS;
4685 return;
4686 }
4687
4688 if (reg == REG_PC)
4689 {
4690 inst.error = _("r15 not allowed in swap");
4691 return;
4692 }
4693
4694 if (skip_past_comma (&str) == FAIL
4695 || *str++ != '[')
4696 {
4697 inst.error = BAD_ARGS;
4698 return;
4699 }
4700
4701 skip_whitespace (str);
4702
4703 if ((reg = reg_required_here (&str, 16)) == FAIL)
4704 return;
4705
4706 if (reg == REG_PC)
4707 {
4708 inst.error = BAD_PC;
4709 return;
4710 }
4711
4712 skip_whitespace (str);
4713
4714 if (*str++ != ']')
4715 {
4716 inst.error = _("missing ]");
4717 return;
4718 }
4719
4720 inst.instruction |= flags;
4721 end_of_line (str);
4722 return;
4723 }
4724
4725 static void
4726 do_branch (str, flags)
4727 char * str;
4728 unsigned long flags ATTRIBUTE_UNUSED;
4729 {
4730 if (my_get_expression (&inst.reloc.exp, &str))
4731 return;
4732
4733 #ifdef OBJ_ELF
4734 {
4735 char * save_in;
4736
4737 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
4738 required for the instruction. */
4739
4740 /* arm_parse_reloc () works on input_line_pointer.
4741 We actually want to parse the operands to the branch instruction
4742 passed in 'str'. Save the input pointer and restore it later. */
4743 save_in = input_line_pointer;
4744 input_line_pointer = str;
4745 if (inst.reloc.exp.X_op == O_symbol
4746 && *str == '('
4747 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4748 {
4749 inst.reloc.type = BFD_RELOC_ARM_PLT32;
4750 inst.reloc.pc_rel = 0;
4751 /* Modify str to point to after parsed operands, otherwise
4752 end_of_line() will complain about the (PLT) left in str. */
4753 str = input_line_pointer;
4754 }
4755 else
4756 {
4757 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
4758 inst.reloc.pc_rel = 1;
4759 }
4760 input_line_pointer = save_in;
4761 }
4762 #else
4763 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
4764 inst.reloc.pc_rel = 1;
4765 #endif /* OBJ_ELF */
4766
4767 end_of_line (str);
4768 return;
4769 }
4770
4771 static void
4772 do_bx (str, flags)
4773 char * str;
4774 unsigned long flags ATTRIBUTE_UNUSED;
4775 {
4776 int reg;
4777
4778 skip_whitespace (str);
4779
4780 if ((reg = reg_required_here (&str, 0)) == FAIL)
4781 {
4782 inst.error = BAD_ARGS;
4783 return;
4784 }
4785
4786 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
4787 if (reg == REG_PC)
4788 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
4789
4790 end_of_line (str);
4791 }
4792
4793 static void
4794 do_cdp (str, flags)
4795 char * str;
4796 unsigned long flags ATTRIBUTE_UNUSED;
4797 {
4798 /* Co-processor data operation.
4799 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
4800 skip_whitespace (str);
4801
4802 if (co_proc_number (&str) == FAIL)
4803 {
4804 if (!inst.error)
4805 inst.error = BAD_ARGS;
4806 return;
4807 }
4808
4809 if (skip_past_comma (&str) == FAIL
4810 || cp_opc_expr (&str, 20,4) == FAIL)
4811 {
4812 if (!inst.error)
4813 inst.error = BAD_ARGS;
4814 return;
4815 }
4816
4817 if (skip_past_comma (&str) == FAIL
4818 || cp_reg_required_here (&str, 12) == FAIL)
4819 {
4820 if (!inst.error)
4821 inst.error = BAD_ARGS;
4822 return;
4823 }
4824
4825 if (skip_past_comma (&str) == FAIL
4826 || cp_reg_required_here (&str, 16) == FAIL)
4827 {
4828 if (!inst.error)
4829 inst.error = BAD_ARGS;
4830 return;
4831 }
4832
4833 if (skip_past_comma (&str) == FAIL
4834 || cp_reg_required_here (&str, 0) == FAIL)
4835 {
4836 if (!inst.error)
4837 inst.error = BAD_ARGS;
4838 return;
4839 }
4840
4841 if (skip_past_comma (&str) == SUCCESS)
4842 {
4843 if (cp_opc_expr (&str, 5, 3) == FAIL)
4844 {
4845 if (!inst.error)
4846 inst.error = BAD_ARGS;
4847 return;
4848 }
4849 }
4850
4851 end_of_line (str);
4852 return;
4853 }
4854
4855 static void
4856 do_lstc (str, flags)
4857 char * str;
4858 unsigned long flags;
4859 {
4860 /* Co-processor register load/store.
4861 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
4862
4863 skip_whitespace (str);
4864
4865 if (co_proc_number (&str) == FAIL)
4866 {
4867 if (!inst.error)
4868 inst.error = BAD_ARGS;
4869 return;
4870 }
4871
4872 if (skip_past_comma (&str) == FAIL
4873 || cp_reg_required_here (&str, 12) == FAIL)
4874 {
4875 if (!inst.error)
4876 inst.error = BAD_ARGS;
4877 return;
4878 }
4879
4880 if (skip_past_comma (&str) == FAIL
4881 || cp_address_required_here (&str) == FAIL)
4882 {
4883 if (! inst.error)
4884 inst.error = BAD_ARGS;
4885 return;
4886 }
4887
4888 inst.instruction |= flags;
4889 end_of_line (str);
4890 return;
4891 }
4892
4893 static void
4894 do_co_reg (str, flags)
4895 char * str;
4896 unsigned long flags;
4897 {
4898 /* Co-processor register transfer.
4899 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
4900
4901 skip_whitespace (str);
4902
4903 if (co_proc_number (&str) == FAIL)
4904 {
4905 if (!inst.error)
4906 inst.error = BAD_ARGS;
4907 return;
4908 }
4909
4910 if (skip_past_comma (&str) == FAIL
4911 || cp_opc_expr (&str, 21, 3) == FAIL)
4912 {
4913 if (!inst.error)
4914 inst.error = BAD_ARGS;
4915 return;
4916 }
4917
4918 if (skip_past_comma (&str) == FAIL
4919 || reg_required_here (&str, 12) == FAIL)
4920 {
4921 if (!inst.error)
4922 inst.error = BAD_ARGS;
4923 return;
4924 }
4925
4926 if (skip_past_comma (&str) == FAIL
4927 || cp_reg_required_here (&str, 16) == FAIL)
4928 {
4929 if (!inst.error)
4930 inst.error = BAD_ARGS;
4931 return;
4932 }
4933
4934 if (skip_past_comma (&str) == FAIL
4935 || cp_reg_required_here (&str, 0) == FAIL)
4936 {
4937 if (!inst.error)
4938 inst.error = BAD_ARGS;
4939 return;
4940 }
4941
4942 if (skip_past_comma (&str) == SUCCESS)
4943 {
4944 if (cp_opc_expr (&str, 5, 3) == FAIL)
4945 {
4946 if (!inst.error)
4947 inst.error = BAD_ARGS;
4948 return;
4949 }
4950 }
4951 if (flags)
4952 {
4953 inst.error = BAD_COND;
4954 }
4955
4956 end_of_line (str);
4957 return;
4958 }
4959
4960 static void
4961 do_fp_ctrl (str, flags)
4962 char * str;
4963 unsigned long flags ATTRIBUTE_UNUSED;
4964 {
4965 /* FP control registers.
4966 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
4967
4968 skip_whitespace (str);
4969
4970 if (reg_required_here (&str, 12) == FAIL)
4971 {
4972 if (!inst.error)
4973 inst.error = BAD_ARGS;
4974 return;
4975 }
4976
4977 end_of_line (str);
4978 return;
4979 }
4980
4981 static void
4982 do_fp_ldst (str, flags)
4983 char * str;
4984 unsigned long flags ATTRIBUTE_UNUSED;
4985 {
4986 skip_whitespace (str);
4987
4988 switch (inst.suffix)
4989 {
4990 case SUFF_S:
4991 break;
4992 case SUFF_D:
4993 inst.instruction |= CP_T_X;
4994 break;
4995 case SUFF_E:
4996 inst.instruction |= CP_T_Y;
4997 break;
4998 case SUFF_P:
4999 inst.instruction |= CP_T_X | CP_T_Y;
5000 break;
5001 default:
5002 abort ();
5003 }
5004
5005 if (fp_reg_required_here (&str, 12) == FAIL)
5006 {
5007 if (!inst.error)
5008 inst.error = BAD_ARGS;
5009 return;
5010 }
5011
5012 if (skip_past_comma (&str) == FAIL
5013 || cp_address_required_here (&str) == FAIL)
5014 {
5015 if (!inst.error)
5016 inst.error = BAD_ARGS;
5017 return;
5018 }
5019
5020 end_of_line (str);
5021 }
5022
5023 static void
5024 do_fp_ldmstm (str, flags)
5025 char * str;
5026 unsigned long flags;
5027 {
5028 int num_regs;
5029
5030 skip_whitespace (str);
5031
5032 if (fp_reg_required_here (&str, 12) == FAIL)
5033 {
5034 if (! inst.error)
5035 inst.error = BAD_ARGS;
5036 return;
5037 }
5038
5039 /* Get Number of registers to transfer. */
5040 if (skip_past_comma (&str) == FAIL
5041 || my_get_expression (&inst.reloc.exp, &str))
5042 {
5043 if (! inst.error)
5044 inst.error = _("constant expression expected");
5045 return;
5046 }
5047
5048 if (inst.reloc.exp.X_op != O_constant)
5049 {
5050 inst.error = _("Constant value required for number of registers");
5051 return;
5052 }
5053
5054 num_regs = inst.reloc.exp.X_add_number;
5055
5056 if (num_regs < 1 || num_regs > 4)
5057 {
5058 inst.error = _("number of registers must be in the range [1:4]");
5059 return;
5060 }
5061
5062 switch (num_regs)
5063 {
5064 case 1:
5065 inst.instruction |= CP_T_X;
5066 break;
5067 case 2:
5068 inst.instruction |= CP_T_Y;
5069 break;
5070 case 3:
5071 inst.instruction |= CP_T_Y | CP_T_X;
5072 break;
5073 case 4:
5074 break;
5075 default:
5076 abort ();
5077 }
5078
5079 if (flags)
5080 {
5081 int reg;
5082 int write_back;
5083 int offset;
5084
5085 /* The instruction specified "ea" or "fd", so we can only accept
5086 [Rn]{!}. The instruction does not really support stacking or
5087 unstacking, so we have to emulate these by setting appropriate
5088 bits and offsets. */
5089 if (skip_past_comma (&str) == FAIL
5090 || *str != '[')
5091 {
5092 if (! inst.error)
5093 inst.error = BAD_ARGS;
5094 return;
5095 }
5096
5097 str++;
5098 skip_whitespace (str);
5099
5100 if ((reg = reg_required_here (&str, 16)) == FAIL)
5101 return;
5102
5103 skip_whitespace (str);
5104
5105 if (*str != ']')
5106 {
5107 inst.error = BAD_ARGS;
5108 return;
5109 }
5110
5111 str++;
5112 if (*str == '!')
5113 {
5114 write_back = 1;
5115 str++;
5116 if (reg == REG_PC)
5117 {
5118 inst.error =
5119 _("R15 not allowed as base register with write-back");
5120 return;
5121 }
5122 }
5123 else
5124 write_back = 0;
5125
5126 if (flags & CP_T_Pre)
5127 {
5128 /* Pre-decrement. */
5129 offset = 3 * num_regs;
5130 if (write_back)
5131 flags |= CP_T_WB;
5132 }
5133 else
5134 {
5135 /* Post-increment. */
5136 if (write_back)
5137 {
5138 flags |= CP_T_WB;
5139 offset = 3 * num_regs;
5140 }
5141 else
5142 {
5143 /* No write-back, so convert this into a standard pre-increment
5144 instruction -- aesthetically more pleasing. */
5145 flags = CP_T_Pre | CP_T_UD;
5146 offset = 0;
5147 }
5148 }
5149
5150 inst.instruction |= flags | offset;
5151 }
5152 else if (skip_past_comma (&str) == FAIL
5153 || cp_address_required_here (&str) == FAIL)
5154 {
5155 if (! inst.error)
5156 inst.error = BAD_ARGS;
5157 return;
5158 }
5159
5160 end_of_line (str);
5161 }
5162
5163 static void
5164 do_fp_dyadic (str, flags)
5165 char * str;
5166 unsigned long flags;
5167 {
5168 skip_whitespace (str);
5169
5170 switch (inst.suffix)
5171 {
5172 case SUFF_S:
5173 break;
5174 case SUFF_D:
5175 inst.instruction |= 0x00000080;
5176 break;
5177 case SUFF_E:
5178 inst.instruction |= 0x00080000;
5179 break;
5180 default:
5181 abort ();
5182 }
5183
5184 if (fp_reg_required_here (&str, 12) == FAIL)
5185 {
5186 if (! inst.error)
5187 inst.error = BAD_ARGS;
5188 return;
5189 }
5190
5191 if (skip_past_comma (&str) == FAIL
5192 || fp_reg_required_here (&str, 16) == FAIL)
5193 {
5194 if (! inst.error)
5195 inst.error = BAD_ARGS;
5196 return;
5197 }
5198
5199 if (skip_past_comma (&str) == FAIL
5200 || fp_op2 (&str) == FAIL)
5201 {
5202 if (! inst.error)
5203 inst.error = BAD_ARGS;
5204 return;
5205 }
5206
5207 inst.instruction |= flags;
5208 end_of_line (str);
5209 return;
5210 }
5211
5212 static void
5213 do_fp_monadic (str, flags)
5214 char * str;
5215 unsigned long flags;
5216 {
5217 skip_whitespace (str);
5218
5219 switch (inst.suffix)
5220 {
5221 case SUFF_S:
5222 break;
5223 case SUFF_D:
5224 inst.instruction |= 0x00000080;
5225 break;
5226 case SUFF_E:
5227 inst.instruction |= 0x00080000;
5228 break;
5229 default:
5230 abort ();
5231 }
5232
5233 if (fp_reg_required_here (&str, 12) == FAIL)
5234 {
5235 if (! inst.error)
5236 inst.error = BAD_ARGS;
5237 return;
5238 }
5239
5240 if (skip_past_comma (&str) == FAIL
5241 || fp_op2 (&str) == FAIL)
5242 {
5243 if (! inst.error)
5244 inst.error = BAD_ARGS;
5245 return;
5246 }
5247
5248 inst.instruction |= flags;
5249 end_of_line (str);
5250 return;
5251 }
5252
5253 static void
5254 do_fp_cmp (str, flags)
5255 char * str;
5256 unsigned long flags;
5257 {
5258 skip_whitespace (str);
5259
5260 if (fp_reg_required_here (&str, 16) == FAIL)
5261 {
5262 if (! inst.error)
5263 inst.error = BAD_ARGS;
5264 return;
5265 }
5266
5267 if (skip_past_comma (&str) == FAIL
5268 || fp_op2 (&str) == FAIL)
5269 {
5270 if (! inst.error)
5271 inst.error = BAD_ARGS;
5272 return;
5273 }
5274
5275 inst.instruction |= flags;
5276 end_of_line (str);
5277 return;
5278 }
5279
5280 static void
5281 do_fp_from_reg (str, flags)
5282 char * str;
5283 unsigned long flags;
5284 {
5285 skip_whitespace (str);
5286
5287 switch (inst.suffix)
5288 {
5289 case SUFF_S:
5290 break;
5291 case SUFF_D:
5292 inst.instruction |= 0x00000080;
5293 break;
5294 case SUFF_E:
5295 inst.instruction |= 0x00080000;
5296 break;
5297 default:
5298 abort ();
5299 }
5300
5301 if (fp_reg_required_here (&str, 16) == FAIL)
5302 {
5303 if (! inst.error)
5304 inst.error = BAD_ARGS;
5305 return;
5306 }
5307
5308 if (skip_past_comma (&str) == FAIL
5309 || reg_required_here (&str, 12) == FAIL)
5310 {
5311 if (! inst.error)
5312 inst.error = BAD_ARGS;
5313 return;
5314 }
5315
5316 inst.instruction |= flags;
5317 end_of_line (str);
5318 return;
5319 }
5320
5321 static void
5322 do_fp_to_reg (str, flags)
5323 char * str;
5324 unsigned long flags;
5325 {
5326 skip_whitespace (str);
5327
5328 if (reg_required_here (&str, 12) == FAIL)
5329 return;
5330
5331 if (skip_past_comma (&str) == FAIL
5332 || fp_reg_required_here (&str, 0) == FAIL)
5333 {
5334 if (! inst.error)
5335 inst.error = BAD_ARGS;
5336 return;
5337 }
5338
5339 inst.instruction |= flags;
5340 end_of_line (str);
5341 return;
5342 }
5343
5344 /* Thumb specific routines. */
5345
5346 /* Parse and validate that a register is of the right form, this saves
5347 repeated checking of this information in many similar cases.
5348 Unlike the 32-bit case we do not insert the register into the opcode
5349 here, since the position is often unknown until the full instruction
5350 has been parsed. */
5351
5352 static int
5353 thumb_reg (strp, hi_lo)
5354 char ** strp;
5355 int hi_lo;
5356 {
5357 int reg;
5358
5359 if ((reg = reg_required_here (strp, -1)) == FAIL)
5360 return FAIL;
5361
5362 switch (hi_lo)
5363 {
5364 case THUMB_REG_LO:
5365 if (reg > 7)
5366 {
5367 inst.error = _("lo register required");
5368 return FAIL;
5369 }
5370 break;
5371
5372 case THUMB_REG_HI:
5373 if (reg < 8)
5374 {
5375 inst.error = _("hi register required");
5376 return FAIL;
5377 }
5378 break;
5379
5380 default:
5381 break;
5382 }
5383
5384 return reg;
5385 }
5386
5387 /* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
5388 was SUB. */
5389
5390 static void
5391 thumb_add_sub (str, subtract)
5392 char * str;
5393 int subtract;
5394 {
5395 int Rd, Rs, Rn = FAIL;
5396
5397 skip_whitespace (str);
5398
5399 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
5400 || skip_past_comma (&str) == FAIL)
5401 {
5402 if (! inst.error)
5403 inst.error = BAD_ARGS;
5404 return;
5405 }
5406
5407 if (is_immediate_prefix (*str))
5408 {
5409 Rs = Rd;
5410 str++;
5411 if (my_get_expression (&inst.reloc.exp, &str))
5412 return;
5413 }
5414 else
5415 {
5416 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5417 return;
5418
5419 if (skip_past_comma (&str) == FAIL)
5420 {
5421 /* Two operand format, shuffle the registers
5422 and pretend there are 3. */
5423 Rn = Rs;
5424 Rs = Rd;
5425 }
5426 else if (is_immediate_prefix (*str))
5427 {
5428 str++;
5429 if (my_get_expression (&inst.reloc.exp, &str))
5430 return;
5431 }
5432 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5433 return;
5434 }
5435
5436 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5437 for the latter case, EXPR contains the immediate that was found. */
5438 if (Rn != FAIL)
5439 {
5440 /* All register format. */
5441 if (Rd > 7 || Rs > 7 || Rn > 7)
5442 {
5443 if (Rs != Rd)
5444 {
5445 inst.error = _("dest and source1 must be the same register");
5446 return;
5447 }
5448
5449 /* Can't do this for SUB. */
5450 if (subtract)
5451 {
5452 inst.error = _("subtract valid only on lo regs");
5453 return;
5454 }
5455
5456 inst.instruction = (T_OPCODE_ADD_HI
5457 | (Rd > 7 ? THUMB_H1 : 0)
5458 | (Rn > 7 ? THUMB_H2 : 0));
5459 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
5460 }
5461 else
5462 {
5463 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
5464 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
5465 }
5466 }
5467 else
5468 {
5469 /* Immediate expression, now things start to get nasty. */
5470
5471 /* First deal with HI regs, only very restricted cases allowed:
5472 Adjusting SP, and using PC or SP to get an address. */
5473 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
5474 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
5475 {
5476 inst.error = _("invalid Hi register with immediate");
5477 return;
5478 }
5479
5480 if (inst.reloc.exp.X_op != O_constant)
5481 {
5482 /* Value isn't known yet, all we can do is store all the fragments
5483 we know about in the instruction and let the reloc hacking
5484 work it all out. */
5485 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
5486 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
5487 }
5488 else
5489 {
5490 int offset = inst.reloc.exp.X_add_number;
5491
5492 if (subtract)
5493 offset = -offset;
5494
5495 if (offset < 0)
5496 {
5497 offset = -offset;
5498 subtract = 1;
5499
5500 /* Quick check, in case offset is MIN_INT. */
5501 if (offset < 0)
5502 {
5503 inst.error = _("immediate value out of range");
5504 return;
5505 }
5506 }
5507 else
5508 subtract = 0;
5509
5510 if (Rd == REG_SP)
5511 {
5512 if (offset & ~0x1fc)
5513 {
5514 inst.error = _("invalid immediate value for stack adjust");
5515 return;
5516 }
5517 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5518 inst.instruction |= offset >> 2;
5519 }
5520 else if (Rs == REG_PC || Rs == REG_SP)
5521 {
5522 if (subtract
5523 || (offset & ~0x3fc))
5524 {
5525 inst.error = _("invalid immediate for address calculation");
5526 return;
5527 }
5528 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
5529 : T_OPCODE_ADD_SP);
5530 inst.instruction |= (Rd << 8) | (offset >> 2);
5531 }
5532 else if (Rs == Rd)
5533 {
5534 if (offset & ~0xff)
5535 {
5536 inst.error = _("immediate value out of range");
5537 return;
5538 }
5539 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5540 inst.instruction |= (Rd << 8) | offset;
5541 }
5542 else
5543 {
5544 if (offset & ~0x7)
5545 {
5546 inst.error = _("immediate value out of range");
5547 return;
5548 }
5549 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5550 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
5551 }
5552 }
5553 }
5554
5555 end_of_line (str);
5556 }
5557
5558 static void
5559 thumb_shift (str, shift)
5560 char * str;
5561 int shift;
5562 {
5563 int Rd, Rs, Rn = FAIL;
5564
5565 skip_whitespace (str);
5566
5567 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
5568 || skip_past_comma (&str) == FAIL)
5569 {
5570 if (! inst.error)
5571 inst.error = BAD_ARGS;
5572 return;
5573 }
5574
5575 if (is_immediate_prefix (*str))
5576 {
5577 /* Two operand immediate format, set Rs to Rd. */
5578 Rs = Rd;
5579 str ++;
5580 if (my_get_expression (&inst.reloc.exp, &str))
5581 return;
5582 }
5583 else
5584 {
5585 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5586 return;
5587
5588 if (skip_past_comma (&str) == FAIL)
5589 {
5590 /* Two operand format, shuffle the registers
5591 and pretend there are 3. */
5592 Rn = Rs;
5593 Rs = Rd;
5594 }
5595 else if (is_immediate_prefix (*str))
5596 {
5597 str++;
5598 if (my_get_expression (&inst.reloc.exp, &str))
5599 return;
5600 }
5601 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5602 return;
5603 }
5604
5605 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5606 for the latter case, EXPR contains the immediate that was found. */
5607
5608 if (Rn != FAIL)
5609 {
5610 if (Rs != Rd)
5611 {
5612 inst.error = _("source1 and dest must be same register");
5613 return;
5614 }
5615
5616 switch (shift)
5617 {
5618 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
5619 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
5620 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
5621 }
5622
5623 inst.instruction |= Rd | (Rn << 3);
5624 }
5625 else
5626 {
5627 switch (shift)
5628 {
5629 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
5630 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
5631 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
5632 }
5633
5634 if (inst.reloc.exp.X_op != O_constant)
5635 {
5636 /* Value isn't known yet, create a dummy reloc and let reloc
5637 hacking fix it up. */
5638 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
5639 }
5640 else
5641 {
5642 unsigned shift_value = inst.reloc.exp.X_add_number;
5643
5644 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
5645 {
5646 inst.error = _("Invalid immediate for shift");
5647 return;
5648 }
5649
5650 /* Shifts of zero are handled by converting to LSL. */
5651 if (shift_value == 0)
5652 inst.instruction = T_OPCODE_LSL_I;
5653
5654 /* Shifts of 32 are encoded as a shift of zero. */
5655 if (shift_value == 32)
5656 shift_value = 0;
5657
5658 inst.instruction |= shift_value << 6;
5659 }
5660
5661 inst.instruction |= Rd | (Rs << 3);
5662 }
5663
5664 end_of_line (str);
5665 }
5666
5667 static void
5668 thumb_mov_compare (str, move)
5669 char * str;
5670 int move;
5671 {
5672 int Rd, Rs = FAIL;
5673
5674 skip_whitespace (str);
5675
5676 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
5677 || skip_past_comma (&str) == FAIL)
5678 {
5679 if (! inst.error)
5680 inst.error = BAD_ARGS;
5681 return;
5682 }
5683
5684 if (is_immediate_prefix (*str))
5685 {
5686 str++;
5687 if (my_get_expression (&inst.reloc.exp, &str))
5688 return;
5689 }
5690 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5691 return;
5692
5693 if (Rs != FAIL)
5694 {
5695 if (Rs < 8 && Rd < 8)
5696 {
5697 if (move == THUMB_MOVE)
5698 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
5699 since a MOV instruction produces unpredictable results. */
5700 inst.instruction = T_OPCODE_ADD_I3;
5701 else
5702 inst.instruction = T_OPCODE_CMP_LR;
5703 inst.instruction |= Rd | (Rs << 3);
5704 }
5705 else
5706 {
5707 if (move == THUMB_MOVE)
5708 inst.instruction = T_OPCODE_MOV_HR;
5709 else
5710 inst.instruction = T_OPCODE_CMP_HR;
5711
5712 if (Rd > 7)
5713 inst.instruction |= THUMB_H1;
5714
5715 if (Rs > 7)
5716 inst.instruction |= THUMB_H2;
5717
5718 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
5719 }
5720 }
5721 else
5722 {
5723 if (Rd > 7)
5724 {
5725 inst.error = _("only lo regs allowed with immediate");
5726 return;
5727 }
5728
5729 if (move == THUMB_MOVE)
5730 inst.instruction = T_OPCODE_MOV_I8;
5731 else
5732 inst.instruction = T_OPCODE_CMP_I8;
5733
5734 inst.instruction |= Rd << 8;
5735
5736 if (inst.reloc.exp.X_op != O_constant)
5737 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
5738 else
5739 {
5740 unsigned value = inst.reloc.exp.X_add_number;
5741
5742 if (value > 255)
5743 {
5744 inst.error = _("invalid immediate");
5745 return;
5746 }
5747
5748 inst.instruction |= value;
5749 }
5750 }
5751
5752 end_of_line (str);
5753 }
5754
5755 static void
5756 thumb_load_store (str, load_store, size)
5757 char * str;
5758 int load_store;
5759 int size;
5760 {
5761 int Rd, Rb, Ro = FAIL;
5762
5763 skip_whitespace (str);
5764
5765 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
5766 || skip_past_comma (&str) == FAIL)
5767 {
5768 if (! inst.error)
5769 inst.error = BAD_ARGS;
5770 return;
5771 }
5772
5773 if (*str == '[')
5774 {
5775 str++;
5776 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5777 return;
5778
5779 if (skip_past_comma (&str) != FAIL)
5780 {
5781 if (is_immediate_prefix (*str))
5782 {
5783 str++;
5784 if (my_get_expression (&inst.reloc.exp, &str))
5785 return;
5786 }
5787 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5788 return;
5789 }
5790 else
5791 {
5792 inst.reloc.exp.X_op = O_constant;
5793 inst.reloc.exp.X_add_number = 0;
5794 }
5795
5796 if (*str != ']')
5797 {
5798 inst.error = _("expected ']'");
5799 return;
5800 }
5801 str++;
5802 }
5803 else if (*str == '=')
5804 {
5805 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5806 str++;
5807
5808 skip_whitespace (str);
5809
5810 if (my_get_expression (& inst.reloc.exp, & str))
5811 return;
5812
5813 end_of_line (str);
5814
5815 if ( inst.reloc.exp.X_op != O_constant
5816 && inst.reloc.exp.X_op != O_symbol)
5817 {
5818 inst.error = "Constant expression expected";
5819 return;
5820 }
5821
5822 if (inst.reloc.exp.X_op == O_constant
5823 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
5824 {
5825 /* This can be done with a mov instruction. */
5826
5827 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
5828 inst.instruction |= inst.reloc.exp.X_add_number;
5829 return;
5830 }
5831
5832 /* Insert into literal pool. */
5833 if (add_to_lit_pool () == FAIL)
5834 {
5835 if (!inst.error)
5836 inst.error = "literal pool insertion failed";
5837 return;
5838 }
5839
5840 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
5841 inst.reloc.pc_rel = 1;
5842 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
5843 /* Adjust ARM pipeline offset to Thumb. */
5844 inst.reloc.exp.X_add_number += 4;
5845
5846 return;
5847 }
5848 else
5849 {
5850 if (my_get_expression (&inst.reloc.exp, &str))
5851 return;
5852
5853 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
5854 inst.reloc.pc_rel = 1;
5855 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
5856 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
5857 end_of_line (str);
5858 return;
5859 }
5860
5861 if (Rb == REG_PC || Rb == REG_SP)
5862 {
5863 if (size != THUMB_WORD)
5864 {
5865 inst.error = _("byte or halfword not valid for base register");
5866 return;
5867 }
5868 else if (Rb == REG_PC && load_store != THUMB_LOAD)
5869 {
5870 inst.error = _("R15 based store not allowed");
5871 return;
5872 }
5873 else if (Ro != FAIL)
5874 {
5875 inst.error = _("Invalid base register for register offset");
5876 return;
5877 }
5878
5879 if (Rb == REG_PC)
5880 inst.instruction = T_OPCODE_LDR_PC;
5881 else if (load_store == THUMB_LOAD)
5882 inst.instruction = T_OPCODE_LDR_SP;
5883 else
5884 inst.instruction = T_OPCODE_STR_SP;
5885
5886 inst.instruction |= Rd << 8;
5887 if (inst.reloc.exp.X_op == O_constant)
5888 {
5889 unsigned offset = inst.reloc.exp.X_add_number;
5890
5891 if (offset & ~0x3fc)
5892 {
5893 inst.error = _("invalid offset");
5894 return;
5895 }
5896
5897 inst.instruction |= offset >> 2;
5898 }
5899 else
5900 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
5901 }
5902 else if (Rb > 7)
5903 {
5904 inst.error = _("invalid base register in load/store");
5905 return;
5906 }
5907 else if (Ro == FAIL)
5908 {
5909 /* Immediate offset. */
5910 if (size == THUMB_WORD)
5911 inst.instruction = (load_store == THUMB_LOAD
5912 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
5913 else if (size == THUMB_HALFWORD)
5914 inst.instruction = (load_store == THUMB_LOAD
5915 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
5916 else
5917 inst.instruction = (load_store == THUMB_LOAD
5918 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
5919
5920 inst.instruction |= Rd | (Rb << 3);
5921
5922 if (inst.reloc.exp.X_op == O_constant)
5923 {
5924 unsigned offset = inst.reloc.exp.X_add_number;
5925
5926 if (offset & ~(0x1f << size))
5927 {
5928 inst.error = _("Invalid offset");
5929 return;
5930 }
5931 inst.instruction |= (offset >> size) << 6;
5932 }
5933 else
5934 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
5935 }
5936 else
5937 {
5938 /* Register offset. */
5939 if (size == THUMB_WORD)
5940 inst.instruction = (load_store == THUMB_LOAD
5941 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
5942 else if (size == THUMB_HALFWORD)
5943 inst.instruction = (load_store == THUMB_LOAD
5944 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
5945 else
5946 inst.instruction = (load_store == THUMB_LOAD
5947 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
5948
5949 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
5950 }
5951
5952 end_of_line (str);
5953 }
5954
5955 static void
5956 do_t_nop (str)
5957 char * str;
5958 {
5959 /* Do nothing. */
5960 end_of_line (str);
5961 return;
5962 }
5963
5964 /* Handle the Format 4 instructions that do not have equivalents in other
5965 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
5966 BIC and MVN. */
5967
5968 static void
5969 do_t_arit (str)
5970 char * str;
5971 {
5972 int Rd, Rs, Rn;
5973
5974 skip_whitespace (str);
5975
5976 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
5977 || skip_past_comma (&str) == FAIL
5978 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5979 {
5980 inst.error = BAD_ARGS;
5981 return;
5982 }
5983
5984 if (skip_past_comma (&str) != FAIL)
5985 {
5986 /* Three operand format not allowed for TST, CMN, NEG and MVN.
5987 (It isn't allowed for CMP either, but that isn't handled by this
5988 function.) */
5989 if (inst.instruction == T_OPCODE_TST
5990 || inst.instruction == T_OPCODE_CMN
5991 || inst.instruction == T_OPCODE_NEG
5992 || inst.instruction == T_OPCODE_MVN)
5993 {
5994 inst.error = BAD_ARGS;
5995 return;
5996 }
5997
5998 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5999 return;
6000
6001 if (Rs != Rd)
6002 {
6003 inst.error = _("dest and source1 one must be the same register");
6004 return;
6005 }
6006 Rs = Rn;
6007 }
6008
6009 if (inst.instruction == T_OPCODE_MUL
6010 && Rs == Rd)
6011 as_tsktsk (_("Rs and Rd must be different in MUL"));
6012
6013 inst.instruction |= Rd | (Rs << 3);
6014 end_of_line (str);
6015 }
6016
6017 static void
6018 do_t_add (str)
6019 char * str;
6020 {
6021 thumb_add_sub (str, 0);
6022 }
6023
6024 static void
6025 do_t_asr (str)
6026 char * str;
6027 {
6028 thumb_shift (str, THUMB_ASR);
6029 }
6030
6031 static void
6032 do_t_branch9 (str)
6033 char * str;
6034 {
6035 if (my_get_expression (&inst.reloc.exp, &str))
6036 return;
6037 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
6038 inst.reloc.pc_rel = 1;
6039 end_of_line (str);
6040 }
6041
6042 static void
6043 do_t_branch12 (str)
6044 char * str;
6045 {
6046 if (my_get_expression (&inst.reloc.exp, &str))
6047 return;
6048 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
6049 inst.reloc.pc_rel = 1;
6050 end_of_line (str);
6051 }
6052
6053 /* Find the real, Thumb encoded start of a Thumb function. */
6054
6055 static symbolS *
6056 find_real_start (symbolP)
6057 symbolS * symbolP;
6058 {
6059 char * real_start;
6060 const char * name = S_GET_NAME (symbolP);
6061 symbolS * new_target;
6062
6063 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
6064 #define STUB_NAME ".real_start_of"
6065
6066 if (name == NULL)
6067 abort ();
6068
6069 /* Names that start with '.' are local labels, not function entry points.
6070 The compiler may generate BL instructions to these labels because it
6071 needs to perform a branch to a far away location. */
6072 if (name[0] == '.')
6073 return symbolP;
6074
6075 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
6076 sprintf (real_start, "%s%s", STUB_NAME, name);
6077
6078 new_target = symbol_find (real_start);
6079
6080 if (new_target == NULL)
6081 {
6082 as_warn ("Failed to find real start of function: %s\n", name);
6083 new_target = symbolP;
6084 }
6085
6086 free (real_start);
6087
6088 return new_target;
6089 }
6090
6091 static void
6092 do_t_branch23 (str)
6093 char * str;
6094 {
6095 if (my_get_expression (& inst.reloc.exp, & str))
6096 return;
6097
6098 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
6099 inst.reloc.pc_rel = 1;
6100 end_of_line (str);
6101
6102 /* If the destination of the branch is a defined symbol which does not have
6103 the THUMB_FUNC attribute, then we must be calling a function which has
6104 the (interfacearm) attribute. We look for the Thumb entry point to that
6105 function and change the branch to refer to that function instead. */
6106 if ( inst.reloc.exp.X_op == O_symbol
6107 && inst.reloc.exp.X_add_symbol != NULL
6108 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
6109 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
6110 inst.reloc.exp.X_add_symbol =
6111 find_real_start (inst.reloc.exp.X_add_symbol);
6112 }
6113
6114 static void
6115 do_t_bx (str)
6116 char * str;
6117 {
6118 int reg;
6119
6120 skip_whitespace (str);
6121
6122 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
6123 return;
6124
6125 /* This sets THUMB_H2 from the top bit of reg. */
6126 inst.instruction |= reg << 3;
6127
6128 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
6129 should cause the alignment to be checked once it is known. This is
6130 because BX PC only works if the instruction is word aligned. */
6131
6132 end_of_line (str);
6133 }
6134
6135 static void
6136 do_t_compare (str)
6137 char * str;
6138 {
6139 thumb_mov_compare (str, THUMB_COMPARE);
6140 }
6141
6142 static void
6143 do_t_ldmstm (str)
6144 char * str;
6145 {
6146 int Rb;
6147 long range;
6148
6149 skip_whitespace (str);
6150
6151 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
6152 return;
6153
6154 if (*str != '!')
6155 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
6156 else
6157 str++;
6158
6159 if (skip_past_comma (&str) == FAIL
6160 || (range = reg_list (&str)) == FAIL)
6161 {
6162 if (! inst.error)
6163 inst.error = BAD_ARGS;
6164 return;
6165 }
6166
6167 if (inst.reloc.type != BFD_RELOC_NONE)
6168 {
6169 /* This really doesn't seem worth it. */
6170 inst.reloc.type = BFD_RELOC_NONE;
6171 inst.error = _("Expression too complex");
6172 return;
6173 }
6174
6175 if (range & ~0xff)
6176 {
6177 inst.error = _("only lo-regs valid in load/store multiple");
6178 return;
6179 }
6180
6181 inst.instruction |= (Rb << 8) | range;
6182 end_of_line (str);
6183 }
6184
6185 static void
6186 do_t_ldr (str)
6187 char * str;
6188 {
6189 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
6190 }
6191
6192 static void
6193 do_t_ldrb (str)
6194 char * str;
6195 {
6196 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
6197 }
6198
6199 static void
6200 do_t_ldrh (str)
6201 char * str;
6202 {
6203 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
6204 }
6205
6206 static void
6207 do_t_lds (str)
6208 char * str;
6209 {
6210 int Rd, Rb, Ro;
6211
6212 skip_whitespace (str);
6213
6214 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
6215 || skip_past_comma (&str) == FAIL
6216 || *str++ != '['
6217 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
6218 || skip_past_comma (&str) == FAIL
6219 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
6220 || *str++ != ']')
6221 {
6222 if (! inst.error)
6223 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
6224 return;
6225 }
6226
6227 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
6228 end_of_line (str);
6229 }
6230
6231 static void
6232 do_t_lsl (str)
6233 char * str;
6234 {
6235 thumb_shift (str, THUMB_LSL);
6236 }
6237
6238 static void
6239 do_t_lsr (str)
6240 char * str;
6241 {
6242 thumb_shift (str, THUMB_LSR);
6243 }
6244
6245 static void
6246 do_t_mov (str)
6247 char * str;
6248 {
6249 thumb_mov_compare (str, THUMB_MOVE);
6250 }
6251
6252 static void
6253 do_t_push_pop (str)
6254 char * str;
6255 {
6256 long range;
6257
6258 skip_whitespace (str);
6259
6260 if ((range = reg_list (&str)) == FAIL)
6261 {
6262 if (! inst.error)
6263 inst.error = BAD_ARGS;
6264 return;
6265 }
6266
6267 if (inst.reloc.type != BFD_RELOC_NONE)
6268 {
6269 /* This really doesn't seem worth it. */
6270 inst.reloc.type = BFD_RELOC_NONE;
6271 inst.error = _("Expression too complex");
6272 return;
6273 }
6274
6275 if (range & ~0xff)
6276 {
6277 if ((inst.instruction == T_OPCODE_PUSH
6278 && (range & ~0xff) == 1 << REG_LR)
6279 || (inst.instruction == T_OPCODE_POP
6280 && (range & ~0xff) == 1 << REG_PC))
6281 {
6282 inst.instruction |= THUMB_PP_PC_LR;
6283 range &= 0xff;
6284 }
6285 else
6286 {
6287 inst.error = _("invalid register list to push/pop instruction");
6288 return;
6289 }
6290 }
6291
6292 inst.instruction |= range;
6293 end_of_line (str);
6294 }
6295
6296 static void
6297 do_t_str (str)
6298 char * str;
6299 {
6300 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
6301 }
6302
6303 static void
6304 do_t_strb (str)
6305 char * str;
6306 {
6307 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
6308 }
6309
6310 static void
6311 do_t_strh (str)
6312 char * str;
6313 {
6314 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
6315 }
6316
6317 static void
6318 do_t_sub (str)
6319 char * str;
6320 {
6321 thumb_add_sub (str, 1);
6322 }
6323
6324 static void
6325 do_t_swi (str)
6326 char * str;
6327 {
6328 skip_whitespace (str);
6329
6330 if (my_get_expression (&inst.reloc.exp, &str))
6331 return;
6332
6333 inst.reloc.type = BFD_RELOC_ARM_SWI;
6334 end_of_line (str);
6335 return;
6336 }
6337
6338 static void
6339 do_t_adr (str)
6340 char * str;
6341 {
6342 int reg;
6343
6344 /* This is a pseudo-op of the form "adr rd, label" to be converted
6345 into a relative address of the form "add rd, pc, #label-.-4". */
6346 skip_whitespace (str);
6347
6348 /* Store Rd in temporary location inside instruction. */
6349 if ((reg = reg_required_here (&str, 4)) == FAIL
6350 || (reg > 7) /* For Thumb reg must be r0..r7. */
6351 || skip_past_comma (&str) == FAIL
6352 || my_get_expression (&inst.reloc.exp, &str))
6353 {
6354 if (!inst.error)
6355 inst.error = BAD_ARGS;
6356 return;
6357 }
6358
6359 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
6360 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
6361 inst.reloc.pc_rel = 1;
6362 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
6363
6364 end_of_line (str);
6365 }
6366
6367 static void
6368 insert_reg (entry)
6369 int entry;
6370 {
6371 int len = strlen (reg_table[entry].name) + 2;
6372 char * buf = (char *) xmalloc (len);
6373 char * buf2 = (char *) xmalloc (len);
6374 int i = 0;
6375
6376 #ifdef REGISTER_PREFIX
6377 buf[i++] = REGISTER_PREFIX;
6378 #endif
6379
6380 strcpy (buf + i, reg_table[entry].name);
6381
6382 for (i = 0; buf[i]; i++)
6383 buf2[i] = islower (buf[i]) ? toupper (buf[i]) : buf[i];
6384
6385 buf2[i] = '\0';
6386
6387 hash_insert (arm_reg_hsh, buf, (PTR) & reg_table[entry]);
6388 hash_insert (arm_reg_hsh, buf2, (PTR) & reg_table[entry]);
6389 }
6390
6391 static void
6392 insert_reg_alias (str, regnum)
6393 char *str;
6394 int regnum;
6395 {
6396 struct reg_entry *new =
6397 (struct reg_entry *) xmalloc (sizeof (struct reg_entry));
6398 char *name = xmalloc (strlen (str) + 1);
6399 strcpy (name, str);
6400
6401 new->name = name;
6402 new->number = regnum;
6403
6404 hash_insert (arm_reg_hsh, name, (PTR) new);
6405 }
6406
6407 static void
6408 set_constant_flonums ()
6409 {
6410 int i;
6411
6412 for (i = 0; i < NUM_FLOAT_VALS; i++)
6413 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
6414 abort ();
6415 }
6416
6417 void
6418 md_begin ()
6419 {
6420 unsigned mach;
6421 unsigned int i;
6422
6423 if ( (arm_ops_hsh = hash_new ()) == NULL
6424 || (arm_tops_hsh = hash_new ()) == NULL
6425 || (arm_cond_hsh = hash_new ()) == NULL
6426 || (arm_shift_hsh = hash_new ()) == NULL
6427 || (arm_reg_hsh = hash_new ()) == NULL
6428 || (arm_psr_hsh = hash_new ()) == NULL)
6429 as_fatal (_("Virtual memory exhausted"));
6430
6431 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
6432 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
6433 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
6434 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
6435 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
6436 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
6437 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
6438 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
6439 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
6440 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
6441
6442 for (i = 0; reg_table[i].name; i++)
6443 insert_reg (i);
6444
6445 set_constant_flonums ();
6446
6447 #if defined OBJ_COFF || defined OBJ_ELF
6448 {
6449 unsigned int flags = 0;
6450
6451 /* Set the flags in the private structure. */
6452 if (uses_apcs_26) flags |= F_APCS26;
6453 if (support_interwork) flags |= F_INTERWORK;
6454 if (uses_apcs_float) flags |= F_APCS_FLOAT;
6455 if (pic_code) flags |= F_PIC;
6456 if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT;
6457
6458 bfd_set_private_flags (stdoutput, flags);
6459
6460 /* We have run out flags in the COFF header to encode the
6461 status of ATPCS support, so instead we create a dummy,
6462 empty, debug section called .arm.atpcs. */
6463 if (atpcs)
6464 {
6465 asection * sec;
6466
6467 sec = bfd_make_section (stdoutput, ".arm.atpcs");
6468
6469 if (sec != NULL)
6470 {
6471 bfd_set_section_flags
6472 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
6473 bfd_set_section_size (stdoutput, sec, 0);
6474 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
6475 }
6476 }
6477 }
6478 #endif
6479
6480 /* Record the CPU type as well. */
6481 switch (cpu_variant & ARM_CPU_MASK)
6482 {
6483 case ARM_2:
6484 mach = bfd_mach_arm_2;
6485 break;
6486
6487 case ARM_3: /* Also ARM_250. */
6488 mach = bfd_mach_arm_2a;
6489 break;
6490
6491 default:
6492 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined. */
6493 mach = bfd_mach_arm_4;
6494 break;
6495
6496 case ARM_7: /* Also ARM_6. */
6497 mach = bfd_mach_arm_3;
6498 break;
6499 }
6500
6501 /* Catch special cases. */
6502 if (cpu_variant != (FPU_DEFAULT | CPU_DEFAULT))
6503 {
6504 if (cpu_variant & ARM_EXT_XSCALE)
6505 mach = bfd_mach_arm_XScale;
6506 else if (cpu_variant & ARM_EXT_V5E)
6507 mach = bfd_mach_arm_5TE;
6508 else if (cpu_variant & ARM_EXT_V5)
6509 {
6510 if (cpu_variant & ARM_EXT_THUMB)
6511 mach = bfd_mach_arm_5T;
6512 else
6513 mach = bfd_mach_arm_5;
6514 }
6515 else if (cpu_variant & ARM_EXT_HALFWORD)
6516 {
6517 if (cpu_variant & ARM_EXT_THUMB)
6518 mach = bfd_mach_arm_4T;
6519 else
6520 mach = bfd_mach_arm_4;
6521 }
6522 else if (cpu_variant & ARM_EXT_LONGMUL)
6523 mach = bfd_mach_arm_3M;
6524 }
6525
6526 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
6527 }
6528
6529 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
6530 for use in the a.out file, and stores them in the array pointed to by buf.
6531 This knows about the endian-ness of the target machine and does
6532 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
6533 2 (short) and 4 (long) Floating numbers are put out as a series of
6534 LITTLENUMS (shorts, here at least). */
6535
6536 void
6537 md_number_to_chars (buf, val, n)
6538 char * buf;
6539 valueT val;
6540 int n;
6541 {
6542 if (target_big_endian)
6543 number_to_chars_bigendian (buf, val, n);
6544 else
6545 number_to_chars_littleendian (buf, val, n);
6546 }
6547
6548 static valueT
6549 md_chars_to_number (buf, n)
6550 char * buf;
6551 int n;
6552 {
6553 valueT result = 0;
6554 unsigned char * where = (unsigned char *) buf;
6555
6556 if (target_big_endian)
6557 {
6558 while (n--)
6559 {
6560 result <<= 8;
6561 result |= (*where++ & 255);
6562 }
6563 }
6564 else
6565 {
6566 while (n--)
6567 {
6568 result <<= 8;
6569 result |= (where[n] & 255);
6570 }
6571 }
6572
6573 return result;
6574 }
6575
6576 /* Turn a string in input_line_pointer into a floating point constant
6577 of type TYPE, and store the appropriate bytes in *LITP. The number
6578 of LITTLENUMS emitted is stored in *SIZEP. An error message is
6579 returned, or NULL on OK.
6580
6581 Note that fp constants aren't represent in the normal way on the ARM.
6582 In big endian mode, things are as expected. However, in little endian
6583 mode fp constants are big-endian word-wise, and little-endian byte-wise
6584 within the words. For example, (double) 1.1 in big endian mode is
6585 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
6586 the byte sequence 99 99 f1 3f 9a 99 99 99.
6587
6588 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
6589
6590 char *
6591 md_atof (type, litP, sizeP)
6592 char type;
6593 char * litP;
6594 int * sizeP;
6595 {
6596 int prec;
6597 LITTLENUM_TYPE words[MAX_LITTLENUMS];
6598 char *t;
6599 int i;
6600
6601 switch (type)
6602 {
6603 case 'f':
6604 case 'F':
6605 case 's':
6606 case 'S':
6607 prec = 2;
6608 break;
6609
6610 case 'd':
6611 case 'D':
6612 case 'r':
6613 case 'R':
6614 prec = 4;
6615 break;
6616
6617 case 'x':
6618 case 'X':
6619 prec = 6;
6620 break;
6621
6622 case 'p':
6623 case 'P':
6624 prec = 6;
6625 break;
6626
6627 default:
6628 *sizeP = 0;
6629 return _("Bad call to MD_ATOF()");
6630 }
6631
6632 t = atof_ieee (input_line_pointer, type, words);
6633 if (t)
6634 input_line_pointer = t;
6635 *sizeP = prec * 2;
6636
6637 if (target_big_endian)
6638 {
6639 for (i = 0; i < prec; i++)
6640 {
6641 md_number_to_chars (litP, (valueT) words[i], 2);
6642 litP += 2;
6643 }
6644 }
6645 else
6646 {
6647 /* For a 4 byte float the order of elements in `words' is 1 0. For an
6648 8 byte float the order is 1 0 3 2. */
6649 for (i = 0; i < prec; i += 2)
6650 {
6651 md_number_to_chars (litP, (valueT) words[i + 1], 2);
6652 md_number_to_chars (litP + 2, (valueT) words[i], 2);
6653 litP += 4;
6654 }
6655 }
6656
6657 return 0;
6658 }
6659
6660 /* The knowledge of the PC's pipeline offset is built into the insns
6661 themselves. */
6662
6663 long
6664 md_pcrel_from (fixP)
6665 fixS * fixP;
6666 {
6667 if (fixP->fx_addsy
6668 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
6669 && fixP->fx_subsy == NULL)
6670 return 0;
6671
6672 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
6673 {
6674 /* PC relative addressing on the Thumb is slightly odd
6675 as the bottom two bits of the PC are forced to zero
6676 for the calculation. */
6677 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
6678 }
6679
6680 #ifdef TE_WINCE
6681 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
6682 so we un-adjust here to compensate for the accomodation. */
6683 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
6684 #else
6685 return fixP->fx_where + fixP->fx_frag->fr_address;
6686 #endif
6687 }
6688
6689 /* Round up a section size to the appropriate boundary. */
6690
6691 valueT
6692 md_section_align (segment, size)
6693 segT segment ATTRIBUTE_UNUSED;
6694 valueT size;
6695 {
6696 #ifdef OBJ_ELF
6697 return size;
6698 #else
6699 /* Round all sects to multiple of 4. */
6700 return (size + 3) & ~3;
6701 #endif
6702 }
6703
6704 /* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
6705 Otherwise we have no need to default values of symbols. */
6706
6707 symbolS *
6708 md_undefined_symbol (name)
6709 char * name ATTRIBUTE_UNUSED;
6710 {
6711 #ifdef OBJ_ELF
6712 if (name[0] == '_' && name[1] == 'G'
6713 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
6714 {
6715 if (!GOT_symbol)
6716 {
6717 if (symbol_find (name))
6718 as_bad ("GOT already in the symbol table");
6719
6720 GOT_symbol = symbol_new (name, undefined_section,
6721 (valueT) 0, & zero_address_frag);
6722 }
6723
6724 return GOT_symbol;
6725 }
6726 #endif
6727
6728 return 0;
6729 }
6730
6731 /* arm_reg_parse () := if it looks like a register, return its token and
6732 advance the pointer. */
6733
6734 static int
6735 arm_reg_parse (ccp)
6736 register char ** ccp;
6737 {
6738 char * start = * ccp;
6739 char c;
6740 char * p;
6741 struct reg_entry * reg;
6742
6743 #ifdef REGISTER_PREFIX
6744 if (*start != REGISTER_PREFIX)
6745 return FAIL;
6746 p = start + 1;
6747 #else
6748 p = start;
6749 #ifdef OPTIONAL_REGISTER_PREFIX
6750 if (*p == OPTIONAL_REGISTER_PREFIX)
6751 p++, start++;
6752 #endif
6753 #endif
6754 if (!isalpha (*p) || !is_name_beginner (*p))
6755 return FAIL;
6756
6757 c = *p++;
6758 while (isalpha (c) || isdigit (c) || c == '_')
6759 c = *p++;
6760
6761 *--p = 0;
6762 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
6763 *p = c;
6764
6765 if (reg)
6766 {
6767 *ccp = p;
6768 return reg->number;
6769 }
6770
6771 return FAIL;
6772 }
6773
6774 int
6775 md_apply_fix3 (fixP, val, seg)
6776 fixS * fixP;
6777 valueT * val;
6778 segT seg;
6779 {
6780 offsetT value = * val;
6781 offsetT newval;
6782 unsigned int newimm;
6783 unsigned long temp;
6784 int sign;
6785 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
6786 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
6787
6788 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
6789
6790 /* Note whether this will delete the relocation. */
6791 #if 0
6792 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
6793 doesn't work fully.) */
6794 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
6795 && !fixP->fx_pcrel)
6796 #else
6797 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
6798 #endif
6799 fixP->fx_done = 1;
6800
6801 /* If this symbol is in a different section then we need to leave it for
6802 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
6803 so we have to undo it's effects here. */
6804 if (fixP->fx_pcrel)
6805 {
6806 if (fixP->fx_addsy != NULL
6807 && S_IS_DEFINED (fixP->fx_addsy)
6808 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
6809 {
6810 if (target_oabi
6811 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
6812 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
6813 ))
6814 value = 0;
6815 else
6816 value += md_pcrel_from (fixP);
6817 }
6818 }
6819
6820 /* Remember value for emit_reloc. */
6821 fixP->fx_addnumber = value;
6822
6823 switch (fixP->fx_r_type)
6824 {
6825 case BFD_RELOC_ARM_IMMEDIATE:
6826 newimm = validate_immediate (value);
6827 temp = md_chars_to_number (buf, INSN_SIZE);
6828
6829 /* If the instruction will fail, see if we can fix things up by
6830 changing the opcode. */
6831 if (newimm == (unsigned int) FAIL
6832 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
6833 {
6834 as_bad_where (fixP->fx_file, fixP->fx_line,
6835 _("invalid constant (%lx) after fixup"),
6836 (unsigned long) value);
6837 break;
6838 }
6839
6840 newimm |= (temp & 0xfffff000);
6841 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
6842 break;
6843
6844 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
6845 {
6846 unsigned int highpart = 0;
6847 unsigned int newinsn = 0xe1a00000; /* nop. */
6848 newimm = validate_immediate (value);
6849 temp = md_chars_to_number (buf, INSN_SIZE);
6850
6851 /* If the instruction will fail, see if we can fix things up by
6852 changing the opcode. */
6853 if (newimm == (unsigned int) FAIL
6854 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
6855 {
6856 /* No ? OK - try using two ADD instructions to generate
6857 the value. */
6858 newimm = validate_immediate_twopart (value, & highpart);
6859
6860 /* Yes - then make sure that the second instruction is
6861 also an add. */
6862 if (newimm != (unsigned int) FAIL)
6863 newinsn = temp;
6864 /* Still No ? Try using a negated value. */
6865 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
6866 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
6867 /* Otherwise - give up. */
6868 else
6869 {
6870 as_bad_where (fixP->fx_file, fixP->fx_line,
6871 _("Unable to compute ADRL instructions for PC offset of 0x%lx"),
6872 value);
6873 break;
6874 }
6875
6876 /* Replace the first operand in the 2nd instruction (which
6877 is the PC) with the destination register. We have
6878 already added in the PC in the first instruction and we
6879 do not want to do it again. */
6880 newinsn &= ~ 0xf0000;
6881 newinsn |= ((newinsn & 0x0f000) << 4);
6882 }
6883
6884 newimm |= (temp & 0xfffff000);
6885 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
6886
6887 highpart |= (newinsn & 0xfffff000);
6888 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
6889 }
6890 break;
6891
6892 case BFD_RELOC_ARM_OFFSET_IMM:
6893 sign = value >= 0;
6894
6895 if (value < 0)
6896 value = - value;
6897
6898 if (validate_offset_imm (value, 0) == FAIL)
6899 {
6900 as_bad_where (fixP->fx_file, fixP->fx_line,
6901 _("bad immediate value for offset (%ld)"),
6902 (long) value);
6903 break;
6904 }
6905
6906 newval = md_chars_to_number (buf, INSN_SIZE);
6907 newval &= 0xff7ff000;
6908 newval |= value | (sign ? INDEX_UP : 0);
6909 md_number_to_chars (buf, newval, INSN_SIZE);
6910 break;
6911
6912 case BFD_RELOC_ARM_OFFSET_IMM8:
6913 case BFD_RELOC_ARM_HWLITERAL:
6914 sign = value >= 0;
6915
6916 if (value < 0)
6917 value = - value;
6918
6919 if (validate_offset_imm (value, 1) == FAIL)
6920 {
6921 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
6922 as_bad_where (fixP->fx_file, fixP->fx_line,
6923 _("invalid literal constant: pool needs to be closer"));
6924 else
6925 as_bad (_("bad immediate value for half-word offset (%ld)"),
6926 (long) value);
6927 break;
6928 }
6929
6930 newval = md_chars_to_number (buf, INSN_SIZE);
6931 newval &= 0xff7ff0f0;
6932 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
6933 md_number_to_chars (buf, newval, INSN_SIZE);
6934 break;
6935
6936 case BFD_RELOC_ARM_LITERAL:
6937 sign = value >= 0;
6938
6939 if (value < 0)
6940 value = - value;
6941
6942 if (validate_offset_imm (value, 0) == FAIL)
6943 {
6944 as_bad_where (fixP->fx_file, fixP->fx_line,
6945 _("invalid literal constant: pool needs to be closer"));
6946 break;
6947 }
6948
6949 newval = md_chars_to_number (buf, INSN_SIZE);
6950 newval &= 0xff7ff000;
6951 newval |= value | (sign ? INDEX_UP : 0);
6952 md_number_to_chars (buf, newval, INSN_SIZE);
6953 break;
6954
6955 case BFD_RELOC_ARM_SHIFT_IMM:
6956 newval = md_chars_to_number (buf, INSN_SIZE);
6957 if (((unsigned long) value) > 32
6958 || (value == 32
6959 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
6960 {
6961 as_bad_where (fixP->fx_file, fixP->fx_line,
6962 _("shift expression is too large"));
6963 break;
6964 }
6965
6966 if (value == 0)
6967 /* Shifts of zero must be done as lsl. */
6968 newval &= ~0x60;
6969 else if (value == 32)
6970 value = 0;
6971 newval &= 0xfffff07f;
6972 newval |= (value & 0x1f) << 7;
6973 md_number_to_chars (buf, newval, INSN_SIZE);
6974 break;
6975
6976 case BFD_RELOC_ARM_SWI:
6977 if (arm_data->thumb_mode)
6978 {
6979 if (((unsigned long) value) > 0xff)
6980 as_bad_where (fixP->fx_file, fixP->fx_line,
6981 _("Invalid swi expression"));
6982 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
6983 newval |= value;
6984 md_number_to_chars (buf, newval, THUMB_SIZE);
6985 }
6986 else
6987 {
6988 if (((unsigned long) value) > 0x00ffffff)
6989 as_bad_where (fixP->fx_file, fixP->fx_line,
6990 _("Invalid swi expression"));
6991 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
6992 newval |= value;
6993 md_number_to_chars (buf, newval, INSN_SIZE);
6994 }
6995 break;
6996
6997 case BFD_RELOC_ARM_MULTI:
6998 if (((unsigned long) value) > 0xffff)
6999 as_bad_where (fixP->fx_file, fixP->fx_line,
7000 _("Invalid expression in load/store multiple"));
7001 newval = value | md_chars_to_number (buf, INSN_SIZE);
7002 md_number_to_chars (buf, newval, INSN_SIZE);
7003 break;
7004
7005 case BFD_RELOC_ARM_PCREL_BRANCH:
7006 newval = md_chars_to_number (buf, INSN_SIZE);
7007
7008 /* Sign-extend a 24-bit number. */
7009 #define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
7010
7011 #ifdef OBJ_ELF
7012 if (! target_oabi)
7013 value = fixP->fx_offset;
7014 #endif
7015
7016 /* We are going to store value (shifted right by two) in the
7017 instruction, in a 24 bit, signed field. Thus we need to check
7018 that none of the top 8 bits of the shifted value (top 7 bits of
7019 the unshifted, unsigned value) are set, or that they are all set. */
7020 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
7021 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
7022 {
7023 #ifdef OBJ_ELF
7024 /* Normally we would be stuck at this point, since we cannot store
7025 the absolute address that is the destination of the branch in the
7026 24 bits of the branch instruction. If however, we happen to know
7027 that the destination of the branch is in the same section as the
7028 branch instruciton itself, then we can compute the relocation for
7029 ourselves and not have to bother the linker with it.
7030
7031 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
7032 because I have not worked out how to do this for OBJ_COFF or
7033 target_oabi. */
7034 if (! target_oabi
7035 && fixP->fx_addsy != NULL
7036 && S_IS_DEFINED (fixP->fx_addsy)
7037 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
7038 {
7039 /* Get pc relative value to go into the branch. */
7040 value = * val;
7041
7042 /* Permit a backward branch provided that enough bits
7043 are set. Allow a forwards branch, provided that
7044 enough bits are clear. */
7045 if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
7046 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
7047 fixP->fx_done = 1;
7048 }
7049
7050 if (! fixP->fx_done)
7051 #endif
7052 as_bad_where (fixP->fx_file, fixP->fx_line,
7053 _("gas can't handle same-section branch dest >= 0x04000000"));
7054 }
7055
7056 value >>= 2;
7057 value += SEXT24 (newval);
7058
7059 if ( (value & ~ ((offsetT) 0xffffff)) != 0
7060 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
7061 as_bad_where (fixP->fx_file, fixP->fx_line,
7062 _("out of range branch"));
7063
7064 newval = (value & 0x00ffffff) | (newval & 0xff000000);
7065 md_number_to_chars (buf, newval, INSN_SIZE);
7066 break;
7067
7068 case BFD_RELOC_ARM_PCREL_BLX:
7069 {
7070 offsetT hbit;
7071 newval = md_chars_to_number (buf, INSN_SIZE);
7072
7073 #ifdef OBJ_ELF
7074 if (! target_oabi)
7075 value = fixP->fx_offset;
7076 #endif
7077 hbit = (value >> 1) & 1;
7078 value = (value >> 2) & 0x00ffffff;
7079 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
7080 newval = value | (newval & 0xfe000000) | (hbit << 24);
7081 md_number_to_chars (buf, newval, INSN_SIZE);
7082 }
7083 break;
7084
7085 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
7086 newval = md_chars_to_number (buf, THUMB_SIZE);
7087 {
7088 addressT diff = (newval & 0xff) << 1;
7089 if (diff & 0x100)
7090 diff |= ~0xff;
7091
7092 value += diff;
7093 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
7094 as_bad_where (fixP->fx_file, fixP->fx_line,
7095 _("Branch out of range"));
7096 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
7097 }
7098 md_number_to_chars (buf, newval, THUMB_SIZE);
7099 break;
7100
7101 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
7102 newval = md_chars_to_number (buf, THUMB_SIZE);
7103 {
7104 addressT diff = (newval & 0x7ff) << 1;
7105 if (diff & 0x800)
7106 diff |= ~0x7ff;
7107
7108 value += diff;
7109 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
7110 as_bad_where (fixP->fx_file, fixP->fx_line,
7111 _("Branch out of range"));
7112 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
7113 }
7114 md_number_to_chars (buf, newval, THUMB_SIZE);
7115 break;
7116
7117 case BFD_RELOC_THUMB_PCREL_BLX:
7118 case BFD_RELOC_THUMB_PCREL_BRANCH23:
7119 {
7120 offsetT newval2;
7121 addressT diff;
7122
7123 newval = md_chars_to_number (buf, THUMB_SIZE);
7124 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
7125 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
7126 if (diff & 0x400000)
7127 diff |= ~0x3fffff;
7128 #ifdef OBJ_ELF
7129 value = fixP->fx_offset;
7130 #endif
7131 value += diff;
7132 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
7133 as_bad_where (fixP->fx_file, fixP->fx_line,
7134 _("Branch with link out of range"));
7135
7136 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
7137 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
7138 md_number_to_chars (buf, newval, THUMB_SIZE);
7139 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
7140 }
7141 break;
7142
7143 case BFD_RELOC_8:
7144 if (fixP->fx_done || fixP->fx_pcrel)
7145 md_number_to_chars (buf, value, 1);
7146 #ifdef OBJ_ELF
7147 else if (!target_oabi)
7148 {
7149 value = fixP->fx_offset;
7150 md_number_to_chars (buf, value, 1);
7151 }
7152 #endif
7153 break;
7154
7155 case BFD_RELOC_16:
7156 if (fixP->fx_done || fixP->fx_pcrel)
7157 md_number_to_chars (buf, value, 2);
7158 #ifdef OBJ_ELF
7159 else if (!target_oabi)
7160 {
7161 value = fixP->fx_offset;
7162 md_number_to_chars (buf, value, 2);
7163 }
7164 #endif
7165 break;
7166
7167 #ifdef OBJ_ELF
7168 case BFD_RELOC_ARM_GOT32:
7169 case BFD_RELOC_ARM_GOTOFF:
7170 md_number_to_chars (buf, 0, 4);
7171 break;
7172 #endif
7173
7174 case BFD_RELOC_RVA:
7175 case BFD_RELOC_32:
7176 if (fixP->fx_done || fixP->fx_pcrel)
7177 md_number_to_chars (buf, value, 4);
7178 #ifdef OBJ_ELF
7179 else if (!target_oabi)
7180 {
7181 value = fixP->fx_offset;
7182 md_number_to_chars (buf, value, 4);
7183 }
7184 #endif
7185 break;
7186
7187 #ifdef OBJ_ELF
7188 case BFD_RELOC_ARM_PLT32:
7189 /* It appears the instruction is fully prepared at this point. */
7190 break;
7191 #endif
7192
7193 case BFD_RELOC_ARM_GOTPC:
7194 md_number_to_chars (buf, value, 4);
7195 break;
7196
7197 case BFD_RELOC_ARM_CP_OFF_IMM:
7198 sign = value >= 0;
7199 if (value < -1023 || value > 1023 || (value & 3))
7200 as_bad_where (fixP->fx_file, fixP->fx_line,
7201 _("Illegal value for co-processor offset"));
7202 if (value < 0)
7203 value = -value;
7204 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
7205 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
7206 md_number_to_chars (buf, newval, INSN_SIZE);
7207 break;
7208
7209 case BFD_RELOC_ARM_THUMB_OFFSET:
7210 newval = md_chars_to_number (buf, THUMB_SIZE);
7211 /* Exactly what ranges, and where the offset is inserted depends
7212 on the type of instruction, we can establish this from the
7213 top 4 bits. */
7214 switch (newval >> 12)
7215 {
7216 case 4: /* PC load. */
7217 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
7218 forced to zero for these loads, so we will need to round
7219 up the offset if the instruction address is not word
7220 aligned (since the final address produced must be, and
7221 we can only describe word-aligned immediate offsets). */
7222
7223 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
7224 as_bad_where (fixP->fx_file, fixP->fx_line,
7225 _("Invalid offset, target not word aligned (0x%08X)"),
7226 (unsigned int) (fixP->fx_frag->fr_address
7227 + fixP->fx_where + value));
7228
7229 if ((value + 2) & ~0x3fe)
7230 as_bad_where (fixP->fx_file, fixP->fx_line,
7231 _("Invalid offset, value too big (0x%08lX)"), value);
7232
7233 /* Round up, since pc will be rounded down. */
7234 newval |= (value + 2) >> 2;
7235 break;
7236
7237 case 9: /* SP load/store. */
7238 if (value & ~0x3fc)
7239 as_bad_where (fixP->fx_file, fixP->fx_line,
7240 _("Invalid offset, value too big (0x%08lX)"), value);
7241 newval |= value >> 2;
7242 break;
7243
7244 case 6: /* Word load/store. */
7245 if (value & ~0x7c)
7246 as_bad_where (fixP->fx_file, fixP->fx_line,
7247 _("Invalid offset, value too big (0x%08lX)"), value);
7248 newval |= value << 4; /* 6 - 2. */
7249 break;
7250
7251 case 7: /* Byte load/store. */
7252 if (value & ~0x1f)
7253 as_bad_where (fixP->fx_file, fixP->fx_line,
7254 _("Invalid offset, value too big (0x%08lX)"), value);
7255 newval |= value << 6;
7256 break;
7257
7258 case 8: /* Halfword load/store. */
7259 if (value & ~0x3e)
7260 as_bad_where (fixP->fx_file, fixP->fx_line,
7261 _("Invalid offset, value too big (0x%08lX)"), value);
7262 newval |= value << 5; /* 6 - 1. */
7263 break;
7264
7265 default:
7266 as_bad_where (fixP->fx_file, fixP->fx_line,
7267 "Unable to process relocation for thumb opcode: %lx",
7268 (unsigned long) newval);
7269 break;
7270 }
7271 md_number_to_chars (buf, newval, THUMB_SIZE);
7272 break;
7273
7274 case BFD_RELOC_ARM_THUMB_ADD:
7275 /* This is a complicated relocation, since we use it for all of
7276 the following immediate relocations:
7277
7278 3bit ADD/SUB
7279 8bit ADD/SUB
7280 9bit ADD/SUB SP word-aligned
7281 10bit ADD PC/SP word-aligned
7282
7283 The type of instruction being processed is encoded in the
7284 instruction field:
7285
7286 0x8000 SUB
7287 0x00F0 Rd
7288 0x000F Rs
7289 */
7290 newval = md_chars_to_number (buf, THUMB_SIZE);
7291 {
7292 int rd = (newval >> 4) & 0xf;
7293 int rs = newval & 0xf;
7294 int subtract = newval & 0x8000;
7295
7296 if (rd == REG_SP)
7297 {
7298 if (value & ~0x1fc)
7299 as_bad_where (fixP->fx_file, fixP->fx_line,
7300 _("Invalid immediate for stack address calculation"));
7301 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
7302 newval |= value >> 2;
7303 }
7304 else if (rs == REG_PC || rs == REG_SP)
7305 {
7306 if (subtract ||
7307 value & ~0x3fc)
7308 as_bad_where (fixP->fx_file, fixP->fx_line,
7309 _("Invalid immediate for address calculation (value = 0x%08lX)"),
7310 (unsigned long) value);
7311 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
7312 newval |= rd << 8;
7313 newval |= value >> 2;
7314 }
7315 else if (rs == rd)
7316 {
7317 if (value & ~0xff)
7318 as_bad_where (fixP->fx_file, fixP->fx_line,
7319 _("Invalid 8bit immediate"));
7320 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
7321 newval |= (rd << 8) | value;
7322 }
7323 else
7324 {
7325 if (value & ~0x7)
7326 as_bad_where (fixP->fx_file, fixP->fx_line,
7327 _("Invalid 3bit immediate"));
7328 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
7329 newval |= rd | (rs << 3) | (value << 6);
7330 }
7331 }
7332 md_number_to_chars (buf, newval, THUMB_SIZE);
7333 break;
7334
7335 case BFD_RELOC_ARM_THUMB_IMM:
7336 newval = md_chars_to_number (buf, THUMB_SIZE);
7337 switch (newval >> 11)
7338 {
7339 case 0x04: /* 8bit immediate MOV. */
7340 case 0x05: /* 8bit immediate CMP. */
7341 if (value < 0 || value > 255)
7342 as_bad_where (fixP->fx_file, fixP->fx_line,
7343 _("Invalid immediate: %ld is too large"),
7344 (long) value);
7345 newval |= value;
7346 break;
7347
7348 default:
7349 abort ();
7350 }
7351 md_number_to_chars (buf, newval, THUMB_SIZE);
7352 break;
7353
7354 case BFD_RELOC_ARM_THUMB_SHIFT:
7355 /* 5bit shift value (0..31). */
7356 if (value < 0 || value > 31)
7357 as_bad_where (fixP->fx_file, fixP->fx_line,
7358 _("Illegal Thumb shift value: %ld"), (long) value);
7359 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
7360 newval |= value << 6;
7361 md_number_to_chars (buf, newval, THUMB_SIZE);
7362 break;
7363
7364 case BFD_RELOC_VTABLE_INHERIT:
7365 case BFD_RELOC_VTABLE_ENTRY:
7366 fixP->fx_done = 0;
7367 return 1;
7368
7369 case BFD_RELOC_NONE:
7370 default:
7371 as_bad_where (fixP->fx_file, fixP->fx_line,
7372 _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
7373 }
7374
7375 return 1;
7376 }
7377
7378 /* Translate internal representation of relocation info to BFD target
7379 format. */
7380
7381 arelent *
7382 tc_gen_reloc (section, fixp)
7383 asection * section ATTRIBUTE_UNUSED;
7384 fixS * fixp;
7385 {
7386 arelent * reloc;
7387 bfd_reloc_code_real_type code;
7388
7389 reloc = (arelent *) xmalloc (sizeof (arelent));
7390
7391 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
7392 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
7393 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
7394
7395 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
7396 #ifndef OBJ_ELF
7397 if (fixp->fx_pcrel == 0)
7398 reloc->addend = fixp->fx_offset;
7399 else
7400 reloc->addend = fixp->fx_offset = reloc->address;
7401 #else /* OBJ_ELF */
7402 reloc->addend = fixp->fx_offset;
7403 #endif
7404
7405 switch (fixp->fx_r_type)
7406 {
7407 case BFD_RELOC_8:
7408 if (fixp->fx_pcrel)
7409 {
7410 code = BFD_RELOC_8_PCREL;
7411 break;
7412 }
7413
7414 case BFD_RELOC_16:
7415 if (fixp->fx_pcrel)
7416 {
7417 code = BFD_RELOC_16_PCREL;
7418 break;
7419 }
7420
7421 case BFD_RELOC_32:
7422 if (fixp->fx_pcrel)
7423 {
7424 code = BFD_RELOC_32_PCREL;
7425 break;
7426 }
7427
7428 case BFD_RELOC_ARM_PCREL_BRANCH:
7429 case BFD_RELOC_ARM_PCREL_BLX:
7430 case BFD_RELOC_RVA:
7431 case BFD_RELOC_THUMB_PCREL_BRANCH9:
7432 case BFD_RELOC_THUMB_PCREL_BRANCH12:
7433 case BFD_RELOC_THUMB_PCREL_BRANCH23:
7434 case BFD_RELOC_THUMB_PCREL_BLX:
7435 case BFD_RELOC_VTABLE_ENTRY:
7436 case BFD_RELOC_VTABLE_INHERIT:
7437 code = fixp->fx_r_type;
7438 break;
7439
7440 case BFD_RELOC_ARM_LITERAL:
7441 case BFD_RELOC_ARM_HWLITERAL:
7442 /* If this is called then the a literal has been referenced across
7443 a section boundary - possibly due to an implicit dump. */
7444 as_bad_where (fixp->fx_file, fixp->fx_line,
7445 _("Literal referenced across section boundary (Implicit dump?)"));
7446 return NULL;
7447
7448 #ifdef OBJ_ELF
7449 case BFD_RELOC_ARM_GOT32:
7450 case BFD_RELOC_ARM_GOTOFF:
7451 case BFD_RELOC_ARM_PLT32:
7452 code = fixp->fx_r_type;
7453 break;
7454 #endif
7455
7456 case BFD_RELOC_ARM_IMMEDIATE:
7457 as_bad_where (fixp->fx_file, fixp->fx_line,
7458 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
7459 fixp->fx_r_type);
7460 return NULL;
7461
7462 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
7463 as_bad_where (fixp->fx_file, fixp->fx_line,
7464 _("ADRL used for a symbol not defined in the same file"));
7465 return NULL;
7466
7467 case BFD_RELOC_ARM_OFFSET_IMM:
7468 as_bad_where (fixp->fx_file, fixp->fx_line,
7469 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
7470 fixp->fx_r_type);
7471 return NULL;
7472
7473 default:
7474 {
7475 char * type;
7476
7477 switch (fixp->fx_r_type)
7478 {
7479 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
7480 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
7481 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
7482 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
7483 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
7484 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
7485 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
7486 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
7487 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
7488 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
7489 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
7490 default: type = _("<unknown>"); break;
7491 }
7492 as_bad_where (fixp->fx_file, fixp->fx_line,
7493 _("Cannot represent %s relocation in this object file format"),
7494 type);
7495 return NULL;
7496 }
7497 }
7498
7499 #ifdef OBJ_ELF
7500 if (code == BFD_RELOC_32_PCREL
7501 && GOT_symbol
7502 && fixp->fx_addsy == GOT_symbol)
7503 {
7504 code = BFD_RELOC_ARM_GOTPC;
7505 reloc->addend = fixp->fx_offset = reloc->address;
7506 }
7507 #endif
7508
7509 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
7510
7511 if (reloc->howto == NULL)
7512 {
7513 as_bad_where (fixp->fx_file, fixp->fx_line,
7514 _("Can not represent %s relocation in this object file format"),
7515 bfd_get_reloc_code_name (code));
7516 return NULL;
7517 }
7518
7519 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
7520 vtable entry to be used in the relocation's section offset. */
7521 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
7522 reloc->address = fixp->fx_offset;
7523
7524 return reloc;
7525 }
7526
7527 int
7528 md_estimate_size_before_relax (fragP, segtype)
7529 fragS * fragP ATTRIBUTE_UNUSED;
7530 segT segtype ATTRIBUTE_UNUSED;
7531 {
7532 as_fatal (_("md_estimate_size_before_relax\n"));
7533 return 1;
7534 }
7535
7536 static void
7537 output_inst PARAMS ((void))
7538 {
7539 char * to = NULL;
7540
7541 if (inst.error)
7542 {
7543 as_bad (inst.error);
7544 return;
7545 }
7546
7547 to = frag_more (inst.size);
7548
7549 if (thumb_mode && (inst.size > THUMB_SIZE))
7550 {
7551 assert (inst.size == (2 * THUMB_SIZE));
7552 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
7553 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
7554 }
7555 else if (inst.size > INSN_SIZE)
7556 {
7557 assert (inst.size == (2 * INSN_SIZE));
7558 md_number_to_chars (to, inst.instruction, INSN_SIZE);
7559 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
7560 }
7561 else
7562 md_number_to_chars (to, inst.instruction, inst.size);
7563
7564 if (inst.reloc.type != BFD_RELOC_NONE)
7565 fix_new_arm (frag_now, to - frag_now->fr_literal,
7566 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
7567 inst.reloc.type);
7568
7569 #ifdef OBJ_ELF
7570 dwarf2_emit_insn (inst.size);
7571 #endif
7572 }
7573
7574 void
7575 md_assemble (str)
7576 char * str;
7577 {
7578 char c;
7579 char * p;
7580 char * q;
7581 char * start;
7582
7583 /* Align the instruction.
7584 This may not be the right thing to do but ... */
7585 #if 0
7586 arm_align (2, 0);
7587 #endif
7588 listing_prev_line (); /* Defined in listing.h. */
7589
7590 /* Align the previous label if needed. */
7591 if (last_label_seen != NULL)
7592 {
7593 symbol_set_frag (last_label_seen, frag_now);
7594 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
7595 S_SET_SEGMENT (last_label_seen, now_seg);
7596 }
7597
7598 memset (&inst, '\0', sizeof (inst));
7599 inst.reloc.type = BFD_RELOC_NONE;
7600
7601 skip_whitespace (str);
7602
7603 /* Scan up to the end of the op-code, which must end in white space or
7604 end of string. */
7605 for (start = p = str; *p != '\0'; p++)
7606 if (*p == ' ')
7607 break;
7608
7609 if (p == str)
7610 {
7611 as_bad (_("No operator -- statement `%s'\n"), str);
7612 return;
7613 }
7614
7615 if (thumb_mode)
7616 {
7617 CONST struct thumb_opcode * opcode;
7618
7619 c = *p;
7620 *p = '\0';
7621 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
7622 *p = c;
7623
7624 if (opcode)
7625 {
7626 /* Check that this instruction is supported for this CPU. */
7627 if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0)
7628 {
7629 as_bad (_("selected processor does not support this opcode"));
7630 return;
7631 }
7632
7633 inst.instruction = opcode->value;
7634 inst.size = opcode->size;
7635 (*opcode->parms) (p);
7636 output_inst ();
7637 return;
7638 }
7639 }
7640 else
7641 {
7642 CONST struct asm_opcode * opcode;
7643 unsigned long cond_code;
7644
7645 inst.size = INSN_SIZE;
7646 /* P now points to the end of the opcode, probably white space, but we
7647 have to break the opcode up in case it contains condionals and flags;
7648 keep trying with progressively smaller basic instructions until one
7649 matches, or we run out of opcode. */
7650 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
7651
7652 for (; q != str; q--)
7653 {
7654 c = *q;
7655 *q = '\0';
7656
7657 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
7658 *q = c;
7659
7660 if (opcode && opcode->template)
7661 {
7662 unsigned long flag_bits = 0;
7663 char * r;
7664
7665 /* Check that this instruction is supported for this CPU. */
7666 if ((opcode->variants & cpu_variant) == 0)
7667 goto try_shorter;
7668
7669 inst.instruction = opcode->value;
7670 if (q == p) /* Just a simple opcode. */
7671 {
7672 if (opcode->comp_suffix)
7673 {
7674 if (*opcode->comp_suffix != '\0')
7675 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
7676 str, opcode->comp_suffix);
7677 else
7678 /* Not a conditional instruction. */
7679 (*opcode->parms) (q, 0);
7680 }
7681 else
7682 {
7683 /* A conditional instruction with default condition. */
7684 inst.instruction |= COND_ALWAYS;
7685 (*opcode->parms) (q, 0);
7686 }
7687 output_inst ();
7688 return;
7689 }
7690
7691 /* Not just a simple opcode. Check if extra is a
7692 conditional. */
7693 r = q;
7694 if (p - r >= 2)
7695 {
7696 CONST struct asm_cond *cond;
7697 char d = *(r + 2);
7698
7699 *(r + 2) = '\0';
7700 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
7701 *(r + 2) = d;
7702 if (cond)
7703 {
7704 if (cond->value == 0xf0000000)
7705 as_tsktsk (
7706 _("Warning: Use of the 'nv' conditional is deprecated\n"));
7707
7708 cond_code = cond->value;
7709 r += 2;
7710 }
7711 else
7712 cond_code = COND_ALWAYS;
7713 }
7714 else
7715 cond_code = COND_ALWAYS;
7716
7717 /* Apply the conditional, or complain it's not allowed. */
7718 if (opcode->comp_suffix && *opcode->comp_suffix == '\0')
7719 {
7720 /* Instruction isn't conditional. */
7721 if (cond_code != COND_ALWAYS)
7722 {
7723 as_bad (_("Opcode `%s' is unconditional\n"), str);
7724 return;
7725 }
7726 }
7727 else
7728 /* Instruction is conditional: set the condition into it. */
7729 inst.instruction |= cond_code;
7730
7731 /* If there is a compulsory suffix, it should come here
7732 before any optional flags. */
7733 if (opcode->comp_suffix && *opcode->comp_suffix != '\0')
7734 {
7735 CONST char *s = opcode->comp_suffix;
7736
7737 while (*s)
7738 {
7739 inst.suffix++;
7740 if (*r == *s)
7741 break;
7742 s++;
7743 }
7744
7745 if (*s == '\0')
7746 {
7747 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
7748 str, opcode->comp_suffix);
7749 return;
7750 }
7751
7752 r++;
7753 }
7754
7755 /* The remainder, if any should now be flags for the instruction;
7756 Scan these checking each one found with the opcode. */
7757 if (r != p)
7758 {
7759 char d;
7760 CONST struct asm_flg *flag = opcode->flags;
7761
7762 if (flag)
7763 {
7764 int flagno;
7765
7766 d = *p;
7767 *p = '\0';
7768
7769 for (flagno = 0; flag[flagno].template; flagno++)
7770 {
7771 if (streq (r, flag[flagno].template))
7772 {
7773 flag_bits |= flag[flagno].set_bits;
7774 break;
7775 }
7776 }
7777
7778 *p = d;
7779 if (! flag[flagno].template)
7780 goto try_shorter;
7781 }
7782 else
7783 goto try_shorter;
7784 }
7785
7786 (*opcode->parms) (p, flag_bits);
7787 output_inst ();
7788 return;
7789 }
7790
7791 try_shorter:
7792 ;
7793 }
7794 }
7795
7796 /* It wasn't an instruction, but it might be a register alias of the form
7797 alias .req reg. */
7798 q = p;
7799 skip_whitespace (q);
7800
7801 c = *p;
7802 *p = '\0';
7803
7804 if (*q && !strncmp (q, ".req ", 4))
7805 {
7806 int reg;
7807 char * copy_of_str;
7808 char * r;
7809
7810 #ifdef IGNORE_OPCODE_CASE
7811 str = original_case_string;
7812 #endif
7813 copy_of_str = str;
7814
7815 q += 4;
7816 skip_whitespace (q);
7817
7818 for (r = q; *r != '\0'; r++)
7819 if (*r == ' ')
7820 break;
7821
7822 if (r != q)
7823 {
7824 int regnum;
7825 char d = *r;
7826
7827 *r = '\0';
7828 regnum = arm_reg_parse (& q);
7829 *r = d;
7830
7831 reg = arm_reg_parse (& str);
7832
7833 if (reg == FAIL)
7834 {
7835 if (regnum != FAIL)
7836 insert_reg_alias (str, regnum);
7837 else
7838 as_warn (_("register '%s' does not exist\n"), q);
7839 }
7840 else if (regnum != FAIL)
7841 {
7842 if (reg != regnum)
7843 as_warn (_("ignoring redefinition of register alias '%s'"),
7844 copy_of_str);
7845
7846 /* Do not warn about redefinitions to the same alias. */
7847 }
7848 else
7849 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
7850 copy_of_str, q);
7851 }
7852 else
7853 as_warn (_("ignoring incomplete .req pseuso op"));
7854
7855 *p = c;
7856 return;
7857 }
7858
7859 *p = c;
7860 as_bad (_("bad instruction `%s'"), start);
7861 }
7862
7863 /* md_parse_option
7864 Invocation line includes a switch not recognized by the base assembler.
7865 See if it's a processor-specific option. These are:
7866 Cpu variants, the arm part is optional:
7867 -m[arm]1 Currently not supported.
7868 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
7869 -m[arm]3 Arm 3 processor
7870 -m[arm]6[xx], Arm 6 processors
7871 -m[arm]7[xx][t][[d]m] Arm 7 processors
7872 -m[arm]8[10] Arm 8 processors
7873 -m[arm]9[20][tdmi] Arm 9 processors
7874 -mstrongarm[110[0]] StrongARM processors
7875 -mxscale XScale processors
7876 -m[arm]v[2345[t[e]]] Arm architectures
7877 -mall All (except the ARM1)
7878 FP variants:
7879 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
7880 -mfpe-old (No float load/store multiples)
7881 -mno-fpu Disable all floating point instructions
7882 Run-time endian selection:
7883 -EB big endian cpu
7884 -EL little endian cpu
7885 ARM Procedure Calling Standard:
7886 -mapcs-32 32 bit APCS
7887 -mapcs-26 26 bit APCS
7888 -mapcs-float Pass floats in float regs
7889 -mapcs-reentrant Position independent code
7890 -mthumb-interwork Code supports Arm/Thumb interworking
7891 -matpcs ARM/Thumb Procedure Call Standard
7892 -moabi Old ELF ABI */
7893
7894 CONST char * md_shortopts = "m:k";
7895
7896 struct option md_longopts[] =
7897 {
7898 #ifdef ARM_BI_ENDIAN
7899 #define OPTION_EB (OPTION_MD_BASE + 0)
7900 {"EB", no_argument, NULL, OPTION_EB},
7901 #define OPTION_EL (OPTION_MD_BASE + 1)
7902 {"EL", no_argument, NULL, OPTION_EL},
7903 #ifdef OBJ_ELF
7904 #define OPTION_OABI (OPTION_MD_BASE +2)
7905 {"oabi", no_argument, NULL, OPTION_OABI},
7906 #endif
7907 #endif
7908 {NULL, no_argument, NULL, 0}
7909 };
7910
7911 size_t md_longopts_size = sizeof (md_longopts);
7912
7913 int
7914 md_parse_option (c, arg)
7915 int c;
7916 char * arg;
7917 {
7918 char * str = arg;
7919
7920 switch (c)
7921 {
7922 #ifdef ARM_BI_ENDIAN
7923 case OPTION_EB:
7924 target_big_endian = 1;
7925 break;
7926 case OPTION_EL:
7927 target_big_endian = 0;
7928 break;
7929 #endif
7930
7931 case 'm':
7932 switch (*str)
7933 {
7934 case 'f':
7935 if (streq (str, "fpa10"))
7936 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
7937 else if (streq (str, "fpa11"))
7938 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
7939 else if (streq (str, "fpe-old"))
7940 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
7941 else
7942 goto bad;
7943 break;
7944
7945 case 'n':
7946 if (streq (str, "no-fpu"))
7947 cpu_variant &= ~FPU_ALL;
7948 break;
7949
7950 #ifdef OBJ_ELF
7951 case 'o':
7952 if (streq (str, "oabi"))
7953 target_oabi = true;
7954 break;
7955 #endif
7956
7957 case 't':
7958 /* Limit assembler to generating only Thumb instructions: */
7959 if (streq (str, "thumb"))
7960 {
7961 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_EXT_THUMB;
7962 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
7963 thumb_mode = 1;
7964 }
7965 else if (streq (str, "thumb-interwork"))
7966 {
7967 if ((cpu_variant & ARM_EXT_THUMB) == 0)
7968 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T;
7969 #if defined OBJ_COFF || defined OBJ_ELF
7970 support_interwork = true;
7971 #endif
7972 }
7973 else
7974 goto bad;
7975 break;
7976
7977 default:
7978 if (streq (str, "all"))
7979 {
7980 cpu_variant = ARM_ALL | FPU_ALL;
7981 return 1;
7982 }
7983 #if defined OBJ_COFF || defined OBJ_ELF
7984 if (! strncmp (str, "apcs-", 5))
7985 {
7986 /* GCC passes on all command line options starting "-mapcs-..."
7987 to us, so we must parse them here. */
7988
7989 str += 5;
7990
7991 if (streq (str, "32"))
7992 {
7993 uses_apcs_26 = false;
7994 return 1;
7995 }
7996 else if (streq (str, "26"))
7997 {
7998 uses_apcs_26 = true;
7999 return 1;
8000 }
8001 else if (streq (str, "frame"))
8002 {
8003 /* Stack frames are being generated - does not affect
8004 linkage of code. */
8005 return 1;
8006 }
8007 else if (streq (str, "stack-check"))
8008 {
8009 /* Stack checking is being performed - does not affect
8010 linkage, but does require that the functions
8011 __rt_stkovf_split_small and __rt_stkovf_split_big be
8012 present in the final link. */
8013
8014 return 1;
8015 }
8016 else if (streq (str, "float"))
8017 {
8018 /* Floating point arguments are being passed in the floating
8019 point registers. This does affect linking, since this
8020 version of the APCS is incompatible with the version that
8021 passes floating points in the integer registers. */
8022
8023 uses_apcs_float = true;
8024 return 1;
8025 }
8026 else if (streq (str, "reentrant"))
8027 {
8028 /* Reentrant code has been generated. This does affect
8029 linking, since there is no point in linking reentrant/
8030 position independent code with absolute position code. */
8031 pic_code = true;
8032 return 1;
8033 }
8034
8035 as_bad (_("Unrecognised APCS switch -m%s"), arg);
8036 return 0;
8037 }
8038
8039 if (! strcmp (str, "atpcs"))
8040 {
8041 atpcs = true;
8042 return 1;
8043 }
8044 #endif
8045 /* Strip off optional "arm". */
8046 if (! strncmp (str, "arm", 3))
8047 str += 3;
8048
8049 switch (*str)
8050 {
8051 case '1':
8052 if (streq (str, "1"))
8053 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
8054 else
8055 goto bad;
8056 break;
8057
8058 case '2':
8059 if (streq (str, "2"))
8060 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
8061 else if (streq (str, "250"))
8062 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
8063 else
8064 goto bad;
8065 break;
8066
8067 case '3':
8068 if (streq (str, "3"))
8069 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
8070 else
8071 goto bad;
8072 break;
8073
8074 case '6':
8075 switch (strtol (str, NULL, 10))
8076 {
8077 case 6:
8078 case 60:
8079 case 600:
8080 case 610:
8081 case 620:
8082 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
8083 break;
8084 default:
8085 goto bad;
8086 }
8087 break;
8088
8089 case '7':
8090 /* Eat the processor name. */
8091 switch (strtol (str, & str, 10))
8092 {
8093 case 7:
8094 case 70:
8095 case 700:
8096 case 710:
8097 case 720:
8098 case 7100:
8099 case 7500:
8100 break;
8101 default:
8102 goto bad;
8103 }
8104 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
8105 for (; *str; str++)
8106 {
8107 switch (*str)
8108 {
8109 case 't':
8110 cpu_variant |= ARM_ARCH_V4T;
8111 break;
8112
8113 case 'm':
8114 cpu_variant |= ARM_EXT_LONGMUL;
8115 break;
8116
8117 case 'f': /* fe => fp enabled cpu. */
8118 if (str[1] == 'e')
8119 ++ str;
8120 else
8121 goto bad;
8122
8123 case 'c': /* Left over from 710c processor name. */
8124 case 'd': /* Debug. */
8125 case 'i': /* Embedded ICE. */
8126 /* Included for completeness in ARM processor naming. */
8127 break;
8128
8129 default:
8130 goto bad;
8131 }
8132 }
8133 break;
8134
8135 case '8':
8136 if (streq (str, "8") || streq (str, "810"))
8137 cpu_variant = (cpu_variant & ~ARM_ANY)
8138 | ARM_8 | ARM_ARCH_V4;
8139 else
8140 goto bad;
8141 break;
8142
8143 case '9':
8144 if (streq (str, "9"))
8145 cpu_variant = (cpu_variant & ~ARM_ANY)
8146 | ARM_9 | ARM_ARCH_V4T;
8147 else if (streq (str, "920"))
8148 cpu_variant = (cpu_variant & ~ARM_ANY)
8149 | ARM_9 | ARM_ARCH_V4;
8150 else if (streq (str, "920t"))
8151 cpu_variant = (cpu_variant & ~ARM_ANY)
8152 | ARM_9 | ARM_ARCH_V4T;
8153 else if (streq (str, "9tdmi"))
8154 cpu_variant = (cpu_variant & ~ARM_ANY)
8155 | ARM_9 | ARM_ARCH_V4T;
8156 else
8157 goto bad;
8158 break;
8159
8160 case 's':
8161 if (streq (str, "strongarm")
8162 || streq (str, "strongarm110")
8163 || streq (str, "strongarm1100"))
8164 cpu_variant = (cpu_variant & ~ARM_ANY)
8165 | ARM_8 | ARM_ARCH_V4;
8166 else
8167 goto bad;
8168 break;
8169
8170 case 'x':
8171 if (streq (str, "xscale"))
8172 cpu_variant = ARM_9 | ARM_ARCH_XSCALE;
8173 else
8174 goto bad;
8175 break;
8176
8177 case 'v':
8178 /* Select variant based on architecture rather than
8179 processor. */
8180 switch (*++str)
8181 {
8182 case '2':
8183 switch (*++str)
8184 {
8185 case 'a':
8186 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
8187 break;
8188 case 0:
8189 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
8190 break;
8191 default:
8192 as_bad (_("Invalid architecture variant -m%s"), arg);
8193 break;
8194 }
8195 break;
8196
8197 case '3':
8198 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
8199
8200 switch (*++str)
8201 {
8202 case 'm': cpu_variant |= ARM_EXT_LONGMUL; break;
8203 case 0: break;
8204 default:
8205 as_bad (_("Invalid architecture variant -m%s"), arg);
8206 break;
8207 }
8208 break;
8209
8210 case '4':
8211 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCH_V4;
8212
8213 switch (*++str)
8214 {
8215 case 't': cpu_variant |= ARM_EXT_THUMB; break;
8216 case 0: break;
8217 default:
8218 as_bad (_("Invalid architecture variant -m%s"), arg);
8219 break;
8220 }
8221 break;
8222
8223 case '5':
8224 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V5;
8225 switch (*++str)
8226 {
8227 case 't': cpu_variant |= ARM_EXT_THUMB; break;
8228 case 'e': cpu_variant |= ARM_EXT_V5E; break;
8229 case 0: break;
8230 default:
8231 as_bad (_("Invalid architecture variant -m%s"), arg);
8232 break;
8233 }
8234 break;
8235
8236 default:
8237 as_bad (_("Invalid architecture variant -m%s"), arg);
8238 break;
8239 }
8240 break;
8241
8242 default:
8243 bad:
8244 as_bad (_("Invalid processor variant -m%s"), arg);
8245 return 0;
8246 }
8247 }
8248 break;
8249
8250 #if defined OBJ_ELF || defined OBJ_COFF
8251 case 'k':
8252 pic_code = 1;
8253 break;
8254 #endif
8255
8256 default:
8257 return 0;
8258 }
8259
8260 return 1;
8261 }
8262
8263 void
8264 md_show_usage (fp)
8265 FILE * fp;
8266 {
8267 fprintf (fp, _("\
8268 ARM Specific Assembler Options:\n\
8269 -m[arm][<processor name>] select processor variant\n\
8270 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
8271 -mthumb only allow Thumb instructions\n\
8272 -mthumb-interwork mark the assembled code as supporting interworking\n\
8273 -mall allow any instruction\n\
8274 -mfpa10, -mfpa11 select floating point architecture\n\
8275 -mfpe-old don't allow floating-point multiple instructions\n\
8276 -mno-fpu don't allow any floating-point instructions.\n\
8277 -k generate PIC code.\n"));
8278 #if defined OBJ_COFF || defined OBJ_ELF
8279 fprintf (fp, _("\
8280 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
8281 -matpcs use ARM/Thumb Procedure Calling Standard\n\
8282 -mapcs-float floating point args are passed in FP regs\n\
8283 -mapcs-reentrant the code is position independent/reentrant\n"));
8284 #endif
8285 #ifdef OBJ_ELF
8286 fprintf (fp, _("\
8287 -moabi support the old ELF ABI\n"));
8288 #endif
8289 #ifdef ARM_BI_ENDIAN
8290 fprintf (fp, _("\
8291 -EB assemble code for a big endian cpu\n\
8292 -EL assemble code for a little endian cpu\n"));
8293 #endif
8294 }
8295
8296 /* We need to be able to fix up arbitrary expressions in some statements.
8297 This is so that we can handle symbols that are an arbitrary distance from
8298 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
8299 which returns part of an address in a form which will be valid for
8300 a data instruction. We do this by pushing the expression into a symbol
8301 in the expr_section, and creating a fix for that. */
8302
8303 static void
8304 fix_new_arm (frag, where, size, exp, pc_rel, reloc)
8305 fragS * frag;
8306 int where;
8307 short int size;
8308 expressionS * exp;
8309 int pc_rel;
8310 int reloc;
8311 {
8312 fixS * new_fix;
8313 arm_fix_data * arm_data;
8314
8315 switch (exp->X_op)
8316 {
8317 case O_constant:
8318 case O_symbol:
8319 case O_add:
8320 case O_subtract:
8321 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
8322 break;
8323
8324 default:
8325 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
8326 pc_rel, reloc);
8327 break;
8328 }
8329
8330 /* Mark whether the fix is to a THUMB instruction, or an ARM
8331 instruction. */
8332 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
8333 new_fix->tc_fix_data = (PTR) arm_data;
8334 arm_data->thumb_mode = thumb_mode;
8335
8336 return;
8337 }
8338
8339 /* This fix_new is called by cons via TC_CONS_FIX_NEW. */
8340
8341 void
8342 cons_fix_new_arm (frag, where, size, exp)
8343 fragS * frag;
8344 int where;
8345 int size;
8346 expressionS * exp;
8347 {
8348 bfd_reloc_code_real_type type;
8349 int pcrel = 0;
8350
8351 /* Pick a reloc.
8352 FIXME: @@ Should look at CPU word size. */
8353 switch (size)
8354 {
8355 case 1:
8356 type = BFD_RELOC_8;
8357 break;
8358 case 2:
8359 type = BFD_RELOC_16;
8360 break;
8361 case 4:
8362 default:
8363 type = BFD_RELOC_32;
8364 break;
8365 case 8:
8366 type = BFD_RELOC_64;
8367 break;
8368 }
8369
8370 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
8371 }
8372
8373 /* A good place to do this, although this was probably not intended
8374 for this kind of use. We need to dump the literal pool before
8375 references are made to a null symbol pointer. */
8376
8377 void
8378 arm_cleanup ()
8379 {
8380 if (current_poolP == NULL)
8381 return;
8382
8383 /* Put it at the end of text section. */
8384 subseg_set (text_section, 0);
8385 s_ltorg (0);
8386 listing_prev_line ();
8387 }
8388
8389 void
8390 arm_start_line_hook ()
8391 {
8392 last_label_seen = NULL;
8393 }
8394
8395 void
8396 arm_frob_label (sym)
8397 symbolS * sym;
8398 {
8399 last_label_seen = sym;
8400
8401 ARM_SET_THUMB (sym, thumb_mode);
8402
8403 #if defined OBJ_COFF || defined OBJ_ELF
8404 ARM_SET_INTERWORK (sym, support_interwork);
8405 #endif
8406
8407 if (label_is_thumb_function_name)
8408 {
8409 /* When the address of a Thumb function is taken the bottom
8410 bit of that address should be set. This will allow
8411 interworking between Arm and Thumb functions to work
8412 correctly. */
8413
8414 THUMB_SET_FUNC (sym, 1);
8415
8416 label_is_thumb_function_name = false;
8417 }
8418 }
8419
8420 /* Adjust the symbol table. This marks Thumb symbols as distinct from
8421 ARM ones. */
8422
8423 void
8424 arm_adjust_symtab ()
8425 {
8426 #ifdef OBJ_COFF
8427 symbolS * sym;
8428
8429 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
8430 {
8431 if (ARM_IS_THUMB (sym))
8432 {
8433 if (THUMB_IS_FUNC (sym))
8434 {
8435 /* Mark the symbol as a Thumb function. */
8436 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
8437 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
8438 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
8439
8440 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
8441 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
8442 else
8443 as_bad (_("%s: unexpected function type: %d"),
8444 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
8445 }
8446 else switch (S_GET_STORAGE_CLASS (sym))
8447 {
8448 case C_EXT:
8449 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
8450 break;
8451 case C_STAT:
8452 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
8453 break;
8454 case C_LABEL:
8455 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
8456 break;
8457 default:
8458 /* Do nothing. */
8459 break;
8460 }
8461 }
8462
8463 if (ARM_IS_INTERWORK (sym))
8464 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
8465 }
8466 #endif
8467 #ifdef OBJ_ELF
8468 symbolS * sym;
8469 char bind;
8470
8471 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
8472 {
8473 if (ARM_IS_THUMB (sym))
8474 {
8475 elf_symbol_type * elf_sym;
8476
8477 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
8478 bind = ELF_ST_BIND (elf_sym);
8479
8480 /* If it's a .thumb_func, declare it as so,
8481 otherwise tag label as .code 16. */
8482 if (THUMB_IS_FUNC (sym))
8483 elf_sym->internal_elf_sym.st_info =
8484 ELF_ST_INFO (bind, STT_ARM_TFUNC);
8485 else
8486 elf_sym->internal_elf_sym.st_info =
8487 ELF_ST_INFO (bind, STT_ARM_16BIT);
8488 }
8489 }
8490 #endif
8491 }
8492
8493 int
8494 arm_data_in_code ()
8495 {
8496 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
8497 {
8498 *input_line_pointer = '/';
8499 input_line_pointer += 5;
8500 *input_line_pointer = 0;
8501 return 1;
8502 }
8503
8504 return 0;
8505 }
8506
8507 char *
8508 arm_canonicalize_symbol_name (name)
8509 char * name;
8510 {
8511 int len;
8512
8513 if (thumb_mode && (len = strlen (name)) > 5
8514 && streq (name + len - 5, "/data"))
8515 *(name + len - 5) = 0;
8516
8517 return name;
8518 }
8519
8520 boolean
8521 arm_validate_fix (fixP)
8522 fixS * fixP;
8523 {
8524 /* If the destination of the branch is a defined symbol which does not have
8525 the THUMB_FUNC attribute, then we must be calling a function which has
8526 the (interfacearm) attribute. We look for the Thumb entry point to that
8527 function and change the branch to refer to that function instead. */
8528 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
8529 && fixP->fx_addsy != NULL
8530 && S_IS_DEFINED (fixP->fx_addsy)
8531 && ! THUMB_IS_FUNC (fixP->fx_addsy))
8532 {
8533 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
8534 return true;
8535 }
8536
8537 return false;
8538 }
8539
8540 #ifdef OBJ_ELF
8541 /* Relocations against Thumb function names must be left unadjusted,
8542 so that the linker can use this information to correctly set the
8543 bottom bit of their addresses. The MIPS version of this function
8544 also prevents relocations that are mips-16 specific, but I do not
8545 know why it does this.
8546
8547 FIXME:
8548 There is one other problem that ought to be addressed here, but
8549 which currently is not: Taking the address of a label (rather
8550 than a function) and then later jumping to that address. Such
8551 addresses also ought to have their bottom bit set (assuming that
8552 they reside in Thumb code), but at the moment they will not. */
8553
8554 boolean
8555 arm_fix_adjustable (fixP)
8556 fixS * fixP;
8557 {
8558 if (fixP->fx_addsy == NULL)
8559 return 1;
8560
8561 /* Prevent all adjustments to global symbols. */
8562 if (S_IS_EXTERN (fixP->fx_addsy))
8563 return 0;
8564
8565 if (S_IS_WEAK (fixP->fx_addsy))
8566 return 0;
8567
8568 if (THUMB_IS_FUNC (fixP->fx_addsy)
8569 && fixP->fx_subsy == NULL)
8570 return 0;
8571
8572 /* We need the symbol name for the VTABLE entries. */
8573 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
8574 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
8575 return 0;
8576
8577 return 1;
8578 }
8579
8580 const char *
8581 elf32_arm_target_format ()
8582 {
8583 if (target_big_endian)
8584 {
8585 if (target_oabi)
8586 return "elf32-bigarm-oabi";
8587 else
8588 return "elf32-bigarm";
8589 }
8590 else
8591 {
8592 if (target_oabi)
8593 return "elf32-littlearm-oabi";
8594 else
8595 return "elf32-littlearm";
8596 }
8597 }
8598
8599 void
8600 armelf_frob_symbol (symp, puntp)
8601 symbolS * symp;
8602 int * puntp;
8603 {
8604 elf_frob_symbol (symp, puntp);
8605 }
8606
8607 int
8608 arm_force_relocation (fixp)
8609 struct fix * fixp;
8610 {
8611 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
8612 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
8613 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
8614 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
8615 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
8616 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
8617 return 1;
8618
8619 return 0;
8620 }
8621
8622 static bfd_reloc_code_real_type
8623 arm_parse_reloc ()
8624 {
8625 char id [16];
8626 char * ip;
8627 unsigned int i;
8628 static struct
8629 {
8630 char * str;
8631 int len;
8632 bfd_reloc_code_real_type reloc;
8633 }
8634 reloc_map[] =
8635 {
8636 #define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
8637 MAP ("(got)", BFD_RELOC_ARM_GOT32),
8638 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
8639 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
8640 branch instructions generated by GCC for PLT relocs. */
8641 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
8642 { NULL, 0, BFD_RELOC_UNUSED }
8643 #undef MAP
8644 };
8645
8646 for (i = 0, ip = input_line_pointer;
8647 i < sizeof (id) && (isalnum (*ip) || ispunct (*ip));
8648 i++, ip++)
8649 id[i] = tolower (*ip);
8650
8651 for (i = 0; reloc_map[i].str; i++)
8652 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
8653 break;
8654
8655 input_line_pointer += reloc_map[i].len;
8656
8657 return reloc_map[i].reloc;
8658 }
8659
8660 static void
8661 s_arm_elf_cons (nbytes)
8662 int nbytes;
8663 {
8664 expressionS exp;
8665
8666 #ifdef md_flush_pending_output
8667 md_flush_pending_output ();
8668 #endif
8669
8670 if (is_it_end_of_statement ())
8671 {
8672 demand_empty_rest_of_line ();
8673 return;
8674 }
8675
8676 #ifdef md_cons_align
8677 md_cons_align (nbytes);
8678 #endif
8679
8680 do
8681 {
8682 bfd_reloc_code_real_type reloc;
8683
8684 expression (& exp);
8685
8686 if (exp.X_op == O_symbol
8687 && * input_line_pointer == '('
8688 && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
8689 {
8690 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
8691 int size = bfd_get_reloc_size (howto);
8692
8693 if (size > nbytes)
8694 as_bad ("%s relocations do not fit in %d bytes",
8695 howto->name, nbytes);
8696 else
8697 {
8698 register char *p = frag_more ((int) nbytes);
8699 int offset = nbytes - size;
8700
8701 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
8702 &exp, 0, reloc);
8703 }
8704 }
8705 else
8706 emit_expr (&exp, (unsigned int) nbytes);
8707 }
8708 while (*input_line_pointer++ == ',');
8709
8710 /* Put terminator back into stream. */
8711 input_line_pointer --;
8712 demand_empty_rest_of_line ();
8713 }
8714
8715 #endif /* OBJ_ELF */
This page took 0.243234 seconds and 4 git commands to generate.