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