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