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