gas/
[deliverable/binutils-gdb.git] / gas / config / tc-arm.c
CommitLineData
b99bd4ef 1/* tc-arm.c -- Assemble for the ARM
f17c130b
AM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005
b99bd4ef
NC
4 Free Software Foundation, Inc.
5 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
6 Modified by David Taylor (dtaylor@armltd.co.uk)
22d9c8c5 7 Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
34920d91
NC
8 Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
9 Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
b99bd4ef
NC
10
11 This file is part of GAS, the GNU Assembler.
12
13 GAS is free software; you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation; either version 2, or (at your option)
16 any later version.
17
18 GAS is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
c19d1205 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b99bd4ef
NC
21 GNU General Public License for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with GAS; see the file COPYING. If not, write to the Free
699d2810
NC
25 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
26 02110-1301, USA. */
b99bd4ef 27
b99bd4ef 28#include <string.h>
c19d1205 29#define NO_RELOC 0
b99bd4ef 30#include "as.h"
3882b010 31#include "safe-ctype.h"
b99bd4ef
NC
32
33/* Need TARGET_CPU. */
34#include "config.h"
35#include "subsegs.h"
36#include "obstack.h"
37#include "symbols.h"
38#include "listing.h"
39
f263249b
RE
40#include "opcode/arm.h"
41
b99bd4ef
NC
42#ifdef OBJ_ELF
43#include "elf/arm.h"
44#include "dwarf2dbg.h"
a394c00f 45#include "dw2gencfi.h"
b99bd4ef
NC
46#endif
47
7ed4c4c5 48/* XXX Set this to 1 after the next binutils release. */
03b1477f
RE
49#define WARN_DEPRECATED 0
50
7ed4c4c5
NC
51#ifdef OBJ_ELF
52/* Must be at least the size of the largest unwind opcode (currently two). */
53#define ARM_OPCODE_CHUNK_SIZE 8
54
55/* This structure holds the unwinding state. */
56
57static struct
58{
c19d1205
ZW
59 symbolS * proc_start;
60 symbolS * table_entry;
61 symbolS * personality_routine;
62 int personality_index;
7ed4c4c5 63 /* The segment containing the function. */
c19d1205
ZW
64 segT saved_seg;
65 subsegT saved_subseg;
7ed4c4c5
NC
66 /* Opcodes generated from this function. */
67 unsigned char * opcodes;
c19d1205
ZW
68 int opcode_count;
69 int opcode_alloc;
7ed4c4c5 70 /* The number of bytes pushed to the stack. */
c19d1205 71 offsetT frame_size;
7ed4c4c5
NC
72 /* We don't add stack adjustment opcodes immediately so that we can merge
73 multiple adjustments. We can also omit the final adjustment
74 when using a frame pointer. */
c19d1205 75 offsetT pending_offset;
7ed4c4c5 76 /* These two fields are set by both unwind_movsp and unwind_setfp. They
c19d1205
ZW
77 hold the reg+offset to use when restoring sp from a frame pointer. */
78 offsetT fp_offset;
79 int fp_reg;
7ed4c4c5 80 /* Nonzero if an unwind_setfp directive has been seen. */
c19d1205 81 unsigned fp_used:1;
7ed4c4c5 82 /* Nonzero if the last opcode restores sp from fp_reg. */
c19d1205 83 unsigned sp_restored:1;
7ed4c4c5
NC
84} unwind;
85
84798bd6
JB
86/* Bit N indicates that an R_ARM_NONE relocation has been output for
87 __aeabi_unwind_cpp_prN already if set. This enables dependencies to be
88 emitted only once per section, to save unnecessary bloat. */
89static unsigned int marked_pr_dependency = 0;
90
7ed4c4c5
NC
91#endif /* OBJ_ELF */
92
33a392fb
PB
93enum arm_float_abi
94{
95 ARM_FLOAT_ABI_HARD,
96 ARM_FLOAT_ABI_SOFTFP,
97 ARM_FLOAT_ABI_SOFT
98};
99
c19d1205 100/* Types of processor to assemble for. */
b89dddec
RE
101#define ARM_1 ARM_ARCH_V1
102#define ARM_2 ARM_ARCH_V2
103#define ARM_3 ARM_ARCH_V2S
104#define ARM_250 ARM_ARCH_V2S
105#define ARM_6 ARM_ARCH_V3
106#define ARM_7 ARM_ARCH_V3
107#define ARM_8 ARM_ARCH_V4
108#define ARM_9 ARM_ARCH_V4T
109#define ARM_STRONG ARM_ARCH_V4
c19d1205 110#define ARM_CPU_MASK 0x0000000f /* XXX? */
b99bd4ef
NC
111
112#ifndef CPU_DEFAULT
113#if defined __XSCALE__
b89dddec 114#define CPU_DEFAULT (ARM_ARCH_XSCALE)
b99bd4ef
NC
115#else
116#if defined __thumb__
c19d1205 117#define CPU_DEFAULT (ARM_ARCH_V5T)
b99bd4ef
NC
118#endif
119#endif
120#endif
121
122#ifndef FPU_DEFAULT
c820d418
MM
123# ifdef TE_LINUX
124# define FPU_DEFAULT FPU_ARCH_FPA
125# elif defined (TE_NetBSD)
126# ifdef OBJ_ELF
127# define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, but VFP order. */
128# else
129 /* Legacy a.out format. */
130# define FPU_DEFAULT FPU_ARCH_FPA /* Soft-float, but FPA order. */
131# endif
4e7fd91e
PB
132# elif defined (TE_VXWORKS)
133# define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, VFP order. */
c820d418
MM
134# else
135 /* For backwards compatibility, default to FPA. */
136# define FPU_DEFAULT FPU_ARCH_FPA
137# endif
138#endif /* ifndef FPU_DEFAULT */
b99bd4ef 139
c19d1205 140#define streq(a, b) (strcmp (a, b) == 0)
b99bd4ef 141
03b1477f 142static unsigned long cpu_variant;
ee065d83
PB
143static unsigned long arm_arch_used;
144static unsigned long thumb_arch_used;
b99bd4ef 145
b99bd4ef 146/* Flags stored in private area of BFD structure. */
c19d1205
ZW
147static int uses_apcs_26 = FALSE;
148static int atpcs = FALSE;
b34976b6
AM
149static int support_interwork = FALSE;
150static int uses_apcs_float = FALSE;
c19d1205 151static int pic_code = FALSE;
03b1477f
RE
152
153/* Variables that we set while parsing command-line options. Once all
154 options have been read we re-process these values to set the real
155 assembly flags. */
156static int legacy_cpu = -1;
157static int legacy_fpu = -1;
158
159static int mcpu_cpu_opt = -1;
160static int mcpu_fpu_opt = -1;
161static int march_cpu_opt = -1;
162static int march_fpu_opt = -1;
163static int mfpu_opt = -1;
33a392fb 164static int mfloat_abi_opt = -1;
ee065d83
PB
165/* Record user cpu selection for object attributes.
166 Zero if no default or user specified CPU. */
167static int selected_cpu = -1;
168/* Must be long enough to hold any of the names in arm_cpus. */
169static char selected_cpu_name[16];
7cc69913 170#ifdef OBJ_ELF
deeaaff8
DJ
171# ifdef EABI_DEFAULT
172static int meabi_flags = EABI_DEFAULT;
173# else
d507cf36 174static int meabi_flags = EF_ARM_EABI_UNKNOWN;
deeaaff8 175# endif
7cc69913 176#endif
b99bd4ef 177
b99bd4ef 178#ifdef OBJ_ELF
c19d1205 179/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
b99bd4ef
NC
180symbolS * GOT_symbol;
181#endif
182
b99bd4ef
NC
183/* 0: assemble for ARM,
184 1: assemble for Thumb,
185 2: assemble for Thumb even though target CPU does not support thumb
186 instructions. */
187static int thumb_mode = 0;
188
c19d1205
ZW
189/* If unified_syntax is true, we are processing the new unified
190 ARM/Thumb syntax. Important differences from the old ARM mode:
191
192 - Immediate operands do not require a # prefix.
193 - Conditional affixes always appear at the end of the
194 instruction. (For backward compatibility, those instructions
195 that formerly had them in the middle, continue to accept them
196 there.)
197 - The IT instruction may appear, and if it does is validated
198 against subsequent conditional affixes. It does not generate
199 machine code.
200
201 Important differences from the old Thumb mode:
202
203 - Immediate operands do not require a # prefix.
204 - Most of the V6T2 instructions are only available in unified mode.
205 - The .N and .W suffixes are recognized and honored (it is an error
206 if they cannot be honored).
207 - All instructions set the flags if and only if they have an 's' affix.
208 - Conditional affixes may be used. They are validated against
209 preceding IT instructions. Unlike ARM mode, you cannot use a
210 conditional affix except in the scope of an IT instruction. */
211
212static bfd_boolean unified_syntax = FALSE;
b99bd4ef
NC
213
214struct arm_it
215{
c19d1205 216 const char * error;
b99bd4ef 217 unsigned long instruction;
c19d1205
ZW
218 int size;
219 int size_req;
220 int cond;
0110f2b8
PB
221 /* Set to the opcode if the instruction needs relaxation.
222 Zero if the instruction is not relaxed. */
223 unsigned long relax;
b99bd4ef
NC
224 struct
225 {
226 bfd_reloc_code_real_type type;
c19d1205
ZW
227 expressionS exp;
228 int pc_rel;
b99bd4ef 229 } reloc;
b99bd4ef 230
c19d1205
ZW
231 struct
232 {
233 unsigned reg;
ca3f61f7
NC
234 signed int imm;
235 unsigned present : 1; /* Operand present. */
236 unsigned isreg : 1; /* Operand was a register. */
237 unsigned immisreg : 1; /* .imm field is a second register. */
238 unsigned hasreloc : 1; /* Operand has relocation suffix. */
239 unsigned writeback : 1; /* Operand has trailing ! */
240 unsigned preind : 1; /* Preindexed address. */
241 unsigned postind : 1; /* Postindexed address. */
242 unsigned negative : 1; /* Index register was negated. */
243 unsigned shifted : 1; /* Shift applied to operation. */
244 unsigned shift_kind : 3; /* Shift operation (enum shift_kind). */
c19d1205 245 } operands[6];
b99bd4ef
NC
246};
247
c19d1205 248static struct arm_it inst;
b99bd4ef
NC
249
250#define NUM_FLOAT_VALS 8
251
05d2d07e 252const char * fp_const[] =
b99bd4ef
NC
253{
254 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
255};
256
c19d1205 257/* Number of littlenums required to hold an extended precision number. */
b99bd4ef
NC
258#define MAX_LITTLENUMS 6
259
260LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
261
262#define FAIL (-1)
263#define SUCCESS (0)
264
265#define SUFF_S 1
266#define SUFF_D 2
267#define SUFF_E 3
268#define SUFF_P 4
269
c19d1205
ZW
270#define CP_T_X 0x00008000
271#define CP_T_Y 0x00400000
b99bd4ef 272
c19d1205
ZW
273#define CONDS_BIT 0x00100000
274#define LOAD_BIT 0x00100000
b99bd4ef
NC
275
276#define DOUBLE_LOAD_FLAG 0x00000001
277
278struct asm_cond
279{
c19d1205 280 const char * template;
b99bd4ef
NC
281 unsigned long value;
282};
283
c19d1205 284#define COND_ALWAYS 0xE
b99bd4ef 285
b99bd4ef
NC
286struct asm_psr
287{
b34976b6 288 const char *template;
b99bd4ef
NC
289 unsigned long field;
290};
291
2d2255b5 292/* The bit that distinguishes CPSR and SPSR. */
b99bd4ef
NC
293#define SPSR_BIT (1 << 22)
294
c19d1205
ZW
295/* The individual PSR flag bits. */
296#define PSR_c (1 << 16)
297#define PSR_x (1 << 17)
298#define PSR_s (1 << 18)
299#define PSR_f (1 << 19)
b99bd4ef 300
c19d1205 301struct reloc_entry
bfae80f2 302{
c19d1205
ZW
303 char *name;
304 bfd_reloc_code_real_type reloc;
bfae80f2
RE
305};
306
307enum vfp_sp_reg_pos
308{
309 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn
310};
311
312enum vfp_ldstm_type
313{
314 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
315};
316
c19d1205
ZW
317/* ARM register categories. This includes coprocessor numbers and various
318 architecture extensions' registers. */
319enum arm_reg_type
bfae80f2 320{
c19d1205
ZW
321 REG_TYPE_RN,
322 REG_TYPE_CP,
323 REG_TYPE_CN,
324 REG_TYPE_FN,
325 REG_TYPE_VFS,
326 REG_TYPE_VFD,
327 REG_TYPE_VFC,
328 REG_TYPE_MVF,
329 REG_TYPE_MVD,
330 REG_TYPE_MVFX,
331 REG_TYPE_MVDX,
332 REG_TYPE_MVAX,
333 REG_TYPE_DSPSC,
334 REG_TYPE_MMXWR,
335 REG_TYPE_MMXWC,
336 REG_TYPE_MMXWCG,
337 REG_TYPE_XSCALE,
bfae80f2
RE
338};
339
6c43fab6
RE
340/* Structure for a hash table entry for a register. */
341struct reg_entry
342{
c19d1205
ZW
343 const char *name;
344 unsigned char number;
345 unsigned char type;
346 unsigned char builtin;
6c43fab6
RE
347};
348
c19d1205
ZW
349/* Diagnostics used when we don't get a register of the expected type. */
350const char *const reg_expected_msgs[] =
351{
352 N_("ARM register expected"),
353 N_("bad or missing co-processor number"),
354 N_("co-processor register expected"),
355 N_("FPA register expected"),
356 N_("VFP single precision register expected"),
357 N_("VFP double precision register expected"),
358 N_("VFP system register expected"),
359 N_("Maverick MVF register expected"),
360 N_("Maverick MVD register expected"),
361 N_("Maverick MVFX register expected"),
362 N_("Maverick MVDX register expected"),
363 N_("Maverick MVAX register expected"),
364 N_("Maverick DSPSC register expected"),
365 N_("iWMMXt data register expected"),
366 N_("iWMMXt control register expected"),
367 N_("iWMMXt scalar register expected"),
368 N_("XScale accumulator register expected"),
6c43fab6
RE
369};
370
c19d1205
ZW
371/* Some well known registers that we refer to directly elsewhere. */
372#define REG_SP 13
373#define REG_LR 14
374#define REG_PC 15
404ff6b5 375
b99bd4ef
NC
376/* ARM instructions take 4bytes in the object file, Thumb instructions
377 take 2: */
c19d1205 378#define INSN_SIZE 4
b99bd4ef
NC
379
380struct asm_opcode
381{
382 /* Basic string to match. */
c19d1205
ZW
383 const char *template;
384
385 /* Parameters to instruction. */
386 unsigned char operands[8];
387
388 /* Conditional tag - see opcode_lookup. */
389 unsigned int tag : 4;
b99bd4ef
NC
390
391 /* Basic instruction code. */
c19d1205 392 unsigned int avalue : 28;
b99bd4ef 393
c19d1205
ZW
394 /* Thumb-format instruction code. */
395 unsigned int tvalue;
b99bd4ef 396
90e4755a 397 /* Which architecture variant provides this instruction. */
c19d1205
ZW
398 unsigned long avariant;
399 unsigned long tvariant;
400
401 /* Function to call to encode instruction in ARM format. */
402 void (* aencode) (void);
b99bd4ef 403
c19d1205
ZW
404 /* Function to call to encode instruction in Thumb format. */
405 void (* tencode) (void);
b99bd4ef
NC
406};
407
a737bd4d
NC
408/* Defines for various bits that we will want to toggle. */
409#define INST_IMMEDIATE 0x02000000
410#define OFFSET_REG 0x02000000
c19d1205 411#define HWOFFSET_IMM 0x00400000
a737bd4d
NC
412#define SHIFT_BY_REG 0x00000010
413#define PRE_INDEX 0x01000000
414#define INDEX_UP 0x00800000
415#define WRITE_BACK 0x00200000
416#define LDM_TYPE_2_OR_3 0x00400000
90e4755a 417
a737bd4d
NC
418#define LITERAL_MASK 0xf000f000
419#define OPCODE_MASK 0xfe1fffff
420#define V4_STR_BIT 0x00000020
90e4755a 421
a737bd4d 422#define DATA_OP_SHIFT 21
90e4755a 423
a737bd4d
NC
424/* Codes to distinguish the arithmetic instructions. */
425#define OPCODE_AND 0
426#define OPCODE_EOR 1
427#define OPCODE_SUB 2
428#define OPCODE_RSB 3
429#define OPCODE_ADD 4
430#define OPCODE_ADC 5
431#define OPCODE_SBC 6
432#define OPCODE_RSC 7
433#define OPCODE_TST 8
434#define OPCODE_TEQ 9
435#define OPCODE_CMP 10
436#define OPCODE_CMN 11
437#define OPCODE_ORR 12
438#define OPCODE_MOV 13
439#define OPCODE_BIC 14
440#define OPCODE_MVN 15
90e4755a 441
a737bd4d
NC
442#define T_OPCODE_MUL 0x4340
443#define T_OPCODE_TST 0x4200
444#define T_OPCODE_CMN 0x42c0
445#define T_OPCODE_NEG 0x4240
446#define T_OPCODE_MVN 0x43c0
90e4755a 447
a737bd4d
NC
448#define T_OPCODE_ADD_R3 0x1800
449#define T_OPCODE_SUB_R3 0x1a00
450#define T_OPCODE_ADD_HI 0x4400
451#define T_OPCODE_ADD_ST 0xb000
452#define T_OPCODE_SUB_ST 0xb080
453#define T_OPCODE_ADD_SP 0xa800
454#define T_OPCODE_ADD_PC 0xa000
455#define T_OPCODE_ADD_I8 0x3000
456#define T_OPCODE_SUB_I8 0x3800
457#define T_OPCODE_ADD_I3 0x1c00
458#define T_OPCODE_SUB_I3 0x1e00
b99bd4ef 459
a737bd4d
NC
460#define T_OPCODE_ASR_R 0x4100
461#define T_OPCODE_LSL_R 0x4080
c19d1205
ZW
462#define T_OPCODE_LSR_R 0x40c0
463#define T_OPCODE_ROR_R 0x41c0
a737bd4d
NC
464#define T_OPCODE_ASR_I 0x1000
465#define T_OPCODE_LSL_I 0x0000
466#define T_OPCODE_LSR_I 0x0800
b99bd4ef 467
a737bd4d
NC
468#define T_OPCODE_MOV_I8 0x2000
469#define T_OPCODE_CMP_I8 0x2800
470#define T_OPCODE_CMP_LR 0x4280
471#define T_OPCODE_MOV_HR 0x4600
472#define T_OPCODE_CMP_HR 0x4500
b99bd4ef 473
a737bd4d
NC
474#define T_OPCODE_LDR_PC 0x4800
475#define T_OPCODE_LDR_SP 0x9800
476#define T_OPCODE_STR_SP 0x9000
477#define T_OPCODE_LDR_IW 0x6800
478#define T_OPCODE_STR_IW 0x6000
479#define T_OPCODE_LDR_IH 0x8800
480#define T_OPCODE_STR_IH 0x8000
481#define T_OPCODE_LDR_IB 0x7800
482#define T_OPCODE_STR_IB 0x7000
483#define T_OPCODE_LDR_RW 0x5800
484#define T_OPCODE_STR_RW 0x5000
485#define T_OPCODE_LDR_RH 0x5a00
486#define T_OPCODE_STR_RH 0x5200
487#define T_OPCODE_LDR_RB 0x5c00
488#define T_OPCODE_STR_RB 0x5400
c9b604bd 489
a737bd4d
NC
490#define T_OPCODE_PUSH 0xb400
491#define T_OPCODE_POP 0xbc00
b99bd4ef 492
2fc8bdac 493#define T_OPCODE_BRANCH 0xe000
b99bd4ef 494
a737bd4d 495#define THUMB_SIZE 2 /* Size of thumb instruction. */
a737bd4d 496#define THUMB_PP_PC_LR 0x0100
c19d1205
ZW
497#define THUMB_LOAD_BIT 0x0800
498
499#define BAD_ARGS _("bad arguments to instruction")
500#define BAD_PC _("r15 not allowed here")
501#define BAD_COND _("instruction cannot be conditional")
502#define BAD_OVERLAP _("registers may not be the same")
503#define BAD_HIREG _("lo register required")
504#define BAD_THUMB32 _("instruction not supported in Thumb16 mode")
01cfc07f 505#define BAD_ADDR_MODE _("instruction does not accept this addressing mode");
c19d1205
ZW
506
507static struct hash_control *arm_ops_hsh;
508static struct hash_control *arm_cond_hsh;
509static struct hash_control *arm_shift_hsh;
510static struct hash_control *arm_psr_hsh;
511static struct hash_control *arm_reg_hsh;
512static struct hash_control *arm_reloc_hsh;
b99bd4ef 513
b99bd4ef
NC
514/* Stuff needed to resolve the label ambiguity
515 As:
516 ...
517 label: <insn>
518 may differ from:
519 ...
520 label:
c19d1205 521 <insn>
b99bd4ef
NC
522*/
523
524symbolS * last_label_seen;
b34976b6 525static int label_is_thumb_function_name = FALSE;
a737bd4d 526\f
3d0c9500
NC
527/* Literal pool structure. Held on a per-section
528 and per-sub-section basis. */
a737bd4d 529
c19d1205 530#define MAX_LITERAL_POOL_SIZE 1024
3d0c9500 531typedef struct literal_pool
b99bd4ef 532{
c19d1205
ZW
533 expressionS literals [MAX_LITERAL_POOL_SIZE];
534 unsigned int next_free_entry;
535 unsigned int id;
536 symbolS * symbol;
537 segT section;
538 subsegT sub_section;
61b5f74b 539 struct literal_pool * next;
3d0c9500 540} literal_pool;
b99bd4ef 541
3d0c9500
NC
542/* Pointer to a linked list of literal pools. */
543literal_pool * list_of_pools = NULL;
e27ec89e
PB
544
545/* State variables for IT block handling. */
546static bfd_boolean current_it_mask = 0;
547static int current_cc;
548
c19d1205
ZW
549\f
550/* Pure syntax. */
b99bd4ef 551
c19d1205
ZW
552/* This array holds the chars that always start a comment. If the
553 pre-processor is disabled, these aren't very useful. */
554const char comment_chars[] = "@";
3d0c9500 555
c19d1205
ZW
556/* This array holds the chars that only start a comment at the beginning of
557 a line. If the line seems to have the form '# 123 filename'
558 .line and .file directives will appear in the pre-processed output. */
559/* Note that input_file.c hand checks for '#' at the beginning of the
560 first line of the input file. This is because the compiler outputs
561 #NO_APP at the beginning of its output. */
562/* Also note that comments like this one will always work. */
563const char line_comment_chars[] = "#";
3d0c9500 564
c19d1205 565const char line_separator_chars[] = ";";
b99bd4ef 566
c19d1205
ZW
567/* Chars that can be used to separate mant
568 from exp in floating point numbers. */
569const char EXP_CHARS[] = "eE";
3d0c9500 570
c19d1205
ZW
571/* Chars that mean this number is a floating point constant. */
572/* As in 0f12.456 */
573/* or 0d1.2345e12 */
b99bd4ef 574
c19d1205 575const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
3d0c9500 576
c19d1205
ZW
577/* Prefix characters that indicate the start of an immediate
578 value. */
579#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
3d0c9500 580
c19d1205
ZW
581/* Separator character handling. */
582
583#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
584
585static inline int
586skip_past_char (char ** str, char c)
587{
588 if (**str == c)
589 {
590 (*str)++;
591 return SUCCESS;
3d0c9500 592 }
c19d1205
ZW
593 else
594 return FAIL;
595}
596#define skip_past_comma(str) skip_past_char (str, ',')
3d0c9500 597
c19d1205
ZW
598/* Arithmetic expressions (possibly involving symbols). */
599
600/* Return TRUE if anything in the expression is a bignum. */
601
602static int
603walk_no_bignums (symbolS * sp)
604{
605 if (symbol_get_value_expression (sp)->X_op == O_big)
606 return 1;
607
608 if (symbol_get_value_expression (sp)->X_add_symbol)
3d0c9500 609 {
c19d1205
ZW
610 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
611 || (symbol_get_value_expression (sp)->X_op_symbol
612 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
3d0c9500
NC
613 }
614
c19d1205 615 return 0;
3d0c9500
NC
616}
617
c19d1205
ZW
618static int in_my_get_expression = 0;
619
620/* Third argument to my_get_expression. */
621#define GE_NO_PREFIX 0
622#define GE_IMM_PREFIX 1
623#define GE_OPT_PREFIX 2
a737bd4d 624
b99bd4ef 625static int
c19d1205 626my_get_expression (expressionS * ep, char ** str, int prefix_mode)
b99bd4ef 627{
c19d1205
ZW
628 char * save_in;
629 segT seg;
b99bd4ef 630
c19d1205
ZW
631 /* In unified syntax, all prefixes are optional. */
632 if (unified_syntax)
633 prefix_mode = GE_OPT_PREFIX;
b99bd4ef 634
c19d1205 635 switch (prefix_mode)
b99bd4ef 636 {
c19d1205
ZW
637 case GE_NO_PREFIX: break;
638 case GE_IMM_PREFIX:
639 if (!is_immediate_prefix (**str))
640 {
641 inst.error = _("immediate expression requires a # prefix");
642 return FAIL;
643 }
644 (*str)++;
645 break;
646 case GE_OPT_PREFIX:
647 if (is_immediate_prefix (**str))
648 (*str)++;
649 break;
650 default: abort ();
651 }
b99bd4ef 652
c19d1205 653 memset (ep, 0, sizeof (expressionS));
b99bd4ef 654
c19d1205
ZW
655 save_in = input_line_pointer;
656 input_line_pointer = *str;
657 in_my_get_expression = 1;
658 seg = expression (ep);
659 in_my_get_expression = 0;
660
661 if (ep->X_op == O_illegal)
b99bd4ef 662 {
c19d1205
ZW
663 /* We found a bad expression in md_operand(). */
664 *str = input_line_pointer;
665 input_line_pointer = save_in;
666 if (inst.error == NULL)
667 inst.error = _("bad expression");
668 return 1;
669 }
b99bd4ef 670
c19d1205
ZW
671#ifdef OBJ_AOUT
672 if (seg != absolute_section
673 && seg != text_section
674 && seg != data_section
675 && seg != bss_section
676 && seg != undefined_section)
677 {
678 inst.error = _("bad segment");
679 *str = input_line_pointer;
680 input_line_pointer = save_in;
681 return 1;
b99bd4ef 682 }
c19d1205 683#endif
b99bd4ef 684
c19d1205
ZW
685 /* Get rid of any bignums now, so that we don't generate an error for which
686 we can't establish a line number later on. Big numbers are never valid
687 in instructions, which is where this routine is always called. */
688 if (ep->X_op == O_big
689 || (ep->X_add_symbol
690 && (walk_no_bignums (ep->X_add_symbol)
691 || (ep->X_op_symbol
692 && walk_no_bignums (ep->X_op_symbol)))))
693 {
694 inst.error = _("invalid constant");
695 *str = input_line_pointer;
696 input_line_pointer = save_in;
697 return 1;
698 }
b99bd4ef 699
c19d1205
ZW
700 *str = input_line_pointer;
701 input_line_pointer = save_in;
702 return 0;
b99bd4ef
NC
703}
704
c19d1205
ZW
705/* Turn a string in input_line_pointer into a floating point constant
706 of type TYPE, and store the appropriate bytes in *LITP. The number
707 of LITTLENUMS emitted is stored in *SIZEP. An error message is
708 returned, or NULL on OK.
b99bd4ef 709
c19d1205
ZW
710 Note that fp constants aren't represent in the normal way on the ARM.
711 In big endian mode, things are as expected. However, in little endian
712 mode fp constants are big-endian word-wise, and little-endian byte-wise
713 within the words. For example, (double) 1.1 in big endian mode is
714 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
715 the byte sequence 99 99 f1 3f 9a 99 99 99.
b99bd4ef 716
c19d1205 717 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
b99bd4ef 718
c19d1205
ZW
719char *
720md_atof (int type, char * litP, int * sizeP)
721{
722 int prec;
723 LITTLENUM_TYPE words[MAX_LITTLENUMS];
724 char *t;
725 int i;
b99bd4ef 726
c19d1205
ZW
727 switch (type)
728 {
729 case 'f':
730 case 'F':
731 case 's':
732 case 'S':
733 prec = 2;
734 break;
b99bd4ef 735
c19d1205
ZW
736 case 'd':
737 case 'D':
738 case 'r':
739 case 'R':
740 prec = 4;
741 break;
b99bd4ef 742
c19d1205
ZW
743 case 'x':
744 case 'X':
745 prec = 6;
746 break;
b99bd4ef 747
c19d1205
ZW
748 case 'p':
749 case 'P':
750 prec = 6;
751 break;
a737bd4d 752
c19d1205
ZW
753 default:
754 *sizeP = 0;
755 return _("bad call to MD_ATOF()");
756 }
b99bd4ef 757
c19d1205
ZW
758 t = atof_ieee (input_line_pointer, type, words);
759 if (t)
760 input_line_pointer = t;
761 *sizeP = prec * 2;
b99bd4ef 762
c19d1205
ZW
763 if (target_big_endian)
764 {
765 for (i = 0; i < prec; i++)
766 {
767 md_number_to_chars (litP, (valueT) words[i], 2);
768 litP += 2;
769 }
770 }
771 else
772 {
773 if (cpu_variant & FPU_ARCH_VFP)
774 for (i = prec - 1; i >= 0; i--)
775 {
776 md_number_to_chars (litP, (valueT) words[i], 2);
777 litP += 2;
778 }
779 else
780 /* For a 4 byte float the order of elements in `words' is 1 0.
781 For an 8 byte float the order is 1 0 3 2. */
782 for (i = 0; i < prec; i += 2)
783 {
784 md_number_to_chars (litP, (valueT) words[i + 1], 2);
785 md_number_to_chars (litP + 2, (valueT) words[i], 2);
786 litP += 4;
787 }
788 }
b99bd4ef 789
c19d1205
ZW
790 return 0;
791}
b99bd4ef 792
c19d1205
ZW
793/* We handle all bad expressions here, so that we can report the faulty
794 instruction in the error message. */
795void
796md_operand (expressionS * expr)
797{
798 if (in_my_get_expression)
799 expr->X_op = O_illegal;
b99bd4ef
NC
800}
801
c19d1205 802/* Immediate values. */
b99bd4ef 803
c19d1205
ZW
804/* Generic immediate-value read function for use in directives.
805 Accepts anything that 'expression' can fold to a constant.
806 *val receives the number. */
807#ifdef OBJ_ELF
808static int
809immediate_for_directive (int *val)
b99bd4ef 810{
c19d1205
ZW
811 expressionS exp;
812 exp.X_op = O_illegal;
b99bd4ef 813
c19d1205
ZW
814 if (is_immediate_prefix (*input_line_pointer))
815 {
816 input_line_pointer++;
817 expression (&exp);
818 }
b99bd4ef 819
c19d1205
ZW
820 if (exp.X_op != O_constant)
821 {
822 as_bad (_("expected #constant"));
823 ignore_rest_of_line ();
824 return FAIL;
825 }
826 *val = exp.X_add_number;
827 return SUCCESS;
b99bd4ef 828}
c19d1205 829#endif
b99bd4ef 830
c19d1205 831/* Register parsing. */
b99bd4ef 832
c19d1205
ZW
833/* Generic register parser. CCP points to what should be the
834 beginning of a register name. If it is indeed a valid register
835 name, advance CCP over it and return the reg_entry structure;
836 otherwise return NULL. Does not issue diagnostics. */
837
838static struct reg_entry *
839arm_reg_parse_multi (char **ccp)
b99bd4ef 840{
c19d1205
ZW
841 char *start = *ccp;
842 char *p;
843 struct reg_entry *reg;
b99bd4ef 844
c19d1205
ZW
845#ifdef REGISTER_PREFIX
846 if (*start != REGISTER_PREFIX)
01cfc07f 847 return NULL;
c19d1205
ZW
848 start++;
849#endif
850#ifdef OPTIONAL_REGISTER_PREFIX
851 if (*start == OPTIONAL_REGISTER_PREFIX)
852 start++;
853#endif
b99bd4ef 854
c19d1205
ZW
855 p = start;
856 if (!ISALPHA (*p) || !is_name_beginner (*p))
857 return NULL;
b99bd4ef 858
c19d1205
ZW
859 do
860 p++;
861 while (ISALPHA (*p) || ISDIGIT (*p) || *p == '_');
862
863 reg = (struct reg_entry *) hash_find_n (arm_reg_hsh, start, p - start);
864
865 if (!reg)
866 return NULL;
867
868 *ccp = p;
869 return reg;
b99bd4ef
NC
870}
871
c19d1205 872/* As above, but the register must be of type TYPE, and the return
01cfc07f 873 value is the register number or FAIL. */
c19d1205 874
b99bd4ef 875static int
c19d1205 876arm_reg_parse (char **ccp, enum arm_reg_type type)
b99bd4ef 877{
c19d1205
ZW
878 char *start = *ccp;
879 struct reg_entry *reg = arm_reg_parse_multi (ccp);
b99bd4ef 880
c19d1205
ZW
881 if (reg && reg->type == type)
882 return reg->number;
6057a28f 883
c19d1205
ZW
884 /* Alternative syntaxes are accepted for a few register classes. */
885 switch (type)
886 {
887 case REG_TYPE_MVF:
888 case REG_TYPE_MVD:
889 case REG_TYPE_MVFX:
890 case REG_TYPE_MVDX:
891 /* Generic coprocessor register names are allowed for these. */
892 if (reg->type == REG_TYPE_CN)
893 return reg->number;
894 break;
69b97547 895
c19d1205
ZW
896 case REG_TYPE_CP:
897 /* For backward compatibility, a bare number is valid here. */
898 {
899 unsigned long processor = strtoul (start, ccp, 10);
900 if (*ccp != start && processor <= 15)
901 return processor;
902 }
6057a28f 903
c19d1205
ZW
904 case REG_TYPE_MMXWC:
905 /* WC includes WCG. ??? I'm not sure this is true for all
906 instructions that take WC registers. */
907 if (reg->type == REG_TYPE_MMXWCG)
908 return reg->number;
6057a28f 909 break;
c19d1205 910
6057a28f 911 default:
c19d1205 912 break;
6057a28f
NC
913 }
914
c19d1205
ZW
915 *ccp = start;
916 return FAIL;
917}
69b97547 918
c19d1205
ZW
919/* Parse an ARM register list. Returns the bitmask, or FAIL. */
920static long
921parse_reg_list (char ** strp)
922{
923 char * str = * strp;
924 long range = 0;
925 int another_range;
a737bd4d 926
c19d1205
ZW
927 /* We come back here if we get ranges concatenated by '+' or '|'. */
928 do
6057a28f 929 {
c19d1205 930 another_range = 0;
a737bd4d 931
c19d1205
ZW
932 if (*str == '{')
933 {
934 int in_range = 0;
935 int cur_reg = -1;
a737bd4d 936
c19d1205
ZW
937 str++;
938 do
939 {
940 int reg;
6057a28f 941
c19d1205
ZW
942 if ((reg = arm_reg_parse (&str, REG_TYPE_RN)) == FAIL)
943 {
944 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
945 return FAIL;
946 }
a737bd4d 947
c19d1205
ZW
948 if (in_range)
949 {
950 int i;
a737bd4d 951
c19d1205
ZW
952 if (reg <= cur_reg)
953 {
954 inst.error = _("bad range in register list");
955 return FAIL;
956 }
40a18ebd 957
c19d1205
ZW
958 for (i = cur_reg + 1; i < reg; i++)
959 {
960 if (range & (1 << i))
961 as_tsktsk
962 (_("Warning: duplicated register (r%d) in register list"),
963 i);
964 else
965 range |= 1 << i;
966 }
967 in_range = 0;
968 }
a737bd4d 969
c19d1205
ZW
970 if (range & (1 << reg))
971 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
972 reg);
973 else if (reg <= cur_reg)
974 as_tsktsk (_("Warning: register range not in ascending order"));
a737bd4d 975
c19d1205
ZW
976 range |= 1 << reg;
977 cur_reg = reg;
978 }
979 while (skip_past_comma (&str) != FAIL
980 || (in_range = 1, *str++ == '-'));
981 str--;
a737bd4d 982
c19d1205
ZW
983 if (*str++ != '}')
984 {
985 inst.error = _("missing `}'");
986 return FAIL;
987 }
988 }
989 else
990 {
991 expressionS expr;
40a18ebd 992
c19d1205
ZW
993 if (my_get_expression (&expr, &str, GE_NO_PREFIX))
994 return FAIL;
40a18ebd 995
c19d1205
ZW
996 if (expr.X_op == O_constant)
997 {
998 if (expr.X_add_number
999 != (expr.X_add_number & 0x0000ffff))
1000 {
1001 inst.error = _("invalid register mask");
1002 return FAIL;
1003 }
a737bd4d 1004
c19d1205
ZW
1005 if ((range & expr.X_add_number) != 0)
1006 {
1007 int regno = range & expr.X_add_number;
a737bd4d 1008
c19d1205
ZW
1009 regno &= -regno;
1010 regno = (1 << regno) - 1;
1011 as_tsktsk
1012 (_("Warning: duplicated register (r%d) in register list"),
1013 regno);
1014 }
a737bd4d 1015
c19d1205
ZW
1016 range |= expr.X_add_number;
1017 }
1018 else
1019 {
1020 if (inst.reloc.type != 0)
1021 {
1022 inst.error = _("expression too complex");
1023 return FAIL;
1024 }
a737bd4d 1025
c19d1205
ZW
1026 memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
1027 inst.reloc.type = BFD_RELOC_ARM_MULTI;
1028 inst.reloc.pc_rel = 0;
1029 }
1030 }
a737bd4d 1031
c19d1205
ZW
1032 if (*str == '|' || *str == '+')
1033 {
1034 str++;
1035 another_range = 1;
1036 }
a737bd4d 1037 }
c19d1205 1038 while (another_range);
a737bd4d 1039
c19d1205
ZW
1040 *strp = str;
1041 return range;
a737bd4d
NC
1042}
1043
c19d1205
ZW
1044/* Parse a VFP register list. If the string is invalid return FAIL.
1045 Otherwise return the number of registers, and set PBASE to the first
1046 register. Double precision registers are matched if DP is nonzero. */
6057a28f 1047
c19d1205 1048static int
ca3f61f7 1049parse_vfp_reg_list (char **str, unsigned int *pbase, int dp)
6057a28f 1050{
c19d1205
ZW
1051 int base_reg;
1052 int new_base;
1053 int regtype;
1054 int max_regs;
1055 int count = 0;
1056 int warned = 0;
1057 unsigned long mask = 0;
a737bd4d 1058 int i;
6057a28f 1059
c19d1205
ZW
1060 if (**str != '{')
1061 return FAIL;
6057a28f 1062
c19d1205 1063 (*str)++;
6057a28f 1064
c19d1205 1065 if (dp)
a737bd4d 1066 {
c19d1205
ZW
1067 regtype = REG_TYPE_VFD;
1068 max_regs = 16;
1069 }
1070 else
1071 {
1072 regtype = REG_TYPE_VFS;
1073 max_regs = 32;
1074 }
6057a28f 1075
c19d1205 1076 base_reg = max_regs;
a737bd4d 1077
c19d1205
ZW
1078 do
1079 {
1080 new_base = arm_reg_parse (str, regtype);
1081 if (new_base == FAIL)
a737bd4d 1082 {
c19d1205
ZW
1083 inst.error = gettext (reg_expected_msgs[regtype]);
1084 return FAIL;
1085 }
a737bd4d 1086
c19d1205
ZW
1087 if (new_base < base_reg)
1088 base_reg = new_base;
a737bd4d 1089
c19d1205
ZW
1090 if (mask & (1 << new_base))
1091 {
1092 inst.error = _("invalid register list");
1093 return FAIL;
a737bd4d 1094 }
a737bd4d 1095
c19d1205
ZW
1096 if ((mask >> new_base) != 0 && ! warned)
1097 {
1098 as_tsktsk (_("register list not in ascending order"));
1099 warned = 1;
1100 }
0bbf2aa4 1101
c19d1205
ZW
1102 mask |= 1 << new_base;
1103 count++;
0bbf2aa4 1104
c19d1205
ZW
1105 if (**str == '-') /* We have the start of a range expression */
1106 {
1107 int high_range;
0bbf2aa4 1108
c19d1205 1109 (*str)++;
0bbf2aa4 1110
c19d1205
ZW
1111 if ((high_range = arm_reg_parse (str, regtype)) == FAIL)
1112 {
1113 inst.error = gettext (reg_expected_msgs[regtype]);
1114 return FAIL;
1115 }
0bbf2aa4 1116
c19d1205
ZW
1117 if (high_range <= new_base)
1118 {
1119 inst.error = _("register range not in ascending order");
1120 return FAIL;
1121 }
0bbf2aa4 1122
c19d1205 1123 for (new_base++; new_base <= high_range; new_base++)
0bbf2aa4 1124 {
c19d1205 1125 if (mask & (1 << new_base))
0bbf2aa4 1126 {
c19d1205
ZW
1127 inst.error = _("invalid register list");
1128 return FAIL;
0bbf2aa4 1129 }
c19d1205
ZW
1130
1131 mask |= 1 << new_base;
1132 count++;
0bbf2aa4 1133 }
0bbf2aa4 1134 }
0bbf2aa4 1135 }
c19d1205 1136 while (skip_past_comma (str) != FAIL);
0bbf2aa4 1137
c19d1205 1138 (*str)++;
0bbf2aa4 1139
c19d1205
ZW
1140 /* Sanity check -- should have raised a parse error above. */
1141 if (count == 0 || count > max_regs)
1142 abort ();
1143
1144 *pbase = base_reg;
1145
1146 /* Final test -- the registers must be consecutive. */
1147 mask >>= base_reg;
1148 for (i = 0; i < count; i++)
1149 {
1150 if ((mask & (1u << i)) == 0)
1151 {
1152 inst.error = _("non-contiguous register range");
1153 return FAIL;
1154 }
1155 }
1156
1157 return count;
b99bd4ef
NC
1158}
1159
c19d1205
ZW
1160/* Parse an explicit relocation suffix on an expression. This is
1161 either nothing, or a word in parentheses. Note that if !OBJ_ELF,
1162 arm_reloc_hsh contains no entries, so this function can only
1163 succeed if there is no () after the word. Returns -1 on error,
1164 BFD_RELOC_UNUSED if there wasn't any suffix. */
1165static int
1166parse_reloc (char **str)
b99bd4ef 1167{
c19d1205
ZW
1168 struct reloc_entry *r;
1169 char *p, *q;
b99bd4ef 1170
c19d1205
ZW
1171 if (**str != '(')
1172 return BFD_RELOC_UNUSED;
b99bd4ef 1173
c19d1205
ZW
1174 p = *str + 1;
1175 q = p;
1176
1177 while (*q && *q != ')' && *q != ',')
1178 q++;
1179 if (*q != ')')
1180 return -1;
1181
1182 if ((r = hash_find_n (arm_reloc_hsh, p, q - p)) == NULL)
1183 return -1;
1184
1185 *str = q + 1;
1186 return r->reloc;
b99bd4ef
NC
1187}
1188
c19d1205
ZW
1189/* Directives: register aliases. */
1190
b99bd4ef 1191static void
c19d1205 1192insert_reg_alias (char *str, int number, int type)
b99bd4ef 1193{
c19d1205
ZW
1194 struct reg_entry *new;
1195 const char *name;
b99bd4ef 1196
c19d1205
ZW
1197 if ((new = hash_find (arm_reg_hsh, str)) != 0)
1198 {
1199 if (new->builtin)
1200 as_warn (_("ignoring attempt to redefine built-in register '%s'"), str);
b99bd4ef 1201
c19d1205
ZW
1202 /* Only warn about a redefinition if it's not defined as the
1203 same register. */
1204 else if (new->number != number || new->type != type)
1205 as_warn (_("ignoring redefinition of register alias '%s'"), str);
69b97547 1206
c19d1205
ZW
1207 return;
1208 }
b99bd4ef 1209
c19d1205
ZW
1210 name = xstrdup (str);
1211 new = xmalloc (sizeof (struct reg_entry));
b99bd4ef 1212
c19d1205
ZW
1213 new->name = name;
1214 new->number = number;
1215 new->type = type;
1216 new->builtin = FALSE;
b99bd4ef 1217
c19d1205
ZW
1218 if (hash_insert (arm_reg_hsh, name, (PTR) new))
1219 abort ();
1220}
b99bd4ef 1221
c19d1205 1222/* Look for the .req directive. This is of the form:
b99bd4ef 1223
c19d1205 1224 new_register_name .req existing_register_name
b99bd4ef 1225
c19d1205
ZW
1226 If we find one, or if it looks sufficiently like one that we want to
1227 handle any error here, return non-zero. Otherwise return zero. */
b99bd4ef 1228
c19d1205
ZW
1229static int
1230create_register_alias (char * newname, char *p)
1231{
1232 struct reg_entry *old;
1233 char *oldname, *nbuf;
1234 size_t nlen;
b99bd4ef 1235
c19d1205
ZW
1236 /* The input scrubber ensures that whitespace after the mnemonic is
1237 collapsed to single spaces. */
1238 oldname = p;
1239 if (strncmp (oldname, " .req ", 6) != 0)
1240 return 0;
b99bd4ef 1241
c19d1205
ZW
1242 oldname += 6;
1243 if (*oldname == '\0')
1244 return 0;
b99bd4ef 1245
c19d1205
ZW
1246 old = hash_find (arm_reg_hsh, oldname);
1247 if (!old)
b99bd4ef 1248 {
c19d1205
ZW
1249 as_warn (_("unknown register '%s' -- .req ignored"), oldname);
1250 return 1;
b99bd4ef
NC
1251 }
1252
c19d1205
ZW
1253 /* If TC_CASE_SENSITIVE is defined, then newname already points to
1254 the desired alias name, and p points to its end. If not, then
1255 the desired alias name is in the global original_case_string. */
1256#ifdef TC_CASE_SENSITIVE
1257 nlen = p - newname;
1258#else
1259 newname = original_case_string;
1260 nlen = strlen (newname);
1261#endif
b99bd4ef 1262
c19d1205
ZW
1263 nbuf = alloca (nlen + 1);
1264 memcpy (nbuf, newname, nlen);
1265 nbuf[nlen] = '\0';
b99bd4ef 1266
c19d1205
ZW
1267 /* Create aliases under the new name as stated; an all-lowercase
1268 version of the new name; and an all-uppercase version of the new
1269 name. */
1270 insert_reg_alias (nbuf, old->number, old->type);
b99bd4ef 1271
c19d1205
ZW
1272 for (p = nbuf; *p; p++)
1273 *p = TOUPPER (*p);
1274
1275 if (strncmp (nbuf, newname, nlen))
1276 insert_reg_alias (nbuf, old->number, old->type);
1277
1278 for (p = nbuf; *p; p++)
1279 *p = TOLOWER (*p);
1280
1281 if (strncmp (nbuf, newname, nlen))
1282 insert_reg_alias (nbuf, old->number, old->type);
1283
1284 return 1;
b99bd4ef
NC
1285}
1286
c19d1205
ZW
1287/* Should never be called, as .req goes between the alias and the
1288 register name, not at the beginning of the line. */
b99bd4ef 1289static void
c19d1205 1290s_req (int a ATTRIBUTE_UNUSED)
b99bd4ef 1291{
c19d1205
ZW
1292 as_bad (_("invalid syntax for .req directive"));
1293}
b99bd4ef 1294
c19d1205
ZW
1295/* The .unreq directive deletes an alias which was previously defined
1296 by .req. For example:
b99bd4ef 1297
c19d1205
ZW
1298 my_alias .req r11
1299 .unreq my_alias */
b99bd4ef
NC
1300
1301static void
c19d1205 1302s_unreq (int a ATTRIBUTE_UNUSED)
b99bd4ef 1303{
c19d1205
ZW
1304 char * name;
1305 char saved_char;
b99bd4ef 1306
c19d1205
ZW
1307 name = input_line_pointer;
1308
1309 while (*input_line_pointer != 0
1310 && *input_line_pointer != ' '
1311 && *input_line_pointer != '\n')
1312 ++input_line_pointer;
1313
1314 saved_char = *input_line_pointer;
1315 *input_line_pointer = 0;
1316
1317 if (!*name)
1318 as_bad (_("invalid syntax for .unreq directive"));
1319 else
1320 {
1321 struct reg_entry *reg = hash_find (arm_reg_hsh, name);
1322
1323 if (!reg)
1324 as_bad (_("unknown register alias '%s'"), name);
1325 else if (reg->builtin)
1326 as_warn (_("ignoring attempt to undefine built-in register '%s'"),
1327 name);
1328 else
1329 {
1330 hash_delete (arm_reg_hsh, name);
1331 free ((char *) reg->name);
1332 free (reg);
1333 }
1334 }
b99bd4ef 1335
c19d1205 1336 *input_line_pointer = saved_char;
b99bd4ef
NC
1337 demand_empty_rest_of_line ();
1338}
1339
c19d1205
ZW
1340/* Directives: Instruction set selection. */
1341
1342#ifdef OBJ_ELF
1343/* This code is to handle mapping symbols as defined in the ARM ELF spec.
1344 (See "Mapping symbols", section 4.5.5, ARM AAELF version 1.0).
1345 Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
1346 and $d has type STT_OBJECT (BSF_OBJECT flag). Now all three are untyped. */
1347
1348static enum mstate mapstate = MAP_UNDEFINED;
b99bd4ef
NC
1349
1350static void
c19d1205 1351mapping_state (enum mstate state)
b99bd4ef 1352{
a737bd4d 1353 symbolS * symbolP;
c19d1205
ZW
1354 const char * symname;
1355 int type;
b99bd4ef 1356
c19d1205
ZW
1357 if (mapstate == state)
1358 /* The mapping symbol has already been emitted.
1359 There is nothing else to do. */
1360 return;
b99bd4ef 1361
c19d1205 1362 mapstate = state;
b99bd4ef 1363
c19d1205 1364 switch (state)
b99bd4ef 1365 {
c19d1205
ZW
1366 case MAP_DATA:
1367 symname = "$d";
1368 type = BSF_NO_FLAGS;
1369 break;
1370 case MAP_ARM:
1371 symname = "$a";
1372 type = BSF_NO_FLAGS;
1373 break;
1374 case MAP_THUMB:
1375 symname = "$t";
1376 type = BSF_NO_FLAGS;
1377 break;
1378 case MAP_UNDEFINED:
1379 return;
1380 default:
1381 abort ();
1382 }
1383
1384 seg_info (now_seg)->tc_segment_info_data.mapstate = state;
1385
1386 symbolP = symbol_new (symname, now_seg, (valueT) frag_now_fix (), frag_now);
1387 symbol_table_insert (symbolP);
1388 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
1389
1390 switch (state)
1391 {
1392 case MAP_ARM:
1393 THUMB_SET_FUNC (symbolP, 0);
1394 ARM_SET_THUMB (symbolP, 0);
1395 ARM_SET_INTERWORK (symbolP, support_interwork);
1396 break;
1397
1398 case MAP_THUMB:
1399 THUMB_SET_FUNC (symbolP, 1);
1400 ARM_SET_THUMB (symbolP, 1);
1401 ARM_SET_INTERWORK (symbolP, support_interwork);
1402 break;
1403
1404 case MAP_DATA:
1405 default:
1406 return;
1407 }
1408}
1409#else
1410#define mapping_state(x) /* nothing */
1411#endif
1412
1413/* Find the real, Thumb encoded start of a Thumb function. */
1414
1415static symbolS *
1416find_real_start (symbolS * symbolP)
1417{
1418 char * real_start;
1419 const char * name = S_GET_NAME (symbolP);
1420 symbolS * new_target;
1421
1422 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
1423#define STUB_NAME ".real_start_of"
1424
1425 if (name == NULL)
1426 abort ();
1427
37f6032b
ZW
1428 /* The compiler may generate BL instructions to local labels because
1429 it needs to perform a branch to a far away location. These labels
1430 do not have a corresponding ".real_start_of" label. We check
1431 both for S_IS_LOCAL and for a leading dot, to give a way to bypass
1432 the ".real_start_of" convention for nonlocal branches. */
1433 if (S_IS_LOCAL (symbolP) || name[0] == '.')
c19d1205
ZW
1434 return symbolP;
1435
37f6032b 1436 real_start = ACONCAT ((STUB_NAME, name, NULL));
c19d1205
ZW
1437 new_target = symbol_find (real_start);
1438
1439 if (new_target == NULL)
1440 {
1441 as_warn ("Failed to find real start of function: %s\n", name);
1442 new_target = symbolP;
1443 }
1444
c19d1205
ZW
1445 return new_target;
1446}
1447
1448static void
1449opcode_select (int width)
1450{
1451 switch (width)
1452 {
1453 case 16:
1454 if (! thumb_mode)
1455 {
1456 if (! (cpu_variant & ARM_EXT_V4T))
1457 as_bad (_("selected processor does not support THUMB opcodes"));
1458
1459 thumb_mode = 1;
1460 /* No need to force the alignment, since we will have been
1461 coming from ARM mode, which is word-aligned. */
1462 record_alignment (now_seg, 1);
1463 }
1464 mapping_state (MAP_THUMB);
1465 break;
1466
1467 case 32:
1468 if (thumb_mode)
1469 {
1470 if ((cpu_variant & ARM_ALL) == ARM_EXT_V4T)
1471 as_bad (_("selected processor does not support ARM opcodes"));
1472
1473 thumb_mode = 0;
1474
1475 if (!need_pass_2)
1476 frag_align (2, 0, 0);
1477
1478 record_alignment (now_seg, 1);
1479 }
1480 mapping_state (MAP_ARM);
1481 break;
1482
1483 default:
1484 as_bad (_("invalid instruction size selected (%d)"), width);
1485 }
1486}
1487
1488static void
1489s_arm (int ignore ATTRIBUTE_UNUSED)
1490{
1491 opcode_select (32);
1492 demand_empty_rest_of_line ();
1493}
1494
1495static void
1496s_thumb (int ignore ATTRIBUTE_UNUSED)
1497{
1498 opcode_select (16);
1499 demand_empty_rest_of_line ();
1500}
1501
1502static void
1503s_code (int unused ATTRIBUTE_UNUSED)
1504{
1505 int temp;
1506
1507 temp = get_absolute_expression ();
1508 switch (temp)
1509 {
1510 case 16:
1511 case 32:
1512 opcode_select (temp);
1513 break;
1514
1515 default:
1516 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
1517 }
1518}
1519
1520static void
1521s_force_thumb (int ignore ATTRIBUTE_UNUSED)
1522{
1523 /* If we are not already in thumb mode go into it, EVEN if
1524 the target processor does not support thumb instructions.
1525 This is used by gcc/config/arm/lib1funcs.asm for example
1526 to compile interworking support functions even if the
1527 target processor should not support interworking. */
1528 if (! thumb_mode)
1529 {
1530 thumb_mode = 2;
1531 record_alignment (now_seg, 1);
1532 }
1533
1534 demand_empty_rest_of_line ();
1535}
1536
1537static void
1538s_thumb_func (int ignore ATTRIBUTE_UNUSED)
1539{
1540 s_thumb (0);
1541
1542 /* The following label is the name/address of the start of a Thumb function.
1543 We need to know this for the interworking support. */
1544 label_is_thumb_function_name = TRUE;
1545}
1546
1547/* Perform a .set directive, but also mark the alias as
1548 being a thumb function. */
1549
1550static void
1551s_thumb_set (int equiv)
1552{
1553 /* XXX the following is a duplicate of the code for s_set() in read.c
1554 We cannot just call that code as we need to get at the symbol that
1555 is created. */
1556 char * name;
1557 char delim;
1558 char * end_name;
1559 symbolS * symbolP;
1560
1561 /* Especial apologies for the random logic:
1562 This just grew, and could be parsed much more simply!
1563 Dean - in haste. */
1564 name = input_line_pointer;
1565 delim = get_symbol_end ();
1566 end_name = input_line_pointer;
1567 *end_name = delim;
1568
1569 if (*input_line_pointer != ',')
1570 {
1571 *end_name = 0;
1572 as_bad (_("expected comma after name \"%s\""), name);
b99bd4ef
NC
1573 *end_name = delim;
1574 ignore_rest_of_line ();
1575 return;
1576 }
1577
1578 input_line_pointer++;
1579 *end_name = 0;
1580
1581 if (name[0] == '.' && name[1] == '\0')
1582 {
1583 /* XXX - this should not happen to .thumb_set. */
1584 abort ();
1585 }
1586
1587 if ((symbolP = symbol_find (name)) == NULL
1588 && (symbolP = md_undefined_symbol (name)) == NULL)
1589 {
1590#ifndef NO_LISTING
1591 /* When doing symbol listings, play games with dummy fragments living
1592 outside the normal fragment chain to record the file and line info
c19d1205 1593 for this symbol. */
b99bd4ef
NC
1594 if (listing & LISTING_SYMBOLS)
1595 {
1596 extern struct list_info_struct * listing_tail;
a737bd4d 1597 fragS * dummy_frag = xmalloc (sizeof (fragS));
b99bd4ef
NC
1598
1599 memset (dummy_frag, 0, sizeof (fragS));
1600 dummy_frag->fr_type = rs_fill;
1601 dummy_frag->line = listing_tail;
1602 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
1603 dummy_frag->fr_symbol = symbolP;
1604 }
1605 else
1606#endif
1607 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
1608
1609#ifdef OBJ_COFF
1610 /* "set" symbols are local unless otherwise specified. */
1611 SF_SET_LOCAL (symbolP);
1612#endif /* OBJ_COFF */
1613 } /* Make a new symbol. */
1614
1615 symbol_table_insert (symbolP);
1616
1617 * end_name = delim;
1618
1619 if (equiv
1620 && S_IS_DEFINED (symbolP)
1621 && S_GET_SEGMENT (symbolP) != reg_section)
1622 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
1623
1624 pseudo_set (symbolP);
1625
1626 demand_empty_rest_of_line ();
1627
c19d1205 1628 /* XXX Now we come to the Thumb specific bit of code. */
b99bd4ef
NC
1629
1630 THUMB_SET_FUNC (symbolP, 1);
1631 ARM_SET_THUMB (symbolP, 1);
1632#if defined OBJ_ELF || defined OBJ_COFF
1633 ARM_SET_INTERWORK (symbolP, support_interwork);
1634#endif
1635}
1636
c19d1205 1637/* Directives: Mode selection. */
b99bd4ef 1638
c19d1205
ZW
1639/* .syntax [unified|divided] - choose the new unified syntax
1640 (same for Arm and Thumb encoding, modulo slight differences in what
1641 can be represented) or the old divergent syntax for each mode. */
b99bd4ef 1642static void
c19d1205 1643s_syntax (int unused ATTRIBUTE_UNUSED)
b99bd4ef 1644{
c19d1205
ZW
1645 char *name, delim;
1646
1647 name = input_line_pointer;
1648 delim = get_symbol_end ();
1649
1650 if (!strcasecmp (name, "unified"))
1651 unified_syntax = TRUE;
1652 else if (!strcasecmp (name, "divided"))
1653 unified_syntax = FALSE;
1654 else
1655 {
1656 as_bad (_("unrecognized syntax mode \"%s\""), name);
1657 return;
1658 }
1659 *input_line_pointer = delim;
b99bd4ef
NC
1660 demand_empty_rest_of_line ();
1661}
1662
c19d1205
ZW
1663/* Directives: sectioning and alignment. */
1664
1665/* Same as s_align_ptwo but align 0 => align 2. */
1666
b99bd4ef 1667static void
c19d1205 1668s_align (int unused ATTRIBUTE_UNUSED)
b99bd4ef 1669{
a737bd4d 1670 int temp;
c19d1205
ZW
1671 long temp_fill;
1672 long max_alignment = 15;
b99bd4ef
NC
1673
1674 temp = get_absolute_expression ();
c19d1205
ZW
1675 if (temp > max_alignment)
1676 as_bad (_("alignment too large: %d assumed"), temp = max_alignment);
1677 else if (temp < 0)
b99bd4ef 1678 {
c19d1205
ZW
1679 as_bad (_("alignment negative. 0 assumed."));
1680 temp = 0;
1681 }
b99bd4ef 1682
c19d1205
ZW
1683 if (*input_line_pointer == ',')
1684 {
1685 input_line_pointer++;
1686 temp_fill = get_absolute_expression ();
b99bd4ef 1687 }
c19d1205
ZW
1688 else
1689 temp_fill = 0;
b99bd4ef 1690
c19d1205
ZW
1691 if (!temp)
1692 temp = 2;
b99bd4ef 1693
c19d1205
ZW
1694 /* Only make a frag if we HAVE to. */
1695 if (temp && !need_pass_2)
1696 frag_align (temp, (int) temp_fill, 0);
1697 demand_empty_rest_of_line ();
1698
1699 record_alignment (now_seg, temp);
b99bd4ef
NC
1700}
1701
c19d1205
ZW
1702static void
1703s_bss (int ignore ATTRIBUTE_UNUSED)
b99bd4ef 1704{
c19d1205
ZW
1705 /* We don't support putting frags in the BSS segment, we fake it by
1706 marking in_bss, then looking at s_skip for clues. */
1707 subseg_set (bss_section, 0);
1708 demand_empty_rest_of_line ();
1709 mapping_state (MAP_DATA);
1710}
b99bd4ef 1711
c19d1205
ZW
1712static void
1713s_even (int ignore ATTRIBUTE_UNUSED)
1714{
1715 /* Never make frag if expect extra pass. */
1716 if (!need_pass_2)
1717 frag_align (1, 0, 0);
b99bd4ef 1718
c19d1205 1719 record_alignment (now_seg, 1);
b99bd4ef 1720
c19d1205 1721 demand_empty_rest_of_line ();
b99bd4ef
NC
1722}
1723
c19d1205 1724/* Directives: Literal pools. */
a737bd4d 1725
c19d1205
ZW
1726static literal_pool *
1727find_literal_pool (void)
a737bd4d 1728{
c19d1205 1729 literal_pool * pool;
a737bd4d 1730
c19d1205 1731 for (pool = list_of_pools; pool != NULL; pool = pool->next)
a737bd4d 1732 {
c19d1205
ZW
1733 if (pool->section == now_seg
1734 && pool->sub_section == now_subseg)
1735 break;
a737bd4d
NC
1736 }
1737
c19d1205 1738 return pool;
a737bd4d
NC
1739}
1740
c19d1205
ZW
1741static literal_pool *
1742find_or_make_literal_pool (void)
a737bd4d 1743{
c19d1205
ZW
1744 /* Next literal pool ID number. */
1745 static unsigned int latest_pool_num = 1;
1746 literal_pool * pool;
a737bd4d 1747
c19d1205 1748 pool = find_literal_pool ();
a737bd4d 1749
c19d1205 1750 if (pool == NULL)
a737bd4d 1751 {
c19d1205
ZW
1752 /* Create a new pool. */
1753 pool = xmalloc (sizeof (* pool));
1754 if (! pool)
1755 return NULL;
a737bd4d 1756
c19d1205
ZW
1757 pool->next_free_entry = 0;
1758 pool->section = now_seg;
1759 pool->sub_section = now_subseg;
1760 pool->next = list_of_pools;
1761 pool->symbol = NULL;
1762
1763 /* Add it to the list. */
1764 list_of_pools = pool;
a737bd4d 1765 }
a737bd4d 1766
c19d1205
ZW
1767 /* New pools, and emptied pools, will have a NULL symbol. */
1768 if (pool->symbol == NULL)
a737bd4d 1769 {
c19d1205
ZW
1770 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
1771 (valueT) 0, &zero_address_frag);
1772 pool->id = latest_pool_num ++;
a737bd4d
NC
1773 }
1774
c19d1205
ZW
1775 /* Done. */
1776 return pool;
a737bd4d
NC
1777}
1778
c19d1205
ZW
1779/* Add the literal in the global 'inst'
1780 structure to the relevent literal pool. */
b99bd4ef
NC
1781
1782static int
c19d1205 1783add_to_lit_pool (void)
b99bd4ef 1784{
c19d1205
ZW
1785 literal_pool * pool;
1786 unsigned int entry;
b99bd4ef 1787
c19d1205
ZW
1788 pool = find_or_make_literal_pool ();
1789
1790 /* Check if this literal value is already in the pool. */
1791 for (entry = 0; entry < pool->next_free_entry; entry ++)
b99bd4ef 1792 {
c19d1205
ZW
1793 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
1794 && (inst.reloc.exp.X_op == O_constant)
1795 && (pool->literals[entry].X_add_number
1796 == inst.reloc.exp.X_add_number)
1797 && (pool->literals[entry].X_unsigned
1798 == inst.reloc.exp.X_unsigned))
1799 break;
1800
1801 if ((pool->literals[entry].X_op == inst.reloc.exp.X_op)
1802 && (inst.reloc.exp.X_op == O_symbol)
1803 && (pool->literals[entry].X_add_number
1804 == inst.reloc.exp.X_add_number)
1805 && (pool->literals[entry].X_add_symbol
1806 == inst.reloc.exp.X_add_symbol)
1807 && (pool->literals[entry].X_op_symbol
1808 == inst.reloc.exp.X_op_symbol))
1809 break;
b99bd4ef
NC
1810 }
1811
c19d1205
ZW
1812 /* Do we need to create a new entry? */
1813 if (entry == pool->next_free_entry)
1814 {
1815 if (entry >= MAX_LITERAL_POOL_SIZE)
1816 {
1817 inst.error = _("literal pool overflow");
1818 return FAIL;
1819 }
1820
1821 pool->literals[entry] = inst.reloc.exp;
1822 pool->next_free_entry += 1;
1823 }
b99bd4ef 1824
c19d1205
ZW
1825 inst.reloc.exp.X_op = O_symbol;
1826 inst.reloc.exp.X_add_number = ((int) entry) * 4;
1827 inst.reloc.exp.X_add_symbol = pool->symbol;
b99bd4ef 1828
c19d1205 1829 return SUCCESS;
b99bd4ef
NC
1830}
1831
c19d1205
ZW
1832/* Can't use symbol_new here, so have to create a symbol and then at
1833 a later date assign it a value. Thats what these functions do. */
e16bb312 1834
c19d1205
ZW
1835static void
1836symbol_locate (symbolS * symbolP,
1837 const char * name, /* It is copied, the caller can modify. */
1838 segT segment, /* Segment identifier (SEG_<something>). */
1839 valueT valu, /* Symbol value. */
1840 fragS * frag) /* Associated fragment. */
1841{
1842 unsigned int name_length;
1843 char * preserved_copy_of_name;
e16bb312 1844
c19d1205
ZW
1845 name_length = strlen (name) + 1; /* +1 for \0. */
1846 obstack_grow (&notes, name, name_length);
1847 preserved_copy_of_name = obstack_finish (&notes);
e16bb312 1848
c19d1205
ZW
1849#ifdef tc_canonicalize_symbol_name
1850 preserved_copy_of_name =
1851 tc_canonicalize_symbol_name (preserved_copy_of_name);
1852#endif
b99bd4ef 1853
c19d1205 1854 S_SET_NAME (symbolP, preserved_copy_of_name);
b99bd4ef 1855
c19d1205
ZW
1856 S_SET_SEGMENT (symbolP, segment);
1857 S_SET_VALUE (symbolP, valu);
1858 symbol_clear_list_pointers (symbolP);
b99bd4ef 1859
c19d1205 1860 symbol_set_frag (symbolP, frag);
b99bd4ef 1861
c19d1205
ZW
1862 /* Link to end of symbol chain. */
1863 {
1864 extern int symbol_table_frozen;
b99bd4ef 1865
c19d1205
ZW
1866 if (symbol_table_frozen)
1867 abort ();
1868 }
b99bd4ef 1869
c19d1205 1870 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
b99bd4ef 1871
c19d1205 1872 obj_symbol_new_hook (symbolP);
b99bd4ef 1873
c19d1205
ZW
1874#ifdef tc_symbol_new_hook
1875 tc_symbol_new_hook (symbolP);
1876#endif
1877
1878#ifdef DEBUG_SYMS
1879 verify_symbol_chain (symbol_rootP, symbol_lastP);
1880#endif /* DEBUG_SYMS */
b99bd4ef
NC
1881}
1882
b99bd4ef 1883
c19d1205
ZW
1884static void
1885s_ltorg (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 1886{
c19d1205
ZW
1887 unsigned int entry;
1888 literal_pool * pool;
1889 char sym_name[20];
b99bd4ef 1890
c19d1205
ZW
1891 pool = find_literal_pool ();
1892 if (pool == NULL
1893 || pool->symbol == NULL
1894 || pool->next_free_entry == 0)
1895 return;
b99bd4ef 1896
c19d1205 1897 mapping_state (MAP_DATA);
b99bd4ef 1898
c19d1205
ZW
1899 /* Align pool as you have word accesses.
1900 Only make a frag if we have to. */
1901 if (!need_pass_2)
1902 frag_align (2, 0, 0);
b99bd4ef 1903
c19d1205 1904 record_alignment (now_seg, 2);
b99bd4ef 1905
c19d1205 1906 sprintf (sym_name, "$$lit_\002%x", pool->id);
b99bd4ef 1907
c19d1205
ZW
1908 symbol_locate (pool->symbol, sym_name, now_seg,
1909 (valueT) frag_now_fix (), frag_now);
1910 symbol_table_insert (pool->symbol);
b99bd4ef 1911
c19d1205 1912 ARM_SET_THUMB (pool->symbol, thumb_mode);
b99bd4ef 1913
c19d1205
ZW
1914#if defined OBJ_COFF || defined OBJ_ELF
1915 ARM_SET_INTERWORK (pool->symbol, support_interwork);
1916#endif
6c43fab6 1917
c19d1205
ZW
1918 for (entry = 0; entry < pool->next_free_entry; entry ++)
1919 /* First output the expression in the instruction to the pool. */
1920 emit_expr (&(pool->literals[entry]), 4); /* .word */
b99bd4ef 1921
c19d1205
ZW
1922 /* Mark the pool as empty. */
1923 pool->next_free_entry = 0;
1924 pool->symbol = NULL;
b99bd4ef
NC
1925}
1926
c19d1205
ZW
1927#ifdef OBJ_ELF
1928/* Forward declarations for functions below, in the MD interface
1929 section. */
1930static void fix_new_arm (fragS *, int, short, expressionS *, int, int);
1931static valueT create_unwind_entry (int);
1932static void start_unwind_section (const segT, int);
1933static void add_unwind_opcode (valueT, int);
1934static void flush_pending_unwind (void);
b99bd4ef 1935
c19d1205 1936/* Directives: Data. */
b99bd4ef 1937
c19d1205
ZW
1938static void
1939s_arm_elf_cons (int nbytes)
1940{
1941 expressionS exp;
b99bd4ef 1942
c19d1205
ZW
1943#ifdef md_flush_pending_output
1944 md_flush_pending_output ();
1945#endif
b99bd4ef 1946
c19d1205 1947 if (is_it_end_of_statement ())
b99bd4ef 1948 {
c19d1205
ZW
1949 demand_empty_rest_of_line ();
1950 return;
b99bd4ef
NC
1951 }
1952
c19d1205
ZW
1953#ifdef md_cons_align
1954 md_cons_align (nbytes);
1955#endif
b99bd4ef 1956
c19d1205
ZW
1957 mapping_state (MAP_DATA);
1958 do
b99bd4ef 1959 {
c19d1205
ZW
1960 int reloc;
1961 char *base = input_line_pointer;
b99bd4ef 1962
c19d1205 1963 expression (& exp);
b99bd4ef 1964
c19d1205
ZW
1965 if (exp.X_op != O_symbol)
1966 emit_expr (&exp, (unsigned int) nbytes);
1967 else
1968 {
1969 char *before_reloc = input_line_pointer;
1970 reloc = parse_reloc (&input_line_pointer);
1971 if (reloc == -1)
1972 {
1973 as_bad (_("unrecognized relocation suffix"));
1974 ignore_rest_of_line ();
1975 return;
1976 }
1977 else if (reloc == BFD_RELOC_UNUSED)
1978 emit_expr (&exp, (unsigned int) nbytes);
1979 else
1980 {
1981 reloc_howto_type *howto = bfd_reloc_type_lookup (stdoutput, reloc);
1982 int size = bfd_get_reloc_size (howto);
b99bd4ef 1983
2fc8bdac
ZW
1984 if (reloc == BFD_RELOC_ARM_PLT32)
1985 {
1986 as_bad (_("(plt) is only valid on branch targets"));
1987 reloc = BFD_RELOC_UNUSED;
1988 size = 0;
1989 }
1990
c19d1205 1991 if (size > nbytes)
2fc8bdac 1992 as_bad (_("%s relocations do not fit in %d bytes"),
c19d1205
ZW
1993 howto->name, nbytes);
1994 else
1995 {
1996 /* We've parsed an expression stopping at O_symbol.
1997 But there may be more expression left now that we
1998 have parsed the relocation marker. Parse it again.
1999 XXX Surely there is a cleaner way to do this. */
2000 char *p = input_line_pointer;
2001 int offset;
2002 char *save_buf = alloca (input_line_pointer - base);
2003 memcpy (save_buf, base, input_line_pointer - base);
2004 memmove (base + (input_line_pointer - before_reloc),
2005 base, before_reloc - base);
2006
2007 input_line_pointer = base + (input_line_pointer-before_reloc);
2008 expression (&exp);
2009 memcpy (base, save_buf, p - base);
2010
2011 offset = nbytes - size;
2012 p = frag_more ((int) nbytes);
2013 fix_new_exp (frag_now, p - frag_now->fr_literal + offset,
2014 size, &exp, 0, reloc);
2015 }
2016 }
2017 }
b99bd4ef 2018 }
c19d1205 2019 while (*input_line_pointer++ == ',');
b99bd4ef 2020
c19d1205
ZW
2021 /* Put terminator back into stream. */
2022 input_line_pointer --;
2023 demand_empty_rest_of_line ();
b99bd4ef
NC
2024}
2025
b99bd4ef 2026
c19d1205 2027/* Parse a .rel31 directive. */
b99bd4ef 2028
c19d1205
ZW
2029static void
2030s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
2031{
2032 expressionS exp;
2033 char *p;
2034 valueT highbit;
b99bd4ef 2035
c19d1205
ZW
2036 highbit = 0;
2037 if (*input_line_pointer == '1')
2038 highbit = 0x80000000;
2039 else if (*input_line_pointer != '0')
2040 as_bad (_("expected 0 or 1"));
b99bd4ef 2041
c19d1205
ZW
2042 input_line_pointer++;
2043 if (*input_line_pointer != ',')
2044 as_bad (_("missing comma"));
2045 input_line_pointer++;
b99bd4ef 2046
c19d1205
ZW
2047#ifdef md_flush_pending_output
2048 md_flush_pending_output ();
2049#endif
b99bd4ef 2050
c19d1205
ZW
2051#ifdef md_cons_align
2052 md_cons_align (4);
2053#endif
b99bd4ef 2054
c19d1205 2055 mapping_state (MAP_DATA);
b99bd4ef 2056
c19d1205 2057 expression (&exp);
b99bd4ef 2058
c19d1205
ZW
2059 p = frag_more (4);
2060 md_number_to_chars (p, highbit, 4);
2061 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
2062 BFD_RELOC_ARM_PREL31);
b99bd4ef 2063
c19d1205 2064 demand_empty_rest_of_line ();
b99bd4ef
NC
2065}
2066
c19d1205 2067/* Directives: AEABI stack-unwind tables. */
b99bd4ef 2068
c19d1205 2069/* Parse an unwind_fnstart directive. Simply records the current location. */
b99bd4ef 2070
c19d1205
ZW
2071static void
2072s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
2073{
2074 demand_empty_rest_of_line ();
2075 /* Mark the start of the function. */
2076 unwind.proc_start = expr_build_dot ();
b99bd4ef 2077
c19d1205
ZW
2078 /* Reset the rest of the unwind info. */
2079 unwind.opcode_count = 0;
2080 unwind.table_entry = NULL;
2081 unwind.personality_routine = NULL;
2082 unwind.personality_index = -1;
2083 unwind.frame_size = 0;
2084 unwind.fp_offset = 0;
2085 unwind.fp_reg = 13;
2086 unwind.fp_used = 0;
2087 unwind.sp_restored = 0;
2088}
b99bd4ef 2089
b99bd4ef 2090
c19d1205
ZW
2091/* Parse a handlerdata directive. Creates the exception handling table entry
2092 for the function. */
b99bd4ef 2093
c19d1205
ZW
2094static void
2095s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
2096{
2097 demand_empty_rest_of_line ();
2098 if (unwind.table_entry)
2099 as_bad (_("dupicate .handlerdata directive"));
f02232aa 2100
c19d1205
ZW
2101 create_unwind_entry (1);
2102}
a737bd4d 2103
c19d1205 2104/* Parse an unwind_fnend directive. Generates the index table entry. */
b99bd4ef 2105
c19d1205
ZW
2106static void
2107s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
2108{
2109 long where;
2110 char *ptr;
2111 valueT val;
f02232aa 2112
c19d1205 2113 demand_empty_rest_of_line ();
f02232aa 2114
c19d1205
ZW
2115 /* Add eh table entry. */
2116 if (unwind.table_entry == NULL)
2117 val = create_unwind_entry (0);
2118 else
2119 val = 0;
f02232aa 2120
c19d1205
ZW
2121 /* Add index table entry. This is two words. */
2122 start_unwind_section (unwind.saved_seg, 1);
2123 frag_align (2, 0, 0);
2124 record_alignment (now_seg, 2);
b99bd4ef 2125
c19d1205
ZW
2126 ptr = frag_more (8);
2127 where = frag_now_fix () - 8;
f02232aa 2128
c19d1205
ZW
2129 /* Self relative offset of the function start. */
2130 fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
2131 BFD_RELOC_ARM_PREL31);
f02232aa 2132
c19d1205
ZW
2133 /* Indicate dependency on EHABI-defined personality routines to the
2134 linker, if it hasn't been done already. */
2135 if (unwind.personality_index >= 0 && unwind.personality_index < 3
2136 && !(marked_pr_dependency & (1 << unwind.personality_index)))
2137 {
2138 static const char *const name[] = {
2139 "__aeabi_unwind_cpp_pr0",
2140 "__aeabi_unwind_cpp_pr1",
2141 "__aeabi_unwind_cpp_pr2"
2142 };
2143 symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
2144 fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
2145 marked_pr_dependency |= 1 << unwind.personality_index;
2146 seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
2147 = marked_pr_dependency;
2148 }
f02232aa 2149
c19d1205
ZW
2150 if (val)
2151 /* Inline exception table entry. */
2152 md_number_to_chars (ptr + 4, val, 4);
2153 else
2154 /* Self relative offset of the table entry. */
2155 fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
2156 BFD_RELOC_ARM_PREL31);
f02232aa 2157
c19d1205
ZW
2158 /* Restore the original section. */
2159 subseg_set (unwind.saved_seg, unwind.saved_subseg);
2160}
f02232aa 2161
f02232aa 2162
c19d1205 2163/* Parse an unwind_cantunwind directive. */
b99bd4ef 2164
c19d1205
ZW
2165static void
2166s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
2167{
2168 demand_empty_rest_of_line ();
2169 if (unwind.personality_routine || unwind.personality_index != -1)
2170 as_bad (_("personality routine specified for cantunwind frame"));
b99bd4ef 2171
c19d1205
ZW
2172 unwind.personality_index = -2;
2173}
b99bd4ef 2174
b99bd4ef 2175
c19d1205 2176/* Parse a personalityindex directive. */
b99bd4ef 2177
c19d1205
ZW
2178static void
2179s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
2180{
2181 expressionS exp;
b99bd4ef 2182
c19d1205
ZW
2183 if (unwind.personality_routine || unwind.personality_index != -1)
2184 as_bad (_("duplicate .personalityindex directive"));
b99bd4ef 2185
c19d1205 2186 expression (&exp);
b99bd4ef 2187
c19d1205
ZW
2188 if (exp.X_op != O_constant
2189 || exp.X_add_number < 0 || exp.X_add_number > 15)
b99bd4ef 2190 {
c19d1205
ZW
2191 as_bad (_("bad personality routine number"));
2192 ignore_rest_of_line ();
2193 return;
b99bd4ef
NC
2194 }
2195
c19d1205 2196 unwind.personality_index = exp.X_add_number;
b99bd4ef 2197
c19d1205
ZW
2198 demand_empty_rest_of_line ();
2199}
e16bb312 2200
e16bb312 2201
c19d1205 2202/* Parse a personality directive. */
e16bb312 2203
c19d1205
ZW
2204static void
2205s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
2206{
2207 char *name, *p, c;
a737bd4d 2208
c19d1205
ZW
2209 if (unwind.personality_routine || unwind.personality_index != -1)
2210 as_bad (_("duplicate .personality directive"));
a737bd4d 2211
c19d1205
ZW
2212 name = input_line_pointer;
2213 c = get_symbol_end ();
2214 p = input_line_pointer;
2215 unwind.personality_routine = symbol_find_or_make (name);
2216 *p = c;
2217 demand_empty_rest_of_line ();
2218}
e16bb312 2219
e16bb312 2220
c19d1205 2221/* Parse a directive saving core registers. */
e16bb312 2222
c19d1205
ZW
2223static void
2224s_arm_unwind_save_core (void)
e16bb312 2225{
c19d1205
ZW
2226 valueT op;
2227 long range;
2228 int n;
e16bb312 2229
c19d1205
ZW
2230 range = parse_reg_list (&input_line_pointer);
2231 if (range == FAIL)
e16bb312 2232 {
c19d1205
ZW
2233 as_bad (_("expected register list"));
2234 ignore_rest_of_line ();
2235 return;
2236 }
e16bb312 2237
c19d1205 2238 demand_empty_rest_of_line ();
e16bb312 2239
c19d1205
ZW
2240 /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
2241 into .unwind_save {..., sp...}. We aren't bothered about the value of
2242 ip because it is clobbered by calls. */
2243 if (unwind.sp_restored && unwind.fp_reg == 12
2244 && (range & 0x3000) == 0x1000)
2245 {
2246 unwind.opcode_count--;
2247 unwind.sp_restored = 0;
2248 range = (range | 0x2000) & ~0x1000;
2249 unwind.pending_offset = 0;
2250 }
e16bb312 2251
01ae4198
DJ
2252 /* Pop r4-r15. */
2253 if (range & 0xfff0)
c19d1205 2254 {
01ae4198
DJ
2255 /* See if we can use the short opcodes. These pop a block of up to 8
2256 registers starting with r4, plus maybe r14. */
2257 for (n = 0; n < 8; n++)
2258 {
2259 /* Break at the first non-saved register. */
2260 if ((range & (1 << (n + 4))) == 0)
2261 break;
2262 }
2263 /* See if there are any other bits set. */
2264 if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
2265 {
2266 /* Use the long form. */
2267 op = 0x8000 | ((range >> 4) & 0xfff);
2268 add_unwind_opcode (op, 2);
2269 }
0dd132b6 2270 else
01ae4198
DJ
2271 {
2272 /* Use the short form. */
2273 if (range & 0x4000)
2274 op = 0xa8; /* Pop r14. */
2275 else
2276 op = 0xa0; /* Do not pop r14. */
2277 op |= (n - 1);
2278 add_unwind_opcode (op, 1);
2279 }
c19d1205 2280 }
0dd132b6 2281
c19d1205
ZW
2282 /* Pop r0-r3. */
2283 if (range & 0xf)
2284 {
2285 op = 0xb100 | (range & 0xf);
2286 add_unwind_opcode (op, 2);
0dd132b6
NC
2287 }
2288
c19d1205
ZW
2289 /* Record the number of bytes pushed. */
2290 for (n = 0; n < 16; n++)
2291 {
2292 if (range & (1 << n))
2293 unwind.frame_size += 4;
2294 }
0dd132b6
NC
2295}
2296
c19d1205
ZW
2297
2298/* Parse a directive saving FPA registers. */
b99bd4ef
NC
2299
2300static void
c19d1205 2301s_arm_unwind_save_fpa (int reg)
b99bd4ef 2302{
c19d1205
ZW
2303 expressionS exp;
2304 int num_regs;
2305 valueT op;
b99bd4ef 2306
c19d1205
ZW
2307 /* Get Number of registers to transfer. */
2308 if (skip_past_comma (&input_line_pointer) != FAIL)
2309 expression (&exp);
2310 else
2311 exp.X_op = O_illegal;
b99bd4ef 2312
c19d1205 2313 if (exp.X_op != O_constant)
b99bd4ef 2314 {
c19d1205
ZW
2315 as_bad (_("expected , <constant>"));
2316 ignore_rest_of_line ();
b99bd4ef
NC
2317 return;
2318 }
2319
c19d1205
ZW
2320 num_regs = exp.X_add_number;
2321
2322 if (num_regs < 1 || num_regs > 4)
b99bd4ef 2323 {
c19d1205
ZW
2324 as_bad (_("number of registers must be in the range [1:4]"));
2325 ignore_rest_of_line ();
b99bd4ef
NC
2326 return;
2327 }
2328
c19d1205 2329 demand_empty_rest_of_line ();
b99bd4ef 2330
c19d1205
ZW
2331 if (reg == 4)
2332 {
2333 /* Short form. */
2334 op = 0xb4 | (num_regs - 1);
2335 add_unwind_opcode (op, 1);
2336 }
b99bd4ef
NC
2337 else
2338 {
c19d1205
ZW
2339 /* Long form. */
2340 op = 0xc800 | (reg << 4) | (num_regs - 1);
2341 add_unwind_opcode (op, 2);
b99bd4ef 2342 }
c19d1205 2343 unwind.frame_size += num_regs * 12;
b99bd4ef
NC
2344}
2345
c19d1205
ZW
2346
2347/* Parse a directive saving VFP registers. */
b99bd4ef
NC
2348
2349static void
c19d1205 2350s_arm_unwind_save_vfp (void)
b99bd4ef 2351{
c19d1205 2352 int count;
ca3f61f7 2353 unsigned int reg;
c19d1205 2354 valueT op;
b99bd4ef 2355
c19d1205
ZW
2356 count = parse_vfp_reg_list (&input_line_pointer, &reg, 1);
2357 if (count == FAIL)
b99bd4ef 2358 {
c19d1205
ZW
2359 as_bad (_("expected register list"));
2360 ignore_rest_of_line ();
b99bd4ef
NC
2361 return;
2362 }
2363
c19d1205 2364 demand_empty_rest_of_line ();
b99bd4ef 2365
c19d1205 2366 if (reg == 8)
b99bd4ef 2367 {
c19d1205
ZW
2368 /* Short form. */
2369 op = 0xb8 | (count - 1);
2370 add_unwind_opcode (op, 1);
b99bd4ef 2371 }
c19d1205 2372 else
b99bd4ef 2373 {
c19d1205
ZW
2374 /* Long form. */
2375 op = 0xb300 | (reg << 4) | (count - 1);
2376 add_unwind_opcode (op, 2);
b99bd4ef 2377 }
c19d1205
ZW
2378 unwind.frame_size += count * 8 + 4;
2379}
b99bd4ef 2380
b99bd4ef 2381
c19d1205
ZW
2382/* Parse a directive saving iWMMXt data registers. */
2383
2384static void
2385s_arm_unwind_save_mmxwr (void)
2386{
2387 int reg;
2388 int hi_reg;
2389 int i;
2390 unsigned mask = 0;
2391 valueT op;
b99bd4ef 2392
c19d1205
ZW
2393 if (*input_line_pointer == '{')
2394 input_line_pointer++;
b99bd4ef 2395
c19d1205 2396 do
b99bd4ef 2397 {
c19d1205 2398 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
b99bd4ef 2399
c19d1205 2400 if (reg == FAIL)
b99bd4ef 2401 {
c19d1205
ZW
2402 as_bad (_(reg_expected_msgs[REG_TYPE_MMXWR]));
2403 goto error;
b99bd4ef
NC
2404 }
2405
c19d1205
ZW
2406 if (mask >> reg)
2407 as_tsktsk (_("register list not in ascending order"));
2408 mask |= 1 << reg;
b99bd4ef 2409
c19d1205
ZW
2410 if (*input_line_pointer == '-')
2411 {
2412 input_line_pointer++;
2413 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
2414 if (hi_reg == FAIL)
2415 {
2416 as_bad (_(reg_expected_msgs[REG_TYPE_MMXWR]));
2417 goto error;
2418 }
2419 else if (reg >= hi_reg)
2420 {
2421 as_bad (_("bad register range"));
2422 goto error;
2423 }
2424 for (; reg < hi_reg; reg++)
2425 mask |= 1 << reg;
2426 }
2427 }
2428 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 2429
c19d1205
ZW
2430 if (*input_line_pointer == '}')
2431 input_line_pointer++;
b99bd4ef 2432
c19d1205 2433 demand_empty_rest_of_line ();
b99bd4ef 2434
c19d1205
ZW
2435 /* Generate any deferred opcodes becuuse we're going to be looking at
2436 the list. */
2437 flush_pending_unwind ();
b99bd4ef 2438
c19d1205 2439 for (i = 0; i < 16; i++)
b99bd4ef 2440 {
c19d1205
ZW
2441 if (mask & (1 << i))
2442 unwind.frame_size += 8;
b99bd4ef
NC
2443 }
2444
c19d1205
ZW
2445 /* Attempt to combine with a previous opcode. We do this because gcc
2446 likes to output separate unwind directives for a single block of
2447 registers. */
2448 if (unwind.opcode_count > 0)
b99bd4ef 2449 {
c19d1205
ZW
2450 i = unwind.opcodes[unwind.opcode_count - 1];
2451 if ((i & 0xf8) == 0xc0)
2452 {
2453 i &= 7;
2454 /* Only merge if the blocks are contiguous. */
2455 if (i < 6)
2456 {
2457 if ((mask & 0xfe00) == (1 << 9))
2458 {
2459 mask |= ((1 << (i + 11)) - 1) & 0xfc00;
2460 unwind.opcode_count--;
2461 }
2462 }
2463 else if (i == 6 && unwind.opcode_count >= 2)
2464 {
2465 i = unwind.opcodes[unwind.opcode_count - 2];
2466 reg = i >> 4;
2467 i &= 0xf;
b99bd4ef 2468
c19d1205
ZW
2469 op = 0xffff << (reg - 1);
2470 if (reg > 0
2471 || ((mask & op) == (1u << (reg - 1))))
2472 {
2473 op = (1 << (reg + i + 1)) - 1;
2474 op &= ~((1 << reg) - 1);
2475 mask |= op;
2476 unwind.opcode_count -= 2;
2477 }
2478 }
2479 }
b99bd4ef
NC
2480 }
2481
c19d1205
ZW
2482 hi_reg = 15;
2483 /* We want to generate opcodes in the order the registers have been
2484 saved, ie. descending order. */
2485 for (reg = 15; reg >= -1; reg--)
b99bd4ef 2486 {
c19d1205
ZW
2487 /* Save registers in blocks. */
2488 if (reg < 0
2489 || !(mask & (1 << reg)))
2490 {
2491 /* We found an unsaved reg. Generate opcodes to save the
2492 preceeding block. */
2493 if (reg != hi_reg)
2494 {
2495 if (reg == 9)
2496 {
2497 /* Short form. */
2498 op = 0xc0 | (hi_reg - 10);
2499 add_unwind_opcode (op, 1);
2500 }
2501 else
2502 {
2503 /* Long form. */
2504 op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
2505 add_unwind_opcode (op, 2);
2506 }
2507 }
2508 hi_reg = reg - 1;
2509 }
b99bd4ef
NC
2510 }
2511
c19d1205
ZW
2512 return;
2513error:
2514 ignore_rest_of_line ();
b99bd4ef
NC
2515}
2516
2517static void
c19d1205 2518s_arm_unwind_save_mmxwcg (void)
b99bd4ef 2519{
c19d1205
ZW
2520 int reg;
2521 int hi_reg;
2522 unsigned mask = 0;
2523 valueT op;
b99bd4ef 2524
c19d1205
ZW
2525 if (*input_line_pointer == '{')
2526 input_line_pointer++;
b99bd4ef 2527
c19d1205 2528 do
b99bd4ef 2529 {
c19d1205 2530 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
b99bd4ef 2531
c19d1205
ZW
2532 if (reg == FAIL)
2533 {
2534 as_bad (_(reg_expected_msgs[REG_TYPE_MMXWCG]));
2535 goto error;
2536 }
b99bd4ef 2537
c19d1205
ZW
2538 reg -= 8;
2539 if (mask >> reg)
2540 as_tsktsk (_("register list not in ascending order"));
2541 mask |= 1 << reg;
b99bd4ef 2542
c19d1205
ZW
2543 if (*input_line_pointer == '-')
2544 {
2545 input_line_pointer++;
2546 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
2547 if (hi_reg == FAIL)
2548 {
2549 as_bad (_(reg_expected_msgs[REG_TYPE_MMXWCG]));
2550 goto error;
2551 }
2552 else if (reg >= hi_reg)
2553 {
2554 as_bad (_("bad register range"));
2555 goto error;
2556 }
2557 for (; reg < hi_reg; reg++)
2558 mask |= 1 << reg;
2559 }
b99bd4ef 2560 }
c19d1205 2561 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 2562
c19d1205
ZW
2563 if (*input_line_pointer == '}')
2564 input_line_pointer++;
b99bd4ef 2565
c19d1205
ZW
2566 demand_empty_rest_of_line ();
2567
2568 /* Generate any deferred opcodes becuuse we're going to be looking at
2569 the list. */
2570 flush_pending_unwind ();
b99bd4ef 2571
c19d1205 2572 for (reg = 0; reg < 16; reg++)
b99bd4ef 2573 {
c19d1205
ZW
2574 if (mask & (1 << reg))
2575 unwind.frame_size += 4;
b99bd4ef 2576 }
c19d1205
ZW
2577 op = 0xc700 | mask;
2578 add_unwind_opcode (op, 2);
2579 return;
2580error:
2581 ignore_rest_of_line ();
b99bd4ef
NC
2582}
2583
c19d1205
ZW
2584
2585/* Parse an unwind_save directive. */
2586
b99bd4ef 2587static void
c19d1205 2588s_arm_unwind_save (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 2589{
c19d1205
ZW
2590 char *peek;
2591 struct reg_entry *reg;
2592 bfd_boolean had_brace = FALSE;
b99bd4ef 2593
c19d1205
ZW
2594 /* Figure out what sort of save we have. */
2595 peek = input_line_pointer;
b99bd4ef 2596
c19d1205 2597 if (*peek == '{')
b99bd4ef 2598 {
c19d1205
ZW
2599 had_brace = TRUE;
2600 peek++;
b99bd4ef
NC
2601 }
2602
c19d1205 2603 reg = arm_reg_parse_multi (&peek);
b99bd4ef 2604
c19d1205 2605 if (!reg)
b99bd4ef 2606 {
c19d1205
ZW
2607 as_bad (_("register expected"));
2608 ignore_rest_of_line ();
b99bd4ef
NC
2609 return;
2610 }
2611
c19d1205 2612 switch (reg->type)
b99bd4ef 2613 {
c19d1205
ZW
2614 case REG_TYPE_FN:
2615 if (had_brace)
2616 {
2617 as_bad (_("FPA .unwind_save does not take a register list"));
2618 ignore_rest_of_line ();
2619 return;
2620 }
2621 s_arm_unwind_save_fpa (reg->number);
b99bd4ef 2622 return;
c19d1205
ZW
2623
2624 case REG_TYPE_RN: s_arm_unwind_save_core (); return;
2625 case REG_TYPE_VFD: s_arm_unwind_save_vfp (); return;
2626 case REG_TYPE_MMXWR: s_arm_unwind_save_mmxwr (); return;
2627 case REG_TYPE_MMXWCG: s_arm_unwind_save_mmxwcg (); return;
2628
2629 default:
2630 as_bad (_(".unwind_save does not support this kind of register"));
2631 ignore_rest_of_line ();
b99bd4ef 2632 }
c19d1205 2633}
b99bd4ef 2634
b99bd4ef 2635
c19d1205
ZW
2636/* Parse an unwind_movsp directive. */
2637
2638static void
2639s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
2640{
2641 int reg;
2642 valueT op;
2643
2644 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
2645 if (reg == FAIL)
b99bd4ef 2646 {
c19d1205
ZW
2647 as_bad (_(reg_expected_msgs[REG_TYPE_RN]));
2648 ignore_rest_of_line ();
b99bd4ef
NC
2649 return;
2650 }
c19d1205 2651 demand_empty_rest_of_line ();
b99bd4ef 2652
c19d1205 2653 if (reg == REG_SP || reg == REG_PC)
b99bd4ef 2654 {
c19d1205 2655 as_bad (_("SP and PC not permitted in .unwind_movsp directive"));
b99bd4ef
NC
2656 return;
2657 }
2658
c19d1205
ZW
2659 if (unwind.fp_reg != REG_SP)
2660 as_bad (_("unexpected .unwind_movsp directive"));
b99bd4ef 2661
c19d1205
ZW
2662 /* Generate opcode to restore the value. */
2663 op = 0x90 | reg;
2664 add_unwind_opcode (op, 1);
2665
2666 /* Record the information for later. */
2667 unwind.fp_reg = reg;
2668 unwind.fp_offset = unwind.frame_size;
2669 unwind.sp_restored = 1;
b05fe5cf
ZW
2670}
2671
c19d1205
ZW
2672/* Parse an unwind_pad directive. */
2673
b05fe5cf 2674static void
c19d1205 2675s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
b05fe5cf 2676{
c19d1205 2677 int offset;
b05fe5cf 2678
c19d1205
ZW
2679 if (immediate_for_directive (&offset) == FAIL)
2680 return;
b99bd4ef 2681
c19d1205
ZW
2682 if (offset & 3)
2683 {
2684 as_bad (_("stack increment must be multiple of 4"));
2685 ignore_rest_of_line ();
2686 return;
2687 }
b99bd4ef 2688
c19d1205
ZW
2689 /* Don't generate any opcodes, just record the details for later. */
2690 unwind.frame_size += offset;
2691 unwind.pending_offset += offset;
2692
2693 demand_empty_rest_of_line ();
2694}
2695
2696/* Parse an unwind_setfp directive. */
2697
2698static void
2699s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 2700{
c19d1205
ZW
2701 int sp_reg;
2702 int fp_reg;
2703 int offset;
2704
2705 fp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
2706 if (skip_past_comma (&input_line_pointer) == FAIL)
2707 sp_reg = FAIL;
2708 else
2709 sp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
b99bd4ef 2710
c19d1205
ZW
2711 if (fp_reg == FAIL || sp_reg == FAIL)
2712 {
2713 as_bad (_("expected <reg>, <reg>"));
2714 ignore_rest_of_line ();
2715 return;
2716 }
b99bd4ef 2717
c19d1205
ZW
2718 /* Optional constant. */
2719 if (skip_past_comma (&input_line_pointer) != FAIL)
2720 {
2721 if (immediate_for_directive (&offset) == FAIL)
2722 return;
2723 }
2724 else
2725 offset = 0;
a737bd4d 2726
c19d1205 2727 demand_empty_rest_of_line ();
a737bd4d 2728
c19d1205 2729 if (sp_reg != 13 && sp_reg != unwind.fp_reg)
a737bd4d 2730 {
c19d1205
ZW
2731 as_bad (_("register must be either sp or set by a previous"
2732 "unwind_movsp directive"));
2733 return;
a737bd4d
NC
2734 }
2735
c19d1205
ZW
2736 /* Don't generate any opcodes, just record the information for later. */
2737 unwind.fp_reg = fp_reg;
2738 unwind.fp_used = 1;
2739 if (sp_reg == 13)
2740 unwind.fp_offset = unwind.frame_size - offset;
2741 else
2742 unwind.fp_offset -= offset;
a737bd4d
NC
2743}
2744
c19d1205
ZW
2745/* Parse an unwind_raw directive. */
2746
2747static void
2748s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
a737bd4d 2749{
c19d1205
ZW
2750 expressionS exp;
2751 /* This is an arbitary limit. */
2752 unsigned char op[16];
2753 int count;
a737bd4d 2754
c19d1205
ZW
2755 expression (&exp);
2756 if (exp.X_op == O_constant
2757 && skip_past_comma (&input_line_pointer) != FAIL)
a737bd4d 2758 {
c19d1205
ZW
2759 unwind.frame_size += exp.X_add_number;
2760 expression (&exp);
2761 }
2762 else
2763 exp.X_op = O_illegal;
a737bd4d 2764
c19d1205
ZW
2765 if (exp.X_op != O_constant)
2766 {
2767 as_bad (_("expected <offset>, <opcode>"));
2768 ignore_rest_of_line ();
2769 return;
2770 }
a737bd4d 2771
c19d1205 2772 count = 0;
a737bd4d 2773
c19d1205
ZW
2774 /* Parse the opcode. */
2775 for (;;)
2776 {
2777 if (count >= 16)
2778 {
2779 as_bad (_("unwind opcode too long"));
2780 ignore_rest_of_line ();
a737bd4d 2781 }
c19d1205 2782 if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
a737bd4d 2783 {
c19d1205
ZW
2784 as_bad (_("invalid unwind opcode"));
2785 ignore_rest_of_line ();
2786 return;
a737bd4d 2787 }
c19d1205 2788 op[count++] = exp.X_add_number;
a737bd4d 2789
c19d1205
ZW
2790 /* Parse the next byte. */
2791 if (skip_past_comma (&input_line_pointer) == FAIL)
2792 break;
a737bd4d 2793
c19d1205
ZW
2794 expression (&exp);
2795 }
b99bd4ef 2796
c19d1205
ZW
2797 /* Add the opcode bytes in reverse order. */
2798 while (count--)
2799 add_unwind_opcode (op[count], 1);
b99bd4ef 2800
c19d1205 2801 demand_empty_rest_of_line ();
b99bd4ef 2802}
ee065d83
PB
2803
2804
2805/* Parse a .eabi_attribute directive. */
2806
2807static void
2808s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
2809{
2810 expressionS exp;
2811 bfd_boolean is_string;
2812 int tag;
2813 unsigned int i = 0;
2814 char *s = NULL;
2815 char saved_char;
2816
2817 expression (& exp);
2818 if (exp.X_op != O_constant)
2819 goto bad;
2820
2821 tag = exp.X_add_number;
2822 if (tag == 4 || tag == 5 || tag == 32 || (tag > 32 && (tag & 1) != 0))
2823 is_string = 1;
2824 else
2825 is_string = 0;
2826
2827 if (skip_past_comma (&input_line_pointer) == FAIL)
2828 goto bad;
2829 if (tag == 32 || !is_string)
2830 {
2831 expression (& exp);
2832 if (exp.X_op != O_constant)
2833 {
2834 as_bad (_("expected numeric constant"));
2835 ignore_rest_of_line ();
2836 return;
2837 }
2838 i = exp.X_add_number;
2839 }
2840 if (tag == Tag_compatibility
2841 && skip_past_comma (&input_line_pointer) == FAIL)
2842 {
2843 as_bad (_("expected comma"));
2844 ignore_rest_of_line ();
2845 return;
2846 }
2847 if (is_string)
2848 {
2849 skip_whitespace(input_line_pointer);
2850 if (*input_line_pointer != '"')
2851 goto bad_string;
2852 input_line_pointer++;
2853 s = input_line_pointer;
2854 while (*input_line_pointer && *input_line_pointer != '"')
2855 input_line_pointer++;
2856 if (*input_line_pointer != '"')
2857 goto bad_string;
2858 saved_char = *input_line_pointer;
2859 *input_line_pointer = 0;
2860 }
2861 else
2862 {
2863 s = NULL;
2864 saved_char = 0;
2865 }
2866
2867 if (tag == Tag_compatibility)
2868 elf32_arm_add_eabi_attr_compat (stdoutput, i, s);
2869 else if (is_string)
2870 elf32_arm_add_eabi_attr_string (stdoutput, tag, s);
2871 else
2872 elf32_arm_add_eabi_attr_int (stdoutput, tag, i);
2873
2874 if (s)
2875 {
2876 *input_line_pointer = saved_char;
2877 input_line_pointer++;
2878 }
2879 demand_empty_rest_of_line ();
2880 return;
2881bad_string:
2882 as_bad (_("bad string constant"));
2883 ignore_rest_of_line ();
2884 return;
2885bad:
2886 as_bad (_("expected <tag> , <value>"));
2887 ignore_rest_of_line ();
2888}
2889
2890static void s_arm_arch (int);
2891static void s_arm_cpu (int);
2892static void s_arm_fpu (int);
c19d1205 2893#endif /* OBJ_ELF */
b99bd4ef 2894
c19d1205
ZW
2895/* This table describes all the machine specific pseudo-ops the assembler
2896 has to support. The fields are:
2897 pseudo-op name without dot
2898 function to call to execute this pseudo-op
2899 Integer arg to pass to the function. */
b99bd4ef 2900
c19d1205 2901const pseudo_typeS md_pseudo_table[] =
b99bd4ef 2902{
c19d1205
ZW
2903 /* Never called because '.req' does not start a line. */
2904 { "req", s_req, 0 },
2905 { "unreq", s_unreq, 0 },
2906 { "bss", s_bss, 0 },
2907 { "align", s_align, 0 },
2908 { "arm", s_arm, 0 },
2909 { "thumb", s_thumb, 0 },
2910 { "code", s_code, 0 },
2911 { "force_thumb", s_force_thumb, 0 },
2912 { "thumb_func", s_thumb_func, 0 },
2913 { "thumb_set", s_thumb_set, 0 },
2914 { "even", s_even, 0 },
2915 { "ltorg", s_ltorg, 0 },
2916 { "pool", s_ltorg, 0 },
2917 { "syntax", s_syntax, 0 },
2918#ifdef OBJ_ELF
2919 { "word", s_arm_elf_cons, 4 },
2920 { "long", s_arm_elf_cons, 4 },
2921 { "rel31", s_arm_rel31, 0 },
2922 { "fnstart", s_arm_unwind_fnstart, 0 },
2923 { "fnend", s_arm_unwind_fnend, 0 },
2924 { "cantunwind", s_arm_unwind_cantunwind, 0 },
2925 { "personality", s_arm_unwind_personality, 0 },
2926 { "personalityindex", s_arm_unwind_personalityindex, 0 },
2927 { "handlerdata", s_arm_unwind_handlerdata, 0 },
2928 { "save", s_arm_unwind_save, 0 },
2929 { "movsp", s_arm_unwind_movsp, 0 },
2930 { "pad", s_arm_unwind_pad, 0 },
2931 { "setfp", s_arm_unwind_setfp, 0 },
2932 { "unwind_raw", s_arm_unwind_raw, 0 },
ee065d83
PB
2933 { "cpu", s_arm_cpu, 0 },
2934 { "arch", s_arm_arch, 0 },
2935 { "fpu", s_arm_fpu, 0 },
2936 { "eabi_attribute", s_arm_eabi_attribute, 0 },
c19d1205
ZW
2937#else
2938 { "word", cons, 4},
2939#endif
2940 { "extend", float_cons, 'x' },
2941 { "ldouble", float_cons, 'x' },
2942 { "packed", float_cons, 'p' },
2943 { 0, 0, 0 }
2944};
2945\f
2946/* Parser functions used exclusively in instruction operands. */
b99bd4ef 2947
c19d1205
ZW
2948/* Generic immediate-value read function for use in insn parsing.
2949 STR points to the beginning of the immediate (the leading #);
2950 VAL receives the value; if the value is outside [MIN, MAX]
2951 issue an error. PREFIX_OPT is true if the immediate prefix is
2952 optional. */
b99bd4ef 2953
c19d1205
ZW
2954static int
2955parse_immediate (char **str, int *val, int min, int max,
2956 bfd_boolean prefix_opt)
2957{
2958 expressionS exp;
2959 my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
2960 if (exp.X_op != O_constant)
b99bd4ef 2961 {
c19d1205
ZW
2962 inst.error = _("constant expression required");
2963 return FAIL;
2964 }
b99bd4ef 2965
c19d1205
ZW
2966 if (exp.X_add_number < min || exp.X_add_number > max)
2967 {
2968 inst.error = _("immediate value out of range");
2969 return FAIL;
2970 }
b99bd4ef 2971
c19d1205
ZW
2972 *val = exp.X_add_number;
2973 return SUCCESS;
2974}
b99bd4ef 2975
c19d1205
ZW
2976/* Returns the pseudo-register number of an FPA immediate constant,
2977 or FAIL if there isn't a valid constant here. */
b99bd4ef 2978
c19d1205
ZW
2979static int
2980parse_fpa_immediate (char ** str)
2981{
2982 LITTLENUM_TYPE words[MAX_LITTLENUMS];
2983 char * save_in;
2984 expressionS exp;
2985 int i;
2986 int j;
b99bd4ef 2987
c19d1205
ZW
2988 /* First try and match exact strings, this is to guarantee
2989 that some formats will work even for cross assembly. */
b99bd4ef 2990
c19d1205
ZW
2991 for (i = 0; fp_const[i]; i++)
2992 {
2993 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
b99bd4ef 2994 {
c19d1205 2995 char *start = *str;
b99bd4ef 2996
c19d1205
ZW
2997 *str += strlen (fp_const[i]);
2998 if (is_end_of_line[(unsigned char) **str])
2999 return i + 8;
3000 *str = start;
3001 }
3002 }
b99bd4ef 3003
c19d1205
ZW
3004 /* Just because we didn't get a match doesn't mean that the constant
3005 isn't valid, just that it is in a format that we don't
3006 automatically recognize. Try parsing it with the standard
3007 expression routines. */
b99bd4ef 3008
c19d1205 3009 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
b99bd4ef 3010
c19d1205
ZW
3011 /* Look for a raw floating point number. */
3012 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
3013 && is_end_of_line[(unsigned char) *save_in])
3014 {
3015 for (i = 0; i < NUM_FLOAT_VALS; i++)
3016 {
3017 for (j = 0; j < MAX_LITTLENUMS; j++)
b99bd4ef 3018 {
c19d1205
ZW
3019 if (words[j] != fp_values[i][j])
3020 break;
b99bd4ef
NC
3021 }
3022
c19d1205 3023 if (j == MAX_LITTLENUMS)
b99bd4ef 3024 {
c19d1205
ZW
3025 *str = save_in;
3026 return i + 8;
b99bd4ef
NC
3027 }
3028 }
3029 }
b99bd4ef 3030
c19d1205
ZW
3031 /* Try and parse a more complex expression, this will probably fail
3032 unless the code uses a floating point prefix (eg "0f"). */
3033 save_in = input_line_pointer;
3034 input_line_pointer = *str;
3035 if (expression (&exp) == absolute_section
3036 && exp.X_op == O_big
3037 && exp.X_add_number < 0)
3038 {
3039 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
3040 Ditto for 15. */
3041 if (gen_to_words (words, 5, (long) 15) == 0)
3042 {
3043 for (i = 0; i < NUM_FLOAT_VALS; i++)
3044 {
3045 for (j = 0; j < MAX_LITTLENUMS; j++)
3046 {
3047 if (words[j] != fp_values[i][j])
3048 break;
3049 }
b99bd4ef 3050
c19d1205
ZW
3051 if (j == MAX_LITTLENUMS)
3052 {
3053 *str = input_line_pointer;
3054 input_line_pointer = save_in;
3055 return i + 8;
3056 }
3057 }
3058 }
b99bd4ef
NC
3059 }
3060
c19d1205
ZW
3061 *str = input_line_pointer;
3062 input_line_pointer = save_in;
3063 inst.error = _("invalid FPA immediate expression");
3064 return FAIL;
b99bd4ef
NC
3065}
3066
c19d1205
ZW
3067/* Shift operands. */
3068enum shift_kind
b99bd4ef 3069{
c19d1205
ZW
3070 SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX
3071};
b99bd4ef 3072
c19d1205
ZW
3073struct asm_shift_name
3074{
3075 const char *name;
3076 enum shift_kind kind;
3077};
b99bd4ef 3078
c19d1205
ZW
3079/* Third argument to parse_shift. */
3080enum parse_shift_mode
3081{
3082 NO_SHIFT_RESTRICT, /* Any kind of shift is accepted. */
3083 SHIFT_IMMEDIATE, /* Shift operand must be an immediate. */
3084 SHIFT_LSL_OR_ASR_IMMEDIATE, /* Shift must be LSL or ASR immediate. */
3085 SHIFT_ASR_IMMEDIATE, /* Shift must be ASR immediate. */
3086 SHIFT_LSL_IMMEDIATE, /* Shift must be LSL immediate. */
3087};
b99bd4ef 3088
c19d1205
ZW
3089/* Parse a <shift> specifier on an ARM data processing instruction.
3090 This has three forms:
b99bd4ef 3091
c19d1205
ZW
3092 (LSL|LSR|ASL|ASR|ROR) Rs
3093 (LSL|LSR|ASL|ASR|ROR) #imm
3094 RRX
b99bd4ef 3095
c19d1205
ZW
3096 Note that ASL is assimilated to LSL in the instruction encoding, and
3097 RRX to ROR #0 (which cannot be written as such). */
b99bd4ef 3098
c19d1205
ZW
3099static int
3100parse_shift (char **str, int i, enum parse_shift_mode mode)
b99bd4ef 3101{
c19d1205
ZW
3102 const struct asm_shift_name *shift_name;
3103 enum shift_kind shift;
3104 char *s = *str;
3105 char *p = s;
3106 int reg;
b99bd4ef 3107
c19d1205
ZW
3108 for (p = *str; ISALPHA (*p); p++)
3109 ;
b99bd4ef 3110
c19d1205 3111 if (p == *str)
b99bd4ef 3112 {
c19d1205
ZW
3113 inst.error = _("shift expression expected");
3114 return FAIL;
b99bd4ef
NC
3115 }
3116
c19d1205
ZW
3117 shift_name = hash_find_n (arm_shift_hsh, *str, p - *str);
3118
3119 if (shift_name == NULL)
b99bd4ef 3120 {
c19d1205
ZW
3121 inst.error = _("shift expression expected");
3122 return FAIL;
b99bd4ef
NC
3123 }
3124
c19d1205 3125 shift = shift_name->kind;
b99bd4ef 3126
c19d1205
ZW
3127 switch (mode)
3128 {
3129 case NO_SHIFT_RESTRICT:
3130 case SHIFT_IMMEDIATE: break;
b99bd4ef 3131
c19d1205
ZW
3132 case SHIFT_LSL_OR_ASR_IMMEDIATE:
3133 if (shift != SHIFT_LSL && shift != SHIFT_ASR)
3134 {
3135 inst.error = _("'LSL' or 'ASR' required");
3136 return FAIL;
3137 }
3138 break;
b99bd4ef 3139
c19d1205
ZW
3140 case SHIFT_LSL_IMMEDIATE:
3141 if (shift != SHIFT_LSL)
3142 {
3143 inst.error = _("'LSL' required");
3144 return FAIL;
3145 }
3146 break;
b99bd4ef 3147
c19d1205
ZW
3148 case SHIFT_ASR_IMMEDIATE:
3149 if (shift != SHIFT_ASR)
3150 {
3151 inst.error = _("'ASR' required");
3152 return FAIL;
3153 }
3154 break;
b99bd4ef 3155
c19d1205
ZW
3156 default: abort ();
3157 }
b99bd4ef 3158
c19d1205
ZW
3159 if (shift != SHIFT_RRX)
3160 {
3161 /* Whitespace can appear here if the next thing is a bare digit. */
3162 skip_whitespace (p);
b99bd4ef 3163
c19d1205
ZW
3164 if (mode == NO_SHIFT_RESTRICT
3165 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
3166 {
3167 inst.operands[i].imm = reg;
3168 inst.operands[i].immisreg = 1;
3169 }
3170 else if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
3171 return FAIL;
3172 }
3173 inst.operands[i].shift_kind = shift;
3174 inst.operands[i].shifted = 1;
3175 *str = p;
3176 return SUCCESS;
b99bd4ef
NC
3177}
3178
c19d1205 3179/* Parse a <shifter_operand> for an ARM data processing instruction:
b99bd4ef 3180
c19d1205
ZW
3181 #<immediate>
3182 #<immediate>, <rotate>
3183 <Rm>
3184 <Rm>, <shift>
b99bd4ef 3185
c19d1205
ZW
3186 where <shift> is defined by parse_shift above, and <rotate> is a
3187 multiple of 2 between 0 and 30. Validation of immediate operands
55cf6793 3188 is deferred to md_apply_fix. */
b99bd4ef 3189
c19d1205
ZW
3190static int
3191parse_shifter_operand (char **str, int i)
3192{
3193 int value;
3194 expressionS expr;
b99bd4ef 3195
c19d1205
ZW
3196 if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
3197 {
3198 inst.operands[i].reg = value;
3199 inst.operands[i].isreg = 1;
b99bd4ef 3200
c19d1205
ZW
3201 /* parse_shift will override this if appropriate */
3202 inst.reloc.exp.X_op = O_constant;
3203 inst.reloc.exp.X_add_number = 0;
b99bd4ef 3204
c19d1205
ZW
3205 if (skip_past_comma (str) == FAIL)
3206 return SUCCESS;
b99bd4ef 3207
c19d1205
ZW
3208 /* Shift operation on register. */
3209 return parse_shift (str, i, NO_SHIFT_RESTRICT);
b99bd4ef
NC
3210 }
3211
c19d1205
ZW
3212 if (my_get_expression (&inst.reloc.exp, str, GE_IMM_PREFIX))
3213 return FAIL;
b99bd4ef 3214
c19d1205 3215 if (skip_past_comma (str) == SUCCESS)
b99bd4ef 3216 {
c19d1205
ZW
3217 /* #x, y -- ie explicit rotation by Y. */
3218 if (my_get_expression (&expr, str, GE_NO_PREFIX))
3219 return FAIL;
b99bd4ef 3220
c19d1205
ZW
3221 if (expr.X_op != O_constant || inst.reloc.exp.X_op != O_constant)
3222 {
3223 inst.error = _("constant expression expected");
3224 return FAIL;
3225 }
b99bd4ef 3226
c19d1205
ZW
3227 value = expr.X_add_number;
3228 if (value < 0 || value > 30 || value % 2 != 0)
3229 {
3230 inst.error = _("invalid rotation");
3231 return FAIL;
3232 }
3233 if (inst.reloc.exp.X_add_number < 0 || inst.reloc.exp.X_add_number > 255)
3234 {
3235 inst.error = _("invalid constant");
3236 return FAIL;
3237 }
09d92015 3238
55cf6793 3239 /* Convert to decoded value. md_apply_fix will put it back. */
c19d1205
ZW
3240 inst.reloc.exp.X_add_number
3241 = (((inst.reloc.exp.X_add_number << (32 - value))
3242 | (inst.reloc.exp.X_add_number >> value)) & 0xffffffff);
09d92015
MM
3243 }
3244
c19d1205
ZW
3245 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
3246 inst.reloc.pc_rel = 0;
3247 return SUCCESS;
09d92015
MM
3248}
3249
c19d1205
ZW
3250/* Parse all forms of an ARM address expression. Information is written
3251 to inst.operands[i] and/or inst.reloc.
09d92015 3252
c19d1205 3253 Preindexed addressing (.preind=1):
09d92015 3254
c19d1205
ZW
3255 [Rn, #offset] .reg=Rn .reloc.exp=offset
3256 [Rn, +/-Rm] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
3257 [Rn, +/-Rm, shift] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
3258 .shift_kind=shift .reloc.exp=shift_imm
09d92015 3259
c19d1205 3260 These three may have a trailing ! which causes .writeback to be set also.
09d92015 3261
c19d1205 3262 Postindexed addressing (.postind=1, .writeback=1):
09d92015 3263
c19d1205
ZW
3264 [Rn], #offset .reg=Rn .reloc.exp=offset
3265 [Rn], +/-Rm .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
3266 [Rn], +/-Rm, shift .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
3267 .shift_kind=shift .reloc.exp=shift_imm
09d92015 3268
c19d1205 3269 Unindexed addressing (.preind=0, .postind=0):
09d92015 3270
c19d1205 3271 [Rn], {option} .reg=Rn .imm=option .immisreg=0
09d92015 3272
c19d1205 3273 Other:
09d92015 3274
c19d1205
ZW
3275 [Rn]{!} shorthand for [Rn,#0]{!}
3276 =immediate .isreg=0 .reloc.exp=immediate
3277 label .reg=PC .reloc.pc_rel=1 .reloc.exp=label
09d92015 3278
c19d1205
ZW
3279 It is the caller's responsibility to check for addressing modes not
3280 supported by the instruction, and to set inst.reloc.type. */
3281
3282static int
3283parse_address (char **str, int i)
09d92015 3284{
c19d1205
ZW
3285 char *p = *str;
3286 int reg;
09d92015 3287
c19d1205 3288 if (skip_past_char (&p, '[') == FAIL)
09d92015 3289 {
c19d1205
ZW
3290 if (skip_past_char (&p, '=') == FAIL)
3291 {
3292 /* bare address - translate to PC-relative offset */
3293 inst.reloc.pc_rel = 1;
3294 inst.operands[i].reg = REG_PC;
3295 inst.operands[i].isreg = 1;
3296 inst.operands[i].preind = 1;
3297 }
3298 /* else a load-constant pseudo op, no special treatment needed here */
09d92015 3299
c19d1205
ZW
3300 if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
3301 return FAIL;
09d92015 3302
c19d1205
ZW
3303 *str = p;
3304 return SUCCESS;
09d92015
MM
3305 }
3306
c19d1205 3307 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
09d92015 3308 {
c19d1205
ZW
3309 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
3310 return FAIL;
09d92015 3311 }
c19d1205
ZW
3312 inst.operands[i].reg = reg;
3313 inst.operands[i].isreg = 1;
09d92015 3314
c19d1205 3315 if (skip_past_comma (&p) == SUCCESS)
09d92015 3316 {
c19d1205 3317 inst.operands[i].preind = 1;
09d92015 3318
c19d1205
ZW
3319 if (*p == '+') p++;
3320 else if (*p == '-') p++, inst.operands[i].negative = 1;
3321
3322 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
09d92015 3323 {
c19d1205
ZW
3324 inst.operands[i].imm = reg;
3325 inst.operands[i].immisreg = 1;
3326
3327 if (skip_past_comma (&p) == SUCCESS)
3328 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
3329 return FAIL;
3330 }
3331 else
3332 {
3333 if (inst.operands[i].negative)
3334 {
3335 inst.operands[i].negative = 0;
3336 p--;
3337 }
3338 if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
3339 return FAIL;
09d92015
MM
3340 }
3341 }
3342
c19d1205 3343 if (skip_past_char (&p, ']') == FAIL)
09d92015 3344 {
c19d1205
ZW
3345 inst.error = _("']' expected");
3346 return FAIL;
09d92015
MM
3347 }
3348
c19d1205
ZW
3349 if (skip_past_char (&p, '!') == SUCCESS)
3350 inst.operands[i].writeback = 1;
09d92015 3351
c19d1205 3352 else if (skip_past_comma (&p) == SUCCESS)
09d92015 3353 {
c19d1205
ZW
3354 if (skip_past_char (&p, '{') == SUCCESS)
3355 {
3356 /* [Rn], {expr} - unindexed, with option */
3357 if (parse_immediate (&p, &inst.operands[i].imm,
ca3f61f7 3358 0, 255, TRUE) == FAIL)
c19d1205 3359 return FAIL;
09d92015 3360
c19d1205
ZW
3361 if (skip_past_char (&p, '}') == FAIL)
3362 {
3363 inst.error = _("'}' expected at end of 'option' field");
3364 return FAIL;
3365 }
3366 if (inst.operands[i].preind)
3367 {
3368 inst.error = _("cannot combine index with option");
3369 return FAIL;
3370 }
3371 *str = p;
3372 return SUCCESS;
09d92015 3373 }
c19d1205
ZW
3374 else
3375 {
3376 inst.operands[i].postind = 1;
3377 inst.operands[i].writeback = 1;
09d92015 3378
c19d1205
ZW
3379 if (inst.operands[i].preind)
3380 {
3381 inst.error = _("cannot combine pre- and post-indexing");
3382 return FAIL;
3383 }
09d92015 3384
c19d1205
ZW
3385 if (*p == '+') p++;
3386 else if (*p == '-') p++, inst.operands[i].negative = 1;
a737bd4d 3387
c19d1205
ZW
3388 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
3389 {
3390 inst.operands[i].imm = reg;
3391 inst.operands[i].immisreg = 1;
a737bd4d 3392
c19d1205
ZW
3393 if (skip_past_comma (&p) == SUCCESS)
3394 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
3395 return FAIL;
3396 }
3397 else
3398 {
3399 if (inst.operands[i].negative)
3400 {
3401 inst.operands[i].negative = 0;
3402 p--;
3403 }
3404 if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
3405 return FAIL;
3406 }
3407 }
a737bd4d
NC
3408 }
3409
c19d1205
ZW
3410 /* If at this point neither .preind nor .postind is set, we have a
3411 bare [Rn]{!}, which is shorthand for [Rn,#0]{!}. */
3412 if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
3413 {
3414 inst.operands[i].preind = 1;
3415 inst.reloc.exp.X_op = O_constant;
3416 inst.reloc.exp.X_add_number = 0;
3417 }
3418 *str = p;
3419 return SUCCESS;
a737bd4d
NC
3420}
3421
c19d1205 3422/* Miscellaneous. */
a737bd4d 3423
c19d1205
ZW
3424/* Parse a PSR flag operand. The value returned is FAIL on syntax error,
3425 or a bitmask suitable to be or-ed into the ARM msr instruction. */
3426static int
3427parse_psr (char **str)
09d92015 3428{
c19d1205
ZW
3429 char *p;
3430 unsigned long psr_field;
09d92015 3431
c19d1205
ZW
3432 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
3433 feature for ease of use and backwards compatibility. */
3434 p = *str;
3435 if (*p == 's' || *p == 'S')
3436 psr_field = SPSR_BIT;
3437 else if (*p == 'c' || *p == 'C')
3438 psr_field = 0;
3439 else
3440 goto error;
09d92015 3441
c19d1205
ZW
3442 p++;
3443 if (strncasecmp (p, "PSR", 3) != 0)
3444 goto error;
3445 p += 3;
09d92015 3446
c19d1205
ZW
3447 if (*p == '_')
3448 {
3449 /* A suffix follows. */
3450 const struct asm_psr *psr;
3451 char *start;
a737bd4d 3452
c19d1205
ZW
3453 p++;
3454 start = p;
a737bd4d 3455
c19d1205
ZW
3456 do
3457 p++;
3458 while (ISALNUM (*p) || *p == '_');
a737bd4d 3459
c19d1205
ZW
3460 psr = hash_find_n (arm_psr_hsh, start, p - start);
3461 if (!psr)
3462 goto error;
a737bd4d 3463
c19d1205 3464 psr_field |= psr->field;
a737bd4d 3465 }
c19d1205 3466 else
a737bd4d 3467 {
c19d1205
ZW
3468 if (ISALNUM (*p))
3469 goto error; /* Garbage after "[CS]PSR". */
3470
3471 psr_field |= (PSR_c | PSR_f);
a737bd4d 3472 }
c19d1205
ZW
3473 *str = p;
3474 return psr_field;
a737bd4d 3475
c19d1205
ZW
3476 error:
3477 inst.error = _("flag for {c}psr instruction expected");
3478 return FAIL;
a737bd4d
NC
3479}
3480
c19d1205
ZW
3481/* Parse the flags argument to CPSI[ED]. Returns FAIL on error, or a
3482 value suitable for splatting into the AIF field of the instruction. */
a737bd4d 3483
c19d1205
ZW
3484static int
3485parse_cps_flags (char **str)
a737bd4d 3486{
c19d1205
ZW
3487 int val = 0;
3488 int saw_a_flag = 0;
3489 char *s = *str;
a737bd4d 3490
c19d1205
ZW
3491 for (;;)
3492 switch (*s++)
3493 {
3494 case '\0': case ',':
3495 goto done;
a737bd4d 3496
c19d1205
ZW
3497 case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
3498 case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
3499 case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
a737bd4d 3500
c19d1205
ZW
3501 default:
3502 inst.error = _("unrecognized CPS flag");
3503 return FAIL;
3504 }
a737bd4d 3505
c19d1205
ZW
3506 done:
3507 if (saw_a_flag == 0)
a737bd4d 3508 {
c19d1205
ZW
3509 inst.error = _("missing CPS flags");
3510 return FAIL;
a737bd4d 3511 }
a737bd4d 3512
c19d1205
ZW
3513 *str = s - 1;
3514 return val;
a737bd4d
NC
3515}
3516
c19d1205
ZW
3517/* Parse an endian specifier ("BE" or "LE", case insensitive);
3518 returns 0 for big-endian, 1 for little-endian, FAIL for an error. */
a737bd4d
NC
3519
3520static int
c19d1205 3521parse_endian_specifier (char **str)
a737bd4d 3522{
c19d1205
ZW
3523 int little_endian;
3524 char *s = *str;
a737bd4d 3525
c19d1205
ZW
3526 if (strncasecmp (s, "BE", 2))
3527 little_endian = 0;
3528 else if (strncasecmp (s, "LE", 2))
3529 little_endian = 1;
3530 else
a737bd4d 3531 {
c19d1205 3532 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
3533 return FAIL;
3534 }
3535
c19d1205 3536 if (ISALNUM (s[2]) || s[2] == '_')
a737bd4d 3537 {
c19d1205 3538 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
3539 return FAIL;
3540 }
3541
c19d1205
ZW
3542 *str = s + 2;
3543 return little_endian;
3544}
a737bd4d 3545
c19d1205
ZW
3546/* Parse a rotation specifier: ROR #0, #8, #16, #24. *val receives a
3547 value suitable for poking into the rotate field of an sxt or sxta
3548 instruction, or FAIL on error. */
3549
3550static int
3551parse_ror (char **str)
3552{
3553 int rot;
3554 char *s = *str;
3555
3556 if (strncasecmp (s, "ROR", 3) == 0)
3557 s += 3;
3558 else
a737bd4d 3559 {
c19d1205 3560 inst.error = _("missing rotation field after comma");
a737bd4d
NC
3561 return FAIL;
3562 }
c19d1205
ZW
3563
3564 if (parse_immediate (&s, &rot, 0, 24, FALSE) == FAIL)
3565 return FAIL;
3566
3567 switch (rot)
a737bd4d 3568 {
c19d1205
ZW
3569 case 0: *str = s; return 0x0;
3570 case 8: *str = s; return 0x1;
3571 case 16: *str = s; return 0x2;
3572 case 24: *str = s; return 0x3;
3573
3574 default:
3575 inst.error = _("rotation can only be 0, 8, 16, or 24");
a737bd4d
NC
3576 return FAIL;
3577 }
c19d1205 3578}
a737bd4d 3579
c19d1205
ZW
3580/* Parse a conditional code (from conds[] below). The value returned is in the
3581 range 0 .. 14, or FAIL. */
3582static int
3583parse_cond (char **str)
3584{
3585 char *p, *q;
3586 const struct asm_cond *c;
a737bd4d 3587
c19d1205
ZW
3588 p = q = *str;
3589 while (ISALPHA (*q))
3590 q++;
a737bd4d 3591
c19d1205
ZW
3592 c = hash_find_n (arm_cond_hsh, p, q - p);
3593 if (!c)
a737bd4d 3594 {
c19d1205 3595 inst.error = _("condition required");
a737bd4d
NC
3596 return FAIL;
3597 }
3598
c19d1205
ZW
3599 *str = q;
3600 return c->value;
3601}
3602
92e90b6e
PB
3603/* Parse the operands of a table branch instruction. Similar to a memory
3604 operand. */
3605static int
3606parse_tb (char **str)
3607{
3608 char * p = *str;
3609 int reg;
3610
3611 if (skip_past_char (&p, '[') == FAIL)
3612 return FAIL;
3613
3614 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
3615 {
3616 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
3617 return FAIL;
3618 }
3619 inst.operands[0].reg = reg;
3620
3621 if (skip_past_comma (&p) == FAIL)
3622 return FAIL;
3623
3624 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
3625 {
3626 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
3627 return FAIL;
3628 }
3629 inst.operands[0].imm = reg;
3630
3631 if (skip_past_comma (&p) == SUCCESS)
3632 {
3633 if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
3634 return FAIL;
3635 if (inst.reloc.exp.X_add_number != 1)
3636 {
3637 inst.error = _("invalid shift");
3638 return FAIL;
3639 }
3640 inst.operands[0].shifted = 1;
3641 }
3642
3643 if (skip_past_char (&p, ']') == FAIL)
3644 {
3645 inst.error = _("']' expected");
3646 return FAIL;
3647 }
3648 *str = p;
3649 return SUCCESS;
3650}
3651
c19d1205
ZW
3652/* Matcher codes for parse_operands. */
3653enum operand_parse_code
3654{
3655 OP_stop, /* end of line */
3656
3657 OP_RR, /* ARM register */
3658 OP_RRnpc, /* ARM register, not r15 */
3659 OP_RRnpcb, /* ARM register, not r15, in square brackets */
3660 OP_RRw, /* ARM register, not r15, optional trailing ! */
3661 OP_RCP, /* Coprocessor number */
3662 OP_RCN, /* Coprocessor register */
3663 OP_RF, /* FPA register */
3664 OP_RVS, /* VFP single precision register */
3665 OP_RVD, /* VFP double precision register */
3666 OP_RVC, /* VFP control register */
3667 OP_RMF, /* Maverick F register */
3668 OP_RMD, /* Maverick D register */
3669 OP_RMFX, /* Maverick FX register */
3670 OP_RMDX, /* Maverick DX register */
3671 OP_RMAX, /* Maverick AX register */
3672 OP_RMDS, /* Maverick DSPSC register */
3673 OP_RIWR, /* iWMMXt wR register */
3674 OP_RIWC, /* iWMMXt wC register */
3675 OP_RIWG, /* iWMMXt wCG register */
3676 OP_RXA, /* XScale accumulator register */
3677
3678 OP_REGLST, /* ARM register list */
3679 OP_VRSLST, /* VFP single-precision register list */
3680 OP_VRDLST, /* VFP double-precision register list */
3681
3682 OP_I7, /* immediate value 0 .. 7 */
3683 OP_I15, /* 0 .. 15 */
3684 OP_I16, /* 1 .. 16 */
3685 OP_I31, /* 0 .. 31 */
3686 OP_I31w, /* 0 .. 31, optional trailing ! */
3687 OP_I32, /* 1 .. 32 */
3688 OP_I63s, /* -64 .. 63 */
3689 OP_I255, /* 0 .. 255 */
3690 OP_Iffff, /* 0 .. 65535 */
3691
3692 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
3693 OP_I7b, /* 0 .. 7 */
3694 OP_I15b, /* 0 .. 15 */
3695 OP_I31b, /* 0 .. 31 */
3696
3697 OP_SH, /* shifter operand */
3698 OP_ADDR, /* Memory address expression (any mode) */
3699 OP_EXP, /* arbitrary expression */
3700 OP_EXPi, /* same, with optional immediate prefix */
3701 OP_EXPr, /* same, with optional relocation suffix */
3702
3703 OP_CPSF, /* CPS flags */
3704 OP_ENDI, /* Endianness specifier */
3705 OP_PSR, /* CPSR/SPSR mask for msr */
3706 OP_COND, /* conditional code */
92e90b6e 3707 OP_TB, /* Table branch. */
c19d1205
ZW
3708
3709 OP_RRnpc_I0, /* ARM register or literal 0 */
3710 OP_RR_EXr, /* ARM register or expression with opt. reloc suff. */
3711 OP_RR_EXi, /* ARM register or expression with imm prefix */
3712 OP_RF_IF, /* FPA register or immediate */
3713 OP_RIWR_RIWC, /* iWMMXt R or C reg */
3714
3715 /* Optional operands. */
3716 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
3717 OP_oI31b, /* 0 .. 31 */
3718 OP_oIffffb, /* 0 .. 65535 */
3719 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
3720
3721 OP_oRR, /* ARM register */
3722 OP_oRRnpc, /* ARM register, not the PC */
3723 OP_oSHll, /* LSL immediate */
3724 OP_oSHar, /* ASR immediate */
3725 OP_oSHllar, /* LSL or ASR immediate */
3726 OP_oROR, /* ROR 0/8/16/24 */
3727
3728 OP_FIRST_OPTIONAL = OP_oI7b
3729};
a737bd4d 3730
c19d1205
ZW
3731/* Generic instruction operand parser. This does no encoding and no
3732 semantic validation; it merely squirrels values away in the inst
3733 structure. Returns SUCCESS or FAIL depending on whether the
3734 specified grammar matched. */
3735static int
ca3f61f7 3736parse_operands (char *str, const unsigned char *pattern)
c19d1205
ZW
3737{
3738 unsigned const char *upat = pattern;
3739 char *backtrack_pos = 0;
3740 const char *backtrack_error = 0;
3741 int i, val, backtrack_index = 0;
3742
3743#define po_char_or_fail(chr) do { \
3744 if (skip_past_char (&str, chr) == FAIL) \
3745 goto bad_args; \
3746} while (0)
3747
3748#define po_reg_or_fail(regtype) do { \
3749 val = arm_reg_parse (&str, regtype); \
3750 if (val == FAIL) \
3751 { \
3752 inst.error = _(reg_expected_msgs[regtype]); \
3753 goto failure; \
3754 } \
3755 inst.operands[i].reg = val; \
3756 inst.operands[i].isreg = 1; \
3757} while (0)
3758
3759#define po_reg_or_goto(regtype, label) do { \
3760 val = arm_reg_parse (&str, regtype); \
3761 if (val == FAIL) \
3762 goto label; \
3763 \
3764 inst.operands[i].reg = val; \
3765 inst.operands[i].isreg = 1; \
3766} while (0)
3767
3768#define po_imm_or_fail(min, max, popt) do { \
3769 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
3770 goto failure; \
3771 inst.operands[i].imm = val; \
3772} while (0)
3773
3774#define po_misc_or_fail(expr) do { \
3775 if (expr) \
3776 goto failure; \
3777} while (0)
3778
3779 skip_whitespace (str);
3780
3781 for (i = 0; upat[i] != OP_stop; i++)
3782 {
3783 if (upat[i] >= OP_FIRST_OPTIONAL)
3784 {
3785 /* Remember where we are in case we need to backtrack. */
3786 assert (!backtrack_pos);
3787 backtrack_pos = str;
3788 backtrack_error = inst.error;
3789 backtrack_index = i;
3790 }
3791
3792 if (i > 0)
3793 po_char_or_fail (',');
3794
3795 switch (upat[i])
3796 {
3797 /* Registers */
3798 case OP_oRRnpc:
3799 case OP_RRnpc:
3800 case OP_oRR:
3801 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
3802 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
3803 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
3804 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
3805 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
3806 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
3807 case OP_RVC: po_reg_or_fail (REG_TYPE_VFC); break;
3808 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
3809 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
3810 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
3811 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
3812 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
3813 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
3814 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
3815 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
3816 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
3817 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
3818
3819 case OP_RRnpcb:
3820 po_char_or_fail ('[');
3821 po_reg_or_fail (REG_TYPE_RN);
3822 po_char_or_fail (']');
3823 break;
a737bd4d 3824
c19d1205
ZW
3825 case OP_RRw:
3826 po_reg_or_fail (REG_TYPE_RN);
3827 if (skip_past_char (&str, '!') == SUCCESS)
3828 inst.operands[i].writeback = 1;
3829 break;
3830
3831 /* Immediates */
3832 case OP_I7: po_imm_or_fail ( 0, 7, FALSE); break;
3833 case OP_I15: po_imm_or_fail ( 0, 15, FALSE); break;
3834 case OP_I16: po_imm_or_fail ( 1, 16, FALSE); break;
3835 case OP_I31: po_imm_or_fail ( 0, 31, FALSE); break;
3836 case OP_I32: po_imm_or_fail ( 1, 32, FALSE); break;
3837 case OP_I63s: po_imm_or_fail (-64, 63, FALSE); break;
3838 case OP_I255: po_imm_or_fail ( 0, 255, FALSE); break;
3839 case OP_Iffff: po_imm_or_fail ( 0, 0xffff, FALSE); break;
3840
3841 case OP_I4b: po_imm_or_fail ( 1, 4, TRUE); break;
3842 case OP_oI7b:
3843 case OP_I7b: po_imm_or_fail ( 0, 7, TRUE); break;
3844 case OP_I15b: po_imm_or_fail ( 0, 15, TRUE); break;
3845 case OP_oI31b:
3846 case OP_I31b: po_imm_or_fail ( 0, 31, TRUE); break;
3847 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, TRUE); break;
3848
3849 /* Immediate variants */
3850 case OP_oI255c:
3851 po_char_or_fail ('{');
3852 po_imm_or_fail (0, 255, TRUE);
3853 po_char_or_fail ('}');
3854 break;
3855
3856 case OP_I31w:
3857 /* The expression parser chokes on a trailing !, so we have
3858 to find it first and zap it. */
3859 {
3860 char *s = str;
3861 while (*s && *s != ',')
3862 s++;
3863 if (s[-1] == '!')
3864 {
3865 s[-1] = '\0';
3866 inst.operands[i].writeback = 1;
3867 }
3868 po_imm_or_fail (0, 31, TRUE);
3869 if (str == s - 1)
3870 str = s;
3871 }
3872 break;
3873
3874 /* Expressions */
3875 case OP_EXPi: EXPi:
3876 po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
3877 GE_OPT_PREFIX));
3878 break;
3879
3880 case OP_EXP:
3881 po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
3882 GE_NO_PREFIX));
3883 break;
3884
3885 case OP_EXPr: EXPr:
3886 po_misc_or_fail (my_get_expression (&inst.reloc.exp, &str,
3887 GE_NO_PREFIX));
3888 if (inst.reloc.exp.X_op == O_symbol)
a737bd4d 3889 {
c19d1205
ZW
3890 val = parse_reloc (&str);
3891 if (val == -1)
3892 {
3893 inst.error = _("unrecognized relocation suffix");
3894 goto failure;
3895 }
3896 else if (val != BFD_RELOC_UNUSED)
3897 {
3898 inst.operands[i].imm = val;
3899 inst.operands[i].hasreloc = 1;
3900 }
a737bd4d 3901 }
c19d1205 3902 break;
a737bd4d 3903
c19d1205
ZW
3904 /* Register or expression */
3905 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
3906 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 3907
c19d1205
ZW
3908 /* Register or immediate */
3909 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
3910 I0: po_imm_or_fail (0, 0, FALSE); break;
a737bd4d 3911
c19d1205
ZW
3912 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
3913 IF:
3914 if (!is_immediate_prefix (*str))
3915 goto bad_args;
3916 str++;
3917 val = parse_fpa_immediate (&str);
3918 if (val == FAIL)
3919 goto failure;
3920 /* FPA immediates are encoded as registers 8-15.
3921 parse_fpa_immediate has already applied the offset. */
3922 inst.operands[i].reg = val;
3923 inst.operands[i].isreg = 1;
3924 break;
09d92015 3925
c19d1205
ZW
3926 /* Two kinds of register */
3927 case OP_RIWR_RIWC:
3928 {
3929 struct reg_entry *rege = arm_reg_parse_multi (&str);
3930 if (rege->type != REG_TYPE_MMXWR
3931 && rege->type != REG_TYPE_MMXWC
3932 && rege->type != REG_TYPE_MMXWCG)
3933 {
3934 inst.error = _("iWMMXt data or control register expected");
3935 goto failure;
3936 }
3937 inst.operands[i].reg = rege->number;
3938 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
3939 }
3940 break;
09d92015 3941
c19d1205
ZW
3942 /* Misc */
3943 case OP_CPSF: val = parse_cps_flags (&str); break;
3944 case OP_ENDI: val = parse_endian_specifier (&str); break;
3945 case OP_oROR: val = parse_ror (&str); break;
3946 case OP_PSR: val = parse_psr (&str); break;
3947 case OP_COND: val = parse_cond (&str); break;
3948
92e90b6e
PB
3949 case OP_TB:
3950 po_misc_or_fail (parse_tb (&str));
3951 break;
3952
c19d1205
ZW
3953 /* Register lists */
3954 case OP_REGLST:
3955 val = parse_reg_list (&str);
3956 if (*str == '^')
3957 {
3958 inst.operands[1].writeback = 1;
3959 str++;
3960 }
3961 break;
09d92015 3962
c19d1205
ZW
3963 case OP_VRSLST:
3964 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, 0);
3965 break;
09d92015 3966
c19d1205
ZW
3967 case OP_VRDLST:
3968 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, 1);
3969 break;
a737bd4d 3970
c19d1205
ZW
3971 /* Addressing modes */
3972 case OP_ADDR:
3973 po_misc_or_fail (parse_address (&str, i));
3974 break;
09d92015 3975
c19d1205
ZW
3976 case OP_SH:
3977 po_misc_or_fail (parse_shifter_operand (&str, i));
3978 break;
09d92015 3979
c19d1205
ZW
3980 case OP_oSHll:
3981 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
3982 break;
09d92015 3983
c19d1205
ZW
3984 case OP_oSHar:
3985 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
3986 break;
09d92015 3987
c19d1205
ZW
3988 case OP_oSHllar:
3989 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
3990 break;
09d92015 3991
c19d1205
ZW
3992 default:
3993 as_fatal ("unhandled operand code %d", upat[i]);
3994 }
09d92015 3995
c19d1205
ZW
3996 /* Various value-based sanity checks and shared operations. We
3997 do not signal immediate failures for the register constraints;
3998 this allows a syntax error to take precedence. */
3999 switch (upat[i])
4000 {
4001 case OP_oRRnpc:
4002 case OP_RRnpc:
4003 case OP_RRnpcb:
4004 case OP_RRw:
4005 case OP_RRnpc_I0:
4006 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
4007 inst.error = BAD_PC;
4008 break;
09d92015 4009
c19d1205
ZW
4010 case OP_CPSF:
4011 case OP_ENDI:
4012 case OP_oROR:
4013 case OP_PSR:
4014 case OP_COND:
4015 case OP_REGLST:
4016 case OP_VRSLST:
4017 case OP_VRDLST:
4018 if (val == FAIL)
4019 goto failure;
4020 inst.operands[i].imm = val;
4021 break;
a737bd4d 4022
c19d1205
ZW
4023 default:
4024 break;
4025 }
09d92015 4026
c19d1205
ZW
4027 /* If we get here, this operand was successfully parsed. */
4028 inst.operands[i].present = 1;
4029 continue;
09d92015 4030
c19d1205 4031 bad_args:
09d92015 4032 inst.error = BAD_ARGS;
c19d1205
ZW
4033
4034 failure:
4035 if (!backtrack_pos)
4036 return FAIL;
4037
4038 /* Do not backtrack over a trailing optional argument that
4039 absorbed some text. We will only fail again, with the
4040 'garbage following instruction' error message, which is
4041 probably less helpful than the current one. */
4042 if (backtrack_index == i && backtrack_pos != str
4043 && upat[i+1] == OP_stop)
4044 return FAIL;
4045
4046 /* Try again, skipping the optional argument at backtrack_pos. */
4047 str = backtrack_pos;
4048 inst.error = backtrack_error;
4049 inst.operands[backtrack_index].present = 0;
4050 i = backtrack_index;
4051 backtrack_pos = 0;
09d92015 4052 }
09d92015 4053
c19d1205
ZW
4054 /* Check that we have parsed all the arguments. */
4055 if (*str != '\0' && !inst.error)
4056 inst.error = _("garbage following instruction");
09d92015 4057
c19d1205 4058 return inst.error ? FAIL : SUCCESS;
09d92015
MM
4059}
4060
c19d1205
ZW
4061#undef po_char_or_fail
4062#undef po_reg_or_fail
4063#undef po_reg_or_goto
4064#undef po_imm_or_fail
4065\f
4066/* Shorthand macro for instruction encoding functions issuing errors. */
4067#define constraint(expr, err) do { \
4068 if (expr) \
4069 { \
4070 inst.error = err; \
4071 return; \
4072 } \
4073} while (0)
4074
4075/* Functions for operand encoding. ARM, then Thumb. */
4076
4077#define rotate_left(v, n) (v << n | v >> (32 - n))
4078
4079/* If VAL can be encoded in the immediate field of an ARM instruction,
4080 return the encoded form. Otherwise, return FAIL. */
4081
4082static unsigned int
4083encode_arm_immediate (unsigned int val)
09d92015 4084{
c19d1205
ZW
4085 unsigned int a, i;
4086
4087 for (i = 0; i < 32; i += 2)
4088 if ((a = rotate_left (val, i)) <= 0xff)
4089 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
4090
4091 return FAIL;
09d92015
MM
4092}
4093
c19d1205
ZW
4094/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
4095 return the encoded form. Otherwise, return FAIL. */
4096static unsigned int
4097encode_thumb32_immediate (unsigned int val)
09d92015 4098{
c19d1205 4099 unsigned int a, i;
09d92015 4100
9c3c69f2 4101 if (val <= 0xff)
c19d1205 4102 return val;
a737bd4d 4103
9c3c69f2 4104 for (i = 1; i <= 24; i++)
09d92015 4105 {
9c3c69f2
PB
4106 a = val >> i;
4107 if ((val & ~(0xff << i)) == 0)
4108 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 4109 }
a737bd4d 4110
c19d1205
ZW
4111 a = val & 0xff;
4112 if (val == ((a << 16) | a))
4113 return 0x100 | a;
4114 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
4115 return 0x300 | a;
09d92015 4116
c19d1205
ZW
4117 a = val & 0xff00;
4118 if (val == ((a << 16) | a))
4119 return 0x200 | (a >> 8);
a737bd4d 4120
c19d1205 4121 return FAIL;
09d92015 4122}
c19d1205 4123/* Encode a VFP SP register number into inst.instruction. */
09d92015
MM
4124
4125static void
c19d1205 4126encode_arm_vfp_sp_reg (int reg, enum vfp_sp_reg_pos pos)
09d92015 4127{
c19d1205 4128 switch (pos)
09d92015 4129 {
c19d1205
ZW
4130 case VFP_REG_Sd:
4131 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
4132 break;
4133
4134 case VFP_REG_Sn:
4135 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
4136 break;
4137
4138 case VFP_REG_Sm:
4139 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
4140 break;
4141
4142 default:
4143 abort ();
09d92015 4144 }
09d92015
MM
4145}
4146
c19d1205 4147/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 4148 if any, is handled by md_apply_fix. */
09d92015 4149static void
c19d1205 4150encode_arm_shift (int i)
09d92015 4151{
c19d1205
ZW
4152 if (inst.operands[i].shift_kind == SHIFT_RRX)
4153 inst.instruction |= SHIFT_ROR << 5;
4154 else
09d92015 4155 {
c19d1205
ZW
4156 inst.instruction |= inst.operands[i].shift_kind << 5;
4157 if (inst.operands[i].immisreg)
4158 {
4159 inst.instruction |= SHIFT_BY_REG;
4160 inst.instruction |= inst.operands[i].imm << 8;
4161 }
4162 else
4163 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 4164 }
c19d1205 4165}
09d92015 4166
c19d1205
ZW
4167static void
4168encode_arm_shifter_operand (int i)
4169{
4170 if (inst.operands[i].isreg)
09d92015 4171 {
c19d1205
ZW
4172 inst.instruction |= inst.operands[i].reg;
4173 encode_arm_shift (i);
09d92015 4174 }
c19d1205
ZW
4175 else
4176 inst.instruction |= INST_IMMEDIATE;
09d92015
MM
4177}
4178
c19d1205 4179/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 4180static void
c19d1205 4181encode_arm_addr_mode_common (int i, bfd_boolean is_t)
09d92015 4182{
c19d1205
ZW
4183 assert (inst.operands[i].isreg);
4184 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 4185
c19d1205 4186 if (inst.operands[i].preind)
09d92015 4187 {
c19d1205
ZW
4188 if (is_t)
4189 {
4190 inst.error = _("instruction does not accept preindexed addressing");
4191 return;
4192 }
4193 inst.instruction |= PRE_INDEX;
4194 if (inst.operands[i].writeback)
4195 inst.instruction |= WRITE_BACK;
09d92015 4196
c19d1205
ZW
4197 }
4198 else if (inst.operands[i].postind)
4199 {
4200 assert (inst.operands[i].writeback);
4201 if (is_t)
4202 inst.instruction |= WRITE_BACK;
4203 }
4204 else /* unindexed - only for coprocessor */
09d92015 4205 {
c19d1205 4206 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
4207 return;
4208 }
4209
c19d1205
ZW
4210 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
4211 && (((inst.instruction & 0x000f0000) >> 16)
4212 == ((inst.instruction & 0x0000f000) >> 12)))
4213 as_warn ((inst.instruction & LOAD_BIT)
4214 ? _("destination register same as write-back base")
4215 : _("source register same as write-back base"));
09d92015
MM
4216}
4217
c19d1205
ZW
4218/* inst.operands[i] was set up by parse_address. Encode it into an
4219 ARM-format mode 2 load or store instruction. If is_t is true,
4220 reject forms that cannot be used with a T instruction (i.e. not
4221 post-indexed). */
a737bd4d 4222static void
c19d1205 4223encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
09d92015 4224{
c19d1205 4225 encode_arm_addr_mode_common (i, is_t);
a737bd4d 4226
c19d1205 4227 if (inst.operands[i].immisreg)
09d92015 4228 {
c19d1205
ZW
4229 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
4230 inst.instruction |= inst.operands[i].imm;
4231 if (!inst.operands[i].negative)
4232 inst.instruction |= INDEX_UP;
4233 if (inst.operands[i].shifted)
4234 {
4235 if (inst.operands[i].shift_kind == SHIFT_RRX)
4236 inst.instruction |= SHIFT_ROR << 5;
4237 else
4238 {
4239 inst.instruction |= inst.operands[i].shift_kind << 5;
4240 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
4241 }
4242 }
09d92015 4243 }
c19d1205 4244 else /* immediate offset in inst.reloc */
09d92015 4245 {
c19d1205
ZW
4246 if (inst.reloc.type == BFD_RELOC_UNUSED)
4247 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
09d92015 4248 }
09d92015
MM
4249}
4250
c19d1205
ZW
4251/* inst.operands[i] was set up by parse_address. Encode it into an
4252 ARM-format mode 3 load or store instruction. Reject forms that
4253 cannot be used with such instructions. If is_t is true, reject
4254 forms that cannot be used with a T instruction (i.e. not
4255 post-indexed). */
4256static void
4257encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
09d92015 4258{
c19d1205 4259 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 4260 {
c19d1205
ZW
4261 inst.error = _("instruction does not accept scaled register index");
4262 return;
09d92015 4263 }
a737bd4d 4264
c19d1205 4265 encode_arm_addr_mode_common (i, is_t);
a737bd4d 4266
c19d1205
ZW
4267 if (inst.operands[i].immisreg)
4268 {
4269 inst.instruction |= inst.operands[i].imm;
4270 if (!inst.operands[i].negative)
4271 inst.instruction |= INDEX_UP;
4272 }
4273 else /* immediate offset in inst.reloc */
4274 {
4275 inst.instruction |= HWOFFSET_IMM;
4276 if (inst.reloc.type == BFD_RELOC_UNUSED)
4277 inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
c19d1205 4278 }
a737bd4d
NC
4279}
4280
c19d1205
ZW
4281/* inst.operands[i] was set up by parse_address. Encode it into an
4282 ARM-format instruction. Reject all forms which cannot be encoded
4283 into a coprocessor load/store instruction. If wb_ok is false,
4284 reject use of writeback; if unind_ok is false, reject use of
4285 unindexed addressing. If reloc_override is not 0, use it instead
4286 of BFD_ARM_CP_OFF_IMM. */
09d92015 4287
c19d1205
ZW
4288static int
4289encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
09d92015 4290{
c19d1205 4291 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 4292
c19d1205 4293 assert (!(inst.operands[i].preind && inst.operands[i].postind));
09d92015 4294
c19d1205 4295 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
09d92015 4296 {
c19d1205
ZW
4297 assert (!inst.operands[i].writeback);
4298 if (!unind_ok)
4299 {
4300 inst.error = _("instruction does not support unindexed addressing");
4301 return FAIL;
4302 }
4303 inst.instruction |= inst.operands[i].imm;
4304 inst.instruction |= INDEX_UP;
4305 return SUCCESS;
09d92015 4306 }
a737bd4d 4307
c19d1205
ZW
4308 if (inst.operands[i].preind)
4309 inst.instruction |= PRE_INDEX;
a737bd4d 4310
c19d1205 4311 if (inst.operands[i].writeback)
09d92015 4312 {
c19d1205
ZW
4313 if (inst.operands[i].reg == REG_PC)
4314 {
4315 inst.error = _("pc may not be used with write-back");
4316 return FAIL;
4317 }
4318 if (!wb_ok)
4319 {
4320 inst.error = _("instruction does not support writeback");
4321 return FAIL;
4322 }
4323 inst.instruction |= WRITE_BACK;
09d92015 4324 }
a737bd4d 4325
c19d1205
ZW
4326 if (reloc_override)
4327 inst.reloc.type = reloc_override;
8f06b2d8
PB
4328 else if (thumb_mode)
4329 inst.reloc.type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
09d92015 4330 else
c19d1205 4331 inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205
ZW
4332 return SUCCESS;
4333}
a737bd4d 4334
c19d1205
ZW
4335/* inst.reloc.exp describes an "=expr" load pseudo-operation.
4336 Determine whether it can be performed with a move instruction; if
4337 it can, convert inst.instruction to that move instruction and
4338 return 1; if it can't, convert inst.instruction to a literal-pool
4339 load and return 0. If this is not a valid thing to do in the
4340 current context, set inst.error and return 1.
a737bd4d 4341
c19d1205
ZW
4342 inst.operands[i] describes the destination register. */
4343
4344static int
4345move_or_literal_pool (int i, bfd_boolean thumb_p, bfd_boolean mode_3)
4346{
4347 if ((inst.instruction & (thumb_p ? THUMB_LOAD_BIT : LOAD_BIT)) == 0)
09d92015 4348 {
c19d1205
ZW
4349 inst.error = _("invalid pseudo operation");
4350 return 1;
09d92015 4351 }
c19d1205 4352 if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol)
09d92015
MM
4353 {
4354 inst.error = _("constant expression expected");
c19d1205 4355 return 1;
09d92015 4356 }
c19d1205 4357 if (inst.reloc.exp.X_op == O_constant)
09d92015 4358 {
c19d1205
ZW
4359 if (thumb_p)
4360 {
4361 if ((inst.reloc.exp.X_add_number & ~0xFF) == 0)
4362 {
4363 /* This can be done with a mov(1) instruction. */
4364 inst.instruction = T_OPCODE_MOV_I8 | (inst.operands[i].reg << 8);
4365 inst.instruction |= inst.reloc.exp.X_add_number;
4366 return 1;
4367 }
4368 }
4369 else
4370 {
4371 int value = encode_arm_immediate (inst.reloc.exp.X_add_number);
4372 if (value != FAIL)
4373 {
4374 /* This can be done with a mov instruction. */
4375 inst.instruction &= LITERAL_MASK;
4376 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
4377 inst.instruction |= value & 0xfff;
4378 return 1;
4379 }
09d92015 4380
c19d1205
ZW
4381 value = encode_arm_immediate (~inst.reloc.exp.X_add_number);
4382 if (value != FAIL)
4383 {
4384 /* This can be done with a mvn instruction. */
4385 inst.instruction &= LITERAL_MASK;
4386 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
4387 inst.instruction |= value & 0xfff;
4388 return 1;
4389 }
4390 }
09d92015
MM
4391 }
4392
c19d1205
ZW
4393 if (add_to_lit_pool () == FAIL)
4394 {
4395 inst.error = _("literal pool insertion failed");
4396 return 1;
4397 }
4398 inst.operands[1].reg = REG_PC;
4399 inst.operands[1].isreg = 1;
4400 inst.operands[1].preind = 1;
4401 inst.reloc.pc_rel = 1;
4402 inst.reloc.type = (thumb_p
4403 ? BFD_RELOC_ARM_THUMB_OFFSET
4404 : (mode_3
4405 ? BFD_RELOC_ARM_HWLITERAL
4406 : BFD_RELOC_ARM_LITERAL));
4407 return 0;
09d92015
MM
4408}
4409
c19d1205
ZW
4410/* Functions for instruction encoding, sorted by subarchitecture.
4411 First some generics; their names are taken from the conventional
4412 bit positions for register arguments in ARM format instructions. */
09d92015 4413
a737bd4d 4414static void
c19d1205 4415do_noargs (void)
09d92015 4416{
c19d1205 4417}
a737bd4d 4418
c19d1205
ZW
4419static void
4420do_rd (void)
4421{
4422 inst.instruction |= inst.operands[0].reg << 12;
4423}
a737bd4d 4424
c19d1205
ZW
4425static void
4426do_rd_rm (void)
4427{
4428 inst.instruction |= inst.operands[0].reg << 12;
4429 inst.instruction |= inst.operands[1].reg;
4430}
09d92015 4431
c19d1205
ZW
4432static void
4433do_rd_rn (void)
4434{
4435 inst.instruction |= inst.operands[0].reg << 12;
4436 inst.instruction |= inst.operands[1].reg << 16;
4437}
a737bd4d 4438
c19d1205
ZW
4439static void
4440do_rn_rd (void)
4441{
4442 inst.instruction |= inst.operands[0].reg << 16;
4443 inst.instruction |= inst.operands[1].reg << 12;
4444}
09d92015 4445
c19d1205
ZW
4446static void
4447do_rd_rm_rn (void)
4448{
9a64e435
PB
4449 unsigned Rn = inst.operands[2].reg;
4450 /* Enforce resutrictions on SWP instruction. */
4451 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
4452 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
4453 _("Rn must not overlap other operands"));
c19d1205
ZW
4454 inst.instruction |= inst.operands[0].reg << 12;
4455 inst.instruction |= inst.operands[1].reg;
9a64e435 4456 inst.instruction |= Rn << 16;
c19d1205 4457}
09d92015 4458
c19d1205
ZW
4459static void
4460do_rd_rn_rm (void)
4461{
4462 inst.instruction |= inst.operands[0].reg << 12;
4463 inst.instruction |= inst.operands[1].reg << 16;
4464 inst.instruction |= inst.operands[2].reg;
4465}
a737bd4d 4466
c19d1205
ZW
4467static void
4468do_rm_rd_rn (void)
4469{
4470 inst.instruction |= inst.operands[0].reg;
4471 inst.instruction |= inst.operands[1].reg << 12;
4472 inst.instruction |= inst.operands[2].reg << 16;
4473}
09d92015 4474
c19d1205
ZW
4475static void
4476do_imm0 (void)
4477{
4478 inst.instruction |= inst.operands[0].imm;
4479}
09d92015 4480
c19d1205
ZW
4481static void
4482do_rd_cpaddr (void)
4483{
4484 inst.instruction |= inst.operands[0].reg << 12;
4485 encode_arm_cp_address (1, TRUE, TRUE, 0);
09d92015 4486}
a737bd4d 4487
c19d1205
ZW
4488/* ARM instructions, in alphabetical order by function name (except
4489 that wrapper functions appear immediately after the function they
4490 wrap). */
09d92015 4491
c19d1205
ZW
4492/* This is a pseudo-op of the form "adr rd, label" to be converted
4493 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
4494
4495static void
c19d1205 4496do_adr (void)
09d92015 4497{
c19d1205 4498 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 4499
c19d1205
ZW
4500 /* Frag hacking will turn this into a sub instruction if the offset turns
4501 out to be negative. */
4502 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
c19d1205 4503 inst.reloc.pc_rel = 1;
2fc8bdac 4504 inst.reloc.exp.X_add_number -= 8;
c19d1205 4505}
b99bd4ef 4506
c19d1205
ZW
4507/* This is a pseudo-op of the form "adrl rd, label" to be converted
4508 into a relative address of the form:
4509 add rd, pc, #low(label-.-8)"
4510 add rd, rd, #high(label-.-8)" */
b99bd4ef 4511
c19d1205
ZW
4512static void
4513do_adrl (void)
4514{
4515 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 4516
c19d1205
ZW
4517 /* Frag hacking will turn this into a sub instruction if the offset turns
4518 out to be negative. */
4519 inst.reloc.type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
c19d1205
ZW
4520 inst.reloc.pc_rel = 1;
4521 inst.size = INSN_SIZE * 2;
2fc8bdac 4522 inst.reloc.exp.X_add_number -= 8;
b99bd4ef
NC
4523}
4524
b99bd4ef 4525static void
c19d1205 4526do_arit (void)
b99bd4ef 4527{
c19d1205
ZW
4528 if (!inst.operands[1].present)
4529 inst.operands[1].reg = inst.operands[0].reg;
4530 inst.instruction |= inst.operands[0].reg << 12;
4531 inst.instruction |= inst.operands[1].reg << 16;
4532 encode_arm_shifter_operand (2);
4533}
b99bd4ef 4534
c19d1205
ZW
4535static void
4536do_bfc (void)
4537{
4538 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
4539 constraint (msb > 32, _("bit-field extends past end of register"));
4540 /* The instruction encoding stores the LSB and MSB,
4541 not the LSB and width. */
4542 inst.instruction |= inst.operands[0].reg << 12;
4543 inst.instruction |= inst.operands[1].imm << 7;
4544 inst.instruction |= (msb - 1) << 16;
4545}
b99bd4ef 4546
c19d1205
ZW
4547static void
4548do_bfi (void)
4549{
4550 unsigned int msb;
b99bd4ef 4551
c19d1205
ZW
4552 /* #0 in second position is alternative syntax for bfc, which is
4553 the same instruction but with REG_PC in the Rm field. */
4554 if (!inst.operands[1].isreg)
4555 inst.operands[1].reg = REG_PC;
b99bd4ef 4556
c19d1205
ZW
4557 msb = inst.operands[2].imm + inst.operands[3].imm;
4558 constraint (msb > 32, _("bit-field extends past end of register"));
4559 /* The instruction encoding stores the LSB and MSB,
4560 not the LSB and width. */
4561 inst.instruction |= inst.operands[0].reg << 12;
4562 inst.instruction |= inst.operands[1].reg;
4563 inst.instruction |= inst.operands[2].imm << 7;
4564 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
4565}
4566
b99bd4ef 4567static void
c19d1205 4568do_bfx (void)
b99bd4ef 4569{
c19d1205
ZW
4570 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
4571 _("bit-field extends past end of register"));
4572 inst.instruction |= inst.operands[0].reg << 12;
4573 inst.instruction |= inst.operands[1].reg;
4574 inst.instruction |= inst.operands[2].imm << 7;
4575 inst.instruction |= (inst.operands[3].imm - 1) << 16;
4576}
09d92015 4577
c19d1205
ZW
4578/* ARM V5 breakpoint instruction (argument parse)
4579 BKPT <16 bit unsigned immediate>
4580 Instruction is not conditional.
4581 The bit pattern given in insns[] has the COND_ALWAYS condition,
4582 and it is an error if the caller tried to override that. */
b99bd4ef 4583
c19d1205
ZW
4584static void
4585do_bkpt (void)
4586{
4587 /* Top 12 of 16 bits to bits 19:8. */
4588 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 4589
c19d1205
ZW
4590 /* Bottom 4 of 16 bits to bits 3:0. */
4591 inst.instruction |= inst.operands[0].imm & 0xf;
4592}
09d92015 4593
c19d1205
ZW
4594static void
4595encode_branch (int default_reloc)
4596{
4597 if (inst.operands[0].hasreloc)
4598 {
4599 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32,
4600 _("the only suffix valid here is '(plt)'"));
4601 inst.reloc.type = BFD_RELOC_ARM_PLT32;
c19d1205 4602 }
b99bd4ef 4603 else
c19d1205
ZW
4604 {
4605 inst.reloc.type = default_reloc;
c19d1205 4606 }
2fc8bdac 4607 inst.reloc.pc_rel = 1;
b99bd4ef
NC
4608}
4609
b99bd4ef 4610static void
c19d1205 4611do_branch (void)
b99bd4ef 4612{
c19d1205
ZW
4613 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
4614}
b99bd4ef 4615
c19d1205
ZW
4616/* ARM V5 branch-link-exchange instruction (argument parse)
4617 BLX <target_addr> ie BLX(1)
4618 BLX{<condition>} <Rm> ie BLX(2)
4619 Unfortunately, there are two different opcodes for this mnemonic.
4620 So, the insns[].value is not used, and the code here zaps values
4621 into inst.instruction.
4622 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 4623
c19d1205
ZW
4624static void
4625do_blx (void)
4626{
4627 if (inst.operands[0].isreg)
b99bd4ef 4628 {
c19d1205
ZW
4629 /* Arg is a register; the opcode provided by insns[] is correct.
4630 It is not illegal to do "blx pc", just useless. */
4631 if (inst.operands[0].reg == REG_PC)
4632 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 4633
c19d1205
ZW
4634 inst.instruction |= inst.operands[0].reg;
4635 }
4636 else
b99bd4ef 4637 {
c19d1205
ZW
4638 /* Arg is an address; this instruction cannot be executed
4639 conditionally, and the opcode must be adjusted. */
4640 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 4641 inst.instruction = 0xfa000000;
c19d1205 4642 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 4643 }
c19d1205
ZW
4644}
4645
4646static void
4647do_bx (void)
4648{
4649 if (inst.operands[0].reg == REG_PC)
4650 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 4651
c19d1205 4652 inst.instruction |= inst.operands[0].reg;
09d92015
MM
4653}
4654
c19d1205
ZW
4655
4656/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
4657
4658static void
c19d1205 4659do_bxj (void)
a737bd4d 4660{
c19d1205
ZW
4661 if (inst.operands[0].reg == REG_PC)
4662 as_tsktsk (_("use of r15 in bxj is not really useful"));
4663
4664 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
4665}
4666
c19d1205
ZW
4667/* Co-processor data operation:
4668 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
4669 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
4670static void
4671do_cdp (void)
4672{
4673 inst.instruction |= inst.operands[0].reg << 8;
4674 inst.instruction |= inst.operands[1].imm << 20;
4675 inst.instruction |= inst.operands[2].reg << 12;
4676 inst.instruction |= inst.operands[3].reg << 16;
4677 inst.instruction |= inst.operands[4].reg;
4678 inst.instruction |= inst.operands[5].imm << 5;
4679}
a737bd4d
NC
4680
4681static void
c19d1205 4682do_cmp (void)
a737bd4d 4683{
c19d1205
ZW
4684 inst.instruction |= inst.operands[0].reg << 16;
4685 encode_arm_shifter_operand (1);
a737bd4d
NC
4686}
4687
c19d1205
ZW
4688/* Transfer between coprocessor and ARM registers.
4689 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
4690 MRC2
4691 MCR{cond}
4692 MCR2
4693
4694 No special properties. */
09d92015
MM
4695
4696static void
c19d1205 4697do_co_reg (void)
09d92015 4698{
c19d1205
ZW
4699 inst.instruction |= inst.operands[0].reg << 8;
4700 inst.instruction |= inst.operands[1].imm << 21;
4701 inst.instruction |= inst.operands[2].reg << 12;
4702 inst.instruction |= inst.operands[3].reg << 16;
4703 inst.instruction |= inst.operands[4].reg;
4704 inst.instruction |= inst.operands[5].imm << 5;
4705}
09d92015 4706
c19d1205
ZW
4707/* Transfer between coprocessor register and pair of ARM registers.
4708 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
4709 MCRR2
4710 MRRC{cond}
4711 MRRC2
b99bd4ef 4712
c19d1205 4713 Two XScale instructions are special cases of these:
09d92015 4714
c19d1205
ZW
4715 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
4716 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 4717
c19d1205 4718 Result unpredicatable if Rd or Rn is R15. */
a737bd4d 4719
c19d1205
ZW
4720static void
4721do_co_reg2c (void)
4722{
4723 inst.instruction |= inst.operands[0].reg << 8;
4724 inst.instruction |= inst.operands[1].imm << 4;
4725 inst.instruction |= inst.operands[2].reg << 12;
4726 inst.instruction |= inst.operands[3].reg << 16;
4727 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
4728}
4729
c19d1205
ZW
4730static void
4731do_cpsi (void)
4732{
4733 inst.instruction |= inst.operands[0].imm << 6;
4734 inst.instruction |= inst.operands[1].imm;
4735}
b99bd4ef
NC
4736
4737static void
c19d1205 4738do_it (void)
b99bd4ef 4739{
c19d1205
ZW
4740 /* There is no IT instruction in ARM mode. We
4741 process it but do not generate code for it. */
4742 inst.size = 0;
09d92015 4743}
b99bd4ef 4744
09d92015 4745static void
c19d1205 4746do_ldmstm (void)
ea6ef066 4747{
c19d1205
ZW
4748 int base_reg = inst.operands[0].reg;
4749 int range = inst.operands[1].imm;
ea6ef066 4750
c19d1205
ZW
4751 inst.instruction |= base_reg << 16;
4752 inst.instruction |= range;
ea6ef066 4753
c19d1205
ZW
4754 if (inst.operands[1].writeback)
4755 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 4756
c19d1205 4757 if (inst.operands[0].writeback)
ea6ef066 4758 {
c19d1205
ZW
4759 inst.instruction |= WRITE_BACK;
4760 /* Check for unpredictable uses of writeback. */
4761 if (inst.instruction & LOAD_BIT)
09d92015 4762 {
c19d1205
ZW
4763 /* Not allowed in LDM type 2. */
4764 if ((inst.instruction & LDM_TYPE_2_OR_3)
4765 && ((range & (1 << REG_PC)) == 0))
4766 as_warn (_("writeback of base register is UNPREDICTABLE"));
4767 /* Only allowed if base reg not in list for other types. */
4768 else if (range & (1 << base_reg))
4769 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
4770 }
4771 else /* STM. */
4772 {
4773 /* Not allowed for type 2. */
4774 if (inst.instruction & LDM_TYPE_2_OR_3)
4775 as_warn (_("writeback of base register is UNPREDICTABLE"));
4776 /* Only allowed if base reg not in list, or first in list. */
4777 else if ((range & (1 << base_reg))
4778 && (range & ((1 << base_reg) - 1)))
4779 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 4780 }
ea6ef066 4781 }
a737bd4d
NC
4782}
4783
c19d1205
ZW
4784/* ARMv5TE load-consecutive (argument parse)
4785 Mode is like LDRH.
4786
4787 LDRccD R, mode
4788 STRccD R, mode. */
4789
a737bd4d 4790static void
c19d1205 4791do_ldrd (void)
a737bd4d 4792{
c19d1205
ZW
4793 constraint (inst.operands[0].reg % 2 != 0,
4794 _("first destination register must be even"));
4795 constraint (inst.operands[1].present
4796 && inst.operands[1].reg != inst.operands[0].reg + 1,
4797 _("can only load two consecutive registers"));
4798 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
4799 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 4800
c19d1205
ZW
4801 if (!inst.operands[1].present)
4802 inst.operands[1].reg = inst.operands[0].reg + 1;
4803
4804 if (inst.instruction & LOAD_BIT)
a737bd4d 4805 {
c19d1205
ZW
4806 /* encode_arm_addr_mode_3 will diagnose overlap between the base
4807 register and the first register written; we have to diagnose
4808 overlap between the base and the second register written here. */
ea6ef066 4809
c19d1205
ZW
4810 if (inst.operands[2].reg == inst.operands[1].reg
4811 && (inst.operands[2].writeback || inst.operands[2].postind))
4812 as_warn (_("base register written back, and overlaps "
4813 "second destination register"));
b05fe5cf 4814
c19d1205
ZW
4815 /* For an index-register load, the index register must not overlap the
4816 destination (even if not write-back). */
4817 else if (inst.operands[2].immisreg
ca3f61f7
NC
4818 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
4819 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
c19d1205 4820 as_warn (_("index register overlaps destination register"));
b05fe5cf 4821 }
c19d1205
ZW
4822
4823 inst.instruction |= inst.operands[0].reg << 12;
4824 encode_arm_addr_mode_3 (2, /*is_t=*/FALSE);
b05fe5cf
ZW
4825}
4826
4827static void
c19d1205 4828do_ldrex (void)
b05fe5cf 4829{
c19d1205
ZW
4830 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
4831 || inst.operands[1].postind || inst.operands[1].writeback
4832 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
4833 || inst.operands[1].negative
4834 /* This can arise if the programmer has written
4835 strex rN, rM, foo
4836 or if they have mistakenly used a register name as the last
4837 operand, eg:
4838 strex rN, rM, rX
4839 It is very difficult to distinguish between these two cases
4840 because "rX" might actually be a label. ie the register
4841 name has been occluded by a symbol of the same name. So we
4842 just generate a general 'bad addressing mode' type error
4843 message and leave it up to the programmer to discover the
4844 true cause and fix their mistake. */
4845 || (inst.operands[1].reg == REG_PC),
4846 BAD_ADDR_MODE);
b05fe5cf 4847
c19d1205
ZW
4848 constraint (inst.reloc.exp.X_op != O_constant
4849 || inst.reloc.exp.X_add_number != 0,
4850 _("offset must be zero in ARM encoding"));
b05fe5cf 4851
c19d1205
ZW
4852 inst.instruction |= inst.operands[0].reg << 12;
4853 inst.instruction |= inst.operands[1].reg << 16;
4854 inst.reloc.type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
4855}
4856
4857static void
c19d1205 4858do_ldrexd (void)
b05fe5cf 4859{
c19d1205
ZW
4860 constraint (inst.operands[0].reg % 2 != 0,
4861 _("even register required"));
4862 constraint (inst.operands[1].present
4863 && inst.operands[1].reg != inst.operands[0].reg + 1,
4864 _("can only load two consecutive registers"));
4865 /* If op 1 were present and equal to PC, this function wouldn't
4866 have been called in the first place. */
4867 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 4868
c19d1205
ZW
4869 inst.instruction |= inst.operands[0].reg << 12;
4870 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
4871}
4872
4873static void
c19d1205 4874do_ldst (void)
b05fe5cf 4875{
c19d1205
ZW
4876 inst.instruction |= inst.operands[0].reg << 12;
4877 if (!inst.operands[1].isreg)
4878 if (move_or_literal_pool (0, /*thumb_p=*/FALSE, /*mode_3=*/FALSE))
b05fe5cf 4879 return;
c19d1205 4880 encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
b05fe5cf
ZW
4881}
4882
4883static void
c19d1205 4884do_ldstt (void)
b05fe5cf 4885{
c19d1205
ZW
4886 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
4887 reject [Rn,...]. */
4888 if (inst.operands[1].preind)
b05fe5cf 4889 {
c19d1205
ZW
4890 constraint (inst.reloc.exp.X_op != O_constant ||
4891 inst.reloc.exp.X_add_number != 0,
4892 _("this instruction requires a post-indexed address"));
b05fe5cf 4893
c19d1205
ZW
4894 inst.operands[1].preind = 0;
4895 inst.operands[1].postind = 1;
4896 inst.operands[1].writeback = 1;
b05fe5cf 4897 }
c19d1205
ZW
4898 inst.instruction |= inst.operands[0].reg << 12;
4899 encode_arm_addr_mode_2 (1, /*is_t=*/TRUE);
4900}
b05fe5cf 4901
c19d1205 4902/* Halfword and signed-byte load/store operations. */
b05fe5cf 4903
c19d1205
ZW
4904static void
4905do_ldstv4 (void)
4906{
4907 inst.instruction |= inst.operands[0].reg << 12;
4908 if (!inst.operands[1].isreg)
4909 if (move_or_literal_pool (0, /*thumb_p=*/FALSE, /*mode_3=*/TRUE))
b05fe5cf 4910 return;
c19d1205 4911 encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
b05fe5cf
ZW
4912}
4913
4914static void
c19d1205 4915do_ldsttv4 (void)
b05fe5cf 4916{
c19d1205
ZW
4917 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
4918 reject [Rn,...]. */
4919 if (inst.operands[1].preind)
b05fe5cf 4920 {
c19d1205
ZW
4921 constraint (inst.reloc.exp.X_op != O_constant ||
4922 inst.reloc.exp.X_add_number != 0,
4923 _("this instruction requires a post-indexed address"));
b05fe5cf 4924
c19d1205
ZW
4925 inst.operands[1].preind = 0;
4926 inst.operands[1].postind = 1;
4927 inst.operands[1].writeback = 1;
b05fe5cf 4928 }
c19d1205
ZW
4929 inst.instruction |= inst.operands[0].reg << 12;
4930 encode_arm_addr_mode_3 (1, /*is_t=*/TRUE);
4931}
b05fe5cf 4932
c19d1205
ZW
4933/* Co-processor register load/store.
4934 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
4935static void
4936do_lstc (void)
4937{
4938 inst.instruction |= inst.operands[0].reg << 8;
4939 inst.instruction |= inst.operands[1].reg << 12;
4940 encode_arm_cp_address (2, TRUE, TRUE, 0);
b05fe5cf
ZW
4941}
4942
b05fe5cf 4943static void
c19d1205 4944do_mlas (void)
b05fe5cf 4945{
c19d1205
ZW
4946 /* This restriction does not apply to mls (nor to mla in v6, but
4947 that's hard to detect at present). */
4948 if (inst.operands[0].reg == inst.operands[1].reg
4949 && !(inst.instruction & 0x00400000))
4950 as_tsktsk (_("rd and rm should be different in mla"));
b05fe5cf 4951
c19d1205
ZW
4952 inst.instruction |= inst.operands[0].reg << 16;
4953 inst.instruction |= inst.operands[1].reg;
4954 inst.instruction |= inst.operands[2].reg << 8;
4955 inst.instruction |= inst.operands[3].reg << 12;
b05fe5cf 4956
c19d1205 4957}
b05fe5cf 4958
c19d1205
ZW
4959static void
4960do_mov (void)
4961{
4962 inst.instruction |= inst.operands[0].reg << 12;
4963 encode_arm_shifter_operand (1);
4964}
b05fe5cf 4965
c19d1205
ZW
4966/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
4967static void
4968do_mov16 (void)
4969{
4970 inst.instruction |= inst.operands[0].reg << 12;
b05fe5cf 4971 /* The value is in two pieces: 0:11, 16:19. */
c19d1205
ZW
4972 inst.instruction |= (inst.operands[1].imm & 0x00000fff);
4973 inst.instruction |= (inst.operands[1].imm & 0x0000f000) << 4;
b05fe5cf 4974}
b99bd4ef
NC
4975
4976static void
c19d1205 4977do_mrs (void)
b99bd4ef 4978{
c19d1205
ZW
4979 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
4980 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
4981 != (PSR_c|PSR_f),
4982 _("'CPSR' or 'SPSR' expected"));
4983 inst.instruction |= inst.operands[0].reg << 12;
4984 inst.instruction |= (inst.operands[1].imm & SPSR_BIT);
4985}
b99bd4ef 4986
c19d1205
ZW
4987/* Two possible forms:
4988 "{C|S}PSR_<field>, Rm",
4989 "{C|S}PSR_f, #expression". */
b99bd4ef 4990
c19d1205
ZW
4991static void
4992do_msr (void)
4993{
4994 inst.instruction |= inst.operands[0].imm;
4995 if (inst.operands[1].isreg)
4996 inst.instruction |= inst.operands[1].reg;
4997 else
b99bd4ef 4998 {
c19d1205
ZW
4999 inst.instruction |= INST_IMMEDIATE;
5000 inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
5001 inst.reloc.pc_rel = 0;
b99bd4ef 5002 }
b99bd4ef
NC
5003}
5004
c19d1205
ZW
5005static void
5006do_mul (void)
a737bd4d 5007{
c19d1205
ZW
5008 if (!inst.operands[2].present)
5009 inst.operands[2].reg = inst.operands[0].reg;
5010 inst.instruction |= inst.operands[0].reg << 16;
5011 inst.instruction |= inst.operands[1].reg;
5012 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 5013
c19d1205
ZW
5014 if (inst.operands[0].reg == inst.operands[1].reg)
5015 as_tsktsk (_("rd and rm should be different in mul"));
a737bd4d
NC
5016}
5017
c19d1205
ZW
5018/* Long Multiply Parser
5019 UMULL RdLo, RdHi, Rm, Rs
5020 SMULL RdLo, RdHi, Rm, Rs
5021 UMLAL RdLo, RdHi, Rm, Rs
5022 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
5023
5024static void
c19d1205 5025do_mull (void)
b99bd4ef 5026{
c19d1205
ZW
5027 inst.instruction |= inst.operands[0].reg << 12;
5028 inst.instruction |= inst.operands[1].reg << 16;
5029 inst.instruction |= inst.operands[2].reg;
5030 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 5031
c19d1205
ZW
5032 /* rdhi, rdlo and rm must all be different. */
5033 if (inst.operands[0].reg == inst.operands[1].reg
5034 || inst.operands[0].reg == inst.operands[2].reg
5035 || inst.operands[1].reg == inst.operands[2].reg)
5036 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
5037}
b99bd4ef 5038
c19d1205
ZW
5039static void
5040do_nop (void)
5041{
5042 if (inst.operands[0].present)
5043 {
5044 /* Architectural NOP hints are CPSR sets with no bits selected. */
5045 inst.instruction &= 0xf0000000;
5046 inst.instruction |= 0x0320f000 + inst.operands[0].imm;
5047 }
b99bd4ef
NC
5048}
5049
c19d1205
ZW
5050/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
5051 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
5052 Condition defaults to COND_ALWAYS.
5053 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
5054
5055static void
c19d1205 5056do_pkhbt (void)
b99bd4ef 5057{
c19d1205
ZW
5058 inst.instruction |= inst.operands[0].reg << 12;
5059 inst.instruction |= inst.operands[1].reg << 16;
5060 inst.instruction |= inst.operands[2].reg;
5061 if (inst.operands[3].present)
5062 encode_arm_shift (3);
5063}
b99bd4ef 5064
c19d1205 5065/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 5066
c19d1205
ZW
5067static void
5068do_pkhtb (void)
5069{
5070 if (!inst.operands[3].present)
b99bd4ef 5071 {
c19d1205
ZW
5072 /* If the shift specifier is omitted, turn the instruction
5073 into pkhbt rd, rm, rn. */
5074 inst.instruction &= 0xfff00010;
5075 inst.instruction |= inst.operands[0].reg << 12;
5076 inst.instruction |= inst.operands[1].reg;
5077 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
5078 }
5079 else
5080 {
c19d1205
ZW
5081 inst.instruction |= inst.operands[0].reg << 12;
5082 inst.instruction |= inst.operands[1].reg << 16;
5083 inst.instruction |= inst.operands[2].reg;
5084 encode_arm_shift (3);
b99bd4ef
NC
5085 }
5086}
5087
c19d1205
ZW
5088/* ARMv5TE: Preload-Cache
5089
5090 PLD <addr_mode>
5091
5092 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
5093
5094static void
c19d1205 5095do_pld (void)
b99bd4ef 5096{
c19d1205
ZW
5097 constraint (!inst.operands[0].isreg,
5098 _("'[' expected after PLD mnemonic"));
5099 constraint (inst.operands[0].postind,
5100 _("post-indexed expression used in preload instruction"));
5101 constraint (inst.operands[0].writeback,
5102 _("writeback used in preload instruction"));
5103 constraint (!inst.operands[0].preind,
5104 _("unindexed addressing used in preload instruction"));
5105 inst.instruction |= inst.operands[0].reg;
5106 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
5107}
b99bd4ef 5108
c19d1205
ZW
5109static void
5110do_push_pop (void)
5111{
5112 inst.operands[1] = inst.operands[0];
5113 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
5114 inst.operands[0].isreg = 1;
5115 inst.operands[0].writeback = 1;
5116 inst.operands[0].reg = REG_SP;
5117 do_ldmstm ();
5118}
b99bd4ef 5119
c19d1205
ZW
5120/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
5121 word at the specified address and the following word
5122 respectively.
5123 Unconditionally executed.
5124 Error if Rn is R15. */
b99bd4ef 5125
c19d1205
ZW
5126static void
5127do_rfe (void)
5128{
5129 inst.instruction |= inst.operands[0].reg << 16;
5130 if (inst.operands[0].writeback)
5131 inst.instruction |= WRITE_BACK;
5132}
b99bd4ef 5133
c19d1205 5134/* ARM V6 ssat (argument parse). */
b99bd4ef 5135
c19d1205
ZW
5136static void
5137do_ssat (void)
5138{
5139 inst.instruction |= inst.operands[0].reg << 12;
5140 inst.instruction |= (inst.operands[1].imm - 1) << 16;
5141 inst.instruction |= inst.operands[2].reg;
b99bd4ef 5142
c19d1205
ZW
5143 if (inst.operands[3].present)
5144 encode_arm_shift (3);
b99bd4ef
NC
5145}
5146
c19d1205 5147/* ARM V6 usat (argument parse). */
b99bd4ef
NC
5148
5149static void
c19d1205 5150do_usat (void)
b99bd4ef 5151{
c19d1205
ZW
5152 inst.instruction |= inst.operands[0].reg << 12;
5153 inst.instruction |= inst.operands[1].imm << 16;
5154 inst.instruction |= inst.operands[2].reg;
b99bd4ef 5155
c19d1205
ZW
5156 if (inst.operands[3].present)
5157 encode_arm_shift (3);
b99bd4ef
NC
5158}
5159
c19d1205 5160/* ARM V6 ssat16 (argument parse). */
09d92015
MM
5161
5162static void
c19d1205 5163do_ssat16 (void)
09d92015 5164{
c19d1205
ZW
5165 inst.instruction |= inst.operands[0].reg << 12;
5166 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
5167 inst.instruction |= inst.operands[2].reg;
09d92015
MM
5168}
5169
c19d1205
ZW
5170static void
5171do_usat16 (void)
a737bd4d 5172{
c19d1205
ZW
5173 inst.instruction |= inst.operands[0].reg << 12;
5174 inst.instruction |= inst.operands[1].imm << 16;
5175 inst.instruction |= inst.operands[2].reg;
5176}
a737bd4d 5177
c19d1205
ZW
5178/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
5179 preserving the other bits.
a737bd4d 5180
c19d1205
ZW
5181 setend <endian_specifier>, where <endian_specifier> is either
5182 BE or LE. */
a737bd4d 5183
c19d1205
ZW
5184static void
5185do_setend (void)
5186{
5187 if (inst.operands[0].imm)
5188 inst.instruction |= 0x200;
a737bd4d
NC
5189}
5190
5191static void
c19d1205 5192do_shift (void)
a737bd4d 5193{
c19d1205
ZW
5194 unsigned int Rm = (inst.operands[1].present
5195 ? inst.operands[1].reg
5196 : inst.operands[0].reg);
a737bd4d 5197
c19d1205
ZW
5198 inst.instruction |= inst.operands[0].reg << 12;
5199 inst.instruction |= Rm;
5200 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 5201 {
c19d1205
ZW
5202 constraint (inst.operands[0].reg != Rm,
5203 _("source1 and dest must be same register"));
5204 inst.instruction |= inst.operands[2].reg << 8;
5205 inst.instruction |= SHIFT_BY_REG;
a737bd4d
NC
5206 }
5207 else
c19d1205 5208 inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
5209}
5210
09d92015 5211static void
3eb17e6b 5212do_smc (void)
09d92015 5213{
3eb17e6b 5214 inst.reloc.type = BFD_RELOC_ARM_SMC;
c19d1205 5215 inst.reloc.pc_rel = 0;
09d92015
MM
5216}
5217
09d92015 5218static void
c19d1205 5219do_swi (void)
09d92015 5220{
c19d1205
ZW
5221 inst.reloc.type = BFD_RELOC_ARM_SWI;
5222 inst.reloc.pc_rel = 0;
09d92015
MM
5223}
5224
c19d1205
ZW
5225/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
5226 SMLAxy{cond} Rd,Rm,Rs,Rn
5227 SMLAWy{cond} Rd,Rm,Rs,Rn
5228 Error if any register is R15. */
e16bb312 5229
c19d1205
ZW
5230static void
5231do_smla (void)
e16bb312 5232{
c19d1205
ZW
5233 inst.instruction |= inst.operands[0].reg << 16;
5234 inst.instruction |= inst.operands[1].reg;
5235 inst.instruction |= inst.operands[2].reg << 8;
5236 inst.instruction |= inst.operands[3].reg << 12;
5237}
a737bd4d 5238
c19d1205
ZW
5239/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
5240 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
5241 Error if any register is R15.
5242 Warning if Rdlo == Rdhi. */
a737bd4d 5243
c19d1205
ZW
5244static void
5245do_smlal (void)
5246{
5247 inst.instruction |= inst.operands[0].reg << 12;
5248 inst.instruction |= inst.operands[1].reg << 16;
5249 inst.instruction |= inst.operands[2].reg;
5250 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 5251
c19d1205
ZW
5252 if (inst.operands[0].reg == inst.operands[1].reg)
5253 as_tsktsk (_("rdhi and rdlo must be different"));
5254}
a737bd4d 5255
c19d1205
ZW
5256/* ARM V5E (El Segundo) signed-multiply (argument parse)
5257 SMULxy{cond} Rd,Rm,Rs
5258 Error if any register is R15. */
a737bd4d 5259
c19d1205
ZW
5260static void
5261do_smul (void)
5262{
5263 inst.instruction |= inst.operands[0].reg << 16;
5264 inst.instruction |= inst.operands[1].reg;
5265 inst.instruction |= inst.operands[2].reg << 8;
5266}
a737bd4d 5267
c19d1205 5268/* ARM V6 srs (argument parse). */
a737bd4d 5269
c19d1205
ZW
5270static void
5271do_srs (void)
5272{
5273 inst.instruction |= inst.operands[0].imm;
5274 if (inst.operands[0].writeback)
5275 inst.instruction |= WRITE_BACK;
5276}
a737bd4d 5277
c19d1205 5278/* ARM V6 strex (argument parse). */
a737bd4d 5279
c19d1205
ZW
5280static void
5281do_strex (void)
5282{
5283 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
5284 || inst.operands[2].postind || inst.operands[2].writeback
5285 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
5286 || inst.operands[2].negative
5287 /* See comment in do_ldrex(). */
5288 || (inst.operands[2].reg == REG_PC),
5289 BAD_ADDR_MODE);
a737bd4d 5290
c19d1205
ZW
5291 constraint (inst.operands[0].reg == inst.operands[1].reg
5292 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 5293
c19d1205
ZW
5294 constraint (inst.reloc.exp.X_op != O_constant
5295 || inst.reloc.exp.X_add_number != 0,
5296 _("offset must be zero in ARM encoding"));
a737bd4d 5297
c19d1205
ZW
5298 inst.instruction |= inst.operands[0].reg << 12;
5299 inst.instruction |= inst.operands[1].reg;
5300 inst.instruction |= inst.operands[2].reg << 16;
5301 inst.reloc.type = BFD_RELOC_UNUSED;
e16bb312
NC
5302}
5303
5304static void
c19d1205 5305do_strexd (void)
e16bb312 5306{
c19d1205
ZW
5307 constraint (inst.operands[1].reg % 2 != 0,
5308 _("even register required"));
5309 constraint (inst.operands[2].present
5310 && inst.operands[2].reg != inst.operands[1].reg + 1,
5311 _("can only store two consecutive registers"));
5312 /* If op 2 were present and equal to PC, this function wouldn't
5313 have been called in the first place. */
5314 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 5315
c19d1205
ZW
5316 constraint (inst.operands[0].reg == inst.operands[1].reg
5317 || inst.operands[0].reg == inst.operands[1].reg + 1
5318 || inst.operands[0].reg == inst.operands[3].reg,
5319 BAD_OVERLAP);
e16bb312 5320
c19d1205
ZW
5321 inst.instruction |= inst.operands[0].reg << 12;
5322 inst.instruction |= inst.operands[1].reg;
5323 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
5324}
5325
c19d1205
ZW
5326/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
5327 extends it to 32-bits, and adds the result to a value in another
5328 register. You can specify a rotation by 0, 8, 16, or 24 bits
5329 before extracting the 16-bit value.
5330 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
5331 Condition defaults to COND_ALWAYS.
5332 Error if any register uses R15. */
5333
e16bb312 5334static void
c19d1205 5335do_sxtah (void)
e16bb312 5336{
c19d1205
ZW
5337 inst.instruction |= inst.operands[0].reg << 12;
5338 inst.instruction |= inst.operands[1].reg << 16;
5339 inst.instruction |= inst.operands[2].reg;
5340 inst.instruction |= inst.operands[3].imm << 10;
5341}
e16bb312 5342
c19d1205 5343/* ARM V6 SXTH.
e16bb312 5344
c19d1205
ZW
5345 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
5346 Condition defaults to COND_ALWAYS.
5347 Error if any register uses R15. */
e16bb312
NC
5348
5349static void
c19d1205 5350do_sxth (void)
e16bb312 5351{
c19d1205
ZW
5352 inst.instruction |= inst.operands[0].reg << 12;
5353 inst.instruction |= inst.operands[1].reg;
5354 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 5355}
c19d1205
ZW
5356\f
5357/* VFP instructions. In a logical order: SP variant first, monad
5358 before dyad, arithmetic then move then load/store. */
e16bb312
NC
5359
5360static void
c19d1205 5361do_vfp_sp_monadic (void)
e16bb312 5362{
c19d1205
ZW
5363 encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sd);
5364 encode_arm_vfp_sp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
5365}
5366
5367static void
c19d1205 5368do_vfp_sp_dyadic (void)
e16bb312 5369{
c19d1205
ZW
5370 encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sd);
5371 encode_arm_vfp_sp_reg (inst.operands[1].reg, VFP_REG_Sn);
5372 encode_arm_vfp_sp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
5373}
5374
5375static void
c19d1205 5376do_vfp_sp_compare_z (void)
e16bb312 5377{
c19d1205 5378 encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
5379}
5380
5381static void
c19d1205 5382do_vfp_dp_sp_cvt (void)
e16bb312 5383{
c19d1205
ZW
5384 inst.instruction |= inst.operands[0].reg << 12;
5385 encode_arm_vfp_sp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
5386}
5387
5388static void
c19d1205 5389do_vfp_sp_dp_cvt (void)
e16bb312 5390{
c19d1205
ZW
5391 encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sd);
5392 inst.instruction |= inst.operands[1].reg;
e16bb312
NC
5393}
5394
5395static void
c19d1205 5396do_vfp_reg_from_sp (void)
e16bb312 5397{
c19d1205
ZW
5398 inst.instruction |= inst.operands[0].reg << 12;
5399 encode_arm_vfp_sp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
5400}
5401
5402static void
c19d1205 5403do_vfp_reg2_from_sp2 (void)
e16bb312 5404{
c19d1205
ZW
5405 constraint (inst.operands[2].imm != 2,
5406 _("only two consecutive VFP SP registers allowed here"));
5407 inst.instruction |= inst.operands[0].reg << 12;
5408 inst.instruction |= inst.operands[1].reg << 16;
5409 encode_arm_vfp_sp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
5410}
5411
5412static void
c19d1205 5413do_vfp_sp_from_reg (void)
e16bb312 5414{
c19d1205
ZW
5415 encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sn);
5416 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
5417}
5418
5419static void
c19d1205 5420do_vfp_sp2_from_reg2 (void)
e16bb312 5421{
c19d1205
ZW
5422 constraint (inst.operands[0].imm != 2,
5423 _("only two consecutive VFP SP registers allowed here"));
5424 encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sm);
5425 inst.instruction |= inst.operands[1].reg << 12;
5426 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
5427}
5428
5429static void
c19d1205 5430do_vfp_sp_ldst (void)
e16bb312 5431{
c19d1205
ZW
5432 encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sd);
5433 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
5434}
5435
5436static void
c19d1205 5437do_vfp_dp_ldst (void)
e16bb312 5438{
c19d1205
ZW
5439 inst.instruction |= inst.operands[0].reg << 12;
5440 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
5441}
5442
c19d1205 5443
e16bb312 5444static void
c19d1205 5445vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 5446{
c19d1205
ZW
5447 if (inst.operands[0].writeback)
5448 inst.instruction |= WRITE_BACK;
5449 else
5450 constraint (ldstm_type != VFP_LDSTMIA,
5451 _("this addressing mode requires base-register writeback"));
5452 inst.instruction |= inst.operands[0].reg << 16;
5453 encode_arm_vfp_sp_reg (inst.operands[1].reg, VFP_REG_Sd);
5454 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
5455}
5456
5457static void
c19d1205 5458vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 5459{
c19d1205 5460 int count;
e16bb312 5461
c19d1205
ZW
5462 if (inst.operands[0].writeback)
5463 inst.instruction |= WRITE_BACK;
5464 else
5465 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
5466 _("this addressing mode requires base-register writeback"));
e16bb312 5467
c19d1205
ZW
5468 inst.instruction |= inst.operands[0].reg << 16;
5469 inst.instruction |= inst.operands[1].reg << 12;
e16bb312 5470
c19d1205
ZW
5471 count = inst.operands[1].imm << 1;
5472 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
5473 count += 1;
e16bb312 5474
c19d1205 5475 inst.instruction |= count;
e16bb312
NC
5476}
5477
5478static void
c19d1205 5479do_vfp_sp_ldstmia (void)
e16bb312 5480{
c19d1205 5481 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
5482}
5483
5484static void
c19d1205 5485do_vfp_sp_ldstmdb (void)
e16bb312 5486{
c19d1205 5487 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
5488}
5489
5490static void
c19d1205 5491do_vfp_dp_ldstmia (void)
e16bb312 5492{
c19d1205 5493 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
5494}
5495
5496static void
c19d1205 5497do_vfp_dp_ldstmdb (void)
e16bb312 5498{
c19d1205 5499 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
5500}
5501
5502static void
c19d1205 5503do_vfp_xp_ldstmia (void)
e16bb312 5504{
c19d1205
ZW
5505 vfp_dp_ldstm (VFP_LDSTMIAX);
5506}
e16bb312 5507
c19d1205
ZW
5508static void
5509do_vfp_xp_ldstmdb (void)
5510{
5511 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 5512}
c19d1205
ZW
5513\f
5514/* FPA instructions. Also in a logical order. */
e16bb312 5515
c19d1205
ZW
5516static void
5517do_fpa_cmp (void)
5518{
5519 inst.instruction |= inst.operands[0].reg << 16;
5520 inst.instruction |= inst.operands[1].reg;
5521}
b99bd4ef
NC
5522
5523static void
c19d1205 5524do_fpa_ldmstm (void)
b99bd4ef 5525{
c19d1205
ZW
5526 inst.instruction |= inst.operands[0].reg << 12;
5527 switch (inst.operands[1].imm)
5528 {
5529 case 1: inst.instruction |= CP_T_X; break;
5530 case 2: inst.instruction |= CP_T_Y; break;
5531 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
5532 case 4: break;
5533 default: abort ();
5534 }
b99bd4ef 5535
c19d1205
ZW
5536 if (inst.instruction & (PRE_INDEX | INDEX_UP))
5537 {
5538 /* The instruction specified "ea" or "fd", so we can only accept
5539 [Rn]{!}. The instruction does not really support stacking or
5540 unstacking, so we have to emulate these by setting appropriate
5541 bits and offsets. */
5542 constraint (inst.reloc.exp.X_op != O_constant
5543 || inst.reloc.exp.X_add_number != 0,
5544 _("this instruction does not support indexing"));
b99bd4ef 5545
c19d1205
ZW
5546 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
5547 inst.reloc.exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 5548
c19d1205
ZW
5549 if (!(inst.instruction & INDEX_UP))
5550 inst.reloc.exp.X_add_number = -inst.reloc.exp.X_add_number;
b99bd4ef 5551
c19d1205
ZW
5552 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
5553 {
5554 inst.operands[2].preind = 0;
5555 inst.operands[2].postind = 1;
5556 }
5557 }
b99bd4ef 5558
c19d1205 5559 encode_arm_cp_address (2, TRUE, TRUE, 0);
b99bd4ef 5560}
c19d1205
ZW
5561\f
5562/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 5563
c19d1205
ZW
5564static void
5565do_iwmmxt_tandorc (void)
5566{
5567 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
5568}
b99bd4ef 5569
c19d1205
ZW
5570static void
5571do_iwmmxt_textrc (void)
5572{
5573 inst.instruction |= inst.operands[0].reg << 12;
5574 inst.instruction |= inst.operands[1].imm;
5575}
b99bd4ef
NC
5576
5577static void
c19d1205 5578do_iwmmxt_textrm (void)
b99bd4ef 5579{
c19d1205
ZW
5580 inst.instruction |= inst.operands[0].reg << 12;
5581 inst.instruction |= inst.operands[1].reg << 16;
5582 inst.instruction |= inst.operands[2].imm;
5583}
b99bd4ef 5584
c19d1205
ZW
5585static void
5586do_iwmmxt_tinsr (void)
5587{
5588 inst.instruction |= inst.operands[0].reg << 16;
5589 inst.instruction |= inst.operands[1].reg << 12;
5590 inst.instruction |= inst.operands[2].imm;
5591}
b99bd4ef 5592
c19d1205
ZW
5593static void
5594do_iwmmxt_tmia (void)
5595{
5596 inst.instruction |= inst.operands[0].reg << 5;
5597 inst.instruction |= inst.operands[1].reg;
5598 inst.instruction |= inst.operands[2].reg << 12;
5599}
b99bd4ef 5600
c19d1205
ZW
5601static void
5602do_iwmmxt_waligni (void)
5603{
5604 inst.instruction |= inst.operands[0].reg << 12;
5605 inst.instruction |= inst.operands[1].reg << 16;
5606 inst.instruction |= inst.operands[2].reg;
5607 inst.instruction |= inst.operands[3].imm << 20;
5608}
b99bd4ef 5609
c19d1205
ZW
5610static void
5611do_iwmmxt_wmov (void)
5612{
5613 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
5614 inst.instruction |= inst.operands[0].reg << 12;
5615 inst.instruction |= inst.operands[1].reg << 16;
5616 inst.instruction |= inst.operands[1].reg;
5617}
b99bd4ef 5618
c19d1205
ZW
5619static void
5620do_iwmmxt_wldstbh (void)
5621{
8f06b2d8 5622 int reloc;
c19d1205
ZW
5623 inst.instruction |= inst.operands[0].reg << 12;
5624 inst.reloc.exp.X_add_number *= 4;
8f06b2d8
PB
5625 if (thumb_mode)
5626 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
5627 else
5628 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
5629 encode_arm_cp_address (1, TRUE, FALSE, reloc);
b99bd4ef
NC
5630}
5631
c19d1205
ZW
5632static void
5633do_iwmmxt_wldstw (void)
5634{
5635 /* RIWR_RIWC clears .isreg for a control register. */
5636 if (!inst.operands[0].isreg)
5637 {
5638 constraint (inst.cond != COND_ALWAYS, BAD_COND);
5639 inst.instruction |= 0xf0000000;
5640 }
b99bd4ef 5641
c19d1205
ZW
5642 inst.instruction |= inst.operands[0].reg << 12;
5643 encode_arm_cp_address (1, TRUE, TRUE, 0);
5644}
b99bd4ef
NC
5645
5646static void
c19d1205 5647do_iwmmxt_wldstd (void)
b99bd4ef 5648{
c19d1205 5649 inst.instruction |= inst.operands[0].reg << 12;
f2184508 5650 encode_arm_cp_address (1, TRUE, FALSE, 0);
c19d1205 5651}
b99bd4ef 5652
c19d1205
ZW
5653static void
5654do_iwmmxt_wshufh (void)
5655{
5656 inst.instruction |= inst.operands[0].reg << 12;
5657 inst.instruction |= inst.operands[1].reg << 16;
5658 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
5659 inst.instruction |= (inst.operands[2].imm & 0x0f);
5660}
b99bd4ef 5661
c19d1205
ZW
5662static void
5663do_iwmmxt_wzero (void)
5664{
5665 /* WZERO reg is an alias for WANDN reg, reg, reg. */
5666 inst.instruction |= inst.operands[0].reg;
5667 inst.instruction |= inst.operands[0].reg << 12;
5668 inst.instruction |= inst.operands[0].reg << 16;
5669}
5670\f
5671/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
5672 operations first, then control, shift, and load/store. */
b99bd4ef 5673
c19d1205 5674/* Insns like "foo X,Y,Z". */
b99bd4ef 5675
c19d1205
ZW
5676static void
5677do_mav_triple (void)
5678{
5679 inst.instruction |= inst.operands[0].reg << 16;
5680 inst.instruction |= inst.operands[1].reg;
5681 inst.instruction |= inst.operands[2].reg << 12;
5682}
b99bd4ef 5683
c19d1205
ZW
5684/* Insns like "foo W,X,Y,Z".
5685 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 5686
c19d1205
ZW
5687static void
5688do_mav_quad (void)
5689{
5690 inst.instruction |= inst.operands[0].reg << 5;
5691 inst.instruction |= inst.operands[1].reg << 12;
5692 inst.instruction |= inst.operands[2].reg << 16;
5693 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
5694}
5695
c19d1205
ZW
5696/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
5697static void
5698do_mav_dspsc (void)
a737bd4d 5699{
c19d1205
ZW
5700 inst.instruction |= inst.operands[1].reg << 12;
5701}
a737bd4d 5702
c19d1205
ZW
5703/* Maverick shift immediate instructions.
5704 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
5705 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 5706
c19d1205
ZW
5707static void
5708do_mav_shift (void)
5709{
5710 int imm = inst.operands[2].imm;
a737bd4d 5711
c19d1205
ZW
5712 inst.instruction |= inst.operands[0].reg << 12;
5713 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 5714
c19d1205
ZW
5715 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
5716 Bits 5-7 of the insn should have bits 4-6 of the immediate.
5717 Bit 4 should be 0. */
5718 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 5719
c19d1205
ZW
5720 inst.instruction |= imm;
5721}
5722\f
5723/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 5724
c19d1205
ZW
5725/* Xscale multiply-accumulate (argument parse)
5726 MIAcc acc0,Rm,Rs
5727 MIAPHcc acc0,Rm,Rs
5728 MIAxycc acc0,Rm,Rs. */
a737bd4d 5729
c19d1205
ZW
5730static void
5731do_xsc_mia (void)
5732{
5733 inst.instruction |= inst.operands[1].reg;
5734 inst.instruction |= inst.operands[2].reg << 12;
5735}
a737bd4d 5736
c19d1205 5737/* Xscale move-accumulator-register (argument parse)
a737bd4d 5738
c19d1205 5739 MARcc acc0,RdLo,RdHi. */
b99bd4ef 5740
c19d1205
ZW
5741static void
5742do_xsc_mar (void)
5743{
5744 inst.instruction |= inst.operands[1].reg << 12;
5745 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
5746}
5747
c19d1205 5748/* Xscale move-register-accumulator (argument parse)
b99bd4ef 5749
c19d1205 5750 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
5751
5752static void
c19d1205 5753do_xsc_mra (void)
b99bd4ef 5754{
c19d1205
ZW
5755 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
5756 inst.instruction |= inst.operands[0].reg << 12;
5757 inst.instruction |= inst.operands[1].reg << 16;
5758}
5759\f
5760/* Encoding functions relevant only to Thumb. */
b99bd4ef 5761
c19d1205
ZW
5762/* inst.operands[i] is a shifted-register operand; encode
5763 it into inst.instruction in the format used by Thumb32. */
5764
5765static void
5766encode_thumb32_shifted_operand (int i)
5767{
5768 unsigned int value = inst.reloc.exp.X_add_number;
5769 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 5770
9c3c69f2
PB
5771 constraint (inst.operands[i].immisreg,
5772 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
5773 inst.instruction |= inst.operands[i].reg;
5774 if (shift == SHIFT_RRX)
5775 inst.instruction |= SHIFT_ROR << 4;
5776 else
b99bd4ef 5777 {
c19d1205
ZW
5778 constraint (inst.reloc.exp.X_op != O_constant,
5779 _("expression too complex"));
5780
5781 constraint (value > 32
5782 || (value == 32 && (shift == SHIFT_LSL
5783 || shift == SHIFT_ROR)),
5784 _("shift expression is too large"));
5785
5786 if (value == 0)
5787 shift = SHIFT_LSL;
5788 else if (value == 32)
5789 value = 0;
5790
5791 inst.instruction |= shift << 4;
5792 inst.instruction |= (value & 0x1c) << 10;
5793 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 5794 }
c19d1205 5795}
b99bd4ef 5796
b99bd4ef 5797
c19d1205
ZW
5798/* inst.operands[i] was set up by parse_address. Encode it into a
5799 Thumb32 format load or store instruction. Reject forms that cannot
5800 be used with such instructions. If is_t is true, reject forms that
5801 cannot be used with a T instruction; if is_d is true, reject forms
5802 that cannot be used with a D instruction. */
b99bd4ef 5803
c19d1205
ZW
5804static void
5805encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
5806{
5807 bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
5808
5809 constraint (!inst.operands[i].isreg,
5810 _("Thumb does not support the ldr =N pseudo-operation"));
b99bd4ef 5811
c19d1205
ZW
5812 inst.instruction |= inst.operands[i].reg << 16;
5813 if (inst.operands[i].immisreg)
b99bd4ef 5814 {
c19d1205
ZW
5815 constraint (is_pc, _("cannot use register index with PC-relative addressing"));
5816 constraint (is_t || is_d, _("cannot use register index with this instruction"));
5817 constraint (inst.operands[i].negative,
5818 _("Thumb does not support negative register indexing"));
5819 constraint (inst.operands[i].postind,
5820 _("Thumb does not support register post-indexing"));
5821 constraint (inst.operands[i].writeback,
5822 _("Thumb does not support register indexing with writeback"));
5823 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
5824 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 5825
c19d1205
ZW
5826 inst.instruction |= inst.operands[1].imm;
5827 if (inst.operands[i].shifted)
b99bd4ef 5828 {
c19d1205
ZW
5829 constraint (inst.reloc.exp.X_op != O_constant,
5830 _("expression too complex"));
9c3c69f2
PB
5831 constraint (inst.reloc.exp.X_add_number < 0
5832 || inst.reloc.exp.X_add_number > 3,
c19d1205 5833 _("shift out of range"));
9c3c69f2 5834 inst.instruction |= inst.reloc.exp.X_add_number << 4;
c19d1205
ZW
5835 }
5836 inst.reloc.type = BFD_RELOC_UNUSED;
5837 }
5838 else if (inst.operands[i].preind)
5839 {
5840 constraint (is_pc && inst.operands[i].writeback,
5841 _("cannot use writeback with PC-relative addressing"));
5842 constraint (is_t && inst.operands[1].writeback,
5843 _("cannot use writeback with this instruction"));
5844
5845 if (is_d)
5846 {
5847 inst.instruction |= 0x01000000;
5848 if (inst.operands[i].writeback)
5849 inst.instruction |= 0x00200000;
b99bd4ef 5850 }
c19d1205 5851 else
b99bd4ef 5852 {
c19d1205
ZW
5853 inst.instruction |= 0x00000c00;
5854 if (inst.operands[i].writeback)
5855 inst.instruction |= 0x00000100;
b99bd4ef 5856 }
c19d1205 5857 inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 5858 }
c19d1205 5859 else if (inst.operands[i].postind)
b99bd4ef 5860 {
c19d1205
ZW
5861 assert (inst.operands[i].writeback);
5862 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
5863 constraint (is_t, _("cannot use post-indexing with this instruction"));
5864
5865 if (is_d)
5866 inst.instruction |= 0x00200000;
5867 else
5868 inst.instruction |= 0x00000900;
5869 inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_IMM;
5870 }
5871 else /* unindexed - only for coprocessor */
5872 inst.error = _("instruction does not accept unindexed addressing");
5873}
5874
5875/* Table of Thumb instructions which exist in both 16- and 32-bit
5876 encodings (the latter only in post-V6T2 cores). The index is the
5877 value used in the insns table below. When there is more than one
5878 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
5879 holds variant (1).
5880 Also contains several pseudo-instructions used during relaxation. */
c19d1205
ZW
5881#define T16_32_TAB \
5882 X(adc, 4140, eb400000), \
5883 X(adcs, 4140, eb500000), \
5884 X(add, 1c00, eb000000), \
5885 X(adds, 1c00, eb100000), \
0110f2b8
PB
5886 X(addi, 0000, f1000000), \
5887 X(addis, 0000, f1100000), \
5888 X(add_pc,000f, f20f0000), \
5889 X(add_sp,000d, f10d0000), \
e9f89963 5890 X(adr, 000f, f20f0000), \
c19d1205
ZW
5891 X(and, 4000, ea000000), \
5892 X(ands, 4000, ea100000), \
5893 X(asr, 1000, fa40f000), \
5894 X(asrs, 1000, fa50f000), \
0110f2b8
PB
5895 X(b, e000, f000b000), \
5896 X(bcond, d000, f0008000), \
c19d1205
ZW
5897 X(bic, 4380, ea200000), \
5898 X(bics, 4380, ea300000), \
5899 X(cmn, 42c0, eb100f00), \
5900 X(cmp, 2800, ebb00f00), \
5901 X(cpsie, b660, f3af8400), \
5902 X(cpsid, b670, f3af8600), \
5903 X(cpy, 4600, ea4f0000), \
0110f2b8 5904 X(dec_sp,80dd, f1bd0d00), \
c19d1205
ZW
5905 X(eor, 4040, ea800000), \
5906 X(eors, 4040, ea900000), \
0110f2b8 5907 X(inc_sp,00dd, f10d0d00), \
c19d1205
ZW
5908 X(ldmia, c800, e8900000), \
5909 X(ldr, 6800, f8500000), \
5910 X(ldrb, 7800, f8100000), \
5911 X(ldrh, 8800, f8300000), \
5912 X(ldrsb, 5600, f9100000), \
5913 X(ldrsh, 5e00, f9300000), \
0110f2b8
PB
5914 X(ldr_pc,4800, f85f0000), \
5915 X(ldr_pc2,4800, f85f0000), \
5916 X(ldr_sp,9800, f85d0000), \
c19d1205
ZW
5917 X(lsl, 0000, fa00f000), \
5918 X(lsls, 0000, fa10f000), \
5919 X(lsr, 0800, fa20f000), \
5920 X(lsrs, 0800, fa30f000), \
5921 X(mov, 2000, ea4f0000), \
5922 X(movs, 2000, ea5f0000), \
5923 X(mul, 4340, fb00f000), \
5924 X(muls, 4340, ffffffff), /* no 32b muls */ \
5925 X(mvn, 43c0, ea6f0000), \
5926 X(mvns, 43c0, ea7f0000), \
5927 X(neg, 4240, f1c00000), /* rsb #0 */ \
5928 X(negs, 4240, f1d00000), /* rsbs #0 */ \
5929 X(orr, 4300, ea400000), \
5930 X(orrs, 4300, ea500000), \
e9f89963
PB
5931 X(pop, bc00, e8bd0000), /* ldmia sp!,... */ \
5932 X(push, b400, e92d0000), /* stmdb sp!,... */ \
c19d1205
ZW
5933 X(rev, ba00, fa90f080), \
5934 X(rev16, ba40, fa90f090), \
5935 X(revsh, bac0, fa90f0b0), \
5936 X(ror, 41c0, fa60f000), \
5937 X(rors, 41c0, fa70f000), \
5938 X(sbc, 4180, eb600000), \
5939 X(sbcs, 4180, eb700000), \
5940 X(stmia, c000, e8800000), \
5941 X(str, 6000, f8400000), \
5942 X(strb, 7000, f8000000), \
5943 X(strh, 8000, f8200000), \
0110f2b8 5944 X(str_sp,9000, f84d0000), \
c19d1205
ZW
5945 X(sub, 1e00, eba00000), \
5946 X(subs, 1e00, ebb00000), \
0110f2b8
PB
5947 X(subi, 8000, f1a00000), \
5948 X(subis, 8000, f1b00000), \
c19d1205
ZW
5949 X(sxtb, b240, fa4ff080), \
5950 X(sxth, b200, fa0ff080), \
5951 X(tst, 4200, ea100f00), \
5952 X(uxtb, b2c0, fa5ff080), \
5953 X(uxth, b280, fa1ff080), \
5954 X(nop, bf00, f3af8000), \
5955 X(yield, bf10, f3af8001), \
5956 X(wfe, bf20, f3af8002), \
5957 X(wfi, bf30, f3af8003), \
5958 X(sev, bf40, f3af9004), /* typo, 8004? */
5959
5960/* To catch errors in encoding functions, the codes are all offset by
5961 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
5962 as 16-bit instructions. */
5963#define X(a,b,c) T_MNEM_##a
5964enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
5965#undef X
5966
5967#define X(a,b,c) 0x##b
5968static const unsigned short thumb_op16[] = { T16_32_TAB };
5969#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
5970#undef X
5971
5972#define X(a,b,c) 0x##c
5973static const unsigned int thumb_op32[] = { T16_32_TAB };
5974#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
5975#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
5976#undef X
5977#undef T16_32_TAB
5978
5979/* Thumb instruction encoders, in alphabetical order. */
5980
92e90b6e
PB
5981/* ADDW or SUBW. */
5982static void
5983do_t_add_sub_w (void)
5984{
5985 int Rd, Rn;
5986
5987 Rd = inst.operands[0].reg;
5988 Rn = inst.operands[1].reg;
5989
5990 constraint (Rd == 15, _("PC not allowed as destination"));
5991 inst.instruction |= (Rn << 16) | (Rd << 8);
5992 inst.reloc.type = BFD_RELOC_ARM_T32_IMM12;
5993}
5994
c19d1205
ZW
5995/* Parse an add or subtract instruction. We get here with inst.instruction
5996 equalling any of THUMB_OPCODE_add, adds, sub, or subs. */
5997
5998static void
5999do_t_add_sub (void)
6000{
6001 int Rd, Rs, Rn;
6002
6003 Rd = inst.operands[0].reg;
6004 Rs = (inst.operands[1].present
6005 ? inst.operands[1].reg /* Rd, Rs, foo */
6006 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
6007
6008 if (unified_syntax)
6009 {
0110f2b8
PB
6010 bfd_boolean flags;
6011 bfd_boolean narrow;
6012 int opcode;
6013
6014 flags = (inst.instruction == T_MNEM_adds
6015 || inst.instruction == T_MNEM_subs);
6016 if (flags)
6017 narrow = (current_it_mask == 0);
6018 else
6019 narrow = (current_it_mask != 0);
c19d1205 6020 if (!inst.operands[2].isreg)
b99bd4ef 6021 {
0110f2b8
PB
6022 opcode = 0;
6023 if (inst.size_req != 4)
6024 {
6025 int add;
6026
6027 add = (inst.instruction == T_MNEM_add
6028 || inst.instruction == T_MNEM_adds);
6029 /* Attempt to use a narrow opcode, with relaxation if
6030 appropriate. */
6031 if (Rd == REG_SP && Rs == REG_SP && !flags)
6032 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
6033 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
6034 opcode = T_MNEM_add_sp;
6035 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
6036 opcode = T_MNEM_add_pc;
6037 else if (Rd <= 7 && Rs <= 7 && narrow)
6038 {
6039 if (flags)
6040 opcode = add ? T_MNEM_addis : T_MNEM_subis;
6041 else
6042 opcode = add ? T_MNEM_addi : T_MNEM_subi;
6043 }
6044 if (opcode)
6045 {
6046 inst.instruction = THUMB_OP16(opcode);
6047 inst.instruction |= (Rd << 4) | Rs;
6048 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
6049 if (inst.size_req != 2)
6050 inst.relax = opcode;
6051 }
6052 else
6053 constraint (inst.size_req == 2, BAD_HIREG);
6054 }
6055 if (inst.size_req == 4
6056 || (inst.size_req != 2 && !opcode))
6057 {
6058 /* ??? Convert large immediates to addw/subw. */
6059 inst.instruction = THUMB_OP32 (inst.instruction);
6060 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
6061 inst.instruction |= inst.operands[0].reg << 8;
6062 inst.instruction |= inst.operands[1].reg << 16;
6063 inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
6064 }
b99bd4ef 6065 }
c19d1205
ZW
6066 else
6067 {
6068 Rn = inst.operands[2].reg;
6069 /* See if we can do this with a 16-bit instruction. */
6070 if (!inst.operands[2].shifted && inst.size_req != 4)
6071 {
e27ec89e
PB
6072 if (Rd > 7 || Rs > 7 || Rn > 7)
6073 narrow = FALSE;
6074
6075 if (narrow)
c19d1205 6076 {
e27ec89e
PB
6077 inst.instruction = ((inst.instruction == T_MNEM_adds
6078 || inst.instruction == T_MNEM_add)
c19d1205
ZW
6079 ? T_OPCODE_ADD_R3
6080 : T_OPCODE_SUB_R3);
6081 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
6082 return;
6083 }
b99bd4ef 6084
c19d1205
ZW
6085 if (inst.instruction == T_MNEM_add)
6086 {
6087 if (Rd == Rs)
6088 {
6089 inst.instruction = T_OPCODE_ADD_HI;
6090 inst.instruction |= (Rd & 8) << 4;
6091 inst.instruction |= (Rd & 7);
6092 inst.instruction |= Rn << 3;
6093 return;
6094 }
6095 /* ... because addition is commutative! */
6096 else if (Rd == Rn)
6097 {
6098 inst.instruction = T_OPCODE_ADD_HI;
6099 inst.instruction |= (Rd & 8) << 4;
6100 inst.instruction |= (Rd & 7);
6101 inst.instruction |= Rs << 3;
6102 return;
6103 }
6104 }
6105 }
6106 /* If we get here, it can't be done in 16 bits. */
6107 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
6108 _("shift must be constant"));
6109 inst.instruction = THUMB_OP32 (inst.instruction);
6110 inst.instruction |= Rd << 8;
6111 inst.instruction |= Rs << 16;
6112 encode_thumb32_shifted_operand (2);
6113 }
6114 }
6115 else
6116 {
6117 constraint (inst.instruction == T_MNEM_adds
6118 || inst.instruction == T_MNEM_subs,
6119 BAD_THUMB32);
b99bd4ef 6120
c19d1205 6121 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 6122 {
c19d1205
ZW
6123 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
6124 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
6125 BAD_HIREG);
6126
6127 inst.instruction = (inst.instruction == T_MNEM_add
6128 ? 0x0000 : 0x8000);
6129 inst.instruction |= (Rd << 4) | Rs;
6130 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
6131 return;
6132 }
6133
c19d1205
ZW
6134 Rn = inst.operands[2].reg;
6135 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 6136
c19d1205
ZW
6137 /* We now have Rd, Rs, and Rn set to registers. */
6138 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 6139 {
c19d1205
ZW
6140 /* Can't do this for SUB. */
6141 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
6142 inst.instruction = T_OPCODE_ADD_HI;
6143 inst.instruction |= (Rd & 8) << 4;
6144 inst.instruction |= (Rd & 7);
6145 if (Rs == Rd)
6146 inst.instruction |= Rn << 3;
6147 else if (Rn == Rd)
6148 inst.instruction |= Rs << 3;
6149 else
6150 constraint (1, _("dest must overlap one source register"));
6151 }
6152 else
6153 {
6154 inst.instruction = (inst.instruction == T_MNEM_add
6155 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
6156 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 6157 }
b99bd4ef 6158 }
b99bd4ef
NC
6159}
6160
c19d1205
ZW
6161static void
6162do_t_adr (void)
6163{
0110f2b8
PB
6164 if (unified_syntax && inst.size_req == 0 && inst.operands[0].reg <= 7)
6165 {
6166 /* Defer to section relaxation. */
6167 inst.relax = inst.instruction;
6168 inst.instruction = THUMB_OP16 (inst.instruction);
6169 inst.instruction |= inst.operands[0].reg << 4;
6170 }
6171 else if (unified_syntax && inst.size_req != 2)
e9f89963 6172 {
0110f2b8 6173 /* Generate a 32-bit opcode. */
e9f89963
PB
6174 inst.instruction = THUMB_OP32 (inst.instruction);
6175 inst.instruction |= inst.operands[0].reg << 8;
6176 inst.reloc.type = BFD_RELOC_ARM_T32_ADD_PC12;
6177 inst.reloc.pc_rel = 1;
6178 }
6179 else
6180 {
0110f2b8 6181 /* Generate a 16-bit opcode. */
e9f89963
PB
6182 inst.instruction = THUMB_OP16 (inst.instruction);
6183 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
6184 inst.reloc.exp.X_add_number -= 4; /* PC relative adjust. */
6185 inst.reloc.pc_rel = 1;
b99bd4ef 6186
e9f89963
PB
6187 inst.instruction |= inst.operands[0].reg << 4;
6188 }
c19d1205 6189}
b99bd4ef 6190
c19d1205
ZW
6191/* Arithmetic instructions for which there is just one 16-bit
6192 instruction encoding, and it allows only two low registers.
6193 For maximal compatibility with ARM syntax, we allow three register
6194 operands even when Thumb-32 instructions are not available, as long
6195 as the first two are identical. For instance, both "sbc r0,r1" and
6196 "sbc r0,r0,r1" are allowed. */
b99bd4ef 6197static void
c19d1205 6198do_t_arit3 (void)
b99bd4ef 6199{
c19d1205 6200 int Rd, Rs, Rn;
b99bd4ef 6201
c19d1205
ZW
6202 Rd = inst.operands[0].reg;
6203 Rs = (inst.operands[1].present
6204 ? inst.operands[1].reg /* Rd, Rs, foo */
6205 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
6206 Rn = inst.operands[2].reg;
b99bd4ef 6207
c19d1205 6208 if (unified_syntax)
b99bd4ef 6209 {
c19d1205
ZW
6210 if (!inst.operands[2].isreg)
6211 {
6212 /* For an immediate, we always generate a 32-bit opcode;
6213 section relaxation will shrink it later if possible. */
6214 inst.instruction = THUMB_OP32 (inst.instruction);
6215 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
6216 inst.instruction |= Rd << 8;
6217 inst.instruction |= Rs << 16;
6218 inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
6219 }
6220 else
6221 {
e27ec89e
PB
6222 bfd_boolean narrow;
6223
c19d1205 6224 /* See if we can do this with a 16-bit instruction. */
e27ec89e
PB
6225 if (THUMB_SETS_FLAGS (inst.instruction))
6226 narrow = current_it_mask == 0;
6227 else
6228 narrow = current_it_mask != 0;
6229
6230 if (Rd > 7 || Rn > 7 || Rs > 7)
6231 narrow = FALSE;
6232 if (inst.operands[2].shifted)
6233 narrow = FALSE;
6234 if (inst.size_req == 4)
6235 narrow = FALSE;
6236
6237 if (narrow
c19d1205
ZW
6238 && Rd == Rs)
6239 {
6240 inst.instruction = THUMB_OP16 (inst.instruction);
6241 inst.instruction |= Rd;
6242 inst.instruction |= Rn << 3;
6243 return;
6244 }
b99bd4ef 6245
c19d1205
ZW
6246 /* If we get here, it can't be done in 16 bits. */
6247 constraint (inst.operands[2].shifted
6248 && inst.operands[2].immisreg,
6249 _("shift must be constant"));
6250 inst.instruction = THUMB_OP32 (inst.instruction);
6251 inst.instruction |= Rd << 8;
6252 inst.instruction |= Rs << 16;
6253 encode_thumb32_shifted_operand (2);
6254 }
a737bd4d 6255 }
c19d1205 6256 else
b99bd4ef 6257 {
c19d1205
ZW
6258 /* On its face this is a lie - the instruction does set the
6259 flags. However, the only supported mnemonic in this mode
6260 says it doesn't. */
6261 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 6262
c19d1205
ZW
6263 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
6264 _("unshifted register required"));
6265 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
6266 constraint (Rd != Rs,
6267 _("dest and source1 must be the same register"));
a737bd4d 6268
c19d1205
ZW
6269 inst.instruction = THUMB_OP16 (inst.instruction);
6270 inst.instruction |= Rd;
6271 inst.instruction |= Rn << 3;
b99bd4ef 6272 }
a737bd4d 6273}
b99bd4ef 6274
c19d1205
ZW
6275/* Similarly, but for instructions where the arithmetic operation is
6276 commutative, so we can allow either of them to be different from
6277 the destination operand in a 16-bit instruction. For instance, all
6278 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
6279 accepted. */
6280static void
6281do_t_arit3c (void)
a737bd4d 6282{
c19d1205 6283 int Rd, Rs, Rn;
b99bd4ef 6284
c19d1205
ZW
6285 Rd = inst.operands[0].reg;
6286 Rs = (inst.operands[1].present
6287 ? inst.operands[1].reg /* Rd, Rs, foo */
6288 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
6289 Rn = inst.operands[2].reg;
a737bd4d 6290
c19d1205 6291 if (unified_syntax)
a737bd4d 6292 {
c19d1205 6293 if (!inst.operands[2].isreg)
b99bd4ef 6294 {
c19d1205
ZW
6295 /* For an immediate, we always generate a 32-bit opcode;
6296 section relaxation will shrink it later if possible. */
6297 inst.instruction = THUMB_OP32 (inst.instruction);
6298 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
6299 inst.instruction |= Rd << 8;
6300 inst.instruction |= Rs << 16;
6301 inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 6302 }
c19d1205 6303 else
a737bd4d 6304 {
e27ec89e
PB
6305 bfd_boolean narrow;
6306
c19d1205 6307 /* See if we can do this with a 16-bit instruction. */
e27ec89e
PB
6308 if (THUMB_SETS_FLAGS (inst.instruction))
6309 narrow = current_it_mask == 0;
6310 else
6311 narrow = current_it_mask != 0;
6312
6313 if (Rd > 7 || Rn > 7 || Rs > 7)
6314 narrow = FALSE;
6315 if (inst.operands[2].shifted)
6316 narrow = FALSE;
6317 if (inst.size_req == 4)
6318 narrow = FALSE;
6319
6320 if (narrow)
a737bd4d 6321 {
c19d1205 6322 if (Rd == Rs)
a737bd4d 6323 {
c19d1205
ZW
6324 inst.instruction = THUMB_OP16 (inst.instruction);
6325 inst.instruction |= Rd;
6326 inst.instruction |= Rn << 3;
6327 return;
a737bd4d 6328 }
c19d1205 6329 if (Rd == Rn)
a737bd4d 6330 {
c19d1205
ZW
6331 inst.instruction = THUMB_OP16 (inst.instruction);
6332 inst.instruction |= Rd;
6333 inst.instruction |= Rs << 3;
6334 return;
a737bd4d
NC
6335 }
6336 }
c19d1205
ZW
6337
6338 /* If we get here, it can't be done in 16 bits. */
6339 constraint (inst.operands[2].shifted
6340 && inst.operands[2].immisreg,
6341 _("shift must be constant"));
6342 inst.instruction = THUMB_OP32 (inst.instruction);
6343 inst.instruction |= Rd << 8;
6344 inst.instruction |= Rs << 16;
6345 encode_thumb32_shifted_operand (2);
a737bd4d 6346 }
b99bd4ef 6347 }
c19d1205
ZW
6348 else
6349 {
6350 /* On its face this is a lie - the instruction does set the
6351 flags. However, the only supported mnemonic in this mode
6352 says it doesn't. */
6353 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 6354
c19d1205
ZW
6355 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
6356 _("unshifted register required"));
6357 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
6358
6359 inst.instruction = THUMB_OP16 (inst.instruction);
6360 inst.instruction |= Rd;
6361
6362 if (Rd == Rs)
6363 inst.instruction |= Rn << 3;
6364 else if (Rd == Rn)
6365 inst.instruction |= Rs << 3;
6366 else
6367 constraint (1, _("dest must overlap one source register"));
6368 }
a737bd4d
NC
6369}
6370
c19d1205
ZW
6371static void
6372do_t_bfc (void)
a737bd4d 6373{
c19d1205
ZW
6374 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
6375 constraint (msb > 32, _("bit-field extends past end of register"));
6376 /* The instruction encoding stores the LSB and MSB,
6377 not the LSB and width. */
6378 inst.instruction |= inst.operands[0].reg << 8;
6379 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
6380 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
6381 inst.instruction |= msb - 1;
b99bd4ef
NC
6382}
6383
c19d1205
ZW
6384static void
6385do_t_bfi (void)
b99bd4ef 6386{
c19d1205 6387 unsigned int msb;
b99bd4ef 6388
c19d1205
ZW
6389 /* #0 in second position is alternative syntax for bfc, which is
6390 the same instruction but with REG_PC in the Rm field. */
6391 if (!inst.operands[1].isreg)
6392 inst.operands[1].reg = REG_PC;
b99bd4ef 6393
c19d1205
ZW
6394 msb = inst.operands[2].imm + inst.operands[3].imm;
6395 constraint (msb > 32, _("bit-field extends past end of register"));
6396 /* The instruction encoding stores the LSB and MSB,
6397 not the LSB and width. */
6398 inst.instruction |= inst.operands[0].reg << 8;
6399 inst.instruction |= inst.operands[1].reg << 16;
6400 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
6401 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
6402 inst.instruction |= msb - 1;
b99bd4ef
NC
6403}
6404
c19d1205
ZW
6405static void
6406do_t_bfx (void)
b99bd4ef 6407{
c19d1205
ZW
6408 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
6409 _("bit-field extends past end of register"));
6410 inst.instruction |= inst.operands[0].reg << 8;
6411 inst.instruction |= inst.operands[1].reg << 16;
6412 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
6413 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
6414 inst.instruction |= inst.operands[3].imm - 1;
6415}
b99bd4ef 6416
c19d1205
ZW
6417/* ARM V5 Thumb BLX (argument parse)
6418 BLX <target_addr> which is BLX(1)
6419 BLX <Rm> which is BLX(2)
6420 Unfortunately, there are two different opcodes for this mnemonic.
6421 So, the insns[].value is not used, and the code here zaps values
6422 into inst.instruction.
b99bd4ef 6423
c19d1205
ZW
6424 ??? How to take advantage of the additional two bits of displacement
6425 available in Thumb32 mode? Need new relocation? */
b99bd4ef 6426
c19d1205
ZW
6427static void
6428do_t_blx (void)
6429{
6430 if (inst.operands[0].isreg)
6431 /* We have a register, so this is BLX(2). */
6432 inst.instruction |= inst.operands[0].reg << 3;
b99bd4ef
NC
6433 else
6434 {
c19d1205 6435 /* No register. This must be BLX(1). */
2fc8bdac 6436 inst.instruction = 0xf000e800;
c19d1205
ZW
6437 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
6438 inst.reloc.pc_rel = 1;
b99bd4ef
NC
6439 }
6440}
6441
c19d1205
ZW
6442static void
6443do_t_branch (void)
b99bd4ef 6444{
0110f2b8
PB
6445 int opcode;
6446 if (inst.cond != COND_ALWAYS)
6447 opcode = T_MNEM_bcond;
6448 else
6449 opcode = inst.instruction;
6450
6451 if (unified_syntax && inst.size_req == 4)
c19d1205 6452 {
0110f2b8 6453 inst.instruction = THUMB_OP32(opcode);
c19d1205 6454 if (inst.cond == COND_ALWAYS)
0110f2b8 6455 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
6456 else
6457 {
6458 assert (inst.cond != 0xF);
0110f2b8 6459 inst.instruction |= inst.cond << 22;
c19d1205
ZW
6460 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH20;
6461 }
6462 }
b99bd4ef
NC
6463 else
6464 {
0110f2b8 6465 inst.instruction = THUMB_OP16(opcode);
c19d1205
ZW
6466 if (inst.cond == COND_ALWAYS)
6467 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH12;
6468 else
b99bd4ef 6469 {
0110f2b8 6470 inst.instruction |= inst.cond << 8;
c19d1205 6471 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 6472 }
0110f2b8
PB
6473 /* Allow section relaxation. */
6474 if (unified_syntax && inst.size_req != 2)
6475 inst.relax = opcode;
b99bd4ef 6476 }
c19d1205
ZW
6477
6478 inst.reloc.pc_rel = 1;
b99bd4ef
NC
6479}
6480
6481static void
c19d1205 6482do_t_bkpt (void)
b99bd4ef 6483{
c19d1205 6484 if (inst.operands[0].present)
b99bd4ef 6485 {
c19d1205
ZW
6486 constraint (inst.operands[0].imm > 255,
6487 _("immediate value out of range"));
6488 inst.instruction |= inst.operands[0].imm;
b99bd4ef 6489 }
b99bd4ef
NC
6490}
6491
6492static void
c19d1205 6493do_t_branch23 (void)
b99bd4ef 6494{
c19d1205 6495 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a
RE
6496 inst.reloc.pc_rel = 1;
6497
c19d1205
ZW
6498 /* If the destination of the branch is a defined symbol which does not have
6499 the THUMB_FUNC attribute, then we must be calling a function which has
6500 the (interfacearm) attribute. We look for the Thumb entry point to that
6501 function and change the branch to refer to that function instead. */
6502 if ( inst.reloc.exp.X_op == O_symbol
6503 && inst.reloc.exp.X_add_symbol != NULL
6504 && S_IS_DEFINED (inst.reloc.exp.X_add_symbol)
6505 && ! THUMB_IS_FUNC (inst.reloc.exp.X_add_symbol))
6506 inst.reloc.exp.X_add_symbol =
6507 find_real_start (inst.reloc.exp.X_add_symbol);
90e4755a
RE
6508}
6509
6510static void
c19d1205 6511do_t_bx (void)
90e4755a 6512{
c19d1205
ZW
6513 inst.instruction |= inst.operands[0].reg << 3;
6514 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
6515 should cause the alignment to be checked once it is known. This is
6516 because BX PC only works if the instruction is word aligned. */
6517}
90e4755a 6518
c19d1205
ZW
6519static void
6520do_t_bxj (void)
6521{
6522 if (inst.operands[0].reg == REG_PC)
6523 as_tsktsk (_("use of r15 in bxj is not really useful"));
90e4755a 6524
c19d1205 6525 inst.instruction |= inst.operands[0].reg << 16;
90e4755a
RE
6526}
6527
6528static void
c19d1205 6529do_t_clz (void)
90e4755a 6530{
c19d1205
ZW
6531 inst.instruction |= inst.operands[0].reg << 8;
6532 inst.instruction |= inst.operands[1].reg << 16;
6533 inst.instruction |= inst.operands[1].reg;
6534}
90e4755a 6535
c19d1205
ZW
6536static void
6537do_t_cpsi (void)
6538{
6539 if (unified_syntax
6540 && (inst.operands[1].present || inst.size_req == 4))
90e4755a 6541 {
c19d1205
ZW
6542 unsigned int imod = (inst.instruction & 0x0030) >> 4;
6543 inst.instruction = 0xf3af8000;
6544 inst.instruction |= imod << 9;
6545 inst.instruction |= inst.operands[0].imm << 5;
6546 if (inst.operands[1].present)
6547 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 6548 }
c19d1205 6549 else
90e4755a 6550 {
c19d1205
ZW
6551 constraint (inst.operands[1].present,
6552 _("Thumb does not support the 2-argument "
6553 "form of this instruction"));
6554 inst.instruction |= inst.operands[0].imm;
90e4755a 6555 }
90e4755a
RE
6556}
6557
c19d1205
ZW
6558/* THUMB CPY instruction (argument parse). */
6559
90e4755a 6560static void
c19d1205 6561do_t_cpy (void)
90e4755a 6562{
c19d1205 6563 if (inst.size_req == 4)
90e4755a 6564 {
c19d1205
ZW
6565 inst.instruction = THUMB_OP32 (T_MNEM_mov);
6566 inst.instruction |= inst.operands[0].reg << 8;
6567 inst.instruction |= inst.operands[1].reg;
90e4755a 6568 }
c19d1205 6569 else
90e4755a 6570 {
c19d1205
ZW
6571 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
6572 inst.instruction |= (inst.operands[0].reg & 0x7);
6573 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 6574 }
90e4755a
RE
6575}
6576
90e4755a 6577static void
c19d1205 6578do_t_czb (void)
90e4755a 6579{
c19d1205
ZW
6580 constraint (inst.operands[0].reg > 7, BAD_HIREG);
6581 inst.instruction |= inst.operands[0].reg;
6582 inst.reloc.pc_rel = 1;
6583 inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH7;
6584}
90e4755a 6585
c19d1205
ZW
6586static void
6587do_t_hint (void)
6588{
6589 if (unified_syntax && inst.size_req == 4)
6590 inst.instruction = THUMB_OP32 (inst.instruction);
6591 else
6592 inst.instruction = THUMB_OP16 (inst.instruction);
6593}
90e4755a 6594
c19d1205
ZW
6595static void
6596do_t_it (void)
6597{
6598 unsigned int cond = inst.operands[0].imm;
e27ec89e
PB
6599
6600 current_it_mask = (inst.instruction & 0xf) | 0x10;
6601 current_cc = cond;
6602
6603 /* If the condition is a negative condition, invert the mask. */
c19d1205 6604 if ((cond & 0x1) == 0x0)
90e4755a 6605 {
c19d1205 6606 unsigned int mask = inst.instruction & 0x000f;
90e4755a 6607
c19d1205
ZW
6608 if ((mask & 0x7) == 0)
6609 /* no conversion needed */;
6610 else if ((mask & 0x3) == 0)
e27ec89e
PB
6611 mask ^= 0x8;
6612 else if ((mask & 0x1) == 0)
6613 mask ^= 0xC;
c19d1205 6614 else
e27ec89e 6615 mask ^= 0xE;
90e4755a 6616
e27ec89e
PB
6617 inst.instruction &= 0xfff0;
6618 inst.instruction |= mask;
c19d1205 6619 }
90e4755a 6620
c19d1205
ZW
6621 inst.instruction |= cond << 4;
6622}
90e4755a 6623
c19d1205
ZW
6624static void
6625do_t_ldmstm (void)
6626{
6627 /* This really doesn't seem worth it. */
6628 constraint (inst.reloc.type != BFD_RELOC_UNUSED,
6629 _("expression too complex"));
6630 constraint (inst.operands[1].writeback,
6631 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 6632
c19d1205
ZW
6633 if (unified_syntax)
6634 {
6635 /* See if we can use a 16-bit instruction. */
6636 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
6637 && inst.size_req != 4
6638 && inst.operands[0].reg <= 7
6639 && !(inst.operands[1].imm & ~0xff)
6640 && (inst.instruction == T_MNEM_stmia
6641 ? inst.operands[0].writeback
6642 : (inst.operands[0].writeback
6643 == !(inst.operands[1].imm & (1 << inst.operands[0].reg)))))
90e4755a 6644 {
c19d1205
ZW
6645 if (inst.instruction == T_MNEM_stmia
6646 && (inst.operands[1].imm & (1 << inst.operands[0].reg))
6647 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
6648 as_warn (_("value stored for r%d is UNPREDICTABLE"),
6649 inst.operands[0].reg);
90e4755a 6650
c19d1205
ZW
6651 inst.instruction = THUMB_OP16 (inst.instruction);
6652 inst.instruction |= inst.operands[0].reg << 8;
6653 inst.instruction |= inst.operands[1].imm;
6654 }
6655 else
6656 {
6657 if (inst.operands[1].imm & (1 << 13))
6658 as_warn (_("SP should not be in register list"));
6659 if (inst.instruction == T_MNEM_stmia)
90e4755a 6660 {
c19d1205
ZW
6661 if (inst.operands[1].imm & (1 << 15))
6662 as_warn (_("PC should not be in register list"));
6663 if (inst.operands[1].imm & (1 << inst.operands[0].reg))
6664 as_warn (_("value stored for r%d is UNPREDICTABLE"),
6665 inst.operands[0].reg);
90e4755a
RE
6666 }
6667 else
6668 {
c19d1205
ZW
6669 if (inst.operands[1].imm & (1 << 14)
6670 && inst.operands[1].imm & (1 << 15))
6671 as_warn (_("LR and PC should not both be in register list"));
6672 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
6673 && inst.operands[0].writeback)
6674 as_warn (_("base register should not be in register list "
6675 "when written back"));
90e4755a 6676 }
c19d1205
ZW
6677 if (inst.instruction < 0xffff)
6678 inst.instruction = THUMB_OP32 (inst.instruction);
6679 inst.instruction |= inst.operands[0].reg << 16;
6680 inst.instruction |= inst.operands[1].imm;
6681 if (inst.operands[0].writeback)
6682 inst.instruction |= WRITE_BACK;
90e4755a
RE
6683 }
6684 }
c19d1205 6685 else
90e4755a 6686 {
c19d1205
ZW
6687 constraint (inst.operands[0].reg > 7
6688 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
6689 if (inst.instruction == T_MNEM_stmia)
f03698e6 6690 {
c19d1205
ZW
6691 if (!inst.operands[0].writeback)
6692 as_warn (_("this instruction will write back the base register"));
6693 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
6694 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
6695 as_warn (_("value stored for r%d is UNPREDICTABLE"),
6696 inst.operands[0].reg);
f03698e6 6697 }
c19d1205 6698 else
90e4755a 6699 {
c19d1205
ZW
6700 if (!inst.operands[0].writeback
6701 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
6702 as_warn (_("this instruction will write back the base register"));
6703 else if (inst.operands[0].writeback
6704 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
6705 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
6706 }
6707
c19d1205
ZW
6708 inst.instruction = THUMB_OP16 (inst.instruction);
6709 inst.instruction |= inst.operands[0].reg << 8;
6710 inst.instruction |= inst.operands[1].imm;
6711 }
6712}
e28cd48c 6713
c19d1205
ZW
6714static void
6715do_t_ldrex (void)
6716{
6717 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
6718 || inst.operands[1].postind || inst.operands[1].writeback
6719 || inst.operands[1].immisreg || inst.operands[1].shifted
6720 || inst.operands[1].negative,
01cfc07f 6721 BAD_ADDR_MODE);
e28cd48c 6722
c19d1205
ZW
6723 inst.instruction |= inst.operands[0].reg << 12;
6724 inst.instruction |= inst.operands[1].reg << 16;
6725 inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_U8;
6726}
e28cd48c 6727
c19d1205
ZW
6728static void
6729do_t_ldrexd (void)
6730{
6731 if (!inst.operands[1].present)
1cac9012 6732 {
c19d1205
ZW
6733 constraint (inst.operands[0].reg == REG_LR,
6734 _("r14 not allowed as first register "
6735 "when second register is omitted"));
6736 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 6737 }
c19d1205
ZW
6738 constraint (inst.operands[0].reg == inst.operands[1].reg,
6739 BAD_OVERLAP);
b99bd4ef 6740
c19d1205
ZW
6741 inst.instruction |= inst.operands[0].reg << 12;
6742 inst.instruction |= inst.operands[1].reg << 8;
6743 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
6744}
6745
6746static void
c19d1205 6747do_t_ldst (void)
b99bd4ef 6748{
0110f2b8
PB
6749 unsigned long opcode;
6750 int Rn;
6751
6752 opcode = inst.instruction;
c19d1205 6753 if (unified_syntax)
b99bd4ef 6754 {
0110f2b8
PB
6755 if (inst.operands[1].isreg
6756 && !inst.operands[1].writeback
c19d1205
ZW
6757 && !inst.operands[1].shifted && !inst.operands[1].postind
6758 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
6759 && opcode <= 0xffff
6760 && inst.size_req != 4)
c19d1205 6761 {
0110f2b8
PB
6762 /* Insn may have a 16-bit form. */
6763 Rn = inst.operands[1].reg;
6764 if (inst.operands[1].immisreg)
6765 {
6766 inst.instruction = THUMB_OP16 (opcode);
6767 /* [Rn, Ri] */
6768 if (Rn <= 7 && inst.operands[1].imm <= 7)
6769 goto op16;
6770 }
6771 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
6772 && opcode != T_MNEM_ldrsb)
6773 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
6774 || (Rn == REG_SP && opcode == T_MNEM_str))
6775 {
6776 /* [Rn, #const] */
6777 if (Rn > 7)
6778 {
6779 if (Rn == REG_PC)
6780 {
6781 if (inst.reloc.pc_rel)
6782 opcode = T_MNEM_ldr_pc2;
6783 else
6784 opcode = T_MNEM_ldr_pc;
6785 }
6786 else
6787 {
6788 if (opcode == T_MNEM_ldr)
6789 opcode = T_MNEM_ldr_sp;
6790 else
6791 opcode = T_MNEM_str_sp;
6792 }
6793 inst.instruction = inst.operands[0].reg << 8;
6794 }
6795 else
6796 {
6797 inst.instruction = inst.operands[0].reg;
6798 inst.instruction |= inst.operands[1].reg << 3;
6799 }
6800 inst.instruction |= THUMB_OP16 (opcode);
6801 if (inst.size_req == 2)
6802 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
6803 else
6804 inst.relax = opcode;
6805 return;
6806 }
c19d1205 6807 }
0110f2b8
PB
6808 /* Definitely a 32-bit variant. */
6809 inst.instruction = THUMB_OP32 (opcode);
c19d1205
ZW
6810 inst.instruction |= inst.operands[0].reg << 12;
6811 encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
b99bd4ef
NC
6812 return;
6813 }
6814
c19d1205
ZW
6815 constraint (inst.operands[0].reg > 7, BAD_HIREG);
6816
6817 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 6818 {
c19d1205
ZW
6819 /* Only [Rn,Rm] is acceptable. */
6820 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
6821 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
6822 || inst.operands[1].postind || inst.operands[1].shifted
6823 || inst.operands[1].negative,
6824 _("Thumb does not support this addressing mode"));
6825 inst.instruction = THUMB_OP16 (inst.instruction);
6826 goto op16;
b99bd4ef 6827 }
c19d1205
ZW
6828
6829 inst.instruction = THUMB_OP16 (inst.instruction);
6830 if (!inst.operands[1].isreg)
6831 if (move_or_literal_pool (0, /*thumb_p=*/TRUE, /*mode_3=*/FALSE))
6832 return;
b99bd4ef 6833
c19d1205
ZW
6834 constraint (!inst.operands[1].preind
6835 || inst.operands[1].shifted
6836 || inst.operands[1].writeback,
6837 _("Thumb does not support this addressing mode"));
6838 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 6839 {
c19d1205
ZW
6840 constraint (inst.instruction & 0x0600,
6841 _("byte or halfword not valid for base register"));
6842 constraint (inst.operands[1].reg == REG_PC
6843 && !(inst.instruction & THUMB_LOAD_BIT),
6844 _("r15 based store not allowed"));
6845 constraint (inst.operands[1].immisreg,
6846 _("invalid base register for register offset"));
b99bd4ef 6847
c19d1205
ZW
6848 if (inst.operands[1].reg == REG_PC)
6849 inst.instruction = T_OPCODE_LDR_PC;
6850 else if (inst.instruction & THUMB_LOAD_BIT)
6851 inst.instruction = T_OPCODE_LDR_SP;
6852 else
6853 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 6854
c19d1205
ZW
6855 inst.instruction |= inst.operands[0].reg << 8;
6856 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
6857 return;
6858 }
90e4755a 6859
c19d1205
ZW
6860 constraint (inst.operands[1].reg > 7, BAD_HIREG);
6861 if (!inst.operands[1].immisreg)
6862 {
6863 /* Immediate offset. */
6864 inst.instruction |= inst.operands[0].reg;
6865 inst.instruction |= inst.operands[1].reg << 3;
6866 inst.reloc.type = BFD_RELOC_ARM_THUMB_OFFSET;
6867 return;
6868 }
90e4755a 6869
c19d1205
ZW
6870 /* Register offset. */
6871 constraint (inst.operands[1].imm > 7, BAD_HIREG);
6872 constraint (inst.operands[1].negative,
6873 _("Thumb does not support this addressing mode"));
90e4755a 6874
c19d1205
ZW
6875 op16:
6876 switch (inst.instruction)
6877 {
6878 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
6879 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
6880 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
6881 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
6882 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
6883 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
6884 case 0x5600 /* ldrsb */:
6885 case 0x5e00 /* ldrsh */: break;
6886 default: abort ();
6887 }
90e4755a 6888
c19d1205
ZW
6889 inst.instruction |= inst.operands[0].reg;
6890 inst.instruction |= inst.operands[1].reg << 3;
6891 inst.instruction |= inst.operands[1].imm << 6;
6892}
90e4755a 6893
c19d1205
ZW
6894static void
6895do_t_ldstd (void)
6896{
6897 if (!inst.operands[1].present)
b99bd4ef 6898 {
c19d1205
ZW
6899 inst.operands[1].reg = inst.operands[0].reg + 1;
6900 constraint (inst.operands[0].reg == REG_LR,
6901 _("r14 not allowed here"));
b99bd4ef 6902 }
c19d1205
ZW
6903 inst.instruction |= inst.operands[0].reg << 12;
6904 inst.instruction |= inst.operands[1].reg << 8;
6905 encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
6906
b99bd4ef
NC
6907}
6908
c19d1205
ZW
6909static void
6910do_t_ldstt (void)
6911{
6912 inst.instruction |= inst.operands[0].reg << 12;
6913 encode_thumb32_addr_mode (1, /*is_t=*/TRUE, /*is_d=*/FALSE);
6914}
a737bd4d 6915
b99bd4ef 6916static void
c19d1205 6917do_t_mla (void)
b99bd4ef 6918{
c19d1205
ZW
6919 inst.instruction |= inst.operands[0].reg << 8;
6920 inst.instruction |= inst.operands[1].reg << 16;
6921 inst.instruction |= inst.operands[2].reg;
6922 inst.instruction |= inst.operands[3].reg << 12;
6923}
b99bd4ef 6924
c19d1205
ZW
6925static void
6926do_t_mlal (void)
6927{
6928 inst.instruction |= inst.operands[0].reg << 12;
6929 inst.instruction |= inst.operands[1].reg << 8;
6930 inst.instruction |= inst.operands[2].reg << 16;
6931 inst.instruction |= inst.operands[3].reg;
6932}
b99bd4ef 6933
c19d1205
ZW
6934static void
6935do_t_mov_cmp (void)
6936{
6937 if (unified_syntax)
b99bd4ef 6938 {
c19d1205
ZW
6939 int r0off = (inst.instruction == T_MNEM_mov
6940 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 6941 unsigned long opcode;
3d388997
PB
6942 bfd_boolean narrow;
6943 bfd_boolean low_regs;
6944
6945 low_regs = (inst.operands[0].reg <= 7 && inst.operands[1].reg <= 7);
0110f2b8 6946 opcode = inst.instruction;
3d388997 6947 if (current_it_mask)
0110f2b8 6948 narrow = opcode != T_MNEM_movs;
3d388997 6949 else
0110f2b8 6950 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
6951 if (inst.size_req == 4
6952 || inst.operands[1].shifted)
6953 narrow = FALSE;
6954
c19d1205
ZW
6955 if (!inst.operands[1].isreg)
6956 {
0110f2b8
PB
6957 /* Immediate operand. */
6958 if (current_it_mask == 0 && opcode == T_MNEM_mov)
6959 narrow = 0;
6960 if (low_regs && narrow)
6961 {
6962 inst.instruction = THUMB_OP16 (opcode);
6963 inst.instruction |= inst.operands[0].reg << 8;
6964 if (inst.size_req == 2)
6965 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
6966 else
6967 inst.relax = opcode;
6968 }
6969 else
6970 {
6971 inst.instruction = THUMB_OP32 (inst.instruction);
6972 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
6973 inst.instruction |= inst.operands[0].reg << r0off;
6974 inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
6975 }
c19d1205 6976 }
3d388997 6977 else if (!narrow)
c19d1205
ZW
6978 {
6979 inst.instruction = THUMB_OP32 (inst.instruction);
6980 inst.instruction |= inst.operands[0].reg << r0off;
6981 encode_thumb32_shifted_operand (1);
6982 }
6983 else
6984 switch (inst.instruction)
6985 {
6986 case T_MNEM_mov:
6987 inst.instruction = T_OPCODE_MOV_HR;
6988 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
6989 inst.instruction |= (inst.operands[0].reg & 0x7);
6990 inst.instruction |= inst.operands[1].reg << 3;
6991 break;
b99bd4ef 6992
c19d1205
ZW
6993 case T_MNEM_movs:
6994 /* We know we have low registers at this point.
6995 Generate ADD Rd, Rs, #0. */
6996 inst.instruction = T_OPCODE_ADD_I3;
6997 inst.instruction |= inst.operands[0].reg;
6998 inst.instruction |= inst.operands[1].reg << 3;
6999 break;
7000
7001 case T_MNEM_cmp:
3d388997 7002 if (low_regs)
c19d1205
ZW
7003 {
7004 inst.instruction = T_OPCODE_CMP_LR;
7005 inst.instruction |= inst.operands[0].reg;
7006 inst.instruction |= inst.operands[1].reg << 3;
7007 }
7008 else
7009 {
7010 inst.instruction = T_OPCODE_CMP_HR;
7011 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
7012 inst.instruction |= (inst.operands[0].reg & 0x7);
7013 inst.instruction |= inst.operands[1].reg << 3;
7014 }
7015 break;
7016 }
b99bd4ef
NC
7017 return;
7018 }
7019
c19d1205
ZW
7020 inst.instruction = THUMB_OP16 (inst.instruction);
7021 if (inst.operands[1].isreg)
b99bd4ef 7022 {
c19d1205 7023 if (inst.operands[0].reg < 8 && inst.operands[1].reg < 8)
b99bd4ef 7024 {
c19d1205
ZW
7025 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
7026 since a MOV instruction produces unpredictable results. */
7027 if (inst.instruction == T_OPCODE_MOV_I8)
7028 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 7029 else
c19d1205 7030 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 7031
c19d1205
ZW
7032 inst.instruction |= inst.operands[0].reg;
7033 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
7034 }
7035 else
7036 {
c19d1205
ZW
7037 if (inst.instruction == T_OPCODE_MOV_I8)
7038 inst.instruction = T_OPCODE_MOV_HR;
7039 else
7040 inst.instruction = T_OPCODE_CMP_HR;
7041 do_t_cpy ();
b99bd4ef
NC
7042 }
7043 }
c19d1205 7044 else
b99bd4ef 7045 {
c19d1205
ZW
7046 constraint (inst.operands[0].reg > 7,
7047 _("only lo regs allowed with immediate"));
7048 inst.instruction |= inst.operands[0].reg << 8;
7049 inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
7050 }
7051}
b99bd4ef 7052
c19d1205
ZW
7053static void
7054do_t_mov16 (void)
7055{
7056 inst.instruction |= inst.operands[0].reg << 8;
7057 inst.instruction |= (inst.operands[1].imm & 0xf000) << 4;
7058 inst.instruction |= (inst.operands[1].imm & 0x0800) << 15;
7059 inst.instruction |= (inst.operands[1].imm & 0x0700) << 4;
7060 inst.instruction |= (inst.operands[1].imm & 0x00ff);
7061}
b99bd4ef 7062
c19d1205
ZW
7063static void
7064do_t_mvn_tst (void)
7065{
7066 if (unified_syntax)
7067 {
7068 int r0off = (inst.instruction == T_MNEM_mvn
7069 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
3d388997
PB
7070 bfd_boolean narrow;
7071
7072 if (inst.size_req == 4
7073 || inst.instruction > 0xffff
7074 || inst.operands[1].shifted
7075 || inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
7076 narrow = FALSE;
7077 else if (inst.instruction == T_MNEM_cmn)
7078 narrow = TRUE;
7079 else if (THUMB_SETS_FLAGS (inst.instruction))
7080 narrow = (current_it_mask == 0);
7081 else
7082 narrow = (current_it_mask != 0);
7083
c19d1205 7084 if (!inst.operands[1].isreg)
b99bd4ef 7085 {
c19d1205
ZW
7086 /* For an immediate, we always generate a 32-bit opcode;
7087 section relaxation will shrink it later if possible. */
7088 if (inst.instruction < 0xffff)
7089 inst.instruction = THUMB_OP32 (inst.instruction);
7090 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
7091 inst.instruction |= inst.operands[0].reg << r0off;
7092 inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 7093 }
c19d1205 7094 else
b99bd4ef 7095 {
c19d1205 7096 /* See if we can do this with a 16-bit instruction. */
3d388997 7097 if (narrow)
b99bd4ef 7098 {
c19d1205
ZW
7099 inst.instruction = THUMB_OP16 (inst.instruction);
7100 inst.instruction |= inst.operands[0].reg;
7101 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef 7102 }
c19d1205 7103 else
b99bd4ef 7104 {
c19d1205
ZW
7105 constraint (inst.operands[1].shifted
7106 && inst.operands[1].immisreg,
7107 _("shift must be constant"));
7108 if (inst.instruction < 0xffff)
7109 inst.instruction = THUMB_OP32 (inst.instruction);
7110 inst.instruction |= inst.operands[0].reg << r0off;
7111 encode_thumb32_shifted_operand (1);
b99bd4ef 7112 }
b99bd4ef
NC
7113 }
7114 }
7115 else
7116 {
c19d1205
ZW
7117 constraint (inst.instruction > 0xffff
7118 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
7119 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
7120 _("unshifted register required"));
7121 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
7122 BAD_HIREG);
b99bd4ef 7123
c19d1205
ZW
7124 inst.instruction = THUMB_OP16 (inst.instruction);
7125 inst.instruction |= inst.operands[0].reg;
7126 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef 7127 }
b99bd4ef
NC
7128}
7129
b05fe5cf 7130static void
c19d1205 7131do_t_mrs (void)
b05fe5cf 7132{
c19d1205
ZW
7133 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
7134 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
7135 != (PSR_c|PSR_f),
7136 _("'CPSR' or 'SPSR' expected"));
7137 inst.instruction |= inst.operands[0].reg << 8;
7138 inst.instruction |= (inst.operands[1].imm & SPSR_BIT) >> 2;
7139}
b05fe5cf 7140
c19d1205
ZW
7141static void
7142do_t_msr (void)
7143{
7144 constraint (!inst.operands[1].isreg,
7145 _("Thumb encoding does not support an immediate here"));
7146 inst.instruction |= (inst.operands[0].imm & SPSR_BIT) >> 2;
7147 inst.instruction |= (inst.operands[0].imm & ~SPSR_BIT) >> 8;
7148 inst.instruction |= inst.operands[1].reg << 16;
7149}
b05fe5cf 7150
c19d1205
ZW
7151static void
7152do_t_mul (void)
7153{
7154 if (!inst.operands[2].present)
7155 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 7156
c19d1205
ZW
7157 /* There is no 32-bit MULS and no 16-bit MUL. */
7158 if (unified_syntax && inst.instruction == T_MNEM_mul)
b05fe5cf 7159 {
c19d1205
ZW
7160 inst.instruction = THUMB_OP32 (inst.instruction);
7161 inst.instruction |= inst.operands[0].reg << 8;
7162 inst.instruction |= inst.operands[1].reg << 16;
7163 inst.instruction |= inst.operands[2].reg << 0;
b05fe5cf 7164 }
c19d1205 7165 else
b05fe5cf 7166 {
c19d1205
ZW
7167 constraint (!unified_syntax
7168 && inst.instruction == T_MNEM_muls, BAD_THUMB32);
7169 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
7170 BAD_HIREG);
b05fe5cf 7171
c19d1205
ZW
7172 inst.instruction = THUMB_OP16 (inst.instruction);
7173 inst.instruction |= inst.operands[0].reg;
b05fe5cf 7174
c19d1205
ZW
7175 if (inst.operands[0].reg == inst.operands[1].reg)
7176 inst.instruction |= inst.operands[2].reg << 3;
7177 else if (inst.operands[0].reg == inst.operands[2].reg)
7178 inst.instruction |= inst.operands[1].reg << 3;
7179 else
7180 constraint (1, _("dest must overlap one source register"));
7181 }
7182}
b05fe5cf 7183
c19d1205
ZW
7184static void
7185do_t_mull (void)
7186{
7187 inst.instruction |= inst.operands[0].reg << 12;
7188 inst.instruction |= inst.operands[1].reg << 8;
7189 inst.instruction |= inst.operands[2].reg << 16;
7190 inst.instruction |= inst.operands[3].reg;
b05fe5cf 7191
c19d1205
ZW
7192 if (inst.operands[0].reg == inst.operands[1].reg)
7193 as_tsktsk (_("rdhi and rdlo must be different"));
7194}
b05fe5cf 7195
c19d1205
ZW
7196static void
7197do_t_nop (void)
7198{
7199 if (unified_syntax)
7200 {
7201 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 7202 {
c19d1205
ZW
7203 inst.instruction = THUMB_OP32 (inst.instruction);
7204 inst.instruction |= inst.operands[0].imm;
7205 }
7206 else
7207 {
7208 inst.instruction = THUMB_OP16 (inst.instruction);
7209 inst.instruction |= inst.operands[0].imm << 4;
7210 }
7211 }
7212 else
7213 {
7214 constraint (inst.operands[0].present,
7215 _("Thumb does not support NOP with hints"));
7216 inst.instruction = 0x46c0;
7217 }
7218}
b05fe5cf 7219
c19d1205
ZW
7220static void
7221do_t_neg (void)
7222{
7223 if (unified_syntax)
7224 {
3d388997
PB
7225 bfd_boolean narrow;
7226
7227 if (THUMB_SETS_FLAGS (inst.instruction))
7228 narrow = (current_it_mask == 0);
7229 else
7230 narrow = (current_it_mask != 0);
7231 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
7232 narrow = FALSE;
7233 if (inst.size_req == 4)
7234 narrow = FALSE;
7235
7236 if (!narrow)
c19d1205
ZW
7237 {
7238 inst.instruction = THUMB_OP32 (inst.instruction);
7239 inst.instruction |= inst.operands[0].reg << 8;
7240 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
7241 }
7242 else
7243 {
c19d1205
ZW
7244 inst.instruction = THUMB_OP16 (inst.instruction);
7245 inst.instruction |= inst.operands[0].reg;
7246 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
7247 }
7248 }
7249 else
7250 {
c19d1205
ZW
7251 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
7252 BAD_HIREG);
7253 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
7254
7255 inst.instruction = THUMB_OP16 (inst.instruction);
7256 inst.instruction |= inst.operands[0].reg;
7257 inst.instruction |= inst.operands[1].reg << 3;
7258 }
7259}
7260
7261static void
7262do_t_pkhbt (void)
7263{
7264 inst.instruction |= inst.operands[0].reg << 8;
7265 inst.instruction |= inst.operands[1].reg << 16;
7266 inst.instruction |= inst.operands[2].reg;
7267 if (inst.operands[3].present)
7268 {
7269 unsigned int val = inst.reloc.exp.X_add_number;
7270 constraint (inst.reloc.exp.X_op != O_constant,
7271 _("expression too complex"));
7272 inst.instruction |= (val & 0x1c) << 10;
7273 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 7274 }
c19d1205 7275}
b05fe5cf 7276
c19d1205
ZW
7277static void
7278do_t_pkhtb (void)
7279{
7280 if (!inst.operands[3].present)
7281 inst.instruction &= ~0x00000020;
7282 do_t_pkhbt ();
b05fe5cf
ZW
7283}
7284
c19d1205
ZW
7285static void
7286do_t_pld (void)
7287{
7288 encode_thumb32_addr_mode (0, /*is_t=*/FALSE, /*is_d=*/FALSE);
7289}
b05fe5cf 7290
c19d1205
ZW
7291static void
7292do_t_push_pop (void)
b99bd4ef 7293{
e9f89963
PB
7294 unsigned mask;
7295
c19d1205
ZW
7296 constraint (inst.operands[0].writeback,
7297 _("push/pop do not support {reglist}^"));
7298 constraint (inst.reloc.type != BFD_RELOC_UNUSED,
7299 _("expression too complex"));
b99bd4ef 7300
e9f89963
PB
7301 mask = inst.operands[0].imm;
7302 if ((mask & ~0xff) == 0)
c19d1205
ZW
7303 inst.instruction = THUMB_OP16 (inst.instruction);
7304 else if ((inst.instruction == T_MNEM_push
e9f89963 7305 && (mask & ~0xff) == 1 << REG_LR)
c19d1205 7306 || (inst.instruction == T_MNEM_pop
e9f89963 7307 && (mask & ~0xff) == 1 << REG_PC))
b99bd4ef 7308 {
c19d1205
ZW
7309 inst.instruction = THUMB_OP16 (inst.instruction);
7310 inst.instruction |= THUMB_PP_PC_LR;
e9f89963 7311 mask &= 0xff;
c19d1205
ZW
7312 }
7313 else if (unified_syntax)
7314 {
e9f89963
PB
7315 if (mask & (1 << 13))
7316 inst.error = _("SP not allowed in register list");
c19d1205 7317 if (inst.instruction == T_MNEM_push)
b99bd4ef 7318 {
e9f89963
PB
7319 if (mask & (1 << 15))
7320 inst.error = _("PC not allowed in register list");
c19d1205
ZW
7321 }
7322 else
7323 {
e9f89963
PB
7324 if (mask & (1 << 14)
7325 && mask & (1 << 15))
7326 inst.error = _("LR and PC should not both be in register list");
c19d1205 7327 }
e9f89963
PB
7328 if ((mask & (mask - 1)) == 0)
7329 {
7330 /* Single register push/pop implemented as str/ldr. */
7331 if (inst.instruction == T_MNEM_push)
7332 inst.instruction = 0xf84d0d04; /* str reg, [sp, #-4]! */
7333 else
7334 inst.instruction = 0xf85d0b04; /* ldr reg, [sp], #4 */
7335 mask = ffs(mask) - 1;
7336 mask <<= 12;
7337 }
7338 else
7339 inst.instruction = THUMB_OP32 (inst.instruction);
c19d1205
ZW
7340 }
7341 else
7342 {
7343 inst.error = _("invalid register list to push/pop instruction");
7344 return;
7345 }
b99bd4ef 7346
e9f89963 7347 inst.instruction |= mask;
c19d1205 7348}
b99bd4ef 7349
c19d1205
ZW
7350static void
7351do_t_rbit (void)
7352{
7353 inst.instruction |= inst.operands[0].reg << 8;
7354 inst.instruction |= inst.operands[1].reg << 16;
7355}
b99bd4ef 7356
c19d1205
ZW
7357static void
7358do_t_rev (void)
7359{
7360 if (inst.operands[0].reg <= 7 && inst.operands[1].reg <= 7
7361 && inst.size_req != 4)
7362 {
7363 inst.instruction = THUMB_OP16 (inst.instruction);
7364 inst.instruction |= inst.operands[0].reg;
7365 inst.instruction |= inst.operands[1].reg << 3;
7366 }
7367 else if (unified_syntax)
7368 {
7369 inst.instruction = THUMB_OP32 (inst.instruction);
7370 inst.instruction |= inst.operands[0].reg << 8;
7371 inst.instruction |= inst.operands[1].reg << 16;
7372 inst.instruction |= inst.operands[1].reg;
7373 }
7374 else
7375 inst.error = BAD_HIREG;
7376}
b99bd4ef 7377
c19d1205
ZW
7378static void
7379do_t_rsb (void)
7380{
7381 int Rd, Rs;
b99bd4ef 7382
c19d1205
ZW
7383 Rd = inst.operands[0].reg;
7384 Rs = (inst.operands[1].present
7385 ? inst.operands[1].reg /* Rd, Rs, foo */
7386 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 7387
c19d1205
ZW
7388 inst.instruction |= Rd << 8;
7389 inst.instruction |= Rs << 16;
7390 if (!inst.operands[2].isreg)
7391 {
7392 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
7393 inst.reloc.type = BFD_RELOC_ARM_T32_IMMEDIATE;
7394 }
7395 else
7396 encode_thumb32_shifted_operand (2);
7397}
b99bd4ef 7398
c19d1205
ZW
7399static void
7400do_t_setend (void)
7401{
7402 if (inst.operands[0].imm)
7403 inst.instruction |= 0x8;
7404}
b99bd4ef 7405
c19d1205
ZW
7406static void
7407do_t_shift (void)
7408{
7409 if (!inst.operands[1].present)
7410 inst.operands[1].reg = inst.operands[0].reg;
7411
7412 if (unified_syntax)
7413 {
3d388997
PB
7414 bfd_boolean narrow;
7415 int shift_kind;
7416
7417 switch (inst.instruction)
7418 {
7419 case T_MNEM_asr:
7420 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
7421 case T_MNEM_lsl:
7422 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
7423 case T_MNEM_lsr:
7424 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
7425 case T_MNEM_ror:
7426 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
7427 default: abort ();
7428 }
7429
7430 if (THUMB_SETS_FLAGS (inst.instruction))
7431 narrow = (current_it_mask == 0);
7432 else
7433 narrow = (current_it_mask != 0);
7434 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
7435 narrow = FALSE;
7436 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
7437 narrow = FALSE;
7438 if (inst.operands[2].isreg
7439 && (inst.operands[1].reg != inst.operands[0].reg
7440 || inst.operands[2].reg > 7))
7441 narrow = FALSE;
7442 if (inst.size_req == 4)
7443 narrow = FALSE;
7444
7445 if (!narrow)
c19d1205
ZW
7446 {
7447 if (inst.operands[2].isreg)
b99bd4ef 7448 {
c19d1205
ZW
7449 inst.instruction = THUMB_OP32 (inst.instruction);
7450 inst.instruction |= inst.operands[0].reg << 8;
7451 inst.instruction |= inst.operands[1].reg << 16;
7452 inst.instruction |= inst.operands[2].reg;
7453 }
7454 else
7455 {
7456 inst.operands[1].shifted = 1;
3d388997 7457 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
7458 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
7459 ? T_MNEM_movs : T_MNEM_mov);
7460 inst.instruction |= inst.operands[0].reg << 8;
7461 encode_thumb32_shifted_operand (1);
7462 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
7463 inst.reloc.type = BFD_RELOC_UNUSED;
b99bd4ef
NC
7464 }
7465 }
7466 else
7467 {
c19d1205 7468 if (inst.operands[2].isreg)
b99bd4ef 7469 {
3d388997 7470 switch (shift_kind)
b99bd4ef 7471 {
3d388997
PB
7472 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
7473 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
7474 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
7475 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 7476 default: abort ();
b99bd4ef 7477 }
c19d1205
ZW
7478
7479 inst.instruction |= inst.operands[0].reg;
7480 inst.instruction |= inst.operands[2].reg << 3;
b99bd4ef
NC
7481 }
7482 else
7483 {
3d388997 7484 switch (shift_kind)
b99bd4ef 7485 {
3d388997
PB
7486 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
7487 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
7488 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 7489 default: abort ();
b99bd4ef 7490 }
c19d1205
ZW
7491 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
7492 inst.instruction |= inst.operands[0].reg;
7493 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
7494 }
7495 }
c19d1205
ZW
7496 }
7497 else
7498 {
7499 constraint (inst.operands[0].reg > 7
7500 || inst.operands[1].reg > 7, BAD_HIREG);
7501 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 7502
c19d1205
ZW
7503 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
7504 {
7505 constraint (inst.operands[2].reg > 7, BAD_HIREG);
7506 constraint (inst.operands[0].reg != inst.operands[1].reg,
7507 _("source1 and dest must be same register"));
b99bd4ef 7508
c19d1205
ZW
7509 switch (inst.instruction)
7510 {
7511 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
7512 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
7513 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
7514 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
7515 default: abort ();
7516 }
7517
7518 inst.instruction |= inst.operands[0].reg;
7519 inst.instruction |= inst.operands[2].reg << 3;
7520 }
7521 else
b99bd4ef 7522 {
c19d1205
ZW
7523 switch (inst.instruction)
7524 {
7525 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
7526 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
7527 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
7528 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
7529 default: abort ();
7530 }
7531 inst.reloc.type = BFD_RELOC_ARM_THUMB_SHIFT;
7532 inst.instruction |= inst.operands[0].reg;
7533 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
7534 }
7535 }
b99bd4ef
NC
7536}
7537
7538static void
c19d1205 7539do_t_simd (void)
b99bd4ef 7540{
c19d1205
ZW
7541 inst.instruction |= inst.operands[0].reg << 8;
7542 inst.instruction |= inst.operands[1].reg << 16;
7543 inst.instruction |= inst.operands[2].reg;
7544}
b99bd4ef 7545
c19d1205 7546static void
3eb17e6b 7547do_t_smc (void)
c19d1205
ZW
7548{
7549 unsigned int value = inst.reloc.exp.X_add_number;
7550 constraint (inst.reloc.exp.X_op != O_constant,
7551 _("expression too complex"));
7552 inst.reloc.type = BFD_RELOC_UNUSED;
7553 inst.instruction |= (value & 0xf000) >> 12;
7554 inst.instruction |= (value & 0x0ff0);
7555 inst.instruction |= (value & 0x000f) << 16;
7556}
b99bd4ef 7557
c19d1205
ZW
7558static void
7559do_t_ssat (void)
7560{
7561 inst.instruction |= inst.operands[0].reg << 8;
7562 inst.instruction |= inst.operands[1].imm - 1;
7563 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef 7564
c19d1205 7565 if (inst.operands[3].present)
b99bd4ef 7566 {
c19d1205
ZW
7567 constraint (inst.reloc.exp.X_op != O_constant,
7568 _("expression too complex"));
b99bd4ef 7569
c19d1205 7570 if (inst.reloc.exp.X_add_number != 0)
6189168b 7571 {
c19d1205
ZW
7572 if (inst.operands[3].shift_kind == SHIFT_ASR)
7573 inst.instruction |= 0x00200000; /* sh bit */
7574 inst.instruction |= (inst.reloc.exp.X_add_number & 0x1c) << 10;
7575 inst.instruction |= (inst.reloc.exp.X_add_number & 0x03) << 6;
6189168b 7576 }
c19d1205 7577 inst.reloc.type = BFD_RELOC_UNUSED;
6189168b 7578 }
b99bd4ef
NC
7579}
7580
0dd132b6 7581static void
c19d1205 7582do_t_ssat16 (void)
0dd132b6 7583{
c19d1205
ZW
7584 inst.instruction |= inst.operands[0].reg << 8;
7585 inst.instruction |= inst.operands[1].imm - 1;
7586 inst.instruction |= inst.operands[2].reg << 16;
7587}
0dd132b6 7588
c19d1205
ZW
7589static void
7590do_t_strex (void)
7591{
7592 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
7593 || inst.operands[2].postind || inst.operands[2].writeback
7594 || inst.operands[2].immisreg || inst.operands[2].shifted
7595 || inst.operands[2].negative,
01cfc07f 7596 BAD_ADDR_MODE);
0dd132b6 7597
c19d1205
ZW
7598 inst.instruction |= inst.operands[0].reg << 8;
7599 inst.instruction |= inst.operands[1].reg << 12;
7600 inst.instruction |= inst.operands[2].reg << 16;
7601 inst.reloc.type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
7602}
7603
b99bd4ef 7604static void
c19d1205 7605do_t_strexd (void)
b99bd4ef 7606{
c19d1205
ZW
7607 if (!inst.operands[2].present)
7608 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 7609
c19d1205
ZW
7610 constraint (inst.operands[0].reg == inst.operands[1].reg
7611 || inst.operands[0].reg == inst.operands[2].reg
7612 || inst.operands[0].reg == inst.operands[3].reg
7613 || inst.operands[1].reg == inst.operands[2].reg,
7614 BAD_OVERLAP);
b99bd4ef 7615
c19d1205
ZW
7616 inst.instruction |= inst.operands[0].reg;
7617 inst.instruction |= inst.operands[1].reg << 12;
7618 inst.instruction |= inst.operands[2].reg << 8;
7619 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
7620}
7621
7622static void
c19d1205 7623do_t_sxtah (void)
b99bd4ef 7624{
c19d1205
ZW
7625 inst.instruction |= inst.operands[0].reg << 8;
7626 inst.instruction |= inst.operands[1].reg << 16;
7627 inst.instruction |= inst.operands[2].reg;
7628 inst.instruction |= inst.operands[3].imm << 4;
7629}
b99bd4ef 7630
c19d1205
ZW
7631static void
7632do_t_sxth (void)
7633{
7634 if (inst.instruction <= 0xffff && inst.size_req != 4
7635 && inst.operands[0].reg <= 7 && inst.operands[1].reg <= 7
7636 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 7637 {
c19d1205
ZW
7638 inst.instruction = THUMB_OP16 (inst.instruction);
7639 inst.instruction |= inst.operands[0].reg;
7640 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef 7641 }
c19d1205 7642 else if (unified_syntax)
b99bd4ef 7643 {
c19d1205
ZW
7644 if (inst.instruction <= 0xffff)
7645 inst.instruction = THUMB_OP32 (inst.instruction);
7646 inst.instruction |= inst.operands[0].reg << 8;
7647 inst.instruction |= inst.operands[1].reg;
7648 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 7649 }
c19d1205 7650 else
b99bd4ef 7651 {
c19d1205
ZW
7652 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
7653 _("Thumb encoding does not support rotation"));
7654 constraint (1, BAD_HIREG);
b99bd4ef 7655 }
c19d1205 7656}
b99bd4ef 7657
c19d1205
ZW
7658static void
7659do_t_swi (void)
7660{
7661 inst.reloc.type = BFD_RELOC_ARM_SWI;
7662}
b99bd4ef 7663
92e90b6e
PB
7664static void
7665do_t_tb (void)
7666{
7667 int half;
7668
7669 half = (inst.instruction & 0x10) != 0;
7670 constraint (inst.operands[0].imm == 15,
7671 _("PC is not a valid index register"));
7672 constraint (!half && inst.operands[0].shifted,
7673 _("instruction does not allow shifted index"));
7674 constraint (half && !inst.operands[0].shifted,
7675 _("instruction requires shifted index"));
7676 inst.instruction |= (inst.operands[0].reg << 16) | inst.operands[0].imm;
7677}
7678
c19d1205
ZW
7679static void
7680do_t_usat (void)
7681{
7682 inst.instruction |= inst.operands[0].reg << 8;
7683 inst.instruction |= inst.operands[1].imm;
7684 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef 7685
c19d1205 7686 if (inst.operands[3].present)
b99bd4ef 7687 {
c19d1205
ZW
7688 constraint (inst.reloc.exp.X_op != O_constant,
7689 _("expression too complex"));
7690 if (inst.reloc.exp.X_add_number != 0)
7691 {
7692 if (inst.operands[3].shift_kind == SHIFT_ASR)
7693 inst.instruction |= 0x00200000; /* sh bit */
b99bd4ef 7694
c19d1205
ZW
7695 inst.instruction |= (inst.reloc.exp.X_add_number & 0x1c) << 10;
7696 inst.instruction |= (inst.reloc.exp.X_add_number & 0x03) << 6;
7697 }
7698 inst.reloc.type = BFD_RELOC_UNUSED;
b99bd4ef 7699 }
b99bd4ef
NC
7700}
7701
7702static void
c19d1205 7703do_t_usat16 (void)
b99bd4ef 7704{
c19d1205
ZW
7705 inst.instruction |= inst.operands[0].reg << 8;
7706 inst.instruction |= inst.operands[1].imm;
7707 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef 7708}
c19d1205
ZW
7709\f
7710/* Overall per-instruction processing. */
7711
7712/* We need to be able to fix up arbitrary expressions in some statements.
7713 This is so that we can handle symbols that are an arbitrary distance from
7714 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
7715 which returns part of an address in a form which will be valid for
7716 a data instruction. We do this by pushing the expression into a symbol
7717 in the expr_section, and creating a fix for that. */
b99bd4ef
NC
7718
7719static void
c19d1205
ZW
7720fix_new_arm (fragS * frag,
7721 int where,
7722 short int size,
7723 expressionS * exp,
7724 int pc_rel,
7725 int reloc)
b99bd4ef 7726{
c19d1205 7727 fixS * new_fix;
b99bd4ef 7728
c19d1205 7729 switch (exp->X_op)
b99bd4ef 7730 {
c19d1205
ZW
7731 case O_constant:
7732 case O_symbol:
7733 case O_add:
7734 case O_subtract:
7735 new_fix = fix_new_exp (frag, where, size, exp, pc_rel, reloc);
7736 break;
b99bd4ef 7737
c19d1205
ZW
7738 default:
7739 new_fix = fix_new (frag, where, size, make_expr_symbol (exp), 0,
7740 pc_rel, reloc);
7741 break;
b99bd4ef
NC
7742 }
7743
c19d1205
ZW
7744 /* Mark whether the fix is to a THUMB instruction, or an ARM
7745 instruction. */
adbaf948 7746 new_fix->tc_fix_data = thumb_mode;
b99bd4ef
NC
7747}
7748
0110f2b8
PB
7749/* Create a frg for an instruction requiring relaxation. */
7750static void
7751output_relax_insn (void)
7752{
7753 char * to;
7754 symbolS *sym;
7755 int offset;
7756
7757 switch (inst.reloc.exp.X_op)
7758 {
7759 case O_symbol:
7760 sym = inst.reloc.exp.X_add_symbol;
7761 offset = inst.reloc.exp.X_add_number;
7762 break;
7763 case O_constant:
7764 sym = NULL;
7765 offset = inst.reloc.exp.X_add_number;
7766 break;
7767 default:
7768 sym = make_expr_symbol (&inst.reloc.exp);
7769 offset = 0;
7770 break;
7771 }
7772 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
7773 inst.relax, sym, offset, NULL/*offset, opcode*/);
7774 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
7775
7776#ifdef OBJ_ELF
7777 dwarf2_emit_insn (INSN_SIZE);
7778#endif
7779}
7780
7781/* Write a 32-bit thumb instruction to buf. */
7782static void
7783put_thumb32_insn (char * buf, unsigned long insn)
7784{
7785 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
7786 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
7787}
7788
b99bd4ef 7789static void
c19d1205 7790output_inst (const char * str)
b99bd4ef 7791{
c19d1205 7792 char * to = NULL;
b99bd4ef 7793
c19d1205 7794 if (inst.error)
b99bd4ef 7795 {
c19d1205 7796 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
7797 return;
7798 }
0110f2b8
PB
7799 if (inst.relax) {
7800 output_relax_insn();
7801 return;
7802 }
c19d1205
ZW
7803 if (inst.size == 0)
7804 return;
b99bd4ef 7805
c19d1205
ZW
7806 to = frag_more (inst.size);
7807
7808 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 7809 {
c19d1205 7810 assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 7811 put_thumb32_insn (to, inst.instruction);
b99bd4ef 7812 }
c19d1205 7813 else if (inst.size > INSN_SIZE)
b99bd4ef 7814 {
c19d1205
ZW
7815 assert (inst.size == (2 * INSN_SIZE));
7816 md_number_to_chars (to, inst.instruction, INSN_SIZE);
7817 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 7818 }
c19d1205
ZW
7819 else
7820 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 7821
c19d1205
ZW
7822 if (inst.reloc.type != BFD_RELOC_UNUSED)
7823 fix_new_arm (frag_now, to - frag_now->fr_literal,
7824 inst.size, & inst.reloc.exp, inst.reloc.pc_rel,
7825 inst.reloc.type);
b99bd4ef 7826
c19d1205
ZW
7827#ifdef OBJ_ELF
7828 dwarf2_emit_insn (inst.size);
7829#endif
7830}
b99bd4ef 7831
c19d1205
ZW
7832/* Tag values used in struct asm_opcode's tag field. */
7833enum opcode_tag
7834{
7835 OT_unconditional, /* Instruction cannot be conditionalized.
7836 The ARM condition field is still 0xE. */
7837 OT_unconditionalF, /* Instruction cannot be conditionalized
7838 and carries 0xF in its ARM condition field. */
7839 OT_csuffix, /* Instruction takes a conditional suffix. */
7840 OT_cinfix3, /* Instruction takes a conditional infix,
7841 beginning at character index 3. (In
7842 unified mode, it becomes a suffix.) */
e3cb604e
PB
7843 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
7844 character index 3, even in unified mode. Used for
7845 legacy instructions where suffix and infix forms
7846 may be ambiguous. */
c19d1205 7847 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 7848 suffix or an infix at character index 3. */
c19d1205
ZW
7849 OT_odd_infix_unc, /* This is the unconditional variant of an
7850 instruction that takes a conditional infix
7851 at an unusual position. In unified mode,
7852 this variant will accept a suffix. */
7853 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
7854 are the conditional variants of instructions that
7855 take conditional infixes in unusual positions.
7856 The infix appears at character index
7857 (tag - OT_odd_infix_0). These are not accepted
7858 in unified mode. */
7859};
b99bd4ef 7860
c19d1205
ZW
7861/* Subroutine of md_assemble, responsible for looking up the primary
7862 opcode from the mnemonic the user wrote. STR points to the
7863 beginning of the mnemonic.
7864
7865 This is not simply a hash table lookup, because of conditional
7866 variants. Most instructions have conditional variants, which are
7867 expressed with a _conditional affix_ to the mnemonic. If we were
7868 to encode each conditional variant as a literal string in the opcode
7869 table, it would have approximately 20,000 entries.
7870
7871 Most mnemonics take this affix as a suffix, and in unified syntax,
7872 'most' is upgraded to 'all'. However, in the divided syntax, some
7873 instructions take the affix as an infix, notably the s-variants of
7874 the arithmetic instructions. Of those instructions, all but six
7875 have the infix appear after the third character of the mnemonic.
7876
7877 Accordingly, the algorithm for looking up primary opcodes given
7878 an identifier is:
7879
7880 1. Look up the identifier in the opcode table.
7881 If we find a match, go to step U.
7882
7883 2. Look up the last two characters of the identifier in the
7884 conditions table. If we find a match, look up the first N-2
7885 characters of the identifier in the opcode table. If we
7886 find a match, go to step CE.
7887
7888 3. Look up the fourth and fifth characters of the identifier in
7889 the conditions table. If we find a match, extract those
7890 characters from the identifier, and look up the remaining
7891 characters in the opcode table. If we find a match, go
7892 to step CM.
7893
7894 4. Fail.
7895
7896 U. Examine the tag field of the opcode structure, in case this is
7897 one of the six instructions with its conditional infix in an
7898 unusual place. If it is, the tag tells us where to find the
7899 infix; look it up in the conditions table and set inst.cond
7900 accordingly. Otherwise, this is an unconditional instruction.
7901 Again set inst.cond accordingly. Return the opcode structure.
7902
7903 CE. Examine the tag field to make sure this is an instruction that
7904 should receive a conditional suffix. If it is not, fail.
7905 Otherwise, set inst.cond from the suffix we already looked up,
7906 and return the opcode structure.
7907
7908 CM. Examine the tag field to make sure this is an instruction that
7909 should receive a conditional infix after the third character.
7910 If it is not, fail. Otherwise, undo the edits to the current
7911 line of input and proceed as for case CE. */
7912
7913static const struct asm_opcode *
7914opcode_lookup (char **str)
7915{
7916 char *end, *base;
7917 char *affix;
7918 const struct asm_opcode *opcode;
7919 const struct asm_cond *cond;
e3cb604e 7920 char save[2];
c19d1205
ZW
7921
7922 /* Scan up to the end of the mnemonic, which must end in white space,
7923 '.' (in unified mode only), or end of string. */
7924 for (base = end = *str; *end != '\0'; end++)
7925 if (*end == ' ' || (unified_syntax && *end == '.'))
7926 break;
b99bd4ef 7927
c19d1205
ZW
7928 if (end == base)
7929 return 0;
b99bd4ef 7930
c19d1205
ZW
7931 /* Handle a possible width suffix. */
7932 if (end[0] == '.')
b99bd4ef 7933 {
c19d1205
ZW
7934 if (end[1] == 'w' && (end[2] == ' ' || end[2] == '\0'))
7935 inst.size_req = 4;
7936 else if (end[1] == 'n' && (end[2] == ' ' || end[2] == '\0'))
7937 inst.size_req = 2;
7938 else
7939 return 0;
b99bd4ef 7940
c19d1205 7941 *str = end + 2;
b99bd4ef 7942 }
c19d1205
ZW
7943 else
7944 *str = end;
b99bd4ef 7945
c19d1205
ZW
7946 /* Look for unaffixed or special-case affixed mnemonic. */
7947 opcode = hash_find_n (arm_ops_hsh, base, end - base);
7948 if (opcode)
b99bd4ef 7949 {
c19d1205
ZW
7950 /* step U */
7951 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 7952 {
c19d1205
ZW
7953 inst.cond = COND_ALWAYS;
7954 return opcode;
b99bd4ef 7955 }
b99bd4ef 7956
c19d1205
ZW
7957 if (unified_syntax)
7958 as_warn (_("conditional infixes are deprecated in unified syntax"));
7959 affix = base + (opcode->tag - OT_odd_infix_0);
7960 cond = hash_find_n (arm_cond_hsh, affix, 2);
7961 assert (cond);
b99bd4ef 7962
c19d1205
ZW
7963 inst.cond = cond->value;
7964 return opcode;
7965 }
b99bd4ef 7966
c19d1205
ZW
7967 /* Cannot have a conditional suffix on a mnemonic of less than two
7968 characters. */
7969 if (end - base < 3)
7970 return 0;
b99bd4ef 7971
c19d1205
ZW
7972 /* Look for suffixed mnemonic. */
7973 affix = end - 2;
7974 cond = hash_find_n (arm_cond_hsh, affix, 2);
7975 opcode = hash_find_n (arm_ops_hsh, base, affix - base);
7976 if (opcode && cond)
7977 {
7978 /* step CE */
7979 switch (opcode->tag)
7980 {
e3cb604e
PB
7981 case OT_cinfix3_legacy:
7982 /* Ignore conditional suffixes matched on infix only mnemonics. */
7983 break;
7984
c19d1205
ZW
7985 case OT_cinfix3:
7986 case OT_odd_infix_unc:
7987 if (!unified_syntax)
e3cb604e 7988 return 0;
c19d1205
ZW
7989 /* else fall through */
7990
7991 case OT_csuffix:
7992 case OT_csuf_or_in3:
7993 inst.cond = cond->value;
7994 return opcode;
7995
7996 case OT_unconditional:
7997 case OT_unconditionalF:
7998 /* delayed diagnostic */
7999 inst.error = BAD_COND;
8000 inst.cond = COND_ALWAYS;
8001 return opcode;
b99bd4ef 8002
c19d1205
ZW
8003 default:
8004 return 0;
8005 }
8006 }
b99bd4ef 8007
c19d1205
ZW
8008 /* Cannot have a usual-position infix on a mnemonic of less than
8009 six characters (five would be a suffix). */
8010 if (end - base < 6)
8011 return 0;
b99bd4ef 8012
c19d1205
ZW
8013 /* Look for infixed mnemonic in the usual position. */
8014 affix = base + 3;
8015 cond = hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e
PB
8016 if (!cond)
8017 return 0;
8018
8019 memcpy (save, affix, 2);
8020 memmove (affix, affix + 2, (end - affix) - 2);
8021 opcode = hash_find_n (arm_ops_hsh, base, (end - base) - 2);
8022 memmove (affix + 2, affix, (end - affix) - 2);
8023 memcpy (affix, save, 2);
8024
8025 if (opcode && (opcode->tag == OT_cinfix3 || opcode->tag == OT_csuf_or_in3
8026 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 8027 {
c19d1205 8028 /* step CM */
e3cb604e 8029 if (unified_syntax && opcode->tag == OT_cinfix3)
c19d1205
ZW
8030 as_warn (_("conditional infixes are deprecated in unified syntax"));
8031
8032 inst.cond = cond->value;
8033 return opcode;
b99bd4ef
NC
8034 }
8035
c19d1205 8036 return 0;
b99bd4ef
NC
8037}
8038
c19d1205
ZW
8039void
8040md_assemble (char *str)
b99bd4ef 8041{
c19d1205
ZW
8042 char *p = str;
8043 const struct asm_opcode * opcode;
b99bd4ef 8044
c19d1205
ZW
8045 /* Align the previous label if needed. */
8046 if (last_label_seen != NULL)
b99bd4ef 8047 {
c19d1205
ZW
8048 symbol_set_frag (last_label_seen, frag_now);
8049 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
8050 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
8051 }
8052
c19d1205
ZW
8053 memset (&inst, '\0', sizeof (inst));
8054 inst.reloc.type = BFD_RELOC_UNUSED;
b99bd4ef 8055
c19d1205
ZW
8056 opcode = opcode_lookup (&p);
8057 if (!opcode)
b99bd4ef 8058 {
c19d1205
ZW
8059 /* It wasn't an instruction, but it might be a register alias of
8060 the form alias .req reg. */
8061 if (!create_register_alias (str, p))
8062 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 8063
b99bd4ef
NC
8064 return;
8065 }
8066
c19d1205 8067 if (thumb_mode)
b99bd4ef 8068 {
8f06b2d8
PB
8069 unsigned long variant;
8070
8071 variant = cpu_variant;
8072 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
8073 if ((variant & ARM_EXT_V6T2) == 0)
8074 variant &= ARM_ANY;
c19d1205 8075 /* Check that this instruction is supported for this CPU. */
8f06b2d8 8076 if (thumb_mode == 1 && (opcode->tvariant & variant) == 0)
b99bd4ef 8077 {
c19d1205 8078 as_bad (_("selected processor does not support `%s'"), str);
b99bd4ef
NC
8079 return;
8080 }
c19d1205
ZW
8081 if (inst.cond != COND_ALWAYS && !unified_syntax
8082 && opcode->tencode != do_t_branch)
b99bd4ef 8083 {
c19d1205 8084 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
8085 return;
8086 }
8087
e27ec89e
PB
8088 /* Check conditional suffixes. */
8089 if (current_it_mask)
8090 {
8091 int cond;
8092 cond = current_cc ^ ((current_it_mask >> 4) & 1) ^ 1;
8093 if (cond != inst.cond)
8094 {
8095 as_bad (_("incorrect condition in IT block"));
8096 return;
8097 }
8098 current_it_mask <<= 1;
8099 current_it_mask &= 0x1f;
8100 }
8101 else if (inst.cond != COND_ALWAYS && opcode->tencode != do_t_branch)
8102 {
8103 as_bad (_("thumb conditional instrunction not in IT block"));
8104 return;
8105 }
8106
c19d1205
ZW
8107 mapping_state (MAP_THUMB);
8108 inst.instruction = opcode->tvalue;
8109
8110 if (!parse_operands (p, opcode->operands))
8111 opcode->tencode ();
8112
e27ec89e
PB
8113 /* Clear current_it_mask at the end of an IT block. */
8114 if (current_it_mask == 0x10)
8115 current_it_mask = 0;
8116
0110f2b8 8117 if (!(inst.error || inst.relax))
b99bd4ef 8118 {
c19d1205
ZW
8119 assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
8120 inst.size = (inst.instruction > 0xffff ? 4 : 2);
8121 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 8122 {
c19d1205 8123 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
8124 return;
8125 }
8126 }
ee065d83
PB
8127 thumb_arch_used |= opcode->tvariant;
8128 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
8129 set those bits when Thumb-2 32-bit instuctions are seen. ie.
8130 anything other than bl/blx.
8131 This is overly pessimistic for relaxable instructions. */
8132 if ((inst.size == 4 && (inst.instruction & 0xf800e800) != 0xf000e800)
8133 || inst.relax)
8134 thumb_arch_used |= ARM_EXT_V6T2;
c19d1205
ZW
8135 }
8136 else
8137 {
8138 /* Check that this instruction is supported for this CPU. */
8139 if ((opcode->avariant & cpu_variant) == 0)
b99bd4ef 8140 {
c19d1205
ZW
8141 as_bad (_("selected processor does not support `%s'"), str);
8142 return;
b99bd4ef 8143 }
c19d1205 8144 if (inst.size_req)
b99bd4ef 8145 {
c19d1205
ZW
8146 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
8147 return;
b99bd4ef
NC
8148 }
8149
c19d1205
ZW
8150 mapping_state (MAP_ARM);
8151 inst.instruction = opcode->avalue;
8152 if (opcode->tag == OT_unconditionalF)
8153 inst.instruction |= 0xF << 28;
8154 else
8155 inst.instruction |= inst.cond << 28;
8156 inst.size = INSN_SIZE;
8157 if (!parse_operands (p, opcode->operands))
8158 opcode->aencode ();
ee065d83
PB
8159 /* Arm mode bx is marked as both v4T and v5 because it's still required
8160 on a hypothetical non-thumb v5 core. */
8161 if (opcode->avariant == (ARM_EXT_V4T | ARM_EXT_V5))
8162 arm_arch_used |= ARM_EXT_V4T;
8163 else
8164 arm_arch_used |= opcode->avariant;
b99bd4ef 8165 }
c19d1205
ZW
8166 output_inst (str);
8167}
b99bd4ef 8168
c19d1205
ZW
8169/* Various frobbings of labels and their addresses. */
8170
8171void
8172arm_start_line_hook (void)
8173{
8174 last_label_seen = NULL;
b99bd4ef
NC
8175}
8176
c19d1205
ZW
8177void
8178arm_frob_label (symbolS * sym)
b99bd4ef 8179{
c19d1205 8180 last_label_seen = sym;
b99bd4ef 8181
c19d1205 8182 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 8183
c19d1205
ZW
8184#if defined OBJ_COFF || defined OBJ_ELF
8185 ARM_SET_INTERWORK (sym, support_interwork);
8186#endif
b99bd4ef 8187
c19d1205
ZW
8188 /* Note - do not allow local symbols (.Lxxx) to be labeled
8189 as Thumb functions. This is because these labels, whilst
8190 they exist inside Thumb code, are not the entry points for
8191 possible ARM->Thumb calls. Also, these labels can be used
8192 as part of a computed goto or switch statement. eg gcc
8193 can generate code that looks like this:
b99bd4ef 8194
c19d1205
ZW
8195 ldr r2, [pc, .Laaa]
8196 lsl r3, r3, #2
8197 ldr r2, [r3, r2]
8198 mov pc, r2
b99bd4ef 8199
c19d1205
ZW
8200 .Lbbb: .word .Lxxx
8201 .Lccc: .word .Lyyy
8202 ..etc...
8203 .Laaa: .word Lbbb
b99bd4ef 8204
c19d1205
ZW
8205 The first instruction loads the address of the jump table.
8206 The second instruction converts a table index into a byte offset.
8207 The third instruction gets the jump address out of the table.
8208 The fourth instruction performs the jump.
b99bd4ef 8209
c19d1205
ZW
8210 If the address stored at .Laaa is that of a symbol which has the
8211 Thumb_Func bit set, then the linker will arrange for this address
8212 to have the bottom bit set, which in turn would mean that the
8213 address computation performed by the third instruction would end
8214 up with the bottom bit set. Since the ARM is capable of unaligned
8215 word loads, the instruction would then load the incorrect address
8216 out of the jump table, and chaos would ensue. */
8217 if (label_is_thumb_function_name
8218 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
8219 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
b99bd4ef 8220 {
c19d1205
ZW
8221 /* When the address of a Thumb function is taken the bottom
8222 bit of that address should be set. This will allow
8223 interworking between Arm and Thumb functions to work
8224 correctly. */
b99bd4ef 8225
c19d1205 8226 THUMB_SET_FUNC (sym, 1);
b99bd4ef 8227
c19d1205 8228 label_is_thumb_function_name = FALSE;
b99bd4ef 8229 }
07a53e5c
RH
8230
8231#ifdef OBJ_ELF
8232 dwarf2_emit_label (sym);
8233#endif
b99bd4ef
NC
8234}
8235
c19d1205
ZW
8236int
8237arm_data_in_code (void)
b99bd4ef 8238{
c19d1205 8239 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
b99bd4ef 8240 {
c19d1205
ZW
8241 *input_line_pointer = '/';
8242 input_line_pointer += 5;
8243 *input_line_pointer = 0;
8244 return 1;
b99bd4ef
NC
8245 }
8246
c19d1205 8247 return 0;
b99bd4ef
NC
8248}
8249
c19d1205
ZW
8250char *
8251arm_canonicalize_symbol_name (char * name)
b99bd4ef 8252{
c19d1205 8253 int len;
b99bd4ef 8254
c19d1205
ZW
8255 if (thumb_mode && (len = strlen (name)) > 5
8256 && streq (name + len - 5, "/data"))
8257 *(name + len - 5) = 0;
b99bd4ef 8258
c19d1205 8259 return name;
b99bd4ef 8260}
c19d1205
ZW
8261\f
8262/* Table of all register names defined by default. The user can
8263 define additional names with .req. Note that all register names
8264 should appear in both upper and lowercase variants. Some registers
8265 also have mixed-case names. */
b99bd4ef 8266
c19d1205
ZW
8267#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, TRUE }
8268#define REGNUM(p,n,t) REGDEF(p##n, n, t)
8269#define REGSET(p,t) \
8270 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
8271 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
8272 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
8273 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
7ed4c4c5 8274
c19d1205 8275static const struct reg_entry reg_names[] =
7ed4c4c5 8276{
c19d1205
ZW
8277 /* ARM integer registers. */
8278 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 8279
c19d1205
ZW
8280 /* ATPCS synonyms. */
8281 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
8282 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
8283 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 8284
c19d1205
ZW
8285 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
8286 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
8287 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 8288
c19d1205
ZW
8289 /* Well-known aliases. */
8290 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
8291 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
8292
8293 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
8294 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
8295
8296 /* Coprocessor numbers. */
8297 REGSET(p, CP), REGSET(P, CP),
8298
8299 /* Coprocessor register numbers. The "cr" variants are for backward
8300 compatibility. */
8301 REGSET(c, CN), REGSET(C, CN),
8302 REGSET(cr, CN), REGSET(CR, CN),
8303
8304 /* FPA registers. */
8305 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
8306 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
8307
8308 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
8309 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
8310
8311 /* VFP SP registers. */
8312 REGSET(s,VFS),
8313 REGNUM(s,16,VFS), REGNUM(s,17,VFS), REGNUM(s,18,VFS), REGNUM(s,19,VFS),
8314 REGNUM(s,20,VFS), REGNUM(s,21,VFS), REGNUM(s,22,VFS), REGNUM(s,23,VFS),
8315 REGNUM(s,24,VFS), REGNUM(s,25,VFS), REGNUM(s,26,VFS), REGNUM(s,27,VFS),
8316 REGNUM(s,28,VFS), REGNUM(s,29,VFS), REGNUM(s,30,VFS), REGNUM(s,31,VFS),
8317
8318 REGSET(S,VFS),
8319 REGNUM(S,16,VFS), REGNUM(S,17,VFS), REGNUM(S,18,VFS), REGNUM(S,19,VFS),
8320 REGNUM(S,20,VFS), REGNUM(S,21,VFS), REGNUM(S,22,VFS), REGNUM(S,23,VFS),
8321 REGNUM(S,24,VFS), REGNUM(S,25,VFS), REGNUM(S,26,VFS), REGNUM(S,27,VFS),
8322 REGNUM(S,28,VFS), REGNUM(S,29,VFS), REGNUM(S,30,VFS), REGNUM(S,31,VFS),
8323
8324 /* VFP DP Registers. */
8325 REGSET(d,VFD), REGSET(D,VFS),
8326
8327 /* VFP control registers. */
8328 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
8329 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
8330
8331 /* Maverick DSP coprocessor registers. */
8332 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
8333 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
8334
8335 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
8336 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
8337 REGDEF(dspsc,0,DSPSC),
8338
8339 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
8340 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
8341 REGDEF(DSPSC,0,DSPSC),
8342
8343 /* iWMMXt data registers - p0, c0-15. */
8344 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
8345
8346 /* iWMMXt control registers - p1, c0-3. */
8347 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
8348 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
8349 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
8350 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
8351
8352 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
8353 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
8354 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
8355 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
8356 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
8357
8358 /* XScale accumulator registers. */
8359 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
8360};
8361#undef REGDEF
8362#undef REGNUM
8363#undef REGSET
7ed4c4c5 8364
c19d1205
ZW
8365/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
8366 within psr_required_here. */
8367static const struct asm_psr psrs[] =
8368{
8369 /* Backward compatibility notation. Note that "all" is no longer
8370 truly all possible PSR bits. */
8371 {"all", PSR_c | PSR_f},
8372 {"flg", PSR_f},
8373 {"ctl", PSR_c},
8374
8375 /* Individual flags. */
8376 {"f", PSR_f},
8377 {"c", PSR_c},
8378 {"x", PSR_x},
8379 {"s", PSR_s},
8380 /* Combinations of flags. */
8381 {"fs", PSR_f | PSR_s},
8382 {"fx", PSR_f | PSR_x},
8383 {"fc", PSR_f | PSR_c},
8384 {"sf", PSR_s | PSR_f},
8385 {"sx", PSR_s | PSR_x},
8386 {"sc", PSR_s | PSR_c},
8387 {"xf", PSR_x | PSR_f},
8388 {"xs", PSR_x | PSR_s},
8389 {"xc", PSR_x | PSR_c},
8390 {"cf", PSR_c | PSR_f},
8391 {"cs", PSR_c | PSR_s},
8392 {"cx", PSR_c | PSR_x},
8393 {"fsx", PSR_f | PSR_s | PSR_x},
8394 {"fsc", PSR_f | PSR_s | PSR_c},
8395 {"fxs", PSR_f | PSR_x | PSR_s},
8396 {"fxc", PSR_f | PSR_x | PSR_c},
8397 {"fcs", PSR_f | PSR_c | PSR_s},
8398 {"fcx", PSR_f | PSR_c | PSR_x},
8399 {"sfx", PSR_s | PSR_f | PSR_x},
8400 {"sfc", PSR_s | PSR_f | PSR_c},
8401 {"sxf", PSR_s | PSR_x | PSR_f},
8402 {"sxc", PSR_s | PSR_x | PSR_c},
8403 {"scf", PSR_s | PSR_c | PSR_f},
8404 {"scx", PSR_s | PSR_c | PSR_x},
8405 {"xfs", PSR_x | PSR_f | PSR_s},
8406 {"xfc", PSR_x | PSR_f | PSR_c},
8407 {"xsf", PSR_x | PSR_s | PSR_f},
8408 {"xsc", PSR_x | PSR_s | PSR_c},
8409 {"xcf", PSR_x | PSR_c | PSR_f},
8410 {"xcs", PSR_x | PSR_c | PSR_s},
8411 {"cfs", PSR_c | PSR_f | PSR_s},
8412 {"cfx", PSR_c | PSR_f | PSR_x},
8413 {"csf", PSR_c | PSR_s | PSR_f},
8414 {"csx", PSR_c | PSR_s | PSR_x},
8415 {"cxf", PSR_c | PSR_x | PSR_f},
8416 {"cxs", PSR_c | PSR_x | PSR_s},
8417 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
8418 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
8419 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
8420 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
8421 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
8422 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
8423 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
8424 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
8425 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
8426 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
8427 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
8428 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
8429 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
8430 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
8431 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
8432 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
8433 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
8434 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
8435 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
8436 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
8437 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
8438 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
8439 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
8440 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
8441};
8442
8443/* Table of all shift-in-operand names. */
8444static const struct asm_shift_name shift_names [] =
b99bd4ef 8445{
c19d1205
ZW
8446 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
8447 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
8448 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
8449 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
8450 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
8451 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX }
8452};
b99bd4ef 8453
c19d1205
ZW
8454/* Table of all explicit relocation names. */
8455#ifdef OBJ_ELF
8456static struct reloc_entry reloc_names[] =
8457{
8458 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
8459 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
8460 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
8461 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
8462 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
8463 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
8464 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
8465 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
8466 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
8467 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
8468 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32}
8469};
8470#endif
b99bd4ef 8471
c19d1205
ZW
8472/* Table of all conditional affixes. 0xF is not defined as a condition code. */
8473static const struct asm_cond conds[] =
8474{
8475 {"eq", 0x0},
8476 {"ne", 0x1},
8477 {"cs", 0x2}, {"hs", 0x2},
8478 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
8479 {"mi", 0x4},
8480 {"pl", 0x5},
8481 {"vs", 0x6},
8482 {"vc", 0x7},
8483 {"hi", 0x8},
8484 {"ls", 0x9},
8485 {"ge", 0xa},
8486 {"lt", 0xb},
8487 {"gt", 0xc},
8488 {"le", 0xd},
8489 {"al", 0xe}
8490};
bfae80f2 8491
c19d1205
ZW
8492/* Table of ARM-format instructions. */
8493
8494/* Macros for gluing together operand strings. N.B. In all cases
8495 other than OPS0, the trailing OP_stop comes from default
8496 zero-initialization of the unspecified elements of the array. */
8497#define OPS0() { OP_stop, }
8498#define OPS1(a) { OP_##a, }
8499#define OPS2(a,b) { OP_##a,OP_##b, }
8500#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
8501#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
8502#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
8503#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
8504
8505/* These macros abstract out the exact format of the mnemonic table and
8506 save some repeated characters. */
8507
8508/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
8509#define TxCE(mnem, op, top, nops, ops, ae, te) \
8510 { #mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
1887dd22 8511 THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
8512
8513/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
8514 a T_MNEM_xyz enumerator. */
8515#define TCE(mnem, aop, top, nops, ops, ae, te) \
8516 TxCE(mnem, aop, 0x##top, nops, ops, ae, te)
8517#define tCE(mnem, aop, top, nops, ops, ae, te) \
8518 TxCE(mnem, aop, T_MNEM_##top, nops, ops, ae, te)
8519
8520/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
8521 infix after the third character. */
8522#define TxC3(mnem, op, top, nops, ops, ae, te) \
8523 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
1887dd22 8524 THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
8525#define TC3(mnem, aop, top, nops, ops, ae, te) \
8526 TxC3(mnem, aop, 0x##top, nops, ops, ae, te)
8527#define tC3(mnem, aop, top, nops, ops, ae, te) \
8528 TxC3(mnem, aop, T_MNEM_##top, nops, ops, ae, te)
8529
8530/* Mnemonic with a conditional infix in an unusual place. Each and every variant has to
8531 appear in the condition table. */
8532#define TxCM_(m1, m2, m3, op, top, nops, ops, ae, te) \
8533 { #m1 #m2 #m3, OPS##nops ops, sizeof(#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof(#m1) - 1, \
1887dd22 8534 0x##op, top, ARM_VARIANT, THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
8535
8536#define TxCM(m1, m2, op, top, nops, ops, ae, te) \
8537 TxCM_(m1, , m2, op, top, nops, ops, ae, te), \
8538 TxCM_(m1, eq, m2, op, top, nops, ops, ae, te), \
8539 TxCM_(m1, ne, m2, op, top, nops, ops, ae, te), \
8540 TxCM_(m1, cs, m2, op, top, nops, ops, ae, te), \
8541 TxCM_(m1, hs, m2, op, top, nops, ops, ae, te), \
8542 TxCM_(m1, cc, m2, op, top, nops, ops, ae, te), \
8543 TxCM_(m1, ul, m2, op, top, nops, ops, ae, te), \
8544 TxCM_(m1, lo, m2, op, top, nops, ops, ae, te), \
8545 TxCM_(m1, mi, m2, op, top, nops, ops, ae, te), \
8546 TxCM_(m1, pl, m2, op, top, nops, ops, ae, te), \
8547 TxCM_(m1, vs, m2, op, top, nops, ops, ae, te), \
8548 TxCM_(m1, vc, m2, op, top, nops, ops, ae, te), \
8549 TxCM_(m1, hi, m2, op, top, nops, ops, ae, te), \
8550 TxCM_(m1, ls, m2, op, top, nops, ops, ae, te), \
8551 TxCM_(m1, ge, m2, op, top, nops, ops, ae, te), \
8552 TxCM_(m1, lt, m2, op, top, nops, ops, ae, te), \
8553 TxCM_(m1, gt, m2, op, top, nops, ops, ae, te), \
8554 TxCM_(m1, le, m2, op, top, nops, ops, ae, te), \
8555 TxCM_(m1, al, m2, op, top, nops, ops, ae, te)
8556
8557#define TCM(m1,m2, aop, top, nops, ops, ae, te) \
8558 TxCM(m1,m2, aop, 0x##top, nops, ops, ae, te)
8559#define tCM(m1,m2, aop, top, nops, ops, ae, te) \
8560 TxCM(m1,m2, aop, T_MNEM_##top, nops, ops, ae, te)
8561
8562/* Mnemonic that cannot be conditionalized. The ARM condition-code
8563 field is still 0xE. */
8564#define TUE(mnem, op, top, nops, ops, ae, te) \
8565 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
1887dd22 8566 THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
8567
8568/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
8569 condition code field. */
8570#define TUF(mnem, op, top, nops, ops, ae, te) \
8571 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
1887dd22 8572 THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
8573
8574/* ARM-only variants of all the above. */
6a86118a
NC
8575#define CE(mnem, op, nops, ops, ae) \
8576 { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
8577
8578#define C3(mnem, op, nops, ops, ae) \
8579 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
8580
e3cb604e
PB
8581/* Legacy mnemonics that always have conditional infix after the third
8582 character. */
8583#define CL(mnem, op, nops, ops, ae) \
8584 { #mnem, OPS##nops ops, OT_cinfix3_legacy, \
8585 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
8586
8f06b2d8
PB
8587/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
8588#define cCE(mnem, op, nops, ops, ae) \
8589 { #mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
8590
e3cb604e
PB
8591/* Legacy coprocessor instructions where conditional infix and conditional
8592 suffix are ambiguous. For consistency this includes all FPA instructions,
8593 not just the potentially ambiguous ones. */
8594#define cCL(mnem, op, nops, ops, ae) \
8595 { #mnem, OPS##nops ops, OT_cinfix3_legacy, \
8596 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
8597
8598/* Coprocessor, takes either a suffix or a position-3 infix
8599 (for an FPA corner case). */
8600#define C3E(mnem, op, nops, ops, ae) \
8601 { #mnem, OPS##nops ops, OT_csuf_or_in3, \
8602 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
8f06b2d8 8603
6a86118a
NC
8604#define xCM_(m1, m2, m3, op, nops, ops, ae) \
8605 { #m1 #m2 #m3, OPS##nops ops, \
8606 sizeof(#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof(#m1) - 1, \
8607 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
8608
8609#define CM(m1, m2, op, nops, ops, ae) \
8610 xCM_(m1, , m2, op, nops, ops, ae), \
8611 xCM_(m1, eq, m2, op, nops, ops, ae), \
8612 xCM_(m1, ne, m2, op, nops, ops, ae), \
8613 xCM_(m1, cs, m2, op, nops, ops, ae), \
8614 xCM_(m1, hs, m2, op, nops, ops, ae), \
8615 xCM_(m1, cc, m2, op, nops, ops, ae), \
8616 xCM_(m1, ul, m2, op, nops, ops, ae), \
8617 xCM_(m1, lo, m2, op, nops, ops, ae), \
8618 xCM_(m1, mi, m2, op, nops, ops, ae), \
8619 xCM_(m1, pl, m2, op, nops, ops, ae), \
8620 xCM_(m1, vs, m2, op, nops, ops, ae), \
8621 xCM_(m1, vc, m2, op, nops, ops, ae), \
8622 xCM_(m1, hi, m2, op, nops, ops, ae), \
8623 xCM_(m1, ls, m2, op, nops, ops, ae), \
8624 xCM_(m1, ge, m2, op, nops, ops, ae), \
8625 xCM_(m1, lt, m2, op, nops, ops, ae), \
8626 xCM_(m1, gt, m2, op, nops, ops, ae), \
8627 xCM_(m1, le, m2, op, nops, ops, ae), \
8628 xCM_(m1, al, m2, op, nops, ops, ae)
8629
8630#define UE(mnem, op, nops, ops, ae) \
8631 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL }
8632
8633#define UF(mnem, op, nops, ops, ae) \
8634 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL }
8635
c19d1205
ZW
8636#define do_0 0
8637
8638/* Thumb-only, unconditional. */
8639#define UT(mnem, op, nops, ops, te) TUE(mnem, 0, op, nops, ops, 0, te)
8640
c19d1205 8641static const struct asm_opcode insns[] =
bfae80f2 8642{
c19d1205
ZW
8643#define ARM_VARIANT ARM_EXT_V1 /* Core ARM Instructions. */
8644#define THUMB_VARIANT ARM_EXT_V4T
8645 tCE(and, 0000000, and, 3, (RR, oRR, SH), arit, t_arit3c),
8646 tC3(ands, 0100000, ands, 3, (RR, oRR, SH), arit, t_arit3c),
8647 tCE(eor, 0200000, eor, 3, (RR, oRR, SH), arit, t_arit3c),
8648 tC3(eors, 0300000, eors, 3, (RR, oRR, SH), arit, t_arit3c),
8649 tCE(sub, 0400000, sub, 3, (RR, oRR, SH), arit, t_add_sub),
8650 tC3(subs, 0500000, subs, 3, (RR, oRR, SH), arit, t_add_sub),
8651 tCE(add, 0800000, add, 3, (RR, oRR, SH), arit, t_add_sub),
8652 tC3(adds, 0900000, adds, 3, (RR, oRR, SH), arit, t_add_sub),
8653 tCE(adc, 0a00000, adc, 3, (RR, oRR, SH), arit, t_arit3c),
8654 tC3(adcs, 0b00000, adcs, 3, (RR, oRR, SH), arit, t_arit3c),
8655 tCE(sbc, 0c00000, sbc, 3, (RR, oRR, SH), arit, t_arit3),
8656 tC3(sbcs, 0d00000, sbcs, 3, (RR, oRR, SH), arit, t_arit3),
8657 tCE(orr, 1800000, orr, 3, (RR, oRR, SH), arit, t_arit3c),
8658 tC3(orrs, 1900000, orrs, 3, (RR, oRR, SH), arit, t_arit3c),
8659 tCE(bic, 1c00000, bic, 3, (RR, oRR, SH), arit, t_arit3),
8660 tC3(bics, 1d00000, bics, 3, (RR, oRR, SH), arit, t_arit3),
8661
8662 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
8663 for setting PSR flag bits. They are obsolete in V6 and do not
8664 have Thumb equivalents. */
8665 tCE(tst, 1100000, tst, 2, (RR, SH), cmp, t_mvn_tst),
8666 tC3(tsts, 1100000, tst, 2, (RR, SH), cmp, t_mvn_tst),
e3cb604e 8667 CL(tstp, 110f000, 2, (RR, SH), cmp),
c19d1205
ZW
8668 tCE(cmp, 1500000, cmp, 2, (RR, SH), cmp, t_mov_cmp),
8669 tC3(cmps, 1500000, cmp, 2, (RR, SH), cmp, t_mov_cmp),
e3cb604e 8670 CL(cmpp, 150f000, 2, (RR, SH), cmp),
c19d1205
ZW
8671 tCE(cmn, 1700000, cmn, 2, (RR, SH), cmp, t_mvn_tst),
8672 tC3(cmns, 1700000, cmn, 2, (RR, SH), cmp, t_mvn_tst),
e3cb604e 8673 CL(cmnp, 170f000, 2, (RR, SH), cmp),
c19d1205
ZW
8674
8675 tCE(mov, 1a00000, mov, 2, (RR, SH), mov, t_mov_cmp),
8676 tC3(movs, 1b00000, movs, 2, (RR, SH), mov, t_mov_cmp),
8677 tCE(mvn, 1e00000, mvn, 2, (RR, SH), mov, t_mvn_tst),
8678 tC3(mvns, 1f00000, mvns, 2, (RR, SH), mov, t_mvn_tst),
8679
8680 tCE(ldr, 4100000, ldr, 2, (RR, ADDR), ldst, t_ldst),
8681 tC3(ldrb, 4500000, ldrb, 2, (RR, ADDR), ldst, t_ldst),
8682 tCE(str, 4000000, str, 2, (RR, ADDR), ldst, t_ldst),
8683 tC3(strb, 4400000, strb, 2, (RR, ADDR), ldst, t_ldst),
8684
8685 tC3(stmia, 8800000, stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
8686 tC3(stmea, 8800000, stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
8687 tC3(ldmia, 8900000, ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
8688 tC3(ldmfd, 8900000, ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
8689
8690 TCE(swi, f000000, df00, 1, (EXPi), swi, t_swi),
0110f2b8 8691 tCE(b, a000000, b, 1, (EXPr), branch, t_branch),
2fc8bdac 8692 TCE(bl, b000000, f000f800, 1, (EXPr), branch, t_branch23),
bfae80f2 8693
c19d1205 8694 /* Pseudo ops. */
e9f89963 8695 tCE(adr, 28f0000, adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac
ZW
8696 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
8697 tCE(nop, 1a00000, nop, 1, (oI255c), nop, t_nop),
c19d1205
ZW
8698
8699 /* Thumb-compatibility pseudo ops. */
8700 tCE(lsl, 1a00000, lsl, 3, (RR, oRR, SH), shift, t_shift),
8701 tC3(lsls, 1b00000, lsls, 3, (RR, oRR, SH), shift, t_shift),
8702 tCE(lsr, 1a00020, lsr, 3, (RR, oRR, SH), shift, t_shift),
8703 tC3(lsrs, 1b00020, lsrs, 3, (RR, oRR, SH), shift, t_shift),
8704 tCE(asr, 1a00040, asr, 3, (RR, oRR, SH), shift, t_shift),
2fc8bdac 8705 tC3(asrs, 1b00040, asrs, 3, (RR, oRR, SH), shift, t_shift),
c19d1205
ZW
8706 tCE(ror, 1a00060, ror, 3, (RR, oRR, SH), shift, t_shift),
8707 tC3(rors, 1b00060, rors, 3, (RR, oRR, SH), shift, t_shift),
8708 tCE(neg, 2600000, neg, 2, (RR, RR), rd_rn, t_neg),
8709 tC3(negs, 2700000, negs, 2, (RR, RR), rd_rn, t_neg),
8710 tCE(push, 92d0000, push, 1, (REGLST), push_pop, t_push_pop),
8711 tCE(pop, 8bd0000, pop, 1, (REGLST), push_pop, t_push_pop),
8712
8713#undef THUMB_VARIANT
8714#define THUMB_VARIANT ARM_EXT_V6
2fc8bdac 8715 TCE(cpy, 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
8716
8717 /* V1 instructions with no Thumb analogue prior to V6T2. */
8718#undef THUMB_VARIANT
8719#define THUMB_VARIANT ARM_EXT_V6T2
8720 TCE(rsb, 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
8721 TC3(rsbs, 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
8722 TCE(teq, 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
8723 TC3(teqs, 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
e3cb604e 8724 CL(teqp, 130f000, 2, (RR, SH), cmp),
c19d1205
ZW
8725
8726 TC3(ldrt, 4300000, f8500e00, 2, (RR, ADDR), ldstt, t_ldstt),
8727 TC3(ldrbt, 4700000, f8300e00, 2, (RR, ADDR), ldstt, t_ldstt),
8728 TC3(strt, 4200000, f8400e00, 2, (RR, ADDR), ldstt, t_ldstt),
8729 TC3(strbt, 4600000, f8200e00, 2, (RR, ADDR), ldstt, t_ldstt),
8730
9c3c69f2
PB
8731 TC3(stmdb, 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
8732 TC3(stmfd, 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 8733
9c3c69f2
PB
8734 TC3(ldmdb, 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
8735 TC3(ldmea, 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
8736
8737 /* V1 instructions with no Thumb analogue at all. */
8738 CE(rsc, 0e00000, 3, (RR, oRR, SH), arit),
8739 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
8740
8741 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
8742 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
8743 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
8744 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
8745 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
8746 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
8747 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
8748 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
8749
8750#undef ARM_VARIANT
8751#define ARM_VARIANT ARM_EXT_V2 /* ARM 2 - multiplies. */
8752#undef THUMB_VARIANT
8753#define THUMB_VARIANT ARM_EXT_V4T
8754 tCE(mul, 0000090, mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
8755 tC3(muls, 0100090, muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
8756
8757#undef THUMB_VARIANT
8758#define THUMB_VARIANT ARM_EXT_V6T2
8759 TCE(mla, 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
8760 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
8761
8762 /* Generic coprocessor instructions. */
8763 TCE(cdp, e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
8764 TCE(ldc, c100000, ec100000, 3, (RCP, RCN, ADDR), lstc, lstc),
8765 TC3(ldcl, c500000, ec500000, 3, (RCP, RCN, ADDR), lstc, lstc),
8766 TCE(stc, c000000, ec000000, 3, (RCP, RCN, ADDR), lstc, lstc),
8767 TC3(stcl, c400000, ec400000, 3, (RCP, RCN, ADDR), lstc, lstc),
8768 TCE(mcr, e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
8769 TCE(mrc, e100010, ee100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
8770
8771#undef ARM_VARIANT
8772#define ARM_VARIANT ARM_EXT_V2S /* ARM 3 - swp instructions. */
8773 CE(swp, 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
8774 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
8775
8776#undef ARM_VARIANT
8777#define ARM_VARIANT ARM_EXT_V3 /* ARM 6 Status register instructions. */
8778 TCE(mrs, 10f0000, f3ef8000, 2, (RR, PSR), mrs, t_mrs),
8779 TCE(msr, 120f000, f3808000, 2, (PSR, RR_EXi), msr, t_msr),
8780
8781#undef ARM_VARIANT
8782#define ARM_VARIANT ARM_EXT_V3M /* ARM 7M long multiplies. */
8783 TCE(smull, 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
8784 CM(smull,s, 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
8785 TCE(umull, 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
8786 CM(umull,s, 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
8787 TCE(smlal, 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
8788 CM(smlal,s, 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
8789 TCE(umlal, 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
8790 CM(umlal,s, 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
8791
8792#undef ARM_VARIANT
8793#define ARM_VARIANT ARM_EXT_V4 /* ARM Architecture 4. */
8794#undef THUMB_VARIANT
8795#define THUMB_VARIANT ARM_EXT_V4T
8796 tC3(ldrh, 01000b0, ldrh, 2, (RR, ADDR), ldstv4, t_ldst),
8797 tC3(strh, 00000b0, strh, 2, (RR, ADDR), ldstv4, t_ldst),
8798 tC3(ldrsh, 01000f0, ldrsh, 2, (RR, ADDR), ldstv4, t_ldst),
8799 tC3(ldrsb, 01000d0, ldrsb, 2, (RR, ADDR), ldstv4, t_ldst),
8800 tCM(ld,sh, 01000f0, ldrsh, 2, (RR, ADDR), ldstv4, t_ldst),
8801 tCM(ld,sb, 01000d0, ldrsb, 2, (RR, ADDR), ldstv4, t_ldst),
8802
8803#undef ARM_VARIANT
8804#define ARM_VARIANT ARM_EXT_V4T|ARM_EXT_V5
8805 /* ARM Architecture 4T. */
8806 /* Note: bx (and blx) are required on V5, even if the processor does
8807 not support Thumb. */
8808 TCE(bx, 12fff10, 4700, 1, (RR), bx, t_bx),
8809
8810#undef ARM_VARIANT
8811#define ARM_VARIANT ARM_EXT_V5 /* ARM Architecture 5T. */
8812#undef THUMB_VARIANT
8813#define THUMB_VARIANT ARM_EXT_V5T
8814 /* Note: blx has 2 variants; the .value coded here is for
8815 BLX(2). Only this variant has conditional execution. */
8816 TCE(blx, 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
8817 TUE(bkpt, 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
8818
8819#undef THUMB_VARIANT
8820#define THUMB_VARIANT ARM_EXT_V6T2
8821 TCE(clz, 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
8822 TUF(ldc2, c100000, fc100000, 3, (RCP, RCN, ADDR), lstc, lstc),
8823 TUF(ldc2l, c500000, fc500000, 3, (RCP, RCN, ADDR), lstc, lstc),
8824 TUF(stc2, c000000, fc000000, 3, (RCP, RCN, ADDR), lstc, lstc),
8825 TUF(stc2l, c400000, fc400000, 3, (RCP, RCN, ADDR), lstc, lstc),
8826 TUF(cdp2, e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
8827 TUF(mcr2, e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
8828 TUF(mrc2, e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
8829
8830#undef ARM_VARIANT
8831#define ARM_VARIANT ARM_EXT_V5ExP /* ARM Architecture 5TExP. */
8832 TCE(smlabb, 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
8833 TCE(smlatb, 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
8834 TCE(smlabt, 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
8835 TCE(smlatt, 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
8836
8837 TCE(smlawb, 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
8838 TCE(smlawt, 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
8839
8840 TCE(smlalbb, 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
8841 TCE(smlaltb, 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
8842 TCE(smlalbt, 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
8843 TCE(smlaltt, 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
8844
8845 TCE(smulbb, 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8846 TCE(smultb, 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8847 TCE(smulbt, 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8848 TCE(smultt, 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8849
8850 TCE(smulwb, 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8851 TCE(smulwt, 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8852
8853 TCE(qadd, 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, rd_rm_rn),
8854 TCE(qdadd, 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, rd_rm_rn),
8855 TCE(qsub, 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, rd_rm_rn),
8856 TCE(qdsub, 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, rd_rm_rn),
8857
8858#undef ARM_VARIANT
8859#define ARM_VARIANT ARM_EXT_V5E /* ARM Architecture 5TE. */
8860 TUF(pld, 450f000, f810f000, 1, (ADDR), pld, t_pld),
8861 TC3(ldrd, 00000d0, e9500000, 3, (RRnpc, oRRnpc, ADDR), ldrd, t_ldstd),
8862 TC3(strd, 00000f0, e9400000, 3, (RRnpc, oRRnpc, ADDR), ldrd, t_ldstd),
8863
8864 TCE(mcrr, c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
8865 TCE(mrrc, c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
8866
8867#undef ARM_VARIANT
8868#define ARM_VARIANT ARM_EXT_V5J /* ARM Architecture 5TEJ. */
8869 TCE(bxj, 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
8870
8871#undef ARM_VARIANT
8872#define ARM_VARIANT ARM_EXT_V6 /* ARM V6. */
8873#undef THUMB_VARIANT
8874#define THUMB_VARIANT ARM_EXT_V6
8875 TUF(cpsie, 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
8876 TUF(cpsid, 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
8877 tCE(rev, 6bf0f30, rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
8878 tCE(rev16, 6bf0fb0, rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
8879 tCE(revsh, 6ff0fb0, revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
8880 tCE(sxth, 6bf0070, sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
8881 tCE(uxth, 6ff0070, uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
8882 tCE(sxtb, 6af0070, sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
8883 tCE(uxtb, 6ef0070, uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
8884 TUF(setend, 1010000, b650, 1, (ENDI), setend, t_setend),
8885
8886#undef THUMB_VARIANT
8887#define THUMB_VARIANT ARM_EXT_V6T2
8888 TUF(cps, 1020000, f3af8100, 1, (I31b), imm0, imm0),
8889 TCE(ldrex, 1900f9f, e8500f00, 2, (RRnpc, ADDR), ldrex, t_ldrex),
8890 TUF(mcrr2, c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
8891 TUF(mrrc2, c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
8892 TCE(pkhbt, 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
8893 TCE(pkhtb, 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
8894 TCE(qadd16, 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8895 TCE(qadd8, 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8896 TCE(qaddsubx, 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8897 TCE(qsub16, 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8898 TCE(qsub8, 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8899 TCE(qsubaddx, 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8900 TCE(sadd16, 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8901 TCE(sadd8, 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8902 TCE(saddsubx, 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8903 TCE(shadd16, 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8904 TCE(shadd8, 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8905 TCE(shaddsubx, 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8906 TCE(shsub16, 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8907 TCE(shsub8, 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8908 TCE(shsubaddx, 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8909 TCE(ssub16, 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8910 TCE(ssub8, 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8911 TCE(ssubaddx, 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8912 TCE(uadd16, 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8913 TCE(uadd8, 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8914 TCE(uaddsubx, 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8915 TCE(uhadd16, 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8916 TCE(uhadd8, 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8917 TCE(uhaddsubx, 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8918 TCE(uhsub16, 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8919 TCE(uhsub8, 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8920 TCE(uhsubaddx, 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8921 TCE(uqadd16, 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8922 TCE(uqadd8, 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8923 TCE(uqaddsubx, 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8924 TCE(uqsub16, 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8925 TCE(uqsub8, 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8926 TCE(uqsubaddx, 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8927 TCE(usub16, 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8928 TCE(usub8, 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8929 TCE(usubaddx, 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
8930 TUF(rfeia, 8900a00, e990c000, 1, (RRw), rfe, rfe),
8931 UF(rfeib, 9900a00, 1, (RRw), rfe),
8932 UF(rfeda, 8100a00, 1, (RRw), rfe),
8933 TUF(rfedb, 9100a00, e810c000, 1, (RRw), rfe, rfe),
8934 TUF(rfefd, 8900a00, e990c000, 1, (RRw), rfe, rfe),
8935 UF(rfefa, 9900a00, 1, (RRw), rfe),
8936 UF(rfeea, 8100a00, 1, (RRw), rfe),
8937 TUF(rfeed, 9100a00, e810c000, 1, (RRw), rfe, rfe),
8938 TCE(sxtah, 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
8939 TCE(sxtab16, 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
8940 TCE(sxtab, 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
8941 TCE(sxtb16, 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
8942 TCE(uxtah, 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
8943 TCE(uxtab16, 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
8944 TCE(uxtab, 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
8945 TCE(uxtb16, 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
f1022c90 8946 TCE(sel, 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
c19d1205
ZW
8947 TCE(smlad, 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
8948 TCE(smladx, 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
8949 TCE(smlald, 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
8950 TCE(smlaldx, 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
8951 TCE(smlsd, 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
8952 TCE(smlsdx, 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
8953 TCE(smlsld, 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
8954 TCE(smlsldx, 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
8955 TCE(smmla, 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
8956 TCE(smmlar, 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
8957 TCE(smmls, 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
8958 TCE(smmlsr, 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
8959 TCE(smmul, 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8960 TCE(smmulr, 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8961 TCE(smuad, 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8962 TCE(smuadx, 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8963 TCE(smusd, 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8964 TCE(smusdx, 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8965 TUF(srsia, 8cd0500, e980c000, 1, (I31w), srs, srs),
8966 UF(srsib, 9cd0500, 1, (I31w), srs),
8967 UF(srsda, 84d0500, 1, (I31w), srs),
8968 TUF(srsdb, 94d0500, e800c000, 1, (I31w), srs, srs),
8969 TCE(ssat, 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
8970 TCE(ssat16, 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
8971 TCE(strex, 1800f90, e8400000, 3, (RRnpc, RRnpc, ADDR), strex, t_strex),
8972 TCE(umaal, 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
8973 TCE(usad8, 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
8974 TCE(usada8, 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
8975 TCE(usat, 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
8976 TCE(usat16, 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
8977
8978#undef ARM_VARIANT
8979#define ARM_VARIANT ARM_EXT_V6K
8980#undef THUMB_VARIANT
8981#define THUMB_VARIANT ARM_EXT_V6K
8982 tCE(yield, 320f001, yield, 0, (), noargs, t_hint),
8983 tCE(wfe, 320f002, wfe, 0, (), noargs, t_hint),
8984 tCE(wfi, 320f003, wfi, 0, (), noargs, t_hint),
8985 tCE(sev, 320f004, sev, 0, (), noargs, t_hint),
8986
8987#undef THUMB_VARIANT
8988#define THUMB_VARIANT ARM_EXT_V6T2
8989 TCE(ldrexb, 1d00f9f, e8d00f4f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
8990 TCE(ldrexh, 1f00f9f, e8d00f5f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
8991 TCE(ldrexd, 1b00f9f, e8d0007f, 3, (RRnpc, oRRnpc, RRnpcb), ldrexd, t_ldrexd),
8992 TCE(strexb, 1c00f90, e8c00f40, 3, (RRnpc, RRnpc, ADDR), strex, rm_rd_rn),
8993 TCE(strexh, 1e00f90, e8c00f50, 3, (RRnpc, RRnpc, ADDR), strex, rm_rd_rn),
8994 TCE(strexd, 1a00f90, e8c00070, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb), strexd, t_strexd),
8995 TUF(clrex, 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
8996
8997#undef ARM_VARIANT
8998#define ARM_VARIANT ARM_EXT_V6Z
3eb17e6b 8999 TCE(smc, 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205
ZW
9000
9001#undef ARM_VARIANT
9002#define ARM_VARIANT ARM_EXT_V6T2
9003 TCE(bfc, 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
9004 TCE(bfi, 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
9005 TCE(sbfx, 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
9006 TCE(ubfx, 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
9007
9008 TCE(mls, 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
9009 TCE(movw, 3000000, f2400000, 2, (RRnpc, Iffff), mov16, t_mov16),
9010 TCE(movt, 3400000, f2c00000, 2, (RRnpc, Iffff), mov16, t_mov16),
9011 TCE(rbit, 3ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
9012
9013 TC3(ldrht, 03000b0, f8300e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
9014 TC3(ldrsht, 03000f0, f9300e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
9015 TC3(ldrsbt, 03000d0, f9100e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
9016 TC3(strht, 02000b0, f8200e00, 2, (RR, ADDR), ldsttv4, t_ldstt),
9017
9018 UT(cbnz, b900, 2, (RR, EXP), t_czb),
9019 UT(cbz, b100, 2, (RR, EXP), t_czb),
9020 /* ARM does not really have an IT instruction. */
9021 TUE(it, 0, bf08, 1, (COND), it, t_it),
9022 TUE(itt, 0, bf0c, 1, (COND), it, t_it),
9023 TUE(ite, 0, bf04, 1, (COND), it, t_it),
9024 TUE(ittt, 0, bf0e, 1, (COND), it, t_it),
9025 TUE(itet, 0, bf06, 1, (COND), it, t_it),
9026 TUE(itte, 0, bf0a, 1, (COND), it, t_it),
9027 TUE(itee, 0, bf02, 1, (COND), it, t_it),
9028 TUE(itttt, 0, bf0f, 1, (COND), it, t_it),
9029 TUE(itett, 0, bf07, 1, (COND), it, t_it),
9030 TUE(ittet, 0, bf0b, 1, (COND), it, t_it),
9031 TUE(iteet, 0, bf03, 1, (COND), it, t_it),
9032 TUE(ittte, 0, bf0d, 1, (COND), it, t_it),
9033 TUE(itete, 0, bf05, 1, (COND), it, t_it),
9034 TUE(ittee, 0, bf09, 1, (COND), it, t_it),
9035 TUE(iteee, 0, bf01, 1, (COND), it, t_it),
9036
92e90b6e
PB
9037 /* Thumb2 only instructions. */
9038#undef ARM_VARIANT
9039#define ARM_VARIANT 0
9040
9041 TCE(addw, 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
9042 TCE(subw, 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
9043 TCE(tbb, 0, e8d0f000, 1, (TB), 0, t_tb),
9044 TCE(tbh, 0, e8d0f010, 1, (TB), 0, t_tb),
9045
c19d1205
ZW
9046#undef ARM_VARIANT
9047#define ARM_VARIANT FPU_FPA_EXT_V1 /* Core FPA instruction set (V1). */
8f06b2d8
PB
9048 cCE(wfs, e200110, 1, (RR), rd),
9049 cCE(rfs, e300110, 1, (RR), rd),
9050 cCE(wfc, e400110, 1, (RR), rd),
9051 cCE(rfc, e500110, 1, (RR), rd),
9052
e3cb604e
PB
9053 cCL(ldfs, c100100, 2, (RF, ADDR), rd_cpaddr),
9054 cCL(ldfd, c108100, 2, (RF, ADDR), rd_cpaddr),
9055 cCL(ldfe, c500100, 2, (RF, ADDR), rd_cpaddr),
9056 cCL(ldfp, c508100, 2, (RF, ADDR), rd_cpaddr),
9057
9058 cCL(stfs, c000100, 2, (RF, ADDR), rd_cpaddr),
9059 cCL(stfd, c008100, 2, (RF, ADDR), rd_cpaddr),
9060 cCL(stfe, c400100, 2, (RF, ADDR), rd_cpaddr),
9061 cCL(stfp, c408100, 2, (RF, ADDR), rd_cpaddr),
9062
9063 cCL(mvfs, e008100, 2, (RF, RF_IF), rd_rm),
9064 cCL(mvfsp, e008120, 2, (RF, RF_IF), rd_rm),
9065 cCL(mvfsm, e008140, 2, (RF, RF_IF), rd_rm),
9066 cCL(mvfsz, e008160, 2, (RF, RF_IF), rd_rm),
9067 cCL(mvfd, e008180, 2, (RF, RF_IF), rd_rm),
9068 cCL(mvfdp, e0081a0, 2, (RF, RF_IF), rd_rm),
9069 cCL(mvfdm, e0081c0, 2, (RF, RF_IF), rd_rm),
9070 cCL(mvfdz, e0081e0, 2, (RF, RF_IF), rd_rm),
9071 cCL(mvfe, e088100, 2, (RF, RF_IF), rd_rm),
9072 cCL(mvfep, e088120, 2, (RF, RF_IF), rd_rm),
9073 cCL(mvfem, e088140, 2, (RF, RF_IF), rd_rm),
9074 cCL(mvfez, e088160, 2, (RF, RF_IF), rd_rm),
9075
9076 cCL(mnfs, e108100, 2, (RF, RF_IF), rd_rm),
9077 cCL(mnfsp, e108120, 2, (RF, RF_IF), rd_rm),
9078 cCL(mnfsm, e108140, 2, (RF, RF_IF), rd_rm),
9079 cCL(mnfsz, e108160, 2, (RF, RF_IF), rd_rm),
9080 cCL(mnfd, e108180, 2, (RF, RF_IF), rd_rm),
9081 cCL(mnfdp, e1081a0, 2, (RF, RF_IF), rd_rm),
9082 cCL(mnfdm, e1081c0, 2, (RF, RF_IF), rd_rm),
9083 cCL(mnfdz, e1081e0, 2, (RF, RF_IF), rd_rm),
9084 cCL(mnfe, e188100, 2, (RF, RF_IF), rd_rm),
9085 cCL(mnfep, e188120, 2, (RF, RF_IF), rd_rm),
9086 cCL(mnfem, e188140, 2, (RF, RF_IF), rd_rm),
9087 cCL(mnfez, e188160, 2, (RF, RF_IF), rd_rm),
9088
9089 cCL(abss, e208100, 2, (RF, RF_IF), rd_rm),
9090 cCL(abssp, e208120, 2, (RF, RF_IF), rd_rm),
9091 cCL(abssm, e208140, 2, (RF, RF_IF), rd_rm),
9092 cCL(abssz, e208160, 2, (RF, RF_IF), rd_rm),
9093 cCL(absd, e208180, 2, (RF, RF_IF), rd_rm),
9094 cCL(absdp, e2081a0, 2, (RF, RF_IF), rd_rm),
9095 cCL(absdm, e2081c0, 2, (RF, RF_IF), rd_rm),
9096 cCL(absdz, e2081e0, 2, (RF, RF_IF), rd_rm),
9097 cCL(abse, e288100, 2, (RF, RF_IF), rd_rm),
9098 cCL(absep, e288120, 2, (RF, RF_IF), rd_rm),
9099 cCL(absem, e288140, 2, (RF, RF_IF), rd_rm),
9100 cCL(absez, e288160, 2, (RF, RF_IF), rd_rm),
9101
9102 cCL(rnds, e308100, 2, (RF, RF_IF), rd_rm),
9103 cCL(rndsp, e308120, 2, (RF, RF_IF), rd_rm),
9104 cCL(rndsm, e308140, 2, (RF, RF_IF), rd_rm),
9105 cCL(rndsz, e308160, 2, (RF, RF_IF), rd_rm),
9106 cCL(rndd, e308180, 2, (RF, RF_IF), rd_rm),
9107 cCL(rnddp, e3081a0, 2, (RF, RF_IF), rd_rm),
9108 cCL(rnddm, e3081c0, 2, (RF, RF_IF), rd_rm),
9109 cCL(rnddz, e3081e0, 2, (RF, RF_IF), rd_rm),
9110 cCL(rnde, e388100, 2, (RF, RF_IF), rd_rm),
9111 cCL(rndep, e388120, 2, (RF, RF_IF), rd_rm),
9112 cCL(rndem, e388140, 2, (RF, RF_IF), rd_rm),
9113 cCL(rndez, e388160, 2, (RF, RF_IF), rd_rm),
9114
9115 cCL(sqts, e408100, 2, (RF, RF_IF), rd_rm),
9116 cCL(sqtsp, e408120, 2, (RF, RF_IF), rd_rm),
9117 cCL(sqtsm, e408140, 2, (RF, RF_IF), rd_rm),
9118 cCL(sqtsz, e408160, 2, (RF, RF_IF), rd_rm),
9119 cCL(sqtd, e408180, 2, (RF, RF_IF), rd_rm),
9120 cCL(sqtdp, e4081a0, 2, (RF, RF_IF), rd_rm),
9121 cCL(sqtdm, e4081c0, 2, (RF, RF_IF), rd_rm),
9122 cCL(sqtdz, e4081e0, 2, (RF, RF_IF), rd_rm),
9123 cCL(sqte, e488100, 2, (RF, RF_IF), rd_rm),
9124 cCL(sqtep, e488120, 2, (RF, RF_IF), rd_rm),
9125 cCL(sqtem, e488140, 2, (RF, RF_IF), rd_rm),
9126 cCL(sqtez, e488160, 2, (RF, RF_IF), rd_rm),
9127
9128 cCL(logs, e508100, 2, (RF, RF_IF), rd_rm),
9129 cCL(logsp, e508120, 2, (RF, RF_IF), rd_rm),
9130 cCL(logsm, e508140, 2, (RF, RF_IF), rd_rm),
9131 cCL(logsz, e508160, 2, (RF, RF_IF), rd_rm),
9132 cCL(logd, e508180, 2, (RF, RF_IF), rd_rm),
9133 cCL(logdp, e5081a0, 2, (RF, RF_IF), rd_rm),
9134 cCL(logdm, e5081c0, 2, (RF, RF_IF), rd_rm),
9135 cCL(logdz, e5081e0, 2, (RF, RF_IF), rd_rm),
9136 cCL(loge, e588100, 2, (RF, RF_IF), rd_rm),
9137 cCL(logep, e588120, 2, (RF, RF_IF), rd_rm),
9138 cCL(logem, e588140, 2, (RF, RF_IF), rd_rm),
9139 cCL(logez, e588160, 2, (RF, RF_IF), rd_rm),
9140
9141 cCL(lgns, e608100, 2, (RF, RF_IF), rd_rm),
9142 cCL(lgnsp, e608120, 2, (RF, RF_IF), rd_rm),
9143 cCL(lgnsm, e608140, 2, (RF, RF_IF), rd_rm),
9144 cCL(lgnsz, e608160, 2, (RF, RF_IF), rd_rm),
9145 cCL(lgnd, e608180, 2, (RF, RF_IF), rd_rm),
9146 cCL(lgndp, e6081a0, 2, (RF, RF_IF), rd_rm),
9147 cCL(lgndm, e6081c0, 2, (RF, RF_IF), rd_rm),
9148 cCL(lgndz, e6081e0, 2, (RF, RF_IF), rd_rm),
9149 cCL(lgne, e688100, 2, (RF, RF_IF), rd_rm),
9150 cCL(lgnep, e688120, 2, (RF, RF_IF), rd_rm),
9151 cCL(lgnem, e688140, 2, (RF, RF_IF), rd_rm),
9152 cCL(lgnez, e688160, 2, (RF, RF_IF), rd_rm),
9153
9154 cCL(exps, e708100, 2, (RF, RF_IF), rd_rm),
9155 cCL(expsp, e708120, 2, (RF, RF_IF), rd_rm),
9156 cCL(expsm, e708140, 2, (RF, RF_IF), rd_rm),
9157 cCL(expsz, e708160, 2, (RF, RF_IF), rd_rm),
9158 cCL(expd, e708180, 2, (RF, RF_IF), rd_rm),
9159 cCL(expdp, e7081a0, 2, (RF, RF_IF), rd_rm),
9160 cCL(expdm, e7081c0, 2, (RF, RF_IF), rd_rm),
9161 cCL(expdz, e7081e0, 2, (RF, RF_IF), rd_rm),
9162 cCL(expe, e788100, 2, (RF, RF_IF), rd_rm),
9163 cCL(expep, e788120, 2, (RF, RF_IF), rd_rm),
9164 cCL(expem, e788140, 2, (RF, RF_IF), rd_rm),
9165 cCL(expdz, e788160, 2, (RF, RF_IF), rd_rm),
9166
9167 cCL(sins, e808100, 2, (RF, RF_IF), rd_rm),
9168 cCL(sinsp, e808120, 2, (RF, RF_IF), rd_rm),
9169 cCL(sinsm, e808140, 2, (RF, RF_IF), rd_rm),
9170 cCL(sinsz, e808160, 2, (RF, RF_IF), rd_rm),
9171 cCL(sind, e808180, 2, (RF, RF_IF), rd_rm),
9172 cCL(sindp, e8081a0, 2, (RF, RF_IF), rd_rm),
9173 cCL(sindm, e8081c0, 2, (RF, RF_IF), rd_rm),
9174 cCL(sindz, e8081e0, 2, (RF, RF_IF), rd_rm),
9175 cCL(sine, e888100, 2, (RF, RF_IF), rd_rm),
9176 cCL(sinep, e888120, 2, (RF, RF_IF), rd_rm),
9177 cCL(sinem, e888140, 2, (RF, RF_IF), rd_rm),
9178 cCL(sinez, e888160, 2, (RF, RF_IF), rd_rm),
9179
9180 cCL(coss, e908100, 2, (RF, RF_IF), rd_rm),
9181 cCL(cossp, e908120, 2, (RF, RF_IF), rd_rm),
9182 cCL(cossm, e908140, 2, (RF, RF_IF), rd_rm),
9183 cCL(cossz, e908160, 2, (RF, RF_IF), rd_rm),
9184 cCL(cosd, e908180, 2, (RF, RF_IF), rd_rm),
9185 cCL(cosdp, e9081a0, 2, (RF, RF_IF), rd_rm),
9186 cCL(cosdm, e9081c0, 2, (RF, RF_IF), rd_rm),
9187 cCL(cosdz, e9081e0, 2, (RF, RF_IF), rd_rm),
9188 cCL(cose, e988100, 2, (RF, RF_IF), rd_rm),
9189 cCL(cosep, e988120, 2, (RF, RF_IF), rd_rm),
9190 cCL(cosem, e988140, 2, (RF, RF_IF), rd_rm),
9191 cCL(cosez, e988160, 2, (RF, RF_IF), rd_rm),
9192
9193 cCL(tans, ea08100, 2, (RF, RF_IF), rd_rm),
9194 cCL(tansp, ea08120, 2, (RF, RF_IF), rd_rm),
9195 cCL(tansm, ea08140, 2, (RF, RF_IF), rd_rm),
9196 cCL(tansz, ea08160, 2, (RF, RF_IF), rd_rm),
9197 cCL(tand, ea08180, 2, (RF, RF_IF), rd_rm),
9198 cCL(tandp, ea081a0, 2, (RF, RF_IF), rd_rm),
9199 cCL(tandm, ea081c0, 2, (RF, RF_IF), rd_rm),
9200 cCL(tandz, ea081e0, 2, (RF, RF_IF), rd_rm),
9201 cCL(tane, ea88100, 2, (RF, RF_IF), rd_rm),
9202 cCL(tanep, ea88120, 2, (RF, RF_IF), rd_rm),
9203 cCL(tanem, ea88140, 2, (RF, RF_IF), rd_rm),
9204 cCL(tanez, ea88160, 2, (RF, RF_IF), rd_rm),
9205
9206 cCL(asns, eb08100, 2, (RF, RF_IF), rd_rm),
9207 cCL(asnsp, eb08120, 2, (RF, RF_IF), rd_rm),
9208 cCL(asnsm, eb08140, 2, (RF, RF_IF), rd_rm),
9209 cCL(asnsz, eb08160, 2, (RF, RF_IF), rd_rm),
9210 cCL(asnd, eb08180, 2, (RF, RF_IF), rd_rm),
9211 cCL(asndp, eb081a0, 2, (RF, RF_IF), rd_rm),
9212 cCL(asndm, eb081c0, 2, (RF, RF_IF), rd_rm),
9213 cCL(asndz, eb081e0, 2, (RF, RF_IF), rd_rm),
9214 cCL(asne, eb88100, 2, (RF, RF_IF), rd_rm),
9215 cCL(asnep, eb88120, 2, (RF, RF_IF), rd_rm),
9216 cCL(asnem, eb88140, 2, (RF, RF_IF), rd_rm),
9217 cCL(asnez, eb88160, 2, (RF, RF_IF), rd_rm),
9218
9219 cCL(acss, ec08100, 2, (RF, RF_IF), rd_rm),
9220 cCL(acssp, ec08120, 2, (RF, RF_IF), rd_rm),
9221 cCL(acssm, ec08140, 2, (RF, RF_IF), rd_rm),
9222 cCL(acssz, ec08160, 2, (RF, RF_IF), rd_rm),
9223 cCL(acsd, ec08180, 2, (RF, RF_IF), rd_rm),
9224 cCL(acsdp, ec081a0, 2, (RF, RF_IF), rd_rm),
9225 cCL(acsdm, ec081c0, 2, (RF, RF_IF), rd_rm),
9226 cCL(acsdz, ec081e0, 2, (RF, RF_IF), rd_rm),
9227 cCL(acse, ec88100, 2, (RF, RF_IF), rd_rm),
9228 cCL(acsep, ec88120, 2, (RF, RF_IF), rd_rm),
9229 cCL(acsem, ec88140, 2, (RF, RF_IF), rd_rm),
9230 cCL(acsez, ec88160, 2, (RF, RF_IF), rd_rm),
9231
9232 cCL(atns, ed08100, 2, (RF, RF_IF), rd_rm),
9233 cCL(atnsp, ed08120, 2, (RF, RF_IF), rd_rm),
9234 cCL(atnsm, ed08140, 2, (RF, RF_IF), rd_rm),
9235 cCL(atnsz, ed08160, 2, (RF, RF_IF), rd_rm),
9236 cCL(atnd, ed08180, 2, (RF, RF_IF), rd_rm),
9237 cCL(atndp, ed081a0, 2, (RF, RF_IF), rd_rm),
9238 cCL(atndm, ed081c0, 2, (RF, RF_IF), rd_rm),
9239 cCL(atndz, ed081e0, 2, (RF, RF_IF), rd_rm),
9240 cCL(atne, ed88100, 2, (RF, RF_IF), rd_rm),
9241 cCL(atnep, ed88120, 2, (RF, RF_IF), rd_rm),
9242 cCL(atnem, ed88140, 2, (RF, RF_IF), rd_rm),
9243 cCL(atnez, ed88160, 2, (RF, RF_IF), rd_rm),
9244
9245 cCL(urds, ee08100, 2, (RF, RF_IF), rd_rm),
9246 cCL(urdsp, ee08120, 2, (RF, RF_IF), rd_rm),
9247 cCL(urdsm, ee08140, 2, (RF, RF_IF), rd_rm),
9248 cCL(urdsz, ee08160, 2, (RF, RF_IF), rd_rm),
9249 cCL(urdd, ee08180, 2, (RF, RF_IF), rd_rm),
9250 cCL(urddp, ee081a0, 2, (RF, RF_IF), rd_rm),
9251 cCL(urddm, ee081c0, 2, (RF, RF_IF), rd_rm),
9252 cCL(urddz, ee081e0, 2, (RF, RF_IF), rd_rm),
9253 cCL(urde, ee88100, 2, (RF, RF_IF), rd_rm),
9254 cCL(urdep, ee88120, 2, (RF, RF_IF), rd_rm),
9255 cCL(urdem, ee88140, 2, (RF, RF_IF), rd_rm),
9256 cCL(urdez, ee88160, 2, (RF, RF_IF), rd_rm),
9257
9258 cCL(nrms, ef08100, 2, (RF, RF_IF), rd_rm),
9259 cCL(nrmsp, ef08120, 2, (RF, RF_IF), rd_rm),
9260 cCL(nrmsm, ef08140, 2, (RF, RF_IF), rd_rm),
9261 cCL(nrmsz, ef08160, 2, (RF, RF_IF), rd_rm),
9262 cCL(nrmd, ef08180, 2, (RF, RF_IF), rd_rm),
9263 cCL(nrmdp, ef081a0, 2, (RF, RF_IF), rd_rm),
9264 cCL(nrmdm, ef081c0, 2, (RF, RF_IF), rd_rm),
9265 cCL(nrmdz, ef081e0, 2, (RF, RF_IF), rd_rm),
9266 cCL(nrme, ef88100, 2, (RF, RF_IF), rd_rm),
9267 cCL(nrmep, ef88120, 2, (RF, RF_IF), rd_rm),
9268 cCL(nrmem, ef88140, 2, (RF, RF_IF), rd_rm),
9269 cCL(nrmez, ef88160, 2, (RF, RF_IF), rd_rm),
9270
9271 cCL(adfs, e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
9272 cCL(adfsp, e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
9273 cCL(adfsm, e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
9274 cCL(adfsz, e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
9275 cCL(adfd, e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
9276 cCL(adfdp, e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9277 cCL(adfdm, e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9278 cCL(adfdz, e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9279 cCL(adfe, e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
9280 cCL(adfep, e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
9281 cCL(adfem, e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
9282 cCL(adfez, e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
9283
9284 cCL(sufs, e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
9285 cCL(sufsp, e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
9286 cCL(sufsm, e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
9287 cCL(sufsz, e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
9288 cCL(sufd, e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
9289 cCL(sufdp, e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9290 cCL(sufdm, e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9291 cCL(sufdz, e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9292 cCL(sufe, e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
9293 cCL(sufep, e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
9294 cCL(sufem, e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
9295 cCL(sufez, e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
9296
9297 cCL(rsfs, e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
9298 cCL(rsfsp, e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
9299 cCL(rsfsm, e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
9300 cCL(rsfsz, e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
9301 cCL(rsfd, e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
9302 cCL(rsfdp, e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9303 cCL(rsfdm, e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9304 cCL(rsfdz, e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9305 cCL(rsfe, e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
9306 cCL(rsfep, e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
9307 cCL(rsfem, e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
9308 cCL(rsfez, e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
9309
9310 cCL(mufs, e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
9311 cCL(mufsp, e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
9312 cCL(mufsm, e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
9313 cCL(mufsz, e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
9314 cCL(mufd, e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
9315 cCL(mufdp, e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9316 cCL(mufdm, e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9317 cCL(mufdz, e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9318 cCL(mufe, e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
9319 cCL(mufep, e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
9320 cCL(mufem, e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
9321 cCL(mufez, e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
9322
9323 cCL(dvfs, e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
9324 cCL(dvfsp, e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
9325 cCL(dvfsm, e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
9326 cCL(dvfsz, e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
9327 cCL(dvfd, e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
9328 cCL(dvfdp, e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9329 cCL(dvfdm, e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9330 cCL(dvfdz, e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9331 cCL(dvfe, e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
9332 cCL(dvfep, e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
9333 cCL(dvfem, e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
9334 cCL(dvfez, e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
9335
9336 cCL(rdfs, e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
9337 cCL(rdfsp, e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
9338 cCL(rdfsm, e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
9339 cCL(rdfsz, e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
9340 cCL(rdfd, e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
9341 cCL(rdfdp, e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9342 cCL(rdfdm, e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9343 cCL(rdfdz, e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9344 cCL(rdfe, e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
9345 cCL(rdfep, e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
9346 cCL(rdfem, e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
9347 cCL(rdfez, e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
9348
9349 cCL(pows, e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
9350 cCL(powsp, e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
9351 cCL(powsm, e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
9352 cCL(powsz, e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
9353 cCL(powd, e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
9354 cCL(powdp, e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9355 cCL(powdm, e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9356 cCL(powdz, e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9357 cCL(powe, e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
9358 cCL(powep, e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
9359 cCL(powem, e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
9360 cCL(powez, e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
9361
9362 cCL(rpws, e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
9363 cCL(rpwsp, e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
9364 cCL(rpwsm, e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
9365 cCL(rpwsz, e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
9366 cCL(rpwd, e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
9367 cCL(rpwdp, e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9368 cCL(rpwdm, e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9369 cCL(rpwdz, e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9370 cCL(rpwe, e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
9371 cCL(rpwep, e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
9372 cCL(rpwem, e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
9373 cCL(rpwez, e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
9374
9375 cCL(rmfs, e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
9376 cCL(rmfsp, e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
9377 cCL(rmfsm, e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
9378 cCL(rmfsz, e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
9379 cCL(rmfd, e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
9380 cCL(rmfdp, e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9381 cCL(rmfdm, e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9382 cCL(rmfdz, e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9383 cCL(rmfe, e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
9384 cCL(rmfep, e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
9385 cCL(rmfem, e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
9386 cCL(rmfez, e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
9387
9388 cCL(fmls, e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
9389 cCL(fmlsp, e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
9390 cCL(fmlsm, e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
9391 cCL(fmlsz, e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
9392 cCL(fmld, e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
9393 cCL(fmldp, e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9394 cCL(fmldm, e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9395 cCL(fmldz, e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9396 cCL(fmle, e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
9397 cCL(fmlep, e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
9398 cCL(fmlem, e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
9399 cCL(fmlez, e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
9400
9401 cCL(fdvs, ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
9402 cCL(fdvsp, ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
9403 cCL(fdvsm, ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
9404 cCL(fdvsz, ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
9405 cCL(fdvd, ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
9406 cCL(fdvdp, ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9407 cCL(fdvdm, ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9408 cCL(fdvdz, ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9409 cCL(fdve, ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
9410 cCL(fdvep, ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
9411 cCL(fdvem, ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
9412 cCL(fdvez, ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
9413
9414 cCL(frds, eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
9415 cCL(frdsp, eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
9416 cCL(frdsm, eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
9417 cCL(frdsz, eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
9418 cCL(frdd, eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
9419 cCL(frddp, eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9420 cCL(frddm, eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9421 cCL(frddz, eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9422 cCL(frde, eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
9423 cCL(frdep, eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
9424 cCL(frdem, eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
9425 cCL(frdez, eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
9426
9427 cCL(pols, ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
9428 cCL(polsp, ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
9429 cCL(polsm, ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
9430 cCL(polsz, ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
9431 cCL(pold, ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
9432 cCL(poldp, ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
9433 cCL(poldm, ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
9434 cCL(poldz, ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
9435 cCL(pole, ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
9436 cCL(polep, ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
9437 cCL(polem, ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
9438 cCL(polez, ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
8f06b2d8
PB
9439
9440 cCE(cmf, e90f110, 2, (RF, RF_IF), fpa_cmp),
c19d1205 9441 C3E(cmfe, ed0f110, 2, (RF, RF_IF), fpa_cmp),
8f06b2d8 9442 cCE(cnf, eb0f110, 2, (RF, RF_IF), fpa_cmp),
c19d1205
ZW
9443 C3E(cnfe, ef0f110, 2, (RF, RF_IF), fpa_cmp),
9444
e3cb604e
PB
9445 cCL(flts, e000110, 2, (RF, RR), rn_rd),
9446 cCL(fltsp, e000130, 2, (RF, RR), rn_rd),
9447 cCL(fltsm, e000150, 2, (RF, RR), rn_rd),
9448 cCL(fltsz, e000170, 2, (RF, RR), rn_rd),
9449 cCL(fltd, e000190, 2, (RF, RR), rn_rd),
9450 cCL(fltdp, e0001b0, 2, (RF, RR), rn_rd),
9451 cCL(fltdm, e0001d0, 2, (RF, RR), rn_rd),
9452 cCL(fltdz, e0001f0, 2, (RF, RR), rn_rd),
9453 cCL(flte, e080110, 2, (RF, RR), rn_rd),
9454 cCL(fltep, e080130, 2, (RF, RR), rn_rd),
9455 cCL(fltem, e080150, 2, (RF, RR), rn_rd),
9456 cCL(fltez, e080170, 2, (RF, RR), rn_rd),
b99bd4ef 9457
c19d1205
ZW
9458 /* The implementation of the FIX instruction is broken on some
9459 assemblers, in that it accepts a precision specifier as well as a
9460 rounding specifier, despite the fact that this is meaningless.
9461 To be more compatible, we accept it as well, though of course it
9462 does not set any bits. */
8f06b2d8 9463 cCE(fix, e100110, 2, (RR, RF), rd_rm),
e3cb604e
PB
9464 cCL(fixp, e100130, 2, (RR, RF), rd_rm),
9465 cCL(fixm, e100150, 2, (RR, RF), rd_rm),
9466 cCL(fixz, e100170, 2, (RR, RF), rd_rm),
9467 cCL(fixsp, e100130, 2, (RR, RF), rd_rm),
9468 cCL(fixsm, e100150, 2, (RR, RF), rd_rm),
9469 cCL(fixsz, e100170, 2, (RR, RF), rd_rm),
9470 cCL(fixdp, e100130, 2, (RR, RF), rd_rm),
9471 cCL(fixdm, e100150, 2, (RR, RF), rd_rm),
9472 cCL(fixdz, e100170, 2, (RR, RF), rd_rm),
9473 cCL(fixep, e100130, 2, (RR, RF), rd_rm),
9474 cCL(fixem, e100150, 2, (RR, RF), rd_rm),
9475 cCL(fixez, e100170, 2, (RR, RF), rd_rm),
bfae80f2 9476
c19d1205
ZW
9477 /* Instructions that were new with the real FPA, call them V2. */
9478#undef ARM_VARIANT
9479#define ARM_VARIANT FPU_FPA_EXT_V2
8f06b2d8 9480 cCE(lfm, c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
e3cb604e
PB
9481 cCL(lfmfd, c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
9482 cCL(lfmea, d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
8f06b2d8 9483 cCE(sfm, c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
e3cb604e
PB
9484 cCL(sfmfd, d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
9485 cCL(sfmea, c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205
ZW
9486
9487#undef ARM_VARIANT
9488#define ARM_VARIANT FPU_VFP_EXT_V1xD /* VFP V1xD (single precision). */
9489 /* Moves and type conversions. */
8f06b2d8
PB
9490 cCE(fcpys, eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
9491 cCE(fmrs, e100a10, 2, (RR, RVS), vfp_reg_from_sp),
9492 cCE(fmsr, e000a10, 2, (RVS, RR), vfp_sp_from_reg),
9493 cCE(fmstat, ef1fa10, 0, (), noargs),
9494 cCE(fsitos, eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
9495 cCE(fuitos, eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
9496 cCE(ftosis, ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
9497 cCE(ftosizs, ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
9498 cCE(ftouis, ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
9499 cCE(ftouizs, ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
9500 cCE(fmrx, ef00a10, 2, (RR, RVC), rd_rn),
9501 cCE(fmxr, ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
9502
9503 /* Memory operations. */
8f06b2d8
PB
9504 cCE(flds, d100a00, 2, (RVS, ADDR), vfp_sp_ldst),
9505 cCE(fsts, d000a00, 2, (RVS, ADDR), vfp_sp_ldst),
9506 cCE(fldmias, c900a00, 2, (RRw, VRSLST), vfp_sp_ldstmia),
9507 cCE(fldmfds, c900a00, 2, (RRw, VRSLST), vfp_sp_ldstmia),
9508 cCE(fldmdbs, d300a00, 2, (RRw, VRSLST), vfp_sp_ldstmdb),
9509 cCE(fldmeas, d300a00, 2, (RRw, VRSLST), vfp_sp_ldstmdb),
9510 cCE(fldmiax, c900b00, 2, (RRw, VRDLST), vfp_xp_ldstmia),
9511 cCE(fldmfdx, c900b00, 2, (RRw, VRDLST), vfp_xp_ldstmia),
9512 cCE(fldmdbx, d300b00, 2, (RRw, VRDLST), vfp_xp_ldstmdb),
9513 cCE(fldmeax, d300b00, 2, (RRw, VRDLST), vfp_xp_ldstmdb),
9514 cCE(fstmias, c800a00, 2, (RRw, VRSLST), vfp_sp_ldstmia),
9515 cCE(fstmeas, c800a00, 2, (RRw, VRSLST), vfp_sp_ldstmia),
9516 cCE(fstmdbs, d200a00, 2, (RRw, VRSLST), vfp_sp_ldstmdb),
9517 cCE(fstmfds, d200a00, 2, (RRw, VRSLST), vfp_sp_ldstmdb),
9518 cCE(fstmiax, c800b00, 2, (RRw, VRDLST), vfp_xp_ldstmia),
9519 cCE(fstmeax, c800b00, 2, (RRw, VRDLST), vfp_xp_ldstmia),
9520 cCE(fstmdbx, d200b00, 2, (RRw, VRDLST), vfp_xp_ldstmdb),
9521 cCE(fstmfdx, d200b00, 2, (RRw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 9522
c19d1205 9523 /* Monadic operations. */
8f06b2d8
PB
9524 cCE(fabss, eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
9525 cCE(fnegs, eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
9526 cCE(fsqrts, eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
9527
9528 /* Dyadic operations. */
8f06b2d8
PB
9529 cCE(fadds, e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
9530 cCE(fsubs, e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
9531 cCE(fmuls, e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
9532 cCE(fdivs, e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
9533 cCE(fmacs, e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
9534 cCE(fmscs, e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
9535 cCE(fnmuls, e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
9536 cCE(fnmacs, e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
9537 cCE(fnmscs, e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 9538
c19d1205 9539 /* Comparisons. */
8f06b2d8
PB
9540 cCE(fcmps, eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
9541 cCE(fcmpzs, eb50a40, 1, (RVS), vfp_sp_compare_z),
9542 cCE(fcmpes, eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
9543 cCE(fcmpezs, eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 9544
c19d1205
ZW
9545#undef ARM_VARIANT
9546#define ARM_VARIANT FPU_VFP_EXT_V1 /* VFP V1 (Double precision). */
9547 /* Moves and type conversions. */
8f06b2d8
PB
9548 cCE(fcpyd, eb00b40, 2, (RVD, RVD), rd_rm),
9549 cCE(fcvtds, eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
9550 cCE(fcvtsd, eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
9551 cCE(fmdhr, e200b10, 2, (RVD, RR), rn_rd),
9552 cCE(fmdlr, e000b10, 2, (RVD, RR), rn_rd),
9553 cCE(fmrdh, e300b10, 2, (RR, RVD), rd_rn),
9554 cCE(fmrdl, e100b10, 2, (RR, RVD), rd_rn),
9555 cCE(fsitod, eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
9556 cCE(fuitod, eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
9557 cCE(ftosid, ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
9558 cCE(ftosizd, ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
9559 cCE(ftouid, ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
9560 cCE(ftouizd, ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205
ZW
9561
9562 /* Memory operations. */
8f06b2d8
PB
9563 cCE(fldd, d100b00, 2, (RVD, ADDR), vfp_dp_ldst),
9564 cCE(fstd, d000b00, 2, (RVD, ADDR), vfp_dp_ldst),
9565 cCE(fldmiad, c900b00, 2, (RRw, VRDLST), vfp_dp_ldstmia),
9566 cCE(fldmfdd, c900b00, 2, (RRw, VRDLST), vfp_dp_ldstmia),
9567 cCE(fldmdbd, d300b00, 2, (RRw, VRDLST), vfp_dp_ldstmdb),
9568 cCE(fldmead, d300b00, 2, (RRw, VRDLST), vfp_dp_ldstmdb),
9569 cCE(fstmiad, c800b00, 2, (RRw, VRDLST), vfp_dp_ldstmia),
9570 cCE(fstmead, c800b00, 2, (RRw, VRDLST), vfp_dp_ldstmia),
9571 cCE(fstmdbd, d200b00, 2, (RRw, VRDLST), vfp_dp_ldstmdb),
9572 cCE(fstmfdd, d200b00, 2, (RRw, VRDLST), vfp_dp_ldstmdb),
b99bd4ef 9573
c19d1205 9574 /* Monadic operations. */
8f06b2d8
PB
9575 cCE(fabsd, eb00bc0, 2, (RVD, RVD), rd_rm),
9576 cCE(fnegd, eb10b40, 2, (RVD, RVD), rd_rm),
9577 cCE(fsqrtd, eb10bc0, 2, (RVD, RVD), rd_rm),
c19d1205
ZW
9578
9579 /* Dyadic operations. */
8f06b2d8
PB
9580 cCE(faddd, e300b00, 3, (RVD, RVD, RVD), rd_rn_rm),
9581 cCE(fsubd, e300b40, 3, (RVD, RVD, RVD), rd_rn_rm),
9582 cCE(fmuld, e200b00, 3, (RVD, RVD, RVD), rd_rn_rm),
9583 cCE(fdivd, e800b00, 3, (RVD, RVD, RVD), rd_rn_rm),
9584 cCE(fmacd, e000b00, 3, (RVD, RVD, RVD), rd_rn_rm),
9585 cCE(fmscd, e100b00, 3, (RVD, RVD, RVD), rd_rn_rm),
9586 cCE(fnmuld, e200b40, 3, (RVD, RVD, RVD), rd_rn_rm),
9587 cCE(fnmacd, e000b40, 3, (RVD, RVD, RVD), rd_rn_rm),
9588 cCE(fnmscd, e100b40, 3, (RVD, RVD, RVD), rd_rn_rm),
b99bd4ef 9589
c19d1205 9590 /* Comparisons. */
8f06b2d8
PB
9591 cCE(fcmpd, eb40b40, 2, (RVD, RVD), rd_rm),
9592 cCE(fcmpzd, eb50b40, 1, (RVD), rd),
9593 cCE(fcmped, eb40bc0, 2, (RVD, RVD), rd_rm),
9594 cCE(fcmpezd, eb50bc0, 1, (RVD), rd),
c19d1205
ZW
9595
9596#undef ARM_VARIANT
9597#define ARM_VARIANT FPU_VFP_EXT_V2
8f06b2d8
PB
9598 cCE(fmsrr, c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
9599 cCE(fmrrs, c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
9600 cCE(fmdrr, c400b10, 3, (RVD, RR, RR), rm_rd_rn),
9601 cCE(fmrrd, c500b10, 3, (RR, RR, RVD), rd_rn_rm),
c19d1205
ZW
9602
9603#undef ARM_VARIANT
9604#define ARM_VARIANT ARM_CEXT_XSCALE /* Intel XScale extensions. */
8f06b2d8
PB
9605 cCE(mia, e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
9606 cCE(miaph, e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
9607 cCE(miabb, e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
9608 cCE(miabt, e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
9609 cCE(miatb, e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
9610 cCE(miatt, e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
9611 cCE(mar, c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
9612 cCE(mra, c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205
ZW
9613
9614#undef ARM_VARIANT
9615#define ARM_VARIANT ARM_CEXT_IWMMXT /* Intel Wireless MMX technology. */
8f06b2d8
PB
9616 cCE(tandcb, e13f130, 1, (RR), iwmmxt_tandorc),
9617 cCE(tandch, e53f130, 1, (RR), iwmmxt_tandorc),
9618 cCE(tandcw, e93f130, 1, (RR), iwmmxt_tandorc),
9619 cCE(tbcstb, e400010, 2, (RIWR, RR), rn_rd),
9620 cCE(tbcsth, e400050, 2, (RIWR, RR), rn_rd),
9621 cCE(tbcstw, e400090, 2, (RIWR, RR), rn_rd),
9622 cCE(textrcb, e130170, 2, (RR, I7), iwmmxt_textrc),
9623 cCE(textrch, e530170, 2, (RR, I7), iwmmxt_textrc),
9624 cCE(textrcw, e930170, 2, (RR, I7), iwmmxt_textrc),
9625 cCE(textrmub, e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
9626 cCE(textrmuh, e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
9627 cCE(textrmuw, e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
9628 cCE(textrmsb, e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
9629 cCE(textrmsh, e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
9630 cCE(textrmsw, e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
9631 cCE(tinsrb, e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
9632 cCE(tinsrh, e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
9633 cCE(tinsrw, e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
9634 cCE(tmcr, e000110, 2, (RIWC, RR), rn_rd),
9635 cCE(tmcrr, c400000, 3, (RIWR, RR, RR), rm_rd_rn),
9636 cCE(tmia, e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
9637 cCE(tmiaph, e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
9638 cCE(tmiabb, e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
9639 cCE(tmiabt, e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
9640 cCE(tmiatb, e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
9641 cCE(tmiatt, e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
9642 cCE(tmovmskb, e100030, 2, (RR, RIWR), rd_rn),
9643 cCE(tmovmskh, e500030, 2, (RR, RIWR), rd_rn),
9644 cCE(tmovmskw, e900030, 2, (RR, RIWR), rd_rn),
9645 cCE(tmrc, e100110, 2, (RR, RIWC), rd_rn),
9646 cCE(tmrrc, c500000, 3, (RR, RR, RIWR), rd_rn_rm),
9647 cCE(torcb, e13f150, 1, (RR), iwmmxt_tandorc),
9648 cCE(torch, e53f150, 1, (RR), iwmmxt_tandorc),
9649 cCE(torcw, e93f150, 1, (RR), iwmmxt_tandorc),
9650 cCE(waccb, e0001c0, 2, (RIWR, RIWR), rd_rn),
9651 cCE(wacch, e4001c0, 2, (RIWR, RIWR), rd_rn),
9652 cCE(waccw, e8001c0, 2, (RIWR, RIWR), rd_rn),
9653 cCE(waddbss, e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9654 cCE(waddb, e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9655 cCE(waddbus, e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9656 cCE(waddhss, e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9657 cCE(waddh, e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9658 cCE(waddhus, e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9659 cCE(waddwss, eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9660 cCE(waddw, e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9661 cCE(waddwus, e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9662 cCE(waligni, e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
9663 cCE(walignr0, e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9664 cCE(walignr1, e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9665 cCE(walignr2, ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9666 cCE(walignr3, eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9667 cCE(wand, e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9668 cCE(wandn, e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9669 cCE(wavg2b, e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9670 cCE(wavg2br, e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9671 cCE(wavg2h, ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9672 cCE(wavg2hr, ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9673 cCE(wcmpeqb, e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9674 cCE(wcmpeqh, e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9675 cCE(wcmpeqw, e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9676 cCE(wcmpgtub, e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9677 cCE(wcmpgtuh, e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9678 cCE(wcmpgtuw, e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9679 cCE(wcmpgtsb, e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9680 cCE(wcmpgtsh, e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9681 cCE(wcmpgtsw, eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9682 cCE(wldrb, c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
9683 cCE(wldrh, c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
9684 cCE(wldrw, c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
9685 cCE(wldrd, c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
9686 cCE(wmacs, e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9687 cCE(wmacsz, e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9688 cCE(wmacu, e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9689 cCE(wmacuz, e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9690 cCE(wmadds, ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9691 cCE(wmaddu, e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9692 cCE(wmaxsb, e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9693 cCE(wmaxsh, e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9694 cCE(wmaxsw, ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9695 cCE(wmaxub, e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9696 cCE(wmaxuh, e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9697 cCE(wmaxuw, e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9698 cCE(wminsb, e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9699 cCE(wminsh, e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9700 cCE(wminsw, eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9701 cCE(wminub, e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9702 cCE(wminuh, e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9703 cCE(wminuw, e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9704 cCE(wmov, e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
9705 cCE(wmulsm, e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9706 cCE(wmulsl, e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9707 cCE(wmulum, e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9708 cCE(wmulul, e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9709 cCE(wor, e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9710 cCE(wpackhss, e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9711 cCE(wpackhus, e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9712 cCE(wpackwss, eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9713 cCE(wpackwus, e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9714 cCE(wpackdss, ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9715 cCE(wpackdus, ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9716 cCE(wrorh, e700040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9717 cCE(wrorhg, e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9718 cCE(wrorw, eb00040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9719 cCE(wrorwg, eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9720 cCE(wrord, ef00040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9721 cCE(wrordg, ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9722 cCE(wsadb, e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9723 cCE(wsadbz, e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9724 cCE(wsadh, e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9725 cCE(wsadhz, e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9726 cCE(wshufh, e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
9727 cCE(wsllh, e500040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9728 cCE(wsllhg, e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9729 cCE(wsllw, e900040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9730 cCE(wsllwg, e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9731 cCE(wslld, ed00040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9732 cCE(wslldg, ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9733 cCE(wsrah, e400040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9734 cCE(wsrahg, e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9735 cCE(wsraw, e800040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9736 cCE(wsrawg, e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9737 cCE(wsrad, ec00040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9738 cCE(wsradg, ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9739 cCE(wsrlh, e600040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9740 cCE(wsrlhg, e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9741 cCE(wsrlw, ea00040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9742 cCE(wsrlwg, ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9743 cCE(wsrld, ee00040, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9744 cCE(wsrldg, ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
9745 cCE(wstrb, c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
9746 cCE(wstrh, c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
9747 cCE(wstrw, c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
9748 cCE(wstrd, c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
9749 cCE(wsubbss, e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9750 cCE(wsubb, e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9751 cCE(wsubbus, e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9752 cCE(wsubhss, e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9753 cCE(wsubh, e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9754 cCE(wsubhus, e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9755 cCE(wsubwss, eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9756 cCE(wsubw, e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9757 cCE(wsubwus, e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9758 cCE(wunpckehub,e0000c0, 2, (RIWR, RIWR), rd_rn),
9759 cCE(wunpckehuh,e4000c0, 2, (RIWR, RIWR), rd_rn),
9760 cCE(wunpckehuw,e8000c0, 2, (RIWR, RIWR), rd_rn),
9761 cCE(wunpckehsb,e2000c0, 2, (RIWR, RIWR), rd_rn),
9762 cCE(wunpckehsh,e6000c0, 2, (RIWR, RIWR), rd_rn),
9763 cCE(wunpckehsw,ea000c0, 2, (RIWR, RIWR), rd_rn),
9764 cCE(wunpckihb, e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9765 cCE(wunpckihh, e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9766 cCE(wunpckihw, e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9767 cCE(wunpckelub,e0000e0, 2, (RIWR, RIWR), rd_rn),
9768 cCE(wunpckeluh,e4000e0, 2, (RIWR, RIWR), rd_rn),
9769 cCE(wunpckeluw,e8000e0, 2, (RIWR, RIWR), rd_rn),
9770 cCE(wunpckelsb,e2000e0, 2, (RIWR, RIWR), rd_rn),
9771 cCE(wunpckelsh,e6000e0, 2, (RIWR, RIWR), rd_rn),
9772 cCE(wunpckelsw,ea000e0, 2, (RIWR, RIWR), rd_rn),
9773 cCE(wunpckilb, e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9774 cCE(wunpckilh, e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9775 cCE(wunpckilw, e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9776 cCE(wxor, e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
9777 cCE(wzero, e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205
ZW
9778
9779#undef ARM_VARIANT
9780#define ARM_VARIANT ARM_CEXT_MAVERICK /* Cirrus Maverick instructions. */
8f06b2d8
PB
9781 cCE(cfldrs, c100400, 2, (RMF, ADDR), rd_cpaddr),
9782 cCE(cfldrd, c500400, 2, (RMD, ADDR), rd_cpaddr),
9783 cCE(cfldr32, c100500, 2, (RMFX, ADDR), rd_cpaddr),
9784 cCE(cfldr64, c500500, 2, (RMDX, ADDR), rd_cpaddr),
9785 cCE(cfstrs, c000400, 2, (RMF, ADDR), rd_cpaddr),
9786 cCE(cfstrd, c400400, 2, (RMD, ADDR), rd_cpaddr),
9787 cCE(cfstr32, c000500, 2, (RMFX, ADDR), rd_cpaddr),
9788 cCE(cfstr64, c400500, 2, (RMDX, ADDR), rd_cpaddr),
9789 cCE(cfmvsr, e000450, 2, (RMF, RR), rn_rd),
9790 cCE(cfmvrs, e100450, 2, (RR, RMF), rd_rn),
9791 cCE(cfmvdlr, e000410, 2, (RMD, RR), rn_rd),
9792 cCE(cfmvrdl, e100410, 2, (RR, RMD), rd_rn),
9793 cCE(cfmvdhr, e000430, 2, (RMD, RR), rn_rd),
9794 cCE(cfmvrdh, e100430, 2, (RR, RMD), rd_rn),
9795 cCE(cfmv64lr, e000510, 2, (RMDX, RR), rn_rd),
9796 cCE(cfmvr64l, e100510, 2, (RR, RMDX), rd_rn),
9797 cCE(cfmv64hr, e000530, 2, (RMDX, RR), rn_rd),
9798 cCE(cfmvr64h, e100530, 2, (RR, RMDX), rd_rn),
9799 cCE(cfmval32, e200440, 2, (RMAX, RMFX), rd_rn),
9800 cCE(cfmv32al, e100440, 2, (RMFX, RMAX), rd_rn),
9801 cCE(cfmvam32, e200460, 2, (RMAX, RMFX), rd_rn),
9802 cCE(cfmv32am, e100460, 2, (RMFX, RMAX), rd_rn),
9803 cCE(cfmvah32, e200480, 2, (RMAX, RMFX), rd_rn),
9804 cCE(cfmv32ah, e100480, 2, (RMFX, RMAX), rd_rn),
9805 cCE(cfmva32, e2004a0, 2, (RMAX, RMFX), rd_rn),
9806 cCE(cfmv32a, e1004a0, 2, (RMFX, RMAX), rd_rn),
9807 cCE(cfmva64, e2004c0, 2, (RMAX, RMDX), rd_rn),
9808 cCE(cfmv64a, e1004c0, 2, (RMDX, RMAX), rd_rn),
9809 cCE(cfmvsc32, e2004e0, 2, (RMDS, RMDX), mav_dspsc),
9810 cCE(cfmv32sc, e1004e0, 2, (RMDX, RMDS), rd),
9811 cCE(cfcpys, e000400, 2, (RMF, RMF), rd_rn),
9812 cCE(cfcpyd, e000420, 2, (RMD, RMD), rd_rn),
9813 cCE(cfcvtsd, e000460, 2, (RMD, RMF), rd_rn),
9814 cCE(cfcvtds, e000440, 2, (RMF, RMD), rd_rn),
9815 cCE(cfcvt32s, e000480, 2, (RMF, RMFX), rd_rn),
9816 cCE(cfcvt32d, e0004a0, 2, (RMD, RMFX), rd_rn),
9817 cCE(cfcvt64s, e0004c0, 2, (RMF, RMDX), rd_rn),
9818 cCE(cfcvt64d, e0004e0, 2, (RMD, RMDX), rd_rn),
9819 cCE(cfcvts32, e100580, 2, (RMFX, RMF), rd_rn),
9820 cCE(cfcvtd32, e1005a0, 2, (RMFX, RMD), rd_rn),
9821 cCE(cftruncs32,e1005c0, 2, (RMFX, RMF), rd_rn),
9822 cCE(cftruncd32,e1005e0, 2, (RMFX, RMD), rd_rn),
9823 cCE(cfrshl32, e000550, 3, (RMFX, RMFX, RR), mav_triple),
9824 cCE(cfrshl64, e000570, 3, (RMDX, RMDX, RR), mav_triple),
9825 cCE(cfsh32, e000500, 3, (RMFX, RMFX, I63s), mav_shift),
9826 cCE(cfsh64, e200500, 3, (RMDX, RMDX, I63s), mav_shift),
9827 cCE(cfcmps, e100490, 3, (RR, RMF, RMF), rd_rn_rm),
9828 cCE(cfcmpd, e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
9829 cCE(cfcmp32, e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
9830 cCE(cfcmp64, e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
9831 cCE(cfabss, e300400, 2, (RMF, RMF), rd_rn),
9832 cCE(cfabsd, e300420, 2, (RMD, RMD), rd_rn),
9833 cCE(cfnegs, e300440, 2, (RMF, RMF), rd_rn),
9834 cCE(cfnegd, e300460, 2, (RMD, RMD), rd_rn),
9835 cCE(cfadds, e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
9836 cCE(cfaddd, e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
9837 cCE(cfsubs, e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
9838 cCE(cfsubd, e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
9839 cCE(cfmuls, e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
9840 cCE(cfmuld, e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
9841 cCE(cfabs32, e300500, 2, (RMFX, RMFX), rd_rn),
9842 cCE(cfabs64, e300520, 2, (RMDX, RMDX), rd_rn),
9843 cCE(cfneg32, e300540, 2, (RMFX, RMFX), rd_rn),
9844 cCE(cfneg64, e300560, 2, (RMDX, RMDX), rd_rn),
9845 cCE(cfadd32, e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
9846 cCE(cfadd64, e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
9847 cCE(cfsub32, e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
9848 cCE(cfsub64, e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
9849 cCE(cfmul32, e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
9850 cCE(cfmul64, e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
9851 cCE(cfmac32, e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
9852 cCE(cfmsc32, e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
9853 cCE(cfmadd32, e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
9854 cCE(cfmsub32, e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
9855 cCE(cfmadda32, e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
9856 cCE(cfmsuba32, e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
c19d1205
ZW
9857};
9858#undef ARM_VARIANT
9859#undef THUMB_VARIANT
9860#undef TCE
9861#undef TCM
9862#undef TUE
9863#undef TUF
9864#undef TCC
8f06b2d8 9865#undef cCE
e3cb604e
PB
9866#undef cCL
9867#undef C3E
c19d1205
ZW
9868#undef CE
9869#undef CM
9870#undef UE
9871#undef UF
9872#undef UT
9873#undef OPS0
9874#undef OPS1
9875#undef OPS2
9876#undef OPS3
9877#undef OPS4
9878#undef OPS5
9879#undef OPS6
9880#undef do_0
9881\f
9882/* MD interface: bits in the object file. */
bfae80f2 9883
c19d1205
ZW
9884/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
9885 for use in the a.out file, and stores them in the array pointed to by buf.
9886 This knows about the endian-ness of the target machine and does
9887 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
9888 2 (short) and 4 (long) Floating numbers are put out as a series of
9889 LITTLENUMS (shorts, here at least). */
b99bd4ef 9890
c19d1205
ZW
9891void
9892md_number_to_chars (char * buf, valueT val, int n)
9893{
9894 if (target_big_endian)
9895 number_to_chars_bigendian (buf, val, n);
9896 else
9897 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
9898}
9899
c19d1205
ZW
9900static valueT
9901md_chars_to_number (char * buf, int n)
bfae80f2 9902{
c19d1205
ZW
9903 valueT result = 0;
9904 unsigned char * where = (unsigned char *) buf;
bfae80f2 9905
c19d1205 9906 if (target_big_endian)
b99bd4ef 9907 {
c19d1205
ZW
9908 while (n--)
9909 {
9910 result <<= 8;
9911 result |= (*where++ & 255);
9912 }
b99bd4ef 9913 }
c19d1205 9914 else
b99bd4ef 9915 {
c19d1205
ZW
9916 while (n--)
9917 {
9918 result <<= 8;
9919 result |= (where[n] & 255);
9920 }
bfae80f2 9921 }
b99bd4ef 9922
c19d1205 9923 return result;
bfae80f2 9924}
b99bd4ef 9925
c19d1205 9926/* MD interface: Sections. */
b99bd4ef 9927
0110f2b8
PB
9928/* Estimate the size of a frag before relaxing. Assume everything fits in
9929 2 bytes. */
9930
c19d1205 9931int
0110f2b8 9932md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
9933 segT segtype ATTRIBUTE_UNUSED)
9934{
0110f2b8
PB
9935 fragp->fr_var = 2;
9936 return 2;
9937}
9938
9939/* Convert a machine dependent frag. */
9940
9941void
9942md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
9943{
9944 unsigned long insn;
9945 unsigned long old_op;
9946 char *buf;
9947 expressionS exp;
9948 fixS *fixp;
9949 int reloc_type;
9950 int pc_rel;
9951 int opcode;
9952
9953 buf = fragp->fr_literal + fragp->fr_fix;
9954
9955 old_op = bfd_get_16(abfd, buf);
9956 if (fragp->fr_symbol) {
9957 exp.X_op = O_symbol;
9958 exp.X_add_symbol = fragp->fr_symbol;
9959 } else {
9960 exp.X_op = O_constant;
9961 }
9962 exp.X_add_number = fragp->fr_offset;
9963 opcode = fragp->fr_subtype;
9964 switch (opcode)
9965 {
9966 case T_MNEM_ldr_pc:
9967 case T_MNEM_ldr_pc2:
9968 case T_MNEM_ldr_sp:
9969 case T_MNEM_str_sp:
9970 case T_MNEM_ldr:
9971 case T_MNEM_ldrb:
9972 case T_MNEM_ldrh:
9973 case T_MNEM_str:
9974 case T_MNEM_strb:
9975 case T_MNEM_strh:
9976 if (fragp->fr_var == 4)
9977 {
9978 insn = THUMB_OP32(opcode);
9979 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
9980 {
9981 insn |= (old_op & 0x700) << 4;
9982 }
9983 else
9984 {
9985 insn |= (old_op & 7) << 12;
9986 insn |= (old_op & 0x38) << 13;
9987 }
9988 insn |= 0x00000c00;
9989 put_thumb32_insn (buf, insn);
9990 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
9991 }
9992 else
9993 {
9994 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
9995 }
9996 pc_rel = (opcode == T_MNEM_ldr_pc2);
9997 break;
9998 case T_MNEM_adr:
9999 if (fragp->fr_var == 4)
10000 {
10001 insn = THUMB_OP32 (opcode);
10002 insn |= (old_op & 0xf0) << 4;
10003 put_thumb32_insn (buf, insn);
10004 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
10005 }
10006 else
10007 {
10008 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
10009 exp.X_add_number -= 4;
10010 }
10011 pc_rel = 1;
10012 break;
10013 case T_MNEM_mov:
10014 case T_MNEM_movs:
10015 case T_MNEM_cmp:
10016 case T_MNEM_cmn:
10017 if (fragp->fr_var == 4)
10018 {
10019 int r0off = (opcode == T_MNEM_mov
10020 || opcode == T_MNEM_movs) ? 0 : 8;
10021 insn = THUMB_OP32 (opcode);
10022 insn = (insn & 0xe1ffffff) | 0x10000000;
10023 insn |= (old_op & 0x700) << r0off;
10024 put_thumb32_insn (buf, insn);
10025 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
10026 }
10027 else
10028 {
10029 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
10030 }
10031 pc_rel = 0;
10032 break;
10033 case T_MNEM_b:
10034 if (fragp->fr_var == 4)
10035 {
10036 insn = THUMB_OP32(opcode);
10037 put_thumb32_insn (buf, insn);
10038 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
10039 }
10040 else
10041 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
10042 pc_rel = 1;
10043 break;
10044 case T_MNEM_bcond:
10045 if (fragp->fr_var == 4)
10046 {
10047 insn = THUMB_OP32(opcode);
10048 insn |= (old_op & 0xf00) << 14;
10049 put_thumb32_insn (buf, insn);
10050 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
10051 }
10052 else
10053 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
10054 pc_rel = 1;
10055 break;
10056 case T_MNEM_add_sp:
10057 case T_MNEM_add_pc:
10058 case T_MNEM_inc_sp:
10059 case T_MNEM_dec_sp:
10060 if (fragp->fr_var == 4)
10061 {
10062 /* ??? Choose between add and addw. */
10063 insn = THUMB_OP32 (opcode);
10064 insn |= (old_op & 0xf0) << 4;
10065 put_thumb32_insn (buf, insn);
10066 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
10067 }
10068 else
10069 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
10070 pc_rel = 0;
10071 break;
10072
10073 case T_MNEM_addi:
10074 case T_MNEM_addis:
10075 case T_MNEM_subi:
10076 case T_MNEM_subis:
10077 if (fragp->fr_var == 4)
10078 {
10079 insn = THUMB_OP32 (opcode);
10080 insn |= (old_op & 0xf0) << 4;
10081 insn |= (old_op & 0xf) << 16;
10082 put_thumb32_insn (buf, insn);
10083 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
10084 }
10085 else
10086 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
10087 pc_rel = 0;
10088 break;
10089 default:
10090 abort();
10091 }
10092 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
10093 reloc_type);
10094 fixp->fx_file = fragp->fr_file;
10095 fixp->fx_line = fragp->fr_line;
10096 fragp->fr_fix += fragp->fr_var;
10097}
10098
10099/* Return the size of a relaxable immediate operand instruction.
10100 SHIFT and SIZE specify the form of the allowable immediate. */
10101static int
10102relax_immediate (fragS *fragp, int size, int shift)
10103{
10104 offsetT offset;
10105 offsetT mask;
10106 offsetT low;
10107
10108 /* ??? Should be able to do better than this. */
10109 if (fragp->fr_symbol)
10110 return 4;
10111
10112 low = (1 << shift) - 1;
10113 mask = (1 << (shift + size)) - (1 << shift);
10114 offset = fragp->fr_offset;
10115 /* Force misaligned offsets to 32-bit variant. */
10116 if (offset & low)
10117 return -4;
10118 if (offset & ~mask)
10119 return 4;
10120 return 2;
10121}
10122
10123/* Return the size of a relaxable adr pseudo-instruction or PC-relative
10124 load. */
10125static int
10126relax_adr (fragS *fragp, asection *sec)
10127{
10128 addressT addr;
10129 offsetT val;
10130
10131 /* Assume worst case for symbols not known to be in the same section. */
10132 if (!S_IS_DEFINED(fragp->fr_symbol)
10133 || sec != S_GET_SEGMENT (fragp->fr_symbol))
10134 return 4;
10135
10136 val = S_GET_VALUE(fragp->fr_symbol) + fragp->fr_offset;
10137 addr = fragp->fr_address + fragp->fr_fix;
10138 addr = (addr + 4) & ~3;
10139 /* Fix the insn as the 4-byte version if the target address is not
10140 sufficiently aligned. This is prevents an infinite loop when two
10141 instructions have contradictory range/alignment requirements. */
10142 if (val & 3)
10143 return -4;
10144 val -= addr;
10145 if (val < 0 || val > 1020)
10146 return 4;
10147 return 2;
10148}
10149
10150/* Return the size of a relaxable add/sub immediate instruction. */
10151static int
10152relax_addsub (fragS *fragp, asection *sec)
10153{
10154 char *buf;
10155 int op;
10156
10157 buf = fragp->fr_literal + fragp->fr_fix;
10158 op = bfd_get_16(sec->owner, buf);
10159 if ((op & 0xf) == ((op >> 4) & 0xf))
10160 return relax_immediate (fragp, 8, 0);
10161 else
10162 return relax_immediate (fragp, 3, 0);
10163}
10164
10165
10166/* Return the size of a relaxable branch instruction. BITS is the
10167 size of the offset field in the narrow instruction. */
10168
10169static int
10170relax_branch (fragS *fragp, asection *sec, int bits)
10171{
10172 addressT addr;
10173 offsetT val;
10174 offsetT limit;
10175
10176 /* Assume worst case for symbols not known to be in the same section. */
10177 if (!S_IS_DEFINED(fragp->fr_symbol)
10178 || sec != S_GET_SEGMENT (fragp->fr_symbol))
10179 return 4;
10180
10181 val = S_GET_VALUE(fragp->fr_symbol) + fragp->fr_offset;
10182 addr = fragp->fr_address + fragp->fr_fix + 4;
10183 val -= addr;
10184
10185 /* Offset is a signed value *2 */
10186 limit = 1 << bits;
10187 if (val >= limit || val < -limit)
10188 return 4;
10189 return 2;
10190}
10191
10192
10193/* Relax a machine dependent frag. This returns the amount by which
10194 the current size of the frag should change. */
10195
10196int
10197arm_relax_frag (asection *sec, fragS *fragp, long stretch ATTRIBUTE_UNUSED)
10198{
10199 int oldsize;
10200 int newsize;
10201
10202 oldsize = fragp->fr_var;
10203 switch (fragp->fr_subtype)
10204 {
10205 case T_MNEM_ldr_pc2:
10206 newsize = relax_adr(fragp, sec);
10207 break;
10208 case T_MNEM_ldr_pc:
10209 case T_MNEM_ldr_sp:
10210 case T_MNEM_str_sp:
10211 newsize = relax_immediate(fragp, 8, 2);
10212 break;
10213 case T_MNEM_ldr:
10214 case T_MNEM_str:
10215 newsize = relax_immediate(fragp, 5, 2);
10216 break;
10217 case T_MNEM_ldrh:
10218 case T_MNEM_strh:
10219 newsize = relax_immediate(fragp, 5, 1);
10220 break;
10221 case T_MNEM_ldrb:
10222 case T_MNEM_strb:
10223 newsize = relax_immediate(fragp, 5, 0);
10224 break;
10225 case T_MNEM_adr:
10226 newsize = relax_adr(fragp, sec);
10227 break;
10228 case T_MNEM_mov:
10229 case T_MNEM_movs:
10230 case T_MNEM_cmp:
10231 case T_MNEM_cmn:
10232 newsize = relax_immediate(fragp, 8, 0);
10233 break;
10234 case T_MNEM_b:
10235 newsize = relax_branch(fragp, sec, 11);
10236 break;
10237 case T_MNEM_bcond:
10238 newsize = relax_branch(fragp, sec, 8);
10239 break;
10240 case T_MNEM_add_sp:
10241 case T_MNEM_add_pc:
10242 newsize = relax_immediate (fragp, 8, 2);
10243 break;
10244 case T_MNEM_inc_sp:
10245 case T_MNEM_dec_sp:
10246 newsize = relax_immediate (fragp, 7, 2);
10247 break;
10248 case T_MNEM_addi:
10249 case T_MNEM_addis:
10250 case T_MNEM_subi:
10251 case T_MNEM_subis:
10252 newsize = relax_addsub (fragp, sec);
10253 break;
10254 default:
10255 abort();
10256 }
10257 if (newsize < 0)
10258 {
10259 fragp->fr_var = -newsize;
10260 md_convert_frag (sec->owner, sec, fragp);
10261 frag_wane(fragp);
10262 return -(newsize + oldsize);
10263 }
10264 fragp->fr_var = newsize;
10265 return newsize - oldsize;
c19d1205 10266}
b99bd4ef 10267
c19d1205 10268/* Round up a section size to the appropriate boundary. */
b99bd4ef 10269
c19d1205
ZW
10270valueT
10271md_section_align (segT segment ATTRIBUTE_UNUSED,
10272 valueT size)
10273{
10274#ifdef OBJ_ELF
10275 return size;
10276#else
10277 /* Round all sects to multiple of 4. */
10278 return (size + 3) & ~3;
10279#endif
bfae80f2 10280}
b99bd4ef 10281
c19d1205
ZW
10282/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
10283 of an rs_align_code fragment. */
10284
10285void
10286arm_handle_align (fragS * fragP)
bfae80f2 10287{
c19d1205
ZW
10288 static char const arm_noop[4] = { 0x00, 0x00, 0xa0, 0xe1 };
10289 static char const thumb_noop[2] = { 0xc0, 0x46 };
10290 static char const arm_bigend_noop[4] = { 0xe1, 0xa0, 0x00, 0x00 };
10291 static char const thumb_bigend_noop[2] = { 0x46, 0xc0 };
10292
10293 int bytes, fix, noop_size;
10294 char * p;
10295 const char * noop;
bfae80f2 10296
c19d1205 10297 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
10298 return;
10299
c19d1205
ZW
10300 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
10301 p = fragP->fr_literal + fragP->fr_fix;
10302 fix = 0;
bfae80f2 10303
c19d1205
ZW
10304 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
10305 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 10306
c19d1205 10307 if (fragP->tc_frag_data)
a737bd4d 10308 {
c19d1205
ZW
10309 if (target_big_endian)
10310 noop = thumb_bigend_noop;
10311 else
10312 noop = thumb_noop;
10313 noop_size = sizeof (thumb_noop);
7ed4c4c5
NC
10314 }
10315 else
10316 {
c19d1205
ZW
10317 if (target_big_endian)
10318 noop = arm_bigend_noop;
10319 else
10320 noop = arm_noop;
10321 noop_size = sizeof (arm_noop);
7ed4c4c5 10322 }
a737bd4d 10323
c19d1205 10324 if (bytes & (noop_size - 1))
7ed4c4c5 10325 {
c19d1205
ZW
10326 fix = bytes & (noop_size - 1);
10327 memset (p, 0, fix);
10328 p += fix;
10329 bytes -= fix;
a737bd4d 10330 }
a737bd4d 10331
c19d1205 10332 while (bytes >= noop_size)
a737bd4d 10333 {
c19d1205
ZW
10334 memcpy (p, noop, noop_size);
10335 p += noop_size;
10336 bytes -= noop_size;
10337 fix += noop_size;
a737bd4d
NC
10338 }
10339
c19d1205
ZW
10340 fragP->fr_fix += fix;
10341 fragP->fr_var = noop_size;
a737bd4d
NC
10342}
10343
c19d1205
ZW
10344/* Called from md_do_align. Used to create an alignment
10345 frag in a code section. */
10346
10347void
10348arm_frag_align_code (int n, int max)
bfae80f2 10349{
c19d1205 10350 char * p;
7ed4c4c5 10351
c19d1205
ZW
10352 /* We assume that there will never be a requirement
10353 to support alignments greater than 32 bytes. */
10354 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
10355 as_fatal (_("alignments greater than 32 bytes not supported in .text sections."));
bfae80f2 10356
c19d1205
ZW
10357 p = frag_var (rs_align_code,
10358 MAX_MEM_FOR_RS_ALIGN_CODE,
10359 1,
10360 (relax_substateT) max,
10361 (symbolS *) NULL,
10362 (offsetT) n,
10363 (char *) NULL);
10364 *p = 0;
10365}
bfae80f2 10366
c19d1205 10367/* Perform target specific initialisation of a frag. */
bfae80f2 10368
c19d1205
ZW
10369void
10370arm_init_frag (fragS * fragP)
10371{
10372 /* Record whether this frag is in an ARM or a THUMB area. */
10373 fragP->tc_frag_data = thumb_mode;
bfae80f2
RE
10374}
10375
c19d1205
ZW
10376#ifdef OBJ_ELF
10377/* When we change sections we need to issue a new mapping symbol. */
10378
10379void
10380arm_elf_change_section (void)
bfae80f2 10381{
c19d1205
ZW
10382 flagword flags;
10383 segment_info_type *seginfo;
bfae80f2 10384
c19d1205
ZW
10385 /* Link an unlinked unwind index table section to the .text section. */
10386 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
10387 && elf_linked_to_section (now_seg) == NULL)
10388 elf_linked_to_section (now_seg) = text_section;
10389
10390 if (!SEG_NORMAL (now_seg))
bfae80f2
RE
10391 return;
10392
c19d1205
ZW
10393 flags = bfd_get_section_flags (stdoutput, now_seg);
10394
10395 /* We can ignore sections that only contain debug info. */
10396 if ((flags & SEC_ALLOC) == 0)
10397 return;
bfae80f2 10398
c19d1205
ZW
10399 seginfo = seg_info (now_seg);
10400 mapstate = seginfo->tc_segment_info_data.mapstate;
10401 marked_pr_dependency = seginfo->tc_segment_info_data.marked_pr_dependency;
bfae80f2
RE
10402}
10403
c19d1205
ZW
10404int
10405arm_elf_section_type (const char * str, size_t len)
e45d0630 10406{
c19d1205
ZW
10407 if (len == 5 && strncmp (str, "exidx", 5) == 0)
10408 return SHT_ARM_EXIDX;
e45d0630 10409
c19d1205
ZW
10410 return -1;
10411}
10412\f
10413/* Code to deal with unwinding tables. */
e45d0630 10414
c19d1205 10415static void add_unwind_adjustsp (offsetT);
e45d0630 10416
c19d1205 10417/* Cenerate and deferred unwind frame offset. */
e45d0630 10418
bfae80f2 10419static void
c19d1205 10420flush_pending_unwind (void)
bfae80f2 10421{
c19d1205 10422 offsetT offset;
bfae80f2 10423
c19d1205
ZW
10424 offset = unwind.pending_offset;
10425 unwind.pending_offset = 0;
10426 if (offset != 0)
10427 add_unwind_adjustsp (offset);
bfae80f2
RE
10428}
10429
c19d1205
ZW
10430/* Add an opcode to this list for this function. Two-byte opcodes should
10431 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
10432 order. */
10433
bfae80f2 10434static void
c19d1205 10435add_unwind_opcode (valueT op, int length)
bfae80f2 10436{
c19d1205
ZW
10437 /* Add any deferred stack adjustment. */
10438 if (unwind.pending_offset)
10439 flush_pending_unwind ();
bfae80f2 10440
c19d1205 10441 unwind.sp_restored = 0;
bfae80f2 10442
c19d1205 10443 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 10444 {
c19d1205
ZW
10445 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
10446 if (unwind.opcodes)
10447 unwind.opcodes = xrealloc (unwind.opcodes,
10448 unwind.opcode_alloc);
10449 else
10450 unwind.opcodes = xmalloc (unwind.opcode_alloc);
bfae80f2 10451 }
c19d1205 10452 while (length > 0)
bfae80f2 10453 {
c19d1205
ZW
10454 length--;
10455 unwind.opcodes[unwind.opcode_count] = op & 0xff;
10456 op >>= 8;
10457 unwind.opcode_count++;
bfae80f2 10458 }
bfae80f2
RE
10459}
10460
c19d1205
ZW
10461/* Add unwind opcodes to adjust the stack pointer. */
10462
bfae80f2 10463static void
c19d1205 10464add_unwind_adjustsp (offsetT offset)
bfae80f2 10465{
c19d1205 10466 valueT op;
bfae80f2 10467
c19d1205 10468 if (offset > 0x200)
bfae80f2 10469 {
c19d1205
ZW
10470 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
10471 char bytes[5];
10472 int n;
10473 valueT o;
bfae80f2 10474
c19d1205
ZW
10475 /* Long form: 0xb2, uleb128. */
10476 /* This might not fit in a word so add the individual bytes,
10477 remembering the list is built in reverse order. */
10478 o = (valueT) ((offset - 0x204) >> 2);
10479 if (o == 0)
10480 add_unwind_opcode (0, 1);
bfae80f2 10481
c19d1205
ZW
10482 /* Calculate the uleb128 encoding of the offset. */
10483 n = 0;
10484 while (o)
10485 {
10486 bytes[n] = o & 0x7f;
10487 o >>= 7;
10488 if (o)
10489 bytes[n] |= 0x80;
10490 n++;
10491 }
10492 /* Add the insn. */
10493 for (; n; n--)
10494 add_unwind_opcode (bytes[n - 1], 1);
10495 add_unwind_opcode (0xb2, 1);
10496 }
10497 else if (offset > 0x100)
bfae80f2 10498 {
c19d1205
ZW
10499 /* Two short opcodes. */
10500 add_unwind_opcode (0x3f, 1);
10501 op = (offset - 0x104) >> 2;
10502 add_unwind_opcode (op, 1);
bfae80f2 10503 }
c19d1205
ZW
10504 else if (offset > 0)
10505 {
10506 /* Short opcode. */
10507 op = (offset - 4) >> 2;
10508 add_unwind_opcode (op, 1);
10509 }
10510 else if (offset < 0)
bfae80f2 10511 {
c19d1205
ZW
10512 offset = -offset;
10513 while (offset > 0x100)
bfae80f2 10514 {
c19d1205
ZW
10515 add_unwind_opcode (0x7f, 1);
10516 offset -= 0x100;
bfae80f2 10517 }
c19d1205
ZW
10518 op = ((offset - 4) >> 2) | 0x40;
10519 add_unwind_opcode (op, 1);
bfae80f2 10520 }
bfae80f2
RE
10521}
10522
c19d1205
ZW
10523/* Finish the list of unwind opcodes for this function. */
10524static void
10525finish_unwind_opcodes (void)
bfae80f2 10526{
c19d1205 10527 valueT op;
bfae80f2 10528
c19d1205 10529 if (unwind.fp_used)
bfae80f2 10530 {
c19d1205
ZW
10531 /* Adjust sp as neccessary. */
10532 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
10533 flush_pending_unwind ();
bfae80f2 10534
c19d1205
ZW
10535 /* After restoring sp from the frame pointer. */
10536 op = 0x90 | unwind.fp_reg;
10537 add_unwind_opcode (op, 1);
10538 }
10539 else
10540 flush_pending_unwind ();
bfae80f2
RE
10541}
10542
bfae80f2 10543
c19d1205
ZW
10544/* Start an exception table entry. If idx is nonzero this is an index table
10545 entry. */
bfae80f2
RE
10546
10547static void
c19d1205 10548start_unwind_section (const segT text_seg, int idx)
bfae80f2 10549{
c19d1205
ZW
10550 const char * text_name;
10551 const char * prefix;
10552 const char * prefix_once;
10553 const char * group_name;
10554 size_t prefix_len;
10555 size_t text_len;
10556 char * sec_name;
10557 size_t sec_name_len;
10558 int type;
10559 int flags;
10560 int linkonce;
bfae80f2 10561
c19d1205 10562 if (idx)
bfae80f2 10563 {
c19d1205
ZW
10564 prefix = ELF_STRING_ARM_unwind;
10565 prefix_once = ELF_STRING_ARM_unwind_once;
10566 type = SHT_ARM_EXIDX;
bfae80f2 10567 }
c19d1205 10568 else
bfae80f2 10569 {
c19d1205
ZW
10570 prefix = ELF_STRING_ARM_unwind_info;
10571 prefix_once = ELF_STRING_ARM_unwind_info_once;
10572 type = SHT_PROGBITS;
bfae80f2
RE
10573 }
10574
c19d1205
ZW
10575 text_name = segment_name (text_seg);
10576 if (streq (text_name, ".text"))
10577 text_name = "";
10578
10579 if (strncmp (text_name, ".gnu.linkonce.t.",
10580 strlen (".gnu.linkonce.t.")) == 0)
bfae80f2 10581 {
c19d1205
ZW
10582 prefix = prefix_once;
10583 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
10584 }
10585
c19d1205
ZW
10586 prefix_len = strlen (prefix);
10587 text_len = strlen (text_name);
10588 sec_name_len = prefix_len + text_len;
10589 sec_name = xmalloc (sec_name_len + 1);
10590 memcpy (sec_name, prefix, prefix_len);
10591 memcpy (sec_name + prefix_len, text_name, text_len);
10592 sec_name[prefix_len + text_len] = '\0';
bfae80f2 10593
c19d1205
ZW
10594 flags = SHF_ALLOC;
10595 linkonce = 0;
10596 group_name = 0;
bfae80f2 10597
c19d1205
ZW
10598 /* Handle COMDAT group. */
10599 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 10600 {
c19d1205
ZW
10601 group_name = elf_group_name (text_seg);
10602 if (group_name == NULL)
10603 {
10604 as_bad ("Group section `%s' has no group signature",
10605 segment_name (text_seg));
10606 ignore_rest_of_line ();
10607 return;
10608 }
10609 flags |= SHF_GROUP;
10610 linkonce = 1;
bfae80f2
RE
10611 }
10612
c19d1205 10613 obj_elf_change_section (sec_name, type, flags, 0, group_name, linkonce, 0);
bfae80f2 10614
c19d1205
ZW
10615 /* Set the setion link for index tables. */
10616 if (idx)
10617 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
10618}
10619
bfae80f2 10620
c19d1205
ZW
10621/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
10622 personality routine data. Returns zero, or the index table value for
10623 and inline entry. */
10624
10625static valueT
10626create_unwind_entry (int have_data)
bfae80f2 10627{
c19d1205
ZW
10628 int size;
10629 addressT where;
10630 char *ptr;
10631 /* The current word of data. */
10632 valueT data;
10633 /* The number of bytes left in this word. */
10634 int n;
bfae80f2 10635
c19d1205 10636 finish_unwind_opcodes ();
bfae80f2 10637
c19d1205
ZW
10638 /* Remember the current text section. */
10639 unwind.saved_seg = now_seg;
10640 unwind.saved_subseg = now_subseg;
bfae80f2 10641
c19d1205 10642 start_unwind_section (now_seg, 0);
bfae80f2 10643
c19d1205 10644 if (unwind.personality_routine == NULL)
bfae80f2 10645 {
c19d1205
ZW
10646 if (unwind.personality_index == -2)
10647 {
10648 if (have_data)
10649 as_bad (_("handerdata in cantunwind frame"));
10650 return 1; /* EXIDX_CANTUNWIND. */
10651 }
bfae80f2 10652
c19d1205
ZW
10653 /* Use a default personality routine if none is specified. */
10654 if (unwind.personality_index == -1)
10655 {
10656 if (unwind.opcode_count > 3)
10657 unwind.personality_index = 1;
10658 else
10659 unwind.personality_index = 0;
10660 }
bfae80f2 10661
c19d1205
ZW
10662 /* Space for the personality routine entry. */
10663 if (unwind.personality_index == 0)
10664 {
10665 if (unwind.opcode_count > 3)
10666 as_bad (_("too many unwind opcodes for personality routine 0"));
bfae80f2 10667
c19d1205
ZW
10668 if (!have_data)
10669 {
10670 /* All the data is inline in the index table. */
10671 data = 0x80;
10672 n = 3;
10673 while (unwind.opcode_count > 0)
10674 {
10675 unwind.opcode_count--;
10676 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
10677 n--;
10678 }
bfae80f2 10679
c19d1205
ZW
10680 /* Pad with "finish" opcodes. */
10681 while (n--)
10682 data = (data << 8) | 0xb0;
bfae80f2 10683
c19d1205
ZW
10684 return data;
10685 }
10686 size = 0;
10687 }
10688 else
10689 /* We get two opcodes "free" in the first word. */
10690 size = unwind.opcode_count - 2;
10691 }
10692 else
10693 /* An extra byte is required for the opcode count. */
10694 size = unwind.opcode_count + 1;
bfae80f2 10695
c19d1205
ZW
10696 size = (size + 3) >> 2;
10697 if (size > 0xff)
10698 as_bad (_("too many unwind opcodes"));
bfae80f2 10699
c19d1205
ZW
10700 frag_align (2, 0, 0);
10701 record_alignment (now_seg, 2);
10702 unwind.table_entry = expr_build_dot ();
10703
10704 /* Allocate the table entry. */
10705 ptr = frag_more ((size << 2) + 4);
10706 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 10707
c19d1205 10708 switch (unwind.personality_index)
bfae80f2 10709 {
c19d1205
ZW
10710 case -1:
10711 /* ??? Should this be a PLT generating relocation? */
10712 /* Custom personality routine. */
10713 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
10714 BFD_RELOC_ARM_PREL31);
bfae80f2 10715
c19d1205
ZW
10716 where += 4;
10717 ptr += 4;
bfae80f2 10718
c19d1205
ZW
10719 /* Set the first byte to the number of additional words. */
10720 data = size - 1;
10721 n = 3;
10722 break;
bfae80f2 10723
c19d1205
ZW
10724 /* ABI defined personality routines. */
10725 case 0:
10726 /* Three opcodes bytes are packed into the first word. */
10727 data = 0x80;
10728 n = 3;
10729 break;
bfae80f2 10730
c19d1205
ZW
10731 case 1:
10732 case 2:
10733 /* The size and first two opcode bytes go in the first word. */
10734 data = ((0x80 + unwind.personality_index) << 8) | size;
10735 n = 2;
10736 break;
bfae80f2 10737
c19d1205
ZW
10738 default:
10739 /* Should never happen. */
10740 abort ();
10741 }
bfae80f2 10742
c19d1205
ZW
10743 /* Pack the opcodes into words (MSB first), reversing the list at the same
10744 time. */
10745 while (unwind.opcode_count > 0)
10746 {
10747 if (n == 0)
10748 {
10749 md_number_to_chars (ptr, data, 4);
10750 ptr += 4;
10751 n = 4;
10752 data = 0;
10753 }
10754 unwind.opcode_count--;
10755 n--;
10756 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
10757 }
10758
10759 /* Finish off the last word. */
10760 if (n < 4)
10761 {
10762 /* Pad with "finish" opcodes. */
10763 while (n--)
10764 data = (data << 8) | 0xb0;
10765
10766 md_number_to_chars (ptr, data, 4);
10767 }
10768
10769 if (!have_data)
10770 {
10771 /* Add an empty descriptor if there is no user-specified data. */
10772 ptr = frag_more (4);
10773 md_number_to_chars (ptr, 0, 4);
10774 }
10775
10776 return 0;
bfae80f2
RE
10777}
10778
c19d1205
ZW
10779/* Convert REGNAME to a DWARF-2 register number. */
10780
10781int
10782tc_arm_regname_to_dw2regnum (const char *regname)
bfae80f2 10783{
c19d1205
ZW
10784 int reg = arm_reg_parse ((char **) &regname, REG_TYPE_RN);
10785
10786 if (reg == FAIL)
10787 return -1;
10788
10789 return reg;
bfae80f2
RE
10790}
10791
c19d1205
ZW
10792/* Initialize the DWARF-2 unwind information for this procedure. */
10793
10794void
10795tc_arm_frame_initial_instructions (void)
bfae80f2 10796{
c19d1205 10797 cfi_add_CFA_def_cfa (REG_SP, 0);
bfae80f2 10798}
c19d1205 10799#endif /* OBJ_ELF */
bfae80f2 10800
bfae80f2 10801
c19d1205 10802/* MD interface: Symbol and relocation handling. */
bfae80f2 10803
2fc8bdac
ZW
10804/* Return the address within the segment that a PC-relative fixup is
10805 relative to. For ARM, PC-relative fixups applied to instructions
10806 are generally relative to the location of the fixup plus 8 bytes.
10807 Thumb branches are offset by 4, and Thumb loads relative to PC
10808 require special handling. */
bfae80f2 10809
c19d1205 10810long
2fc8bdac 10811md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 10812{
2fc8bdac
ZW
10813 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
10814
10815 /* If this is pc-relative and we are going to emit a relocation
10816 then we just want to put out any pipeline compensation that the linker
10817 will need. Otherwise we want to use the calculated base. */
10818 if (fixP->fx_pcrel
10819 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
10820 || arm_force_relocation (fixP)))
10821 base = 0;
bfae80f2 10822
c19d1205 10823 switch (fixP->fx_r_type)
bfae80f2 10824 {
2fc8bdac
ZW
10825 /* PC relative addressing on the Thumb is slightly odd as the
10826 bottom two bits of the PC are forced to zero for the
10827 calculation. This happens *after* application of the
10828 pipeline offset. However, Thumb adrl already adjusts for
10829 this, so we need not do it again. */
c19d1205 10830 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 10831 return base & ~3;
c19d1205
ZW
10832
10833 case BFD_RELOC_ARM_THUMB_OFFSET:
10834 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 10835 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 10836 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 10837 return (base + 4) & ~3;
c19d1205 10838
2fc8bdac
ZW
10839 /* Thumb branches are simply offset by +4. */
10840 case BFD_RELOC_THUMB_PCREL_BRANCH7:
10841 case BFD_RELOC_THUMB_PCREL_BRANCH9:
10842 case BFD_RELOC_THUMB_PCREL_BRANCH12:
10843 case BFD_RELOC_THUMB_PCREL_BRANCH20:
10844 case BFD_RELOC_THUMB_PCREL_BRANCH23:
10845 case BFD_RELOC_THUMB_PCREL_BRANCH25:
10846 case BFD_RELOC_THUMB_PCREL_BLX:
10847 return base + 4;
bfae80f2 10848
2fc8bdac
ZW
10849 /* ARM mode branches are offset by +8. However, the Windows CE
10850 loader expects the relocation not to take this into account. */
10851 case BFD_RELOC_ARM_PCREL_BRANCH:
10852 case BFD_RELOC_ARM_PCREL_BLX:
10853 case BFD_RELOC_ARM_PLT32:
c19d1205 10854#ifdef TE_WINCE
2fc8bdac 10855 return base;
c19d1205 10856#else
2fc8bdac 10857 return base + 8;
c19d1205 10858#endif
2fc8bdac
ZW
10859
10860 /* ARM mode loads relative to PC are also offset by +8. Unlike
10861 branches, the Windows CE loader *does* expect the relocation
10862 to take this into account. */
10863 case BFD_RELOC_ARM_OFFSET_IMM:
10864 case BFD_RELOC_ARM_OFFSET_IMM8:
10865 case BFD_RELOC_ARM_HWLITERAL:
10866 case BFD_RELOC_ARM_LITERAL:
10867 case BFD_RELOC_ARM_CP_OFF_IMM:
10868 return base + 8;
10869
10870
10871 /* Other PC-relative relocations are un-offset. */
10872 default:
10873 return base;
10874 }
bfae80f2
RE
10875}
10876
c19d1205
ZW
10877/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
10878 Otherwise we have no need to default values of symbols. */
10879
10880symbolS *
10881md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
bfae80f2 10882{
c19d1205
ZW
10883#ifdef OBJ_ELF
10884 if (name[0] == '_' && name[1] == 'G'
10885 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
10886 {
10887 if (!GOT_symbol)
10888 {
10889 if (symbol_find (name))
10890 as_bad ("GOT already in the symbol table");
bfae80f2 10891
c19d1205
ZW
10892 GOT_symbol = symbol_new (name, undefined_section,
10893 (valueT) 0, & zero_address_frag);
10894 }
bfae80f2 10895
c19d1205 10896 return GOT_symbol;
bfae80f2 10897 }
c19d1205 10898#endif
bfae80f2 10899
c19d1205 10900 return 0;
bfae80f2
RE
10901}
10902
55cf6793 10903/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
10904 computed as two separate immediate values, added together. We
10905 already know that this value cannot be computed by just one ARM
10906 instruction. */
10907
10908static unsigned int
10909validate_immediate_twopart (unsigned int val,
10910 unsigned int * highpart)
bfae80f2 10911{
c19d1205
ZW
10912 unsigned int a;
10913 unsigned int i;
bfae80f2 10914
c19d1205
ZW
10915 for (i = 0; i < 32; i += 2)
10916 if (((a = rotate_left (val, i)) & 0xff) != 0)
10917 {
10918 if (a & 0xff00)
10919 {
10920 if (a & ~ 0xffff)
10921 continue;
10922 * highpart = (a >> 8) | ((i + 24) << 7);
10923 }
10924 else if (a & 0xff0000)
10925 {
10926 if (a & 0xff000000)
10927 continue;
10928 * highpart = (a >> 16) | ((i + 16) << 7);
10929 }
10930 else
10931 {
10932 assert (a & 0xff000000);
10933 * highpart = (a >> 24) | ((i + 8) << 7);
10934 }
bfae80f2 10935
c19d1205
ZW
10936 return (a & 0xff) | (i << 7);
10937 }
bfae80f2 10938
c19d1205 10939 return FAIL;
bfae80f2
RE
10940}
10941
c19d1205
ZW
10942static int
10943validate_offset_imm (unsigned int val, int hwse)
10944{
10945 if ((hwse && val > 255) || val > 4095)
10946 return FAIL;
10947 return val;
10948}
bfae80f2 10949
55cf6793 10950/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
10951 negative immediate constant by altering the instruction. A bit of
10952 a hack really.
10953 MOV <-> MVN
10954 AND <-> BIC
10955 ADC <-> SBC
10956 by inverting the second operand, and
10957 ADD <-> SUB
10958 CMP <-> CMN
10959 by negating the second operand. */
bfae80f2 10960
c19d1205
ZW
10961static int
10962negate_data_op (unsigned long * instruction,
10963 unsigned long value)
bfae80f2 10964{
c19d1205
ZW
10965 int op, new_inst;
10966 unsigned long negated, inverted;
bfae80f2 10967
c19d1205
ZW
10968 negated = encode_arm_immediate (-value);
10969 inverted = encode_arm_immediate (~value);
bfae80f2 10970
c19d1205
ZW
10971 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
10972 switch (op)
bfae80f2 10973 {
c19d1205
ZW
10974 /* First negates. */
10975 case OPCODE_SUB: /* ADD <-> SUB */
10976 new_inst = OPCODE_ADD;
10977 value = negated;
10978 break;
bfae80f2 10979
c19d1205
ZW
10980 case OPCODE_ADD:
10981 new_inst = OPCODE_SUB;
10982 value = negated;
10983 break;
bfae80f2 10984
c19d1205
ZW
10985 case OPCODE_CMP: /* CMP <-> CMN */
10986 new_inst = OPCODE_CMN;
10987 value = negated;
10988 break;
bfae80f2 10989
c19d1205
ZW
10990 case OPCODE_CMN:
10991 new_inst = OPCODE_CMP;
10992 value = negated;
10993 break;
bfae80f2 10994
c19d1205
ZW
10995 /* Now Inverted ops. */
10996 case OPCODE_MOV: /* MOV <-> MVN */
10997 new_inst = OPCODE_MVN;
10998 value = inverted;
10999 break;
bfae80f2 11000
c19d1205
ZW
11001 case OPCODE_MVN:
11002 new_inst = OPCODE_MOV;
11003 value = inverted;
11004 break;
bfae80f2 11005
c19d1205
ZW
11006 case OPCODE_AND: /* AND <-> BIC */
11007 new_inst = OPCODE_BIC;
11008 value = inverted;
11009 break;
bfae80f2 11010
c19d1205
ZW
11011 case OPCODE_BIC:
11012 new_inst = OPCODE_AND;
11013 value = inverted;
11014 break;
bfae80f2 11015
c19d1205
ZW
11016 case OPCODE_ADC: /* ADC <-> SBC */
11017 new_inst = OPCODE_SBC;
11018 value = inverted;
11019 break;
bfae80f2 11020
c19d1205
ZW
11021 case OPCODE_SBC:
11022 new_inst = OPCODE_ADC;
11023 value = inverted;
11024 break;
bfae80f2 11025
c19d1205
ZW
11026 /* We cannot do anything. */
11027 default:
11028 return FAIL;
b99bd4ef
NC
11029 }
11030
c19d1205
ZW
11031 if (value == (unsigned) FAIL)
11032 return FAIL;
11033
11034 *instruction &= OPCODE_MASK;
11035 *instruction |= new_inst << DATA_OP_SHIFT;
11036 return value;
b99bd4ef
NC
11037}
11038
8f06b2d8
PB
11039/* Read a 32-bit thumb instruction from buf. */
11040static unsigned long
11041get_thumb32_insn (char * buf)
11042{
11043 unsigned long insn;
11044 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
11045 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
11046
11047 return insn;
11048}
11049
c19d1205 11050void
55cf6793 11051md_apply_fix (fixS * fixP,
c19d1205
ZW
11052 valueT * valP,
11053 segT seg)
11054{
11055 offsetT value = * valP;
11056 offsetT newval;
11057 unsigned int newimm;
11058 unsigned long temp;
11059 int sign;
11060 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 11061
c19d1205 11062 assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 11063
c19d1205
ZW
11064 /* Note whether this will delete the relocation. */
11065 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
11066 fixP->fx_done = 1;
b99bd4ef 11067
adbaf948
ZW
11068 /* On a 64-bit host, silently truncate 'value' to 32 bits for
11069 consistency with the behavior on 32-bit hosts. Remember value
11070 for emit_reloc. */
11071 value &= 0xffffffff;
11072 value ^= 0x80000000;
11073 value -= 0x80000000;
11074
11075 *valP = value;
c19d1205 11076 fixP->fx_addnumber = value;
b99bd4ef 11077
adbaf948
ZW
11078 /* Same treatment for fixP->fx_offset. */
11079 fixP->fx_offset &= 0xffffffff;
11080 fixP->fx_offset ^= 0x80000000;
11081 fixP->fx_offset -= 0x80000000;
11082
c19d1205 11083 switch (fixP->fx_r_type)
b99bd4ef 11084 {
c19d1205
ZW
11085 case BFD_RELOC_NONE:
11086 /* This will need to go in the object file. */
11087 fixP->fx_done = 0;
11088 break;
b99bd4ef 11089
c19d1205
ZW
11090 case BFD_RELOC_ARM_IMMEDIATE:
11091 /* We claim that this fixup has been processed here,
11092 even if in fact we generate an error because we do
11093 not have a reloc for it, so tc_gen_reloc will reject it. */
11094 fixP->fx_done = 1;
b99bd4ef 11095
c19d1205
ZW
11096 if (fixP->fx_addsy
11097 && ! S_IS_DEFINED (fixP->fx_addsy))
b99bd4ef 11098 {
c19d1205
ZW
11099 as_bad_where (fixP->fx_file, fixP->fx_line,
11100 _("undefined symbol %s used as an immediate value"),
11101 S_GET_NAME (fixP->fx_addsy));
11102 break;
b99bd4ef
NC
11103 }
11104
c19d1205
ZW
11105 newimm = encode_arm_immediate (value);
11106 temp = md_chars_to_number (buf, INSN_SIZE);
11107
11108 /* If the instruction will fail, see if we can fix things up by
11109 changing the opcode. */
11110 if (newimm == (unsigned int) FAIL
11111 && (newimm = negate_data_op (&temp, value)) == (unsigned int) FAIL)
b99bd4ef 11112 {
c19d1205
ZW
11113 as_bad_where (fixP->fx_file, fixP->fx_line,
11114 _("invalid constant (%lx) after fixup"),
11115 (unsigned long) value);
11116 break;
b99bd4ef 11117 }
b99bd4ef 11118
c19d1205
ZW
11119 newimm |= (temp & 0xfffff000);
11120 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
11121 break;
b99bd4ef 11122
c19d1205
ZW
11123 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11124 {
11125 unsigned int highpart = 0;
11126 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 11127
c19d1205
ZW
11128 newimm = encode_arm_immediate (value);
11129 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 11130
c19d1205
ZW
11131 /* If the instruction will fail, see if we can fix things up by
11132 changing the opcode. */
11133 if (newimm == (unsigned int) FAIL
11134 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
11135 {
11136 /* No ? OK - try using two ADD instructions to generate
11137 the value. */
11138 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 11139
c19d1205
ZW
11140 /* Yes - then make sure that the second instruction is
11141 also an add. */
11142 if (newimm != (unsigned int) FAIL)
11143 newinsn = temp;
11144 /* Still No ? Try using a negated value. */
11145 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
11146 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
11147 /* Otherwise - give up. */
11148 else
11149 {
11150 as_bad_where (fixP->fx_file, fixP->fx_line,
11151 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
11152 (long) value);
11153 break;
11154 }
b99bd4ef 11155
c19d1205
ZW
11156 /* Replace the first operand in the 2nd instruction (which
11157 is the PC) with the destination register. We have
11158 already added in the PC in the first instruction and we
11159 do not want to do it again. */
11160 newinsn &= ~ 0xf0000;
11161 newinsn |= ((newinsn & 0x0f000) << 4);
11162 }
b99bd4ef 11163
c19d1205
ZW
11164 newimm |= (temp & 0xfffff000);
11165 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 11166
c19d1205
ZW
11167 highpart |= (newinsn & 0xfffff000);
11168 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
11169 }
11170 break;
b99bd4ef 11171
c19d1205
ZW
11172 case BFD_RELOC_ARM_OFFSET_IMM:
11173 case BFD_RELOC_ARM_LITERAL:
11174 sign = value >= 0;
b99bd4ef 11175
c19d1205
ZW
11176 if (value < 0)
11177 value = - value;
b99bd4ef 11178
c19d1205 11179 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 11180 {
c19d1205
ZW
11181 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
11182 as_bad_where (fixP->fx_file, fixP->fx_line,
11183 _("invalid literal constant: pool needs to be closer"));
11184 else
11185 as_bad_where (fixP->fx_file, fixP->fx_line,
11186 _("bad immediate value for offset (%ld)"),
11187 (long) value);
11188 break;
f03698e6
RE
11189 }
11190
c19d1205
ZW
11191 newval = md_chars_to_number (buf, INSN_SIZE);
11192 newval &= 0xff7ff000;
11193 newval |= value | (sign ? INDEX_UP : 0);
11194 md_number_to_chars (buf, newval, INSN_SIZE);
11195 break;
b99bd4ef 11196
c19d1205
ZW
11197 case BFD_RELOC_ARM_OFFSET_IMM8:
11198 case BFD_RELOC_ARM_HWLITERAL:
11199 sign = value >= 0;
b99bd4ef 11200
c19d1205
ZW
11201 if (value < 0)
11202 value = - value;
b99bd4ef 11203
c19d1205 11204 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 11205 {
c19d1205
ZW
11206 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
11207 as_bad_where (fixP->fx_file, fixP->fx_line,
11208 _("invalid literal constant: pool needs to be closer"));
11209 else
11210 as_bad (_("bad immediate value for half-word offset (%ld)"),
11211 (long) value);
11212 break;
b99bd4ef
NC
11213 }
11214
c19d1205
ZW
11215 newval = md_chars_to_number (buf, INSN_SIZE);
11216 newval &= 0xff7ff0f0;
11217 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
11218 md_number_to_chars (buf, newval, INSN_SIZE);
11219 break;
b99bd4ef 11220
c19d1205
ZW
11221 case BFD_RELOC_ARM_T32_OFFSET_U8:
11222 if (value < 0 || value > 1020 || value % 4 != 0)
11223 as_bad_where (fixP->fx_file, fixP->fx_line,
11224 _("bad immediate value for offset (%ld)"), (long) value);
11225 value /= 4;
b99bd4ef 11226
c19d1205 11227 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
11228 newval |= value;
11229 md_number_to_chars (buf+2, newval, THUMB_SIZE);
11230 break;
b99bd4ef 11231
c19d1205
ZW
11232 case BFD_RELOC_ARM_T32_OFFSET_IMM:
11233 /* This is a complicated relocation used for all varieties of Thumb32
11234 load/store instruction with immediate offset:
11235
11236 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
11237 *4, optional writeback(W)
11238 (doubleword load/store)
11239
11240 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
11241 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
11242 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
11243 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
11244 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
11245
11246 Uppercase letters indicate bits that are already encoded at
11247 this point. Lowercase letters are our problem. For the
11248 second block of instructions, the secondary opcode nybble
11249 (bits 8..11) is present, and bit 23 is zero, even if this is
11250 a PC-relative operation. */
11251 newval = md_chars_to_number (buf, THUMB_SIZE);
11252 newval <<= 16;
11253 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 11254
c19d1205 11255 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 11256 {
c19d1205
ZW
11257 /* Doubleword load/store: 8-bit offset, scaled by 4. */
11258 if (value >= 0)
11259 newval |= (1 << 23);
11260 else
11261 value = -value;
11262 if (value % 4 != 0)
11263 {
11264 as_bad_where (fixP->fx_file, fixP->fx_line,
11265 _("offset not a multiple of 4"));
11266 break;
11267 }
11268 value /= 4;
11269 if (value >= 0xff)
11270 {
11271 as_bad_where (fixP->fx_file, fixP->fx_line,
11272 _("offset out of range"));
11273 break;
11274 }
11275 newval &= ~0xff;
b99bd4ef 11276 }
c19d1205 11277 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 11278 {
c19d1205
ZW
11279 /* PC-relative, 12-bit offset. */
11280 if (value >= 0)
11281 newval |= (1 << 23);
11282 else
11283 value = -value;
11284 if (value >= 0xfff)
11285 {
11286 as_bad_where (fixP->fx_file, fixP->fx_line,
11287 _("offset out of range"));
11288 break;
11289 }
11290 newval &= ~0xfff;
b99bd4ef 11291 }
c19d1205 11292 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 11293 {
c19d1205
ZW
11294 /* Writeback: 8-bit, +/- offset. */
11295 if (value >= 0)
11296 newval |= (1 << 9);
11297 else
11298 value = -value;
11299 if (value >= 0xff)
11300 {
11301 as_bad_where (fixP->fx_file, fixP->fx_line,
11302 _("offset out of range"));
11303 break;
11304 }
11305 newval &= ~0xff;
b99bd4ef 11306 }
c19d1205 11307 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 11308 {
c19d1205
ZW
11309 /* T-instruction: positive 8-bit offset. */
11310 if (value < 0 || value >= 0xff)
b99bd4ef 11311 {
c19d1205
ZW
11312 as_bad_where (fixP->fx_file, fixP->fx_line,
11313 _("offset out of range"));
11314 break;
b99bd4ef 11315 }
c19d1205
ZW
11316 newval &= ~0xff;
11317 newval |= value;
b99bd4ef
NC
11318 }
11319 else
b99bd4ef 11320 {
c19d1205
ZW
11321 /* Positive 12-bit or negative 8-bit offset. */
11322 int limit;
11323 if (value >= 0)
b99bd4ef 11324 {
c19d1205
ZW
11325 newval |= (1 << 23);
11326 limit = 0xfff;
11327 }
11328 else
11329 {
11330 value = -value;
11331 limit = 0xff;
11332 }
11333 if (value > limit)
11334 {
11335 as_bad_where (fixP->fx_file, fixP->fx_line,
11336 _("offset out of range"));
11337 break;
b99bd4ef 11338 }
c19d1205 11339 newval &= ~limit;
b99bd4ef 11340 }
b99bd4ef 11341
c19d1205
ZW
11342 newval |= value;
11343 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
11344 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
11345 break;
404ff6b5 11346
c19d1205
ZW
11347 case BFD_RELOC_ARM_SHIFT_IMM:
11348 newval = md_chars_to_number (buf, INSN_SIZE);
11349 if (((unsigned long) value) > 32
11350 || (value == 32
11351 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
11352 {
11353 as_bad_where (fixP->fx_file, fixP->fx_line,
11354 _("shift expression is too large"));
11355 break;
11356 }
404ff6b5 11357
c19d1205
ZW
11358 if (value == 0)
11359 /* Shifts of zero must be done as lsl. */
11360 newval &= ~0x60;
11361 else if (value == 32)
11362 value = 0;
11363 newval &= 0xfffff07f;
11364 newval |= (value & 0x1f) << 7;
11365 md_number_to_chars (buf, newval, INSN_SIZE);
11366 break;
404ff6b5 11367
c19d1205 11368 case BFD_RELOC_ARM_T32_IMMEDIATE:
92e90b6e 11369 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 11370 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
11371 /* We claim that this fixup has been processed here,
11372 even if in fact we generate an error because we do
11373 not have a reloc for it, so tc_gen_reloc will reject it. */
11374 fixP->fx_done = 1;
404ff6b5 11375
c19d1205
ZW
11376 if (fixP->fx_addsy
11377 && ! S_IS_DEFINED (fixP->fx_addsy))
11378 {
11379 as_bad_where (fixP->fx_file, fixP->fx_line,
11380 _("undefined symbol %s used as an immediate value"),
11381 S_GET_NAME (fixP->fx_addsy));
11382 break;
11383 }
404ff6b5 11384
c19d1205
ZW
11385 newval = md_chars_to_number (buf, THUMB_SIZE);
11386 newval <<= 16;
11387 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 11388
e9f89963
PB
11389 /* FUTURE: Implement analogue of negate_data_op for T32. */
11390 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE)
11391 newimm = encode_thumb32_immediate (value);
11392 else
92e90b6e 11393 {
e9f89963
PB
11394 /* 12 bit immediate for addw/subw. */
11395 if (value < 0)
11396 {
11397 value = -value;
11398 newval ^= 0x00a00000;
11399 }
92e90b6e
PB
11400 if (value > 0xfff)
11401 newimm = (unsigned int) FAIL;
11402 else
11403 newimm = value;
11404 }
cc8a6dd0 11405
c19d1205 11406 if (newimm == (unsigned int)FAIL)
3631a3c8 11407 {
c19d1205
ZW
11408 as_bad_where (fixP->fx_file, fixP->fx_line,
11409 _("invalid constant (%lx) after fixup"),
11410 (unsigned long) value);
11411 break;
3631a3c8
NC
11412 }
11413
c19d1205
ZW
11414 newval |= (newimm & 0x800) << 15;
11415 newval |= (newimm & 0x700) << 4;
11416 newval |= (newimm & 0x0ff);
cc8a6dd0 11417
c19d1205
ZW
11418 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
11419 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
11420 break;
a737bd4d 11421
3eb17e6b 11422 case BFD_RELOC_ARM_SMC:
c19d1205
ZW
11423 if (((unsigned long) value) > 0xffff)
11424 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 11425 _("invalid smc expression"));
2fc8bdac 11426 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
11427 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
11428 md_number_to_chars (buf, newval, INSN_SIZE);
11429 break;
a737bd4d 11430
c19d1205 11431 case BFD_RELOC_ARM_SWI:
adbaf948 11432 if (fixP->tc_fix_data != 0)
c19d1205
ZW
11433 {
11434 if (((unsigned long) value) > 0xff)
11435 as_bad_where (fixP->fx_file, fixP->fx_line,
11436 _("invalid swi expression"));
2fc8bdac 11437 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
11438 newval |= value;
11439 md_number_to_chars (buf, newval, THUMB_SIZE);
11440 }
11441 else
11442 {
11443 if (((unsigned long) value) > 0x00ffffff)
11444 as_bad_where (fixP->fx_file, fixP->fx_line,
11445 _("invalid swi expression"));
2fc8bdac 11446 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
11447 newval |= value;
11448 md_number_to_chars (buf, newval, INSN_SIZE);
11449 }
11450 break;
a737bd4d 11451
c19d1205
ZW
11452 case BFD_RELOC_ARM_MULTI:
11453 if (((unsigned long) value) > 0xffff)
11454 as_bad_where (fixP->fx_file, fixP->fx_line,
11455 _("invalid expression in load/store multiple"));
11456 newval = value | md_chars_to_number (buf, INSN_SIZE);
11457 md_number_to_chars (buf, newval, INSN_SIZE);
11458 break;
a737bd4d 11459
c19d1205 11460 case BFD_RELOC_ARM_PCREL_BRANCH:
c19d1205 11461#ifdef OBJ_ELF
2fc8bdac 11462 case BFD_RELOC_ARM_PLT32:
c19d1205 11463#endif
a737bd4d 11464
c19d1205 11465 /* We are going to store value (shifted right by two) in the
2fc8bdac
ZW
11466 instruction, in a 24 bit, signed field. Bits 0 and 1 must be
11467 clear, and bits 26 through 32 either all clear or all set. */
11468 if (value & 0x00000003)
c19d1205 11469 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac
ZW
11470 _("misaligned branch destination"));
11471 if ((value & (offsetT)0xfe000000) != (offsetT)0
11472 && (value & (offsetT)0xfe000000) != (offsetT)0xfe000000)
11473 as_bad_where (fixP->fx_file, fixP->fx_line,
11474 _("branch out of range"));
a737bd4d 11475
2fc8bdac 11476 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 11477 {
2fc8bdac
ZW
11478 newval = md_chars_to_number (buf, INSN_SIZE);
11479 newval |= (value >> 2) & 0x00ffffff;
11480 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 11481 }
c19d1205 11482 break;
a737bd4d 11483
c19d1205 11484 case BFD_RELOC_ARM_PCREL_BLX:
2fc8bdac
ZW
11485 /* BLX allows bit 1 to be set in the branch destination, since
11486 it targets a Thumb instruction which is only required to be
11487 aligned modulo 2. Other constraints are as for B/BL. */
11488 if (value & 0x00000001)
11489 as_bad_where (fixP->fx_file, fixP->fx_line,
11490 _("misaligned BLX destination"));
11491 if ((value & (offsetT)0xfe000000) != (offsetT)0
11492 && (value & (offsetT)0xfe000000) != (offsetT)0xfe000000)
11493 as_bad_where (fixP->fx_file, fixP->fx_line,
11494 _("branch out of range"));
a737bd4d 11495
2fc8bdac
ZW
11496 if (fixP->fx_done || !seg->use_rela_p)
11497 {
11498 offsetT hbit;
11499 hbit = (value >> 1) & 1;
11500 value = (value >> 2) & 0x00ffffff;
a737bd4d 11501
2fc8bdac
ZW
11502 newval = md_chars_to_number (buf, INSN_SIZE);
11503 newval |= value | hbit << 24;
11504 md_number_to_chars (buf, newval, INSN_SIZE);
11505 }
c19d1205 11506 break;
a737bd4d 11507
c19d1205 11508 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CZB */
2fc8bdac
ZW
11509 /* CZB can only branch forward. */
11510 if (value & ~0x7e)
11511 as_bad_where (fixP->fx_file, fixP->fx_line,
11512 _("branch out of range"));
a737bd4d 11513
2fc8bdac
ZW
11514 if (fixP->fx_done || !seg->use_rela_p)
11515 {
11516 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205 11517 newval |= ((value & 0x2e) << 2) | ((value & 0x40) << 3);
2fc8bdac
ZW
11518 md_number_to_chars (buf, newval, THUMB_SIZE);
11519 }
c19d1205 11520 break;
a737bd4d 11521
c19d1205 11522 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
2fc8bdac
ZW
11523 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
11524 as_bad_where (fixP->fx_file, fixP->fx_line,
11525 _("branch out of range"));
a737bd4d 11526
2fc8bdac
ZW
11527 if (fixP->fx_done || !seg->use_rela_p)
11528 {
11529 newval = md_chars_to_number (buf, THUMB_SIZE);
11530 newval |= (value & 0x1ff) >> 1;
11531 md_number_to_chars (buf, newval, THUMB_SIZE);
11532 }
c19d1205 11533 break;
a737bd4d 11534
c19d1205 11535 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
2fc8bdac
ZW
11536 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
11537 as_bad_where (fixP->fx_file, fixP->fx_line,
11538 _("branch out of range"));
a737bd4d 11539
2fc8bdac
ZW
11540 if (fixP->fx_done || !seg->use_rela_p)
11541 {
11542 newval = md_chars_to_number (buf, THUMB_SIZE);
11543 newval |= (value & 0xfff) >> 1;
11544 md_number_to_chars (buf, newval, THUMB_SIZE);
11545 }
c19d1205 11546 break;
a737bd4d 11547
c19d1205 11548 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac
ZW
11549 if ((value & ~0x1fffff) && ((value & ~0x1fffff) != ~0x1fffff))
11550 as_bad_where (fixP->fx_file, fixP->fx_line,
11551 _("conditional branch out of range"));
404ff6b5 11552
2fc8bdac
ZW
11553 if (fixP->fx_done || !seg->use_rela_p)
11554 {
11555 offsetT newval2;
11556 addressT S, J1, J2, lo, hi;
404ff6b5 11557
2fc8bdac
ZW
11558 S = (value & 0x00100000) >> 20;
11559 J2 = (value & 0x00080000) >> 19;
11560 J1 = (value & 0x00040000) >> 18;
11561 hi = (value & 0x0003f000) >> 12;
11562 lo = (value & 0x00000ffe) >> 1;
6c43fab6 11563
2fc8bdac
ZW
11564 newval = md_chars_to_number (buf, THUMB_SIZE);
11565 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
11566 newval |= (S << 10) | hi;
11567 newval2 |= (J1 << 13) | (J2 << 11) | lo;
11568 md_number_to_chars (buf, newval, THUMB_SIZE);
11569 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
11570 }
c19d1205 11571 break;
6c43fab6 11572
c19d1205
ZW
11573 case BFD_RELOC_THUMB_PCREL_BLX:
11574 case BFD_RELOC_THUMB_PCREL_BRANCH23:
2fc8bdac
ZW
11575 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
11576 as_bad_where (fixP->fx_file, fixP->fx_line,
11577 _("branch out of range"));
404ff6b5 11578
2fc8bdac
ZW
11579 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
11580 /* For a BLX instruction, make sure that the relocation is rounded up
11581 to a word boundary. This follows the semantics of the instruction
11582 which specifies that bit 1 of the target address will come from bit
11583 1 of the base address. */
11584 value = (value + 1) & ~ 1;
404ff6b5 11585
2fc8bdac 11586 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 11587 {
2fc8bdac
ZW
11588 offsetT newval2;
11589
11590 newval = md_chars_to_number (buf, THUMB_SIZE);
11591 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
11592 newval |= (value & 0x7fffff) >> 12;
11593 newval2 |= (value & 0xfff) >> 1;
11594 md_number_to_chars (buf, newval, THUMB_SIZE);
11595 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
c19d1205 11596 }
c19d1205 11597 break;
404ff6b5 11598
c19d1205 11599 case BFD_RELOC_THUMB_PCREL_BRANCH25:
2fc8bdac
ZW
11600 if ((value & ~0x1ffffff) && ((value & ~0x1ffffff) != ~0x1ffffff))
11601 as_bad_where (fixP->fx_file, fixP->fx_line,
11602 _("branch out of range"));
6c43fab6 11603
2fc8bdac
ZW
11604 if (fixP->fx_done || !seg->use_rela_p)
11605 {
11606 offsetT newval2;
11607 addressT S, I1, I2, lo, hi;
6c43fab6 11608
2fc8bdac
ZW
11609 S = (value & 0x01000000) >> 24;
11610 I1 = (value & 0x00800000) >> 23;
11611 I2 = (value & 0x00400000) >> 22;
11612 hi = (value & 0x003ff000) >> 12;
11613 lo = (value & 0x00000ffe) >> 1;
6c43fab6 11614
2fc8bdac
ZW
11615 I1 = !(I1 ^ S);
11616 I2 = !(I2 ^ S);
a737bd4d 11617
2fc8bdac
ZW
11618 newval = md_chars_to_number (buf, THUMB_SIZE);
11619 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
11620 newval |= (S << 10) | hi;
11621 newval2 |= (I1 << 13) | (I2 << 11) | lo;
11622 md_number_to_chars (buf, newval, THUMB_SIZE);
11623 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
11624 }
11625 break;
a737bd4d 11626
2fc8bdac
ZW
11627 case BFD_RELOC_8:
11628 if (fixP->fx_done || !seg->use_rela_p)
11629 md_number_to_chars (buf, value, 1);
c19d1205 11630 break;
a737bd4d 11631
c19d1205 11632 case BFD_RELOC_16:
2fc8bdac 11633 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 11634 md_number_to_chars (buf, value, 2);
c19d1205 11635 break;
a737bd4d 11636
c19d1205
ZW
11637#ifdef OBJ_ELF
11638 case BFD_RELOC_ARM_TLS_GD32:
11639 case BFD_RELOC_ARM_TLS_LE32:
11640 case BFD_RELOC_ARM_TLS_IE32:
11641 case BFD_RELOC_ARM_TLS_LDM32:
11642 case BFD_RELOC_ARM_TLS_LDO32:
11643 S_SET_THREAD_LOCAL (fixP->fx_addsy);
11644 /* fall through */
6c43fab6 11645
c19d1205
ZW
11646 case BFD_RELOC_ARM_GOT32:
11647 case BFD_RELOC_ARM_GOTOFF:
11648 case BFD_RELOC_ARM_TARGET2:
2fc8bdac
ZW
11649 if (fixP->fx_done || !seg->use_rela_p)
11650 md_number_to_chars (buf, 0, 4);
c19d1205
ZW
11651 break;
11652#endif
6c43fab6 11653
c19d1205
ZW
11654 case BFD_RELOC_RVA:
11655 case BFD_RELOC_32:
11656 case BFD_RELOC_ARM_TARGET1:
11657 case BFD_RELOC_ARM_ROSEGREL32:
11658 case BFD_RELOC_ARM_SBREL32:
11659 case BFD_RELOC_32_PCREL:
2fc8bdac 11660 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 11661 md_number_to_chars (buf, value, 4);
c19d1205 11662 break;
6c43fab6 11663
c19d1205
ZW
11664#ifdef OBJ_ELF
11665 case BFD_RELOC_ARM_PREL31:
2fc8bdac 11666 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
11667 {
11668 newval = md_chars_to_number (buf, 4) & 0x80000000;
11669 if ((value ^ (value >> 1)) & 0x40000000)
11670 {
11671 as_bad_where (fixP->fx_file, fixP->fx_line,
11672 _("rel31 relocation overflow"));
11673 }
11674 newval |= value & 0x7fffffff;
11675 md_number_to_chars (buf, newval, 4);
11676 }
11677 break;
c19d1205 11678#endif
a737bd4d 11679
c19d1205 11680 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 11681 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
c19d1205
ZW
11682 if (value < -1023 || value > 1023 || (value & 3))
11683 as_bad_where (fixP->fx_file, fixP->fx_line,
11684 _("co-processor offset out of range"));
11685 cp_off_common:
11686 sign = value >= 0;
11687 if (value < 0)
11688 value = -value;
8f06b2d8
PB
11689 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
11690 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
11691 newval = md_chars_to_number (buf, INSN_SIZE);
11692 else
11693 newval = get_thumb32_insn (buf);
11694 newval &= 0xff7fff00;
c19d1205
ZW
11695 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
11696 if (value == 0)
11697 newval &= ~WRITE_BACK;
8f06b2d8
PB
11698 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
11699 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
11700 md_number_to_chars (buf, newval, INSN_SIZE);
11701 else
11702 put_thumb32_insn (buf, newval);
c19d1205 11703 break;
a737bd4d 11704
c19d1205 11705 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 11706 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
c19d1205
ZW
11707 if (value < -255 || value > 255)
11708 as_bad_where (fixP->fx_file, fixP->fx_line,
11709 _("co-processor offset out of range"));
11710 goto cp_off_common;
6c43fab6 11711
c19d1205
ZW
11712 case BFD_RELOC_ARM_THUMB_OFFSET:
11713 newval = md_chars_to_number (buf, THUMB_SIZE);
11714 /* Exactly what ranges, and where the offset is inserted depends
11715 on the type of instruction, we can establish this from the
11716 top 4 bits. */
11717 switch (newval >> 12)
11718 {
11719 case 4: /* PC load. */
11720 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
11721 forced to zero for these loads; md_pcrel_from has already
11722 compensated for this. */
11723 if (value & 3)
11724 as_bad_where (fixP->fx_file, fixP->fx_line,
11725 _("invalid offset, target not word aligned (0x%08lX)"),
11726 (((unsigned int) fixP->fx_frag->fr_address
11727 + (unsigned int) fixP->fx_where) & ~3) + value);
a737bd4d 11728
c19d1205
ZW
11729 if (value & ~0x3fc)
11730 as_bad_where (fixP->fx_file, fixP->fx_line,
11731 _("invalid offset, value too big (0x%08lX)"),
11732 (long) value);
a737bd4d 11733
c19d1205
ZW
11734 newval |= value >> 2;
11735 break;
a737bd4d 11736
c19d1205
ZW
11737 case 9: /* SP load/store. */
11738 if (value & ~0x3fc)
11739 as_bad_where (fixP->fx_file, fixP->fx_line,
11740 _("invalid offset, value too big (0x%08lX)"),
11741 (long) value);
11742 newval |= value >> 2;
11743 break;
6c43fab6 11744
c19d1205
ZW
11745 case 6: /* Word load/store. */
11746 if (value & ~0x7c)
11747 as_bad_where (fixP->fx_file, fixP->fx_line,
11748 _("invalid offset, value too big (0x%08lX)"),
11749 (long) value);
11750 newval |= value << 4; /* 6 - 2. */
11751 break;
a737bd4d 11752
c19d1205
ZW
11753 case 7: /* Byte load/store. */
11754 if (value & ~0x1f)
11755 as_bad_where (fixP->fx_file, fixP->fx_line,
11756 _("invalid offset, value too big (0x%08lX)"),
11757 (long) value);
11758 newval |= value << 6;
11759 break;
a737bd4d 11760
c19d1205
ZW
11761 case 8: /* Halfword load/store. */
11762 if (value & ~0x3e)
11763 as_bad_where (fixP->fx_file, fixP->fx_line,
11764 _("invalid offset, value too big (0x%08lX)"),
11765 (long) value);
11766 newval |= value << 5; /* 6 - 1. */
11767 break;
a737bd4d 11768
c19d1205
ZW
11769 default:
11770 as_bad_where (fixP->fx_file, fixP->fx_line,
11771 "Unable to process relocation for thumb opcode: %lx",
11772 (unsigned long) newval);
11773 break;
11774 }
11775 md_number_to_chars (buf, newval, THUMB_SIZE);
11776 break;
a737bd4d 11777
c19d1205
ZW
11778 case BFD_RELOC_ARM_THUMB_ADD:
11779 /* This is a complicated relocation, since we use it for all of
11780 the following immediate relocations:
a737bd4d 11781
c19d1205
ZW
11782 3bit ADD/SUB
11783 8bit ADD/SUB
11784 9bit ADD/SUB SP word-aligned
11785 10bit ADD PC/SP word-aligned
a737bd4d 11786
c19d1205
ZW
11787 The type of instruction being processed is encoded in the
11788 instruction field:
a737bd4d 11789
c19d1205
ZW
11790 0x8000 SUB
11791 0x00F0 Rd
11792 0x000F Rs
11793 */
11794 newval = md_chars_to_number (buf, THUMB_SIZE);
11795 {
11796 int rd = (newval >> 4) & 0xf;
11797 int rs = newval & 0xf;
11798 int subtract = !!(newval & 0x8000);
a737bd4d 11799
c19d1205
ZW
11800 /* Check for HI regs, only very restricted cases allowed:
11801 Adjusting SP, and using PC or SP to get an address. */
11802 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
11803 || (rs > 7 && rs != REG_SP && rs != REG_PC))
11804 as_bad_where (fixP->fx_file, fixP->fx_line,
11805 _("invalid Hi register with immediate"));
a737bd4d 11806
c19d1205
ZW
11807 /* If value is negative, choose the opposite instruction. */
11808 if (value < 0)
11809 {
11810 value = -value;
11811 subtract = !subtract;
11812 if (value < 0)
11813 as_bad_where (fixP->fx_file, fixP->fx_line,
11814 _("immediate value out of range"));
11815 }
a737bd4d 11816
c19d1205
ZW
11817 if (rd == REG_SP)
11818 {
11819 if (value & ~0x1fc)
11820 as_bad_where (fixP->fx_file, fixP->fx_line,
11821 _("invalid immediate for stack address calculation"));
11822 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
11823 newval |= value >> 2;
11824 }
11825 else if (rs == REG_PC || rs == REG_SP)
11826 {
11827 if (subtract || value & ~0x3fc)
11828 as_bad_where (fixP->fx_file, fixP->fx_line,
11829 _("invalid immediate for address calculation (value = 0x%08lX)"),
11830 (unsigned long) value);
11831 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
11832 newval |= rd << 8;
11833 newval |= value >> 2;
11834 }
11835 else if (rs == rd)
11836 {
11837 if (value & ~0xff)
11838 as_bad_where (fixP->fx_file, fixP->fx_line,
11839 _("immediate value out of range"));
11840 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
11841 newval |= (rd << 8) | value;
11842 }
11843 else
11844 {
11845 if (value & ~0x7)
11846 as_bad_where (fixP->fx_file, fixP->fx_line,
11847 _("immediate value out of range"));
11848 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
11849 newval |= rd | (rs << 3) | (value << 6);
11850 }
11851 }
11852 md_number_to_chars (buf, newval, THUMB_SIZE);
11853 break;
a737bd4d 11854
c19d1205
ZW
11855 case BFD_RELOC_ARM_THUMB_IMM:
11856 newval = md_chars_to_number (buf, THUMB_SIZE);
11857 if (value < 0 || value > 255)
11858 as_bad_where (fixP->fx_file, fixP->fx_line,
11859 _("invalid immediate: %ld is too large"),
11860 (long) value);
11861 newval |= value;
11862 md_number_to_chars (buf, newval, THUMB_SIZE);
11863 break;
a737bd4d 11864
c19d1205
ZW
11865 case BFD_RELOC_ARM_THUMB_SHIFT:
11866 /* 5bit shift value (0..32). LSL cannot take 32. */
11867 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
11868 temp = newval & 0xf800;
11869 if (value < 0 || value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
11870 as_bad_where (fixP->fx_file, fixP->fx_line,
11871 _("invalid shift value: %ld"), (long) value);
11872 /* Shifts of zero must be encoded as LSL. */
11873 if (value == 0)
11874 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
11875 /* Shifts of 32 are encoded as zero. */
11876 else if (value == 32)
11877 value = 0;
11878 newval |= value << 6;
11879 md_number_to_chars (buf, newval, THUMB_SIZE);
11880 break;
a737bd4d 11881
c19d1205
ZW
11882 case BFD_RELOC_VTABLE_INHERIT:
11883 case BFD_RELOC_VTABLE_ENTRY:
11884 fixP->fx_done = 0;
11885 return;
6c43fab6 11886
c19d1205
ZW
11887 case BFD_RELOC_UNUSED:
11888 default:
11889 as_bad_where (fixP->fx_file, fixP->fx_line,
11890 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
11891 }
6c43fab6
RE
11892}
11893
c19d1205
ZW
11894/* Translate internal representation of relocation info to BFD target
11895 format. */
a737bd4d 11896
c19d1205
ZW
11897arelent *
11898tc_gen_reloc (asection * section ATTRIBUTE_UNUSED,
11899 fixS * fixp)
a737bd4d 11900{
c19d1205
ZW
11901 arelent * reloc;
11902 bfd_reloc_code_real_type code;
a737bd4d 11903
c19d1205 11904 reloc = xmalloc (sizeof (arelent));
a737bd4d 11905
c19d1205
ZW
11906 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
11907 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
11908 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 11909
2fc8bdac
ZW
11910 if (fixp->fx_pcrel)
11911 fixp->fx_offset = reloc->address;
c19d1205 11912 reloc->addend = fixp->fx_offset;
a737bd4d 11913
c19d1205 11914 switch (fixp->fx_r_type)
a737bd4d 11915 {
c19d1205
ZW
11916 case BFD_RELOC_8:
11917 if (fixp->fx_pcrel)
11918 {
11919 code = BFD_RELOC_8_PCREL;
11920 break;
11921 }
a737bd4d 11922
c19d1205
ZW
11923 case BFD_RELOC_16:
11924 if (fixp->fx_pcrel)
11925 {
11926 code = BFD_RELOC_16_PCREL;
11927 break;
11928 }
6c43fab6 11929
c19d1205
ZW
11930 case BFD_RELOC_32:
11931 if (fixp->fx_pcrel)
11932 {
11933 code = BFD_RELOC_32_PCREL;
11934 break;
11935 }
a737bd4d 11936
c19d1205
ZW
11937 case BFD_RELOC_NONE:
11938 case BFD_RELOC_ARM_PCREL_BRANCH:
11939 case BFD_RELOC_ARM_PCREL_BLX:
11940 case BFD_RELOC_RVA:
11941 case BFD_RELOC_THUMB_PCREL_BRANCH7:
11942 case BFD_RELOC_THUMB_PCREL_BRANCH9:
11943 case BFD_RELOC_THUMB_PCREL_BRANCH12:
11944 case BFD_RELOC_THUMB_PCREL_BRANCH20:
11945 case BFD_RELOC_THUMB_PCREL_BRANCH23:
11946 case BFD_RELOC_THUMB_PCREL_BRANCH25:
11947 case BFD_RELOC_THUMB_PCREL_BLX:
11948 case BFD_RELOC_VTABLE_ENTRY:
11949 case BFD_RELOC_VTABLE_INHERIT:
11950 code = fixp->fx_r_type;
11951 break;
a737bd4d 11952
c19d1205
ZW
11953 case BFD_RELOC_ARM_LITERAL:
11954 case BFD_RELOC_ARM_HWLITERAL:
11955 /* If this is called then the a literal has
11956 been referenced across a section boundary. */
11957 as_bad_where (fixp->fx_file, fixp->fx_line,
11958 _("literal referenced across section boundary"));
11959 return NULL;
a737bd4d 11960
c19d1205
ZW
11961#ifdef OBJ_ELF
11962 case BFD_RELOC_ARM_GOT32:
11963 case BFD_RELOC_ARM_GOTOFF:
11964 case BFD_RELOC_ARM_PLT32:
11965 case BFD_RELOC_ARM_TARGET1:
11966 case BFD_RELOC_ARM_ROSEGREL32:
11967 case BFD_RELOC_ARM_SBREL32:
11968 case BFD_RELOC_ARM_PREL31:
11969 case BFD_RELOC_ARM_TARGET2:
11970 case BFD_RELOC_ARM_TLS_LE32:
11971 case BFD_RELOC_ARM_TLS_LDO32:
11972 code = fixp->fx_r_type;
11973 break;
a737bd4d 11974
c19d1205
ZW
11975 case BFD_RELOC_ARM_TLS_GD32:
11976 case BFD_RELOC_ARM_TLS_IE32:
11977 case BFD_RELOC_ARM_TLS_LDM32:
11978 /* BFD will include the symbol's address in the addend.
11979 But we don't want that, so subtract it out again here. */
11980 if (!S_IS_COMMON (fixp->fx_addsy))
11981 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
11982 code = fixp->fx_r_type;
11983 break;
11984#endif
a737bd4d 11985
c19d1205
ZW
11986 case BFD_RELOC_ARM_IMMEDIATE:
11987 as_bad_where (fixp->fx_file, fixp->fx_line,
11988 _("internal relocation (type: IMMEDIATE) not fixed up"));
11989 return NULL;
a737bd4d 11990
c19d1205
ZW
11991 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
11992 as_bad_where (fixp->fx_file, fixp->fx_line,
11993 _("ADRL used for a symbol not defined in the same file"));
11994 return NULL;
a737bd4d 11995
c19d1205
ZW
11996 case BFD_RELOC_ARM_OFFSET_IMM:
11997 if (fixp->fx_addsy != NULL
11998 && !S_IS_DEFINED (fixp->fx_addsy)
11999 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 12000 {
c19d1205
ZW
12001 as_bad_where (fixp->fx_file, fixp->fx_line,
12002 _("undefined local label `%s'"),
12003 S_GET_NAME (fixp->fx_addsy));
12004 return NULL;
a737bd4d
NC
12005 }
12006
c19d1205
ZW
12007 as_bad_where (fixp->fx_file, fixp->fx_line,
12008 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
12009 return NULL;
a737bd4d 12010
c19d1205
ZW
12011 default:
12012 {
12013 char * type;
6c43fab6 12014
c19d1205
ZW
12015 switch (fixp->fx_r_type)
12016 {
12017 case BFD_RELOC_NONE: type = "NONE"; break;
12018 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
12019 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 12020 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
12021 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
12022 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
12023 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
8f06b2d8 12024 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
12025 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
12026 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
12027 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
12028 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
12029 default: type = _("<unknown>"); break;
12030 }
12031 as_bad_where (fixp->fx_file, fixp->fx_line,
12032 _("cannot represent %s relocation in this object file format"),
12033 type);
12034 return NULL;
12035 }
a737bd4d 12036 }
6c43fab6 12037
c19d1205
ZW
12038#ifdef OBJ_ELF
12039 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
12040 && GOT_symbol
12041 && fixp->fx_addsy == GOT_symbol)
12042 {
12043 code = BFD_RELOC_ARM_GOTPC;
12044 reloc->addend = fixp->fx_offset = reloc->address;
12045 }
12046#endif
6c43fab6 12047
c19d1205 12048 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 12049
c19d1205
ZW
12050 if (reloc->howto == NULL)
12051 {
12052 as_bad_where (fixp->fx_file, fixp->fx_line,
12053 _("cannot represent %s relocation in this object file format"),
12054 bfd_get_reloc_code_name (code));
12055 return NULL;
12056 }
6c43fab6 12057
c19d1205
ZW
12058 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
12059 vtable entry to be used in the relocation's section offset. */
12060 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12061 reloc->address = fixp->fx_offset;
6c43fab6 12062
c19d1205 12063 return reloc;
6c43fab6
RE
12064}
12065
c19d1205 12066/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 12067
c19d1205
ZW
12068void
12069cons_fix_new_arm (fragS * frag,
12070 int where,
12071 int size,
12072 expressionS * exp)
6c43fab6 12073{
c19d1205
ZW
12074 bfd_reloc_code_real_type type;
12075 int pcrel = 0;
6c43fab6 12076
c19d1205
ZW
12077 /* Pick a reloc.
12078 FIXME: @@ Should look at CPU word size. */
12079 switch (size)
12080 {
12081 case 1:
12082 type = BFD_RELOC_8;
12083 break;
12084 case 2:
12085 type = BFD_RELOC_16;
12086 break;
12087 case 4:
12088 default:
12089 type = BFD_RELOC_32;
12090 break;
12091 case 8:
12092 type = BFD_RELOC_64;
12093 break;
12094 }
6c43fab6 12095
c19d1205
ZW
12096 fix_new_exp (frag, where, (int) size, exp, pcrel, type);
12097}
6c43fab6 12098
c19d1205
ZW
12099#if defined OBJ_COFF || defined OBJ_ELF
12100void
12101arm_validate_fix (fixS * fixP)
6c43fab6 12102{
c19d1205
ZW
12103 /* If the destination of the branch is a defined symbol which does not have
12104 the THUMB_FUNC attribute, then we must be calling a function which has
12105 the (interfacearm) attribute. We look for the Thumb entry point to that
12106 function and change the branch to refer to that function instead. */
12107 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
12108 && fixP->fx_addsy != NULL
12109 && S_IS_DEFINED (fixP->fx_addsy)
12110 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 12111 {
c19d1205 12112 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 12113 }
c19d1205
ZW
12114}
12115#endif
6c43fab6 12116
c19d1205
ZW
12117int
12118arm_force_relocation (struct fix * fixp)
12119{
12120#if defined (OBJ_COFF) && defined (TE_PE)
12121 if (fixp->fx_r_type == BFD_RELOC_RVA)
12122 return 1;
12123#endif
6c43fab6 12124
c19d1205
ZW
12125 /* Resolve these relocations even if the symbol is extern or weak. */
12126 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
12127 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
0110f2b8
PB
12128 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
12129 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
12130 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
12131 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12)
c19d1205 12132 return 0;
a737bd4d 12133
c19d1205 12134 return generic_force_reloc (fixp);
404ff6b5
AH
12135}
12136
c19d1205
ZW
12137#ifdef OBJ_COFF
12138/* This is a little hack to help the gas/arm/adrl.s test. It prevents
12139 local labels from being added to the output symbol table when they
12140 are used with the ADRL pseudo op. The ADRL relocation should always
12141 be resolved before the binbary is emitted, so it is safe to say that
12142 it is adjustable. */
404ff6b5 12143
c19d1205
ZW
12144bfd_boolean
12145arm_fix_adjustable (fixS * fixP)
404ff6b5 12146{
c19d1205
ZW
12147 if (fixP->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE)
12148 return 1;
12149 return 0;
404ff6b5 12150}
c19d1205 12151#endif
404ff6b5 12152
c19d1205
ZW
12153#ifdef OBJ_ELF
12154/* Relocations against Thumb function names must be left unadjusted,
12155 so that the linker can use this information to correctly set the
12156 bottom bit of their addresses. The MIPS version of this function
12157 also prevents relocations that are mips-16 specific, but I do not
12158 know why it does this.
404ff6b5 12159
c19d1205
ZW
12160 FIXME:
12161 There is one other problem that ought to be addressed here, but
12162 which currently is not: Taking the address of a label (rather
12163 than a function) and then later jumping to that address. Such
12164 addresses also ought to have their bottom bit set (assuming that
12165 they reside in Thumb code), but at the moment they will not. */
404ff6b5 12166
c19d1205
ZW
12167bfd_boolean
12168arm_fix_adjustable (fixS * fixP)
404ff6b5 12169{
c19d1205
ZW
12170 if (fixP->fx_addsy == NULL)
12171 return 1;
404ff6b5 12172
c19d1205
ZW
12173 if (THUMB_IS_FUNC (fixP->fx_addsy)
12174 && fixP->fx_subsy == NULL)
12175 return 0;
a737bd4d 12176
c19d1205
ZW
12177 /* We need the symbol name for the VTABLE entries. */
12178 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
12179 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
12180 return 0;
404ff6b5 12181
c19d1205
ZW
12182 /* Don't allow symbols to be discarded on GOT related relocs. */
12183 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
12184 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
12185 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
12186 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
12187 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
12188 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
12189 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
12190 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
12191 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
12192 return 0;
a737bd4d 12193
c19d1205 12194 return 1;
a737bd4d 12195}
404ff6b5 12196
c19d1205
ZW
12197const char *
12198elf32_arm_target_format (void)
404ff6b5 12199{
c19d1205
ZW
12200#ifdef TE_SYMBIAN
12201 return (target_big_endian
12202 ? "elf32-bigarm-symbian"
12203 : "elf32-littlearm-symbian");
12204#elif defined (TE_VXWORKS)
12205 return (target_big_endian
12206 ? "elf32-bigarm-vxworks"
12207 : "elf32-littlearm-vxworks");
12208#else
12209 if (target_big_endian)
12210 return "elf32-bigarm";
12211 else
12212 return "elf32-littlearm";
12213#endif
404ff6b5
AH
12214}
12215
c19d1205
ZW
12216void
12217armelf_frob_symbol (symbolS * symp,
12218 int * puntp)
404ff6b5 12219{
c19d1205
ZW
12220 elf_frob_symbol (symp, puntp);
12221}
12222#endif
404ff6b5 12223
c19d1205 12224/* MD interface: Finalization. */
a737bd4d 12225
c19d1205
ZW
12226/* A good place to do this, although this was probably not intended
12227 for this kind of use. We need to dump the literal pool before
12228 references are made to a null symbol pointer. */
a737bd4d 12229
c19d1205
ZW
12230void
12231arm_cleanup (void)
12232{
12233 literal_pool * pool;
a737bd4d 12234
c19d1205
ZW
12235 for (pool = list_of_pools; pool; pool = pool->next)
12236 {
12237 /* Put it at the end of the relevent section. */
12238 subseg_set (pool->section, pool->sub_section);
12239#ifdef OBJ_ELF
12240 arm_elf_change_section ();
12241#endif
12242 s_ltorg (0);
12243 }
404ff6b5
AH
12244}
12245
c19d1205
ZW
12246/* Adjust the symbol table. This marks Thumb symbols as distinct from
12247 ARM ones. */
404ff6b5 12248
c19d1205
ZW
12249void
12250arm_adjust_symtab (void)
404ff6b5 12251{
c19d1205
ZW
12252#ifdef OBJ_COFF
12253 symbolS * sym;
404ff6b5 12254
c19d1205
ZW
12255 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
12256 {
12257 if (ARM_IS_THUMB (sym))
12258 {
12259 if (THUMB_IS_FUNC (sym))
12260 {
12261 /* Mark the symbol as a Thumb function. */
12262 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
12263 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
12264 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 12265
c19d1205
ZW
12266 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
12267 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
12268 else
12269 as_bad (_("%s: unexpected function type: %d"),
12270 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
12271 }
12272 else switch (S_GET_STORAGE_CLASS (sym))
12273 {
12274 case C_EXT:
12275 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
12276 break;
12277 case C_STAT:
12278 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
12279 break;
12280 case C_LABEL:
12281 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
12282 break;
12283 default:
12284 /* Do nothing. */
12285 break;
12286 }
12287 }
a737bd4d 12288
c19d1205
ZW
12289 if (ARM_IS_INTERWORK (sym))
12290 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 12291 }
c19d1205
ZW
12292#endif
12293#ifdef OBJ_ELF
12294 symbolS * sym;
12295 char bind;
404ff6b5 12296
c19d1205 12297 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 12298 {
c19d1205
ZW
12299 if (ARM_IS_THUMB (sym))
12300 {
12301 elf_symbol_type * elf_sym;
404ff6b5 12302
c19d1205
ZW
12303 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
12304 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 12305
c19d1205
ZW
12306 if (! bfd_is_arm_mapping_symbol_name (elf_sym->symbol.name))
12307 {
12308 /* If it's a .thumb_func, declare it as so,
12309 otherwise tag label as .code 16. */
12310 if (THUMB_IS_FUNC (sym))
12311 elf_sym->internal_elf_sym.st_info =
12312 ELF_ST_INFO (bind, STT_ARM_TFUNC);
12313 else
12314 elf_sym->internal_elf_sym.st_info =
12315 ELF_ST_INFO (bind, STT_ARM_16BIT);
12316 }
12317 }
12318 }
12319#endif
404ff6b5
AH
12320}
12321
c19d1205 12322/* MD interface: Initialization. */
404ff6b5 12323
a737bd4d 12324static void
c19d1205 12325set_constant_flonums (void)
a737bd4d 12326{
c19d1205 12327 int i;
404ff6b5 12328
c19d1205
ZW
12329 for (i = 0; i < NUM_FLOAT_VALS; i++)
12330 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
12331 abort ();
a737bd4d 12332}
404ff6b5 12333
c19d1205
ZW
12334void
12335md_begin (void)
a737bd4d 12336{
c19d1205
ZW
12337 unsigned mach;
12338 unsigned int i;
404ff6b5 12339
c19d1205
ZW
12340 if ( (arm_ops_hsh = hash_new ()) == NULL
12341 || (arm_cond_hsh = hash_new ()) == NULL
12342 || (arm_shift_hsh = hash_new ()) == NULL
12343 || (arm_psr_hsh = hash_new ()) == NULL
12344 || (arm_reg_hsh = hash_new ()) == NULL
12345 || (arm_reloc_hsh = hash_new ()) == NULL)
12346 as_fatal (_("virtual memory exhausted"));
12347
12348 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
12349 hash_insert (arm_ops_hsh, insns[i].template, (PTR) (insns + i));
12350 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
12351 hash_insert (arm_cond_hsh, conds[i].template, (PTR) (conds + i));
12352 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
12353 hash_insert (arm_shift_hsh, shift_names[i].name, (PTR) (shift_names + i));
12354 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
12355 hash_insert (arm_psr_hsh, psrs[i].template, (PTR) (psrs + i));
12356 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
12357 hash_insert (arm_reg_hsh, reg_names[i].name, (PTR) (reg_names + i));
12358#ifdef OBJ_ELF
12359 for (i = 0; i < sizeof (reloc_names) / sizeof (struct reloc_entry); i++)
12360 hash_insert (arm_reloc_hsh, reloc_names[i].name, (PTR) (reloc_names + i));
12361#endif
12362
12363 set_constant_flonums ();
404ff6b5 12364
c19d1205
ZW
12365 /* Set the cpu variant based on the command-line options. We prefer
12366 -mcpu= over -march= if both are set (as for GCC); and we prefer
12367 -mfpu= over any other way of setting the floating point unit.
12368 Use of legacy options with new options are faulted. */
12369 if (legacy_cpu != -1)
404ff6b5 12370 {
c19d1205
ZW
12371 if (mcpu_cpu_opt != -1 || march_cpu_opt != -1)
12372 as_bad (_("use of old and new-style options to set CPU type"));
12373
12374 mcpu_cpu_opt = legacy_cpu;
404ff6b5 12375 }
c19d1205
ZW
12376 else if (mcpu_cpu_opt == -1)
12377 mcpu_cpu_opt = march_cpu_opt;
404ff6b5 12378
c19d1205
ZW
12379 if (legacy_fpu != -1)
12380 {
12381 if (mfpu_opt != -1)
12382 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f
RE
12383
12384 mfpu_opt = legacy_fpu;
12385 }
12386 else if (mfpu_opt == -1)
12387 {
c19d1205 12388#if !(defined (TE_LINUX) || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
12389 /* Some environments specify a default FPU. If they don't, infer it
12390 from the processor. */
03b1477f
RE
12391 if (mcpu_fpu_opt != -1)
12392 mfpu_opt = mcpu_fpu_opt;
12393 else
12394 mfpu_opt = march_fpu_opt;
39c2da32
RE
12395#else
12396 mfpu_opt = FPU_DEFAULT;
12397#endif
03b1477f
RE
12398 }
12399
12400 if (mfpu_opt == -1)
12401 {
12402 if (mcpu_cpu_opt == -1)
12403 mfpu_opt = FPU_DEFAULT;
12404 else if (mcpu_cpu_opt & ARM_EXT_V5)
12405 mfpu_opt = FPU_ARCH_VFP_V2;
12406 else
12407 mfpu_opt = FPU_ARCH_FPA;
12408 }
12409
ee065d83
PB
12410#ifdef CPU_DEFAULT
12411 if (mcpu_cpu_opt == -1)
12412 selected_cpu = mcpu_cpu_opt = CPU_DEFAULT;
12413#else
03b1477f 12414 if (mcpu_cpu_opt == -1)
ee065d83
PB
12415 {
12416 mcpu_cpu_opt = ARM_ANY;
12417 selected_cpu = 0;
12418 }
12419 else
12420 selected_cpu = mcpu_cpu_opt;
12421#endif
03b1477f
RE
12422
12423 cpu_variant = mcpu_cpu_opt | mfpu_opt;
12424
ee065d83
PB
12425 arm_arch_used = thumb_arch_used = 0;
12426
f17c130b 12427#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 12428 {
7cc69913
NC
12429 unsigned int flags = 0;
12430
12431#if defined OBJ_ELF
12432 flags = meabi_flags;
d507cf36
PB
12433
12434 switch (meabi_flags)
33a392fb 12435 {
d507cf36 12436 case EF_ARM_EABI_UNKNOWN:
7cc69913 12437#endif
d507cf36
PB
12438 /* Set the flags in the private structure. */
12439 if (uses_apcs_26) flags |= F_APCS26;
12440 if (support_interwork) flags |= F_INTERWORK;
12441 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 12442 if (pic_code) flags |= F_PIC;
d507cf36
PB
12443 if ((cpu_variant & FPU_ANY) == FPU_NONE
12444 || (cpu_variant & FPU_ANY) == FPU_ARCH_VFP) /* VFP layout only. */
7cc69913
NC
12445 flags |= F_SOFT_FLOAT;
12446
d507cf36
PB
12447 switch (mfloat_abi_opt)
12448 {
12449 case ARM_FLOAT_ABI_SOFT:
12450 case ARM_FLOAT_ABI_SOFTFP:
12451 flags |= F_SOFT_FLOAT;
12452 break;
33a392fb 12453
d507cf36
PB
12454 case ARM_FLOAT_ABI_HARD:
12455 if (flags & F_SOFT_FLOAT)
12456 as_bad (_("hard-float conflicts with specified fpu"));
12457 break;
12458 }
03b1477f 12459
c19d1205 12460 /* Using VFP conventions (even if soft-float). */
7cc69913
NC
12461 if (cpu_variant & FPU_VFP_EXT_NONE)
12462 flags |= F_VFP_FLOAT;
f17c130b 12463
fde78edd 12464#if defined OBJ_ELF
d507cf36
PB
12465 if (cpu_variant & FPU_ARCH_MAVERICK)
12466 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
12467 break;
12468
8cb51566 12469 case EF_ARM_EABI_VER4:
c19d1205 12470 /* No additional flags to set. */
d507cf36
PB
12471 break;
12472
12473 default:
12474 abort ();
12475 }
7cc69913 12476#endif
b99bd4ef
NC
12477 bfd_set_private_flags (stdoutput, flags);
12478
12479 /* We have run out flags in the COFF header to encode the
12480 status of ATPCS support, so instead we create a dummy,
c19d1205 12481 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
12482 if (atpcs)
12483 {
12484 asection * sec;
12485
12486 sec = bfd_make_section (stdoutput, ".arm.atpcs");
12487
12488 if (sec != NULL)
12489 {
12490 bfd_set_section_flags
12491 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
12492 bfd_set_section_size (stdoutput, sec, 0);
12493 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
12494 }
12495 }
7cc69913 12496 }
f17c130b 12497#endif
b99bd4ef
NC
12498
12499 /* Record the CPU type as well. */
12500 switch (cpu_variant & ARM_CPU_MASK)
12501 {
12502 case ARM_2:
12503 mach = bfd_mach_arm_2;
12504 break;
12505
c19d1205 12506 case ARM_3: /* Also ARM_250. */
b99bd4ef
NC
12507 mach = bfd_mach_arm_2a;
12508 break;
12509
c19d1205 12510 case ARM_6: /* Also ARM_7. */
b89dddec
RE
12511 mach = bfd_mach_arm_3;
12512 break;
12513
b99bd4ef 12514 default:
5a6c6817 12515 mach = bfd_mach_arm_unknown;
b99bd4ef 12516 break;
b99bd4ef
NC
12517 }
12518
12519 /* Catch special cases. */
e16bb312
NC
12520 if (cpu_variant & ARM_CEXT_IWMMXT)
12521 mach = bfd_mach_arm_iWMMXt;
12522 else if (cpu_variant & ARM_CEXT_XSCALE)
b99bd4ef 12523 mach = bfd_mach_arm_XScale;
fde78edd
NC
12524 else if (cpu_variant & ARM_CEXT_MAVERICK)
12525 mach = bfd_mach_arm_ep9312;
b99bd4ef
NC
12526 else if (cpu_variant & ARM_EXT_V5E)
12527 mach = bfd_mach_arm_5TE;
12528 else if (cpu_variant & ARM_EXT_V5)
12529 {
b89dddec 12530 if (cpu_variant & ARM_EXT_V4T)
b99bd4ef
NC
12531 mach = bfd_mach_arm_5T;
12532 else
12533 mach = bfd_mach_arm_5;
12534 }
b89dddec 12535 else if (cpu_variant & ARM_EXT_V4)
b99bd4ef 12536 {
b89dddec 12537 if (cpu_variant & ARM_EXT_V4T)
b99bd4ef
NC
12538 mach = bfd_mach_arm_4T;
12539 else
12540 mach = bfd_mach_arm_4;
12541 }
b89dddec 12542 else if (cpu_variant & ARM_EXT_V3M)
b99bd4ef
NC
12543 mach = bfd_mach_arm_3M;
12544
12545 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
12546}
12547
c19d1205 12548/* Command line processing. */
b99bd4ef 12549
c19d1205
ZW
12550/* md_parse_option
12551 Invocation line includes a switch not recognized by the base assembler.
12552 See if it's a processor-specific option.
b99bd4ef 12553
c19d1205
ZW
12554 This routine is somewhat complicated by the need for backwards
12555 compatibility (since older releases of gcc can't be changed).
12556 The new options try to make the interface as compatible as
12557 possible with GCC.
b99bd4ef 12558
c19d1205 12559 New options (supported) are:
b99bd4ef 12560
c19d1205
ZW
12561 -mcpu=<cpu name> Assemble for selected processor
12562 -march=<architecture name> Assemble for selected architecture
12563 -mfpu=<fpu architecture> Assemble for selected FPU.
12564 -EB/-mbig-endian Big-endian
12565 -EL/-mlittle-endian Little-endian
12566 -k Generate PIC code
12567 -mthumb Start in Thumb mode
12568 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 12569
c19d1205 12570 For now we will also provide support for:
b99bd4ef 12571
c19d1205
ZW
12572 -mapcs-32 32-bit Program counter
12573 -mapcs-26 26-bit Program counter
12574 -macps-float Floats passed in FP registers
12575 -mapcs-reentrant Reentrant code
12576 -matpcs
12577 (sometime these will probably be replaced with -mapcs=<list of options>
12578 and -matpcs=<list of options>)
b99bd4ef 12579
c19d1205
ZW
12580 The remaining options are only supported for back-wards compatibility.
12581 Cpu variants, the arm part is optional:
12582 -m[arm]1 Currently not supported.
12583 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
12584 -m[arm]3 Arm 3 processor
12585 -m[arm]6[xx], Arm 6 processors
12586 -m[arm]7[xx][t][[d]m] Arm 7 processors
12587 -m[arm]8[10] Arm 8 processors
12588 -m[arm]9[20][tdmi] Arm 9 processors
12589 -mstrongarm[110[0]] StrongARM processors
12590 -mxscale XScale processors
12591 -m[arm]v[2345[t[e]]] Arm architectures
12592 -mall All (except the ARM1)
12593 FP variants:
12594 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
12595 -mfpe-old (No float load/store multiples)
12596 -mvfpxd VFP Single precision
12597 -mvfp All VFP
12598 -mno-fpu Disable all floating point instructions
b99bd4ef 12599
c19d1205
ZW
12600 The following CPU names are recognized:
12601 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
12602 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
12603 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
12604 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
12605 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
12606 arm10t arm10e, arm1020t, arm1020e, arm10200e,
12607 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 12608
c19d1205 12609 */
b99bd4ef 12610
c19d1205 12611const char * md_shortopts = "m:k";
b99bd4ef 12612
c19d1205
ZW
12613#ifdef ARM_BI_ENDIAN
12614#define OPTION_EB (OPTION_MD_BASE + 0)
12615#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 12616#else
c19d1205
ZW
12617#if TARGET_BYTES_BIG_ENDIAN
12618#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 12619#else
c19d1205
ZW
12620#define OPTION_EL (OPTION_MD_BASE + 1)
12621#endif
b99bd4ef 12622#endif
b99bd4ef 12623
c19d1205 12624struct option md_longopts[] =
b99bd4ef 12625{
c19d1205
ZW
12626#ifdef OPTION_EB
12627 {"EB", no_argument, NULL, OPTION_EB},
12628#endif
12629#ifdef OPTION_EL
12630 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 12631#endif
c19d1205
ZW
12632 {NULL, no_argument, NULL, 0}
12633};
b99bd4ef 12634
c19d1205 12635size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 12636
c19d1205 12637struct arm_option_table
b99bd4ef 12638{
c19d1205
ZW
12639 char *option; /* Option name to match. */
12640 char *help; /* Help information. */
12641 int *var; /* Variable to change. */
12642 int value; /* What to change it to. */
12643 char *deprecated; /* If non-null, print this message. */
12644};
b99bd4ef 12645
c19d1205
ZW
12646struct arm_option_table arm_opts[] =
12647{
12648 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
12649 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
12650 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
12651 &support_interwork, 1, NULL},
12652 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
12653 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
12654 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
12655 1, NULL},
12656 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
12657 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
12658 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
12659 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
12660 NULL},
b99bd4ef 12661
c19d1205
ZW
12662 /* These are recognized by the assembler, but have no affect on code. */
12663 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
12664 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
b99bd4ef 12665
c19d1205
ZW
12666 /* DON'T add any new processors to this list -- we want the whole list
12667 to go away... Add them to the processors table instead. */
12668 {"marm1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
12669 {"m1", NULL, &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
12670 {"marm2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
12671 {"m2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
12672 {"marm250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12673 {"m250", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
12674 {"marm3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12675 {"m3", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
12676 {"marm6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
12677 {"m6", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
12678 {"marm600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
12679 {"m600", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
12680 {"marm610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
12681 {"m610", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
12682 {"marm620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
12683 {"m620", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
12684 {"marm7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
12685 {"m7", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
12686 {"marm70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
12687 {"m70", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
12688 {"marm700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
12689 {"m700", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
12690 {"marm700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
12691 {"m700i", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
12692 {"marm710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
12693 {"m710", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
12694 {"marm710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
12695 {"m710c", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
12696 {"marm720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
12697 {"m720", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
12698 {"marm7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
12699 {"m7d", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
12700 {"marm7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
12701 {"m7di", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
12702 {"marm7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12703 {"m7m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
12704 {"marm7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12705 {"m7dm", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
12706 {"marm7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12707 {"m7dmi", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
12708 {"marm7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
12709 {"m7100", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
12710 {"marm7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
12711 {"m7500", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
12712 {"marm7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
12713 {"m7500fe", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
12714 {"marm7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12715 {"m7t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12716 {"marm7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12717 {"m7tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
12718 {"marm710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12719 {"m710t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
12720 {"marm720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12721 {"m720t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
12722 {"marm740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12723 {"m740t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
12724 {"marm8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
12725 {"m8", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
12726 {"marm810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
12727 {"m810", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
12728 {"marm9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12729 {"m9", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
12730 {"marm9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12731 {"m9tdmi", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
12732 {"marm920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12733 {"m920", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
12734 {"marm940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12735 {"m940", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
12736 {"mstrongarm", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
12737 {"mstrongarm110", NULL, &legacy_cpu, ARM_ARCH_V4,
12738 N_("use -mcpu=strongarm110")},
12739 {"mstrongarm1100", NULL, &legacy_cpu, ARM_ARCH_V4,
12740 N_("use -mcpu=strongarm1100")},
12741 {"mstrongarm1110", NULL, &legacy_cpu, ARM_ARCH_V4,
12742 N_("use -mcpu=strongarm1110")},
12743 {"mxscale", NULL, &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
12744 {"miwmmxt", NULL, &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
12745 {"mall", NULL, &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 12746
c19d1205
ZW
12747 /* Architecture variants -- don't add any more to this list either. */
12748 {"mv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
12749 {"marmv2", NULL, &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
12750 {"mv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12751 {"marmv2a", NULL, &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
12752 {"mv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
12753 {"marmv3", NULL, &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
12754 {"mv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12755 {"marmv3m", NULL, &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
12756 {"mv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
12757 {"marmv4", NULL, &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
12758 {"mv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12759 {"marmv4t", NULL, &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
12760 {"mv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
12761 {"marmv5", NULL, &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
12762 {"mv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12763 {"marmv5t", NULL, &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
12764 {"mv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
12765 {"marmv5e", NULL, &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 12766
c19d1205
ZW
12767 /* Floating point variants -- don't add any more to this list either. */
12768 {"mfpe-old", NULL, &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
12769 {"mfpa10", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
12770 {"mfpa11", NULL, &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
12771 {"mno-fpu", NULL, &legacy_fpu, 0,
12772 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 12773
c19d1205
ZW
12774 {NULL, NULL, NULL, 0, NULL}
12775};
7ed4c4c5 12776
c19d1205 12777struct arm_cpu_option_table
7ed4c4c5 12778{
c19d1205
ZW
12779 char *name;
12780 int value;
12781 /* For some CPUs we assume an FPU unless the user explicitly sets
12782 -mfpu=... */
12783 int default_fpu;
ee065d83
PB
12784 /* The canonical name of the CPU, or NULL to use NAME converted to upper
12785 case. */
12786 const char *canonical_name;
c19d1205 12787};
7ed4c4c5 12788
c19d1205
ZW
12789/* This list should, at a minimum, contain all the cpu names
12790 recognized by GCC. */
12791static struct arm_cpu_option_table arm_cpus[] =
12792{
ee065d83
PB
12793 {"all", ARM_ANY, FPU_ARCH_FPA, NULL},
12794 {"arm1", ARM_ARCH_V1, FPU_ARCH_FPA, NULL},
12795 {"arm2", ARM_ARCH_V2, FPU_ARCH_FPA, NULL},
12796 {"arm250", ARM_ARCH_V2S, FPU_ARCH_FPA, NULL},
12797 {"arm3", ARM_ARCH_V2S, FPU_ARCH_FPA, NULL},
12798 {"arm6", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12799 {"arm60", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12800 {"arm600", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12801 {"arm610", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12802 {"arm620", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12803 {"arm7", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12804 {"arm7m", ARM_ARCH_V3M, FPU_ARCH_FPA, NULL},
12805 {"arm7d", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12806 {"arm7dm", ARM_ARCH_V3M, FPU_ARCH_FPA, NULL},
12807 {"arm7di", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12808 {"arm7dmi", ARM_ARCH_V3M, FPU_ARCH_FPA, NULL},
12809 {"arm70", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12810 {"arm700", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12811 {"arm700i", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12812 {"arm710", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12813 {"arm710t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
12814 {"arm720", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12815 {"arm720t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
12816 {"arm740t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
12817 {"arm710c", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12818 {"arm7100", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12819 {"arm7500", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12820 {"arm7500fe", ARM_ARCH_V3, FPU_ARCH_FPA, NULL},
12821 {"arm7t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
12822 {"arm7tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
12823 {"arm7tdmi-s", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
12824 {"arm8", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
12825 {"arm810", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
12826 {"strongarm", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
12827 {"strongarm1", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
12828 {"strongarm110", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
12829 {"strongarm1100", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
12830 {"strongarm1110", ARM_ARCH_V4, FPU_ARCH_FPA, NULL},
12831 {"arm9", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
12832 {"arm920", ARM_ARCH_V4T, FPU_ARCH_FPA, "ARM920T"},
12833 {"arm920t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
12834 {"arm922t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
12835 {"arm940t", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
12836 {"arm9tdmi", ARM_ARCH_V4T, FPU_ARCH_FPA, NULL},
c19d1205
ZW
12837 /* For V5 or later processors we default to using VFP; but the user
12838 should really set the FPU type explicitly. */
ee065d83
PB
12839 {"arm9e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL},
12840 {"arm9e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
12841 {"arm926ej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, "ARM926EJ-S"},
12842 {"arm926ejs", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, "ARM926EJ-S"},
12843 {"arm926ej-s", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, NULL},
12844 {"arm946e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL},
12845 {"arm946e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, "ARM946E-S"},
12846 {"arm946e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
12847 {"arm966e-r0", ARM_ARCH_V5TExP, FPU_ARCH_VFP_V2, NULL},
12848 {"arm966e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, "ARM966E-S"},
12849 {"arm966e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
12850 {"arm968e-s", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
12851 {"arm10t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL},
12852 {"arm10tdmi", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL},
12853 {"arm10e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
12854 {"arm1020", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, "ARM1020E"},
12855 {"arm1020t", ARM_ARCH_V5T, FPU_ARCH_VFP_V1, NULL},
12856 {"arm1020e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
12857 {"arm1022e", ARM_ARCH_V5TE, FPU_ARCH_VFP_V2, NULL},
12858 {"arm1026ejs", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, "ARM1026EJ-S"},
12859 {"arm1026ej-s", ARM_ARCH_V5TEJ, FPU_ARCH_VFP_V2, NULL},
12860 {"arm1136js", ARM_ARCH_V6, FPU_NONE, "ARM1136J-S"},
12861 {"arm1136j-s", ARM_ARCH_V6, FPU_NONE, NULL},
12862 {"arm1136jfs", ARM_ARCH_V6, FPU_ARCH_VFP_V2, "ARM1136JF-S"},
12863 {"arm1136jf-s", ARM_ARCH_V6, FPU_ARCH_VFP_V2, NULL},
12864 {"mpcore", ARM_ARCH_V6K, FPU_ARCH_VFP_V2, NULL},
12865 {"mpcorenovfp", ARM_ARCH_V6K, FPU_NONE, NULL},
12866 {"arm1156t2-s", ARM_ARCH_V6T2, FPU_NONE, NULL},
12867 {"arm1156t2f-s", ARM_ARCH_V6T2, FPU_ARCH_VFP_V2, NULL},
12868 {"arm1176jz-s", ARM_ARCH_V6ZK, FPU_NONE, NULL},
12869 {"arm1176jzf-s", ARM_ARCH_V6ZK, FPU_ARCH_VFP_V2, NULL},
c19d1205 12870 /* ??? XSCALE is really an architecture. */
ee065d83 12871 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL},
c19d1205 12872 /* ??? iwmmxt is not a processor. */
ee065d83
PB
12873 {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP_V2, NULL},
12874 {"i80200", ARM_ARCH_XSCALE, FPU_ARCH_VFP_V2, NULL},
c19d1205 12875 /* Maverick */
ee065d83
PB
12876 {"ep9312", ARM_ARCH_V4T | ARM_CEXT_MAVERICK, FPU_ARCH_MAVERICK, "ARM920T"},
12877 {NULL, 0, 0, NULL}
c19d1205 12878};
7ed4c4c5 12879
c19d1205 12880struct arm_arch_option_table
7ed4c4c5 12881{
c19d1205
ZW
12882 char *name;
12883 int value;
12884 int default_fpu;
12885};
7ed4c4c5 12886
c19d1205
ZW
12887/* This list should, at a minimum, contain all the architecture names
12888 recognized by GCC. */
12889static struct arm_arch_option_table arm_archs[] =
12890{
12891 {"all", ARM_ANY, FPU_ARCH_FPA},
12892 {"armv1", ARM_ARCH_V1, FPU_ARCH_FPA},
12893 {"armv2", ARM_ARCH_V2, FPU_ARCH_FPA},
12894 {"armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA},
12895 {"armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA},
12896 {"armv3", ARM_ARCH_V3, FPU_ARCH_FPA},
12897 {"armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA},
12898 {"armv4", ARM_ARCH_V4, FPU_ARCH_FPA},
12899 {"armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA},
12900 {"armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA},
12901 {"armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA},
12902 {"armv5", ARM_ARCH_V5, FPU_ARCH_VFP},
12903 {"armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP},
12904 {"armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP},
12905 {"armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP},
12906 {"armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP},
12907 {"armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP},
12908 {"armv6", ARM_ARCH_V6, FPU_ARCH_VFP},
12909 {"armv6j", ARM_ARCH_V6, FPU_ARCH_VFP},
12910 {"armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP},
12911 {"armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP},
12912 {"armv6zk", ARM_ARCH_V6ZK, FPU_ARCH_VFP},
12913 {"armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP},
12914 {"armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP},
12915 {"armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP},
12916 {"armv6zkt2", ARM_ARCH_V6ZKT2, FPU_ARCH_VFP},
12917 {"xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP},
12918 {"iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP},
12919 {NULL, 0, 0}
12920};
7ed4c4c5 12921
c19d1205
ZW
12922/* ISA extensions in the co-processor space. */
12923struct arm_option_value_table
12924{
12925 char *name;
12926 int value;
12927};
7ed4c4c5 12928
c19d1205
ZW
12929static struct arm_option_value_table arm_extensions[] =
12930{
12931 {"maverick", ARM_CEXT_MAVERICK},
12932 {"xscale", ARM_CEXT_XSCALE},
12933 {"iwmmxt", ARM_CEXT_IWMMXT},
12934 {NULL, 0}
12935};
7ed4c4c5 12936
c19d1205
ZW
12937/* This list should, at a minimum, contain all the fpu names
12938 recognized by GCC. */
12939static struct arm_option_value_table arm_fpus[] =
12940{
12941 {"softfpa", FPU_NONE},
12942 {"fpe", FPU_ARCH_FPE},
12943 {"fpe2", FPU_ARCH_FPE},
12944 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
12945 {"fpa", FPU_ARCH_FPA},
12946 {"fpa10", FPU_ARCH_FPA},
12947 {"fpa11", FPU_ARCH_FPA},
12948 {"arm7500fe", FPU_ARCH_FPA},
12949 {"softvfp", FPU_ARCH_VFP},
12950 {"softvfp+vfp", FPU_ARCH_VFP_V2},
12951 {"vfp", FPU_ARCH_VFP_V2},
12952 {"vfp9", FPU_ARCH_VFP_V2},
12953 {"vfp10", FPU_ARCH_VFP_V2},
12954 {"vfp10-r0", FPU_ARCH_VFP_V1},
12955 {"vfpxd", FPU_ARCH_VFP_V1xD},
12956 {"arm1020t", FPU_ARCH_VFP_V1},
12957 {"arm1020e", FPU_ARCH_VFP_V2},
12958 {"arm1136jfs", FPU_ARCH_VFP_V2},
12959 {"arm1136jf-s", FPU_ARCH_VFP_V2},
12960 {"maverick", FPU_ARCH_MAVERICK},
12961 {NULL, 0}
12962};
7ed4c4c5 12963
c19d1205
ZW
12964static struct arm_option_value_table arm_float_abis[] =
12965{
12966 {"hard", ARM_FLOAT_ABI_HARD},
12967 {"softfp", ARM_FLOAT_ABI_SOFTFP},
12968 {"soft", ARM_FLOAT_ABI_SOFT},
12969 {NULL, 0}
12970};
7ed4c4c5 12971
c19d1205
ZW
12972#ifdef OBJ_ELF
12973/* We only know how to output GNU and ver 4 (AAELF) formats. */
12974static struct arm_option_value_table arm_eabis[] =
12975{
12976 {"gnu", EF_ARM_EABI_UNKNOWN},
12977 {"4", EF_ARM_EABI_VER4},
12978 {NULL, 0}
12979};
12980#endif
7ed4c4c5 12981
c19d1205
ZW
12982struct arm_long_option_table
12983{
12984 char * option; /* Substring to match. */
12985 char * help; /* Help information. */
12986 int (* func) (char * subopt); /* Function to decode sub-option. */
12987 char * deprecated; /* If non-null, print this message. */
12988};
7ed4c4c5
NC
12989
12990static int
c19d1205 12991arm_parse_extension (char * str, int * opt_p)
7ed4c4c5 12992{
c19d1205 12993 while (str != NULL && *str != 0)
7ed4c4c5 12994 {
c19d1205
ZW
12995 struct arm_option_value_table * opt;
12996 char * ext;
12997 int optlen;
7ed4c4c5 12998
c19d1205
ZW
12999 if (*str != '+')
13000 {
13001 as_bad (_("invalid architectural extension"));
13002 return 0;
13003 }
7ed4c4c5 13004
c19d1205
ZW
13005 str++;
13006 ext = strchr (str, '+');
7ed4c4c5 13007
c19d1205
ZW
13008 if (ext != NULL)
13009 optlen = ext - str;
13010 else
13011 optlen = strlen (str);
7ed4c4c5 13012
c19d1205
ZW
13013 if (optlen == 0)
13014 {
13015 as_bad (_("missing architectural extension"));
13016 return 0;
13017 }
7ed4c4c5 13018
c19d1205
ZW
13019 for (opt = arm_extensions; opt->name != NULL; opt++)
13020 if (strncmp (opt->name, str, optlen) == 0)
13021 {
13022 *opt_p |= opt->value;
13023 break;
13024 }
7ed4c4c5 13025
c19d1205
ZW
13026 if (opt->name == NULL)
13027 {
13028 as_bad (_("unknown architectural extnsion `%s'"), str);
13029 return 0;
13030 }
7ed4c4c5 13031
c19d1205
ZW
13032 str = ext;
13033 };
7ed4c4c5 13034
c19d1205
ZW
13035 return 1;
13036}
7ed4c4c5 13037
c19d1205
ZW
13038static int
13039arm_parse_cpu (char * str)
7ed4c4c5 13040{
c19d1205
ZW
13041 struct arm_cpu_option_table * opt;
13042 char * ext = strchr (str, '+');
13043 int optlen;
7ed4c4c5 13044
c19d1205
ZW
13045 if (ext != NULL)
13046 optlen = ext - str;
7ed4c4c5 13047 else
c19d1205 13048 optlen = strlen (str);
7ed4c4c5 13049
c19d1205 13050 if (optlen == 0)
7ed4c4c5 13051 {
c19d1205
ZW
13052 as_bad (_("missing cpu name `%s'"), str);
13053 return 0;
7ed4c4c5
NC
13054 }
13055
c19d1205
ZW
13056 for (opt = arm_cpus; opt->name != NULL; opt++)
13057 if (strncmp (opt->name, str, optlen) == 0)
13058 {
13059 mcpu_cpu_opt = opt->value;
13060 mcpu_fpu_opt = opt->default_fpu;
ee065d83
PB
13061 if (opt->canonical_name)
13062 strcpy(selected_cpu_name, opt->canonical_name);
13063 else
13064 {
13065 int i;
13066 for (i = 0; i < optlen; i++)
13067 selected_cpu_name[i] = TOUPPER (opt->name[i]);
13068 selected_cpu_name[i] = 0;
13069 }
7ed4c4c5 13070
c19d1205
ZW
13071 if (ext != NULL)
13072 return arm_parse_extension (ext, &mcpu_cpu_opt);
7ed4c4c5 13073
c19d1205
ZW
13074 return 1;
13075 }
7ed4c4c5 13076
c19d1205
ZW
13077 as_bad (_("unknown cpu `%s'"), str);
13078 return 0;
7ed4c4c5
NC
13079}
13080
c19d1205
ZW
13081static int
13082arm_parse_arch (char * str)
7ed4c4c5 13083{
c19d1205
ZW
13084 struct arm_arch_option_table *opt;
13085 char *ext = strchr (str, '+');
13086 int optlen;
7ed4c4c5 13087
c19d1205
ZW
13088 if (ext != NULL)
13089 optlen = ext - str;
7ed4c4c5 13090 else
c19d1205 13091 optlen = strlen (str);
7ed4c4c5 13092
c19d1205 13093 if (optlen == 0)
7ed4c4c5 13094 {
c19d1205
ZW
13095 as_bad (_("missing architecture name `%s'"), str);
13096 return 0;
7ed4c4c5
NC
13097 }
13098
c19d1205
ZW
13099 for (opt = arm_archs; opt->name != NULL; opt++)
13100 if (streq (opt->name, str))
13101 {
13102 march_cpu_opt = opt->value;
13103 march_fpu_opt = opt->default_fpu;
ee065d83 13104 strcpy(selected_cpu_name, opt->name);
7ed4c4c5 13105
c19d1205
ZW
13106 if (ext != NULL)
13107 return arm_parse_extension (ext, &march_cpu_opt);
7ed4c4c5 13108
c19d1205
ZW
13109 return 1;
13110 }
13111
13112 as_bad (_("unknown architecture `%s'\n"), str);
13113 return 0;
7ed4c4c5 13114}
eb043451 13115
c19d1205
ZW
13116static int
13117arm_parse_fpu (char * str)
13118{
13119 struct arm_option_value_table * opt;
b99bd4ef 13120
c19d1205
ZW
13121 for (opt = arm_fpus; opt->name != NULL; opt++)
13122 if (streq (opt->name, str))
13123 {
13124 mfpu_opt = opt->value;
13125 return 1;
13126 }
b99bd4ef 13127
c19d1205
ZW
13128 as_bad (_("unknown floating point format `%s'\n"), str);
13129 return 0;
13130}
13131
13132static int
13133arm_parse_float_abi (char * str)
b99bd4ef 13134{
c19d1205 13135 struct arm_option_value_table * opt;
b99bd4ef 13136
c19d1205
ZW
13137 for (opt = arm_float_abis; opt->name != NULL; opt++)
13138 if (streq (opt->name, str))
13139 {
13140 mfloat_abi_opt = opt->value;
13141 return 1;
13142 }
cc8a6dd0 13143
c19d1205
ZW
13144 as_bad (_("unknown floating point abi `%s'\n"), str);
13145 return 0;
13146}
b99bd4ef 13147
c19d1205
ZW
13148#ifdef OBJ_ELF
13149static int
13150arm_parse_eabi (char * str)
13151{
13152 struct arm_option_value_table *opt;
cc8a6dd0 13153
c19d1205
ZW
13154 for (opt = arm_eabis; opt->name != NULL; opt++)
13155 if (streq (opt->name, str))
13156 {
13157 meabi_flags = opt->value;
13158 return 1;
13159 }
13160 as_bad (_("unknown EABI `%s'\n"), str);
13161 return 0;
13162}
13163#endif
cc8a6dd0 13164
c19d1205
ZW
13165struct arm_long_option_table arm_long_opts[] =
13166{
13167 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
13168 arm_parse_cpu, NULL},
13169 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
13170 arm_parse_arch, NULL},
13171 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
13172 arm_parse_fpu, NULL},
13173 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
13174 arm_parse_float_abi, NULL},
13175#ifdef OBJ_ELF
13176 {"meabi=", N_("<ver>\t assemble for eabi version <ver>"),
13177 arm_parse_eabi, NULL},
13178#endif
13179 {NULL, NULL, 0, NULL}
13180};
cc8a6dd0 13181
c19d1205
ZW
13182int
13183md_parse_option (int c, char * arg)
13184{
13185 struct arm_option_table *opt;
13186 struct arm_long_option_table *lopt;
b99bd4ef 13187
c19d1205 13188 switch (c)
b99bd4ef 13189 {
c19d1205
ZW
13190#ifdef OPTION_EB
13191 case OPTION_EB:
13192 target_big_endian = 1;
13193 break;
13194#endif
cc8a6dd0 13195
c19d1205
ZW
13196#ifdef OPTION_EL
13197 case OPTION_EL:
13198 target_big_endian = 0;
13199 break;
13200#endif
b99bd4ef 13201
c19d1205
ZW
13202 case 'a':
13203 /* Listing option. Just ignore these, we don't support additional
13204 ones. */
13205 return 0;
b99bd4ef 13206
c19d1205
ZW
13207 default:
13208 for (opt = arm_opts; opt->option != NULL; opt++)
13209 {
13210 if (c == opt->option[0]
13211 && ((arg == NULL && opt->option[1] == 0)
13212 || streq (arg, opt->option + 1)))
13213 {
13214#if WARN_DEPRECATED
13215 /* If the option is deprecated, tell the user. */
13216 if (opt->deprecated != NULL)
13217 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
13218 arg ? arg : "", _(opt->deprecated));
13219#endif
b99bd4ef 13220
c19d1205
ZW
13221 if (opt->var != NULL)
13222 *opt->var = opt->value;
cc8a6dd0 13223
c19d1205
ZW
13224 return 1;
13225 }
13226 }
b99bd4ef 13227
c19d1205
ZW
13228 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13229 {
13230 /* These options are expected to have an argument. */
13231 if (c == lopt->option[0]
13232 && arg != NULL
13233 && strncmp (arg, lopt->option + 1,
13234 strlen (lopt->option + 1)) == 0)
13235 {
13236#if WARN_DEPRECATED
13237 /* If the option is deprecated, tell the user. */
13238 if (lopt->deprecated != NULL)
13239 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
13240 _(lopt->deprecated));
13241#endif
b99bd4ef 13242
c19d1205
ZW
13243 /* Call the sup-option parser. */
13244 return lopt->func (arg + strlen (lopt->option) - 1);
13245 }
13246 }
a737bd4d 13247
c19d1205
ZW
13248 return 0;
13249 }
a394c00f 13250
c19d1205
ZW
13251 return 1;
13252}
a394c00f 13253
c19d1205
ZW
13254void
13255md_show_usage (FILE * fp)
a394c00f 13256{
c19d1205
ZW
13257 struct arm_option_table *opt;
13258 struct arm_long_option_table *lopt;
a394c00f 13259
c19d1205 13260 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 13261
c19d1205
ZW
13262 for (opt = arm_opts; opt->option != NULL; opt++)
13263 if (opt->help != NULL)
13264 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 13265
c19d1205
ZW
13266 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
13267 if (lopt->help != NULL)
13268 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 13269
c19d1205
ZW
13270#ifdef OPTION_EB
13271 fprintf (fp, _("\
13272 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
13273#endif
13274
c19d1205
ZW
13275#ifdef OPTION_EL
13276 fprintf (fp, _("\
13277 -EL assemble code for a little-endian cpu\n"));
a737bd4d 13278#endif
c19d1205 13279}
ee065d83
PB
13280
13281
13282#ifdef OBJ_ELF
13283/* Set the public EABI object attributes. */
13284static void
13285aeabi_set_public_attributes (void)
13286{
13287 int arch;
13288 int flags;
13289
13290 /* Choose the architecture based on the capabilities of the requested cpu
13291 (if any) and/or the instructions actually used. */
2e10c237 13292 flags = selected_cpu | mfpu_opt | arm_arch_used | thumb_arch_used;
ee065d83
PB
13293 if (flags & ARM_EXT_V6T2)
13294 arch = 8;
13295 else if (flags & ARM_EXT_V6Z)
13296 arch = 7;
13297 else if (flags & ARM_EXT_V6K)
13298 arch = 9;
13299 else if (flags & ARM_EXT_V6)
13300 arch = 6;
13301 else if (flags & ARM_EXT_V5E)
13302 arch = 4;
13303 else if (flags & (ARM_EXT_V5 | ARM_EXT_V5T))
13304 arch = 3;
13305 else if (flags & ARM_EXT_V4T)
13306 arch = 2;
13307 else if (flags & ARM_EXT_V4)
13308 arch = 1;
13309 else
13310 arch = 0;
13311
13312 /* Tag_CPU_name. */
13313 if (selected_cpu_name[0])
13314 {
13315 char *p;
13316
13317 p = selected_cpu_name;
13318 if (strncmp(p, "armv", 4) == 0)
13319 {
13320 int i;
13321
13322 p += 4;
13323 for (i = 0; p[i]; i++)
13324 p[i] = TOUPPER (p[i]);
13325 }
13326 elf32_arm_add_eabi_attr_string (stdoutput, 5, p);
13327 }
13328 /* Tag_CPU_arch. */
13329 elf32_arm_add_eabi_attr_int (stdoutput, 6, arch);
13330 /* Tag_ARM_ISA_use. */
13331 if (arm_arch_used)
13332 elf32_arm_add_eabi_attr_int (stdoutput, 8, 1);
13333 /* Tag_THUMB_ISA_use. */
13334 if (thumb_arch_used)
13335 elf32_arm_add_eabi_attr_int (stdoutput, 9,
13336 (thumb_arch_used & ARM_EXT_V6T2) ? 2 : 1);
13337 /* Tag_VFP_arch. */
13338 if ((arm_arch_used | thumb_arch_used) & FPU_ARCH_VFP_V2)
13339 elf32_arm_add_eabi_attr_int (stdoutput, 10, 2);
13340 else if ((arm_arch_used | thumb_arch_used) & FPU_ARCH_VFP_V1)
13341 elf32_arm_add_eabi_attr_int (stdoutput, 10, 1);
13342 /* Tag_WMMX_arch. */
13343 if ((arm_arch_used | thumb_arch_used) & ARM_CEXT_IWMMXT)
13344 elf32_arm_add_eabi_attr_int (stdoutput, 11, 1);
13345}
13346
13347/* Add the .ARM.attributes section. */
13348void
13349arm_md_end (void)
13350{
13351 segT s;
13352 char *p;
13353 addressT addr;
13354 offsetT size;
13355
13356 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
13357 return;
13358
13359 aeabi_set_public_attributes ();
13360 size = elf32_arm_eabi_attr_size (stdoutput);
13361 s = subseg_new (".ARM.attributes", 0);
13362 bfd_set_section_flags (stdoutput, s, SEC_READONLY | SEC_DATA);
13363 addr = frag_now_fix ();
13364 p = frag_more (size);
13365 elf32_arm_set_eabi_attr_contents (stdoutput, (bfd_byte *)p, size);
13366}
13367
13368
13369/* Parse a .cpu directive. */
13370
13371static void
13372s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
13373{
13374 struct arm_cpu_option_table *opt;
13375 char *name;
13376 char saved_char;
13377
13378 name = input_line_pointer;
13379 while (*input_line_pointer && !ISSPACE(*input_line_pointer))
13380 input_line_pointer++;
13381 saved_char = *input_line_pointer;
13382 *input_line_pointer = 0;
13383
13384 /* Skip the first "all" entry. */
13385 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
13386 if (streq (opt->name, name))
13387 {
13388 mcpu_cpu_opt = opt->value;
13389 selected_cpu = mcpu_cpu_opt;
13390 if (opt->canonical_name)
13391 strcpy(selected_cpu_name, opt->canonical_name);
13392 else
13393 {
13394 int i;
13395 for (i = 0; opt->name[i]; i++)
13396 selected_cpu_name[i] = TOUPPER (opt->name[i]);
13397 selected_cpu_name[i] = 0;
13398 }
13399 cpu_variant = mcpu_cpu_opt | mfpu_opt;
13400 *input_line_pointer = saved_char;
13401 demand_empty_rest_of_line ();
13402 return;
13403 }
13404 as_bad (_("unknown cpu `%s'"), name);
13405 *input_line_pointer = saved_char;
13406 ignore_rest_of_line ();
13407}
13408
13409
13410/* Parse a .arch directive. */
13411
13412static void
13413s_arm_arch (int ignored ATTRIBUTE_UNUSED)
13414{
13415 struct arm_arch_option_table *opt;
13416 char saved_char;
13417 char *name;
13418
13419 name = input_line_pointer;
13420 while (*input_line_pointer && !ISSPACE(*input_line_pointer))
13421 input_line_pointer++;
13422 saved_char = *input_line_pointer;
13423 *input_line_pointer = 0;
13424
13425 /* Skip the first "all" entry. */
13426 for (opt = arm_archs + 1; opt->name != NULL; opt++)
13427 if (streq (opt->name, name))
13428 {
13429 mcpu_cpu_opt = opt->value;
13430 selected_cpu = mcpu_cpu_opt;
13431 strcpy(selected_cpu_name, opt->name);
13432 cpu_variant = mcpu_cpu_opt | mfpu_opt;
13433 *input_line_pointer = saved_char;
13434 demand_empty_rest_of_line ();
13435 return;
13436 }
13437
13438 as_bad (_("unknown architecture `%s'\n"), name);
13439 *input_line_pointer = saved_char;
13440 ignore_rest_of_line ();
13441}
13442
13443
13444/* Parse a .fpu directive. */
13445
13446static void
13447s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
13448{
13449 struct arm_option_value_table *opt;
13450 char saved_char;
13451 char *name;
13452
13453 name = input_line_pointer;
13454 while (*input_line_pointer && !ISSPACE(*input_line_pointer))
13455 input_line_pointer++;
13456 saved_char = *input_line_pointer;
13457 *input_line_pointer = 0;
13458
13459 for (opt = arm_fpus; opt->name != NULL; opt++)
13460 if (streq (opt->name, name))
13461 {
13462 mfpu_opt = opt->value;
13463 cpu_variant = mcpu_cpu_opt | mfpu_opt;
13464 *input_line_pointer = saved_char;
13465 demand_empty_rest_of_line ();
13466 return;
13467 }
13468
13469 as_bad (_("unknown floating point format `%s'\n"), name);
13470 *input_line_pointer = saved_char;
13471 ignore_rest_of_line ();
13472}
13473#endif /* OBJ_ELF */
13474
This page took 1.211191 seconds and 4 git commands to generate.