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