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