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