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