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