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