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