]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-arm.c
* bfd/config.bfd (targ_cpu): Add arm9e-*-elf.
[thirdparty/binutils-gdb.git] / gas / config / tc-arm.c
CommitLineData
b99bd4ef
NC
1/* tc-arm.c -- Assemble for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001
3 Free Software Foundation, Inc.
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
b99bd4ef
NC
24#include <string.h>
25#define NO_RELOC 0
26#include "as.h"
3882b010 27#include "safe-ctype.h"
b99bd4ef
NC
28
29/* Need TARGET_CPU. */
30#include "config.h"
31#include "subsegs.h"
32#include "obstack.h"
33#include "symbols.h"
34#include "listing.h"
35
36#ifdef OBJ_ELF
37#include "elf/arm.h"
38#include "dwarf2dbg.h"
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
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. */
50#define ARM_CPU_MASK 0x0000000f
51
52/* The following bitmasks control CPU extensions (ARM7 onwards): */
53#define ARM_EXT_LONGMUL 0x00000010 /* Allow long multiplies. */
54#define ARM_EXT_HALFWORD 0x00000020 /* Allow half word loads. */
55#define ARM_EXT_THUMB 0x00000040 /* Allow BX instruction. */
56#define ARM_EXT_V5 0x00000080 /* Allow CLZ, etc. */
57#define ARM_EXT_V5E 0x00000100 /* "El Segundo". */
58#define ARM_EXT_XSCALE 0x00000200 /* Allow MIA etc. */
404ff6b5 59#define ARM_EXT_MAVERIK 0x00000400 /* Use Cirrus/DSP coprocessor. */
b99bd4ef
NC
60
61/* Architectures are the sum of the base and extensions. */
62#define ARM_ARCH_V3M ARM_EXT_LONGMUL
63#define ARM_ARCH_V4 (ARM_ARCH_V3M | ARM_EXT_HALFWORD)
64#define ARM_ARCH_V4T (ARM_ARCH_V4 | ARM_EXT_THUMB)
65#define ARM_ARCH_V5 (ARM_ARCH_V4 | ARM_EXT_V5)
66#define ARM_ARCH_V5T (ARM_ARCH_V5 | ARM_EXT_THUMB)
67#define ARM_ARCH_V5TE (ARM_ARCH_V5T | ARM_EXT_V5E)
68#define ARM_ARCH_XSCALE (ARM_ARCH_V5TE | ARM_EXT_XSCALE)
69
70/* Some useful combinations: */
71#define ARM_ANY 0x00ffffff
72#define ARM_2UP (ARM_ANY - ARM_1)
73#define ARM_ALL ARM_2UP /* Not arm1 only. */
74#define ARM_3UP 0x00fffffc
75#define ARM_6UP 0x00fffff8 /* Includes ARM7. */
76
77#define FPU_CORE 0x80000000
78#define FPU_FPA10 0x40000000
79#define FPU_FPA11 0x40000000
80#define FPU_NONE 0
81
82/* Some useful combinations. */
83#define FPU_ALL 0xff000000 /* Note this is ~ARM_ANY. */
84#define FPU_MEMMULTI 0x7f000000 /* Not fpu_core. */
85
86#ifndef CPU_DEFAULT
87#if defined __XSCALE__
88#define CPU_DEFAULT (ARM_9 | ARM_ARCH_XSCALE)
89#else
90#if defined __thumb__
91#define CPU_DEFAULT (ARM_7 | ARM_ARCH_V4T)
92#else
93#define CPU_DEFAULT ARM_ALL
94#endif
95#endif
96#endif
97
98#ifndef FPU_DEFAULT
99#define FPU_DEFAULT FPU_ALL
100#endif
101
102#define streq(a, b) (strcmp (a, b) == 0)
103#define skip_whitespace(str) while (*(str) == ' ') ++(str)
104
105static unsigned long cpu_variant = CPU_DEFAULT | FPU_DEFAULT;
106static int target_oabi = 0;
107
108#if defined OBJ_COFF || defined OBJ_ELF
109/* Flags stored in private area of BFD structure. */
110static boolean uses_apcs_26 = false;
111static boolean atpcs = false;
112static boolean support_interwork = false;
113static boolean uses_apcs_float = false;
114static boolean pic_code = false;
115#endif
116
117/* This array holds the chars that always start a comment. If the
118 pre-processor is disabled, these aren't very useful. */
119CONST char comment_chars[] = "@";
120
121/* This array holds the chars that only start a comment at the beginning of
122 a line. If the line seems to have the form '# 123 filename'
123 .line and .file directives will appear in the pre-processed output. */
124/* Note that input_file.c hand checks for '#' at the beginning of the
125 first line of the input file. This is because the compiler outputs
126 #NO_APP at the beginning of its output. */
127/* Also note that comments like this one will always work. */
128CONST char line_comment_chars[] = "#";
129
130CONST char line_separator_chars[] = ";";
131
132/* Chars that can be used to separate mant
133 from exp in floating point numbers. */
134CONST char EXP_CHARS[] = "eE";
135
136/* Chars that mean this number is a floating point constant. */
137/* As in 0f12.456 */
138/* or 0d1.2345e12 */
139
140CONST char FLT_CHARS[] = "rRsSfFdDxXeEpP";
141
142/* Prefix characters that indicate the start of an immediate
143 value. */
144#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
145
146#ifdef OBJ_ELF
147/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
148symbolS * GOT_symbol;
149#endif
150
151/* Size of relocation record. */
152CONST int md_reloc_size = 8;
153
154/* 0: assemble for ARM,
155 1: assemble for Thumb,
156 2: assemble for Thumb even though target CPU does not support thumb
157 instructions. */
158static int thumb_mode = 0;
159
160typedef struct arm_fix
161{
162 int thumb_mode;
163} arm_fix_data;
164
165struct arm_it
166{
167 CONST char * error;
168 unsigned long instruction;
169 int suffix;
170 int size;
171 struct
172 {
173 bfd_reloc_code_real_type type;
174 expressionS exp;
175 int pc_rel;
176 } reloc;
177};
178
179struct arm_it inst;
180
181enum asm_shift_index
182{
183 SHIFT_LSL = 0,
184 SHIFT_LSR,
185 SHIFT_ASR,
186 SHIFT_ROR,
187 SHIFT_RRX
188};
189
190struct asm_shift_properties
191{
192 enum asm_shift_index index;
193 unsigned long bit_field;
194 unsigned int allows_0 : 1;
195 unsigned int allows_32 : 1;
196};
197
198static const struct asm_shift_properties shift_properties [] =
199{
200 { SHIFT_LSL, 0, 1, 0},
201 { SHIFT_LSR, 0x20, 0, 1},
202 { SHIFT_ASR, 0x40, 0, 1},
203 { SHIFT_ROR, 0x60, 0, 0},
204 { SHIFT_RRX, 0x60, 0, 0}
205};
206
207struct asm_shift_name
208{
209 const char * name;
210 const struct asm_shift_properties * properties;
211};
212
213static const struct asm_shift_name shift_names [] =
214{
215 { "asl", shift_properties + SHIFT_LSL },
216 { "lsl", shift_properties + SHIFT_LSL },
217 { "lsr", shift_properties + SHIFT_LSR },
218 { "asr", shift_properties + SHIFT_ASR },
219 { "ror", shift_properties + SHIFT_ROR },
220 { "rrx", shift_properties + SHIFT_RRX },
221 { "ASL", shift_properties + SHIFT_LSL },
222 { "LSL", shift_properties + SHIFT_LSL },
223 { "LSR", shift_properties + SHIFT_LSR },
224 { "ASR", shift_properties + SHIFT_ASR },
225 { "ROR", shift_properties + SHIFT_ROR },
226 { "RRX", shift_properties + SHIFT_RRX }
227};
228
229#define NO_SHIFT_RESTRICT 1
230#define SHIFT_RESTRICT 0
231
232#define NUM_FLOAT_VALS 8
233
234CONST char * fp_const[] =
235{
236 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
237};
238
239/* Number of littlenums required to hold an extended precision number. */
240#define MAX_LITTLENUMS 6
241
242LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
243
244#define FAIL (-1)
245#define SUCCESS (0)
246
247#define SUFF_S 1
248#define SUFF_D 2
249#define SUFF_E 3
250#define SUFF_P 4
251
252#define CP_T_X 0x00008000
253#define CP_T_Y 0x00400000
254#define CP_T_Pre 0x01000000
255#define CP_T_UD 0x00800000
256#define CP_T_WB 0x00200000
257
258#define CONDS_BIT 0x00100000
259#define LOAD_BIT 0x00100000
260#define TRANS_BIT 0x00200000
261
262#define DOUBLE_LOAD_FLAG 0x00000001
263
264struct asm_cond
265{
266 CONST char * template;
267 unsigned long value;
268};
269
270/* This is to save a hash look-up in the common case. */
271#define COND_ALWAYS 0xe0000000
272
273static CONST struct asm_cond conds[] =
274{
275 {"eq", 0x00000000},
276 {"ne", 0x10000000},
277 {"cs", 0x20000000}, {"hs", 0x20000000},
278 {"cc", 0x30000000}, {"ul", 0x30000000}, {"lo", 0x30000000},
279 {"mi", 0x40000000},
280 {"pl", 0x50000000},
281 {"vs", 0x60000000},
282 {"vc", 0x70000000},
283 {"hi", 0x80000000},
284 {"ls", 0x90000000},
285 {"ge", 0xa0000000},
286 {"lt", 0xb0000000},
287 {"gt", 0xc0000000},
288 {"le", 0xd0000000},
289 {"al", 0xe0000000},
290 {"nv", 0xf0000000}
291};
292
293/* Warning: If the top bit of the set_bits is set, then the standard
294 instruction bitmask is ignored, and the new bitmask is taken from
295 the set_bits: */
296struct asm_flg
297{
298 CONST char * template; /* Basic flag string. */
299 unsigned long set_bits; /* Bits to set. */
300};
301
302static CONST struct asm_flg s_flag[] =
303{
304 {"s", CONDS_BIT},
305 {NULL, 0}
306};
307
308static CONST struct asm_flg ldr_flags[] =
309{
310 {"d", DOUBLE_LOAD_FLAG},
311 {"b", 0x00400000},
312 {"t", TRANS_BIT},
313 {"bt", 0x00400000 | TRANS_BIT},
314 {"h", 0x801000b0},
315 {"sh", 0x801000f0},
316 {"sb", 0x801000d0},
317 {NULL, 0}
318};
319
320static CONST struct asm_flg str_flags[] =
321{
322 {"d", DOUBLE_LOAD_FLAG},
323 {"b", 0x00400000},
324 {"t", TRANS_BIT},
325 {"bt", 0x00400000 | TRANS_BIT},
326 {"h", 0x800000b0},
327 {NULL, 0}
328};
329
330static CONST struct asm_flg byte_flag[] =
331{
332 {"b", 0x00400000},
333 {NULL, 0}
334};
335
336static CONST struct asm_flg cmp_flags[] =
337{
338 {"s", CONDS_BIT},
339 {"p", 0x0010f000},
340 {NULL, 0}
341};
342
343static CONST struct asm_flg ldm_flags[] =
344{
345 {"ed", 0x01800000},
346 {"fd", 0x00800000},
347 {"ea", 0x01000000},
348 {"fa", 0x00000000},
349 {"ib", 0x01800000},
350 {"ia", 0x00800000},
351 {"db", 0x01000000},
352 {"da", 0x00000000},
353 {NULL, 0}
354};
355
356static CONST struct asm_flg stm_flags[] =
357{
358 {"ed", 0x00000000},
359 {"fd", 0x01000000},
360 {"ea", 0x00800000},
361 {"fa", 0x01800000},
362 {"ib", 0x01800000},
363 {"ia", 0x00800000},
364 {"db", 0x01000000},
365 {"da", 0x00000000},
366 {NULL, 0}
367};
368
369static CONST struct asm_flg lfm_flags[] =
370{
371 {"fd", 0x00800000},
372 {"ea", 0x01000000},
373 {NULL, 0}
374};
375
376static CONST struct asm_flg sfm_flags[] =
377{
378 {"fd", 0x01000000},
379 {"ea", 0x00800000},
380 {NULL, 0}
381};
382
383static CONST struct asm_flg round_flags[] =
384{
385 {"p", 0x00000020},
386 {"m", 0x00000040},
387 {"z", 0x00000060},
388 {NULL, 0}
389};
390
391/* The implementation of the FIX instruction is broken on some assemblers,
392 in that it accepts a precision specifier as well as a rounding specifier,
393 despite the fact that this is meaningless. To be more compatible, we
394 accept it as well, though of course it does not set any bits. */
395static CONST struct asm_flg fix_flags[] =
396{
397 {"p", 0x00000020},
398 {"m", 0x00000040},
399 {"z", 0x00000060},
400 {"sp", 0x00000020},
401 {"sm", 0x00000040},
402 {"sz", 0x00000060},
403 {"dp", 0x00000020},
404 {"dm", 0x00000040},
405 {"dz", 0x00000060},
406 {"ep", 0x00000020},
407 {"em", 0x00000040},
408 {"ez", 0x00000060},
409 {NULL, 0}
410};
411
412static CONST struct asm_flg except_flag[] =
413{
414 {"e", 0x00400000},
415 {NULL, 0}
416};
417
1cac9012 418static CONST struct asm_flg long_flag[] =
b99bd4ef
NC
419{
420 {"l", 0x00400000},
421 {NULL, 0}
422};
423
424struct asm_psr
425{
426 CONST char * template;
427 boolean cpsr;
428 unsigned long field;
429};
430
431/* The bit that distnguishes CPSR and SPSR. */
432#define SPSR_BIT (1 << 22)
433
434/* How many bits to shift the PSR_xxx bits up by. */
435#define PSR_SHIFT 16
436
437#define PSR_c (1 << 0)
438#define PSR_x (1 << 1)
439#define PSR_s (1 << 2)
440#define PSR_f (1 << 3)
441
442static CONST struct asm_psr psrs[] =
443{
444 {"CPSR", true, PSR_c | PSR_f},
445 {"CPSR_all", true, PSR_c | PSR_f},
446 {"SPSR", false, PSR_c | PSR_f},
447 {"SPSR_all", false, PSR_c | PSR_f},
448 {"CPSR_flg", true, PSR_f},
449 {"CPSR_f", true, PSR_f},
450 {"SPSR_flg", false, PSR_f},
451 {"SPSR_f", false, PSR_f},
452 {"CPSR_c", true, PSR_c},
453 {"CPSR_ctl", true, PSR_c},
454 {"SPSR_c", false, PSR_c},
455 {"SPSR_ctl", false, PSR_c},
456 {"CPSR_x", true, PSR_x},
457 {"CPSR_s", true, PSR_s},
458 {"SPSR_x", false, PSR_x},
459 {"SPSR_s", false, PSR_s},
460 /* Combinations of flags. */
461 {"CPSR_fs", true, PSR_f | PSR_s},
462 {"CPSR_fx", true, PSR_f | PSR_x},
463 {"CPSR_fc", true, PSR_f | PSR_c},
464 {"CPSR_sf", true, PSR_s | PSR_f},
465 {"CPSR_sx", true, PSR_s | PSR_x},
466 {"CPSR_sc", true, PSR_s | PSR_c},
467 {"CPSR_xf", true, PSR_x | PSR_f},
468 {"CPSR_xs", true, PSR_x | PSR_s},
469 {"CPSR_xc", true, PSR_x | PSR_c},
470 {"CPSR_cf", true, PSR_c | PSR_f},
471 {"CPSR_cs", true, PSR_c | PSR_s},
472 {"CPSR_cx", true, PSR_c | PSR_x},
473 {"CPSR_fsx", true, PSR_f | PSR_s | PSR_x},
474 {"CPSR_fsc", true, PSR_f | PSR_s | PSR_c},
475 {"CPSR_fxs", true, PSR_f | PSR_x | PSR_s},
476 {"CPSR_fxc", true, PSR_f | PSR_x | PSR_c},
477 {"CPSR_fcs", true, PSR_f | PSR_c | PSR_s},
478 {"CPSR_fcx", true, PSR_f | PSR_c | PSR_x},
479 {"CPSR_sfx", true, PSR_s | PSR_f | PSR_x},
480 {"CPSR_sfc", true, PSR_s | PSR_f | PSR_c},
481 {"CPSR_sxf", true, PSR_s | PSR_x | PSR_f},
482 {"CPSR_sxc", true, PSR_s | PSR_x | PSR_c},
483 {"CPSR_scf", true, PSR_s | PSR_c | PSR_f},
484 {"CPSR_scx", true, PSR_s | PSR_c | PSR_x},
485 {"CPSR_xfs", true, PSR_x | PSR_f | PSR_s},
486 {"CPSR_xfc", true, PSR_x | PSR_f | PSR_c},
487 {"CPSR_xsf", true, PSR_x | PSR_s | PSR_f},
488 {"CPSR_xsc", true, PSR_x | PSR_s | PSR_c},
489 {"CPSR_xcf", true, PSR_x | PSR_c | PSR_f},
490 {"CPSR_xcs", true, PSR_x | PSR_c | PSR_s},
491 {"CPSR_cfs", true, PSR_c | PSR_f | PSR_s},
492 {"CPSR_cfx", true, PSR_c | PSR_f | PSR_x},
493 {"CPSR_csf", true, PSR_c | PSR_s | PSR_f},
494 {"CPSR_csx", true, PSR_c | PSR_s | PSR_x},
495 {"CPSR_cxf", true, PSR_c | PSR_x | PSR_f},
496 {"CPSR_cxs", true, PSR_c | PSR_x | PSR_s},
497 {"CPSR_fsxc", true, PSR_f | PSR_s | PSR_x | PSR_c},
498 {"CPSR_fscx", true, PSR_f | PSR_s | PSR_c | PSR_x},
499 {"CPSR_fxsc", true, PSR_f | PSR_x | PSR_s | PSR_c},
500 {"CPSR_fxcs", true, PSR_f | PSR_x | PSR_c | PSR_s},
501 {"CPSR_fcsx", true, PSR_f | PSR_c | PSR_s | PSR_x},
502 {"CPSR_fcxs", true, PSR_f | PSR_c | PSR_x | PSR_s},
503 {"CPSR_sfxc", true, PSR_s | PSR_f | PSR_x | PSR_c},
504 {"CPSR_sfcx", true, PSR_s | PSR_f | PSR_c | PSR_x},
505 {"CPSR_sxfc", true, PSR_s | PSR_x | PSR_f | PSR_c},
506 {"CPSR_sxcf", true, PSR_s | PSR_x | PSR_c | PSR_f},
507 {"CPSR_scfx", true, PSR_s | PSR_c | PSR_f | PSR_x},
508 {"CPSR_scxf", true, PSR_s | PSR_c | PSR_x | PSR_f},
509 {"CPSR_xfsc", true, PSR_x | PSR_f | PSR_s | PSR_c},
510 {"CPSR_xfcs", true, PSR_x | PSR_f | PSR_c | PSR_s},
511 {"CPSR_xsfc", true, PSR_x | PSR_s | PSR_f | PSR_c},
512 {"CPSR_xscf", true, PSR_x | PSR_s | PSR_c | PSR_f},
513 {"CPSR_xcfs", true, PSR_x | PSR_c | PSR_f | PSR_s},
514 {"CPSR_xcsf", true, PSR_x | PSR_c | PSR_s | PSR_f},
515 {"CPSR_cfsx", true, PSR_c | PSR_f | PSR_s | PSR_x},
516 {"CPSR_cfxs", true, PSR_c | PSR_f | PSR_x | PSR_s},
517 {"CPSR_csfx", true, PSR_c | PSR_s | PSR_f | PSR_x},
518 {"CPSR_csxf", true, PSR_c | PSR_s | PSR_x | PSR_f},
519 {"CPSR_cxfs", true, PSR_c | PSR_x | PSR_f | PSR_s},
520 {"CPSR_cxsf", true, PSR_c | PSR_x | PSR_s | PSR_f},
521 {"SPSR_fs", false, PSR_f | PSR_s},
522 {"SPSR_fx", false, PSR_f | PSR_x},
523 {"SPSR_fc", false, PSR_f | PSR_c},
524 {"SPSR_sf", false, PSR_s | PSR_f},
525 {"SPSR_sx", false, PSR_s | PSR_x},
526 {"SPSR_sc", false, PSR_s | PSR_c},
527 {"SPSR_xf", false, PSR_x | PSR_f},
528 {"SPSR_xs", false, PSR_x | PSR_s},
529 {"SPSR_xc", false, PSR_x | PSR_c},
530 {"SPSR_cf", false, PSR_c | PSR_f},
531 {"SPSR_cs", false, PSR_c | PSR_s},
532 {"SPSR_cx", false, PSR_c | PSR_x},
533 {"SPSR_fsx", false, PSR_f | PSR_s | PSR_x},
534 {"SPSR_fsc", false, PSR_f | PSR_s | PSR_c},
535 {"SPSR_fxs", false, PSR_f | PSR_x | PSR_s},
536 {"SPSR_fxc", false, PSR_f | PSR_x | PSR_c},
537 {"SPSR_fcs", false, PSR_f | PSR_c | PSR_s},
538 {"SPSR_fcx", false, PSR_f | PSR_c | PSR_x},
539 {"SPSR_sfx", false, PSR_s | PSR_f | PSR_x},
540 {"SPSR_sfc", false, PSR_s | PSR_f | PSR_c},
541 {"SPSR_sxf", false, PSR_s | PSR_x | PSR_f},
542 {"SPSR_sxc", false, PSR_s | PSR_x | PSR_c},
543 {"SPSR_scf", false, PSR_s | PSR_c | PSR_f},
544 {"SPSR_scx", false, PSR_s | PSR_c | PSR_x},
545 {"SPSR_xfs", false, PSR_x | PSR_f | PSR_s},
546 {"SPSR_xfc", false, PSR_x | PSR_f | PSR_c},
547 {"SPSR_xsf", false, PSR_x | PSR_s | PSR_f},
548 {"SPSR_xsc", false, PSR_x | PSR_s | PSR_c},
549 {"SPSR_xcf", false, PSR_x | PSR_c | PSR_f},
550 {"SPSR_xcs", false, PSR_x | PSR_c | PSR_s},
551 {"SPSR_cfs", false, PSR_c | PSR_f | PSR_s},
552 {"SPSR_cfx", false, PSR_c | PSR_f | PSR_x},
553 {"SPSR_csf", false, PSR_c | PSR_s | PSR_f},
554 {"SPSR_csx", false, PSR_c | PSR_s | PSR_x},
555 {"SPSR_cxf", false, PSR_c | PSR_x | PSR_f},
556 {"SPSR_cxs", false, PSR_c | PSR_x | PSR_s},
557 {"SPSR_fsxc", false, PSR_f | PSR_s | PSR_x | PSR_c},
558 {"SPSR_fscx", false, PSR_f | PSR_s | PSR_c | PSR_x},
559 {"SPSR_fxsc", false, PSR_f | PSR_x | PSR_s | PSR_c},
560 {"SPSR_fxcs", false, PSR_f | PSR_x | PSR_c | PSR_s},
561 {"SPSR_fcsx", false, PSR_f | PSR_c | PSR_s | PSR_x},
562 {"SPSR_fcxs", false, PSR_f | PSR_c | PSR_x | PSR_s},
563 {"SPSR_sfxc", false, PSR_s | PSR_f | PSR_x | PSR_c},
564 {"SPSR_sfcx", false, PSR_s | PSR_f | PSR_c | PSR_x},
565 {"SPSR_sxfc", false, PSR_s | PSR_x | PSR_f | PSR_c},
566 {"SPSR_sxcf", false, PSR_s | PSR_x | PSR_c | PSR_f},
567 {"SPSR_scfx", false, PSR_s | PSR_c | PSR_f | PSR_x},
568 {"SPSR_scxf", false, PSR_s | PSR_c | PSR_x | PSR_f},
569 {"SPSR_xfsc", false, PSR_x | PSR_f | PSR_s | PSR_c},
570 {"SPSR_xfcs", false, PSR_x | PSR_f | PSR_c | PSR_s},
571 {"SPSR_xsfc", false, PSR_x | PSR_s | PSR_f | PSR_c},
572 {"SPSR_xscf", false, PSR_x | PSR_s | PSR_c | PSR_f},
573 {"SPSR_xcfs", false, PSR_x | PSR_c | PSR_f | PSR_s},
574 {"SPSR_xcsf", false, PSR_x | PSR_c | PSR_s | PSR_f},
575 {"SPSR_cfsx", false, PSR_c | PSR_f | PSR_s | PSR_x},
576 {"SPSR_cfxs", false, PSR_c | PSR_f | PSR_x | PSR_s},
577 {"SPSR_csfx", false, PSR_c | PSR_s | PSR_f | PSR_x},
578 {"SPSR_csxf", false, PSR_c | PSR_s | PSR_x | PSR_f},
579 {"SPSR_cxfs", false, PSR_c | PSR_x | PSR_f | PSR_s},
580 {"SPSR_cxsf", false, PSR_c | PSR_x | PSR_s | PSR_f},
581};
582
404ff6b5
AH
583enum cirrus_regtype
584 {
585 CIRRUS_REGTYPE_MVF = 1,
586 CIRRUS_REGTYPE_MVFX = 2,
587 CIRRUS_REGTYPE_MVD = 3,
588 CIRRUS_REGTYPE_MVDX = 4,
589 CIRRUS_REGTYPE_MVAX = 5,
590 CIRRUS_REGTYPE_DSPSC = 6,
591 CIRRUS_REGTYPE_ANY = 7
592 };
593
b99bd4ef
NC
594/* Functions called by parser. */
595/* ARM instructions. */
596static void do_arit PARAMS ((char *, unsigned long));
597static void do_cmp PARAMS ((char *, unsigned long));
598static void do_mov PARAMS ((char *, unsigned long));
599static void do_ldst PARAMS ((char *, unsigned long));
600static void do_ldmstm PARAMS ((char *, unsigned long));
601static void do_branch PARAMS ((char *, unsigned long));
602static void do_swi PARAMS ((char *, unsigned long));
603/* Pseudo Op codes. */
604static void do_adr PARAMS ((char *, unsigned long));
b99bd4ef
NC
605static void do_nop PARAMS ((char *, unsigned long));
606/* ARM 2. */
607static void do_mul PARAMS ((char *, unsigned long));
608static void do_mla PARAMS ((char *, unsigned long));
609/* ARM 3. */
610static void do_swap PARAMS ((char *, unsigned long));
611/* ARM 6. */
612static void do_msr PARAMS ((char *, unsigned long));
613static void do_mrs PARAMS ((char *, unsigned long));
614/* ARM 7M. */
615static void do_mull PARAMS ((char *, unsigned long));
616/* ARM THUMB. */
617static void do_bx PARAMS ((char *, unsigned long));
618
619/* ARM_EXT_XScale. */
620static void do_mia PARAMS ((char *, unsigned long));
621static void do_mar PARAMS ((char *, unsigned long));
622static void do_mra PARAMS ((char *, unsigned long));
623static void do_pld PARAMS ((char *, unsigned long));
624static void do_ldrd PARAMS ((char *, unsigned long));
625
626/* ARM_EXT_V5. */
627static void do_blx PARAMS ((char *, unsigned long));
628static void do_bkpt PARAMS ((char *, unsigned long));
629static void do_clz PARAMS ((char *, unsigned long));
630static void do_lstc2 PARAMS ((char *, unsigned long));
631static void do_cdp2 PARAMS ((char *, unsigned long));
632static void do_co_reg2 PARAMS ((char *, unsigned long));
633
634static void do_t_blx PARAMS ((char *));
635static void do_t_bkpt PARAMS ((char *));
636
637/* ARM_EXT_V5E. */
638static void do_smla PARAMS ((char *, unsigned long));
639static void do_smlal PARAMS ((char *, unsigned long));
640static void do_smul PARAMS ((char *, unsigned long));
641static void do_qadd PARAMS ((char *, unsigned long));
642static void do_co_reg2c PARAMS ((char *, unsigned long));
643
644/* Coprocessor Instructions. */
645static void do_cdp PARAMS ((char *, unsigned long));
646static void do_lstc PARAMS ((char *, unsigned long));
647static void do_co_reg PARAMS ((char *, unsigned long));
648static void do_fp_ctrl PARAMS ((char *, unsigned long));
649static void do_fp_ldst PARAMS ((char *, unsigned long));
650static void do_fp_ldmstm PARAMS ((char *, unsigned long));
651static void do_fp_dyadic PARAMS ((char *, unsigned long));
652static void do_fp_monadic PARAMS ((char *, unsigned long));
653static void do_fp_cmp PARAMS ((char *, unsigned long));
654static void do_fp_from_reg PARAMS ((char *, unsigned long));
655static void do_fp_to_reg PARAMS ((char *, unsigned long));
656
404ff6b5
AH
657/* ARM_EXT_MAVERIK. */
658static void do_c_binops PARAMS ((char *, unsigned long, int));
659static void do_c_binops_1 PARAMS ((char *, unsigned long));
660static void do_c_binops_2 PARAMS ((char *, unsigned long));
661static void do_c_binops_3 PARAMS ((char *, unsigned long));
662static void do_c_triple PARAMS ((char *, unsigned long, int));
663static void do_c_triple_4 PARAMS ((char *, unsigned long));
664static void do_c_triple_5 PARAMS ((char *, unsigned long));
665static void do_c_quad PARAMS ((char *, unsigned long, int));
666static void do_c_quad_6 PARAMS ((char *, unsigned long));
667static void do_c_dspsc PARAMS ((char *, unsigned long, int));
668static void do_c_dspsc_1 PARAMS ((char *, unsigned long));
669static void do_c_dspsc_2 PARAMS ((char *, unsigned long));
670static void do_c_shift PARAMS ((char *, unsigned long, int));
671static void do_c_shift_1 PARAMS ((char *, unsigned long));
672static void do_c_shift_2 PARAMS ((char *, unsigned long));
673static void do_c_ldst PARAMS ((char *, unsigned long, int));
674static void do_c_ldst_1 PARAMS ((char *, unsigned long));
675static void do_c_ldst_2 PARAMS ((char *, unsigned long));
676static void do_c_ldst_3 PARAMS ((char *, unsigned long));
677static void do_c_ldst_4 PARAMS ((char *, unsigned long));
678static int cirrus_reg_required_here PARAMS ((char **, int, enum cirrus_regtype));
679static int cirrus_valid_reg PARAMS ((int, enum cirrus_regtype));
680static int cirrus_parse_offset PARAMS ((char **, int *));
681
b99bd4ef
NC
682static void fix_new_arm PARAMS ((fragS *, int, short, expressionS *, int, int));
683static int arm_reg_parse PARAMS ((char **));
684static CONST struct asm_psr * arm_psr_parse PARAMS ((char **));
685static void symbol_locate PARAMS ((symbolS *, CONST char *, segT, valueT, fragS *));
686static int add_to_lit_pool PARAMS ((void));
687static unsigned validate_immediate PARAMS ((unsigned));
688static unsigned validate_immediate_twopart PARAMS ((unsigned int, unsigned int *));
689static int validate_offset_imm PARAMS ((unsigned int, int));
690static void opcode_select PARAMS ((int));
691static void end_of_line PARAMS ((char *));
692static int reg_required_here PARAMS ((char **, int));
693static int psr_required_here PARAMS ((char **));
694static int co_proc_number PARAMS ((char **));
695static int cp_opc_expr PARAMS ((char **, int, int));
696static int cp_reg_required_here PARAMS ((char **, int));
697static int fp_reg_required_here PARAMS ((char **, int));
698static int cp_address_offset PARAMS ((char **));
699static int cp_address_required_here PARAMS ((char **));
700static int my_get_float_expression PARAMS ((char **));
701static int skip_past_comma PARAMS ((char **));
702static int walk_no_bignums PARAMS ((symbolS *));
703static int negate_data_op PARAMS ((unsigned long *, unsigned long));
704static int data_op2 PARAMS ((char **));
705static int fp_op2 PARAMS ((char **));
706static long reg_list PARAMS ((char **));
707static void thumb_load_store PARAMS ((char *, int, int));
708static int decode_shift PARAMS ((char **, int));
709static int ldst_extend PARAMS ((char **, int));
710static void thumb_add_sub PARAMS ((char *, int));
711static void insert_reg PARAMS ((int));
712static void thumb_shift PARAMS ((char *, int));
713static void thumb_mov_compare PARAMS ((char *, int));
714static void set_constant_flonums PARAMS ((void));
715static valueT md_chars_to_number PARAMS ((char *, int));
716static void insert_reg_alias PARAMS ((char *, int));
717static void output_inst PARAMS ((void));
2c20dfb2
NC
718static int accum0_required_here PARAMS ((char **));
719static int ld_mode_required_here PARAMS ((char **));
720static void do_branch25 PARAMS ((char *, unsigned long));
721static symbolS * find_real_start PARAMS ((symbolS *));
b99bd4ef
NC
722#ifdef OBJ_ELF
723static bfd_reloc_code_real_type arm_parse_reloc PARAMS ((void));
724#endif
725
726/* ARM instructions take 4bytes in the object file, Thumb instructions
727 take 2: */
728#define INSN_SIZE 4
729
730/* LONGEST_INST is the longest basic instruction name without
731 conditions or flags. ARM7M has 4 of length 5. El Segundo
732 has one basic instruction name of length 7 (SMLALxy). */
404ff6b5
AH
733#define LONGEST_INST 10
734
735/* "INSN<cond> X,Y" where X:bit12, Y:bit16. */
736#define CIRRUS_MODE1 0x100c
737
738/* "INSN<cond> X,Y" where X:bit16, Y:bit12. */
739#define CIRRUS_MODE2 0x0c10
740
741/* "INSN<cond> X,Y" where X:0, Y:bit16. */
742#define CIRRUS_MODE3 0x1000
743
744/* "INSN<cond> X,Y,Z" where X:16, Y:0, Z:12. */
745#define CIRRUS_MODE4 0x0c0010
746
747/* "INSN<cond> X,Y,Z" where X:12, Y:16, Z:0. */
748#define CIRRUS_MODE5 0x00100c
749
750/* "INSN<cond> W,X,Y,Z" where W:5, X:12, Y:16, Z:0. */
751#define CIRRUS_MODE6 0x00100c05
b99bd4ef
NC
752
753struct asm_opcode
754{
755 /* Basic string to match. */
756 CONST char * template;
757
758 /* Basic instruction code. */
759 unsigned long value;
760
761 /* Compulsory suffix that must follow conds. If "", then the
762 instruction is not conditional and must have no suffix. */
763 CONST char * comp_suffix;
764
765 /* Bits to toggle if flag 'n' set. */
766 CONST struct asm_flg * flags;
767
768 /* Which CPU variants this exists for. */
769 unsigned long variants;
770
771 /* Function to call to parse args. */
772 void (* parms) PARAMS ((char *, unsigned long));
773};
774
775static CONST struct asm_opcode insns[] =
776{
777/* Intel XScale extensions to ARM V5 ISA. */
778 {"mia", 0x0e200010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
779 {"miaph", 0x0e280010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
780 {"miabb", 0x0e2c0010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
781 {"miabt", 0x0e2d0010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
782 {"miatb", 0x0e2e0010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
783 {"miatt", 0x0e2f0010, NULL, NULL, ARM_EXT_XSCALE, do_mia},
784 {"mar", 0x0c400000, NULL, NULL, ARM_EXT_XSCALE, do_mar},
785 {"mra", 0x0c500000, NULL, NULL, ARM_EXT_XSCALE, do_mra},
786 {"pld", 0xf450f000, "", NULL, ARM_EXT_XSCALE, do_pld},
787 {"ldr", 0x000000d0, NULL, ldr_flags, ARM_ANY, do_ldrd},
788 {"str", 0x000000f0, NULL, str_flags, ARM_ANY, do_ldrd},
789
790/* ARM Instructions. */
791 {"and", 0x00000000, NULL, s_flag, ARM_ANY, do_arit},
792 {"eor", 0x00200000, NULL, s_flag, ARM_ANY, do_arit},
793 {"sub", 0x00400000, NULL, s_flag, ARM_ANY, do_arit},
794 {"rsb", 0x00600000, NULL, s_flag, ARM_ANY, do_arit},
795 {"add", 0x00800000, NULL, s_flag, ARM_ANY, do_arit},
796 {"adc", 0x00a00000, NULL, s_flag, ARM_ANY, do_arit},
797 {"sbc", 0x00c00000, NULL, s_flag, ARM_ANY, do_arit},
798 {"rsc", 0x00e00000, NULL, s_flag, ARM_ANY, do_arit},
799 {"orr", 0x01800000, NULL, s_flag, ARM_ANY, do_arit},
800 {"bic", 0x01c00000, NULL, s_flag, ARM_ANY, do_arit},
801 {"tst", 0x01000000, NULL, cmp_flags, ARM_ANY, do_cmp},
802 {"teq", 0x01200000, NULL, cmp_flags, ARM_ANY, do_cmp},
803 {"cmp", 0x01400000, NULL, cmp_flags, ARM_ANY, do_cmp},
804 {"cmn", 0x01600000, NULL, cmp_flags, ARM_ANY, do_cmp},
805 {"mov", 0x01a00000, NULL, s_flag, ARM_ANY, do_mov},
806 {"mvn", 0x01e00000, NULL, s_flag, ARM_ANY, do_mov},
807 {"str", 0x04000000, NULL, str_flags, ARM_ANY, do_ldst},
808 {"ldr", 0x04100000, NULL, ldr_flags, ARM_ANY, do_ldst},
809 {"stm", 0x08000000, NULL, stm_flags, ARM_ANY, do_ldmstm},
810 {"ldm", 0x08100000, NULL, ldm_flags, ARM_ANY, do_ldmstm},
811 {"swi", 0x0f000000, NULL, NULL, ARM_ANY, do_swi},
812#ifdef TE_WINCE
813 {"bl", 0x0b000000, NULL, NULL, ARM_ANY, do_branch},
814 {"b", 0x0a000000, NULL, NULL, ARM_ANY, do_branch},
815#else
816 {"bl", 0x0bfffffe, NULL, NULL, ARM_ANY, do_branch},
817 {"b", 0x0afffffe, NULL, NULL, ARM_ANY, do_branch},
818#endif
819
820/* Pseudo ops. */
1cac9012 821 {"adr", 0x028f0000, NULL, long_flag, ARM_ANY, do_adr},
b99bd4ef
NC
822 {"nop", 0x01a00000, NULL, NULL, ARM_ANY, do_nop},
823
824/* ARM 2 multiplies. */
825 {"mul", 0x00000090, NULL, s_flag, ARM_2UP, do_mul},
826 {"mla", 0x00200090, NULL, s_flag, ARM_2UP, do_mla},
827
828/* ARM 3 - swp instructions. */
829 {"swp", 0x01000090, NULL, byte_flag, ARM_3UP, do_swap},
830
831/* ARM 6 Coprocessor instructions. */
832 {"mrs", 0x010f0000, NULL, NULL, ARM_6UP, do_mrs},
833 {"msr", 0x0120f000, NULL, NULL, ARM_6UP, do_msr},
834/* ScottB: our code uses 0x0128f000 for msr.
835 NickC: but this is wrong because the bits 16 through 19 are
836 handled by the PSR_xxx defines above. */
837
838/* ARM 7M long multiplies - need signed/unsigned flags! */
839 {"smull", 0x00c00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull},
840 {"umull", 0x00800090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull},
841 {"smlal", 0x00e00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull},
842 {"umlal", 0x00a00090, NULL, s_flag, ARM_EXT_LONGMUL, do_mull},
843
844/* ARM THUMB interworking. */
845 {"bx", 0x012fff10, NULL, NULL, ARM_EXT_THUMB, do_bx},
846
847/* Floating point instructions. */
848 {"wfs", 0x0e200110, NULL, NULL, FPU_ALL, do_fp_ctrl},
849 {"rfs", 0x0e300110, NULL, NULL, FPU_ALL, do_fp_ctrl},
850 {"wfc", 0x0e400110, NULL, NULL, FPU_ALL, do_fp_ctrl},
851 {"rfc", 0x0e500110, NULL, NULL, FPU_ALL, do_fp_ctrl},
852 {"ldf", 0x0c100100, "sdep", NULL, FPU_ALL, do_fp_ldst},
853 {"stf", 0x0c000100, "sdep", NULL, FPU_ALL, do_fp_ldst},
854 {"lfm", 0x0c100200, NULL, lfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
855 {"sfm", 0x0c000200, NULL, sfm_flags, FPU_MEMMULTI, do_fp_ldmstm},
856 {"mvf", 0x0e008100, "sde", round_flags, FPU_ALL, do_fp_monadic},
857 {"mnf", 0x0e108100, "sde", round_flags, FPU_ALL, do_fp_monadic},
858 {"abs", 0x0e208100, "sde", round_flags, FPU_ALL, do_fp_monadic},
859 {"rnd", 0x0e308100, "sde", round_flags, FPU_ALL, do_fp_monadic},
860 {"sqt", 0x0e408100, "sde", round_flags, FPU_ALL, do_fp_monadic},
861 {"log", 0x0e508100, "sde", round_flags, FPU_ALL, do_fp_monadic},
862 {"lgn", 0x0e608100, "sde", round_flags, FPU_ALL, do_fp_monadic},
863 {"exp", 0x0e708100, "sde", round_flags, FPU_ALL, do_fp_monadic},
864 {"sin", 0x0e808100, "sde", round_flags, FPU_ALL, do_fp_monadic},
865 {"cos", 0x0e908100, "sde", round_flags, FPU_ALL, do_fp_monadic},
866 {"tan", 0x0ea08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
867 {"asn", 0x0eb08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
868 {"acs", 0x0ec08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
869 {"atn", 0x0ed08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
870 {"urd", 0x0ee08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
871 {"nrm", 0x0ef08100, "sde", round_flags, FPU_ALL, do_fp_monadic},
872 {"adf", 0x0e000100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
873 {"suf", 0x0e200100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
874 {"rsf", 0x0e300100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
875 {"muf", 0x0e100100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
876 {"dvf", 0x0e400100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
877 {"rdf", 0x0e500100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
878 {"pow", 0x0e600100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
879 {"rpw", 0x0e700100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
880 {"rmf", 0x0e800100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
881 {"fml", 0x0e900100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
882 {"fdv", 0x0ea00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
883 {"frd", 0x0eb00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
884 {"pol", 0x0ec00100, "sde", round_flags, FPU_ALL, do_fp_dyadic},
885 {"cmf", 0x0e90f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
886 {"cnf", 0x0eb0f110, NULL, except_flag, FPU_ALL, do_fp_cmp},
887/* The FPA10 data sheet suggests that the 'E' of cmfe/cnfe should not
888 be an optional suffix, but part of the instruction. To be compatible,
889 we accept either. */
890 {"cmfe", 0x0ed0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
891 {"cnfe", 0x0ef0f110, NULL, NULL, FPU_ALL, do_fp_cmp},
892 {"flt", 0x0e000110, "sde", round_flags, FPU_ALL, do_fp_from_reg},
893 {"fix", 0x0e100110, NULL, fix_flags, FPU_ALL, do_fp_to_reg},
894
895/* Generic copressor instructions. */
896 {"cdp", 0x0e000000, NULL, NULL, ARM_2UP, do_cdp},
1cac9012
NC
897 {"ldc", 0x0c100000, NULL, long_flag, ARM_2UP, do_lstc},
898 {"stc", 0x0c000000, NULL, long_flag, ARM_2UP, do_lstc},
b99bd4ef
NC
899 {"mcr", 0x0e000010, NULL, NULL, ARM_2UP, do_co_reg},
900 {"mrc", 0x0e100010, NULL, NULL, ARM_2UP, do_co_reg},
901
902/* ARM ISA extension 5. */
903/* Note: blx is actually 2 opcodes, so the .value is set dynamically.
904 And it's sometimes conditional and sometimes not. */
905 {"blx", 0, NULL, NULL, ARM_EXT_V5, do_blx},
906 {"clz", 0x016f0f10, NULL, NULL, ARM_EXT_V5, do_clz},
907 {"bkpt", 0xe1200070, "", NULL, ARM_EXT_V5, do_bkpt},
1cac9012
NC
908 {"ldc2", 0xfc100000, "", long_flag, ARM_EXT_V5, do_lstc2},
909 {"stc2", 0xfc000000, "", long_flag, ARM_EXT_V5, do_lstc2},
b99bd4ef
NC
910 {"cdp2", 0xfe000000, "", NULL, ARM_EXT_V5, do_cdp2},
911 {"mcr2", 0xfe000010, "", NULL, ARM_EXT_V5, do_co_reg2},
912 {"mrc2", 0xfe100010, "", NULL, ARM_EXT_V5, do_co_reg2},
913
914/* ARM ISA extension 5E, El Segundo. */
915 {"smlabb", 0x01000080, NULL, NULL, ARM_EXT_V5E, do_smla},
916 {"smlatb", 0x010000a0, NULL, NULL, ARM_EXT_V5E, do_smla},
917 {"smlabt", 0x010000c0, NULL, NULL, ARM_EXT_V5E, do_smla},
918 {"smlatt", 0x010000e0, NULL, NULL, ARM_EXT_V5E, do_smla},
919
920 {"smlawb", 0x01200080, NULL, NULL, ARM_EXT_V5E, do_smla},
921 {"smlawt", 0x012000c0, NULL, NULL, ARM_EXT_V5E, do_smla},
922
923 {"smlalbb",0x01400080, NULL, NULL, ARM_EXT_V5E, do_smlal},
924 {"smlaltb",0x014000a0, NULL, NULL, ARM_EXT_V5E, do_smlal},
925 {"smlalbt",0x014000c0, NULL, NULL, ARM_EXT_V5E, do_smlal},
926 {"smlaltt",0x014000e0, NULL, NULL, ARM_EXT_V5E, do_smlal},
927
928 {"smulbb", 0x01600080, NULL, NULL, ARM_EXT_V5E, do_smul},
929 {"smultb", 0x016000a0, NULL, NULL, ARM_EXT_V5E, do_smul},
930 {"smulbt", 0x016000c0, NULL, NULL, ARM_EXT_V5E, do_smul},
931 {"smultt", 0x016000e0, NULL, NULL, ARM_EXT_V5E, do_smul},
932
933 {"smulwb", 0x012000a0, NULL, NULL, ARM_EXT_V5E, do_smul},
934 {"smulwt", 0x012000e0, NULL, NULL, ARM_EXT_V5E, do_smul},
935
936 {"qadd", 0x01000050, NULL, NULL, ARM_EXT_V5E, do_qadd},
937 {"qdadd", 0x01400050, NULL, NULL, ARM_EXT_V5E, do_qadd},
938 {"qsub", 0x01200050, NULL, NULL, ARM_EXT_V5E, do_qadd},
939 {"qdsub", 0x01600050, NULL, NULL, ARM_EXT_V5E, do_qadd},
940
941 {"mcrr", 0x0c400000, NULL, NULL, ARM_EXT_V5E, do_co_reg2c},
942 {"mrrc", 0x0c500000, NULL, NULL, ARM_EXT_V5E, do_co_reg2c},
404ff6b5
AH
943
944 /* Cirrus DSP instructions. */
945 {"cfldrs", 0x0c100400, NULL, NULL, ARM_EXT_MAVERIK, do_c_ldst_1},
946 {"cfldrd", 0x0c500400, NULL, NULL, ARM_EXT_MAVERIK, do_c_ldst_2},
947 {"cfldr32", 0x0c100500, NULL, NULL, ARM_EXT_MAVERIK, do_c_ldst_3},
948 {"cfldr64", 0x0c500500, NULL, NULL, ARM_EXT_MAVERIK, do_c_ldst_4},
949 {"cfstrs", 0x0c000400, NULL, NULL, ARM_EXT_MAVERIK, do_c_ldst_1},
950 {"cfstrd", 0x0c400400, NULL, NULL, ARM_EXT_MAVERIK, do_c_ldst_2},
951 {"cfstr32", 0x0c000500, NULL, NULL, ARM_EXT_MAVERIK, do_c_ldst_3},
952 {"cfstr64", 0x0c400500, NULL, NULL, ARM_EXT_MAVERIK, do_c_ldst_4},
953 {"cfmvsr", 0x0e000450, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_2},
954 {"cfmvrs", 0x0e100450, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
955 {"cfmvdlr", 0x0e000410, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_2},
956 {"cfmvrdl", 0x0e100410, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
957 {"cfmvdhr", 0x0e000430, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_2},
958 {"cfmvrdh", 0x0e100430, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
959 {"cfmv64lr", 0x0e000510, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_2},
960 {"cfmvr64l", 0x0e100510, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
961 {"cfmv64hr", 0x0e000530, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_2},
962 {"cfmvr64h", 0x0e100530, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
963 {"cfmval32", 0x0e100610, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_3},
964 {"cfmv32al", 0x0e000610, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_3},
965 {"cfmvam32", 0x0e100630, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_3},
966 {"cfmv32am", 0x0e000630, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_3},
967 {"cfmvah32", 0x0e100650, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_3},
968 {"cfmv32ah", 0x0e000650, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_3},
969 {"cfmv32a", 0x0e000670, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_3},
970 {"cfmva32", 0x0e100670, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_3},
971 {"cfmv64a", 0x0e000690, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_3},
972 {"cfmva64", 0x0e100690, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_3},
973 {"cfmvsc32", 0x0e1006b0, NULL, NULL, ARM_EXT_MAVERIK, do_c_dspsc_1},
974 {"cfmv32sc", 0x0e0006b0, NULL, NULL, ARM_EXT_MAVERIK, do_c_dspsc_2},
975 {"cfcpys", 0x0e000400, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
976 {"cfcpyd", 0x0e000420, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
977 {"cfcvtsd", 0x0e000460, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
978 {"cfcvtds", 0x0e000440, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
979 {"cfcvt32s", 0x0e000480, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
980 {"cfcvt32d", 0x0e0004a0, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
981 {"cfcvt64s", 0x0e0004c0, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
982 {"cfcvt64d", 0x0e0004e0, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
983 {"cfcvts32", 0x0e100580, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
984 {"cfcvtd32", 0x0e1005a0, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
985 {"cftruncs32",0x0e1005c0, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
986 {"cftruncd32",0x0e1005e0, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
987 {"cfrshl32", 0x0e000550, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_4},
988 {"cfrshl64", 0x0e000570, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_4},
989 {"cfsh32", 0x0e000500, NULL, NULL, ARM_EXT_MAVERIK, do_c_shift_1},
990 {"cfsh64", 0x0e200500, NULL, NULL, ARM_EXT_MAVERIK, do_c_shift_2},
991 {"cfcmps", 0x0e100490, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
992 {"cfcmpd", 0x0e1004b0, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
993 {"cfcmp32", 0x0e100590, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
994 {"cfcmp64", 0x0e1005b0, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
995 {"cfabss", 0x0e300400, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
996 {"cfabsd", 0x0e300420, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
997 {"cfnegs", 0x0e300440, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
998 {"cfnegd", 0x0e300460, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
999 {"cfadds", 0x0e300480, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1000 {"cfaddd", 0x0e3004a0, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1001 {"cfsubs", 0x0e3004c0, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1002 {"cfsubd", 0x0e3004e0, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1003 {"cfmuls", 0x0e100400, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1004 {"cfmuld", 0x0e100420, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1005 {"cfabs32", 0x0e300500, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
1006 {"cfabs64", 0x0e300520, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
1007 {"cfneg32", 0x0e300540, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
1008 {"cfneg64", 0x0e300560, NULL, NULL, ARM_EXT_MAVERIK, do_c_binops_1},
1009 {"cfadd32", 0x0e300580, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1010 {"cfadd64", 0x0e3005a0, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1011 {"cfsub32", 0x0e3005c0, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1012 {"cfsub64", 0x0e3005e0, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1013 {"cfmul32", 0x0e100500, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1014 {"cfmul64", 0x0e100520, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1015 {"cfmac32", 0x0e100540, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1016 {"cfmsc32", 0x0e100560, NULL, NULL, ARM_EXT_MAVERIK, do_c_triple_5},
1017 {"cfmadd32", 0x0e000600, NULL, NULL, ARM_EXT_MAVERIK, do_c_quad_6},
1018 {"cfmsub32", 0x0e100600, NULL, NULL, ARM_EXT_MAVERIK, do_c_quad_6},
1019 {"cfmadda32", 0x0e200600, NULL, NULL, ARM_EXT_MAVERIK, do_c_quad_6},
1020 {"cfmsuba32", 0x0e300600, NULL, NULL, ARM_EXT_MAVERIK, do_c_quad_6},
b99bd4ef
NC
1021};
1022
1023/* Defines for various bits that we will want to toggle. */
1024#define INST_IMMEDIATE 0x02000000
1025#define OFFSET_REG 0x02000000
1026#define HWOFFSET_IMM 0x00400000
1027#define SHIFT_BY_REG 0x00000010
1028#define PRE_INDEX 0x01000000
1029#define INDEX_UP 0x00800000
1030#define WRITE_BACK 0x00200000
1031#define LDM_TYPE_2_OR_3 0x00400000
1032
1033#define LITERAL_MASK 0xf000f000
1034#define COND_MASK 0xf0000000
1035#define OPCODE_MASK 0xfe1fffff
1036#define DATA_OP_SHIFT 21
1037
1038/* Codes to distinguish the arithmetic instructions. */
1039#define OPCODE_AND 0
1040#define OPCODE_EOR 1
1041#define OPCODE_SUB 2
1042#define OPCODE_RSB 3
1043#define OPCODE_ADD 4
1044#define OPCODE_ADC 5
1045#define OPCODE_SBC 6
1046#define OPCODE_RSC 7
1047#define OPCODE_TST 8
1048#define OPCODE_TEQ 9
1049#define OPCODE_CMP 10
1050#define OPCODE_CMN 11
1051#define OPCODE_ORR 12
1052#define OPCODE_MOV 13
1053#define OPCODE_BIC 14
1054#define OPCODE_MVN 15
1055
1056static void do_t_nop PARAMS ((char *));
1057static void do_t_arit PARAMS ((char *));
1058static void do_t_add PARAMS ((char *));
1059static void do_t_asr PARAMS ((char *));
1060static void do_t_branch9 PARAMS ((char *));
1061static void do_t_branch12 PARAMS ((char *));
1062static void do_t_branch23 PARAMS ((char *));
1063static void do_t_bx PARAMS ((char *));
1064static void do_t_compare PARAMS ((char *));
1065static void do_t_ldmstm PARAMS ((char *));
1066static void do_t_ldr PARAMS ((char *));
1067static void do_t_ldrb PARAMS ((char *));
1068static void do_t_ldrh PARAMS ((char *));
1069static void do_t_lds PARAMS ((char *));
1070static void do_t_lsl PARAMS ((char *));
1071static void do_t_lsr PARAMS ((char *));
1072static void do_t_mov PARAMS ((char *));
1073static void do_t_push_pop PARAMS ((char *));
1074static void do_t_str PARAMS ((char *));
1075static void do_t_strb PARAMS ((char *));
1076static void do_t_strh PARAMS ((char *));
1077static void do_t_sub PARAMS ((char *));
1078static void do_t_swi PARAMS ((char *));
1079static void do_t_adr PARAMS ((char *));
1080
1081#define T_OPCODE_MUL 0x4340
1082#define T_OPCODE_TST 0x4200
1083#define T_OPCODE_CMN 0x42c0
1084#define T_OPCODE_NEG 0x4240
1085#define T_OPCODE_MVN 0x43c0
1086
1087#define T_OPCODE_ADD_R3 0x1800
1088#define T_OPCODE_SUB_R3 0x1a00
1089#define T_OPCODE_ADD_HI 0x4400
1090#define T_OPCODE_ADD_ST 0xb000
1091#define T_OPCODE_SUB_ST 0xb080
1092#define T_OPCODE_ADD_SP 0xa800
1093#define T_OPCODE_ADD_PC 0xa000
1094#define T_OPCODE_ADD_I8 0x3000
1095#define T_OPCODE_SUB_I8 0x3800
1096#define T_OPCODE_ADD_I3 0x1c00
1097#define T_OPCODE_SUB_I3 0x1e00
1098
1099#define T_OPCODE_ASR_R 0x4100
1100#define T_OPCODE_LSL_R 0x4080
1101#define T_OPCODE_LSR_R 0x40c0
1102#define T_OPCODE_ASR_I 0x1000
1103#define T_OPCODE_LSL_I 0x0000
1104#define T_OPCODE_LSR_I 0x0800
1105
1106#define T_OPCODE_MOV_I8 0x2000
1107#define T_OPCODE_CMP_I8 0x2800
1108#define T_OPCODE_CMP_LR 0x4280
1109#define T_OPCODE_MOV_HR 0x4600
1110#define T_OPCODE_CMP_HR 0x4500
1111
1112#define T_OPCODE_LDR_PC 0x4800
1113#define T_OPCODE_LDR_SP 0x9800
1114#define T_OPCODE_STR_SP 0x9000
1115#define T_OPCODE_LDR_IW 0x6800
1116#define T_OPCODE_STR_IW 0x6000
1117#define T_OPCODE_LDR_IH 0x8800
1118#define T_OPCODE_STR_IH 0x8000
1119#define T_OPCODE_LDR_IB 0x7800
1120#define T_OPCODE_STR_IB 0x7000
1121#define T_OPCODE_LDR_RW 0x5800
1122#define T_OPCODE_STR_RW 0x5000
1123#define T_OPCODE_LDR_RH 0x5a00
1124#define T_OPCODE_STR_RH 0x5200
1125#define T_OPCODE_LDR_RB 0x5c00
1126#define T_OPCODE_STR_RB 0x5400
1127
1128#define T_OPCODE_PUSH 0xb400
1129#define T_OPCODE_POP 0xbc00
1130
1131#define T_OPCODE_BRANCH 0xe7fe
1132
1133static int thumb_reg PARAMS ((char ** str, int hi_lo));
1134
1135#define THUMB_SIZE 2 /* Size of thumb instruction. */
1136#define THUMB_REG_LO 0x1
1137#define THUMB_REG_HI 0x2
1138#define THUMB_REG_ANY 0x3
1139
1140#define THUMB_H1 0x0080
1141#define THUMB_H2 0x0040
1142
1143#define THUMB_ASR 0
1144#define THUMB_LSL 1
1145#define THUMB_LSR 2
1146
1147#define THUMB_MOVE 0
1148#define THUMB_COMPARE 1
1149
1150#define THUMB_LOAD 0
1151#define THUMB_STORE 1
1152
1153#define THUMB_PP_PC_LR 0x0100
1154
1155/* These three are used for immediate shifts, do not alter. */
1156#define THUMB_WORD 2
1157#define THUMB_HALFWORD 1
1158#define THUMB_BYTE 0
1159
1160struct thumb_opcode
1161{
1162 /* Basic string to match. */
1163 CONST char * template;
1164
1165 /* Basic instruction code. */
1166 unsigned long value;
1167
1168 int size;
1169
1170 /* Which CPU variants this exists for. */
1171 unsigned long variants;
1172
1173 /* Function to call to parse args. */
1174 void (* parms) PARAMS ((char *));
1175};
1176
1177static CONST struct thumb_opcode tinsns[] =
1178{
1179 {"adc", 0x4140, 2, ARM_EXT_THUMB, do_t_arit},
1180 {"add", 0x0000, 2, ARM_EXT_THUMB, do_t_add},
1181 {"and", 0x4000, 2, ARM_EXT_THUMB, do_t_arit},
1182 {"asr", 0x0000, 2, ARM_EXT_THUMB, do_t_asr},
1183 {"b", T_OPCODE_BRANCH, 2, ARM_EXT_THUMB, do_t_branch12},
1184 {"beq", 0xd0fe, 2, ARM_EXT_THUMB, do_t_branch9},
1185 {"bne", 0xd1fe, 2, ARM_EXT_THUMB, do_t_branch9},
1186 {"bcs", 0xd2fe, 2, ARM_EXT_THUMB, do_t_branch9},
1187 {"bhs", 0xd2fe, 2, ARM_EXT_THUMB, do_t_branch9},
1188 {"bcc", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9},
1189 {"bul", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9},
1190 {"blo", 0xd3fe, 2, ARM_EXT_THUMB, do_t_branch9},
1191 {"bmi", 0xd4fe, 2, ARM_EXT_THUMB, do_t_branch9},
1192 {"bpl", 0xd5fe, 2, ARM_EXT_THUMB, do_t_branch9},
1193 {"bvs", 0xd6fe, 2, ARM_EXT_THUMB, do_t_branch9},
1194 {"bvc", 0xd7fe, 2, ARM_EXT_THUMB, do_t_branch9},
1195 {"bhi", 0xd8fe, 2, ARM_EXT_THUMB, do_t_branch9},
1196 {"bls", 0xd9fe, 2, ARM_EXT_THUMB, do_t_branch9},
1197 {"bge", 0xdafe, 2, ARM_EXT_THUMB, do_t_branch9},
1198 {"blt", 0xdbfe, 2, ARM_EXT_THUMB, do_t_branch9},
1199 {"bgt", 0xdcfe, 2, ARM_EXT_THUMB, do_t_branch9},
1200 {"ble", 0xddfe, 2, ARM_EXT_THUMB, do_t_branch9},
1201 {"bal", 0xdefe, 2, ARM_EXT_THUMB, do_t_branch9},
1202 {"bic", 0x4380, 2, ARM_EXT_THUMB, do_t_arit},
1203 {"bl", 0xf7fffffe, 4, ARM_EXT_THUMB, do_t_branch23},
1204 {"blx", 0, 0, ARM_EXT_V5, do_t_blx},
1205 {"bkpt", 0xbe00, 2, ARM_EXT_V5, do_t_bkpt},
1206 {"bx", 0x4700, 2, ARM_EXT_THUMB, do_t_bx},
1207 {"cmn", T_OPCODE_CMN, 2, ARM_EXT_THUMB, do_t_arit},
1208 {"cmp", 0x0000, 2, ARM_EXT_THUMB, do_t_compare},
1209 {"eor", 0x4040, 2, ARM_EXT_THUMB, do_t_arit},
1210 {"ldmia", 0xc800, 2, ARM_EXT_THUMB, do_t_ldmstm},
1211 {"ldr", 0x0000, 2, ARM_EXT_THUMB, do_t_ldr},
1212 {"ldrb", 0x0000, 2, ARM_EXT_THUMB, do_t_ldrb},
1213 {"ldrh", 0x0000, 2, ARM_EXT_THUMB, do_t_ldrh},
1214 {"ldrsb", 0x5600, 2, ARM_EXT_THUMB, do_t_lds},
1215 {"ldrsh", 0x5e00, 2, ARM_EXT_THUMB, do_t_lds},
1216 {"ldsb", 0x5600, 2, ARM_EXT_THUMB, do_t_lds},
1217 {"ldsh", 0x5e00, 2, ARM_EXT_THUMB, do_t_lds},
1218 {"lsl", 0x0000, 2, ARM_EXT_THUMB, do_t_lsl},
1219 {"lsr", 0x0000, 2, ARM_EXT_THUMB, do_t_lsr},
1220 {"mov", 0x0000, 2, ARM_EXT_THUMB, do_t_mov},
1221 {"mul", T_OPCODE_MUL, 2, ARM_EXT_THUMB, do_t_arit},
1222 {"mvn", T_OPCODE_MVN, 2, ARM_EXT_THUMB, do_t_arit},
1223 {"neg", T_OPCODE_NEG, 2, ARM_EXT_THUMB, do_t_arit},
1224 {"orr", 0x4300, 2, ARM_EXT_THUMB, do_t_arit},
1225 {"pop", 0xbc00, 2, ARM_EXT_THUMB, do_t_push_pop},
1226 {"push", 0xb400, 2, ARM_EXT_THUMB, do_t_push_pop},
1227 {"ror", 0x41c0, 2, ARM_EXT_THUMB, do_t_arit},
1228 {"sbc", 0x4180, 2, ARM_EXT_THUMB, do_t_arit},
1229 {"stmia", 0xc000, 2, ARM_EXT_THUMB, do_t_ldmstm},
1230 {"str", 0x0000, 2, ARM_EXT_THUMB, do_t_str},
1231 {"strb", 0x0000, 2, ARM_EXT_THUMB, do_t_strb},
1232 {"strh", 0x0000, 2, ARM_EXT_THUMB, do_t_strh},
1233 {"swi", 0xdf00, 2, ARM_EXT_THUMB, do_t_swi},
1234 {"sub", 0x0000, 2, ARM_EXT_THUMB, do_t_sub},
1235 {"tst", T_OPCODE_TST, 2, ARM_EXT_THUMB, do_t_arit},
1236 /* Pseudo ops: */
1237 {"adr", 0x0000, 2, ARM_EXT_THUMB, do_t_adr},
1238 {"nop", 0x46C0, 2, ARM_EXT_THUMB, do_t_nop}, /* mov r8,r8 */
1239};
1240
1241struct reg_entry
1242{
1243 CONST char * name;
1244 int number;
1245};
1246
1247#define int_register(reg) ((reg) >= 0 && (reg) <= 15)
1248#define cp_register(reg) ((reg) >= 32 && (reg) <= 47)
1249#define fp_register(reg) ((reg) >= 16 && (reg) <= 23)
1250
404ff6b5
AH
1251#define ARM_EXT_MAVERIKSC_REG 134
1252
1253#define cirrus_register(reg) ((reg) >= 50 && (reg) <= 134)
1254#define cirrus_mvf_register(reg) ((reg) >= 50 && (reg) <= 65)
1255#define cirrus_mvd_register(reg) ((reg) >= 70 && (reg) <= 85)
1256#define cirrus_mvfx_register(reg) ((reg) >= 90 && (reg) <= 105)
1257#define cirrus_mvdx_register(reg) ((reg) >= 110 && (reg) <= 125)
1258#define cirrus_mvax_register(reg) ((reg) >= 130 && (reg) <= 133)
1259#define ARM_EXT_MAVERIKsc_register(reg) ((reg) == ARM_EXT_MAVERIKSC_REG)
1260
b99bd4ef
NC
1261#define REG_PC 15
1262#define REG_LR 14
1263#define REG_SP 13
1264
1265/* These are the standard names. Users can add aliases with .req. */
1266static CONST struct reg_entry reg_table[] =
1267{
1268 /* Processor Register Numbers. */
1269 {"r0", 0}, {"r1", 1}, {"r2", 2}, {"r3", 3},
1270 {"r4", 4}, {"r5", 5}, {"r6", 6}, {"r7", 7},
1271 {"r8", 8}, {"r9", 9}, {"r10", 10}, {"r11", 11},
1272 {"r12", 12}, {"r13", REG_SP},{"r14", REG_LR},{"r15", REG_PC},
1273 /* APCS conventions. */
1274 {"a1", 0}, {"a2", 1}, {"a3", 2}, {"a4", 3},
1275 {"v1", 4}, {"v2", 5}, {"v3", 6}, {"v4", 7}, {"v5", 8},
1276 {"v6", 9}, {"sb", 9}, {"v7", 10}, {"sl", 10},
1277 {"fp", 11}, {"ip", 12}, {"sp", REG_SP},{"lr", REG_LR},{"pc", REG_PC},
1278 /* ATPCS additions to APCS conventions. */
1279 {"wr", 7}, {"v8", 11},
1280 /* FP Registers. */
1281 {"f0", 16}, {"f1", 17}, {"f2", 18}, {"f3", 19},
1282 {"f4", 20}, {"f5", 21}, {"f6", 22}, {"f7", 23},
1283 {"c0", 32}, {"c1", 33}, {"c2", 34}, {"c3", 35},
1284 {"c4", 36}, {"c5", 37}, {"c6", 38}, {"c7", 39},
1285 {"c8", 40}, {"c9", 41}, {"c10", 42}, {"c11", 43},
1286 {"c12", 44}, {"c13", 45}, {"c14", 46}, {"c15", 47},
1287 {"cr0", 32}, {"cr1", 33}, {"cr2", 34}, {"cr3", 35},
1288 {"cr4", 36}, {"cr5", 37}, {"cr6", 38}, {"cr7", 39},
1289 {"cr8", 40}, {"cr9", 41}, {"cr10", 42}, {"cr11", 43},
1290 {"cr12", 44}, {"cr13", 45}, {"cr14", 46}, {"cr15", 47},
1291 /* ATPCS additions to float register names. */
1292 {"s0",16}, {"s1",17}, {"s2",18}, {"s3",19},
1293 {"s4",20}, {"s5",21}, {"s6",22}, {"s7",23},
1294 {"d0",16}, {"d1",17}, {"d2",18}, {"d3",19},
1295 {"d4",20}, {"d5",21}, {"d6",22}, {"d7",23},
404ff6b5
AH
1296 /* Cirrus DSP coprocessor registers. */
1297 {"mvf0", 50}, {"mvf1", 51}, {"mvf2", 52}, {"mvf3", 53},
1298 {"mvf4", 54}, {"mvf5", 55}, {"mvf6", 56}, {"mvf7", 57},
1299 {"mvf8", 58}, {"mvf9", 59}, {"mvf10", 60}, {"mvf11", 61},
1300 {"mvf12", 62},{"mvf13", 63}, {"mvf14", 64}, {"mvf15", 65},
1301 {"mvd0", 70}, {"mvd1", 71}, {"mvd2", 72}, {"mvd3", 73},
1302 {"mvd4", 74}, {"mvd5", 75}, {"mvd6", 76}, {"mvd7", 77},
1303 {"mvd8", 78}, {"mvd9", 79}, {"mvd10", 80}, {"mvd11", 81},
1304 {"mvd12", 82},{"mvd13", 83}, {"mvd14", 84}, {"mvd15", 85},
1305 {"mvfx0", 90},{"mvfx1", 91}, {"mvfx2", 92}, {"mvfx3", 93},
1306 {"mvfx4", 94},{"mvfx5", 95}, {"mvfx6", 96}, {"mvfx7", 97},
1307 {"mvfx8", 98},{"mvfx9", 99}, {"mvfx10", 100},{"mvfx11", 101},
1308 {"mvfx12", 102},{"mvfx13", 103},{"mvfx14", 104},{"mvfx15", 105},
1309 {"mvdx0", 110}, {"mvdx1", 111}, {"mvdx2", 112}, {"mvdx3", 113},
1310 {"mvdx4", 114}, {"mvdx5", 115}, {"mvdx6", 116}, {"mvdx7", 117},
1311 {"mvdx8", 118}, {"mvdx9", 119}, {"mvdx10", 120},{"mvdx11", 121},
1312 {"mvdx12", 122},{"mvdx13", 123},{"mvdx14", 124},{"mvdx15", 125},
1313 {"mvax0", 130}, {"mvax1", 131}, {"mvax2", 132}, {"mvax3", 133},
1314 {"dspsc", ARM_EXT_MAVERIKSC_REG},
b99bd4ef
NC
1315 /* FIXME: At some point we need to add VFP register names. */
1316 /* Array terminator. */
1317 {NULL, 0}
1318};
1319
1320#define BAD_ARGS _("Bad arguments to instruction")
1321#define BAD_PC _("r15 not allowed here")
1322#define BAD_FLAGS _("Instruction should not have flags")
1323#define BAD_COND _("Instruction is not conditional")
1324#define ERR_NO_ACCUM _("acc0 expected")
1325
1326static struct hash_control * arm_ops_hsh = NULL;
1327static struct hash_control * arm_tops_hsh = NULL;
1328static struct hash_control * arm_cond_hsh = NULL;
1329static struct hash_control * arm_shift_hsh = NULL;
1330static struct hash_control * arm_reg_hsh = NULL;
1331static struct hash_control * arm_psr_hsh = NULL;
1332
1333/* This table describes all the machine specific pseudo-ops the assembler
1334 has to support. The fields are:
1335 pseudo-op name without dot
1336 function to call to execute this pseudo-op
1337 Integer arg to pass to the function. */
1338
1339static void s_req PARAMS ((int));
1340static void s_align PARAMS ((int));
1341static void s_bss PARAMS ((int));
1342static void s_even PARAMS ((int));
1343static void s_ltorg PARAMS ((int));
1344static void s_arm PARAMS ((int));
1345static void s_thumb PARAMS ((int));
1346static void s_code PARAMS ((int));
1347static void s_force_thumb PARAMS ((int));
1348static void s_thumb_func PARAMS ((int));
1349static void s_thumb_set PARAMS ((int));
1350static void arm_s_text PARAMS ((int));
1351static void arm_s_data PARAMS ((int));
1352#ifdef OBJ_ELF
1353static void arm_s_section PARAMS ((int));
1354static void s_arm_elf_cons PARAMS ((int));
1355#endif
1356
1357static int my_get_expression PARAMS ((expressionS *, char **));
1358
1359CONST pseudo_typeS md_pseudo_table[] =
1360{
1361 /* Never called becasue '.req' does not start line. */
1362 { "req", s_req, 0 },
1363 { "bss", s_bss, 0 },
1364 { "align", s_align, 0 },
1365 { "arm", s_arm, 0 },
1366 { "thumb", s_thumb, 0 },
1367 { "code", s_code, 0 },
1368 { "force_thumb", s_force_thumb, 0 },
1369 { "thumb_func", s_thumb_func, 0 },
1370 { "thumb_set", s_thumb_set, 0 },
1371 { "even", s_even, 0 },
1372 { "ltorg", s_ltorg, 0 },
1373 { "pool", s_ltorg, 0 },
1374 /* Allow for the effect of section changes. */
1375 { "text", arm_s_text, 0 },
1376 { "data", arm_s_data, 0 },
1377#ifdef OBJ_ELF
1378 { "section", arm_s_section, 0 },
1379 { "section.s", arm_s_section, 0 },
1380 { "sect", arm_s_section, 0 },
1381 { "sect.s", arm_s_section, 0 },
1382 { "word", s_arm_elf_cons, 4 },
1383 { "long", s_arm_elf_cons, 4 },
1384 { "file", dwarf2_directive_file, 0 },
1385 { "loc", dwarf2_directive_loc, 0 },
1386#else
1387 { "word", cons, 4},
1388#endif
1389 { "extend", float_cons, 'x' },
1390 { "ldouble", float_cons, 'x' },
1391 { "packed", float_cons, 'p' },
1392 { 0, 0, 0 }
1393};
1394
1395/* Stuff needed to resolve the label ambiguity
1396 As:
1397 ...
1398 label: <insn>
1399 may differ from:
1400 ...
1401 label:
1402 <insn>
1403*/
1404
1405symbolS * last_label_seen;
1406static int label_is_thumb_function_name = false;
1407
1408/* Literal stuff. */
1409
1410#define MAX_LITERAL_POOL_SIZE 1024
1411
1412typedef struct literalS
1413{
1414 struct expressionS exp;
1415 struct arm_it * inst;
1416} literalT;
1417
1418literalT literals[MAX_LITERAL_POOL_SIZE];
1419
1420/* Next free entry in the pool. */
1421int next_literal_pool_place = 0;
1422
1423/* Next literal pool number. */
1424int lit_pool_num = 1;
1425
1426symbolS * current_poolP = NULL;
1427
1428static int
1429add_to_lit_pool ()
1430{
1431 int lit_count = 0;
1432
1433 if (current_poolP == NULL)
1434 current_poolP = symbol_create (FAKE_LABEL_NAME, undefined_section,
1435 (valueT) 0, &zero_address_frag);
1436
1437 /* Check if this literal value is already in the pool: */
1438 while (lit_count < next_literal_pool_place)
1439 {
1440 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
1441 && inst.reloc.exp.X_op == O_constant
1442 && (literals[lit_count].exp.X_add_number
1443 == inst.reloc.exp.X_add_number)
1444 && literals[lit_count].exp.X_unsigned == inst.reloc.exp.X_unsigned)
1445 break;
1446
1447 if (literals[lit_count].exp.X_op == inst.reloc.exp.X_op
1448 && inst.reloc.exp.X_op == O_symbol
1449 && (literals[lit_count].exp.X_add_number
1450 == inst.reloc.exp.X_add_number)
1451 && (literals[lit_count].exp.X_add_symbol
1452 == inst.reloc.exp.X_add_symbol)
1453 && (literals[lit_count].exp.X_op_symbol
1454 == inst.reloc.exp.X_op_symbol))
1455 break;
1456
1457 lit_count++;
1458 }
1459
1460 if (lit_count == next_literal_pool_place) /* New entry. */
1461 {
1462 if (next_literal_pool_place >= MAX_LITERAL_POOL_SIZE)
1463 {
1464 inst.error = _("Literal Pool Overflow");
1465 return FAIL;
1466 }
1467
1468 literals[next_literal_pool_place].exp = inst.reloc.exp;
1469 lit_count = next_literal_pool_place++;
1470 }
1471
1472 inst.reloc.exp.X_op = O_symbol;
1473 inst.reloc.exp.X_add_number = (lit_count) * 4 - 8;
1474 inst.reloc.exp.X_add_symbol = current_poolP;
1475
1476 return SUCCESS;
1477}
1478
1479/* Can't use symbol_new here, so have to create a symbol and then at
1480 a later date assign it a value. Thats what these functions do. */
1481
1482static void
1483symbol_locate (symbolP, name, segment, valu, frag)
1484 symbolS * symbolP;
1485 CONST char * name; /* It is copied, the caller can modify. */
1486 segT segment; /* Segment identifier (SEG_<something>). */
1487 valueT valu; /* Symbol value. */
1488 fragS * frag; /* Associated fragment. */
1489{
1490 unsigned int name_length;
1491 char * preserved_copy_of_name;
1492
1493 name_length = strlen (name) + 1; /* +1 for \0. */
1494 obstack_grow (&notes, name, name_length);
1495 preserved_copy_of_name = obstack_finish (&notes);
1496#ifdef STRIP_UNDERSCORE
1497 if (preserved_copy_of_name[0] == '_')
1498 preserved_copy_of_name++;
1499#endif
1500
1501#ifdef tc_canonicalize_symbol_name
1502 preserved_copy_of_name =
1503 tc_canonicalize_symbol_name (preserved_copy_of_name);
1504#endif
1505
1506 S_SET_NAME (symbolP, preserved_copy_of_name);
1507
1508 S_SET_SEGMENT (symbolP, segment);
1509 S_SET_VALUE (symbolP, valu);
1510 symbol_clear_list_pointers(symbolP);
1511
1512 symbol_set_frag (symbolP, frag);
1513
1514 /* Link to end of symbol chain. */
1515 {
1516 extern int symbol_table_frozen;
1517 if (symbol_table_frozen)
1518 abort ();
1519 }
1520
1521 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
1522
1523 obj_symbol_new_hook (symbolP);
1524
1525#ifdef tc_symbol_new_hook
1526 tc_symbol_new_hook (symbolP);
1527#endif
1528
1529#ifdef DEBUG_SYMS
1530 verify_symbol_chain (symbol_rootP, symbol_lastP);
1531#endif /* DEBUG_SYMS */
1532}
1533
1534/* Check that an immediate is valid.
1535 If so, convert it to the right format. */
1536
1537static unsigned int
1538validate_immediate (val)
1539 unsigned int val;
1540{
1541 unsigned int a;
1542 unsigned int i;
1543
1544#define rotate_left(v, n) (v << n | v >> (32 - n))
1545
1546 for (i = 0; i < 32; i += 2)
1547 if ((a = rotate_left (val, i)) <= 0xff)
1548 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
1549
1550 return FAIL;
1551}
1552
1553/* Check to see if an immediate can be computed as two seperate immediate
1554 values, added together. We already know that this value cannot be
1555 computed by just one ARM instruction. */
1556
1557static unsigned int
1558validate_immediate_twopart (val, highpart)
1559 unsigned int val;
1560 unsigned int * highpart;
1561{
1562 unsigned int a;
1563 unsigned int i;
1564
1565 for (i = 0; i < 32; i += 2)
1566 if (((a = rotate_left (val, i)) & 0xff) != 0)
1567 {
1568 if (a & 0xff00)
1569 {
1570 if (a & ~ 0xffff)
1571 continue;
1572 * highpart = (a >> 8) | ((i + 24) << 7);
1573 }
1574 else if (a & 0xff0000)
1575 {
1576 if (a & 0xff000000)
1577 continue;
1578 * highpart = (a >> 16) | ((i + 16) << 7);
1579 }
1580 else
1581 {
1582 assert (a & 0xff000000);
1583 * highpart = (a >> 24) | ((i + 8) << 7);
1584 }
1585
1586 return (a & 0xff) | (i << 7);
1587 }
1588
1589 return FAIL;
1590}
1591
1592static int
1593validate_offset_imm (val, hwse)
1594 unsigned int val;
1595 int hwse;
1596{
1597 if ((hwse && val > 255) || val > 4095)
1598 return FAIL;
1599 return val;
1600}
1601
1602static void
1603s_req (a)
1604 int a ATTRIBUTE_UNUSED;
1605{
1606 as_bad (_("Invalid syntax for .req directive."));
1607}
1608
1609static void
1610s_bss (ignore)
1611 int ignore ATTRIBUTE_UNUSED;
1612{
1613 /* We don't support putting frags in the BSS segment, we fake it by
1614 marking in_bss, then looking at s_skip for clues. */
1615 subseg_set (bss_section, 0);
1616 demand_empty_rest_of_line ();
1617}
1618
1619static void
1620s_even (ignore)
1621 int ignore ATTRIBUTE_UNUSED;
1622{
1623 /* Never make frag if expect extra pass. */
1624 if (!need_pass_2)
1625 frag_align (1, 0, 0);
1626
1627 record_alignment (now_seg, 1);
1628
1629 demand_empty_rest_of_line ();
1630}
1631
1632static void
1633s_ltorg (ignored)
1634 int ignored ATTRIBUTE_UNUSED;
1635{
1636 int lit_count = 0;
1637 char sym_name[20];
1638
1639 if (current_poolP == NULL)
1640 return;
1641
1642 /* Align pool as you have word accesses.
1643 Only make a frag if we have to. */
1644 if (!need_pass_2)
1645 frag_align (2, 0, 0);
1646
1647 record_alignment (now_seg, 2);
1648
1649 sprintf (sym_name, "$$lit_\002%x", lit_pool_num++);
1650
1651 symbol_locate (current_poolP, sym_name, now_seg,
1652 (valueT) frag_now_fix (), frag_now);
1653 symbol_table_insert (current_poolP);
1654
1655 ARM_SET_THUMB (current_poolP, thumb_mode);
1656
1657#if defined OBJ_COFF || defined OBJ_ELF
1658 ARM_SET_INTERWORK (current_poolP, support_interwork);
1659#endif
1660
1661 while (lit_count < next_literal_pool_place)
1662 /* First output the expression in the instruction to the pool. */
1663 emit_expr (&(literals[lit_count++].exp), 4); /* .word */
1664
1665 next_literal_pool_place = 0;
1666 current_poolP = NULL;
1667}
1668
1669/* Same as s_align_ptwo but align 0 => align 2. */
1670
1671static void
1672s_align (unused)
1673 int unused ATTRIBUTE_UNUSED;
1674{
1675 register int temp;
1676 register long temp_fill;
1677 long max_alignment = 15;
1678
1679 temp = get_absolute_expression ();
1680 if (temp > max_alignment)
1681 as_bad (_("Alignment too large: %d. assumed."), temp = max_alignment);
1682 else if (temp < 0)
1683 {
1684 as_bad (_("Alignment negative. 0 assumed."));
1685 temp = 0;
1686 }
1687
1688 if (*input_line_pointer == ',')
1689 {
1690 input_line_pointer++;
1691 temp_fill = get_absolute_expression ();
1692 }
1693 else
1694 temp_fill = 0;
1695
1696 if (!temp)
1697 temp = 2;
1698
1699 /* Only make a frag if we HAVE to. */
1700 if (temp && !need_pass_2)
1701 frag_align (temp, (int) temp_fill, 0);
1702 demand_empty_rest_of_line ();
1703
1704 record_alignment (now_seg, temp);
1705}
1706
1707static void
1708s_force_thumb (ignore)
1709 int ignore ATTRIBUTE_UNUSED;
1710{
1711 /* If we are not already in thumb mode go into it, EVEN if
1712 the target processor does not support thumb instructions.
1713 This is used by gcc/config/arm/lib1funcs.asm for example
1714 to compile interworking support functions even if the
1715 target processor should not support interworking. */
1716 if (! thumb_mode)
1717 {
1718 thumb_mode = 2;
1719
1720 record_alignment (now_seg, 1);
1721 }
1722
1723 demand_empty_rest_of_line ();
1724}
1725
1726static void
1727s_thumb_func (ignore)
1728 int ignore ATTRIBUTE_UNUSED;
1729{
1730 if (! thumb_mode)
1731 opcode_select (16);
1732
1733 /* The following label is the name/address of the start of a Thumb function.
1734 We need to know this for the interworking support. */
1735 label_is_thumb_function_name = true;
1736
1737 demand_empty_rest_of_line ();
1738}
1739
1740/* Perform a .set directive, but also mark the alias as
1741 being a thumb function. */
1742
1743static void
1744s_thumb_set (equiv)
1745 int equiv;
1746{
1747 /* XXX the following is a duplicate of the code for s_set() in read.c
1748 We cannot just call that code as we need to get at the symbol that
1749 is created. */
1750 register char * name;
1751 register char delim;
1752 register char * end_name;
1753 register symbolS * symbolP;
1754
1755 /* Especial apologies for the random logic:
1756 This just grew, and could be parsed much more simply!
1757 Dean - in haste. */
1758 name = input_line_pointer;
1759 delim = get_symbol_end ();
1760 end_name = input_line_pointer;
1761 *end_name = delim;
1762
1763 SKIP_WHITESPACE ();
1764
1765 if (*input_line_pointer != ',')
1766 {
1767 *end_name = 0;
1768 as_bad (_("Expected comma after name \"%s\""), name);
1769 *end_name = delim;
1770 ignore_rest_of_line ();
1771 return;
1772 }
1773
1774 input_line_pointer++;
1775 *end_name = 0;
1776
1777 if (name[0] == '.' && name[1] == '\0')
1778 {
1779 /* XXX - this should not happen to .thumb_set. */
1780 abort ();
1781 }
1782
1783 if ((symbolP = symbol_find (name)) == NULL
1784 && (symbolP = md_undefined_symbol (name)) == NULL)
1785 {
1786#ifndef NO_LISTING
1787 /* When doing symbol listings, play games with dummy fragments living
1788 outside the normal fragment chain to record the file and line info
1789 for this symbol. */
1790 if (listing & LISTING_SYMBOLS)
1791 {
1792 extern struct list_info_struct * listing_tail;
1793 fragS * dummy_frag = (fragS *) xmalloc (sizeof (fragS));
1794
1795 memset (dummy_frag, 0, sizeof (fragS));
1796 dummy_frag->fr_type = rs_fill;
1797 dummy_frag->line = listing_tail;
1798 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1799 dummy_frag->fr_symbol = symbolP;
1800 }
1801 else
1802#endif
1803 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1804
1805#ifdef OBJ_COFF
1806 /* "set" symbols are local unless otherwise specified. */
1807 SF_SET_LOCAL (symbolP);
1808#endif /* OBJ_COFF */
1809 } /* Make a new symbol. */
1810
1811 symbol_table_insert (symbolP);
1812
1813 * end_name = delim;
1814
1815 if (equiv
1816 && S_IS_DEFINED (symbolP)
1817 && S_GET_SEGMENT (symbolP) != reg_section)
1818 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1819
1820 pseudo_set (symbolP);
1821
1822 demand_empty_rest_of_line ();
1823
1824 /* XXX Now we come to the Thumb specific bit of code. */
1825
1826 THUMB_SET_FUNC (symbolP, 1);
1827 ARM_SET_THUMB (symbolP, 1);
1828#if defined OBJ_ELF || defined OBJ_COFF
1829 ARM_SET_INTERWORK (symbolP, support_interwork);
1830#endif
1831}
1832
1833/* If we change section we must dump the literal pool first. */
1834
1835static void
1836arm_s_text (ignore)
1837 int ignore;
1838{
1839 if (now_seg != text_section)
1840 s_ltorg (0);
1841
1842#ifdef OBJ_ELF
1843 obj_elf_text (ignore);
1844#else
1845 s_text (ignore);
1846#endif
1847}
1848
1849static void
1850arm_s_data (ignore)
1851 int ignore;
1852{
1853 if (flag_readonly_data_in_text)
1854 {
1855 if (now_seg != text_section)
1856 s_ltorg (0);
1857 }
1858 else if (now_seg != data_section)
1859 s_ltorg (0);
1860
1861#ifdef OBJ_ELF
1862 obj_elf_data (ignore);
1863#else
1864 s_data (ignore);
1865#endif
1866}
1867
1868#ifdef OBJ_ELF
1869static void
1870arm_s_section (ignore)
1871 int ignore;
1872{
1873 s_ltorg (0);
1874
1875 obj_elf_section (ignore);
1876}
1877#endif
1878
1879static void
1880opcode_select (width)
1881 int width;
1882{
1883 switch (width)
1884 {
1885 case 16:
1886 if (! thumb_mode)
1887 {
1888 if (! (cpu_variant & ARM_EXT_THUMB))
1889 as_bad (_("selected processor does not support THUMB opcodes"));
1890
1891 thumb_mode = 1;
1892 /* No need to force the alignment, since we will have been
1893 coming from ARM mode, which is word-aligned. */
1894 record_alignment (now_seg, 1);
1895 }
1896 break;
1897
1898 case 32:
1899 if (thumb_mode)
1900 {
1901 if ((cpu_variant & ARM_ANY) == ARM_EXT_THUMB)
1902 as_bad (_("selected processor does not support ARM opcodes"));
1903
1904 thumb_mode = 0;
1905
1906 if (!need_pass_2)
1907 frag_align (2, 0, 0);
1908
1909 record_alignment (now_seg, 1);
1910 }
1911 break;
1912
1913 default:
1914 as_bad (_("invalid instruction size selected (%d)"), width);
1915 }
1916}
1917
1918static void
1919s_arm (ignore)
1920 int ignore ATTRIBUTE_UNUSED;
1921{
1922 opcode_select (32);
1923 demand_empty_rest_of_line ();
1924}
1925
1926static void
1927s_thumb (ignore)
1928 int ignore ATTRIBUTE_UNUSED;
1929{
1930 opcode_select (16);
1931 demand_empty_rest_of_line ();
1932}
1933
1934static void
1935s_code (unused)
1936 int unused ATTRIBUTE_UNUSED;
1937{
1938 register int temp;
1939
1940 temp = get_absolute_expression ();
1941 switch (temp)
1942 {
1943 case 16:
1944 case 32:
1945 opcode_select (temp);
1946 break;
1947
1948 default:
1949 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1950 }
1951}
1952
1953static void
1954end_of_line (str)
1955 char * str;
1956{
1957 skip_whitespace (str);
1958
1959 if (* str != '\0')
1960 inst.error = _("Garbage following instruction");
1961}
1962
1963static int
1964skip_past_comma (str)
1965 char ** str;
1966{
1967 char * p = * str, c;
1968 int comma = 0;
1969
1970 while ((c = *p) == ' ' || c == ',')
1971 {
1972 p++;
1973 if (c == ',' && comma++)
1974 return FAIL;
1975 }
1976
1977 if (c == '\0')
1978 return FAIL;
1979
1980 *str = p;
1981 return comma ? SUCCESS : FAIL;
1982}
1983
1984/* A standard register must be given at this point.
1985 SHIFT is the place to put it in inst.instruction.
1986 Restores input start point on error.
1987 Returns the reg#, or FAIL. */
1988
1989static int
1990reg_required_here (str, shift)
1991 char ** str;
1992 int shift;
1993{
1994 static char buff [128]; /* XXX */
1995 int reg;
1996 char * start = * str;
1997
1998 if ((reg = arm_reg_parse (str)) != FAIL && int_register (reg))
1999 {
2000 if (shift >= 0)
2001 inst.instruction |= reg << shift;
2002 return reg;
2003 }
2004
2005 /* Restore the start point, we may have got a reg of the wrong class. */
2006 *str = start;
2007
2008 /* In the few cases where we might be able to accept something else
2009 this error can be overridden. */
2010 sprintf (buff, _("Register expected, not '%.100s'"), start);
2011 inst.error = buff;
2012
2013 return FAIL;
2014}
2015
2016static CONST struct asm_psr *
2017arm_psr_parse (ccp)
2018 register char ** ccp;
2019{
2020 char * start = * ccp;
2021 char c;
2022 char * p;
2023 CONST struct asm_psr * psr;
2024
2025 p = start;
2026
2027 /* Skip to the end of the next word in the input stream. */
2028 do
2029 {
2030 c = *p++;
2031 }
3882b010 2032 while (ISALPHA (c) || c == '_');
b99bd4ef
NC
2033
2034 /* Terminate the word. */
2035 *--p = 0;
2036
2037 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
2038 feature for ease of use and backwards compatibility. */
2039 if (!strncmp (start, "cpsr", 4))
2040 strncpy (start, "CPSR", 4);
2041 else if (!strncmp (start, "spsr", 4))
2042 strncpy (start, "SPSR", 4);
2043
2044 /* Now locate the word in the psr hash table. */
2045 psr = (CONST struct asm_psr *) hash_find (arm_psr_hsh, start);
2046
2047 /* Restore the input stream. */
2048 *p = c;
2049
2050 /* If we found a valid match, advance the
2051 stream pointer past the end of the word. */
2052 *ccp = p;
2053
2054 return psr;
2055}
2056
2057/* Parse the input looking for a PSR flag. */
2058
2059static int
2060psr_required_here (str)
2061 char ** str;
2062{
2063 char * start = * str;
2064 CONST struct asm_psr * psr;
2065
2066 psr = arm_psr_parse (str);
2067
2068 if (psr)
2069 {
2070 /* If this is the SPSR that is being modified, set the R bit. */
2071 if (! psr->cpsr)
2072 inst.instruction |= SPSR_BIT;
2073
2074 /* Set the psr flags in the MSR instruction. */
2075 inst.instruction |= psr->field << PSR_SHIFT;
2076
2077 return SUCCESS;
2078 }
2079
2080 /* In the few cases where we might be able to accept
2081 something else this error can be overridden. */
2082 inst.error = _("flag for {c}psr instruction expected");
2083
2084 /* Restore the start point. */
2085 *str = start;
2086 return FAIL;
2087}
2088
2089static int
2090co_proc_number (str)
2091 char ** str;
2092{
2093 int processor, pchar;
2094
2095 skip_whitespace (* str);
2096
2097 /* The data sheet seems to imply that just a number on its own is valid
2098 here, but the RISC iX assembler seems to accept a prefix 'p'. We will
2099 accept either. */
2100 if (**str == 'p' || **str == 'P')
2101 (*str)++;
2102
2103 pchar = *(*str)++;
2104 if (pchar >= '0' && pchar <= '9')
2105 {
2106 processor = pchar - '0';
2107 if (**str >= '0' && **str <= '9')
2108 {
2109 processor = processor * 10 + *(*str)++ - '0';
2110 if (processor > 15)
2111 {
2112 inst.error = _("Illegal co-processor number");
2113 return FAIL;
2114 }
2115 }
2116 }
2117 else
2118 {
2119 inst.error = _("Bad or missing co-processor number");
2120 return FAIL;
2121 }
2122
2123 inst.instruction |= processor << 8;
2124 return SUCCESS;
2125}
2126
2127static int
2128cp_opc_expr (str, where, length)
2129 char ** str;
2130 int where;
2131 int length;
2132{
2133 expressionS expr;
2134
2135 skip_whitespace (* str);
2136
2137 memset (&expr, '\0', sizeof (expr));
2138
2139 if (my_get_expression (&expr, str))
2140 return FAIL;
2141 if (expr.X_op != O_constant)
2142 {
2143 inst.error = _("bad or missing expression");
2144 return FAIL;
2145 }
2146
2147 if ((expr.X_add_number & ((1 << length) - 1)) != expr.X_add_number)
2148 {
2149 inst.error = _("immediate co-processor expression too large");
2150 return FAIL;
2151 }
2152
2153 inst.instruction |= expr.X_add_number << where;
2154 return SUCCESS;
2155}
2156
2157static int
2158cp_reg_required_here (str, where)
2159 char ** str;
2160 int where;
2161{
2162 int reg;
2163 char * start = *str;
2164
2165 if ((reg = arm_reg_parse (str)) != FAIL && cp_register (reg))
2166 {
2167 reg &= 15;
2168 inst.instruction |= reg << where;
2169 return reg;
2170 }
2171
2172 /* In the few cases where we might be able to accept something else
2173 this error can be overridden. */
2174 inst.error = _("Co-processor register expected");
2175
2176 /* Restore the start point. */
2177 *str = start;
2178 return FAIL;
2179}
2180
2181static int
2182fp_reg_required_here (str, where)
2183 char ** str;
2184 int where;
2185{
2186 int reg;
2187 char * start = * str;
2188
2189 if ((reg = arm_reg_parse (str)) != FAIL && fp_register (reg))
2190 {
2191 reg &= 7;
2192 inst.instruction |= reg << where;
2193 return reg;
2194 }
2195
2196 /* In the few cases where we might be able to accept something else
2197 this error can be overridden. */
2198 inst.error = _("Floating point register expected");
2199
2200 /* Restore the start point. */
2201 *str = start;
2202 return FAIL;
2203}
2204
2205static int
2206cp_address_offset (str)
2207 char ** str;
2208{
2209 int offset;
2210
2211 skip_whitespace (* str);
2212
2213 if (! is_immediate_prefix (**str))
2214 {
2215 inst.error = _("immediate expression expected");
2216 return FAIL;
2217 }
2218
2219 (*str)++;
2220
2221 if (my_get_expression (& inst.reloc.exp, str))
2222 return FAIL;
2223
2224 if (inst.reloc.exp.X_op == O_constant)
2225 {
2226 offset = inst.reloc.exp.X_add_number;
2227
2228 if (offset & 3)
2229 {
2230 inst.error = _("co-processor address must be word aligned");
2231 return FAIL;
2232 }
2233
2234 if (offset > 1023 || offset < -1023)
2235 {
2236 inst.error = _("offset too large");
2237 return FAIL;
2238 }
2239
2240 if (offset >= 0)
2241 inst.instruction |= INDEX_UP;
2242 else
2243 offset = -offset;
2244
2245 inst.instruction |= offset >> 2;
2246 }
2247 else
2248 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2249
2250 return SUCCESS;
2251}
2252
2253static int
2254cp_address_required_here (str)
2255 char ** str;
2256{
2257 char * p = * str;
2258 int pre_inc = 0;
2259 int write_back = 0;
2260
2261 if (*p == '[')
2262 {
2263 int reg;
2264
2265 p++;
2266 skip_whitespace (p);
2267
2268 if ((reg = reg_required_here (& p, 16)) == FAIL)
2269 return FAIL;
2270
2271 skip_whitespace (p);
2272
2273 if (*p == ']')
2274 {
2275 p++;
2276
2277 if (skip_past_comma (& p) == SUCCESS)
2278 {
2279 /* [Rn], #expr */
2280 write_back = WRITE_BACK;
2281
2282 if (reg == REG_PC)
2283 {
2284 inst.error = _("pc may not be used in post-increment");
2285 return FAIL;
2286 }
2287
2288 if (cp_address_offset (& p) == FAIL)
2289 return FAIL;
2290 }
2291 else
2292 pre_inc = PRE_INDEX | INDEX_UP;
2293 }
2294 else
2295 {
2296 /* '['Rn, #expr']'[!] */
2297
2298 if (skip_past_comma (& p) == FAIL)
2299 {
2300 inst.error = _("pre-indexed expression expected");
2301 return FAIL;
2302 }
2303
2304 pre_inc = PRE_INDEX;
2305
2306 if (cp_address_offset (& p) == FAIL)
2307 return FAIL;
2308
2309 skip_whitespace (p);
2310
2311 if (*p++ != ']')
2312 {
2313 inst.error = _("missing ]");
2314 return FAIL;
2315 }
2316
2317 skip_whitespace (p);
2318
2319 if (*p == '!')
2320 {
2321 if (reg == REG_PC)
2322 {
2323 inst.error = _("pc may not be used with write-back");
2324 return FAIL;
2325 }
2326
2327 p++;
2328 write_back = WRITE_BACK;
2329 }
2330 }
2331 }
2332 else
2333 {
2334 if (my_get_expression (&inst.reloc.exp, &p))
2335 return FAIL;
2336
2337 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
2338 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
2339 inst.reloc.pc_rel = 1;
2340 inst.instruction |= (REG_PC << 16);
2341 pre_inc = PRE_INDEX;
2342 }
2343
2344 inst.instruction |= write_back | pre_inc;
2345 *str = p;
2346 return SUCCESS;
2347}
2348
2349static void
2350do_nop (str, flags)
2351 char * str;
2352 unsigned long flags;
2353{
2354 /* Do nothing really. */
2355 inst.instruction |= flags; /* This is pointless. */
2356 end_of_line (str);
2357 return;
2358}
2359
2360static void
2361do_mrs (str, flags)
2362 char *str;
2363 unsigned long flags;
2364{
2365 int skip = 0;
2366
2367 /* Only one syntax. */
2368 skip_whitespace (str);
2369
2370 if (reg_required_here (&str, 12) == FAIL)
2371 {
2372 inst.error = BAD_ARGS;
2373 return;
2374 }
2375
2376 if (skip_past_comma (&str) == FAIL)
2377 {
2378 inst.error = _("comma expected after register name");
2379 return;
2380 }
2381
2382 skip_whitespace (str);
2383
2384 if ( strcmp (str, "CPSR") == 0
2385 || strcmp (str, "SPSR") == 0
2386 /* Lower case versions for backwards compatability. */
2387 || strcmp (str, "cpsr") == 0
2388 || strcmp (str, "spsr") == 0)
2389 skip = 4;
2390
2391 /* This is for backwards compatability with older toolchains. */
2392 else if ( strcmp (str, "cpsr_all") == 0
2393 || strcmp (str, "spsr_all") == 0)
2394 skip = 8;
2395 else
2396 {
2397 inst.error = _("{C|S}PSR expected");
2398 return;
2399 }
2400
2401 if (* str == 's' || * str == 'S')
2402 inst.instruction |= SPSR_BIT;
2403 str += skip;
2404
2405 inst.instruction |= flags;
2406 end_of_line (str);
2407}
2408
2409/* Two possible forms:
2410 "{C|S}PSR_<field>, Rm",
2411 "{C|S}PSR_f, #expression". */
2412
2413static void
2414do_msr (str, flags)
2415 char * str;
2416 unsigned long flags;
2417{
2418 skip_whitespace (str);
2419
2420 if (psr_required_here (& str) == FAIL)
2421 return;
2422
2423 if (skip_past_comma (& str) == FAIL)
2424 {
2425 inst.error = _("comma missing after psr flags");
2426 return;
2427 }
2428
2429 skip_whitespace (str);
2430
2431 if (reg_required_here (& str, 0) != FAIL)
2432 {
2433 inst.error = NULL;
2434 inst.instruction |= flags;
2435 end_of_line (str);
2436 return;
2437 }
2438
2439 if (! is_immediate_prefix (* str))
2440 {
2441 inst.error =
2442 _("only a register or immediate value can follow a psr flag");
2443 return;
2444 }
2445
2446 str ++;
2447 inst.error = NULL;
2448
2449 if (my_get_expression (& inst.reloc.exp, & str))
2450 {
2451 inst.error =
2452 _("only a register or immediate value can follow a psr flag");
2453 return;
2454 }
2455
2456#if 0 /* The first edition of the ARM architecture manual stated that
2457 writing anything other than the flags with an immediate operation
2458 had UNPREDICTABLE effects. This constraint was removed in the
2459 second edition of the specification. */
2460 if ((cpu_variant & ARM_EXT_V5) != ARM_EXT_V5
2461 && inst.instruction & ((PSR_c | PSR_x | PSR_s) << PSR_SHIFT))
2462 {
2463 inst.error = _("immediate value cannot be used to set this field");
2464 return;
2465 }
2466#endif
2467
2468 flags |= INST_IMMEDIATE;
2469
2470 if (inst.reloc.exp.X_add_symbol)
2471 {
2472 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
2473 inst.reloc.pc_rel = 0;
2474 }
2475 else
2476 {
2477 unsigned value = validate_immediate (inst.reloc.exp.X_add_number);
2478
2479 if (value == (unsigned) FAIL)
2480 {
2481 inst.error = _("Invalid constant");
2482 return;
2483 }
2484
2485 inst.instruction |= value;
2486 }
2487
2488 inst.error = NULL;
2489 inst.instruction |= flags;
2490 end_of_line (str);
2491}
2492
2493/* Long Multiply Parser
2494 UMULL RdLo, RdHi, Rm, Rs
2495 SMULL RdLo, RdHi, Rm, Rs
2496 UMLAL RdLo, RdHi, Rm, Rs
2497 SMLAL RdLo, RdHi, Rm, Rs. */
2498
2499static void
2500do_mull (str, flags)
2501 char * str;
2502 unsigned long flags;
2503{
2504 int rdlo, rdhi, rm, rs;
2505
2506 /* Only one format "rdlo, rdhi, rm, rs". */
2507 skip_whitespace (str);
2508
2509 if ((rdlo = reg_required_here (&str, 12)) == FAIL)
2510 {
2511 inst.error = BAD_ARGS;
2512 return;
2513 }
2514
2515 if (skip_past_comma (&str) == FAIL
2516 || (rdhi = reg_required_here (&str, 16)) == FAIL)
2517 {
2518 inst.error = BAD_ARGS;
2519 return;
2520 }
2521
2522 if (skip_past_comma (&str) == FAIL
2523 || (rm = reg_required_here (&str, 0)) == FAIL)
2524 {
2525 inst.error = BAD_ARGS;
2526 return;
2527 }
2528
2529 /* rdhi, rdlo and rm must all be different. */
2530 if (rdlo == rdhi || rdlo == rm || rdhi == rm)
2531 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
2532
2533 if (skip_past_comma (&str) == FAIL
2534 || (rs = reg_required_here (&str, 8)) == FAIL)
2535 {
2536 inst.error = BAD_ARGS;
2537 return;
2538 }
2539
2540 if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
2541 {
2542 inst.error = BAD_PC;
2543 return;
2544 }
2545
2546 inst.instruction |= flags;
2547 end_of_line (str);
2548 return;
2549}
2550
2551static void
2552do_mul (str, flags)
2553 char * str;
2554 unsigned long flags;
2555{
2556 int rd, rm;
2557
2558 /* Only one format "rd, rm, rs". */
2559 skip_whitespace (str);
2560
2561 if ((rd = reg_required_here (&str, 16)) == FAIL)
2562 {
2563 inst.error = BAD_ARGS;
2564 return;
2565 }
2566
2567 if (rd == REG_PC)
2568 {
2569 inst.error = BAD_PC;
2570 return;
2571 }
2572
2573 if (skip_past_comma (&str) == FAIL
2574 || (rm = reg_required_here (&str, 0)) == FAIL)
2575 {
2576 inst.error = BAD_ARGS;
2577 return;
2578 }
2579
2580 if (rm == REG_PC)
2581 {
2582 inst.error = BAD_PC;
2583 return;
2584 }
2585
2586 if (rm == rd)
2587 as_tsktsk (_("rd and rm should be different in mul"));
2588
2589 if (skip_past_comma (&str) == FAIL
2590 || (rm = reg_required_here (&str, 8)) == FAIL)
2591 {
2592 inst.error = BAD_ARGS;
2593 return;
2594 }
2595
2596 if (rm == REG_PC)
2597 {
2598 inst.error = BAD_PC;
2599 return;
2600 }
2601
2602 inst.instruction |= flags;
2603 end_of_line (str);
2604 return;
2605}
2606
2607static void
2608do_mla (str, flags)
2609 char * str;
2610 unsigned long flags;
2611{
2612 int rd, rm;
2613
2614 /* Only one format "rd, rm, rs, rn". */
2615 skip_whitespace (str);
2616
2617 if ((rd = reg_required_here (&str, 16)) == FAIL)
2618 {
2619 inst.error = BAD_ARGS;
2620 return;
2621 }
2622
2623 if (rd == REG_PC)
2624 {
2625 inst.error = BAD_PC;
2626 return;
2627 }
2628
2629 if (skip_past_comma (&str) == FAIL
2630 || (rm = reg_required_here (&str, 0)) == FAIL)
2631 {
2632 inst.error = BAD_ARGS;
2633 return;
2634 }
2635
2636 if (rm == REG_PC)
2637 {
2638 inst.error = BAD_PC;
2639 return;
2640 }
2641
2642 if (rm == rd)
2643 as_tsktsk (_("rd and rm should be different in mla"));
2644
2645 if (skip_past_comma (&str) == FAIL
2646 || (rd = reg_required_here (&str, 8)) == FAIL
2647 || skip_past_comma (&str) == FAIL
2648 || (rm = reg_required_here (&str, 12)) == FAIL)
2649 {
2650 inst.error = BAD_ARGS;
2651 return;
2652 }
2653
2654 if (rd == REG_PC || rm == REG_PC)
2655 {
2656 inst.error = BAD_PC;
2657 return;
2658 }
2659
2660 inst.instruction |= flags;
2661 end_of_line (str);
2662 return;
2663}
2664
2665/* Expects *str -> the characters "acc0", possibly with leading blanks.
2666 Advances *str to the next non-alphanumeric.
2667 Returns 0, or else FAIL (in which case sets inst.error).
2668
2669 (In a future XScale, there may be accumulators other than zero.
2670 At that time this routine and its callers can be upgraded to suit.) */
2671
2672static int
2673accum0_required_here (str)
2674 char ** str;
2675{
2676 static char buff [128]; /* Note the address is taken. Hence, static. */
2677 char * p = * str;
2678 char c;
2679 int result = 0; /* The accum number. */
2680
2681 skip_whitespace (p);
2682
2683 *str = p; /* Advance caller's string pointer too. */
2684 c = *p++;
3882b010 2685 while (ISALNUM (c))
b99bd4ef
NC
2686 c = *p++;
2687
2688 *--p = 0; /* Aap nul into input buffer at non-alnum. */
2689
2690 if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
2691 {
2692 sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
2693 inst.error = buff;
2694 result = FAIL;
2695 }
2696
2697 *p = c; /* Unzap. */
2698 *str = p; /* Caller's string pointer to after match. */
2699 return result;
2700}
2701
2702/* Expects **str -> after a comma. May be leading blanks.
2703 Advances *str, recognizing a load mode, and setting inst.instruction.
2704 Returns rn, or else FAIL (in which case may set inst.error
2705 and not advance str)
2706
2707 Note: doesn't know Rd, so no err checks that require such knowledge. */
2708
2709static int
2710ld_mode_required_here (string)
2711 char ** string;
2712{
2713 char * str = * string;
2714 int rn;
2715 int pre_inc = 0;
2716
2717 skip_whitespace (str);
2718
2719 if (* str == '[')
2720 {
2721 str++;
2722
2723 skip_whitespace (str);
2724
2725 if ((rn = reg_required_here (& str, 16)) == FAIL)
2726 return FAIL;
2727
2728 skip_whitespace (str);
2729
2730 if (* str == ']')
2731 {
2732 str ++;
2733
2734 if (skip_past_comma (& str) == SUCCESS)
2735 {
2736 /* [Rn],... (post inc) */
2737 if (ldst_extend (& str, 1) == FAIL)
2738 return FAIL;
2739 }
2740 else /* [Rn] */
2741 {
2742 skip_whitespace (str);
2743
2744 if (* str == '!')
2745 {
2746 str ++;
2747 inst.instruction |= WRITE_BACK;
2748 }
2749
2750 inst.instruction |= INDEX_UP | HWOFFSET_IMM;
2751 pre_inc = 1;
2752 }
2753 }
2754 else /* [Rn,...] */
2755 {
2756 if (skip_past_comma (& str) == FAIL)
2757 {
2758 inst.error = _("pre-indexed expression expected");
2759 return FAIL;
2760 }
2761
2762 pre_inc = 1;
2763
2764 if (ldst_extend (& str, 1) == FAIL)
2765 return FAIL;
2766
2767 skip_whitespace (str);
2768
2769 if (* str ++ != ']')
2770 {
2771 inst.error = _("missing ]");
2772 return FAIL;
2773 }
2774
2775 skip_whitespace (str);
2776
2777 if (* str == '!')
2778 {
2779 str ++;
2780 inst.instruction |= WRITE_BACK;
2781 }
2782 }
2783 }
2784 else if (* str == '=') /* ldr's "r,=label" syntax */
2785 /* We should never reach here, because <text> = <expression> is
2786 caught gas/read.c read_a_source_file() as a .set operation. */
2787 return FAIL;
2788 else /* PC +- 8 bit immediate offset. */
2789 {
2790 if (my_get_expression (& inst.reloc.exp, & str))
2791 return FAIL;
2792
2793 inst.instruction |= HWOFFSET_IMM; /* The I bit. */
2794 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
2795 inst.reloc.exp.X_add_number -= 8; /* PC rel adjust. */
2796 inst.reloc.pc_rel = 1;
2797 inst.instruction |= (REG_PC << 16);
2798
2799 rn = REG_PC;
2800 pre_inc = 1;
2801 }
2802
2803 inst.instruction |= (pre_inc ? PRE_INDEX : 0);
2804 * string = str;
2805
2806 return rn;
2807}
2808
2809/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
2810 SMLAxy{cond} Rd,Rm,Rs,Rn
2811 SMLAWy{cond} Rd,Rm,Rs,Rn
2812 Error if any register is R15. */
2813
2814static void
2815do_smla (str, flags)
2816 char * str;
2817 unsigned long flags;
2818{
2819 int rd, rm, rs, rn;
2820
2821 skip_whitespace (str);
2822
2823 if ((rd = reg_required_here (& str, 16)) == FAIL
2824 || skip_past_comma (& str) == FAIL
2825 || (rm = reg_required_here (& str, 0)) == FAIL
2826 || skip_past_comma (& str) == FAIL
2827 || (rs = reg_required_here (& str, 8)) == FAIL
2828 || skip_past_comma (& str) == FAIL
2829 || (rn = reg_required_here (& str, 12)) == FAIL)
2830 inst.error = BAD_ARGS;
2831
2832 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
2833 inst.error = BAD_PC;
2834
2835 else if (flags)
2836 inst.error = BAD_FLAGS;
2837
2838 else
2839 end_of_line (str);
2840}
2841
2842/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
2843 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
2844 Error if any register is R15.
2845 Warning if Rdlo == Rdhi. */
2846
2847static void
2848do_smlal (str, flags)
2849 char * str;
2850 unsigned long flags;
2851{
2852 int rdlo, rdhi, rm, rs;
2853
2854 skip_whitespace (str);
2855
2856 if ((rdlo = reg_required_here (& str, 12)) == FAIL
2857 || skip_past_comma (& str) == FAIL
2858 || (rdhi = reg_required_here (& str, 16)) == FAIL
2859 || skip_past_comma (& str) == FAIL
2860 || (rm = reg_required_here (& str, 0)) == FAIL
2861 || skip_past_comma (& str) == FAIL
2862 || (rs = reg_required_here (& str, 8)) == FAIL)
2863 {
2864 inst.error = BAD_ARGS;
2865 return;
2866 }
2867
2868 if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
2869 {
2870 inst.error = BAD_PC;
2871 return;
2872 }
2873
2874 if (rdlo == rdhi)
2875 as_tsktsk (_("rdhi and rdlo must be different"));
2876
2877 if (flags)
2878 inst.error = BAD_FLAGS;
2879 else
2880 end_of_line (str);
2881}
2882
2883/* ARM V5E (El Segundo) signed-multiply (argument parse)
2884 SMULxy{cond} Rd,Rm,Rs
2885 Error if any register is R15. */
2886
2887static void
2888do_smul (str, flags)
2889 char * str;
2890 unsigned long flags;
2891{
2892 int rd, rm, rs;
2893
2894 skip_whitespace (str);
2895
2896 if ((rd = reg_required_here (& str, 16)) == FAIL
2897 || skip_past_comma (& str) == FAIL
2898 || (rm = reg_required_here (& str, 0)) == FAIL
2899 || skip_past_comma (& str) == FAIL
2900 || (rs = reg_required_here (& str, 8)) == FAIL)
2901 inst.error = BAD_ARGS;
2902
2903 else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
2904 inst.error = BAD_PC;
2905
2906 else if (flags)
2907 inst.error = BAD_FLAGS;
2908
2909 else
2910 end_of_line (str);
2911}
2912
2913/* ARM V5E (El Segundo) saturating-add/subtract (argument parse)
2914 Q[D]{ADD,SUB}{cond} Rd,Rm,Rn
2915 Error if any register is R15. */
2916
2917static void
2918do_qadd (str, flags)
2919 char * str;
2920 unsigned long flags;
2921{
2922 int rd, rm, rn;
2923
2924 skip_whitespace (str);
2925
2926 if ((rd = reg_required_here (& str, 12)) == FAIL
2927 || skip_past_comma (& str) == FAIL
2928 || (rm = reg_required_here (& str, 0)) == FAIL
2929 || skip_past_comma (& str) == FAIL
2930 || (rn = reg_required_here (& str, 16)) == FAIL)
2931 inst.error = BAD_ARGS;
2932
2933 else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
2934 inst.error = BAD_PC;
2935
2936 else if (flags)
2937 inst.error = BAD_FLAGS;
2938
2939 else
2940 end_of_line (str);
2941}
2942
2943/* ARM V5E (el Segundo)
2944 MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2945 MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
2946
2947 These are equivalent to the XScale instructions MAR and MRA,
2948 respectively, when coproc == 0, opcode == 0, and CRm == 0.
2949
2950 Result unpredicatable if Rd or Rn is R15. */
2951
2952static void
2953do_co_reg2c (str, flags)
2954 char * str;
2955 unsigned long flags;
2956{
2957 int rd, rn;
2958
2959 skip_whitespace (str);
2960
2961 if (co_proc_number (& str) == FAIL)
2962 {
2963 if (!inst.error)
2964 inst.error = BAD_ARGS;
2965 return;
2966 }
2967
2968 if (skip_past_comma (& str) == FAIL
2969 || cp_opc_expr (& str, 4, 4) == FAIL)
2970 {
2971 if (!inst.error)
2972 inst.error = BAD_ARGS;
2973 return;
2974 }
2975
2976 if (skip_past_comma (& str) == FAIL
2977 || (rd = reg_required_here (& str, 12)) == FAIL)
2978 {
2979 if (!inst.error)
2980 inst.error = BAD_ARGS;
2981 return;
2982 }
2983
2984 if (skip_past_comma (& str) == FAIL
2985 || (rn = reg_required_here (& str, 16)) == FAIL)
2986 {
2987 if (!inst.error)
2988 inst.error = BAD_ARGS;
2989 return;
2990 }
2991
2992 /* Unpredictable result if rd or rn is R15. */
2993 if (rd == REG_PC || rn == REG_PC)
2994 as_tsktsk
2995 (_("Warning: Instruction unpredictable when using r15"));
2996
2997 if (skip_past_comma (& str) == FAIL
2998 || cp_reg_required_here (& str, 0) == FAIL)
2999 {
3000 if (!inst.error)
3001 inst.error = BAD_ARGS;
3002 return;
3003 }
3004
3005 if (flags)
3006 inst.error = BAD_COND;
3007
3008 end_of_line (str);
3009}
3010
3011/* ARM V5 count-leading-zeroes instruction (argument parse)
3012 CLZ{<cond>} <Rd>, <Rm>
3013 Condition defaults to COND_ALWAYS.
3014 Error if Rd or Rm are R15. */
3015
3016static void
3017do_clz (str, flags)
3018 char * str;
3019 unsigned long flags;
3020{
3021 int rd, rm;
3022
3023 if (flags)
3024 {
3025 as_bad (BAD_FLAGS);
3026 return;
3027 }
3028
3029 skip_whitespace (str);
3030
3031 if (((rd = reg_required_here (& str, 12)) == FAIL)
3032 || (skip_past_comma (& str) == FAIL)
3033 || ((rm = reg_required_here (& str, 0)) == FAIL))
3034 inst.error = BAD_ARGS;
3035
3036 else if (rd == REG_PC || rm == REG_PC )
3037 inst.error = BAD_PC;
3038
3039 else
3040 end_of_line (str);
3041}
3042
3043/* ARM V5 (argument parse)
3044 LDC2{L} <coproc>, <CRd>, <addressing mode>
3045 STC2{L} <coproc>, <CRd>, <addressing mode>
3046 Instruction is not conditional, and has 0xf in the codition field.
3047 Otherwise, it's the same as LDC/STC. */
3048
3049static void
3050do_lstc2 (str, flags)
3051 char * str;
3052 unsigned long flags;
3053{
3054 if (flags)
3055 inst.error = BAD_COND;
3056
3057 skip_whitespace (str);
3058
3059 if (co_proc_number (& str) == FAIL)
3060 {
3061 if (!inst.error)
3062 inst.error = BAD_ARGS;
3063 }
3064 else if (skip_past_comma (& str) == FAIL
3065 || cp_reg_required_here (& str, 12) == FAIL)
3066 {
3067 if (!inst.error)
3068 inst.error = BAD_ARGS;
3069 }
3070 else if (skip_past_comma (& str) == FAIL
3071 || cp_address_required_here (& str) == FAIL)
3072 {
3073 if (! inst.error)
3074 inst.error = BAD_ARGS;
3075 }
3076 else
3077 end_of_line (str);
3078}
3079
3080/* ARM V5 (argument parse)
3081 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
3082 Instruction is not conditional, and has 0xf in the condition field.
3083 Otherwise, it's the same as CDP. */
3084
3085static void
3086do_cdp2 (str, flags)
3087 char * str;
3088 unsigned long flags;
3089{
3090 skip_whitespace (str);
3091
3092 if (co_proc_number (& str) == FAIL)
3093 {
3094 if (!inst.error)
3095 inst.error = BAD_ARGS;
3096 return;
3097 }
3098
3099 if (skip_past_comma (& str) == FAIL
3100 || cp_opc_expr (& str, 20,4) == FAIL)
3101 {
3102 if (!inst.error)
3103 inst.error = BAD_ARGS;
3104 return;
3105 }
3106
3107 if (skip_past_comma (& str) == FAIL
3108 || cp_reg_required_here (& str, 12) == FAIL)
3109 {
3110 if (!inst.error)
3111 inst.error = BAD_ARGS;
3112 return;
3113 }
3114
3115 if (skip_past_comma (& str) == FAIL
3116 || cp_reg_required_here (& str, 16) == FAIL)
3117 {
3118 if (!inst.error)
3119 inst.error = BAD_ARGS;
3120 return;
3121 }
3122
3123 if (skip_past_comma (& str) == FAIL
3124 || cp_reg_required_here (& str, 0) == FAIL)
3125 {
3126 if (!inst.error)
3127 inst.error = BAD_ARGS;
3128 return;
3129 }
3130
3131 if (skip_past_comma (& str) == SUCCESS)
3132 {
3133 if (cp_opc_expr (& str, 5, 3) == FAIL)
3134 {
3135 if (!inst.error)
3136 inst.error = BAD_ARGS;
3137 return;
3138 }
3139 }
3140
3141 if (flags)
3142 inst.error = BAD_FLAGS;
3143
3144 end_of_line (str);
3145}
3146
3147/* ARM V5 (argument parse)
3148 MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3149 MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
3150 Instruction is not conditional, and has 0xf in the condition field.
3151 Otherwise, it's the same as MCR/MRC. */
3152
3153static void
3154do_co_reg2 (str, flags)
3155 char * str;
3156 unsigned long flags;
3157{
3158 skip_whitespace (str);
3159
3160 if (co_proc_number (& str) == FAIL)
3161 {
3162 if (!inst.error)
3163 inst.error = BAD_ARGS;
3164 return;
3165 }
3166
3167 if (skip_past_comma (& str) == FAIL
3168 || cp_opc_expr (& str, 21, 3) == FAIL)
3169 {
3170 if (!inst.error)
3171 inst.error = BAD_ARGS;
3172 return;
3173 }
3174
3175 if (skip_past_comma (& str) == FAIL
3176 || reg_required_here (& str, 12) == FAIL)
3177 {
3178 if (!inst.error)
3179 inst.error = BAD_ARGS;
3180 return;
3181 }
3182
3183 if (skip_past_comma (& str) == FAIL
3184 || cp_reg_required_here (& str, 16) == FAIL)
3185 {
3186 if (!inst.error)
3187 inst.error = BAD_ARGS;
3188 return;
3189 }
3190
3191 if (skip_past_comma (& str) == FAIL
3192 || cp_reg_required_here (& str, 0) == FAIL)
3193 {
3194 if (!inst.error)
3195 inst.error = BAD_ARGS;
3196 return;
3197 }
3198
3199 if (skip_past_comma (& str) == SUCCESS)
3200 {
3201 if (cp_opc_expr (& str, 5, 3) == FAIL)
3202 {
3203 if (!inst.error)
3204 inst.error = BAD_ARGS;
3205 return;
3206 }
3207 }
3208
3209 if (flags)
3210 inst.error = BAD_COND;
3211
3212 end_of_line (str);
3213}
3214
3215/* THUMB V5 breakpoint instruction (argument parse)
3216 BKPT <immed_8>. */
3217
3218static void
3219do_t_bkpt (str)
3220 char * str;
3221{
3222 expressionS expr;
3223 unsigned long number;
3224
3225 skip_whitespace (str);
3226
3227 /* Allow optional leading '#'. */
3228 if (is_immediate_prefix (*str))
3229 str ++;
3230
3231 memset (& expr, '\0', sizeof (expr));
3232 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
3233 {
3234 inst.error = _("bad or missing expression");
3235 return;
3236 }
3237
3238 number = expr.X_add_number;
3239
3240 /* Check it fits an 8 bit unsigned. */
3241 if (number != (number & 0xff))
3242 {
3243 inst.error = _("immediate value out of range");
3244 return;
3245 }
3246
3247 inst.instruction |= number;
3248
3249 end_of_line (str);
3250}
3251
3252/* ARM V5 branch-link-exchange (argument parse) for BLX(1) only.
3253 Expects inst.instruction is set for BLX(1).
3254 Note: this is cloned from do_branch, and the reloc changed to be a
3255 new one that can cope with setting one extra bit (the H bit). */
3256
3257static void
3258do_branch25 (str, flags)
3259 char * str;
3260 unsigned long flags ATTRIBUTE_UNUSED;
3261{
3262 if (my_get_expression (& inst.reloc.exp, & str))
3263 return;
3264
3265#ifdef OBJ_ELF
3266 {
3267 char * save_in;
3268
3269 /* ScottB: February 5, 1998 */
3270 /* Check to see of PLT32 reloc required for the instruction. */
3271
3272 /* arm_parse_reloc() works on input_line_pointer.
3273 We actually want to parse the operands to the branch instruction
3274 passed in 'str'. Save the input pointer and restore it later. */
3275 save_in = input_line_pointer;
3276 input_line_pointer = str;
3277
3278 if (inst.reloc.exp.X_op == O_symbol
3279 && *str == '('
3280 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
3281 {
3282 inst.reloc.type = BFD_RELOC_ARM_PLT32;
3283 inst.reloc.pc_rel = 0;
3284 /* Modify str to point to after parsed operands, otherwise
3285 end_of_line() will complain about the (PLT) left in str. */
3286 str = input_line_pointer;
3287 }
3288 else
3289 {
3290 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
3291 inst.reloc.pc_rel = 1;
3292 }
3293
3294 input_line_pointer = save_in;
3295 }
3296#else
3297 inst.reloc.type = BFD_RELOC_ARM_PCREL_BLX;
3298 inst.reloc.pc_rel = 1;
3299#endif /* OBJ_ELF */
3300
3301 end_of_line (str);
3302}
3303
3304/* ARM V5 branch-link-exchange instruction (argument parse)
3305 BLX <target_addr> ie BLX(1)
3306 BLX{<condition>} <Rm> ie BLX(2)
3307 Unfortunately, there are two different opcodes for this mnemonic.
3308 So, the insns[].value is not used, and the code here zaps values
3309 into inst.instruction.
3310 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
3311
3312static void
3313do_blx (str, flags)
3314 char * str;
3315 unsigned long flags;
3316{
3317 char * mystr = str;
3318 int rm;
3319
3320 if (flags)
3321 {
3322 as_bad (BAD_FLAGS);
3323 return;
3324 }
3325
3326 skip_whitespace (mystr);
3327 rm = reg_required_here (& mystr, 0);
3328
3329 /* The above may set inst.error. Ignore his opinion. */
3330 inst.error = 0;
3331
3332 if (rm != FAIL)
3333 {
3334 /* Arg is a register.
3335 Use the condition code our caller put in inst.instruction.
3336 Pass ourselves off as a BX with a funny opcode. */
3337 inst.instruction |= 0x012fff30;
3338 do_bx (str, flags);
3339 }
3340 else
3341 {
3342 /* This must be is BLX <target address>, no condition allowed. */
3343 if (inst.instruction != COND_ALWAYS)
3344 {
3345 inst.error = BAD_COND;
3346 return;
3347 }
3348
3349 inst.instruction = 0xfafffffe;
3350
3351 /* Process like a B/BL, but with a different reloc.
3352 Note that B/BL expecte fffffe, not 0, offset in the opcode table. */
3353 do_branch25 (str, flags);
3354 }
3355}
3356
3357/* ARM V5 Thumb BLX (argument parse)
3358 BLX <target_addr> which is BLX(1)
3359 BLX <Rm> which is BLX(2)
3360 Unfortunately, there are two different opcodes for this mnemonic.
3361 So, the tinsns[].value is not used, and the code here zaps values
3362 into inst.instruction. */
3363
3364static void
3365do_t_blx (str)
3366 char * str;
3367{
3368 char * mystr = str;
3369 int rm;
3370
3371 skip_whitespace (mystr);
3372 inst.instruction = 0x4780;
3373
3374 /* Note that this call is to the ARM register recognizer. BLX(2)
3375 uses the ARM register space, not the Thumb one, so a call to
3376 thumb_reg() would be wrong. */
3377 rm = reg_required_here (& mystr, 3);
3378 inst.error = 0;
3379
3380 if (rm != FAIL)
3381 {
3382 /* It's BLX(2). The .instruction was zapped with rm & is final. */
3383 inst.size = 2;
3384 }
3385 else
3386 {
3387 /* No ARM register. This must be BLX(1). Change the .instruction. */
3388 inst.instruction = 0xf7ffeffe;
3389 inst.size = 4;
3390
3391 if (my_get_expression (& inst.reloc.exp, & mystr))
3392 return;
3393
3394 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
3395 inst.reloc.pc_rel = 1;
3396 }
3397
3398 end_of_line (mystr);
3399}
3400
3401/* ARM V5 breakpoint instruction (argument parse)
3402 BKPT <16 bit unsigned immediate>
3403 Instruction is not conditional.
3404 The bit pattern given in insns[] has the COND_ALWAYS condition,
3405 and it is an error if the caller tried to override that.
3406 Note "flags" is nonzero if a flag was supplied (which is an error). */
3407
3408static void
3409do_bkpt (str, flags)
3410 char * str;
3411 unsigned long flags;
3412{
3413 expressionS expr;
3414 unsigned long number;
3415
3416 skip_whitespace (str);
3417
3418 /* Allow optional leading '#'. */
3419 if (is_immediate_prefix (* str))
3420 str++;
3421
3422 memset (& expr, '\0', sizeof (expr));
3423
3424 if (my_get_expression (& expr, & str) || (expr.X_op != O_constant))
3425 {
3426 inst.error = _("bad or missing expression");
3427 return;
3428 }
3429
3430 number = expr.X_add_number;
3431
3432 /* Check it fits a 16 bit unsigned. */
3433 if (number != (number & 0xffff))
3434 {
3435 inst.error = _("immediate value out of range");
3436 return;
3437 }
3438
3439 /* Top 12 of 16 bits to bits 19:8. */
3440 inst.instruction |= (number & 0xfff0) << 4;
3441
3442 /* Bottom 4 of 16 bits to bits 3:0. */
3443 inst.instruction |= number & 0xf;
3444
3445 end_of_line (str);
3446
3447 if (flags)
3448 inst.error = BAD_FLAGS;
3449}
3450
3451/* Xscale multiply-accumulate (argument parse)
3452 MIAcc acc0,Rm,Rs
3453 MIAPHcc acc0,Rm,Rs
3454 MIAxycc acc0,Rm,Rs. */
3455
3456static void
3457do_mia (str, flags)
3458 char * str;
3459 unsigned long flags;
3460{
3461 int rs;
3462 int rm;
3463
3464 if (flags)
3465 as_bad (BAD_FLAGS);
3466
3467 else if (accum0_required_here (& str) == FAIL)
3468 inst.error = ERR_NO_ACCUM;
3469
3470 else if (skip_past_comma (& str) == FAIL
3471 || (rm = reg_required_here (& str, 0)) == FAIL)
3472 inst.error = BAD_ARGS;
3473
3474 else if (skip_past_comma (& str) == FAIL
3475 || (rs = reg_required_here (& str, 12)) == FAIL)
3476 inst.error = BAD_ARGS;
3477
3478 /* inst.instruction has now been zapped with both rm and rs. */
3479 else if (rm == REG_PC || rs == REG_PC)
3480 inst.error = BAD_PC; /* Undefined result if rm or rs is R15. */
3481
3482 else
3483 end_of_line (str);
3484}
3485
3486/* Xscale move-accumulator-register (argument parse)
3487
3488 MARcc acc0,RdLo,RdHi. */
3489
3490static void
3491do_mar (str, flags)
3492 char * str;
3493 unsigned long flags;
3494{
3495 int rdlo, rdhi;
3496
3497 if (flags)
3498 as_bad (BAD_FLAGS);
3499
3500 else if (accum0_required_here (& str) == FAIL)
3501 inst.error = ERR_NO_ACCUM;
3502
3503 else if (skip_past_comma (& str) == FAIL
3504 || (rdlo = reg_required_here (& str, 12)) == FAIL)
3505 inst.error = BAD_ARGS;
3506
3507 else if (skip_past_comma (& str) == FAIL
3508 || (rdhi = reg_required_here (& str, 16)) == FAIL)
3509 inst.error = BAD_ARGS;
3510
3511 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3512 else if (rdlo == REG_PC || rdhi == REG_PC)
3513 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
3514
3515 else
3516 end_of_line (str);
3517}
3518
3519/* Xscale move-register-accumulator (argument parse)
3520
3521 MRAcc RdLo,RdHi,acc0. */
3522
3523static void
3524do_mra (str, flags)
3525 char * str;
3526 unsigned long flags;
3527{
3528 int rdlo;
3529 int rdhi;
3530
3531 if (flags)
3532 {
3533 as_bad (BAD_FLAGS);
3534 return;
3535 }
3536
3537 skip_whitespace (str);
3538
3539 if ((rdlo = reg_required_here (& str, 12)) == FAIL)
3540 inst.error = BAD_ARGS;
3541
3542 else if (skip_past_comma (& str) == FAIL
3543 || (rdhi = reg_required_here (& str, 16)) == FAIL)
3544 inst.error = BAD_ARGS;
3545
3546 else if (skip_past_comma (& str) == FAIL
3547 || accum0_required_here (& str) == FAIL)
3548 inst.error = ERR_NO_ACCUM;
3549
3550 /* inst.instruction has now been zapped with both rdlo and rdhi. */
3551 else if (rdlo == rdhi)
3552 inst.error = BAD_ARGS; /* Undefined result if 2 writes to same reg. */
3553
3554 else if (rdlo == REG_PC || rdhi == REG_PC)
3555 inst.error = BAD_PC; /* Undefined result if rdlo or rdhi is R15. */
3556 else
3557 end_of_line (str);
3558}
3559
3560/* Xscale: Preload-Cache
3561
3562 PLD <addr_mode>
3563
3564 Syntactically, like LDR with B=1, W=0, L=1. */
3565
3566static void
3567do_pld (str, flags)
3568 char * str;
3569 unsigned long flags;
3570{
3571 int rd;
3572
3573 if (flags)
3574 {
3575 as_bad (BAD_FLAGS);
3576 return;
3577 }
3578
3579 skip_whitespace (str);
3580
3581 if (* str != '[')
3582 {
3583 inst.error = _("'[' expected after PLD mnemonic");
3584 return;
3585 }
3586
3587 ++ str;
3588 skip_whitespace (str);
3589
3590 if ((rd = reg_required_here (& str, 16)) == FAIL)
3591 return;
3592
3593 skip_whitespace (str);
3594
3595 if (* str == ']')
3596 {
3597 /* [Rn], ... ? */
3598 ++ str;
3599 skip_whitespace (str);
3600
3601 if (skip_past_comma (& str) == SUCCESS)
3602 {
3603 if (ldst_extend (& str, 0) == FAIL)
3604 return;
3605 }
3606 else if (* str == '!') /* [Rn]! */
3607 {
3608 inst.error = _("writeback used in preload instruction");
3609 ++ str;
3610 }
3611 else /* [Rn] */
3612 inst.instruction |= INDEX_UP | PRE_INDEX;
3613 }
3614 else /* [Rn, ...] */
3615 {
3616 if (skip_past_comma (& str) == FAIL)
3617 {
3618 inst.error = _("pre-indexed expression expected");
3619 return;
3620 }
3621
3622 if (ldst_extend (& str, 0) == FAIL)
3623 return;
3624
3625 skip_whitespace (str);
3626
3627 if (* str != ']')
3628 {
3629 inst.error = _("missing ]");
3630 return;
3631 }
3632
3633 ++ str;
3634 skip_whitespace (str);
3635
3636 if (* str == '!') /* [Rn]! */
3637 {
3638 inst.error = _("writeback used in preload instruction");
3639 ++ str;
3640 }
3641
3642 inst.instruction |= PRE_INDEX;
3643 }
3644
3645 end_of_line (str);
3646}
3647
3648/* Xscale load-consecutive (argument parse)
3649 Mode is like LDRH.
3650
3651 LDRccD R, mode
3652 STRccD R, mode. */
3653
3654static void
3655do_ldrd (str, flags)
3656 char * str;
3657 unsigned long flags;
3658{
3659 int rd;
3660 int rn;
3661
3662 if (flags != DOUBLE_LOAD_FLAG)
3663 {
3664 /* Change instruction pattern to normal ldr/str. */
3665 if (inst.instruction & 0x20)
3666 inst.instruction = (inst.instruction & COND_MASK) | 0x04000000; /* str */
3667 else
3668 inst.instruction = (inst.instruction & COND_MASK) | 0x04100000; /* ldr */
3669
3670 /* Perform a normal load/store instruction parse. */
3671 do_ldst (str, flags);
3672
3673 return;
3674 }
3675
3676 if ((cpu_variant & ARM_EXT_XSCALE) != ARM_EXT_XSCALE)
3677 {
3678 static char buff[128];
3679
3680 --str;
3882b010 3681 while (ISSPACE (*str))
b99bd4ef
NC
3682 --str;
3683 str -= 4;
3684
3685 /* Deny all knowledge. */
3686 sprintf (buff, _("bad instruction '%.100s'"), str);
3687 inst.error = buff;
3688 return;
3689 }
3690
3691 skip_whitespace (str);
3692
3693 if ((rd = reg_required_here (& str, 12)) == FAIL)
3694 {
3695 inst.error = BAD_ARGS;
3696 return;
3697 }
3698
3699 if (skip_past_comma (& str) == FAIL
3700 || (rn = ld_mode_required_here (& str)) == FAIL)
3701 {
3702 if (!inst.error)
3703 inst.error = BAD_ARGS;
3704 return;
3705 }
3706
3707 /* inst.instruction has now been zapped with Rd and the addressing mode. */
3708 if (rd & 1) /* Unpredictable result if Rd is odd. */
3709 {
3710 inst.error = _("Destination register must be even");
3711 return;
3712 }
3713
3714 if (rd == REG_LR || rd == 12)
3715 {
3716 inst.error = _("r12 or r14 not allowed here");
3717 return;
3718 }
3719
3720 if (((rd == rn) || (rd + 1 == rn))
3721 &&
3722 ((inst.instruction & WRITE_BACK)
3723 || (!(inst.instruction & PRE_INDEX))))
3724 as_warn (_("pre/post-indexing used when modified address register is destination"));
3725
3726 end_of_line (str);
3727}
3728
3729/* Returns the index into fp_values of a floating point number,
3730 or -1 if not in the table. */
3731
3732static int
3733my_get_float_expression (str)
3734 char ** str;
3735{
3736 LITTLENUM_TYPE words[MAX_LITTLENUMS];
3737 char * save_in;
3738 expressionS exp;
3739 int i;
3740 int j;
3741
3742 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
3743
3744 /* Look for a raw floating point number. */
3745 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
3746 && is_end_of_line[(unsigned char) *save_in])
3747 {
3748 for (i = 0; i < NUM_FLOAT_VALS; i++)
3749 {
3750 for (j = 0; j < MAX_LITTLENUMS; j++)
3751 {
3752 if (words[j] != fp_values[i][j])
3753 break;
3754 }
3755
3756 if (j == MAX_LITTLENUMS)
3757 {
3758 *str = save_in;
3759 return i;
3760 }
3761 }
3762 }
3763
3764 /* Try and parse a more complex expression, this will probably fail
3765 unless the code uses a floating point prefix (eg "0f"). */
3766 save_in = input_line_pointer;
3767 input_line_pointer = *str;
3768 if (expression (&exp) == absolute_section
3769 && exp.X_op == O_big
3770 && exp.X_add_number < 0)
3771 {
3772 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
3773 Ditto for 15. */
3774 if (gen_to_words (words, 5, (long) 15) == 0)
3775 {
3776 for (i = 0; i < NUM_FLOAT_VALS; i++)
3777 {
3778 for (j = 0; j < MAX_LITTLENUMS; j++)
3779 {
3780 if (words[j] != fp_values[i][j])
3781 break;
3782 }
3783
3784 if (j == MAX_LITTLENUMS)
3785 {
3786 *str = input_line_pointer;
3787 input_line_pointer = save_in;
3788 return i;
3789 }
3790 }
3791 }
3792 }
3793
3794 *str = input_line_pointer;
3795 input_line_pointer = save_in;
3796 return -1;
3797}
3798
3799/* Return true if anything in the expression is a bignum. */
3800
3801static int
3802walk_no_bignums (sp)
3803 symbolS * sp;
3804{
3805 if (symbol_get_value_expression (sp)->X_op == O_big)
3806 return 1;
3807
3808 if (symbol_get_value_expression (sp)->X_add_symbol)
3809 {
3810 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
3811 || (symbol_get_value_expression (sp)->X_op_symbol
3812 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
3813 }
3814
3815 return 0;
3816}
3817
3818static int
3819my_get_expression (ep, str)
3820 expressionS * ep;
3821 char ** str;
3822{
3823 char * save_in;
3824 segT seg;
3825
3826 save_in = input_line_pointer;
3827 input_line_pointer = *str;
3828 seg = expression (ep);
3829
3830#ifdef OBJ_AOUT
3831 if (seg != absolute_section
3832 && seg != text_section
3833 && seg != data_section
3834 && seg != bss_section
3835 && seg != undefined_section)
3836 {
3837 inst.error = _("bad_segment");
3838 *str = input_line_pointer;
3839 input_line_pointer = save_in;
3840 return 1;
3841 }
3842#endif
3843
3844 /* Get rid of any bignums now, so that we don't generate an error for which
3845 we can't establish a line number later on. Big numbers are never valid
3846 in instructions, which is where this routine is always called. */
3847 if (ep->X_op == O_big
3848 || (ep->X_add_symbol
3849 && (walk_no_bignums (ep->X_add_symbol)
3850 || (ep->X_op_symbol
3851 && walk_no_bignums (ep->X_op_symbol)))))
3852 {
3853 inst.error = _("Invalid constant");
3854 *str = input_line_pointer;
3855 input_line_pointer = save_in;
3856 return 1;
3857 }
3858
3859 *str = input_line_pointer;
3860 input_line_pointer = save_in;
3861 return 0;
3862}
3863
3864/* UNRESTRICT should be one if <shift> <register> is permitted for this
3865 instruction. */
3866
3867static int
3868decode_shift (str, unrestrict)
3869 char ** str;
3870 int unrestrict;
3871{
3872 const struct asm_shift_name * shift;
3873 char * p;
3874 char c;
3875
3876 skip_whitespace (* str);
3877
3882b010 3878 for (p = * str; ISALPHA (* p); p ++)
b99bd4ef
NC
3879 ;
3880
3881 if (p == * str)
3882 {
3883 inst.error = _("Shift expression expected");
3884 return FAIL;
3885 }
3886
3887 c = * p;
3888 * p = '\0';
3889 shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
3890 * p = c;
3891
3892 if (shift == NULL)
3893 {
3894 inst.error = _("Shift expression expected");
3895 return FAIL;
3896 }
3897
3898 assert (shift->properties->index == shift_properties[shift->properties->index].index);
3899
3900 if (shift->properties->index == SHIFT_RRX)
3901 {
3902 * str = p;
3903 inst.instruction |= shift->properties->bit_field;
3904 return SUCCESS;
3905 }
3906
3907 skip_whitespace (p);
3908
3909 if (unrestrict && reg_required_here (& p, 8) != FAIL)
3910 {
3911 inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
3912 * str = p;
3913 return SUCCESS;
3914 }
3915 else if (! is_immediate_prefix (* p))
3916 {
3917 inst.error = (unrestrict
3918 ? _("shift requires register or #expression")
3919 : _("shift requires #expression"));
3920 * str = p;
3921 return FAIL;
3922 }
3923
3924 inst.error = NULL;
3925 p ++;
3926
3927 if (my_get_expression (& inst.reloc.exp, & p))
3928 return FAIL;
3929
3930 /* Validate some simple #expressions. */
3931 if (inst.reloc.exp.X_op == O_constant)
3932 {
3933 unsigned num = inst.reloc.exp.X_add_number;
3934
3935 /* Reject operations greater than 32. */
3936 if (num > 32
3937 /* Reject a shift of 0 unless the mode allows it. */
3938 || (num == 0 && shift->properties->allows_0 == 0)
3939 /* Reject a shift of 32 unless the mode allows it. */
3940 || (num == 32 && shift->properties->allows_32 == 0)
3941 )
3942 {
3943 /* As a special case we allow a shift of zero for
3944 modes that do not support it to be recoded as an
3945 logical shift left of zero (ie nothing). We warn
3946 about this though. */
3947 if (num == 0)
3948 {
3949 as_warn (_("Shift of 0 ignored."));
3950 shift = & shift_names[0];
3951 assert (shift->properties->index == SHIFT_LSL);
3952 }
3953 else
3954 {
3955 inst.error = _("Invalid immediate shift");
3956 return FAIL;
3957 }
3958 }
3959
3960 /* Shifts of 32 are encoded as 0, for those shifts that
3961 support it. */
3962 if (num == 32)
3963 num = 0;
3964
3965 inst.instruction |= (num << 7) | shift->properties->bit_field;
3966 }
3967 else
3968 {
3969 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
3970 inst.reloc.pc_rel = 0;
3971 inst.instruction |= shift->properties->bit_field;
3972 }
3973
3974 * str = p;
3975 return SUCCESS;
3976}
3977
3978/* Do those data_ops which can take a negative immediate constant
3979 by altering the instuction. A bit of a hack really.
3980 MOV <-> MVN
3981 AND <-> BIC
3982 ADC <-> SBC
3983 by inverting the second operand, and
3984 ADD <-> SUB
3985 CMP <-> CMN
3986 by negating the second operand. */
3987
3988static int
3989negate_data_op (instruction, value)
3990 unsigned long * instruction;
3991 unsigned long value;
3992{
3993 int op, new_inst;
3994 unsigned long negated, inverted;
3995
3996 negated = validate_immediate (-value);
3997 inverted = validate_immediate (~value);
3998
3999 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
4000 switch (op)
4001 {
4002 /* First negates. */
4003 case OPCODE_SUB: /* ADD <-> SUB */
4004 new_inst = OPCODE_ADD;
4005 value = negated;
4006 break;
4007
4008 case OPCODE_ADD:
4009 new_inst = OPCODE_SUB;
4010 value = negated;
4011 break;
4012
4013 case OPCODE_CMP: /* CMP <-> CMN */
4014 new_inst = OPCODE_CMN;
4015 value = negated;
4016 break;
4017
4018 case OPCODE_CMN:
4019 new_inst = OPCODE_CMP;
4020 value = negated;
4021 break;
4022
4023 /* Now Inverted ops. */
4024 case OPCODE_MOV: /* MOV <-> MVN */
4025 new_inst = OPCODE_MVN;
4026 value = inverted;
4027 break;
4028
4029 case OPCODE_MVN:
4030 new_inst = OPCODE_MOV;
4031 value = inverted;
4032 break;
4033
4034 case OPCODE_AND: /* AND <-> BIC */
4035 new_inst = OPCODE_BIC;
4036 value = inverted;
4037 break;
4038
4039 case OPCODE_BIC:
4040 new_inst = OPCODE_AND;
4041 value = inverted;
4042 break;
4043
4044 case OPCODE_ADC: /* ADC <-> SBC */
4045 new_inst = OPCODE_SBC;
4046 value = inverted;
4047 break;
4048
4049 case OPCODE_SBC:
4050 new_inst = OPCODE_ADC;
4051 value = inverted;
4052 break;
4053
4054 /* We cannot do anything. */
4055 default:
4056 return FAIL;
4057 }
4058
4059 if (value == (unsigned) FAIL)
4060 return FAIL;
4061
4062 *instruction &= OPCODE_MASK;
4063 *instruction |= new_inst << DATA_OP_SHIFT;
4064 return value;
4065}
4066
4067static int
4068data_op2 (str)
4069 char ** str;
4070{
4071 int value;
4072 expressionS expr;
4073
4074 skip_whitespace (* str);
4075
4076 if (reg_required_here (str, 0) != FAIL)
4077 {
4078 if (skip_past_comma (str) == SUCCESS)
4079 /* Shift operation on register. */
4080 return decode_shift (str, NO_SHIFT_RESTRICT);
4081
4082 return SUCCESS;
4083 }
4084 else
4085 {
4086 /* Immediate expression. */
4087 if (is_immediate_prefix (**str))
4088 {
4089 (*str)++;
4090 inst.error = NULL;
4091
4092 if (my_get_expression (&inst.reloc.exp, str))
4093 return FAIL;
4094
4095 if (inst.reloc.exp.X_add_symbol)
4096 {
4097 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4098 inst.reloc.pc_rel = 0;
4099 }
4100 else
4101 {
4102 if (skip_past_comma (str) == SUCCESS)
4103 {
4104 /* #x, y -- ie explicit rotation by Y. */
4105 if (my_get_expression (&expr, str))
4106 return FAIL;
4107
4108 if (expr.X_op != O_constant)
4109 {
4110 inst.error = _("Constant expression expected");
4111 return FAIL;
4112 }
4113
4114 /* Rotate must be a multiple of 2. */
4115 if (((unsigned) expr.X_add_number) > 30
4116 || (expr.X_add_number & 1) != 0
4117 || ((unsigned) inst.reloc.exp.X_add_number) > 255)
4118 {
4119 inst.error = _("Invalid constant");
4120 return FAIL;
4121 }
4122 inst.instruction |= INST_IMMEDIATE;
4123 inst.instruction |= inst.reloc.exp.X_add_number;
4124 inst.instruction |= expr.X_add_number << 7;
4125 return SUCCESS;
4126 }
4127
4128 /* Implicit rotation, select a suitable one. */
4129 value = validate_immediate (inst.reloc.exp.X_add_number);
4130
4131 if (value == FAIL)
4132 {
4133 /* Can't be done. Perhaps the code reads something like
4134 "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK. */
4135 if ((value = negate_data_op (&inst.instruction,
4136 inst.reloc.exp.X_add_number))
4137 == FAIL)
4138 {
4139 inst.error = _("Invalid constant");
4140 return FAIL;
4141 }
4142 }
4143
4144 inst.instruction |= value;
4145 }
4146
4147 inst.instruction |= INST_IMMEDIATE;
4148 return SUCCESS;
4149 }
4150
4151 (*str)++;
4152 inst.error = _("Register or shift expression expected");
4153 return FAIL;
4154 }
4155}
4156
4157static int
4158fp_op2 (str)
4159 char ** str;
4160{
4161 skip_whitespace (* str);
4162
4163 if (fp_reg_required_here (str, 0) != FAIL)
4164 return SUCCESS;
4165 else
4166 {
4167 /* Immediate expression. */
4168 if (*((*str)++) == '#')
4169 {
4170 int i;
4171
4172 inst.error = NULL;
4173
4174 skip_whitespace (* str);
4175
4176 /* First try and match exact strings, this is to guarantee
4177 that some formats will work even for cross assembly. */
4178
4179 for (i = 0; fp_const[i]; i++)
4180 {
4181 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
4182 {
4183 char *start = *str;
4184
4185 *str += strlen (fp_const[i]);
4186 if (is_end_of_line[(unsigned char) **str])
4187 {
4188 inst.instruction |= i + 8;
4189 return SUCCESS;
4190 }
4191 *str = start;
4192 }
4193 }
4194
4195 /* Just because we didn't get a match doesn't mean that the
4196 constant isn't valid, just that it is in a format that we
4197 don't automatically recognize. Try parsing it with
4198 the standard expression routines. */
4199 if ((i = my_get_float_expression (str)) >= 0)
4200 {
4201 inst.instruction |= i + 8;
4202 return SUCCESS;
4203 }
4204
4205 inst.error = _("Invalid floating point immediate expression");
4206 return FAIL;
4207 }
4208 inst.error =
4209 _("Floating point register or immediate expression expected");
4210 return FAIL;
4211 }
4212}
4213
4214static void
4215do_arit (str, flags)
4216 char * str;
4217 unsigned long flags;
4218{
4219 skip_whitespace (str);
4220
4221 if (reg_required_here (&str, 12) == FAIL
4222 || skip_past_comma (&str) == FAIL
4223 || reg_required_here (&str, 16) == FAIL
4224 || skip_past_comma (&str) == FAIL
4225 || data_op2 (&str) == FAIL)
4226 {
4227 if (!inst.error)
4228 inst.error = BAD_ARGS;
4229 return;
4230 }
4231
4232 inst.instruction |= flags;
4233 end_of_line (str);
4234 return;
4235}
4236
4237static void
4238do_adr (str, flags)
4239 char * str;
4240 unsigned long flags;
4241{
b99bd4ef
NC
4242 skip_whitespace (str);
4243
4244 if (reg_required_here (&str, 12) == FAIL
4245 || skip_past_comma (&str) == FAIL
4246 || my_get_expression (&inst.reloc.exp, &str))
4247 {
4248 if (!inst.error)
4249 inst.error = BAD_ARGS;
4250 return;
4251 }
4252
1cac9012 4253 if (flags & 0x00400000)
b99bd4ef 4254 {
1cac9012
NC
4255 /* This is a pseudo-op of the form "adrl rd, label" to be converted
4256 into a relative address of the form:
4257 add rd, pc, #low(label-.-8)"
4258 add rd, rd, #high(label-.-8)" */
4259 /* Frag hacking will turn this into a sub instruction if the offset turns
4260 out to be negative. */
4261 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
4262 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust */
4263 inst.reloc.pc_rel = 1;
4264 inst.instruction |= flags & ~0x00400000;
4265 inst.size = INSN_SIZE * 2;
4266 }
4267 else
4268 {
4269 /* This is a pseudo-op of the form "adr rd, label" to be converted
4270 into a relative address of the form "add rd, pc, #label-.-8". */
4271 /* Frag hacking will turn this into a sub instruction if the offset turns
4272 out to be negative. */
4273 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
4274 inst.reloc.exp.X_add_number -= 8; /* PC relative adjust. */
4275 inst.reloc.pc_rel = 1;
4276 inst.instruction |= flags;
b99bd4ef
NC
4277 }
4278
4279 end_of_line (str);
b99bd4ef
NC
4280}
4281
4282static void
4283do_cmp (str, flags)
4284 char * str;
4285 unsigned long flags;
4286{
4287 skip_whitespace (str);
4288
4289 if (reg_required_here (&str, 16) == FAIL)
4290 {
4291 if (!inst.error)
4292 inst.error = BAD_ARGS;
4293 return;
4294 }
4295
4296 if (skip_past_comma (&str) == FAIL
4297 || data_op2 (&str) == FAIL)
4298 {
4299 if (!inst.error)
4300 inst.error = BAD_ARGS;
4301 return;
4302 }
4303
4304 inst.instruction |= flags;
4305 if ((flags & 0x0000f000) == 0)
4306 inst.instruction |= CONDS_BIT;
4307
4308 end_of_line (str);
4309 return;
4310}
4311
4312static void
4313do_mov (str, flags)
4314 char * str;
4315 unsigned long flags;
4316{
4317 skip_whitespace (str);
4318
4319 if (reg_required_here (&str, 12) == FAIL)
4320 {
4321 if (!inst.error)
4322 inst.error = BAD_ARGS;
4323 return;
4324 }
4325
4326 if (skip_past_comma (&str) == FAIL
4327 || data_op2 (&str) == FAIL)
4328 {
4329 if (!inst.error)
4330 inst.error = BAD_ARGS;
4331 return;
4332 }
4333
4334 inst.instruction |= flags;
4335 end_of_line (str);
4336 return;
4337}
4338
4339static int
4340ldst_extend (str, hwse)
4341 char ** str;
4342 int hwse;
4343{
4344 int add = INDEX_UP;
4345
4346 switch (**str)
4347 {
4348 case '#':
4349 case '$':
4350 (*str)++;
4351 if (my_get_expression (& inst.reloc.exp, str))
4352 return FAIL;
4353
4354 if (inst.reloc.exp.X_op == O_constant)
4355 {
4356 int value = inst.reloc.exp.X_add_number;
4357
4358 if ((hwse && (value < -255 || value > 255))
4359 || (value < -4095 || value > 4095))
4360 {
4361 inst.error = _("address offset too large");
4362 return FAIL;
4363 }
4364
4365 if (value < 0)
4366 {
4367 value = -value;
4368 add = 0;
4369 }
4370
4371 /* Halfword and signextension instructions have the
4372 immediate value split across bits 11..8 and bits 3..0. */
4373 if (hwse)
4374 inst.instruction |= (add | HWOFFSET_IMM
4375 | ((value >> 4) << 8) | (value & 0xF));
4376 else
4377 inst.instruction |= add | value;
4378 }
4379 else
4380 {
4381 if (hwse)
4382 {
4383 inst.instruction |= HWOFFSET_IMM;
4384 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
4385 }
4386 else
4387 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
4388 inst.reloc.pc_rel = 0;
4389 }
4390 return SUCCESS;
4391
4392 case '-':
4393 add = 0;
4394 /* Fall through. */
4395
4396 case '+':
4397 (*str)++;
4398 /* Fall through. */
4399
4400 default:
4401 if (reg_required_here (str, 0) == FAIL)
4402 return FAIL;
4403
4404 if (hwse)
4405 inst.instruction |= add;
4406 else
4407 {
4408 inst.instruction |= add | OFFSET_REG;
4409 if (skip_past_comma (str) == SUCCESS)
4410 return decode_shift (str, SHIFT_RESTRICT);
4411 }
4412
4413 return SUCCESS;
4414 }
4415}
4416
4417static void
4418do_ldst (str, flags)
4419 char * str;
4420 unsigned long flags;
4421{
4422 int halfword = 0;
4423 int pre_inc = 0;
4424 int conflict_reg;
4425 int value;
4426
4427 /* This is not ideal, but it is the simplest way of dealing with the
4428 ARM7T halfword instructions (since they use a different
4429 encoding, but the same mnemonic): */
4430 halfword = (flags & 0x80000000) != 0;
4431 if (halfword)
4432 {
4433 /* This is actually a load/store of a halfword, or a
4434 signed-extension load. */
4435 if ((cpu_variant & ARM_EXT_HALFWORD) == 0)
4436 {
4437 inst.error
4438 = _("Processor does not support halfwords or signed bytes");
4439 return;
4440 }
4441
4442 inst.instruction = ((inst.instruction & COND_MASK)
4443 | (flags & ~COND_MASK));
4444
4445 flags = 0;
4446 }
4447
4448 skip_whitespace (str);
4449
4450 if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
4451 {
4452 if (!inst.error)
4453 inst.error = BAD_ARGS;
4454 return;
4455 }
4456
4457 if (skip_past_comma (& str) == FAIL)
4458 {
4459 inst.error = _("Address expected");
4460 return;
4461 }
4462
4463 if (*str == '[')
4464 {
4465 int reg;
4466
4467 str++;
4468
4469 skip_whitespace (str);
4470
4471 if ((reg = reg_required_here (&str, 16)) == FAIL)
4472 return;
4473
4474 /* Conflicts can occur on stores as well as loads. */
4475 conflict_reg = (conflict_reg == reg);
4476
4477 skip_whitespace (str);
4478
4479 if (*str == ']')
4480 {
4481 str ++;
4482
4483 if (skip_past_comma (&str) == SUCCESS)
4484 {
4485 /* [Rn],... (post inc) */
4486 if (ldst_extend (&str, halfword) == FAIL)
4487 return;
4488 if (conflict_reg)
4489 {
4490 if (flags & TRANS_BIT)
4491 as_warn (_("Rn and Rd must be different in %s"),
4492 ((inst.instruction & LOAD_BIT)
4493 ? "LDRT" : "STRT"));
4494 else
4495 as_warn (_("%s register same as write-back base"),
4496 ((inst.instruction & LOAD_BIT)
4497 ? _("destination") : _("source")));
4498 }
4499 }
4500 else
4501 {
4502 /* [Rn] */
4503 if (halfword)
4504 inst.instruction |= HWOFFSET_IMM;
4505
4506 skip_whitespace (str);
4507
4508 if (*str == '!')
4509 {
4510 if (conflict_reg)
4511 as_warn (_("%s register same as write-back base"),
4512 ((inst.instruction & LOAD_BIT)
4513 ? _("destination") : _("source")));
4514 str++;
4515 inst.instruction |= WRITE_BACK;
4516 }
4517
4518 flags |= INDEX_UP;
4519 if (flags & TRANS_BIT)
4520 {
4521 if (conflict_reg)
4522 as_warn (_("Rn and Rd must be different in %s"),
4523 ((inst.instruction & LOAD_BIT)
4524 ? "LDRT" : "STRT"));
4525 }
4526 else
4527 pre_inc = 1;
4528 }
4529 }
4530 else
4531 {
4532 /* [Rn,...] */
4533 if (skip_past_comma (&str) == FAIL)
4534 {
4535 inst.error = _("pre-indexed expression expected");
4536 return;
4537 }
4538
4539 pre_inc = 1;
4540 if (ldst_extend (&str, halfword) == FAIL)
4541 return;
4542
4543 skip_whitespace (str);
4544
4545 if (*str++ != ']')
4546 {
4547 inst.error = _("missing ]");
4548 return;
4549 }
4550
4551 skip_whitespace (str);
4552
4553 if (*str == '!')
4554 {
4555 if (conflict_reg)
4556 as_warn (_("%s register same as write-back base"),
4557 ((inst.instruction & LOAD_BIT)
4558 ? _("destination") : _("source")));
4559 str++;
4560 inst.instruction |= WRITE_BACK;
4561 }
4562 }
4563 }
4564 else if (*str == '=')
4565 {
4566 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
4567 str++;
4568
4569 skip_whitespace (str);
4570
4571 if (my_get_expression (&inst.reloc.exp, &str))
4572 return;
4573
4574 if (inst.reloc.exp.X_op != O_constant
4575 && inst.reloc.exp.X_op != O_symbol)
4576 {
4577 inst.error = _("Constant expression expected");
4578 return;
4579 }
4580
d8273442 4581 if (inst.reloc.exp.X_op == O_constant)
b99bd4ef 4582 {
d8273442
NC
4583 value = validate_immediate (inst.reloc.exp.X_add_number);
4584
4585 if (value != FAIL)
b99bd4ef 4586 {
d8273442
NC
4587 /* This can be done with a mov instruction. */
4588 inst.instruction &= LITERAL_MASK;
4589 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
4590 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
4591 end_of_line (str);
b99bd4ef
NC
4592 return;
4593 }
d8273442
NC
4594
4595 value = validate_immediate (~ inst.reloc.exp.X_add_number);
b99bd4ef 4596
d8273442 4597 if (value != FAIL)
b99bd4ef 4598 {
d8273442
NC
4599 /* This can be done with a mvn instruction. */
4600 inst.instruction &= LITERAL_MASK;
4601 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
4602 inst.instruction |= (flags & COND_MASK) | (value & 0xfff);
4603 end_of_line (str);
4604 return;
b99bd4ef 4605 }
b99bd4ef 4606 }
d8273442
NC
4607
4608 /* Insert into literal pool. */
4609 if (add_to_lit_pool () == FAIL)
4610 {
4611 if (!inst.error)
4612 inst.error = _("literal pool insertion failed");
4613 return;
4614 }
4615
4616 /* Change the instruction exp to point to the pool. */
4617 if (halfword)
4618 {
4619 inst.instruction |= HWOFFSET_IMM;
4620 inst.reloc.type = BFD_RELOC_ARM_HWLITERAL;
4621 }
4622 else
4623 inst.reloc.type = BFD_RELOC_ARM_LITERAL;
4624
4625 inst.reloc.pc_rel = 1;
4626 inst.instruction |= (REG_PC << 16);
4627 pre_inc = 1;
b99bd4ef
NC
4628 }
4629 else
4630 {
4631 if (my_get_expression (&inst.reloc.exp, &str))
4632 return;
4633
4634 if (halfword)
4635 {
4636 inst.instruction |= HWOFFSET_IMM;
4637 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
4638 }
4639 else
4640 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
4641#ifndef TE_WINCE
4642 /* PC rel adjust. */
4643 inst.reloc.exp.X_add_number -= 8;
4644#endif
4645 inst.reloc.pc_rel = 1;
4646 inst.instruction |= (REG_PC << 16);
4647 pre_inc = 1;
4648 }
4649
4650 if (pre_inc && (flags & TRANS_BIT))
4651 inst.error = _("Pre-increment instruction with translate");
4652
4653 inst.instruction |= flags | (pre_inc ? PRE_INDEX : 0);
4654 end_of_line (str);
4655 return;
4656}
4657
4658static long
4659reg_list (strp)
4660 char ** strp;
4661{
4662 char * str = * strp;
4663 long range = 0;
4664 int another_range;
4665
4666 /* We come back here if we get ranges concatenated by '+' or '|'. */
4667 do
4668 {
4669 another_range = 0;
4670
4671 if (*str == '{')
4672 {
4673 int in_range = 0;
4674 int cur_reg = -1;
4675
4676 str++;
4677 do
4678 {
4679 int reg;
4680
4681 skip_whitespace (str);
4682
4683 if ((reg = reg_required_here (& str, -1)) == FAIL)
4684 return FAIL;
4685
4686 if (in_range)
4687 {
4688 int i;
4689
4690 if (reg <= cur_reg)
4691 {
4692 inst.error = _("Bad range in register list");
4693 return FAIL;
4694 }
4695
4696 for (i = cur_reg + 1; i < reg; i++)
4697 {
4698 if (range & (1 << i))
4699 as_tsktsk
4700 (_("Warning: Duplicated register (r%d) in register list"),
4701 i);
4702 else
4703 range |= 1 << i;
4704 }
4705 in_range = 0;
4706 }
4707
4708 if (range & (1 << reg))
4709 as_tsktsk (_("Warning: Duplicated register (r%d) in register list"),
4710 reg);
4711 else if (reg <= cur_reg)
4712 as_tsktsk (_("Warning: Register range not in ascending order"));
4713
4714 range |= 1 << reg;
4715 cur_reg = reg;
4716 }
4717 while (skip_past_comma (&str) != FAIL
4718 || (in_range = 1, *str++ == '-'));
4719 str--;
4720 skip_whitespace (str);
4721
4722 if (*str++ != '}')
4723 {
4724 inst.error = _("Missing `}'");
4725 return FAIL;
4726 }
4727 }
4728 else
4729 {
4730 expressionS expr;
4731
4732 if (my_get_expression (&expr, &str))
4733 return FAIL;
4734
4735 if (expr.X_op == O_constant)
4736 {
4737 if (expr.X_add_number
4738 != (expr.X_add_number & 0x0000ffff))
4739 {
4740 inst.error = _("invalid register mask");
4741 return FAIL;
4742 }
4743
4744 if ((range & expr.X_add_number) != 0)
4745 {
4746 int regno = range & expr.X_add_number;
4747
4748 regno &= -regno;
4749 regno = (1 << regno) - 1;
4750 as_tsktsk
4751 (_("Warning: Duplicated register (r%d) in register list"),
4752 regno);
4753 }
4754
4755 range |= expr.X_add_number;
4756 }
4757 else
4758 {
4759 if (inst.reloc.type != 0)
4760 {
4761 inst.error = _("expression too complex");
4762 return FAIL;
4763 }
4764
4765 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
4766 inst.reloc.type = BFD_RELOC_ARM_MULTI;
4767 inst.reloc.pc_rel = 0;
4768 }
4769 }
4770
4771 skip_whitespace (str);
4772
4773 if (*str == '|' || *str == '+')
4774 {
4775 str++;
4776 another_range = 1;
4777 }
4778 }
4779 while (another_range);
4780
4781 *strp = str;
4782 return range;
4783}
4784
4785static void
4786do_ldmstm (str, flags)
4787 char * str;
4788 unsigned long flags;
4789{
4790 int base_reg;
4791 long range;
4792
4793 skip_whitespace (str);
4794
4795 if ((base_reg = reg_required_here (&str, 16)) == FAIL)
4796 return;
4797
4798 if (base_reg == REG_PC)
4799 {
4800 inst.error = _("r15 not allowed as base register");
4801 return;
4802 }
4803
4804 skip_whitespace (str);
4805
4806 if (*str == '!')
4807 {
4808 flags |= WRITE_BACK;
4809 str++;
4810 }
4811
4812 if (skip_past_comma (&str) == FAIL
4813 || (range = reg_list (&str)) == FAIL)
4814 {
4815 if (! inst.error)
4816 inst.error = BAD_ARGS;
4817 return;
4818 }
4819
4820 if (*str == '^')
4821 {
4822 str++;
4823 flags |= LDM_TYPE_2_OR_3;
4824 }
4825
4826 inst.instruction |= flags | range;
4827 end_of_line (str);
4828 return;
4829}
4830
4831static void
4832do_swi (str, flags)
4833 char * str;
4834 unsigned long flags;
4835{
4836 skip_whitespace (str);
4837
4838 /* Allow optional leading '#'. */
4839 if (is_immediate_prefix (*str))
4840 str++;
4841
4842 if (my_get_expression (& inst.reloc.exp, & str))
4843 return;
4844
4845 inst.reloc.type = BFD_RELOC_ARM_SWI;
4846 inst.reloc.pc_rel = 0;
4847 inst.instruction |= flags;
4848
4849 end_of_line (str);
4850
4851 return;
4852}
4853
4854static void
4855do_swap (str, flags)
4856 char * str;
4857 unsigned long flags;
4858{
4859 int reg;
4860
4861 skip_whitespace (str);
4862
4863 if ((reg = reg_required_here (&str, 12)) == FAIL)
4864 return;
4865
4866 if (reg == REG_PC)
4867 {
4868 inst.error = _("r15 not allowed in swap");
4869 return;
4870 }
4871
4872 if (skip_past_comma (&str) == FAIL
4873 || (reg = reg_required_here (&str, 0)) == FAIL)
4874 {
4875 if (!inst.error)
4876 inst.error = BAD_ARGS;
4877 return;
4878 }
4879
4880 if (reg == REG_PC)
4881 {
4882 inst.error = _("r15 not allowed in swap");
4883 return;
4884 }
4885
4886 if (skip_past_comma (&str) == FAIL
4887 || *str++ != '[')
4888 {
4889 inst.error = BAD_ARGS;
4890 return;
4891 }
4892
4893 skip_whitespace (str);
4894
4895 if ((reg = reg_required_here (&str, 16)) == FAIL)
4896 return;
4897
4898 if (reg == REG_PC)
4899 {
4900 inst.error = BAD_PC;
4901 return;
4902 }
4903
4904 skip_whitespace (str);
4905
4906 if (*str++ != ']')
4907 {
4908 inst.error = _("missing ]");
4909 return;
4910 }
4911
4912 inst.instruction |= flags;
4913 end_of_line (str);
4914 return;
4915}
4916
4917static void
4918do_branch (str, flags)
4919 char * str;
4920 unsigned long flags ATTRIBUTE_UNUSED;
4921{
4922 if (my_get_expression (&inst.reloc.exp, &str))
4923 return;
4924
4925#ifdef OBJ_ELF
4926 {
4927 char * save_in;
4928
4929 /* ScottB: February 5, 1998 - Check to see of PLT32 reloc
4930 required for the instruction. */
4931
4932 /* arm_parse_reloc () works on input_line_pointer.
4933 We actually want to parse the operands to the branch instruction
4934 passed in 'str'. Save the input pointer and restore it later. */
4935 save_in = input_line_pointer;
4936 input_line_pointer = str;
4937 if (inst.reloc.exp.X_op == O_symbol
4938 && *str == '('
4939 && arm_parse_reloc () == BFD_RELOC_ARM_PLT32)
4940 {
4941 inst.reloc.type = BFD_RELOC_ARM_PLT32;
4942 inst.reloc.pc_rel = 0;
4943 /* Modify str to point to after parsed operands, otherwise
4944 end_of_line() will complain about the (PLT) left in str. */
4945 str = input_line_pointer;
4946 }
4947 else
4948 {
4949 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
4950 inst.reloc.pc_rel = 1;
4951 }
4952 input_line_pointer = save_in;
4953 }
4954#else
4955 inst.reloc.type = BFD_RELOC_ARM_PCREL_BRANCH;
4956 inst.reloc.pc_rel = 1;
4957#endif /* OBJ_ELF */
4958
4959 end_of_line (str);
4960 return;
4961}
4962
4963static void
4964do_bx (str, flags)
4965 char * str;
4966 unsigned long flags ATTRIBUTE_UNUSED;
4967{
4968 int reg;
4969
4970 skip_whitespace (str);
4971
4972 if ((reg = reg_required_here (&str, 0)) == FAIL)
4973 {
4974 inst.error = BAD_ARGS;
4975 return;
4976 }
4977
4978 /* Note - it is not illegal to do a "bx pc". Useless, but not illegal. */
4979 if (reg == REG_PC)
4980 as_tsktsk (_("Use of r15 in bx in ARM mode is not really useful"));
4981
4982 end_of_line (str);
4983}
4984
4985static void
4986do_cdp (str, flags)
4987 char * str;
4988 unsigned long flags ATTRIBUTE_UNUSED;
4989{
4990 /* Co-processor data operation.
4991 Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>} */
4992 skip_whitespace (str);
4993
4994 if (co_proc_number (&str) == FAIL)
4995 {
4996 if (!inst.error)
4997 inst.error = BAD_ARGS;
4998 return;
4999 }
5000
5001 if (skip_past_comma (&str) == FAIL
5002 || cp_opc_expr (&str, 20,4) == FAIL)
5003 {
5004 if (!inst.error)
5005 inst.error = BAD_ARGS;
5006 return;
5007 }
5008
5009 if (skip_past_comma (&str) == FAIL
5010 || cp_reg_required_here (&str, 12) == FAIL)
5011 {
5012 if (!inst.error)
5013 inst.error = BAD_ARGS;
5014 return;
5015 }
5016
5017 if (skip_past_comma (&str) == FAIL
5018 || cp_reg_required_here (&str, 16) == FAIL)
5019 {
5020 if (!inst.error)
5021 inst.error = BAD_ARGS;
5022 return;
5023 }
5024
5025 if (skip_past_comma (&str) == FAIL
5026 || cp_reg_required_here (&str, 0) == FAIL)
5027 {
5028 if (!inst.error)
5029 inst.error = BAD_ARGS;
5030 return;
5031 }
5032
5033 if (skip_past_comma (&str) == SUCCESS)
5034 {
5035 if (cp_opc_expr (&str, 5, 3) == FAIL)
5036 {
5037 if (!inst.error)
5038 inst.error = BAD_ARGS;
5039 return;
5040 }
5041 }
5042
5043 end_of_line (str);
5044 return;
5045}
5046
5047static void
5048do_lstc (str, flags)
5049 char * str;
5050 unsigned long flags;
5051{
5052 /* Co-processor register load/store.
5053 Format: <LDC|STC{cond}[L] CP#,CRd,<address> */
5054
5055 skip_whitespace (str);
5056
5057 if (co_proc_number (&str) == FAIL)
5058 {
5059 if (!inst.error)
5060 inst.error = BAD_ARGS;
5061 return;
5062 }
5063
5064 if (skip_past_comma (&str) == FAIL
5065 || cp_reg_required_here (&str, 12) == FAIL)
5066 {
5067 if (!inst.error)
5068 inst.error = BAD_ARGS;
5069 return;
5070 }
5071
5072 if (skip_past_comma (&str) == FAIL
5073 || cp_address_required_here (&str) == FAIL)
5074 {
5075 if (! inst.error)
5076 inst.error = BAD_ARGS;
5077 return;
5078 }
5079
5080 inst.instruction |= flags;
5081 end_of_line (str);
5082 return;
5083}
5084
5085static void
5086do_co_reg (str, flags)
5087 char * str;
5088 unsigned long flags;
5089{
5090 /* Co-processor register transfer.
5091 Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>} */
5092
5093 skip_whitespace (str);
5094
5095 if (co_proc_number (&str) == FAIL)
5096 {
5097 if (!inst.error)
5098 inst.error = BAD_ARGS;
5099 return;
5100 }
5101
5102 if (skip_past_comma (&str) == FAIL
5103 || cp_opc_expr (&str, 21, 3) == FAIL)
5104 {
5105 if (!inst.error)
5106 inst.error = BAD_ARGS;
5107 return;
5108 }
5109
5110 if (skip_past_comma (&str) == FAIL
5111 || reg_required_here (&str, 12) == FAIL)
5112 {
5113 if (!inst.error)
5114 inst.error = BAD_ARGS;
5115 return;
5116 }
5117
5118 if (skip_past_comma (&str) == FAIL
5119 || cp_reg_required_here (&str, 16) == FAIL)
5120 {
5121 if (!inst.error)
5122 inst.error = BAD_ARGS;
5123 return;
5124 }
5125
5126 if (skip_past_comma (&str) == FAIL
5127 || cp_reg_required_here (&str, 0) == FAIL)
5128 {
5129 if (!inst.error)
5130 inst.error = BAD_ARGS;
5131 return;
5132 }
5133
5134 if (skip_past_comma (&str) == SUCCESS)
5135 {
5136 if (cp_opc_expr (&str, 5, 3) == FAIL)
5137 {
5138 if (!inst.error)
5139 inst.error = BAD_ARGS;
5140 return;
5141 }
5142 }
5143 if (flags)
5144 {
5145 inst.error = BAD_COND;
5146 }
5147
5148 end_of_line (str);
5149 return;
5150}
5151
5152static void
5153do_fp_ctrl (str, flags)
5154 char * str;
5155 unsigned long flags ATTRIBUTE_UNUSED;
5156{
5157 /* FP control registers.
5158 Format: <WFS|RFS|WFC|RFC>{cond} Rn */
5159
5160 skip_whitespace (str);
5161
5162 if (reg_required_here (&str, 12) == FAIL)
5163 {
5164 if (!inst.error)
5165 inst.error = BAD_ARGS;
5166 return;
5167 }
5168
5169 end_of_line (str);
5170 return;
5171}
5172
5173static void
5174do_fp_ldst (str, flags)
5175 char * str;
5176 unsigned long flags ATTRIBUTE_UNUSED;
5177{
5178 skip_whitespace (str);
5179
5180 switch (inst.suffix)
5181 {
5182 case SUFF_S:
5183 break;
5184 case SUFF_D:
5185 inst.instruction |= CP_T_X;
5186 break;
5187 case SUFF_E:
5188 inst.instruction |= CP_T_Y;
5189 break;
5190 case SUFF_P:
5191 inst.instruction |= CP_T_X | CP_T_Y;
5192 break;
5193 default:
5194 abort ();
5195 }
5196
5197 if (fp_reg_required_here (&str, 12) == FAIL)
5198 {
5199 if (!inst.error)
5200 inst.error = BAD_ARGS;
5201 return;
5202 }
5203
5204 if (skip_past_comma (&str) == FAIL
5205 || cp_address_required_here (&str) == FAIL)
5206 {
5207 if (!inst.error)
5208 inst.error = BAD_ARGS;
5209 return;
5210 }
5211
5212 end_of_line (str);
5213}
5214
5215static void
5216do_fp_ldmstm (str, flags)
5217 char * str;
5218 unsigned long flags;
5219{
5220 int num_regs;
5221
5222 skip_whitespace (str);
5223
5224 if (fp_reg_required_here (&str, 12) == FAIL)
5225 {
5226 if (! inst.error)
5227 inst.error = BAD_ARGS;
5228 return;
5229 }
5230
5231 /* Get Number of registers to transfer. */
5232 if (skip_past_comma (&str) == FAIL
5233 || my_get_expression (&inst.reloc.exp, &str))
5234 {
5235 if (! inst.error)
5236 inst.error = _("constant expression expected");
5237 return;
5238 }
5239
5240 if (inst.reloc.exp.X_op != O_constant)
5241 {
5242 inst.error = _("Constant value required for number of registers");
5243 return;
5244 }
5245
5246 num_regs = inst.reloc.exp.X_add_number;
5247
5248 if (num_regs < 1 || num_regs > 4)
5249 {
5250 inst.error = _("number of registers must be in the range [1:4]");
5251 return;
5252 }
5253
5254 switch (num_regs)
5255 {
5256 case 1:
5257 inst.instruction |= CP_T_X;
5258 break;
5259 case 2:
5260 inst.instruction |= CP_T_Y;
5261 break;
5262 case 3:
5263 inst.instruction |= CP_T_Y | CP_T_X;
5264 break;
5265 case 4:
5266 break;
5267 default:
5268 abort ();
5269 }
5270
5271 if (flags)
5272 {
5273 int reg;
5274 int write_back;
5275 int offset;
5276
5277 /* The instruction specified "ea" or "fd", so we can only accept
5278 [Rn]{!}. The instruction does not really support stacking or
5279 unstacking, so we have to emulate these by setting appropriate
5280 bits and offsets. */
5281 if (skip_past_comma (&str) == FAIL
5282 || *str != '[')
5283 {
5284 if (! inst.error)
5285 inst.error = BAD_ARGS;
5286 return;
5287 }
5288
5289 str++;
5290 skip_whitespace (str);
5291
5292 if ((reg = reg_required_here (&str, 16)) == FAIL)
5293 return;
5294
5295 skip_whitespace (str);
5296
5297 if (*str != ']')
5298 {
5299 inst.error = BAD_ARGS;
5300 return;
5301 }
5302
5303 str++;
5304 if (*str == '!')
5305 {
5306 write_back = 1;
5307 str++;
5308 if (reg == REG_PC)
5309 {
5310 inst.error =
5311 _("R15 not allowed as base register with write-back");
5312 return;
5313 }
5314 }
5315 else
5316 write_back = 0;
5317
5318 if (flags & CP_T_Pre)
5319 {
5320 /* Pre-decrement. */
5321 offset = 3 * num_regs;
5322 if (write_back)
5323 flags |= CP_T_WB;
5324 }
5325 else
5326 {
5327 /* Post-increment. */
5328 if (write_back)
5329 {
5330 flags |= CP_T_WB;
5331 offset = 3 * num_regs;
5332 }
5333 else
5334 {
5335 /* No write-back, so convert this into a standard pre-increment
5336 instruction -- aesthetically more pleasing. */
5337 flags = CP_T_Pre | CP_T_UD;
5338 offset = 0;
5339 }
5340 }
5341
5342 inst.instruction |= flags | offset;
5343 }
5344 else if (skip_past_comma (&str) == FAIL
5345 || cp_address_required_here (&str) == FAIL)
5346 {
5347 if (! inst.error)
5348 inst.error = BAD_ARGS;
5349 return;
5350 }
5351
5352 end_of_line (str);
5353}
5354
5355static void
5356do_fp_dyadic (str, flags)
5357 char * str;
5358 unsigned long flags;
5359{
5360 skip_whitespace (str);
5361
5362 switch (inst.suffix)
5363 {
5364 case SUFF_S:
5365 break;
5366 case SUFF_D:
5367 inst.instruction |= 0x00000080;
5368 break;
5369 case SUFF_E:
5370 inst.instruction |= 0x00080000;
5371 break;
5372 default:
5373 abort ();
5374 }
5375
5376 if (fp_reg_required_here (&str, 12) == FAIL)
5377 {
5378 if (! inst.error)
5379 inst.error = BAD_ARGS;
5380 return;
5381 }
5382
5383 if (skip_past_comma (&str) == FAIL
5384 || fp_reg_required_here (&str, 16) == FAIL)
5385 {
5386 if (! inst.error)
5387 inst.error = BAD_ARGS;
5388 return;
5389 }
5390
5391 if (skip_past_comma (&str) == FAIL
5392 || fp_op2 (&str) == FAIL)
5393 {
5394 if (! inst.error)
5395 inst.error = BAD_ARGS;
5396 return;
5397 }
5398
5399 inst.instruction |= flags;
5400 end_of_line (str);
5401 return;
5402}
5403
5404static void
5405do_fp_monadic (str, flags)
5406 char * str;
5407 unsigned long flags;
5408{
5409 skip_whitespace (str);
5410
5411 switch (inst.suffix)
5412 {
5413 case SUFF_S:
5414 break;
5415 case SUFF_D:
5416 inst.instruction |= 0x00000080;
5417 break;
5418 case SUFF_E:
5419 inst.instruction |= 0x00080000;
5420 break;
5421 default:
5422 abort ();
5423 }
5424
5425 if (fp_reg_required_here (&str, 12) == FAIL)
5426 {
5427 if (! inst.error)
5428 inst.error = BAD_ARGS;
5429 return;
5430 }
5431
5432 if (skip_past_comma (&str) == FAIL
5433 || fp_op2 (&str) == FAIL)
5434 {
5435 if (! inst.error)
5436 inst.error = BAD_ARGS;
5437 return;
5438 }
5439
5440 inst.instruction |= flags;
5441 end_of_line (str);
5442 return;
5443}
5444
5445static void
5446do_fp_cmp (str, flags)
5447 char * str;
5448 unsigned long flags;
5449{
5450 skip_whitespace (str);
5451
5452 if (fp_reg_required_here (&str, 16) == FAIL)
5453 {
5454 if (! inst.error)
5455 inst.error = BAD_ARGS;
5456 return;
5457 }
5458
5459 if (skip_past_comma (&str) == FAIL
5460 || fp_op2 (&str) == FAIL)
5461 {
5462 if (! inst.error)
5463 inst.error = BAD_ARGS;
5464 return;
5465 }
5466
5467 inst.instruction |= flags;
5468 end_of_line (str);
5469 return;
5470}
5471
5472static void
5473do_fp_from_reg (str, flags)
5474 char * str;
5475 unsigned long flags;
5476{
5477 skip_whitespace (str);
5478
5479 switch (inst.suffix)
5480 {
5481 case SUFF_S:
5482 break;
5483 case SUFF_D:
5484 inst.instruction |= 0x00000080;
5485 break;
5486 case SUFF_E:
5487 inst.instruction |= 0x00080000;
5488 break;
5489 default:
5490 abort ();
5491 }
5492
5493 if (fp_reg_required_here (&str, 16) == FAIL)
5494 {
5495 if (! inst.error)
5496 inst.error = BAD_ARGS;
5497 return;
5498 }
5499
5500 if (skip_past_comma (&str) == FAIL
5501 || reg_required_here (&str, 12) == FAIL)
5502 {
5503 if (! inst.error)
5504 inst.error = BAD_ARGS;
5505 return;
5506 }
5507
5508 inst.instruction |= flags;
5509 end_of_line (str);
5510 return;
5511}
5512
5513static void
5514do_fp_to_reg (str, flags)
5515 char * str;
5516 unsigned long flags;
5517{
5518 skip_whitespace (str);
5519
5520 if (reg_required_here (&str, 12) == FAIL)
5521 return;
5522
5523 if (skip_past_comma (&str) == FAIL
5524 || fp_reg_required_here (&str, 0) == FAIL)
5525 {
5526 if (! inst.error)
5527 inst.error = BAD_ARGS;
5528 return;
5529 }
5530
5531 inst.instruction |= flags;
5532 end_of_line (str);
5533 return;
5534}
5535
5536/* Thumb specific routines. */
5537
5538/* Parse and validate that a register is of the right form, this saves
5539 repeated checking of this information in many similar cases.
5540 Unlike the 32-bit case we do not insert the register into the opcode
5541 here, since the position is often unknown until the full instruction
5542 has been parsed. */
5543
5544static int
5545thumb_reg (strp, hi_lo)
5546 char ** strp;
5547 int hi_lo;
5548{
5549 int reg;
5550
5551 if ((reg = reg_required_here (strp, -1)) == FAIL)
5552 return FAIL;
5553
5554 switch (hi_lo)
5555 {
5556 case THUMB_REG_LO:
5557 if (reg > 7)
5558 {
5559 inst.error = _("lo register required");
5560 return FAIL;
5561 }
5562 break;
5563
5564 case THUMB_REG_HI:
5565 if (reg < 8)
5566 {
5567 inst.error = _("hi register required");
5568 return FAIL;
5569 }
5570 break;
5571
5572 default:
5573 break;
5574 }
5575
5576 return reg;
5577}
5578
5579/* Parse an add or subtract instruction, SUBTRACT is non-zero if the opcode
5580 was SUB. */
5581
5582static void
5583thumb_add_sub (str, subtract)
5584 char * str;
5585 int subtract;
5586{
5587 int Rd, Rs, Rn = FAIL;
5588
5589 skip_whitespace (str);
5590
5591 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
5592 || skip_past_comma (&str) == FAIL)
5593 {
5594 if (! inst.error)
5595 inst.error = BAD_ARGS;
5596 return;
5597 }
5598
5599 if (is_immediate_prefix (*str))
5600 {
5601 Rs = Rd;
5602 str++;
5603 if (my_get_expression (&inst.reloc.exp, &str))
5604 return;
5605 }
5606 else
5607 {
5608 if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5609 return;
5610
5611 if (skip_past_comma (&str) == FAIL)
5612 {
5613 /* Two operand format, shuffle the registers
5614 and pretend there are 3. */
5615 Rn = Rs;
5616 Rs = Rd;
5617 }
5618 else if (is_immediate_prefix (*str))
5619 {
5620 str++;
5621 if (my_get_expression (&inst.reloc.exp, &str))
5622 return;
5623 }
5624 else if ((Rn = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5625 return;
5626 }
5627
5628 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5629 for the latter case, EXPR contains the immediate that was found. */
5630 if (Rn != FAIL)
5631 {
5632 /* All register format. */
5633 if (Rd > 7 || Rs > 7 || Rn > 7)
5634 {
5635 if (Rs != Rd)
5636 {
5637 inst.error = _("dest and source1 must be the same register");
5638 return;
5639 }
5640
5641 /* Can't do this for SUB. */
5642 if (subtract)
5643 {
5644 inst.error = _("subtract valid only on lo regs");
5645 return;
5646 }
5647
5648 inst.instruction = (T_OPCODE_ADD_HI
5649 | (Rd > 7 ? THUMB_H1 : 0)
5650 | (Rn > 7 ? THUMB_H2 : 0));
5651 inst.instruction |= (Rd & 7) | ((Rn & 7) << 3);
5652 }
5653 else
5654 {
5655 inst.instruction = subtract ? T_OPCODE_SUB_R3 : T_OPCODE_ADD_R3;
5656 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
5657 }
5658 }
5659 else
5660 {
5661 /* Immediate expression, now things start to get nasty. */
5662
5663 /* First deal with HI regs, only very restricted cases allowed:
5664 Adjusting SP, and using PC or SP to get an address. */
5665 if ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
5666 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC))
5667 {
5668 inst.error = _("invalid Hi register with immediate");
5669 return;
5670 }
5671
5672 if (inst.reloc.exp.X_op != O_constant)
5673 {
5674 /* Value isn't known yet, all we can do is store all the fragments
5675 we know about in the instruction and let the reloc hacking
5676 work it all out. */
5677 inst.instruction = (subtract ? 0x8000 : 0) | (Rd << 4) | Rs;
5678 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
5679 }
5680 else
5681 {
5682 int offset = inst.reloc.exp.X_add_number;
5683
5684 if (subtract)
5685 offset = -offset;
5686
5687 if (offset < 0)
5688 {
5689 offset = -offset;
5690 subtract = 1;
5691
5692 /* Quick check, in case offset is MIN_INT. */
5693 if (offset < 0)
5694 {
5695 inst.error = _("immediate value out of range");
5696 return;
5697 }
5698 }
5699 else
5700 subtract = 0;
5701
5702 if (Rd == REG_SP)
5703 {
5704 if (offset & ~0x1fc)
5705 {
5706 inst.error = _("invalid immediate value for stack adjust");
5707 return;
5708 }
5709 inst.instruction = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
5710 inst.instruction |= offset >> 2;
5711 }
5712 else if (Rs == REG_PC || Rs == REG_SP)
5713 {
5714 if (subtract
5715 || (offset & ~0x3fc))
5716 {
5717 inst.error = _("invalid immediate for address calculation");
5718 return;
5719 }
5720 inst.instruction = (Rs == REG_PC ? T_OPCODE_ADD_PC
5721 : T_OPCODE_ADD_SP);
5722 inst.instruction |= (Rd << 8) | (offset >> 2);
5723 }
5724 else if (Rs == Rd)
5725 {
5726 if (offset & ~0xff)
5727 {
5728 inst.error = _("immediate value out of range");
5729 return;
5730 }
5731 inst.instruction = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
5732 inst.instruction |= (Rd << 8) | offset;
5733 }
5734 else
5735 {
5736 if (offset & ~0x7)
5737 {
5738 inst.error = _("immediate value out of range");
5739 return;
5740 }
5741 inst.instruction = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
5742 inst.instruction |= Rd | (Rs << 3) | (offset << 6);
5743 }
5744 }
5745 }
5746
5747 end_of_line (str);
5748}
5749
5750static void
5751thumb_shift (str, shift)
5752 char * str;
5753 int shift;
5754{
5755 int Rd, Rs, Rn = FAIL;
5756
5757 skip_whitespace (str);
5758
5759 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
5760 || skip_past_comma (&str) == FAIL)
5761 {
5762 if (! inst.error)
5763 inst.error = BAD_ARGS;
5764 return;
5765 }
5766
5767 if (is_immediate_prefix (*str))
5768 {
5769 /* Two operand immediate format, set Rs to Rd. */
5770 Rs = Rd;
5771 str ++;
5772 if (my_get_expression (&inst.reloc.exp, &str))
5773 return;
5774 }
5775 else
5776 {
5777 if ((Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5778 return;
5779
5780 if (skip_past_comma (&str) == FAIL)
5781 {
5782 /* Two operand format, shuffle the registers
5783 and pretend there are 3. */
5784 Rn = Rs;
5785 Rs = Rd;
5786 }
5787 else if (is_immediate_prefix (*str))
5788 {
5789 str++;
5790 if (my_get_expression (&inst.reloc.exp, &str))
5791 return;
5792 }
5793 else if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5794 return;
5795 }
5796
5797 /* We now have Rd and Rs set to registers, and Rn set to a register or FAIL;
5798 for the latter case, EXPR contains the immediate that was found. */
5799
5800 if (Rn != FAIL)
5801 {
5802 if (Rs != Rd)
5803 {
5804 inst.error = _("source1 and dest must be same register");
5805 return;
5806 }
5807
5808 switch (shift)
5809 {
5810 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_R; break;
5811 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_R; break;
5812 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_R; break;
5813 }
5814
5815 inst.instruction |= Rd | (Rn << 3);
5816 }
5817 else
5818 {
5819 switch (shift)
5820 {
5821 case THUMB_ASR: inst.instruction = T_OPCODE_ASR_I; break;
5822 case THUMB_LSL: inst.instruction = T_OPCODE_LSL_I; break;
5823 case THUMB_LSR: inst.instruction = T_OPCODE_LSR_I; break;
5824 }
5825
5826 if (inst.reloc.exp.X_op != O_constant)
5827 {
5828 /* Value isn't known yet, create a dummy reloc and let reloc
5829 hacking fix it up. */
5830 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
5831 }
5832 else
5833 {
5834 unsigned shift_value = inst.reloc.exp.X_add_number;
5835
5836 if (shift_value > 32 || (shift_value == 32 && shift == THUMB_LSL))
5837 {
5838 inst.error = _("Invalid immediate for shift");
5839 return;
5840 }
5841
5842 /* Shifts of zero are handled by converting to LSL. */
5843 if (shift_value == 0)
5844 inst.instruction = T_OPCODE_LSL_I;
5845
5846 /* Shifts of 32 are encoded as a shift of zero. */
5847 if (shift_value == 32)
5848 shift_value = 0;
5849
5850 inst.instruction |= shift_value << 6;
5851 }
5852
5853 inst.instruction |= Rd | (Rs << 3);
5854 }
5855
5856 end_of_line (str);
5857}
5858
5859static void
5860thumb_mov_compare (str, move)
5861 char * str;
5862 int move;
5863{
5864 int Rd, Rs = FAIL;
5865
5866 skip_whitespace (str);
5867
5868 if ((Rd = thumb_reg (&str, THUMB_REG_ANY)) == FAIL
5869 || skip_past_comma (&str) == FAIL)
5870 {
5871 if (! inst.error)
5872 inst.error = BAD_ARGS;
5873 return;
5874 }
5875
5876 if (is_immediate_prefix (*str))
5877 {
5878 str++;
5879 if (my_get_expression (&inst.reloc.exp, &str))
5880 return;
5881 }
5882 else if ((Rs = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5883 return;
5884
5885 if (Rs != FAIL)
5886 {
5887 if (Rs < 8 && Rd < 8)
5888 {
5889 if (move == THUMB_MOVE)
5890 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
5891 since a MOV instruction produces unpredictable results. */
5892 inst.instruction = T_OPCODE_ADD_I3;
5893 else
5894 inst.instruction = T_OPCODE_CMP_LR;
5895 inst.instruction |= Rd | (Rs << 3);
5896 }
5897 else
5898 {
5899 if (move == THUMB_MOVE)
5900 inst.instruction = T_OPCODE_MOV_HR;
5901 else
5902 inst.instruction = T_OPCODE_CMP_HR;
5903
5904 if (Rd > 7)
5905 inst.instruction |= THUMB_H1;
5906
5907 if (Rs > 7)
5908 inst.instruction |= THUMB_H2;
5909
5910 inst.instruction |= (Rd & 7) | ((Rs & 7) << 3);
5911 }
5912 }
5913 else
5914 {
5915 if (Rd > 7)
5916 {
5917 inst.error = _("only lo regs allowed with immediate");
5918 return;
5919 }
5920
5921 if (move == THUMB_MOVE)
5922 inst.instruction = T_OPCODE_MOV_I8;
5923 else
5924 inst.instruction = T_OPCODE_CMP_I8;
5925
5926 inst.instruction |= Rd << 8;
5927
5928 if (inst.reloc.exp.X_op != O_constant)
5929 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
5930 else
5931 {
5932 unsigned value = inst.reloc.exp.X_add_number;
5933
5934 if (value > 255)
5935 {
5936 inst.error = _("invalid immediate");
5937 return;
5938 }
5939
5940 inst.instruction |= value;
5941 }
5942 }
5943
5944 end_of_line (str);
5945}
5946
5947static void
5948thumb_load_store (str, load_store, size)
5949 char * str;
5950 int load_store;
5951 int size;
5952{
5953 int Rd, Rb, Ro = FAIL;
5954
5955 skip_whitespace (str);
5956
5957 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
5958 || skip_past_comma (&str) == FAIL)
5959 {
5960 if (! inst.error)
5961 inst.error = BAD_ARGS;
5962 return;
5963 }
5964
5965 if (*str == '[')
5966 {
5967 str++;
5968 if ((Rb = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
5969 return;
5970
5971 if (skip_past_comma (&str) != FAIL)
5972 {
5973 if (is_immediate_prefix (*str))
5974 {
5975 str++;
5976 if (my_get_expression (&inst.reloc.exp, &str))
5977 return;
5978 }
5979 else if ((Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
5980 return;
5981 }
5982 else
5983 {
5984 inst.reloc.exp.X_op = O_constant;
5985 inst.reloc.exp.X_add_number = 0;
5986 }
5987
5988 if (*str != ']')
5989 {
5990 inst.error = _("expected ']'");
5991 return;
5992 }
5993 str++;
5994 }
5995 else if (*str == '=')
5996 {
5997 /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op. */
5998 str++;
5999
6000 skip_whitespace (str);
6001
6002 if (my_get_expression (& inst.reloc.exp, & str))
6003 return;
6004
6005 end_of_line (str);
6006
6007 if ( inst.reloc.exp.X_op != O_constant
6008 && inst.reloc.exp.X_op != O_symbol)
6009 {
6010 inst.error = "Constant expression expected";
6011 return;
6012 }
6013
6014 if (inst.reloc.exp.X_op == O_constant
6015 && ((inst.reloc.exp.X_add_number & ~0xFF) == 0))
6016 {
6017 /* This can be done with a mov instruction. */
6018
6019 inst.instruction = T_OPCODE_MOV_I8 | (Rd << 8);
6020 inst.instruction |= inst.reloc.exp.X_add_number;
6021 return;
6022 }
6023
6024 /* Insert into literal pool. */
6025 if (add_to_lit_pool () == FAIL)
6026 {
6027 if (!inst.error)
6028 inst.error = "literal pool insertion failed";
6029 return;
6030 }
6031
6032 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
6033 inst.reloc.pc_rel = 1;
6034 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
6035 /* Adjust ARM pipeline offset to Thumb. */
6036 inst.reloc.exp.X_add_number += 4;
6037
6038 return;
6039 }
6040 else
6041 {
6042 if (my_get_expression (&inst.reloc.exp, &str))
6043 return;
6044
6045 inst.instruction = T_OPCODE_LDR_PC | (Rd << 8);
6046 inst.reloc.pc_rel = 1;
6047 inst.reloc.exp.X_add_number -= 4; /* Pipeline offset. */
6048 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
6049 end_of_line (str);
6050 return;
6051 }
6052
6053 if (Rb == REG_PC || Rb == REG_SP)
6054 {
6055 if (size != THUMB_WORD)
6056 {
6057 inst.error = _("byte or halfword not valid for base register");
6058 return;
6059 }
6060 else if (Rb == REG_PC && load_store != THUMB_LOAD)
6061 {
6062 inst.error = _("R15 based store not allowed");
6063 return;
6064 }
6065 else if (Ro != FAIL)
6066 {
6067 inst.error = _("Invalid base register for register offset");
6068 return;
6069 }
6070
6071 if (Rb == REG_PC)
6072 inst.instruction = T_OPCODE_LDR_PC;
6073 else if (load_store == THUMB_LOAD)
6074 inst.instruction = T_OPCODE_LDR_SP;
6075 else
6076 inst.instruction = T_OPCODE_STR_SP;
6077
6078 inst.instruction |= Rd << 8;
6079 if (inst.reloc.exp.X_op == O_constant)
6080 {
6081 unsigned offset = inst.reloc.exp.X_add_number;
6082
6083 if (offset & ~0x3fc)
6084 {
6085 inst.error = _("invalid offset");
6086 return;
6087 }
6088
6089 inst.instruction |= offset >> 2;
6090 }
6091 else
6092 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
6093 }
6094 else if (Rb > 7)
6095 {
6096 inst.error = _("invalid base register in load/store");
6097 return;
6098 }
6099 else if (Ro == FAIL)
6100 {
6101 /* Immediate offset. */
6102 if (size == THUMB_WORD)
6103 inst.instruction = (load_store == THUMB_LOAD
6104 ? T_OPCODE_LDR_IW : T_OPCODE_STR_IW);
6105 else if (size == THUMB_HALFWORD)
6106 inst.instruction = (load_store == THUMB_LOAD
6107 ? T_OPCODE_LDR_IH : T_OPCODE_STR_IH);
6108 else
6109 inst.instruction = (load_store == THUMB_LOAD
6110 ? T_OPCODE_LDR_IB : T_OPCODE_STR_IB);
6111
6112 inst.instruction |= Rd | (Rb << 3);
6113
6114 if (inst.reloc.exp.X_op == O_constant)
6115 {
6116 unsigned offset = inst.reloc.exp.X_add_number;
6117
6118 if (offset & ~(0x1f << size))
6119 {
6120 inst.error = _("Invalid offset");
6121 return;
6122 }
6123 inst.instruction |= (offset >> size) << 6;
6124 }
6125 else
6126 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
6127 }
6128 else
6129 {
6130 /* Register offset. */
6131 if (size == THUMB_WORD)
6132 inst.instruction = (load_store == THUMB_LOAD
6133 ? T_OPCODE_LDR_RW : T_OPCODE_STR_RW);
6134 else if (size == THUMB_HALFWORD)
6135 inst.instruction = (load_store == THUMB_LOAD
6136 ? T_OPCODE_LDR_RH : T_OPCODE_STR_RH);
6137 else
6138 inst.instruction = (load_store == THUMB_LOAD
6139 ? T_OPCODE_LDR_RB : T_OPCODE_STR_RB);
6140
6141 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
6142 }
6143
6144 end_of_line (str);
6145}
6146
404ff6b5
AH
6147/* Given a register and a register type, return 1 if
6148 the register is of the given type, else return 0. */
6149
6150static int
6151cirrus_valid_reg (reg, regtype)
6152 int reg;
6153 enum cirrus_regtype regtype;
6154{
6155 switch (regtype)
6156 {
6157 case CIRRUS_REGTYPE_ANY:
6158 return 1;
6159
6160 case CIRRUS_REGTYPE_MVF:
6161 return cirrus_mvf_register (reg);
6162
6163 case CIRRUS_REGTYPE_MVFX:
6164 return cirrus_mvfx_register (reg);
6165
6166 case CIRRUS_REGTYPE_MVD:
6167 return cirrus_mvd_register (reg);
6168
6169 case CIRRUS_REGTYPE_MVDX:
6170 return cirrus_mvdx_register (reg);
6171
6172 case CIRRUS_REGTYPE_MVAX:
6173 return cirrus_mvax_register (reg);
6174
6175 case CIRRUS_REGTYPE_DSPSC:
6176 return ARM_EXT_MAVERIKsc_register (reg);
6177 }
6178
6179 return 0;
6180}
6181
6182/* A register must be given at this point.
6183
6184 If the register is a Cirrus register, convert it's reg# appropriately.
6185
6186 Shift is the place to put it in inst.instruction.
6187
6188 regtype is type register type expected, and is:
6189 CIRRUS_REGTYPE_MVF
6190 CIRRUS_REGTYPE_MVFX
6191 CIRRUS_REGTYPE_MVD
6192 CIRRUS_REGTYPE_MVDX
6193 CIRRUS_REGTYPE_MVAX
6194 CIRRUS_REGTYPE_DSPSC
6195
6196 Restores input start point on err.
6197 Returns the reg#, or FAIL. */
6198
6199static int
6200cirrus_reg_required_here (str, shift, regtype)
6201 char ** str;
6202 int shift;
6203 enum cirrus_regtype regtype;
6204{
6205 static char buff [135]; /* XXX */
6206 int reg;
6207 char * start = * str;
6208
6209 if ((reg = arm_reg_parse (str)) != FAIL
6210 && (int_register (reg)
6211 || cirrus_register (reg)))
6212 {
6213 int orig_reg = reg;
6214
6215 /* Calculate actual register # for opcode. */
6216 if (cirrus_register (reg)
6217 && !ARM_EXT_MAVERIKsc_register (reg)) /* Leave this one as is. */
6218 {
6219 if (reg >= 130)
6220 reg -= 130;
6221 else if (reg >= 110)
6222 reg -= 110;
6223 else if (reg >= 90)
6224 reg -= 90;
6225 else if (reg >= 70)
6226 reg -= 70;
6227 else if (reg >= 50)
6228 reg -= 50;
6229 }
6230
6231 if (!cirrus_valid_reg (orig_reg, regtype))
6232 {
6233 sprintf (buff, _("invalid register type at '%.100s'"), start);
6234 inst.error = buff;
6235 return FAIL;
6236 }
6237
6238 if (shift >= 0)
6239 inst.instruction |= reg << shift;
6240
6241 return orig_reg;
6242 }
6243
6244 /* Restore the start point, we may have got a reg of the wrong class. */
6245 *str = start;
6246
6247 /* In the few cases where we might be able to accept something else
6248 this error can be overridden. */
6249 sprintf (buff, _("Cirrus register expected, not '%.100s'"), start);
6250 inst.error = buff;
6251
6252 return FAIL;
6253}
6254
6255/* Cirrus Instructions. */
6256
6257/* Wrapper functions. */
6258
6259static void
6260do_c_binops_1 (str, flags)
6261 char * str;
6262 unsigned long flags;
6263{
6264 do_c_binops (str, flags, CIRRUS_MODE1);
6265}
6266
6267static void
6268do_c_binops_2 (str, flags)
6269 char * str;
6270 unsigned long flags;
6271{
6272 do_c_binops (str, flags, CIRRUS_MODE2);
6273}
6274
6275static void
6276do_c_binops_3 (str, flags)
6277 char * str;
6278 unsigned long flags;
6279{
6280 do_c_binops (str, flags, CIRRUS_MODE3);
6281}
6282
6283static void
6284do_c_triple_4 (str, flags)
6285 char * str;
6286 unsigned long flags;
6287{
6288 do_c_triple (str, flags, CIRRUS_MODE4);
6289}
6290
6291static void
6292do_c_triple_5 (str, flags)
6293 char * str;
6294 unsigned long flags;
6295{
6296 do_c_triple (str, flags, CIRRUS_MODE5);
6297}
6298
6299static void
6300do_c_quad_6 (str, flags)
6301 char * str;
6302 unsigned long flags;
6303{
6304 do_c_quad (str, flags, CIRRUS_MODE6);
6305}
6306
6307static void
6308do_c_dspsc_1 (str, flags)
6309 char * str;
6310 unsigned long flags;
6311{
6312 do_c_dspsc (str, flags, CIRRUS_MODE1);
6313}
6314
6315static void
6316do_c_dspsc_2 (str, flags)
6317 char * str;
6318 unsigned long flags;
6319{
6320 do_c_dspsc (str, flags, CIRRUS_MODE2);
6321}
6322
6323static void
6324do_c_shift_1 (str, flags)
6325 char * str;
6326 unsigned long flags;
6327{
6328 do_c_shift (str, flags, CIRRUS_MODE1);
6329}
6330
6331static void
6332do_c_shift_2 (str, flags)
6333 char * str;
6334 unsigned long flags;
6335{
6336 do_c_shift (str, flags, CIRRUS_MODE2);
6337}
6338
6339static void
6340do_c_ldst_1 (str, flags)
6341 char * str;
6342 unsigned long flags;
6343{
6344 do_c_ldst (str, flags, CIRRUS_MODE1);
6345}
6346
6347static void
6348do_c_ldst_2 (str, flags)
6349 char * str;
6350 unsigned long flags;
6351{
6352 do_c_ldst (str, flags, CIRRUS_MODE2);
6353}
6354
6355static void
6356do_c_ldst_3 (str, flags)
6357 char * str;
6358 unsigned long flags;
6359{
6360 do_c_ldst (str, flags, CIRRUS_MODE3);
6361}
6362
6363static void
6364do_c_ldst_4 (str, flags)
6365 char * str;
6366 unsigned long flags;
6367{
6368 do_c_ldst (str, flags, CIRRUS_MODE4);
6369}
6370
6371/* Isnsn like "foo X,Y". */
6372
6373static void
6374do_c_binops (str, flags, mode)
6375 char * str;
6376 unsigned long flags;
6377 int mode;
6378{
6379 int shift1, shift2;
6380
6381 shift1 = mode & 0xff;
6382 shift2 = (mode >> 8) & 0xff;
6383
6384 skip_whitespace (str);
6385
6386 if (cirrus_reg_required_here (&str, shift1, CIRRUS_REGTYPE_ANY) == FAIL
6387 || skip_past_comma (&str) == FAIL
6388 || cirrus_reg_required_here (&str, shift2, CIRRUS_REGTYPE_ANY) == FAIL)
6389 {
6390 if (!inst.error)
6391 inst.error = BAD_ARGS;
6392 }
6393 else
6394 end_of_line (str);
6395
6396 inst.instruction |= flags;
6397 return;
6398}
6399
6400/* Isnsn like "foo X,Y,Z". */
6401
6402static void
6403do_c_triple (str, flags, mode)
6404 char * str;
6405 unsigned long flags;
6406 int mode;
6407{
6408 int shift1, shift2, shift3;
6409
6410 shift1 = mode & 0xff;
6411 shift2 = (mode >> 8) & 0xff;
6412 shift3 = (mode >> 16) & 0xff;
6413
6414 skip_whitespace (str);
6415
6416 if (cirrus_reg_required_here (&str, shift1, CIRRUS_REGTYPE_ANY) == FAIL
6417 || skip_past_comma (&str) == FAIL
6418 || cirrus_reg_required_here (&str, shift2, CIRRUS_REGTYPE_ANY) == FAIL
6419 || skip_past_comma (&str) == FAIL
6420 || cirrus_reg_required_here (&str, shift3, CIRRUS_REGTYPE_ANY) == FAIL)
6421 {
6422 if (!inst.error)
6423 inst.error = BAD_ARGS;
6424 }
6425 else
6426 end_of_line (str);
6427
6428 inst.instruction |= flags;
6429 return;
6430}
6431
6432/* Isnsn like "foo W,X,Y,Z".
6433 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
6434
6435static void
6436do_c_quad (str, flags, mode)
6437 char * str;
6438 unsigned long flags;
6439 int mode;
6440{
6441 int shift1, shift2, shift3, shift4;
6442 enum cirrus_regtype rt;
6443
6444 rt = (inst.instruction << 4 == 0xe2006000
6445 || inst.instruction << 4 == 0xe3006000) ? CIRRUS_REGTYPE_MVAX
6446 : CIRRUS_REGTYPE_MVFX;
6447
6448 shift1 = mode & 0xff;
6449 shift2 = (mode >> 8) & 0xff;
6450 shift3 = (mode >> 16) & 0xff;
6451 shift4 = (mode >> 24) & 0xff;
6452
6453 skip_whitespace (str);
6454
6455 if (cirrus_reg_required_here (&str, shift1, CIRRUS_REGTYPE_MVAX) == FAIL
6456 || skip_past_comma (&str) == FAIL
6457 || cirrus_reg_required_here (&str, shift2, rt) == FAIL
6458 || skip_past_comma (&str) == FAIL
6459 || cirrus_reg_required_here (&str, shift3, CIRRUS_REGTYPE_MVFX) == FAIL
6460 || skip_past_comma (&str) == FAIL
6461 || cirrus_reg_required_here (&str, shift4, CIRRUS_REGTYPE_MVFX) == FAIL)
6462 {
6463 if (!inst.error)
6464 inst.error = BAD_ARGS;
6465 }
6466 else
6467 end_of_line (str);
6468
6469 inst.instruction |= flags;
6470 return;
6471}
6472
6473/* cfmvsc32<cond> DSPSC,MVFX[15:0].
6474 cfmv32sc<cond> MVFX[15:0],DSPSC. */
6475
6476static void
6477do_c_dspsc (str, flags, mode)
6478 char * str;
6479 unsigned long flags;
6480 int mode;
6481{
6482 int error;
6483
6484 skip_whitespace (str);
6485
6486 error = 0;
6487
6488 if (mode == CIRRUS_MODE1)
6489 {
6490 /* cfmvsc32. */
6491 if (cirrus_reg_required_here (&str, -1, CIRRUS_REGTYPE_DSPSC) == FAIL
6492 || skip_past_comma (&str) == FAIL
6493 || cirrus_reg_required_here (&str, 16, CIRRUS_REGTYPE_MVFX) == FAIL)
6494 error = 1;
6495 }
6496 else
6497 {
6498 /* cfmv32sc. */
6499 if (cirrus_reg_required_here (&str, 0, CIRRUS_REGTYPE_MVFX) == FAIL
6500 || skip_past_comma (&str) == FAIL
6501 || cirrus_reg_required_here (&str, -1, CIRRUS_REGTYPE_DSPSC) == FAIL)
6502 error = 1;
6503 }
6504
6505 if (error)
6506 {
6507 if (!inst.error)
6508 inst.error = BAD_ARGS;
6509 }
6510 else
6511 {
6512 inst.instruction |= flags;
6513 end_of_line (str);
6514 }
6515
6516 return;
6517}
6518
6519/* Cirrus shift immediate instructions.
6520 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
6521 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
6522
6523static void
6524do_c_shift (str, flags, mode)
6525 char * str;
6526 unsigned long flags;
6527 int mode;
6528{
6529 int error;
6530 int imm, neg = 0;
6531
6532 skip_whitespace (str);
6533
6534 error = 0;
6535
6536 if (cirrus_reg_required_here (&str, 12,
6537 (mode == CIRRUS_MODE1)
6538 ? CIRRUS_REGTYPE_MVFX
6539 : CIRRUS_REGTYPE_MVDX) == FAIL
6540 || skip_past_comma (&str) == FAIL
6541 || cirrus_reg_required_here (&str, 16,
6542 (mode == CIRRUS_MODE1)
6543 ? CIRRUS_REGTYPE_MVFX
6544 : CIRRUS_REGTYPE_MVDX) == FAIL
6545 || skip_past_comma (&str) == FAIL)
6546 {
6547 if (!inst.error)
6548 inst.error = BAD_ARGS;
6549 return;
6550 }
6551
6552 /* Calculate the immediate operand.
6553 The operand is a 7bit signed number. */
6554 skip_whitespace (str);
6555
6556 if (*str == '#')
6557 ++str;
6558
6559 if (!isdigit (*str) && *str != '-')
6560 {
6561 inst.error = _("expecting immediate, 7bit operand");
6562 return;
6563 }
6564
6565 if (*str == '-')
6566 {
6567 neg = 1;
6568 ++str;
6569 }
6570
6571 for (imm = 0; *str && isdigit (*str); ++str)
6572 imm = imm * 10 + *str - '0';
6573
6574 if (imm > 64)
6575 {
6576 inst.error = _("immediate out of range");
6577 return;
6578 }
6579
6580 /* Make negative imm's into 7bit signed numbers. */
6581 if (neg)
6582 {
6583 imm = -imm;
6584 imm &= 0x0000007f;
6585 }
6586
6587 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
6588 Bits 5-7 of the insn should have bits 4-6 of the immediate.
6589 Bit 4 should be 0. */
6590 imm = (imm & 0xf) | ((imm & 0x70) << 1);
6591
6592 inst.instruction |= imm;
6593 inst.instruction |= flags;
6594
6595 end_of_line (str);
6596
6597 return;
6598}
6599
6600static int
6601cirrus_parse_offset (str, negative)
6602 char ** str;
6603 int *negative;
6604{
6605 char * p = *str;
6606 int offset;
6607
6608 *negative = 0;
6609
6610 skip_whitespace (p);
6611
6612 if (*p == '#')
6613 ++p;
6614
6615 if (*p == '-')
6616 {
6617 *negative = 1;
6618 ++p;
6619 }
6620
6621 if (!isdigit (*p))
6622 {
6623 inst.error = _("offset expected");
6624 return 0;
6625 }
6626
6627 for (offset = 0; *p && isdigit (*p); ++p)
6628 offset = offset * 10 + *p - '0';
6629
6630 if (offset > 0xff)
6631 {
6632 inst.error = _("offset out of range");
6633 return 0;
6634 }
6635
6636 *str = p;
6637
6638 return *negative ? -offset : offset;
6639}
6640
6641/* Cirrus load/store instructions.
6642 <insn><cond> CRd,[Rn,<offset>]{!}.
6643 <insn><cond> CRd,[Rn],<offset>. */
6644
6645static void
6646do_c_ldst (str, flags, mode)
6647 char * str;
6648 unsigned long flags;
6649 int mode;
6650{
6651 int offset, negative;
6652 enum cirrus_regtype rt;
6653
6654 rt = mode == CIRRUS_MODE1 ? CIRRUS_REGTYPE_MVF
6655 : mode == CIRRUS_MODE2 ? CIRRUS_REGTYPE_MVD
6656 : mode == CIRRUS_MODE3 ? CIRRUS_REGTYPE_MVFX
6657 : mode == CIRRUS_MODE4 ? CIRRUS_REGTYPE_MVDX : CIRRUS_REGTYPE_MVF;
6658
6659 skip_whitespace (str);
6660
6661 if (cirrus_reg_required_here (& str, 12, rt) == FAIL
6662 || skip_past_comma (& str) == FAIL
6663 || *str++ != '['
6664 || reg_required_here (& str, 16) == FAIL)
6665 goto fail_ldst;
6666
6667 if (skip_past_comma (& str) == SUCCESS)
6668 {
6669 /* You are here: "<offset>]{!}". */
6670 inst.instruction |= PRE_INDEX;
6671
6672 offset = cirrus_parse_offset (&str, &negative);
6673
6674 if (inst.error)
6675 return;
6676
6677 if (*str++ != ']')
6678 {
6679 inst.error = _("missing ]");
6680 return;
6681 }
6682
6683 if (*str == '!')
6684 {
6685 inst.instruction |= WRITE_BACK;
6686 ++str;
6687 }
6688 }
6689 else
6690 {
6691 /* You are here: "], <offset>". */
6692 if (*str++ != ']')
6693 {
6694 inst.error = _("missing ]");
6695 return;
6696 }
6697
6698 if (skip_past_comma (&str) == FAIL
6699 || (offset = cirrus_parse_offset (&str, &negative), inst.error))
6700 goto fail_ldst;
6701
6702 inst.instruction |= CP_T_WB; /* Post indexed, set bit W. */
6703 }
6704
6705 if (negative)
6706 offset = -offset;
6707 else
6708 inst.instruction |= CP_T_UD; /* Postive, so set bit U. */
6709
6710 inst.instruction |= offset >> 2;
6711 inst.instruction |= flags;
6712
6713 end_of_line (str);
6714 return;
6715
6716fail_ldst:
6717 if (!inst.error)
6718 inst.error = BAD_ARGS;
6719 return;
6720}
6721
b99bd4ef
NC
6722static void
6723do_t_nop (str)
6724 char * str;
6725{
6726 /* Do nothing. */
6727 end_of_line (str);
6728 return;
6729}
6730
6731/* Handle the Format 4 instructions that do not have equivalents in other
6732 formats. That is, ADC, AND, EOR, SBC, ROR, TST, NEG, CMN, ORR, MUL,
6733 BIC and MVN. */
6734
6735static void
6736do_t_arit (str)
6737 char * str;
6738{
6739 int Rd, Rs, Rn;
6740
6741 skip_whitespace (str);
6742
6743 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
6744 || skip_past_comma (&str) == FAIL
6745 || (Rs = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
6746 {
6747 inst.error = BAD_ARGS;
6748 return;
6749 }
6750
6751 if (skip_past_comma (&str) != FAIL)
6752 {
6753 /* Three operand format not allowed for TST, CMN, NEG and MVN.
6754 (It isn't allowed for CMP either, but that isn't handled by this
6755 function.) */
6756 if (inst.instruction == T_OPCODE_TST
6757 || inst.instruction == T_OPCODE_CMN
6758 || inst.instruction == T_OPCODE_NEG
6759 || inst.instruction == T_OPCODE_MVN)
6760 {
6761 inst.error = BAD_ARGS;
6762 return;
6763 }
6764
6765 if ((Rn = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
6766 return;
6767
6768 if (Rs != Rd)
6769 {
6770 inst.error = _("dest and source1 must be the same register");
6771 return;
6772 }
6773 Rs = Rn;
6774 }
6775
6776 if (inst.instruction == T_OPCODE_MUL
6777 && Rs == Rd)
6778 as_tsktsk (_("Rs and Rd must be different in MUL"));
6779
6780 inst.instruction |= Rd | (Rs << 3);
6781 end_of_line (str);
6782}
6783
6784static void
6785do_t_add (str)
6786 char * str;
6787{
6788 thumb_add_sub (str, 0);
6789}
6790
6791static void
6792do_t_asr (str)
6793 char * str;
6794{
6795 thumb_shift (str, THUMB_ASR);
6796}
6797
6798static void
6799do_t_branch9 (str)
6800 char * str;
6801{
6802 if (my_get_expression (&inst.reloc.exp, &str))
6803 return;
6804 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
6805 inst.reloc.pc_rel = 1;
6806 end_of_line (str);
6807}
6808
6809static void
6810do_t_branch12 (str)
6811 char * str;
6812{
6813 if (my_get_expression (&inst.reloc.exp, &str))
6814 return;
6815 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
6816 inst.reloc.pc_rel = 1;
6817 end_of_line (str);
6818}
6819
6820/* Find the real, Thumb encoded start of a Thumb function. */
6821
6822static symbolS *
6823find_real_start (symbolP)
6824 symbolS * symbolP;
6825{
6826 char * real_start;
6827 const char * name = S_GET_NAME (symbolP);
6828 symbolS * new_target;
6829
6830 /* This definiton must agree with the one in gcc/config/arm/thumb.c. */
6831#define STUB_NAME ".real_start_of"
6832
6833 if (name == NULL)
6834 abort ();
6835
6836 /* Names that start with '.' are local labels, not function entry points.
6837 The compiler may generate BL instructions to these labels because it
6838 needs to perform a branch to a far away location. */
6839 if (name[0] == '.')
6840 return symbolP;
6841
6842 real_start = malloc (strlen (name) + strlen (STUB_NAME) + 1);
6843 sprintf (real_start, "%s%s", STUB_NAME, name);
6844
6845 new_target = symbol_find (real_start);
6846
6847 if (new_target == NULL)
6848 {
6849 as_warn ("Failed to find real start of function: %s\n", name);
6850 new_target = symbolP;
6851 }
6852
6853 free (real_start);
6854
6855 return new_target;
6856}
6857
6858static void
6859do_t_branch23 (str)
6860 char * str;
6861{
6862 if (my_get_expression (& inst.reloc.exp, & str))
6863 return;
6864
6865 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
6866 inst.reloc.pc_rel = 1;
6867 end_of_line (str);
6868
6869 /* If the destination of the branch is a defined symbol which does not have
6870 the THUMB_FUNC attribute, then we must be calling a function which has
6871 the (interfacearm) attribute. We look for the Thumb entry point to that
6872 function and change the branch to refer to that function instead. */
6873 if ( inst.reloc.exp.X_op == O_symbol
6874 && inst.reloc.exp.X_add_symbol != NULL
6875 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
6876 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
6877 inst.reloc.exp.X_add_symbol =
6878 find_real_start (inst.reloc.exp.X_add_symbol);
6879}
6880
6881static void
6882do_t_bx (str)
6883 char * str;
6884{
6885 int reg;
6886
6887 skip_whitespace (str);
6888
6889 if ((reg = thumb_reg (&str, THUMB_REG_ANY)) == FAIL)
6890 return;
6891
6892 /* This sets THUMB_H2 from the top bit of reg. */
6893 inst.instruction |= reg << 3;
6894
6895 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
6896 should cause the alignment to be checked once it is known. This is
6897 because BX PC only works if the instruction is word aligned. */
6898
6899 end_of_line (str);
6900}
6901
6902static void
6903do_t_compare (str)
6904 char * str;
6905{
6906 thumb_mov_compare (str, THUMB_COMPARE);
6907}
6908
6909static void
6910do_t_ldmstm (str)
6911 char * str;
6912{
6913 int Rb;
6914 long range;
6915
6916 skip_whitespace (str);
6917
6918 if ((Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL)
6919 return;
6920
6921 if (*str != '!')
6922 as_warn (_("Inserted missing '!': load/store multiple always writes back base register"));
6923 else
6924 str++;
6925
6926 if (skip_past_comma (&str) == FAIL
6927 || (range = reg_list (&str)) == FAIL)
6928 {
6929 if (! inst.error)
6930 inst.error = BAD_ARGS;
6931 return;
6932 }
6933
6934 if (inst.reloc.type != BFD_RELOC_NONE)
6935 {
6936 /* This really doesn't seem worth it. */
6937 inst.reloc.type = BFD_RELOC_NONE;
6938 inst.error = _("Expression too complex");
6939 return;
6940 }
6941
6942 if (range & ~0xff)
6943 {
6944 inst.error = _("only lo-regs valid in load/store multiple");
6945 return;
6946 }
6947
6948 inst.instruction |= (Rb << 8) | range;
6949 end_of_line (str);
6950}
6951
6952static void
6953do_t_ldr (str)
6954 char * str;
6955{
6956 thumb_load_store (str, THUMB_LOAD, THUMB_WORD);
6957}
6958
6959static void
6960do_t_ldrb (str)
6961 char * str;
6962{
6963 thumb_load_store (str, THUMB_LOAD, THUMB_BYTE);
6964}
6965
6966static void
6967do_t_ldrh (str)
6968 char * str;
6969{
6970 thumb_load_store (str, THUMB_LOAD, THUMB_HALFWORD);
6971}
6972
6973static void
6974do_t_lds (str)
6975 char * str;
6976{
6977 int Rd, Rb, Ro;
6978
6979 skip_whitespace (str);
6980
6981 if ((Rd = thumb_reg (&str, THUMB_REG_LO)) == FAIL
6982 || skip_past_comma (&str) == FAIL
6983 || *str++ != '['
6984 || (Rb = thumb_reg (&str, THUMB_REG_LO)) == FAIL
6985 || skip_past_comma (&str) == FAIL
6986 || (Ro = thumb_reg (&str, THUMB_REG_LO)) == FAIL
6987 || *str++ != ']')
6988 {
6989 if (! inst.error)
6990 inst.error = _("Syntax: ldrs[b] Rd, [Rb, Ro]");
6991 return;
6992 }
6993
6994 inst.instruction |= Rd | (Rb << 3) | (Ro << 6);
6995 end_of_line (str);
6996}
6997
6998static void
6999do_t_lsl (str)
7000 char * str;
7001{
7002 thumb_shift (str, THUMB_LSL);
7003}
7004
7005static void
7006do_t_lsr (str)
7007 char * str;
7008{
7009 thumb_shift (str, THUMB_LSR);
7010}
7011
7012static void
7013do_t_mov (str)
7014 char * str;
7015{
7016 thumb_mov_compare (str, THUMB_MOVE);
7017}
7018
7019static void
7020do_t_push_pop (str)
7021 char * str;
7022{
7023 long range;
7024
7025 skip_whitespace (str);
7026
7027 if ((range = reg_list (&str)) == FAIL)
7028 {
7029 if (! inst.error)
7030 inst.error = BAD_ARGS;
7031 return;
7032 }
7033
7034 if (inst.reloc.type != BFD_RELOC_NONE)
7035 {
7036 /* This really doesn't seem worth it. */
7037 inst.reloc.type = BFD_RELOC_NONE;
7038 inst.error = _("Expression too complex");
7039 return;
7040 }
7041
7042 if (range & ~0xff)
7043 {
7044 if ((inst.instruction == T_OPCODE_PUSH
7045 && (range & ~0xff) == 1 << REG_LR)
7046 || (inst.instruction == T_OPCODE_POP
7047 && (range & ~0xff) == 1 << REG_PC))
7048 {
7049 inst.instruction |= THUMB_PP_PC_LR;
7050 range &= 0xff;
7051 }
7052 else
7053 {
7054 inst.error = _("invalid register list to push/pop instruction");
7055 return;
7056 }
7057 }
7058
7059 inst.instruction |= range;
7060 end_of_line (str);
7061}
7062
7063static void
7064do_t_str (str)
7065 char * str;
7066{
7067 thumb_load_store (str, THUMB_STORE, THUMB_WORD);
7068}
7069
7070static void
7071do_t_strb (str)
7072 char * str;
7073{
7074 thumb_load_store (str, THUMB_STORE, THUMB_BYTE);
7075}
7076
7077static void
7078do_t_strh (str)
7079 char * str;
7080{
7081 thumb_load_store (str, THUMB_STORE, THUMB_HALFWORD);
7082}
7083
7084static void
7085do_t_sub (str)
7086 char * str;
7087{
7088 thumb_add_sub (str, 1);
7089}
7090
7091static void
7092do_t_swi (str)
7093 char * str;
7094{
7095 skip_whitespace (str);
7096
7097 if (my_get_expression (&inst.reloc.exp, &str))
7098 return;
7099
7100 inst.reloc.type = BFD_RELOC_ARM_SWI;
7101 end_of_line (str);
7102 return;
7103}
7104
7105static void
7106do_t_adr (str)
7107 char * str;
7108{
7109 int reg;
7110
7111 /* This is a pseudo-op of the form "adr rd, label" to be converted
7112 into a relative address of the form "add rd, pc, #label-.-4". */
7113 skip_whitespace (str);
7114
7115 /* Store Rd in temporary location inside instruction. */
7116 if ((reg = reg_required_here (&str, 4)) == FAIL
7117 || (reg > 7) /* For Thumb reg must be r0..r7. */
7118 || skip_past_comma (&str) == FAIL
7119 || my_get_expression (&inst.reloc.exp, &str))
7120 {
7121 if (!inst.error)
7122 inst.error = BAD_ARGS;
7123 return;
7124 }
7125
7126 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
7127 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
7128 inst.reloc.pc_rel = 1;
7129 inst.instruction |= REG_PC; /* Rd is already placed into the instruction. */
7130
7131 end_of_line (str);
7132}
7133
7134static void
7135insert_reg (entry)
7136 int entry;
7137{
7138 int len = strlen (reg_table[entry].name) + 2;
7139 char * buf = (char *) xmalloc (len);
7140 char * buf2 = (char *) xmalloc (len);
7141 int i = 0;
7142
7143#ifdef REGISTER_PREFIX
7144 buf[i++] = REGISTER_PREFIX;
7145#endif
7146
7147 strcpy (buf + i, reg_table[entry].name);
7148
7149 for (i = 0; buf[i]; i++)
3882b010 7150 buf2[i] = TOUPPER (buf[i]);
b99bd4ef
NC
7151
7152 buf2[i] = '\0';
7153
7154 hash_insert (arm_reg_hsh, buf, (PTR) & reg_table[entry]);
7155 hash_insert (arm_reg_hsh, buf2, (PTR) & reg_table[entry]);
7156}
7157
7158static void
7159insert_reg_alias (str, regnum)
7160 char *str;
7161 int regnum;
7162{
7163 struct reg_entry *new =
7164 (struct reg_entry *) xmalloc (sizeof (struct reg_entry));
7165 char *name = xmalloc (strlen (str) + 1);
7166 strcpy (name, str);
7167
7168 new->name = name;
7169 new->number = regnum;
7170
7171 hash_insert (arm_reg_hsh, name, (PTR) new);
7172}
7173
7174static void
7175set_constant_flonums ()
7176{
7177 int i;
7178
7179 for (i = 0; i < NUM_FLOAT_VALS; i++)
7180 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
7181 abort ();
7182}
7183
7184void
7185md_begin ()
7186{
7187 unsigned mach;
7188 unsigned int i;
7189
7190 if ( (arm_ops_hsh = hash_new ()) == NULL
7191 || (arm_tops_hsh = hash_new ()) == NULL
7192 || (arm_cond_hsh = hash_new ()) == NULL
7193 || (arm_shift_hsh = hash_new ()) == NULL
7194 || (arm_reg_hsh = hash_new ()) == NULL
7195 || (arm_psr_hsh = hash_new ()) == NULL)
7196 as_fatal (_("Virtual memory exhausted"));
7197
7198 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
7199 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
7200 for (i = 0; i < sizeof (tinsns) / sizeof (struct thumb_opcode); i++)
7201 hash_insert (arm_tops_hsh, tinsns[i].template, (PTR) (tinsns + i));
7202 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
7203 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
7204 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
7205 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
7206 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
7207 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
7208
7209 for (i = 0; reg_table[i].name; i++)
7210 insert_reg (i);
7211
7212 set_constant_flonums ();
7213
7214#if defined OBJ_COFF || defined OBJ_ELF
7215 {
7216 unsigned int flags = 0;
7217
7218 /* Set the flags in the private structure. */
7219 if (uses_apcs_26) flags |= F_APCS26;
7220 if (support_interwork) flags |= F_INTERWORK;
7221 if (uses_apcs_float) flags |= F_APCS_FLOAT;
7222 if (pic_code) flags |= F_PIC;
7223 if ((cpu_variant & FPU_ALL) == FPU_NONE) flags |= F_SOFT_FLOAT;
7224
7225 bfd_set_private_flags (stdoutput, flags);
7226
7227 /* We have run out flags in the COFF header to encode the
7228 status of ATPCS support, so instead we create a dummy,
7229 empty, debug section called .arm.atpcs. */
7230 if (atpcs)
7231 {
7232 asection * sec;
7233
7234 sec = bfd_make_section (stdoutput, ".arm.atpcs");
7235
7236 if (sec != NULL)
7237 {
7238 bfd_set_section_flags
7239 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
7240 bfd_set_section_size (stdoutput, sec, 0);
7241 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
7242 }
7243 }
7244 }
7245#endif
7246
7247 /* Record the CPU type as well. */
7248 switch (cpu_variant & ARM_CPU_MASK)
7249 {
7250 case ARM_2:
7251 mach = bfd_mach_arm_2;
7252 break;
7253
7254 case ARM_3: /* Also ARM_250. */
7255 mach = bfd_mach_arm_2a;
7256 break;
7257
7258 default:
7259 case ARM_6 | ARM_3 | ARM_2: /* Actually no CPU type defined. */
7260 mach = bfd_mach_arm_4;
7261 break;
7262
7263 case ARM_7: /* Also ARM_6. */
7264 mach = bfd_mach_arm_3;
7265 break;
7266 }
7267
7268 /* Catch special cases. */
7269 if (cpu_variant & ARM_EXT_XSCALE)
7270 mach = bfd_mach_arm_XScale;
7271 else if (cpu_variant & ARM_EXT_V5E)
7272 mach = bfd_mach_arm_5TE;
7273 else if (cpu_variant & ARM_EXT_V5)
7274 {
7275 if (cpu_variant & ARM_EXT_THUMB)
7276 mach = bfd_mach_arm_5T;
7277 else
7278 mach = bfd_mach_arm_5;
7279 }
7280 else if (cpu_variant & ARM_EXT_HALFWORD)
7281 {
7282 if (cpu_variant & ARM_EXT_THUMB)
7283 mach = bfd_mach_arm_4T;
7284 else
7285 mach = bfd_mach_arm_4;
7286 }
7287 else if (cpu_variant & ARM_EXT_LONGMUL)
7288 mach = bfd_mach_arm_3M;
7289
7290 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
7291}
7292
7293/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
7294 for use in the a.out file, and stores them in the array pointed to by buf.
7295 This knows about the endian-ness of the target machine and does
7296 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
7297 2 (short) and 4 (long) Floating numbers are put out as a series of
7298 LITTLENUMS (shorts, here at least). */
7299
7300void
7301md_number_to_chars (buf, val, n)
7302 char * buf;
7303 valueT val;
7304 int n;
7305{
7306 if (target_big_endian)
7307 number_to_chars_bigendian (buf, val, n);
7308 else
7309 number_to_chars_littleendian (buf, val, n);
7310}
7311
7312static valueT
7313md_chars_to_number (buf, n)
7314 char * buf;
7315 int n;
7316{
7317 valueT result = 0;
7318 unsigned char * where = (unsigned char *) buf;
7319
7320 if (target_big_endian)
7321 {
7322 while (n--)
7323 {
7324 result <<= 8;
7325 result |= (*where++ & 255);
7326 }
7327 }
7328 else
7329 {
7330 while (n--)
7331 {
7332 result <<= 8;
7333 result |= (where[n] & 255);
7334 }
7335 }
7336
7337 return result;
7338}
7339
7340/* Turn a string in input_line_pointer into a floating point constant
7341 of type TYPE, and store the appropriate bytes in *LITP. The number
7342 of LITTLENUMS emitted is stored in *SIZEP. An error message is
7343 returned, or NULL on OK.
7344
7345 Note that fp constants aren't represent in the normal way on the ARM.
7346 In big endian mode, things are as expected. However, in little endian
7347 mode fp constants are big-endian word-wise, and little-endian byte-wise
7348 within the words. For example, (double) 1.1 in big endian mode is
7349 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
7350 the byte sequence 99 99 f1 3f 9a 99 99 99.
7351
7352 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
7353
7354char *
7355md_atof (type, litP, sizeP)
7356 char type;
7357 char * litP;
7358 int * sizeP;
7359{
7360 int prec;
7361 LITTLENUM_TYPE words[MAX_LITTLENUMS];
7362 char *t;
7363 int i;
7364
7365 switch (type)
7366 {
7367 case 'f':
7368 case 'F':
7369 case 's':
7370 case 'S':
7371 prec = 2;
7372 break;
7373
7374 case 'd':
7375 case 'D':
7376 case 'r':
7377 case 'R':
7378 prec = 4;
7379 break;
7380
7381 case 'x':
7382 case 'X':
7383 prec = 6;
7384 break;
7385
7386 case 'p':
7387 case 'P':
7388 prec = 6;
7389 break;
7390
7391 default:
7392 *sizeP = 0;
7393 return _("Bad call to MD_ATOF()");
7394 }
7395
7396 t = atof_ieee (input_line_pointer, type, words);
7397 if (t)
7398 input_line_pointer = t;
7399 *sizeP = prec * 2;
7400
7401 if (target_big_endian)
7402 {
7403 for (i = 0; i < prec; i++)
7404 {
7405 md_number_to_chars (litP, (valueT) words[i], 2);
7406 litP += 2;
7407 }
7408 }
7409 else
7410 {
7411 /* For a 4 byte float the order of elements in `words' is 1 0. For an
7412 8 byte float the order is 1 0 3 2. */
7413 for (i = 0; i < prec; i += 2)
7414 {
7415 md_number_to_chars (litP, (valueT) words[i + 1], 2);
7416 md_number_to_chars (litP + 2, (valueT) words[i], 2);
7417 litP += 4;
7418 }
7419 }
7420
7421 return 0;
7422}
7423
7424/* The knowledge of the PC's pipeline offset is built into the insns
7425 themselves. */
7426
7427long
7428md_pcrel_from (fixP)
7429 fixS * fixP;
7430{
7431 if (fixP->fx_addsy
7432 && S_GET_SEGMENT (fixP->fx_addsy) == undefined_section
7433 && fixP->fx_subsy == NULL)
7434 return 0;
7435
7436 if (fixP->fx_pcrel && (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_ADD))
7437 {
7438 /* PC relative addressing on the Thumb is slightly odd
7439 as the bottom two bits of the PC are forced to zero
7440 for the calculation. */
7441 return (fixP->fx_where + fixP->fx_frag->fr_address) & ~3;
7442 }
7443
7444#ifdef TE_WINCE
7445 /* The pattern was adjusted to accomodate CE's off-by-one fixups,
7446 so we un-adjust here to compensate for the accomodation. */
7447 return fixP->fx_where + fixP->fx_frag->fr_address + 8;
7448#else
7449 return fixP->fx_where + fixP->fx_frag->fr_address;
7450#endif
7451}
7452
7453/* Round up a section size to the appropriate boundary. */
7454
7455valueT
7456md_section_align (segment, size)
7457 segT segment ATTRIBUTE_UNUSED;
7458 valueT size;
7459{
7460#ifdef OBJ_ELF
7461 return size;
7462#else
7463 /* Round all sects to multiple of 4. */
7464 return (size + 3) & ~3;
7465#endif
7466}
7467
7468/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
7469 Otherwise we have no need to default values of symbols. */
7470
7471symbolS *
7472md_undefined_symbol (name)
7473 char * name ATTRIBUTE_UNUSED;
7474{
7475#ifdef OBJ_ELF
7476 if (name[0] == '_' && name[1] == 'G'
7477 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
7478 {
7479 if (!GOT_symbol)
7480 {
7481 if (symbol_find (name))
7482 as_bad ("GOT already in the symbol table");
7483
7484 GOT_symbol = symbol_new (name, undefined_section,
7485 (valueT) 0, & zero_address_frag);
7486 }
7487
7488 return GOT_symbol;
7489 }
7490#endif
7491
7492 return 0;
7493}
7494
7495/* arm_reg_parse () := if it looks like a register, return its token and
7496 advance the pointer. */
7497
7498static int
7499arm_reg_parse (ccp)
7500 register char ** ccp;
7501{
7502 char * start = * ccp;
7503 char c;
7504 char * p;
7505 struct reg_entry * reg;
7506
7507#ifdef REGISTER_PREFIX
7508 if (*start != REGISTER_PREFIX)
7509 return FAIL;
7510 p = start + 1;
7511#else
7512 p = start;
7513#ifdef OPTIONAL_REGISTER_PREFIX
7514 if (*p == OPTIONAL_REGISTER_PREFIX)
7515 p++, start++;
7516#endif
7517#endif
3882b010 7518 if (!ISALPHA (*p) || !is_name_beginner (*p))
b99bd4ef
NC
7519 return FAIL;
7520
7521 c = *p++;
3882b010 7522 while (ISALPHA (c) || ISDIGIT (c) || c == '_')
b99bd4ef
NC
7523 c = *p++;
7524
7525 *--p = 0;
7526 reg = (struct reg_entry *) hash_find (arm_reg_hsh, start);
7527 *p = c;
7528
7529 if (reg)
7530 {
7531 *ccp = p;
7532 return reg->number;
7533 }
7534
7535 return FAIL;
7536}
7537
7538int
7539md_apply_fix3 (fixP, val, seg)
7540 fixS * fixP;
7541 valueT * val;
7542 segT seg;
7543{
7544 offsetT value = * val;
7545 offsetT newval;
7546 unsigned int newimm;
7547 unsigned long temp;
7548 int sign;
7549 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
7550 arm_fix_data * arm_data = (arm_fix_data *) fixP->tc_fix_data;
7551
7552 assert (fixP->fx_r_type < BFD_RELOC_UNUSED);
7553
7554 /* Note whether this will delete the relocation. */
7555#if 0
7556 /* Patch from REarnshaw to JDavis (disabled for the moment, since it
7557 doesn't work fully.) */
7558 if ((fixP->fx_addsy == 0 || symbol_constant_p (fixP->fx_addsy))
7559 && !fixP->fx_pcrel)
7560#else
7561 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
7562#endif
7563 fixP->fx_done = 1;
7564
7565 /* If this symbol is in a different section then we need to leave it for
7566 the linker to deal with. Unfortunately, md_pcrel_from can't tell,
7567 so we have to undo it's effects here. */
7568 if (fixP->fx_pcrel)
7569 {
7570 if (fixP->fx_addsy != NULL
7571 && S_IS_DEFINED (fixP->fx_addsy)
7572 && S_GET_SEGMENT (fixP->fx_addsy) != seg)
7573 {
7574 if (target_oabi
7575 && (fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
7576 || fixP->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
7577 ))
7578 value = 0;
7579 else
7580 value += md_pcrel_from (fixP);
7581 }
7582 }
7583
7584 /* Remember value for emit_reloc. */
7585 fixP->fx_addnumber = value;
7586
7587 switch (fixP->fx_r_type)
7588 {
7589 case BFD_RELOC_ARM_IMMEDIATE:
7590 newimm = validate_immediate (value);
7591 temp = md_chars_to_number (buf, INSN_SIZE);
7592
7593 /* If the instruction will fail, see if we can fix things up by
7594 changing the opcode. */
7595 if (newimm == (unsigned int) FAIL
7596 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
7597 {
7598 as_bad_where (fixP->fx_file, fixP->fx_line,
7599 _("invalid constant (%lx) after fixup"),
7600 (unsigned long) value);
7601 break;
7602 }
7603
7604 newimm |= (temp & 0xfffff000);
7605 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
7606 break;
7607
7608 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
7609 {
7610 unsigned int highpart = 0;
7611 unsigned int newinsn = 0xe1a00000; /* nop. */
7612 newimm = validate_immediate (value);
7613 temp = md_chars_to_number (buf, INSN_SIZE);
7614
7615 /* If the instruction will fail, see if we can fix things up by
7616 changing the opcode. */
7617 if (newimm == (unsigned int) FAIL
7618 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
7619 {
7620 /* No ? OK - try using two ADD instructions to generate
7621 the value. */
7622 newimm = validate_immediate_twopart (value, & highpart);
7623
7624 /* Yes - then make sure that the second instruction is
7625 also an add. */
7626 if (newimm != (unsigned int) FAIL)
7627 newinsn = temp;
7628 /* Still No ? Try using a negated value. */
7629 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
7630 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
7631 /* Otherwise - give up. */
7632 else
7633 {
7634 as_bad_where (fixP->fx_file, fixP->fx_line,
7635 _("Unable to compute ADRL instructions for PC offset of 0x%lx"),
7636 value);
7637 break;
7638 }
7639
7640 /* Replace the first operand in the 2nd instruction (which
7641 is the PC) with the destination register. We have
7642 already added in the PC in the first instruction and we
7643 do not want to do it again. */
7644 newinsn &= ~ 0xf0000;
7645 newinsn |= ((newinsn & 0x0f000) << 4);
7646 }
7647
7648 newimm |= (temp & 0xfffff000);
7649 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
7650
7651 highpart |= (newinsn & 0xfffff000);
7652 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
7653 }
7654 break;
7655
7656 case BFD_RELOC_ARM_OFFSET_IMM:
7657 sign = value >= 0;
7658
7659 if (value < 0)
7660 value = - value;
7661
7662 if (validate_offset_imm (value, 0) == FAIL)
7663 {
7664 as_bad_where (fixP->fx_file, fixP->fx_line,
7665 _("bad immediate value for offset (%ld)"),
7666 (long) value);
7667 break;
7668 }
7669
7670 newval = md_chars_to_number (buf, INSN_SIZE);
7671 newval &= 0xff7ff000;
7672 newval |= value | (sign ? INDEX_UP : 0);
7673 md_number_to_chars (buf, newval, INSN_SIZE);
7674 break;
7675
7676 case BFD_RELOC_ARM_OFFSET_IMM8:
7677 case BFD_RELOC_ARM_HWLITERAL:
7678 sign = value >= 0;
7679
7680 if (value < 0)
7681 value = - value;
7682
7683 if (validate_offset_imm (value, 1) == FAIL)
7684 {
7685 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
7686 as_bad_where (fixP->fx_file, fixP->fx_line,
7687 _("invalid literal constant: pool needs to be closer"));
7688 else
7689 as_bad (_("bad immediate value for half-word offset (%ld)"),
7690 (long) value);
7691 break;
7692 }
7693
7694 newval = md_chars_to_number (buf, INSN_SIZE);
7695 newval &= 0xff7ff0f0;
7696 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
7697 md_number_to_chars (buf, newval, INSN_SIZE);
7698 break;
7699
7700 case BFD_RELOC_ARM_LITERAL:
7701 sign = value >= 0;
7702
7703 if (value < 0)
7704 value = - value;
7705
7706 if (validate_offset_imm (value, 0) == FAIL)
7707 {
7708 as_bad_where (fixP->fx_file, fixP->fx_line,
7709 _("invalid literal constant: pool needs to be closer"));
7710 break;
7711 }
7712
7713 newval = md_chars_to_number (buf, INSN_SIZE);
7714 newval &= 0xff7ff000;
7715 newval |= value | (sign ? INDEX_UP : 0);
7716 md_number_to_chars (buf, newval, INSN_SIZE);
7717 break;
7718
7719 case BFD_RELOC_ARM_SHIFT_IMM:
7720 newval = md_chars_to_number (buf, INSN_SIZE);
7721 if (((unsigned long) value) > 32
7722 || (value == 32
7723 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
7724 {
7725 as_bad_where (fixP->fx_file, fixP->fx_line,
7726 _("shift expression is too large"));
7727 break;
7728 }
7729
7730 if (value == 0)
7731 /* Shifts of zero must be done as lsl. */
7732 newval &= ~0x60;
7733 else if (value == 32)
7734 value = 0;
7735 newval &= 0xfffff07f;
7736 newval |= (value & 0x1f) << 7;
7737 md_number_to_chars (buf, newval, INSN_SIZE);
7738 break;
7739
7740 case BFD_RELOC_ARM_SWI:
7741 if (arm_data->thumb_mode)
7742 {
7743 if (((unsigned long) value) > 0xff)
7744 as_bad_where (fixP->fx_file, fixP->fx_line,
7745 _("Invalid swi expression"));
7746 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xff00;
7747 newval |= value;
7748 md_number_to_chars (buf, newval, THUMB_SIZE);
7749 }
7750 else
7751 {
7752 if (((unsigned long) value) > 0x00ffffff)
7753 as_bad_where (fixP->fx_file, fixP->fx_line,
7754 _("Invalid swi expression"));
7755 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff000000;
7756 newval |= value;
7757 md_number_to_chars (buf, newval, INSN_SIZE);
7758 }
7759 break;
7760
7761 case BFD_RELOC_ARM_MULTI:
7762 if (((unsigned long) value) > 0xffff)
7763 as_bad_where (fixP->fx_file, fixP->fx_line,
7764 _("Invalid expression in load/store multiple"));
7765 newval = value | md_chars_to_number (buf, INSN_SIZE);
7766 md_number_to_chars (buf, newval, INSN_SIZE);
7767 break;
7768
7769 case BFD_RELOC_ARM_PCREL_BRANCH:
7770 newval = md_chars_to_number (buf, INSN_SIZE);
7771
7772 /* Sign-extend a 24-bit number. */
7773#define SEXT24(x) ((((x) & 0xffffff) ^ (~ 0x7fffff)) + 0x800000)
7774
7775#ifdef OBJ_ELF
7776 if (! target_oabi)
7777 value = fixP->fx_offset;
7778#endif
7779
7780 /* We are going to store value (shifted right by two) in the
7781 instruction, in a 24 bit, signed field. Thus we need to check
7782 that none of the top 8 bits of the shifted value (top 7 bits of
7783 the unshifted, unsigned value) are set, or that they are all set. */
7784 if ((value & ~ ((offsetT) 0x1ffffff)) != 0
7785 && ((value & ~ ((offsetT) 0x1ffffff)) != ~ ((offsetT) 0x1ffffff)))
7786 {
7787#ifdef OBJ_ELF
7788 /* Normally we would be stuck at this point, since we cannot store
7789 the absolute address that is the destination of the branch in the
7790 24 bits of the branch instruction. If however, we happen to know
7791 that the destination of the branch is in the same section as the
7792 branch instruciton itself, then we can compute the relocation for
7793 ourselves and not have to bother the linker with it.
7794
7795 FIXME: The tests for OBJ_ELF and ! target_oabi are only here
7796 because I have not worked out how to do this for OBJ_COFF or
7797 target_oabi. */
7798 if (! target_oabi
7799 && fixP->fx_addsy != NULL
7800 && S_IS_DEFINED (fixP->fx_addsy)
7801 && S_GET_SEGMENT (fixP->fx_addsy) == seg)
7802 {
7803 /* Get pc relative value to go into the branch. */
7804 value = * val;
7805
7806 /* Permit a backward branch provided that enough bits
7807 are set. Allow a forwards branch, provided that
7808 enough bits are clear. */
7809 if ( (value & ~ ((offsetT) 0x1ffffff)) == ~ ((offsetT) 0x1ffffff)
7810 || (value & ~ ((offsetT) 0x1ffffff)) == 0)
7811 fixP->fx_done = 1;
7812 }
7813
7814 if (! fixP->fx_done)
7815#endif
7816 as_bad_where (fixP->fx_file, fixP->fx_line,
7817 _("gas can't handle same-section branch dest >= 0x04000000"));
7818 }
7819
7820 value >>= 2;
7821 value += SEXT24 (newval);
7822
7823 if ( (value & ~ ((offsetT) 0xffffff)) != 0
7824 && ((value & ~ ((offsetT) 0xffffff)) != ~ ((offsetT) 0xffffff)))
7825 as_bad_where (fixP->fx_file, fixP->fx_line,
7826 _("out of range branch"));
7827
7828 newval = (value & 0x00ffffff) | (newval & 0xff000000);
7829 md_number_to_chars (buf, newval, INSN_SIZE);
7830 break;
7831
7832 case BFD_RELOC_ARM_PCREL_BLX:
7833 {
7834 offsetT hbit;
7835 newval = md_chars_to_number (buf, INSN_SIZE);
7836
7837#ifdef OBJ_ELF
7838 if (! target_oabi)
7839 value = fixP->fx_offset;
7840#endif
7841 hbit = (value >> 1) & 1;
7842 value = (value >> 2) & 0x00ffffff;
7843 value = (value + (newval & 0x00ffffff)) & 0x00ffffff;
7844 newval = value | (newval & 0xfe000000) | (hbit << 24);
7845 md_number_to_chars (buf, newval, INSN_SIZE);
7846 }
7847 break;
7848
7849 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
7850 newval = md_chars_to_number (buf, THUMB_SIZE);
7851 {
7852 addressT diff = (newval & 0xff) << 1;
7853 if (diff & 0x100)
7854 diff |= ~0xff;
7855
7856 value += diff;
7857 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
7858 as_bad_where (fixP->fx_file, fixP->fx_line,
7859 _("Branch out of range"));
7860 newval = (newval & 0xff00) | ((value & 0x1ff) >> 1);
7861 }
7862 md_number_to_chars (buf, newval, THUMB_SIZE);
7863 break;
7864
7865 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
7866 newval = md_chars_to_number (buf, THUMB_SIZE);
7867 {
7868 addressT diff = (newval & 0x7ff) << 1;
7869 if (diff & 0x800)
7870 diff |= ~0x7ff;
7871
7872 value += diff;
7873 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
7874 as_bad_where (fixP->fx_file, fixP->fx_line,
7875 _("Branch out of range"));
7876 newval = (newval & 0xf800) | ((value & 0xfff) >> 1);
7877 }
7878 md_number_to_chars (buf, newval, THUMB_SIZE);
7879 break;
7880
7881 case BFD_RELOC_THUMB_PCREL_BLX:
7882 case BFD_RELOC_THUMB_PCREL_BRANCH23:
7883 {
7884 offsetT newval2;
7885 addressT diff;
7886
7887 newval = md_chars_to_number (buf, THUMB_SIZE);
7888 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
7889 diff = ((newval & 0x7ff) << 12) | ((newval2 & 0x7ff) << 1);
7890 if (diff & 0x400000)
7891 diff |= ~0x3fffff;
7892#ifdef OBJ_ELF
7893 value = fixP->fx_offset;
7894#endif
7895 value += diff;
7896 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
7897 as_bad_where (fixP->fx_file, fixP->fx_line,
7898 _("Branch with link out of range"));
7899
7900 newval = (newval & 0xf800) | ((value & 0x7fffff) >> 12);
7901 newval2 = (newval2 & 0xf800) | ((value & 0xfff) >> 1);
7902 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
7903 /* Remove bit zero of the adjusted offset. Bit zero can only be
7904 set if the upper insn is at a half-word boundary, since the
7905 destination address, an ARM instruction, must always be on a
7906 word boundary. The semantics of the BLX (1) instruction, however,
7907 are that bit zero in the offset must always be zero, and the
7908 corresponding bit one in the target address will be set from bit
7909 one of the source address. */
7910 newval2 &= ~1;
7911 md_number_to_chars (buf, newval, THUMB_SIZE);
7912 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
7913 }
7914 break;
7915
7916 case BFD_RELOC_8:
7917 if (fixP->fx_done || fixP->fx_pcrel)
7918 md_number_to_chars (buf, value, 1);
7919#ifdef OBJ_ELF
7920 else if (!target_oabi)
7921 {
7922 value = fixP->fx_offset;
7923 md_number_to_chars (buf, value, 1);
7924 }
7925#endif
7926 break;
7927
7928 case BFD_RELOC_16:
7929 if (fixP->fx_done || fixP->fx_pcrel)
7930 md_number_to_chars (buf, value, 2);
7931#ifdef OBJ_ELF
7932 else if (!target_oabi)
7933 {
7934 value = fixP->fx_offset;
7935 md_number_to_chars (buf, value, 2);
7936 }
7937#endif
7938 break;
7939
7940#ifdef OBJ_ELF
7941 case BFD_RELOC_ARM_GOT32:
7942 case BFD_RELOC_ARM_GOTOFF:
7943 md_number_to_chars (buf, 0, 4);
7944 break;
7945#endif
7946
7947 case BFD_RELOC_RVA:
7948 case BFD_RELOC_32:
7949 if (fixP->fx_done || fixP->fx_pcrel)
7950 md_number_to_chars (buf, value, 4);
7951#ifdef OBJ_ELF
7952 else if (!target_oabi)
7953 {
7954 value = fixP->fx_offset;
7955 md_number_to_chars (buf, value, 4);
7956 }
7957#endif
7958 break;
7959
7960#ifdef OBJ_ELF
7961 case BFD_RELOC_ARM_PLT32:
7962 /* It appears the instruction is fully prepared at this point. */
7963 break;
7964#endif
7965
7966 case BFD_RELOC_ARM_GOTPC:
7967 md_number_to_chars (buf, value, 4);
7968 break;
7969
7970 case BFD_RELOC_ARM_CP_OFF_IMM:
7971 sign = value >= 0;
7972 if (value < -1023 || value > 1023 || (value & 3))
7973 as_bad_where (fixP->fx_file, fixP->fx_line,
7974 _("Illegal value for co-processor offset"));
7975 if (value < 0)
7976 value = -value;
7977 newval = md_chars_to_number (buf, INSN_SIZE) & 0xff7fff00;
7978 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
7979 md_number_to_chars (buf, newval, INSN_SIZE);
7980 break;
7981
7982 case BFD_RELOC_ARM_THUMB_OFFSET:
7983 newval = md_chars_to_number (buf, THUMB_SIZE);
7984 /* Exactly what ranges, and where the offset is inserted depends
7985 on the type of instruction, we can establish this from the
7986 top 4 bits. */
7987 switch (newval >> 12)
7988 {
7989 case 4: /* PC load. */
7990 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
7991 forced to zero for these loads, so we will need to round
7992 up the offset if the instruction address is not word
7993 aligned (since the final address produced must be, and
7994 we can only describe word-aligned immediate offsets). */
7995
7996 if ((fixP->fx_frag->fr_address + fixP->fx_where + value) & 3)
7997 as_bad_where (fixP->fx_file, fixP->fx_line,
7998 _("Invalid offset, target not word aligned (0x%08X)"),
7999 (unsigned int) (fixP->fx_frag->fr_address
8000 + fixP->fx_where + value));
8001
8002 if ((value + 2) & ~0x3fe)
8003 as_bad_where (fixP->fx_file, fixP->fx_line,
8004 _("Invalid offset, value too big (0x%08lX)"), value);
8005
8006 /* Round up, since pc will be rounded down. */
8007 newval |= (value + 2) >> 2;
8008 break;
8009
8010 case 9: /* SP load/store. */
8011 if (value & ~0x3fc)
8012 as_bad_where (fixP->fx_file, fixP->fx_line,
8013 _("Invalid offset, value too big (0x%08lX)"), value);
8014 newval |= value >> 2;
8015 break;
8016
8017 case 6: /* Word load/store. */
8018 if (value & ~0x7c)
8019 as_bad_where (fixP->fx_file, fixP->fx_line,
8020 _("Invalid offset, value too big (0x%08lX)"), value);
8021 newval |= value << 4; /* 6 - 2. */
8022 break;
8023
8024 case 7: /* Byte load/store. */
8025 if (value & ~0x1f)
8026 as_bad_where (fixP->fx_file, fixP->fx_line,
8027 _("Invalid offset, value too big (0x%08lX)"), value);
8028 newval |= value << 6;
8029 break;
8030
8031 case 8: /* Halfword load/store. */
8032 if (value & ~0x3e)
8033 as_bad_where (fixP->fx_file, fixP->fx_line,
8034 _("Invalid offset, value too big (0x%08lX)"), value);
8035 newval |= value << 5; /* 6 - 1. */
8036 break;
8037
8038 default:
8039 as_bad_where (fixP->fx_file, fixP->fx_line,
8040 "Unable to process relocation for thumb opcode: %lx",
8041 (unsigned long) newval);
8042 break;
8043 }
8044 md_number_to_chars (buf, newval, THUMB_SIZE);
8045 break;
8046
8047 case BFD_RELOC_ARM_THUMB_ADD:
8048 /* This is a complicated relocation, since we use it for all of
8049 the following immediate relocations:
8050
8051 3bit ADD/SUB
8052 8bit ADD/SUB
8053 9bit ADD/SUB SP word-aligned
8054 10bit ADD PC/SP word-aligned
8055
8056 The type of instruction being processed is encoded in the
8057 instruction field:
8058
8059 0x8000 SUB
8060 0x00F0 Rd
8061 0x000F Rs
8062 */
8063 newval = md_chars_to_number (buf, THUMB_SIZE);
8064 {
8065 int rd = (newval >> 4) & 0xf;
8066 int rs = newval & 0xf;
8067 int subtract = newval & 0x8000;
8068
8069 if (rd == REG_SP)
8070 {
8071 if (value & ~0x1fc)
8072 as_bad_where (fixP->fx_file, fixP->fx_line,
8073 _("Invalid immediate for stack address calculation"));
8074 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
8075 newval |= value >> 2;
8076 }
8077 else if (rs == REG_PC || rs == REG_SP)
8078 {
8079 if (subtract ||
8080 value & ~0x3fc)
8081 as_bad_where (fixP->fx_file, fixP->fx_line,
8082 _("Invalid immediate for address calculation (value = 0x%08lX)"),
8083 (unsigned long) value);
8084 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
8085 newval |= rd << 8;
8086 newval |= value >> 2;
8087 }
8088 else if (rs == rd)
8089 {
8090 if (value & ~0xff)
8091 as_bad_where (fixP->fx_file, fixP->fx_line,
8092 _("Invalid 8bit immediate"));
8093 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
8094 newval |= (rd << 8) | value;
8095 }
8096 else
8097 {
8098 if (value & ~0x7)
8099 as_bad_where (fixP->fx_file, fixP->fx_line,
8100 _("Invalid 3bit immediate"));
8101 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
8102 newval |= rd | (rs << 3) | (value << 6);
8103 }
8104 }
8105 md_number_to_chars (buf, newval, THUMB_SIZE);
8106 break;
8107
8108 case BFD_RELOC_ARM_THUMB_IMM:
8109 newval = md_chars_to_number (buf, THUMB_SIZE);
8110 switch (newval >> 11)
8111 {
8112 case 0x04: /* 8bit immediate MOV. */
8113 case 0x05: /* 8bit immediate CMP. */
8114 if (value < 0 || value > 255)
8115 as_bad_where (fixP->fx_file, fixP->fx_line,
8116 _("Invalid immediate: %ld is too large"),
8117 (long) value);
8118 newval |= value;
8119 break;
8120
8121 default:
8122 abort ();
8123 }
8124 md_number_to_chars (buf, newval, THUMB_SIZE);
8125 break;
8126
8127 case BFD_RELOC_ARM_THUMB_SHIFT:
8128 /* 5bit shift value (0..31). */
8129 if (value < 0 || value > 31)
8130 as_bad_where (fixP->fx_file, fixP->fx_line,
8131 _("Illegal Thumb shift value: %ld"), (long) value);
8132 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf03f;
8133 newval |= value << 6;
8134 md_number_to_chars (buf, newval, THUMB_SIZE);
8135 break;
8136
8137 case BFD_RELOC_VTABLE_INHERIT:
8138 case BFD_RELOC_VTABLE_ENTRY:
8139 fixP->fx_done = 0;
8140 return 1;
8141
8142 case BFD_RELOC_NONE:
8143 default:
8144 as_bad_where (fixP->fx_file, fixP->fx_line,
8145 _("Bad relocation fixup type (%d)"), fixP->fx_r_type);
8146 }
8147
8148 return 1;
8149}
8150
8151/* Translate internal representation of relocation info to BFD target
8152 format. */
8153
8154arelent *
8155tc_gen_reloc (section, fixp)
8156 asection * section ATTRIBUTE_UNUSED;
8157 fixS * fixp;
8158{
8159 arelent * reloc;
8160 bfd_reloc_code_real_type code;
8161
8162 reloc = (arelent *) xmalloc (sizeof (arelent));
8163
8164 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
8165 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
8166 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
8167
8168 /* @@ Why fx_addnumber sometimes and fx_offset other times? */
8169#ifndef OBJ_ELF
8170 if (fixp->fx_pcrel == 0)
8171 reloc->addend = fixp->fx_offset;
8172 else
8173 reloc->addend = fixp->fx_offset = reloc->address;
8174#else /* OBJ_ELF */
8175 reloc->addend = fixp->fx_offset;
8176#endif
8177
8178 switch (fixp->fx_r_type)
8179 {
8180 case BFD_RELOC_8:
8181 if (fixp->fx_pcrel)
8182 {
8183 code = BFD_RELOC_8_PCREL;
8184 break;
8185 }
8186
8187 case BFD_RELOC_16:
8188 if (fixp->fx_pcrel)
8189 {
8190 code = BFD_RELOC_16_PCREL;
8191 break;
8192 }
8193
8194 case BFD_RELOC_32:
8195 if (fixp->fx_pcrel)
8196 {
8197 code = BFD_RELOC_32_PCREL;
8198 break;
8199 }
8200
8201 case BFD_RELOC_ARM_PCREL_BRANCH:
8202 case BFD_RELOC_ARM_PCREL_BLX:
8203 case BFD_RELOC_RVA:
8204 case BFD_RELOC_THUMB_PCREL_BRANCH9:
8205 case BFD_RELOC_THUMB_PCREL_BRANCH12:
8206 case BFD_RELOC_THUMB_PCREL_BRANCH23:
8207 case BFD_RELOC_THUMB_PCREL_BLX:
8208 case BFD_RELOC_VTABLE_ENTRY:
8209 case BFD_RELOC_VTABLE_INHERIT:
8210 code = fixp->fx_r_type;
8211 break;
8212
8213 case BFD_RELOC_ARM_LITERAL:
8214 case BFD_RELOC_ARM_HWLITERAL:
8215 /* If this is called then the a literal has been referenced across
8216 a section boundary - possibly due to an implicit dump. */
8217 as_bad_where (fixp->fx_file, fixp->fx_line,
8218 _("Literal referenced across section boundary (Implicit dump?)"));
8219 return NULL;
8220
8221#ifdef OBJ_ELF
8222 case BFD_RELOC_ARM_GOT32:
8223 case BFD_RELOC_ARM_GOTOFF:
8224 case BFD_RELOC_ARM_PLT32:
8225 code = fixp->fx_r_type;
8226 break;
8227#endif
8228
8229 case BFD_RELOC_ARM_IMMEDIATE:
8230 as_bad_where (fixp->fx_file, fixp->fx_line,
8231 _("Internal_relocation (type %d) not fixed up (IMMEDIATE)"),
8232 fixp->fx_r_type);
8233 return NULL;
8234
8235 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
8236 as_bad_where (fixp->fx_file, fixp->fx_line,
8237 _("ADRL used for a symbol not defined in the same file"));
8238 return NULL;
8239
8240 case BFD_RELOC_ARM_OFFSET_IMM:
8241 as_bad_where (fixp->fx_file, fixp->fx_line,
8242 _("Internal_relocation (type %d) not fixed up (OFFSET_IMM)"),
8243 fixp->fx_r_type);
8244 return NULL;
8245
8246 default:
8247 {
8248 char * type;
8249
8250 switch (fixp->fx_r_type)
8251 {
8252 case BFD_RELOC_ARM_IMMEDIATE: type = "IMMEDIATE"; break;
8253 case BFD_RELOC_ARM_OFFSET_IMM: type = "OFFSET_IMM"; break;
8254 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
8255 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
8256 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
8257 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
8258 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
8259 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
8260 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
8261 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
8262 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
8263 default: type = _("<unknown>"); break;
8264 }
8265 as_bad_where (fixp->fx_file, fixp->fx_line,
8266 _("Cannot represent %s relocation in this object file format"),
8267 type);
8268 return NULL;
8269 }
8270 }
8271
8272#ifdef OBJ_ELF
8273 if (code == BFD_RELOC_32_PCREL
8274 && GOT_symbol
8275 && fixp->fx_addsy == GOT_symbol)
8276 {
8277 code = BFD_RELOC_ARM_GOTPC;
8278 reloc->addend = fixp->fx_offset = reloc->address;
8279 }
8280#endif
8281
8282 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
8283
8284 if (reloc->howto == NULL)
8285 {
8286 as_bad_where (fixp->fx_file, fixp->fx_line,
8287 _("Can not represent %s relocation in this object file format"),
8288 bfd_get_reloc_code_name (code));
8289 return NULL;
8290 }
8291
8292 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
8293 vtable entry to be used in the relocation's section offset. */
8294 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
8295 reloc->address = fixp->fx_offset;
8296
8297 return reloc;
8298}
8299
8300int
8301md_estimate_size_before_relax (fragP, segtype)
8302 fragS * fragP ATTRIBUTE_UNUSED;
8303 segT segtype ATTRIBUTE_UNUSED;
8304{
8305 as_fatal (_("md_estimate_size_before_relax\n"));
8306 return 1;
8307}
8308
8309static void
8310output_inst PARAMS ((void))
8311{
8312 char * to = NULL;
8313
8314 if (inst.error)
8315 {
8316 as_bad (inst.error);
8317 return;
8318 }
8319
8320 to = frag_more (inst.size);
8321
8322 if (thumb_mode && (inst.size > THUMB_SIZE))
8323 {
8324 assert (inst.size == (2 * THUMB_SIZE));
8325 md_number_to_chars (to, inst.instruction >> 16, THUMB_SIZE);
8326 md_number_to_chars (to + THUMB_SIZE, inst.instruction, THUMB_SIZE);
8327 }
8328 else if (inst.size > INSN_SIZE)
8329 {
8330 assert (inst.size == (2 * INSN_SIZE));
8331 md_number_to_chars (to, inst.instruction, INSN_SIZE);
8332 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
8333 }
8334 else
8335 md_number_to_chars (to, inst.instruction, inst.size);
8336
8337 if (inst.reloc.type != BFD_RELOC_NONE)
8338 fix_new_arm (frag_now, to - frag_now->fr_literal,
8339 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
8340 inst.reloc.type);
8341
8342#ifdef OBJ_ELF
8343 dwarf2_emit_insn (inst.size);
8344#endif
8345}
8346
8347void
8348md_assemble (str)
8349 char * str;
8350{
8351 char c;
8352 char * p;
8353 char * q;
8354 char * start;
8355
8356 /* Align the instruction.
8357 This may not be the right thing to do but ... */
8358#if 0
8359 arm_align (2, 0);
8360#endif
8361 listing_prev_line (); /* Defined in listing.h. */
8362
8363 /* Align the previous label if needed. */
8364 if (last_label_seen != NULL)
8365 {
8366 symbol_set_frag (last_label_seen, frag_now);
8367 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
8368 S_SET_SEGMENT (last_label_seen, now_seg);
8369 }
8370
8371 memset (&inst, '\0', sizeof (inst));
8372 inst.reloc.type = BFD_RELOC_NONE;
8373
8374 skip_whitespace (str);
8375
8376 /* Scan up to the end of the op-code, which must end in white space or
8377 end of string. */
8378 for (start = p = str; *p != '\0'; p++)
8379 if (*p == ' ')
8380 break;
8381
8382 if (p == str)
8383 {
8384 as_bad (_("No operator -- statement `%s'\n"), str);
8385 return;
8386 }
8387
8388 if (thumb_mode)
8389 {
8390 CONST struct thumb_opcode * opcode;
8391
8392 c = *p;
8393 *p = '\0';
8394 opcode = (CONST struct thumb_opcode *) hash_find (arm_tops_hsh, str);
8395 *p = c;
8396
8397 if (opcode)
8398 {
8399 /* Check that this instruction is supported for this CPU. */
8400 if (thumb_mode == 1 && (opcode->variants & cpu_variant) == 0)
8401 {
8402 as_bad (_("selected processor does not support this opcode"));
8403 return;
8404 }
8405
8406 inst.instruction = opcode->value;
8407 inst.size = opcode->size;
8408 (*opcode->parms) (p);
8409 output_inst ();
8410 return;
8411 }
8412 }
8413 else
8414 {
8415 CONST struct asm_opcode * opcode;
8416 unsigned long cond_code;
8417
8418 inst.size = INSN_SIZE;
8419 /* P now points to the end of the opcode, probably white space, but we
8420 have to break the opcode up in case it contains condionals and flags;
8421 keep trying with progressively smaller basic instructions until one
8422 matches, or we run out of opcode. */
8423 q = (p - str > LONGEST_INST) ? str + LONGEST_INST : p;
8424
8425 for (; q != str; q--)
8426 {
8427 c = *q;
8428 *q = '\0';
8429
8430 opcode = (CONST struct asm_opcode *) hash_find (arm_ops_hsh, str);
8431 *q = c;
8432
8433 if (opcode && opcode->template)
8434 {
8435 unsigned long flag_bits = 0;
8436 char * r;
8437
8438 /* Check that this instruction is supported for this CPU. */
8439 if ((opcode->variants & cpu_variant) == 0)
8440 goto try_shorter;
8441
8442 inst.instruction = opcode->value;
8443 if (q == p) /* Just a simple opcode. */
8444 {
8445 if (opcode->comp_suffix)
8446 {
8447 if (*opcode->comp_suffix != '\0')
8448 as_bad (_("Opcode `%s' must have suffix from list: <%s>"),
8449 str, opcode->comp_suffix);
8450 else
8451 /* Not a conditional instruction. */
8452 (*opcode->parms) (q, 0);
8453 }
8454 else
8455 {
8456 /* A conditional instruction with default condition. */
8457 inst.instruction |= COND_ALWAYS;
8458 (*opcode->parms) (q, 0);
8459 }
8460 output_inst ();
8461 return;
8462 }
8463
8464 /* Not just a simple opcode. Check if extra is a
8465 conditional. */
8466 r = q;
8467 if (p - r >= 2)
8468 {
8469 CONST struct asm_cond *cond;
8470 char d = *(r + 2);
8471
8472 *(r + 2) = '\0';
8473 cond = (CONST struct asm_cond *) hash_find (arm_cond_hsh, r);
8474 *(r + 2) = d;
8475 if (cond)
8476 {
8477 if (cond->value == 0xf0000000)
8478 as_tsktsk (
8479_("Warning: Use of the 'nv' conditional is deprecated\n"));
8480
8481 cond_code = cond->value;
8482 r += 2;
8483 }
8484 else
8485 cond_code = COND_ALWAYS;
8486 }
8487 else
8488 cond_code = COND_ALWAYS;
8489
8490 /* Apply the conditional, or complain it's not allowed. */
8491 if (opcode->comp_suffix && *opcode->comp_suffix == '\0')
8492 {
8493 /* Instruction isn't conditional. */
8494 if (cond_code != COND_ALWAYS)
8495 {
8496 as_bad (_("Opcode `%s' is unconditional\n"), str);
8497 return;
8498 }
8499 }
8500 else
8501 /* Instruction is conditional: set the condition into it. */
8502 inst.instruction |= cond_code;
8503
8504 /* If there is a compulsory suffix, it should come here
8505 before any optional flags. */
8506 if (opcode->comp_suffix && *opcode->comp_suffix != '\0')
8507 {
8508 CONST char *s = opcode->comp_suffix;
8509
8510 while (*s)
8511 {
8512 inst.suffix++;
8513 if (*r == *s)
8514 break;
8515 s++;
8516 }
8517
8518 if (*s == '\0')
8519 {
8520 as_bad (_("Opcode `%s' must have suffix from <%s>\n"),
8521 str, opcode->comp_suffix);
8522 return;
8523 }
8524
8525 r++;
8526 }
8527
8528 /* The remainder, if any should now be flags for the instruction;
8529 Scan these checking each one found with the opcode. */
8530 if (r != p)
8531 {
8532 char d;
8533 CONST struct asm_flg *flag = opcode->flags;
8534
8535 if (flag)
8536 {
8537 int flagno;
8538
8539 d = *p;
8540 *p = '\0';
8541
8542 for (flagno = 0; flag[flagno].template; flagno++)
8543 {
8544 if (streq (r, flag[flagno].template))
8545 {
8546 flag_bits |= flag[flagno].set_bits;
8547 break;
8548 }
8549 }
8550
8551 *p = d;
8552 if (! flag[flagno].template)
8553 goto try_shorter;
8554 }
8555 else
8556 goto try_shorter;
8557 }
8558
8559 (*opcode->parms) (p, flag_bits);
8560 output_inst ();
8561 return;
8562 }
8563
8564 try_shorter:
8565 ;
8566 }
8567 }
8568
8569 /* It wasn't an instruction, but it might be a register alias of the form
8570 alias .req reg. */
8571 q = p;
8572 skip_whitespace (q);
8573
8574 c = *p;
8575 *p = '\0';
8576
8577 if (*q && !strncmp (q, ".req ", 4))
8578 {
8579 int reg;
8580 char * copy_of_str;
8581 char * r;
8582
8583#ifdef IGNORE_OPCODE_CASE
8584 str = original_case_string;
8585#endif
8586 copy_of_str = str;
8587
8588 q += 4;
8589 skip_whitespace (q);
8590
8591 for (r = q; *r != '\0'; r++)
8592 if (*r == ' ')
8593 break;
8594
8595 if (r != q)
8596 {
8597 int regnum;
8598 char d = *r;
8599
8600 *r = '\0';
8601 regnum = arm_reg_parse (& q);
8602 *r = d;
8603
8604 reg = arm_reg_parse (& str);
8605
8606 if (reg == FAIL)
8607 {
8608 if (regnum != FAIL)
8609 insert_reg_alias (str, regnum);
8610 else
8611 as_warn (_("register '%s' does not exist\n"), q);
8612 }
8613 else if (regnum != FAIL)
8614 {
8615 if (reg != regnum)
8616 as_warn (_("ignoring redefinition of register alias '%s'"),
8617 copy_of_str);
8618
8619 /* Do not warn about redefinitions to the same alias. */
8620 }
8621 else
8622 as_warn (_("ignoring redefinition of register alias '%s' to non-existant register '%s'"),
8623 copy_of_str, q);
8624 }
8625 else
8626 as_warn (_("ignoring incomplete .req pseuso op"));
8627
8628 *p = c;
8629 return;
8630 }
8631
8632 *p = c;
8633 as_bad (_("bad instruction `%s'"), start);
8634}
8635
8636/* md_parse_option
8637 Invocation line includes a switch not recognized by the base assembler.
8638 See if it's a processor-specific option. These are:
8639 Cpu variants, the arm part is optional:
8640 -m[arm]1 Currently not supported.
8641 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
8642 -m[arm]3 Arm 3 processor
8643 -m[arm]6[xx], Arm 6 processors
8644 -m[arm]7[xx][t][[d]m] Arm 7 processors
8645 -m[arm]8[10] Arm 8 processors
8646 -m[arm]9[20][tdmi] Arm 9 processors
404ff6b5 8647 -marm9e Allow Cirrus/DSP instructions
b99bd4ef
NC
8648 -mstrongarm[110[0]] StrongARM processors
8649 -mxscale XScale processors
8650 -m[arm]v[2345[t[e]]] Arm architectures
8651 -mall All (except the ARM1)
8652 FP variants:
8653 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
8654 -mfpe-old (No float load/store multiples)
8655 -mno-fpu Disable all floating point instructions
8656 Run-time endian selection:
8657 -EB big endian cpu
8658 -EL little endian cpu
8659 ARM Procedure Calling Standard:
8660 -mapcs-32 32 bit APCS
8661 -mapcs-26 26 bit APCS
8662 -mapcs-float Pass floats in float regs
8663 -mapcs-reentrant Position independent code
8664 -mthumb-interwork Code supports Arm/Thumb interworking
8665 -matpcs ARM/Thumb Procedure Call Standard
8666 -moabi Old ELF ABI */
8667
8668CONST char * md_shortopts = "m:k";
8669
8670struct option md_longopts[] =
8671{
8672#ifdef ARM_BI_ENDIAN
8673#define OPTION_EB (OPTION_MD_BASE + 0)
8674 {"EB", no_argument, NULL, OPTION_EB},
8675#define OPTION_EL (OPTION_MD_BASE + 1)
8676 {"EL", no_argument, NULL, OPTION_EL},
8677#ifdef OBJ_ELF
8678#define OPTION_OABI (OPTION_MD_BASE +2)
8679 {"oabi", no_argument, NULL, OPTION_OABI},
8680#endif
8681#endif
8682 {NULL, no_argument, NULL, 0}
8683};
8684
8685size_t md_longopts_size = sizeof (md_longopts);
8686
8687int
8688md_parse_option (c, arg)
8689 int c;
8690 char * arg;
8691{
8692 char * str = arg;
8693
8694 switch (c)
8695 {
8696#ifdef ARM_BI_ENDIAN
8697 case OPTION_EB:
8698 target_big_endian = 1;
8699 break;
8700 case OPTION_EL:
8701 target_big_endian = 0;
8702 break;
8703#endif
8704
8705 case 'm':
8706 switch (*str)
8707 {
8708 case 'f':
8709 if (streq (str, "fpa10"))
8710 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA10;
8711 else if (streq (str, "fpa11"))
8712 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_FPA11;
8713 else if (streq (str, "fpe-old"))
8714 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_CORE;
8715 else
8716 goto bad;
8717 break;
8718
8719 case 'n':
8720 if (streq (str, "no-fpu"))
8721 cpu_variant &= ~FPU_ALL;
8722 break;
8723
8724#ifdef OBJ_ELF
8725 case 'o':
8726 if (streq (str, "oabi"))
8727 target_oabi = true;
8728 break;
8729#endif
8730
8731 case 't':
8732 /* Limit assembler to generating only Thumb instructions: */
8733 if (streq (str, "thumb"))
8734 {
8735 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_EXT_THUMB;
8736 cpu_variant = (cpu_variant & ~FPU_ALL) | FPU_NONE;
8737 thumb_mode = 1;
8738 }
8739 else if (streq (str, "thumb-interwork"))
8740 {
8741 if ((cpu_variant & ARM_EXT_THUMB) == 0)
8742 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_ARCH_V4T;
8743#if defined OBJ_COFF || defined OBJ_ELF
8744 support_interwork = true;
8745#endif
8746 }
8747 else
8748 goto bad;
8749 break;
8750
8751 default:
8752 if (streq (str, "all"))
8753 {
8754 cpu_variant = ARM_ALL | FPU_ALL;
8755 return 1;
8756 }
8757#if defined OBJ_COFF || defined OBJ_ELF
8758 if (! strncmp (str, "apcs-", 5))
8759 {
8760 /* GCC passes on all command line options starting "-mapcs-..."
8761 to us, so we must parse them here. */
8762
8763 str += 5;
8764
8765 if (streq (str, "32"))
8766 {
8767 uses_apcs_26 = false;
8768 return 1;
8769 }
8770 else if (streq (str, "26"))
8771 {
8772 uses_apcs_26 = true;
8773 return 1;
8774 }
8775 else if (streq (str, "frame"))
8776 {
8777 /* Stack frames are being generated - does not affect
8778 linkage of code. */
8779 return 1;
8780 }
8781 else if (streq (str, "stack-check"))
8782 {
8783 /* Stack checking is being performed - does not affect
8784 linkage, but does require that the functions
8785 __rt_stkovf_split_small and __rt_stkovf_split_big be
8786 present in the final link. */
8787
8788 return 1;
8789 }
8790 else if (streq (str, "float"))
8791 {
8792 /* Floating point arguments are being passed in the floating
8793 point registers. This does affect linking, since this
8794 version of the APCS is incompatible with the version that
8795 passes floating points in the integer registers. */
8796
8797 uses_apcs_float = true;
8798 return 1;
8799 }
8800 else if (streq (str, "reentrant"))
8801 {
8802 /* Reentrant code has been generated. This does affect
8803 linking, since there is no point in linking reentrant/
8804 position independent code with absolute position code. */
8805 pic_code = true;
8806 return 1;
8807 }
8808
8809 as_bad (_("Unrecognised APCS switch -m%s"), arg);
8810 return 0;
8811 }
8812
8813 if (! strcmp (str, "atpcs"))
8814 {
8815 atpcs = true;
8816 return 1;
8817 }
8818#endif
8819 /* Strip off optional "arm". */
8820 if (! strncmp (str, "arm", 3))
8821 str += 3;
8822
8823 switch (*str)
8824 {
8825 case '1':
8826 if (streq (str, "1"))
8827 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_1;
8828 else
8829 goto bad;
8830 break;
8831
8832 case '2':
8833 if (streq (str, "2"))
8834 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
8835 else if (streq (str, "250"))
8836 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_250;
8837 else
8838 goto bad;
8839 break;
8840
8841 case '3':
8842 if (streq (str, "3"))
8843 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
8844 else
8845 goto bad;
8846 break;
8847
8848 case '6':
8849 switch (strtol (str, NULL, 10))
8850 {
8851 case 6:
8852 case 60:
8853 case 600:
8854 case 610:
8855 case 620:
8856 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_6;
8857 break;
8858 default:
8859 goto bad;
8860 }
8861 break;
8862
8863 case '7':
8864 /* Eat the processor name. */
8865 switch (strtol (str, & str, 10))
8866 {
8867 case 7:
8868 case 70:
8869 case 700:
8870 case 710:
8871 case 720:
8872 case 7100:
8873 case 7500:
8874 break;
8875 default:
8876 goto bad;
8877 }
8878 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
8879 for (; *str; str++)
8880 {
8881 switch (*str)
8882 {
8883 case 't':
8884 cpu_variant |= ARM_ARCH_V4T;
8885 break;
8886
8887 case 'm':
8888 cpu_variant |= ARM_EXT_LONGMUL;
8889 break;
8890
8891 case 'f': /* fe => fp enabled cpu. */
8892 if (str[1] == 'e')
8893 ++ str;
8894 else
8895 goto bad;
8896
8897 case 'c': /* Left over from 710c processor name. */
8898 case 'd': /* Debug. */
8899 case 'i': /* Embedded ICE. */
8900 /* Included for completeness in ARM processor naming. */
8901 break;
8902
8903 default:
8904 goto bad;
8905 }
8906 }
8907 break;
8908
8909 case '8':
8910 if (streq (str, "8") || streq (str, "810"))
8911 cpu_variant = (cpu_variant & ~ARM_ANY)
8912 | ARM_8 | ARM_ARCH_V4;
8913 else
8914 goto bad;
8915 break;
8916
8917 case '9':
8918 if (streq (str, "9"))
8919 cpu_variant = (cpu_variant & ~ARM_ANY)
8920 | ARM_9 | ARM_ARCH_V4T;
8921 else if (streq (str, "920"))
8922 cpu_variant = (cpu_variant & ~ARM_ANY)
8923 | ARM_9 | ARM_ARCH_V4;
8924 else if (streq (str, "920t"))
8925 cpu_variant = (cpu_variant & ~ARM_ANY)
8926 | ARM_9 | ARM_ARCH_V4T;
8927 else if (streq (str, "9tdmi"))
8928 cpu_variant = (cpu_variant & ~ARM_ANY)
8929 | ARM_9 | ARM_ARCH_V4T;
404ff6b5
AH
8930 else if (streq (str, "9e"))
8931 cpu_variant = (cpu_variant & ~ARM_ANY)
8932 | ARM_9 | ARM_ARCH_V4T | ARM_EXT_MAVERIK;
b99bd4ef
NC
8933 else
8934 goto bad;
8935 break;
8936
8937 case 's':
8938 if (streq (str, "strongarm")
8939 || streq (str, "strongarm110")
8940 || streq (str, "strongarm1100"))
8941 cpu_variant = (cpu_variant & ~ARM_ANY)
8942 | ARM_8 | ARM_ARCH_V4;
8943 else
8944 goto bad;
8945 break;
8946
8947 case 'x':
8948 if (streq (str, "xscale"))
8949 cpu_variant = ARM_9 | ARM_ARCH_XSCALE;
8950 else
8951 goto bad;
8952 break;
8953
8954 case 'v':
8955 /* Select variant based on architecture rather than
8956 processor. */
8957 switch (*++str)
8958 {
8959 case '2':
8960 switch (*++str)
8961 {
8962 case 'a':
8963 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_3;
8964 break;
8965 case 0:
8966 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_2;
8967 break;
8968 default:
8969 as_bad (_("Invalid architecture variant -m%s"), arg);
8970 break;
8971 }
8972 break;
8973
8974 case '3':
8975 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7;
8976
8977 switch (*++str)
8978 {
8979 case 'm': cpu_variant |= ARM_EXT_LONGMUL; break;
8980 case 0: break;
8981 default:
8982 as_bad (_("Invalid architecture variant -m%s"), arg);
8983 break;
8984 }
8985 break;
8986
8987 case '4':
8988 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_7 | ARM_ARCH_V4;
8989
8990 switch (*++str)
8991 {
8992 case 't': cpu_variant |= ARM_EXT_THUMB; break;
8993 case 0: break;
8994 default:
8995 as_bad (_("Invalid architecture variant -m%s"), arg);
8996 break;
8997 }
8998 break;
8999
9000 case '5':
9001 cpu_variant = (cpu_variant & ~ARM_ANY) | ARM_9 | ARM_ARCH_V5;
9002 switch (*++str)
9003 {
9004 case 't': cpu_variant |= ARM_EXT_THUMB; break;
9005 case 'e': cpu_variant |= ARM_EXT_V5E; break;
9006 case 0: break;
9007 default:
9008 as_bad (_("Invalid architecture variant -m%s"), arg);
9009 break;
9010 }
9011 break;
9012
9013 default:
9014 as_bad (_("Invalid architecture variant -m%s"), arg);
9015 break;
9016 }
9017 break;
9018
9019 default:
9020 bad:
9021 as_bad (_("Invalid processor variant -m%s"), arg);
9022 return 0;
9023 }
9024 }
9025 break;
9026
9027#if defined OBJ_ELF || defined OBJ_COFF
9028 case 'k':
9029 pic_code = 1;
9030 break;
9031#endif
9032
9033 default:
9034 return 0;
9035 }
9036
9037 return 1;
9038}
9039
9040void
9041md_show_usage (fp)
9042 FILE * fp;
9043{
9044 fprintf (fp, _("\
9045 ARM Specific Assembler Options:\n\
9046 -m[arm][<processor name>] select processor variant\n\
9047 -m[arm]v[2|2a|3|3m|4|4t|5[t][e]] select architecture variant\n\
404ff6b5 9048 -marm9e allow Cirrus/DSP instructions\n\
b99bd4ef
NC
9049 -mthumb only allow Thumb instructions\n\
9050 -mthumb-interwork mark the assembled code as supporting interworking\n\
9051 -mall allow any instruction\n\
9052 -mfpa10, -mfpa11 select floating point architecture\n\
9053 -mfpe-old don't allow floating-point multiple instructions\n\
9054 -mno-fpu don't allow any floating-point instructions.\n\
9055 -k generate PIC code.\n"));
9056#if defined OBJ_COFF || defined OBJ_ELF
9057 fprintf (fp, _("\
9058 -mapcs-32, -mapcs-26 specify which ARM Procedure Calling Standard to use\n\
9059 -matpcs use ARM/Thumb Procedure Calling Standard\n\
9060 -mapcs-float floating point args are passed in FP regs\n\
9061 -mapcs-reentrant the code is position independent/reentrant\n"));
9062#endif
9063#ifdef OBJ_ELF
9064 fprintf (fp, _("\
9065 -moabi support the old ELF ABI\n"));
9066#endif
9067#ifdef ARM_BI_ENDIAN
9068 fprintf (fp, _("\
9069 -EB assemble code for a big endian cpu\n\
9070 -EL assemble code for a little endian cpu\n"));
9071#endif
9072}
9073
9074/* We need to be able to fix up arbitrary expressions in some statements.
9075 This is so that we can handle symbols that are an arbitrary distance from
9076 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
9077 which returns part of an address in a form which will be valid for
9078 a data instruction. We do this by pushing the expression into a symbol
9079 in the expr_section, and creating a fix for that. */
9080
9081static void
9082fix_new_arm (frag, where, size, exp, pc_rel, reloc)
9083 fragS * frag;
9084 int where;
9085 short int size;
9086 expressionS * exp;
9087 int pc_rel;
9088 int reloc;
9089{
9090 fixS * new_fix;
9091 arm_fix_data * arm_data;
9092
9093 switch (exp->X_op)
9094 {
9095 case O_constant:
9096 case O_symbol:
9097 case O_add:
9098 case O_subtract:
9099 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
9100 break;
9101
9102 default:
9103 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
9104 pc_rel, reloc);
9105 break;
9106 }
9107
9108 /* Mark whether the fix is to a THUMB instruction, or an ARM
9109 instruction. */
9110 arm_data = (arm_fix_data *) obstack_alloc (& notes, sizeof (arm_fix_data));
9111 new_fix->tc_fix_data = (PTR) arm_data;
9112 arm_data->thumb_mode = thumb_mode;
9113
9114 return;
9115}
9116
9117/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
9118
9119void
9120cons_fix_new_arm (frag, where, size, exp)
9121 fragS * frag;
9122 int where;
9123 int size;
9124 expressionS * exp;
9125{
9126 bfd_reloc_code_real_type type;
9127 int pcrel = 0;
9128
9129 /* Pick a reloc.
9130 FIXME: @@ Should look at CPU word size. */
9131 switch (size)
9132 {
9133 case 1:
9134 type = BFD_RELOC_8;
9135 break;
9136 case 2:
9137 type = BFD_RELOC_16;
9138 break;
9139 case 4:
9140 default:
9141 type = BFD_RELOC_32;
9142 break;
9143 case 8:
9144 type = BFD_RELOC_64;
9145 break;
9146 }
9147
9148 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
9149}
9150
9151/* A good place to do this, although this was probably not intended
9152 for this kind of use. We need to dump the literal pool before
9153 references are made to a null symbol pointer. */
9154
9155void
9156arm_cleanup ()
9157{
9158 if (current_poolP == NULL)
9159 return;
9160
9161 /* Put it at the end of text section. */
9162 subseg_set (text_section, 0);
9163 s_ltorg (0);
9164 listing_prev_line ();
9165}
9166
9167void
9168arm_start_line_hook ()
9169{
9170 last_label_seen = NULL;
9171}
9172
9173void
9174arm_frob_label (sym)
9175 symbolS * sym;
9176{
9177 last_label_seen = sym;
9178
9179 ARM_SET_THUMB (sym, thumb_mode);
9180
9181#if defined OBJ_COFF || defined OBJ_ELF
9182 ARM_SET_INTERWORK (sym, support_interwork);
9183#endif
9184
9185 /* Note - do not allow local symbols (.Lxxx) to be labeled
9186 as Thumb functions. This is because these labels, whilst
9187 they exist inside Thumb code, are not the entry points for
9188 possible ARM->Thumb calls. Also, these labels can be used
9189 as part of a computed goto or switch statement. eg gcc
9190 can generate code that looks like this:
9191
9192 ldr r2, [pc, .Laaa]
9193 lsl r3, r3, #2
9194 ldr r2, [r3, r2]
9195 mov pc, r2
9196
9197 .Lbbb: .word .Lxxx
9198 .Lccc: .word .Lyyy
9199 ..etc...
9200 .Laaa: .word Lbbb
9201
9202 The first instruction loads the address of the jump table.
9203 The second instruction converts a table index into a byte offset.
9204 The third instruction gets the jump address out of the table.
9205 The fourth instruction performs the jump.
9206
9207 If the address stored at .Laaa is that of a symbol which has the
9208 Thumb_Func bit set, then the linker will arrange for this address
9209 to have the bottom bit set, which in turn would mean that the
9210 address computation performed by the third instruction would end
9211 up with the bottom bit set. Since the ARM is capable of unaligned
9212 word loads, the instruction would then load the incorrect address
9213 out of the jump table, and chaos would ensue. */
9214 if (label_is_thumb_function_name
9215 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
9216 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
9217 {
9218 /* When the address of a Thumb function is taken the bottom
9219 bit of that address should be set. This will allow
9220 interworking between Arm and Thumb functions to work
9221 correctly. */
9222
9223 THUMB_SET_FUNC (sym, 1);
9224
9225 label_is_thumb_function_name = false;
9226 }
9227}
9228
9229/* Adjust the symbol table. This marks Thumb symbols as distinct from
9230 ARM ones. */
9231
9232void
9233arm_adjust_symtab ()
9234{
9235#ifdef OBJ_COFF
9236 symbolS * sym;
9237
9238 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
9239 {
9240 if (ARM_IS_THUMB (sym))
9241 {
9242 if (THUMB_IS_FUNC (sym))
9243 {
9244 /* Mark the symbol as a Thumb function. */
9245 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
9246 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
9247 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
9248
9249 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
9250 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
9251 else
9252 as_bad (_("%s: unexpected function type: %d"),
9253 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
9254 }
9255 else switch (S_GET_STORAGE_CLASS (sym))
9256 {
9257 case C_EXT:
9258 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
9259 break;
9260 case C_STAT:
9261 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
9262 break;
9263 case C_LABEL:
9264 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
9265 break;
9266 default:
9267 /* Do nothing. */
9268 break;
9269 }
9270 }
9271
9272 if (ARM_IS_INTERWORK (sym))
9273 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
9274 }
9275#endif
9276#ifdef OBJ_ELF
9277 symbolS * sym;
9278 char bind;
9279
9280 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
9281 {
9282 if (ARM_IS_THUMB (sym))
9283 {
9284 elf_symbol_type * elf_sym;
9285
9286 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
9287 bind = ELF_ST_BIND (elf_sym);
9288
9289 /* If it's a .thumb_func, declare it as so,
9290 otherwise tag label as .code 16. */
9291 if (THUMB_IS_FUNC (sym))
9292 elf_sym->internal_elf_sym.st_info =
9293 ELF_ST_INFO (bind, STT_ARM_TFUNC);
9294 else
9295 elf_sym->internal_elf_sym.st_info =
9296 ELF_ST_INFO (bind, STT_ARM_16BIT);
9297 }
9298 }
9299#endif
9300}
9301
9302int
9303arm_data_in_code ()
9304{
9305 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
9306 {
9307 *input_line_pointer = '/';
9308 input_line_pointer += 5;
9309 *input_line_pointer = 0;
9310 return 1;
9311 }
9312
9313 return 0;
9314}
9315
9316char *
9317arm_canonicalize_symbol_name (name)
9318 char * name;
9319{
9320 int len;
9321
9322 if (thumb_mode && (len = strlen (name)) > 5
9323 && streq (name + len - 5, "/data"))
9324 *(name + len - 5) = 0;
9325
9326 return name;
9327}
9328
9329boolean
9330arm_validate_fix (fixP)
9331 fixS * fixP;
9332{
9333 /* If the destination of the branch is a defined symbol which does not have
9334 the THUMB_FUNC attribute, then we must be calling a function which has
9335 the (interfacearm) attribute. We look for the Thumb entry point to that
9336 function and change the branch to refer to that function instead. */
9337 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
9338 && fixP->fx_addsy != NULL
9339 && S_IS_DEFINED (fixP->fx_addsy)
9340 && ! THUMB_IS_FUNC (fixP->fx_addsy))
9341 {
9342 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
9343 return true;
9344 }
9345
9346 return false;
9347}
9348
9349#ifdef OBJ_COFF
9350/* This is a little hack to help the gas/arm/adrl.s test. It prevents
9351 local labels from being added to the output symbol table when they
9352 are used with the ADRL pseudo op. The ADRL relocation should always
9353 be resolved before the binbary is emitted, so it is safe to say that
9354 it is adjustable. */
9355
9356boolean
9357arm_fix_adjustable (fixP)
9358 fixS * fixP;
9359{
9360 if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
9361 return 1;
9362 return 0;
9363}
9364#endif
9365#ifdef OBJ_ELF
9366/* Relocations against Thumb function names must be left unadjusted,
9367 so that the linker can use this information to correctly set the
9368 bottom bit of their addresses. The MIPS version of this function
9369 also prevents relocations that are mips-16 specific, but I do not
9370 know why it does this.
9371
9372 FIXME:
9373 There is one other problem that ought to be addressed here, but
9374 which currently is not: Taking the address of a label (rather
9375 than a function) and then later jumping to that address. Such
9376 addresses also ought to have their bottom bit set (assuming that
9377 they reside in Thumb code), but at the moment they will not. */
9378
9379boolean
9380arm_fix_adjustable (fixP)
9381 fixS * fixP;
9382{
9383 if (fixP->fx_addsy == NULL)
9384 return 1;
9385
9386 /* Prevent all adjustments to global symbols. */
9387 if (S_IS_EXTERN (fixP->fx_addsy))
9388 return 0;
9389
9390 if (S_IS_WEAK (fixP->fx_addsy))
9391 return 0;
9392
9393 if (THUMB_IS_FUNC (fixP->fx_addsy)
9394 && fixP->fx_subsy == NULL)
9395 return 0;
9396
9397 /* We need the symbol name for the VTABLE entries. */
9398 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
9399 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
9400 return 0;
9401
9402 return 1;
9403}
9404
9405const char *
9406elf32_arm_target_format ()
9407{
9408 if (target_big_endian)
9409 {
9410 if (target_oabi)
9411 return "elf32-bigarm-oabi";
9412 else
9413 return "elf32-bigarm";
9414 }
9415 else
9416 {
9417 if (target_oabi)
9418 return "elf32-littlearm-oabi";
9419 else
9420 return "elf32-littlearm";
9421 }
9422}
9423
9424void
9425armelf_frob_symbol (symp, puntp)
9426 symbolS * symp;
9427 int * puntp;
9428{
9429 elf_frob_symbol (symp, puntp);
9430}
9431
9432int
9433arm_force_relocation (fixp)
9434 struct fix * fixp;
9435{
9436 if ( fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
9437 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
9438 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BRANCH
9439 || fixp->fx_r_type == BFD_RELOC_ARM_PCREL_BLX
9440 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX
9441 || fixp->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23)
9442 return 1;
9443
9444 return 0;
9445}
9446
9447static bfd_reloc_code_real_type
9448arm_parse_reloc ()
9449{
9450 char id [16];
9451 char * ip;
9452 unsigned int i;
9453 static struct
9454 {
9455 char * str;
9456 int len;
9457 bfd_reloc_code_real_type reloc;
9458 }
9459 reloc_map[] =
9460 {
9461#define MAP(str,reloc) { str, sizeof (str) - 1, reloc }
9462 MAP ("(got)", BFD_RELOC_ARM_GOT32),
9463 MAP ("(gotoff)", BFD_RELOC_ARM_GOTOFF),
9464 /* ScottB: Jan 30, 1998 - Added support for parsing "var(PLT)"
9465 branch instructions generated by GCC for PLT relocs. */
9466 MAP ("(plt)", BFD_RELOC_ARM_PLT32),
9467 { NULL, 0, BFD_RELOC_UNUSED }
9468#undef MAP
9469 };
9470
9471 for (i = 0, ip = input_line_pointer;
3882b010 9472 i < sizeof (id) && (ISALNUM (*ip) || ISPUNCT (*ip));
b99bd4ef 9473 i++, ip++)
3882b010 9474 id[i] = TOLOWER (*ip);
b99bd4ef
NC
9475
9476 for (i = 0; reloc_map[i].str; i++)
9477 if (strncmp (id, reloc_map[i].str, reloc_map[i].len) == 0)
9478 break;
9479
9480 input_line_pointer += reloc_map[i].len;
9481
9482 return reloc_map[i].reloc;
9483}
9484
9485static void
9486s_arm_elf_cons (nbytes)
9487 int nbytes;
9488{
9489 expressionS exp;
9490
9491#ifdef md_flush_pending_output
9492 md_flush_pending_output ();
9493#endif
9494
9495 if (is_it_end_of_statement ())
9496 {
9497 demand_empty_rest_of_line ();
9498 return;
9499 }
9500
9501#ifdef md_cons_align
9502 md_cons_align (nbytes);
9503#endif
9504
9505 do
9506 {
9507 bfd_reloc_code_real_type reloc;
9508
9509 expression (& exp);
9510
9511 if (exp.X_op == O_symbol
9512 && * input_line_pointer == '('
9513 && (reloc = arm_parse_reloc ()) != BFD_RELOC_UNUSED)
9514 {
9515 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
9516 int size = bfd_get_reloc_size (howto);
9517
9518 if (size > nbytes)
9519 as_bad ("%s relocations do not fit in %d bytes",
9520 howto->name, nbytes);
9521 else
9522 {
9523 register char *p = frag_more ((int) nbytes);
9524 int offset = nbytes - size;
9525
9526 fix_new_exp (frag_now, p - frag_now->fr_literal + offset, size,
9527 &exp, 0, reloc);
9528 }
9529 }
9530 else
9531 emit_expr (&exp, (unsigned int) nbytes);
9532 }
9533 while (*input_line_pointer++ == ',');
9534
9535 /* Put terminator back into stream. */
9536 input_line_pointer --;
9537 demand_empty_rest_of_line ();
9538}
9539
9540#endif /* OBJ_ELF */
9541
9542/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
9543 of an rs_align_code fragment. */
9544
9545void
9546arm_handle_align (fragP)
9547 fragS *fragP;
9548{
9549 static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
9550 static char const thumb_noop[2] = { 0xc0, 0x46 };
9551 static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
9552 static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
9553
9554 int bytes, fix, noop_size;
9555 char * p;
9556 const char * noop;
9557
9558 if (fragP->fr_type != rs_align_code)
9559 return;
9560
9561 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
9562 p = fragP->fr_literal + fragP->fr_fix;
9563 fix = 0;
9564
9565 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
9566 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
9567
9568 if (fragP->tc_frag_data)
9569 {
9570 if (target_big_endian)
9571 noop = thumb_bigend_noop;
9572 else
9573 noop = thumb_noop;
9574 noop_size = sizeof (thumb_noop);
9575 }
9576 else
9577 {
9578 if (target_big_endian)
9579 noop = arm_bigend_noop;
9580 else
9581 noop = arm_noop;
9582 noop_size = sizeof (arm_noop);
9583 }
9584
9585 if (bytes & (noop_size - 1))
9586 {
9587 fix = bytes & (noop_size - 1);
9588 memset (p, 0, fix);
9589 p += fix;
9590 bytes -= fix;
9591 }
9592
9593 while (bytes >= noop_size)
9594 {
9595 memcpy (p, noop, noop_size);
9596 p += noop_size;
9597 bytes -= noop_size;
9598 fix += noop_size;
9599 }
9600
9601 fragP->fr_fix += fix;
9602 fragP->fr_var = noop_size;
9603}
9604
9605/* Called from md_do_align. Used to create an alignment
9606 frag in a code section. */
9607
9608void
9609arm_frag_align_code (n, max)
9610 int n;
9611 int max;
9612{
9613 char * p;
9614
9615 /* We assume that there will never be a requirment
9616 to support alignments greater than 32 bytes. */
9617 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
9618 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
9619
9620 p = frag_var (rs_align_code,
9621 MAX_MEM_FOR_RS_ALIGN_CODE,
9622 1,
9623 (relax_substateT) max,
9624 (symbolS *) NULL,
9625 (offsetT) n,
9626 (char *) NULL);
9627 *p = 0;
9628
9629}
9630
9631/* Perform target specific initialisation of a frag. */
9632
9633void
9634arm_init_frag (fragP)
9635 fragS *fragP;
9636{
9637 /* Record whether this frag is in an ARM or a THUMB area. */
9638 fragP->tc_frag_data = thumb_mode;
9639}