]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-arm.c
[PATCH 1/57][Arm][GAS]: Add support for +mve and +mve.fp
[thirdparty/binutils-gdb.git] / gas / config / tc-arm.c
CommitLineData
b99bd4ef 1/* tc-arm.c -- Assemble for the ARM
82704155 2 Copyright (C) 1994-2019 Free Software Foundation, Inc.
b99bd4ef
NC
3 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
4 Modified by David Taylor (dtaylor@armltd.co.uk)
22d9c8c5 5 Cirrus coprocessor mods by Aldy Hernandez (aldyh@redhat.com)
34920d91
NC
6 Cirrus coprocessor fixes by Petko Manolov (petkan@nucleusys.com)
7 Cirrus coprocessor fixes by Vladimir Ivanov (vladitx@nucleusys.com)
b99bd4ef
NC
8
9 This file is part of GAS, the GNU Assembler.
10
11 GAS is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
ec2655a6 13 the Free Software Foundation; either version 3, or (at your option)
b99bd4ef
NC
14 any later version.
15
16 GAS is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
c19d1205 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
b99bd4ef
NC
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with GAS; see the file COPYING. If not, write to the Free
699d2810
NC
23 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
24 02110-1301, USA. */
b99bd4ef 25
42a68e18 26#include "as.h"
5287ad62 27#include <limits.h>
037e8744 28#include <stdarg.h>
c19d1205 29#define NO_RELOC 0
3882b010 30#include "safe-ctype.h"
b99bd4ef
NC
31#include "subsegs.h"
32#include "obstack.h"
3da1d841 33#include "libiberty.h"
f263249b
RE
34#include "opcode/arm.h"
35
b99bd4ef
NC
36#ifdef OBJ_ELF
37#include "elf/arm.h"
a394c00f 38#include "dw2gencfi.h"
b99bd4ef
NC
39#endif
40
f0927246
NC
41#include "dwarf2dbg.h"
42
7ed4c4c5
NC
43#ifdef OBJ_ELF
44/* Must be at least the size of the largest unwind opcode (currently two). */
45#define ARM_OPCODE_CHUNK_SIZE 8
46
47/* This structure holds the unwinding state. */
48
49static struct
50{
c19d1205
ZW
51 symbolS * proc_start;
52 symbolS * table_entry;
53 symbolS * personality_routine;
54 int personality_index;
7ed4c4c5 55 /* The segment containing the function. */
c19d1205
ZW
56 segT saved_seg;
57 subsegT saved_subseg;
7ed4c4c5
NC
58 /* Opcodes generated from this function. */
59 unsigned char * opcodes;
c19d1205
ZW
60 int opcode_count;
61 int opcode_alloc;
7ed4c4c5 62 /* The number of bytes pushed to the stack. */
c19d1205 63 offsetT frame_size;
7ed4c4c5
NC
64 /* We don't add stack adjustment opcodes immediately so that we can merge
65 multiple adjustments. We can also omit the final adjustment
66 when using a frame pointer. */
c19d1205 67 offsetT pending_offset;
7ed4c4c5 68 /* These two fields are set by both unwind_movsp and unwind_setfp. They
c19d1205
ZW
69 hold the reg+offset to use when restoring sp from a frame pointer. */
70 offsetT fp_offset;
71 int fp_reg;
7ed4c4c5 72 /* Nonzero if an unwind_setfp directive has been seen. */
c19d1205 73 unsigned fp_used:1;
7ed4c4c5 74 /* Nonzero if the last opcode restores sp from fp_reg. */
c19d1205 75 unsigned sp_restored:1;
7ed4c4c5
NC
76} unwind;
77
18a20338
CL
78/* Whether --fdpic was given. */
79static int arm_fdpic;
80
8b1ad454
NC
81#endif /* OBJ_ELF */
82
4962c51a
MS
83/* Results from operand parsing worker functions. */
84
85typedef enum
86{
87 PARSE_OPERAND_SUCCESS,
88 PARSE_OPERAND_FAIL,
89 PARSE_OPERAND_FAIL_NO_BACKTRACK
90} parse_operand_result;
91
33a392fb
PB
92enum arm_float_abi
93{
94 ARM_FLOAT_ABI_HARD,
95 ARM_FLOAT_ABI_SOFTFP,
96 ARM_FLOAT_ABI_SOFT
97};
98
c19d1205 99/* Types of processor to assemble for. */
b99bd4ef 100#ifndef CPU_DEFAULT
8a59fff3 101/* The code that was here used to select a default CPU depending on compiler
fa94de6b 102 pre-defines which were only present when doing native builds, thus
8a59fff3
MGD
103 changing gas' default behaviour depending upon the build host.
104
105 If you have a target that requires a default CPU option then the you
106 should define CPU_DEFAULT here. */
b99bd4ef
NC
107#endif
108
109#ifndef FPU_DEFAULT
c820d418
MM
110# ifdef TE_LINUX
111# define FPU_DEFAULT FPU_ARCH_FPA
112# elif defined (TE_NetBSD)
113# ifdef OBJ_ELF
114# define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, but VFP order. */
115# else
116 /* Legacy a.out format. */
117# define FPU_DEFAULT FPU_ARCH_FPA /* Soft-float, but FPA order. */
118# endif
4e7fd91e
PB
119# elif defined (TE_VXWORKS)
120# define FPU_DEFAULT FPU_ARCH_VFP /* Soft-float, VFP order. */
c820d418
MM
121# else
122 /* For backwards compatibility, default to FPA. */
123# define FPU_DEFAULT FPU_ARCH_FPA
124# endif
125#endif /* ifndef FPU_DEFAULT */
b99bd4ef 126
c19d1205 127#define streq(a, b) (strcmp (a, b) == 0)
b99bd4ef 128
4d354d8b
TP
129/* Current set of feature bits available (CPU+FPU). Different from
130 selected_cpu + selected_fpu in case of autodetection since the CPU
131 feature bits are then all set. */
e74cfd16 132static arm_feature_set cpu_variant;
4d354d8b
TP
133/* Feature bits used in each execution state. Used to set build attribute
134 (in particular Tag_*_ISA_use) in CPU autodetection mode. */
e74cfd16
PB
135static arm_feature_set arm_arch_used;
136static arm_feature_set thumb_arch_used;
b99bd4ef 137
b99bd4ef 138/* Flags stored in private area of BFD structure. */
c19d1205
ZW
139static int uses_apcs_26 = FALSE;
140static int atpcs = FALSE;
b34976b6
AM
141static int support_interwork = FALSE;
142static int uses_apcs_float = FALSE;
c19d1205 143static int pic_code = FALSE;
845b51d6 144static int fix_v4bx = FALSE;
278df34e
NS
145/* Warn on using deprecated features. */
146static int warn_on_deprecated = TRUE;
147
2e6976a8
DG
148/* Understand CodeComposer Studio assembly syntax. */
149bfd_boolean codecomposer_syntax = FALSE;
03b1477f
RE
150
151/* Variables that we set while parsing command-line options. Once all
152 options have been read we re-process these values to set the real
153 assembly flags. */
4d354d8b
TP
154
155/* CPU and FPU feature bits set for legacy CPU and FPU options (eg. -marm1
156 instead of -mcpu=arm1). */
157static const arm_feature_set *legacy_cpu = NULL;
158static const arm_feature_set *legacy_fpu = NULL;
159
160/* CPU, extension and FPU feature bits selected by -mcpu. */
161static const arm_feature_set *mcpu_cpu_opt = NULL;
162static arm_feature_set *mcpu_ext_opt = NULL;
163static const arm_feature_set *mcpu_fpu_opt = NULL;
164
165/* CPU, extension and FPU feature bits selected by -march. */
166static const arm_feature_set *march_cpu_opt = NULL;
167static arm_feature_set *march_ext_opt = NULL;
168static const arm_feature_set *march_fpu_opt = NULL;
169
170/* Feature bits selected by -mfpu. */
171static const arm_feature_set *mfpu_opt = NULL;
e74cfd16
PB
172
173/* Constants for known architecture features. */
174static const arm_feature_set fpu_default = FPU_DEFAULT;
f85d59c3 175static const arm_feature_set fpu_arch_vfp_v1 ATTRIBUTE_UNUSED = FPU_ARCH_VFP_V1;
e74cfd16 176static const arm_feature_set fpu_arch_vfp_v2 = FPU_ARCH_VFP_V2;
f85d59c3
KT
177static const arm_feature_set fpu_arch_vfp_v3 ATTRIBUTE_UNUSED = FPU_ARCH_VFP_V3;
178static const arm_feature_set fpu_arch_neon_v1 ATTRIBUTE_UNUSED = FPU_ARCH_NEON_V1;
e74cfd16
PB
179static const arm_feature_set fpu_arch_fpa = FPU_ARCH_FPA;
180static const arm_feature_set fpu_any_hard = FPU_ANY_HARD;
69c9e028 181#ifdef OBJ_ELF
e74cfd16 182static const arm_feature_set fpu_arch_maverick = FPU_ARCH_MAVERICK;
69c9e028 183#endif
e74cfd16
PB
184static const arm_feature_set fpu_endian_pure = FPU_ARCH_ENDIAN_PURE;
185
186#ifdef CPU_DEFAULT
187static const arm_feature_set cpu_default = CPU_DEFAULT;
188#endif
189
823d2571 190static const arm_feature_set arm_ext_v1 = ARM_FEATURE_CORE_LOW (ARM_EXT_V1);
4070243b 191static const arm_feature_set arm_ext_v2 = ARM_FEATURE_CORE_LOW (ARM_EXT_V2);
823d2571
TG
192static const arm_feature_set arm_ext_v2s = ARM_FEATURE_CORE_LOW (ARM_EXT_V2S);
193static const arm_feature_set arm_ext_v3 = ARM_FEATURE_CORE_LOW (ARM_EXT_V3);
194static const arm_feature_set arm_ext_v3m = ARM_FEATURE_CORE_LOW (ARM_EXT_V3M);
195static const arm_feature_set arm_ext_v4 = ARM_FEATURE_CORE_LOW (ARM_EXT_V4);
196static const arm_feature_set arm_ext_v4t = ARM_FEATURE_CORE_LOW (ARM_EXT_V4T);
197static const arm_feature_set arm_ext_v5 = ARM_FEATURE_CORE_LOW (ARM_EXT_V5);
e74cfd16 198static const arm_feature_set arm_ext_v4t_5 =
823d2571
TG
199 ARM_FEATURE_CORE_LOW (ARM_EXT_V4T | ARM_EXT_V5);
200static const arm_feature_set arm_ext_v5t = ARM_FEATURE_CORE_LOW (ARM_EXT_V5T);
201static const arm_feature_set arm_ext_v5e = ARM_FEATURE_CORE_LOW (ARM_EXT_V5E);
202static const arm_feature_set arm_ext_v5exp = ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP);
203static const arm_feature_set arm_ext_v5j = ARM_FEATURE_CORE_LOW (ARM_EXT_V5J);
204static const arm_feature_set arm_ext_v6 = ARM_FEATURE_CORE_LOW (ARM_EXT_V6);
205static const arm_feature_set arm_ext_v6k = ARM_FEATURE_CORE_LOW (ARM_EXT_V6K);
206static const arm_feature_set arm_ext_v6t2 = ARM_FEATURE_CORE_LOW (ARM_EXT_V6T2);
55e8aae7
SP
207/* Only for compatability of hint instructions. */
208static const arm_feature_set arm_ext_v6k_v6t2 =
209 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K | ARM_EXT_V6T2);
823d2571
TG
210static const arm_feature_set arm_ext_v6_notm =
211 ARM_FEATURE_CORE_LOW (ARM_EXT_V6_NOTM);
212static const arm_feature_set arm_ext_v6_dsp =
213 ARM_FEATURE_CORE_LOW (ARM_EXT_V6_DSP);
214static const arm_feature_set arm_ext_barrier =
215 ARM_FEATURE_CORE_LOW (ARM_EXT_BARRIER);
216static const arm_feature_set arm_ext_msr =
217 ARM_FEATURE_CORE_LOW (ARM_EXT_THUMB_MSR);
218static const arm_feature_set arm_ext_div = ARM_FEATURE_CORE_LOW (ARM_EXT_DIV);
219static const arm_feature_set arm_ext_v7 = ARM_FEATURE_CORE_LOW (ARM_EXT_V7);
220static const arm_feature_set arm_ext_v7a = ARM_FEATURE_CORE_LOW (ARM_EXT_V7A);
221static const arm_feature_set arm_ext_v7r = ARM_FEATURE_CORE_LOW (ARM_EXT_V7R);
69c9e028 222#ifdef OBJ_ELF
e7d39ed3 223static const arm_feature_set ATTRIBUTE_UNUSED arm_ext_v7m = ARM_FEATURE_CORE_LOW (ARM_EXT_V7M);
69c9e028 224#endif
823d2571 225static const arm_feature_set arm_ext_v8 = ARM_FEATURE_CORE_LOW (ARM_EXT_V8);
7e806470 226static const arm_feature_set arm_ext_m =
173205ca 227 ARM_FEATURE_CORE (ARM_EXT_V6M | ARM_EXT_V7M,
16a1fa25 228 ARM_EXT2_V8M | ARM_EXT2_V8M_MAIN);
823d2571
TG
229static const arm_feature_set arm_ext_mp = ARM_FEATURE_CORE_LOW (ARM_EXT_MP);
230static const arm_feature_set arm_ext_sec = ARM_FEATURE_CORE_LOW (ARM_EXT_SEC);
231static const arm_feature_set arm_ext_os = ARM_FEATURE_CORE_LOW (ARM_EXT_OS);
232static const arm_feature_set arm_ext_adiv = ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV);
233static const arm_feature_set arm_ext_virt = ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT);
ddfded2f 234static const arm_feature_set arm_ext_pan = ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN);
4ed7ed8d 235static const arm_feature_set arm_ext_v8m = ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M);
16a1fa25
TP
236static const arm_feature_set arm_ext_v8m_main =
237 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M_MAIN);
e12437dc
AV
238static const arm_feature_set arm_ext_v8_1m_main =
239ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_1M_MAIN);
16a1fa25
TP
240/* Instructions in ARMv8-M only found in M profile architectures. */
241static const arm_feature_set arm_ext_v8m_m_only =
242 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8M | ARM_EXT2_V8M_MAIN);
ff8646ee
TP
243static const arm_feature_set arm_ext_v6t2_v8m =
244 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V6T2_V8M);
4ed7ed8d
TP
245/* Instructions shared between ARMv8-A and ARMv8-M. */
246static const arm_feature_set arm_ext_atomics =
247 ARM_FEATURE_CORE_HIGH (ARM_EXT2_ATOMICS);
69c9e028 248#ifdef OBJ_ELF
15afaa63
TP
249/* DSP instructions Tag_DSP_extension refers to. */
250static const arm_feature_set arm_ext_dsp =
251 ARM_FEATURE_CORE_LOW (ARM_EXT_V5E | ARM_EXT_V5ExP | ARM_EXT_V6_DSP);
69c9e028 252#endif
4d1464f2
MW
253static const arm_feature_set arm_ext_ras =
254 ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS);
b8ec4e87
JW
255/* FP16 instructions. */
256static const arm_feature_set arm_ext_fp16 =
257 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST);
01f48020
TC
258static const arm_feature_set arm_ext_fp16_fml =
259 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_FML);
dec41383
JW
260static const arm_feature_set arm_ext_v8_2 =
261 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_2A);
49e8a725
SN
262static const arm_feature_set arm_ext_v8_3 =
263 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8_3A);
7fadb25d
SD
264static const arm_feature_set arm_ext_sb =
265 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB);
dad0c3bf
SD
266static const arm_feature_set arm_ext_predres =
267 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES);
e74cfd16
PB
268
269static const arm_feature_set arm_arch_any = ARM_ANY;
49fa50ef 270#ifdef OBJ_ELF
2c6b98ea 271static const arm_feature_set fpu_any = FPU_ANY;
49fa50ef 272#endif
f85d59c3 273static const arm_feature_set arm_arch_full ATTRIBUTE_UNUSED = ARM_FEATURE (-1, -1, -1);
e74cfd16
PB
274static const arm_feature_set arm_arch_t2 = ARM_ARCH_THUMB2;
275static const arm_feature_set arm_arch_none = ARM_ARCH_NONE;
276
2d447fca 277static const arm_feature_set arm_cext_iwmmxt2 =
823d2571 278 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2);
e74cfd16 279static const arm_feature_set arm_cext_iwmmxt =
823d2571 280 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT);
e74cfd16 281static const arm_feature_set arm_cext_xscale =
823d2571 282 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE);
e74cfd16 283static const arm_feature_set arm_cext_maverick =
823d2571
TG
284 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK);
285static const arm_feature_set fpu_fpa_ext_v1 =
286 ARM_FEATURE_COPROC (FPU_FPA_EXT_V1);
287static const arm_feature_set fpu_fpa_ext_v2 =
288 ARM_FEATURE_COPROC (FPU_FPA_EXT_V2);
e74cfd16 289static const arm_feature_set fpu_vfp_ext_v1xd =
823d2571
TG
290 ARM_FEATURE_COPROC (FPU_VFP_EXT_V1xD);
291static const arm_feature_set fpu_vfp_ext_v1 =
292 ARM_FEATURE_COPROC (FPU_VFP_EXT_V1);
293static const arm_feature_set fpu_vfp_ext_v2 =
294 ARM_FEATURE_COPROC (FPU_VFP_EXT_V2);
295static const arm_feature_set fpu_vfp_ext_v3xd =
296 ARM_FEATURE_COPROC (FPU_VFP_EXT_V3xD);
297static const arm_feature_set fpu_vfp_ext_v3 =
298 ARM_FEATURE_COPROC (FPU_VFP_EXT_V3);
b1cc4aeb 299static const arm_feature_set fpu_vfp_ext_d32 =
823d2571
TG
300 ARM_FEATURE_COPROC (FPU_VFP_EXT_D32);
301static const arm_feature_set fpu_neon_ext_v1 =
302 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1);
5287ad62 303static const arm_feature_set fpu_vfp_v3_or_neon_ext =
823d2571 304 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_VFP_EXT_V3);
a7ad558c
AV
305static const arm_feature_set mve_ext =
306 ARM_FEATURE_COPROC (FPU_MVE);
307static const arm_feature_set mve_fp_ext =
308 ARM_FEATURE_COPROC (FPU_MVE_FP);
69c9e028 309#ifdef OBJ_ELF
823d2571
TG
310static const arm_feature_set fpu_vfp_fp16 =
311 ARM_FEATURE_COPROC (FPU_VFP_EXT_FP16);
312static const arm_feature_set fpu_neon_ext_fma =
313 ARM_FEATURE_COPROC (FPU_NEON_EXT_FMA);
69c9e028 314#endif
823d2571
TG
315static const arm_feature_set fpu_vfp_ext_fma =
316 ARM_FEATURE_COPROC (FPU_VFP_EXT_FMA);
bca38921 317static const arm_feature_set fpu_vfp_ext_armv8 =
823d2571 318 ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8);
a715796b 319static const arm_feature_set fpu_vfp_ext_armv8xd =
823d2571 320 ARM_FEATURE_COPROC (FPU_VFP_EXT_ARMV8xD);
bca38921 321static const arm_feature_set fpu_neon_ext_armv8 =
823d2571 322 ARM_FEATURE_COPROC (FPU_NEON_EXT_ARMV8);
bca38921 323static const arm_feature_set fpu_crypto_ext_armv8 =
823d2571 324 ARM_FEATURE_COPROC (FPU_CRYPTO_EXT_ARMV8);
dd5181d5 325static const arm_feature_set crc_ext_armv8 =
823d2571 326 ARM_FEATURE_COPROC (CRC_EXT_ARMV8);
d6b4b13e 327static const arm_feature_set fpu_neon_ext_v8_1 =
643afb90 328 ARM_FEATURE_COPROC (FPU_NEON_EXT_RDMA);
c604a79a
JW
329static const arm_feature_set fpu_neon_ext_dotprod =
330 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD);
e74cfd16 331
33a392fb 332static int mfloat_abi_opt = -1;
4d354d8b
TP
333/* Architecture feature bits selected by the last -mcpu/-march or .cpu/.arch
334 directive. */
335static arm_feature_set selected_arch = ARM_ARCH_NONE;
336/* Extension feature bits selected by the last -mcpu/-march or .arch_extension
337 directive. */
338static arm_feature_set selected_ext = ARM_ARCH_NONE;
339/* Feature bits selected by the last -mcpu/-march or by the combination of the
340 last .cpu/.arch directive .arch_extension directives since that
341 directive. */
e74cfd16 342static arm_feature_set selected_cpu = ARM_ARCH_NONE;
4d354d8b
TP
343/* FPU feature bits selected by the last -mfpu or .fpu directive. */
344static arm_feature_set selected_fpu = FPU_NONE;
345/* Feature bits selected by the last .object_arch directive. */
346static arm_feature_set selected_object_arch = ARM_ARCH_NONE;
ee065d83 347/* Must be long enough to hold any of the names in arm_cpus. */
ef8e6722 348static char selected_cpu_name[20];
8d67f500 349
aacf0b33
KT
350extern FLONUM_TYPE generic_floating_point_number;
351
8d67f500
NC
352/* Return if no cpu was selected on command-line. */
353static bfd_boolean
354no_cpu_selected (void)
355{
823d2571 356 return ARM_FEATURE_EQUAL (selected_cpu, arm_arch_none);
8d67f500
NC
357}
358
7cc69913 359#ifdef OBJ_ELF
deeaaff8
DJ
360# ifdef EABI_DEFAULT
361static int meabi_flags = EABI_DEFAULT;
362# else
d507cf36 363static int meabi_flags = EF_ARM_EABI_UNKNOWN;
deeaaff8 364# endif
e1da3f5b 365
ee3c0378
AS
366static int attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES];
367
e1da3f5b 368bfd_boolean
5f4273c7 369arm_is_eabi (void)
e1da3f5b
PB
370{
371 return (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4);
372}
7cc69913 373#endif
b99bd4ef 374
b99bd4ef 375#ifdef OBJ_ELF
c19d1205 376/* Pre-defined "_GLOBAL_OFFSET_TABLE_" */
b99bd4ef
NC
377symbolS * GOT_symbol;
378#endif
379
b99bd4ef
NC
380/* 0: assemble for ARM,
381 1: assemble for Thumb,
382 2: assemble for Thumb even though target CPU does not support thumb
383 instructions. */
384static int thumb_mode = 0;
8dc2430f
NC
385/* A value distinct from the possible values for thumb_mode that we
386 can use to record whether thumb_mode has been copied into the
387 tc_frag_data field of a frag. */
388#define MODE_RECORDED (1 << 4)
b99bd4ef 389
e07e6e58
NC
390/* Specifies the intrinsic IT insn behavior mode. */
391enum implicit_it_mode
392{
393 IMPLICIT_IT_MODE_NEVER = 0x00,
394 IMPLICIT_IT_MODE_ARM = 0x01,
395 IMPLICIT_IT_MODE_THUMB = 0x02,
396 IMPLICIT_IT_MODE_ALWAYS = (IMPLICIT_IT_MODE_ARM | IMPLICIT_IT_MODE_THUMB)
397};
398static int implicit_it_mode = IMPLICIT_IT_MODE_ARM;
399
c19d1205
ZW
400/* If unified_syntax is true, we are processing the new unified
401 ARM/Thumb syntax. Important differences from the old ARM mode:
402
403 - Immediate operands do not require a # prefix.
404 - Conditional affixes always appear at the end of the
405 instruction. (For backward compatibility, those instructions
406 that formerly had them in the middle, continue to accept them
407 there.)
408 - The IT instruction may appear, and if it does is validated
409 against subsequent conditional affixes. It does not generate
410 machine code.
411
412 Important differences from the old Thumb mode:
413
414 - Immediate operands do not require a # prefix.
415 - Most of the V6T2 instructions are only available in unified mode.
416 - The .N and .W suffixes are recognized and honored (it is an error
417 if they cannot be honored).
418 - All instructions set the flags if and only if they have an 's' affix.
419 - Conditional affixes may be used. They are validated against
420 preceding IT instructions. Unlike ARM mode, you cannot use a
421 conditional affix except in the scope of an IT instruction. */
422
423static bfd_boolean unified_syntax = FALSE;
b99bd4ef 424
bacebabc
RM
425/* An immediate operand can start with #, and ld*, st*, pld operands
426 can contain [ and ]. We need to tell APP not to elide whitespace
477330fc
RM
427 before a [, which can appear as the first operand for pld.
428 Likewise, a { can appear as the first operand for push, pop, vld*, etc. */
429const char arm_symbol_chars[] = "#[]{}";
bacebabc 430
5287ad62
JB
431enum neon_el_type
432{
dcbf9037 433 NT_invtype,
5287ad62
JB
434 NT_untyped,
435 NT_integer,
436 NT_float,
437 NT_poly,
438 NT_signed,
dcbf9037 439 NT_unsigned
5287ad62
JB
440};
441
442struct neon_type_el
443{
444 enum neon_el_type type;
445 unsigned size;
446};
447
448#define NEON_MAX_TYPE_ELS 4
449
450struct neon_type
451{
452 struct neon_type_el el[NEON_MAX_TYPE_ELS];
453 unsigned elems;
454};
455
e07e6e58
NC
456enum it_instruction_type
457{
458 OUTSIDE_IT_INSN,
459 INSIDE_IT_INSN,
460 INSIDE_IT_LAST_INSN,
461 IF_INSIDE_IT_LAST_INSN, /* Either outside or inside;
477330fc 462 if inside, should be the last one. */
e07e6e58 463 NEUTRAL_IT_INSN, /* This could be either inside or outside,
477330fc 464 i.e. BKPT and NOP. */
e07e6e58
NC
465 IT_INSN /* The IT insn has been parsed. */
466};
467
ad6cec43
MGD
468/* The maximum number of operands we need. */
469#define ARM_IT_MAX_OPERANDS 6
e2b0ab59 470#define ARM_IT_MAX_RELOCS 3
ad6cec43 471
b99bd4ef
NC
472struct arm_it
473{
c19d1205 474 const char * error;
b99bd4ef 475 unsigned long instruction;
c19d1205
ZW
476 int size;
477 int size_req;
478 int cond;
037e8744
JB
479 /* "uncond_value" is set to the value in place of the conditional field in
480 unconditional versions of the instruction, or -1 if nothing is
481 appropriate. */
482 int uncond_value;
5287ad62 483 struct neon_type vectype;
88714cb8
DG
484 /* This does not indicate an actual NEON instruction, only that
485 the mnemonic accepts neon-style type suffixes. */
486 int is_neon;
0110f2b8
PB
487 /* Set to the opcode if the instruction needs relaxation.
488 Zero if the instruction is not relaxed. */
489 unsigned long relax;
b99bd4ef
NC
490 struct
491 {
492 bfd_reloc_code_real_type type;
c19d1205
ZW
493 expressionS exp;
494 int pc_rel;
e2b0ab59 495 } relocs[ARM_IT_MAX_RELOCS];
b99bd4ef 496
e07e6e58
NC
497 enum it_instruction_type it_insn_type;
498
c19d1205
ZW
499 struct
500 {
501 unsigned reg;
ca3f61f7 502 signed int imm;
dcbf9037 503 struct neon_type_el vectype;
ca3f61f7
NC
504 unsigned present : 1; /* Operand present. */
505 unsigned isreg : 1; /* Operand was a register. */
506 unsigned immisreg : 1; /* .imm field is a second register. */
5287ad62
JB
507 unsigned isscalar : 1; /* Operand is a (Neon) scalar. */
508 unsigned immisalign : 1; /* Immediate is an alignment specifier. */
c96612cc 509 unsigned immisfloat : 1; /* Immediate was parsed as a float. */
5287ad62
JB
510 /* Note: we abuse "regisimm" to mean "is Neon register" in VMOV
511 instructions. This allows us to disambiguate ARM <-> vector insns. */
512 unsigned regisimm : 1; /* 64-bit immediate, reg forms high 32 bits. */
037e8744 513 unsigned isvec : 1; /* Is a single, double or quad VFP/Neon reg. */
5287ad62 514 unsigned isquad : 1; /* Operand is Neon quad-precision register. */
037e8744 515 unsigned issingle : 1; /* Operand is VFP single-precision register. */
ca3f61f7
NC
516 unsigned hasreloc : 1; /* Operand has relocation suffix. */
517 unsigned writeback : 1; /* Operand has trailing ! */
518 unsigned preind : 1; /* Preindexed address. */
519 unsigned postind : 1; /* Postindexed address. */
520 unsigned negative : 1; /* Index register was negated. */
521 unsigned shifted : 1; /* Shift applied to operation. */
522 unsigned shift_kind : 3; /* Shift operation (enum shift_kind). */
ad6cec43 523 } operands[ARM_IT_MAX_OPERANDS];
b99bd4ef
NC
524};
525
c19d1205 526static struct arm_it inst;
b99bd4ef
NC
527
528#define NUM_FLOAT_VALS 8
529
05d2d07e 530const char * fp_const[] =
b99bd4ef
NC
531{
532 "0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0", 0
533};
534
b99bd4ef
NC
535LITTLENUM_TYPE fp_values[NUM_FLOAT_VALS][MAX_LITTLENUMS];
536
537#define FAIL (-1)
538#define SUCCESS (0)
539
540#define SUFF_S 1
541#define SUFF_D 2
542#define SUFF_E 3
543#define SUFF_P 4
544
c19d1205
ZW
545#define CP_T_X 0x00008000
546#define CP_T_Y 0x00400000
b99bd4ef 547
c19d1205
ZW
548#define CONDS_BIT 0x00100000
549#define LOAD_BIT 0x00100000
b99bd4ef
NC
550
551#define DOUBLE_LOAD_FLAG 0x00000001
552
553struct asm_cond
554{
d3ce72d0 555 const char * template_name;
c921be7d 556 unsigned long value;
b99bd4ef
NC
557};
558
c19d1205 559#define COND_ALWAYS 0xE
b99bd4ef 560
b99bd4ef
NC
561struct asm_psr
562{
d3ce72d0 563 const char * template_name;
c921be7d 564 unsigned long field;
b99bd4ef
NC
565};
566
62b3e311
PB
567struct asm_barrier_opt
568{
e797f7e0
MGD
569 const char * template_name;
570 unsigned long value;
571 const arm_feature_set arch;
62b3e311
PB
572};
573
2d2255b5 574/* The bit that distinguishes CPSR and SPSR. */
b99bd4ef
NC
575#define SPSR_BIT (1 << 22)
576
c19d1205
ZW
577/* The individual PSR flag bits. */
578#define PSR_c (1 << 16)
579#define PSR_x (1 << 17)
580#define PSR_s (1 << 18)
581#define PSR_f (1 << 19)
b99bd4ef 582
c19d1205 583struct reloc_entry
bfae80f2 584{
0198d5e6 585 const char * name;
c921be7d 586 bfd_reloc_code_real_type reloc;
bfae80f2
RE
587};
588
5287ad62 589enum vfp_reg_pos
bfae80f2 590{
5287ad62
JB
591 VFP_REG_Sd, VFP_REG_Sm, VFP_REG_Sn,
592 VFP_REG_Dd, VFP_REG_Dm, VFP_REG_Dn
bfae80f2
RE
593};
594
595enum vfp_ldstm_type
596{
597 VFP_LDSTMIA, VFP_LDSTMDB, VFP_LDSTMIAX, VFP_LDSTMDBX
598};
599
dcbf9037
JB
600/* Bits for DEFINED field in neon_typed_alias. */
601#define NTA_HASTYPE 1
602#define NTA_HASINDEX 2
603
604struct neon_typed_alias
605{
c921be7d
NC
606 unsigned char defined;
607 unsigned char index;
608 struct neon_type_el eltype;
dcbf9037
JB
609};
610
c19d1205 611/* ARM register categories. This includes coprocessor numbers and various
5aa75429
TP
612 architecture extensions' registers. Each entry should have an error message
613 in reg_expected_msgs below. */
c19d1205 614enum arm_reg_type
bfae80f2 615{
c19d1205
ZW
616 REG_TYPE_RN,
617 REG_TYPE_CP,
618 REG_TYPE_CN,
619 REG_TYPE_FN,
620 REG_TYPE_VFS,
621 REG_TYPE_VFD,
5287ad62 622 REG_TYPE_NQ,
037e8744 623 REG_TYPE_VFSD,
5287ad62 624 REG_TYPE_NDQ,
dec41383 625 REG_TYPE_NSD,
037e8744 626 REG_TYPE_NSDQ,
c19d1205
ZW
627 REG_TYPE_VFC,
628 REG_TYPE_MVF,
629 REG_TYPE_MVD,
630 REG_TYPE_MVFX,
631 REG_TYPE_MVDX,
632 REG_TYPE_MVAX,
633 REG_TYPE_DSPSC,
634 REG_TYPE_MMXWR,
635 REG_TYPE_MMXWC,
636 REG_TYPE_MMXWCG,
637 REG_TYPE_XSCALE,
90ec0d68 638 REG_TYPE_RNB
bfae80f2
RE
639};
640
dcbf9037
JB
641/* Structure for a hash table entry for a register.
642 If TYPE is REG_TYPE_VFD or REG_TYPE_NQ, the NEON field can point to extra
643 information which states whether a vector type or index is specified (for a
644 register alias created with .dn or .qn). Otherwise NEON should be NULL. */
6c43fab6
RE
645struct reg_entry
646{
c921be7d 647 const char * name;
90ec0d68 648 unsigned int number;
c921be7d
NC
649 unsigned char type;
650 unsigned char builtin;
651 struct neon_typed_alias * neon;
6c43fab6
RE
652};
653
c19d1205 654/* Diagnostics used when we don't get a register of the expected type. */
c921be7d 655const char * const reg_expected_msgs[] =
c19d1205 656{
5aa75429
TP
657 [REG_TYPE_RN] = N_("ARM register expected"),
658 [REG_TYPE_CP] = N_("bad or missing co-processor number"),
659 [REG_TYPE_CN] = N_("co-processor register expected"),
660 [REG_TYPE_FN] = N_("FPA register expected"),
661 [REG_TYPE_VFS] = N_("VFP single precision register expected"),
662 [REG_TYPE_VFD] = N_("VFP/Neon double precision register expected"),
663 [REG_TYPE_NQ] = N_("Neon quad precision register expected"),
664 [REG_TYPE_VFSD] = N_("VFP single or double precision register expected"),
665 [REG_TYPE_NDQ] = N_("Neon double or quad precision register expected"),
666 [REG_TYPE_NSD] = N_("Neon single or double precision register expected"),
667 [REG_TYPE_NSDQ] = N_("VFP single, double or Neon quad precision register"
668 " expected"),
669 [REG_TYPE_VFC] = N_("VFP system register expected"),
670 [REG_TYPE_MVF] = N_("Maverick MVF register expected"),
671 [REG_TYPE_MVD] = N_("Maverick MVD register expected"),
672 [REG_TYPE_MVFX] = N_("Maverick MVFX register expected"),
673 [REG_TYPE_MVDX] = N_("Maverick MVDX register expected"),
674 [REG_TYPE_MVAX] = N_("Maverick MVAX register expected"),
675 [REG_TYPE_DSPSC] = N_("Maverick DSPSC register expected"),
676 [REG_TYPE_MMXWR] = N_("iWMMXt data register expected"),
677 [REG_TYPE_MMXWC] = N_("iWMMXt control register expected"),
678 [REG_TYPE_MMXWCG] = N_("iWMMXt scalar register expected"),
679 [REG_TYPE_XSCALE] = N_("XScale accumulator register expected"),
680 [REG_TYPE_RNB] = N_("")
6c43fab6
RE
681};
682
c19d1205 683/* Some well known registers that we refer to directly elsewhere. */
bd340a04 684#define REG_R12 12
c19d1205
ZW
685#define REG_SP 13
686#define REG_LR 14
687#define REG_PC 15
404ff6b5 688
b99bd4ef
NC
689/* ARM instructions take 4bytes in the object file, Thumb instructions
690 take 2: */
c19d1205 691#define INSN_SIZE 4
b99bd4ef
NC
692
693struct asm_opcode
694{
695 /* Basic string to match. */
d3ce72d0 696 const char * template_name;
c19d1205
ZW
697
698 /* Parameters to instruction. */
5be8be5d 699 unsigned int operands[8];
c19d1205
ZW
700
701 /* Conditional tag - see opcode_lookup. */
702 unsigned int tag : 4;
b99bd4ef
NC
703
704 /* Basic instruction code. */
c19d1205 705 unsigned int avalue : 28;
b99bd4ef 706
c19d1205
ZW
707 /* Thumb-format instruction code. */
708 unsigned int tvalue;
b99bd4ef 709
90e4755a 710 /* Which architecture variant provides this instruction. */
c921be7d
NC
711 const arm_feature_set * avariant;
712 const arm_feature_set * tvariant;
c19d1205
ZW
713
714 /* Function to call to encode instruction in ARM format. */
715 void (* aencode) (void);
b99bd4ef 716
c19d1205
ZW
717 /* Function to call to encode instruction in Thumb format. */
718 void (* tencode) (void);
b99bd4ef
NC
719};
720
a737bd4d
NC
721/* Defines for various bits that we will want to toggle. */
722#define INST_IMMEDIATE 0x02000000
723#define OFFSET_REG 0x02000000
c19d1205 724#define HWOFFSET_IMM 0x00400000
a737bd4d
NC
725#define SHIFT_BY_REG 0x00000010
726#define PRE_INDEX 0x01000000
727#define INDEX_UP 0x00800000
728#define WRITE_BACK 0x00200000
729#define LDM_TYPE_2_OR_3 0x00400000
a028a6f5 730#define CPSI_MMOD 0x00020000
90e4755a 731
a737bd4d
NC
732#define LITERAL_MASK 0xf000f000
733#define OPCODE_MASK 0xfe1fffff
734#define V4_STR_BIT 0x00000020
8335d6aa 735#define VLDR_VMOV_SAME 0x0040f000
90e4755a 736
efd81785
PB
737#define T2_SUBS_PC_LR 0xf3de8f00
738
a737bd4d 739#define DATA_OP_SHIFT 21
bada4342 740#define SBIT_SHIFT 20
90e4755a 741
ef8d22e6
PB
742#define T2_OPCODE_MASK 0xfe1fffff
743#define T2_DATA_OP_SHIFT 21
bada4342 744#define T2_SBIT_SHIFT 20
ef8d22e6 745
6530b175
NC
746#define A_COND_MASK 0xf0000000
747#define A_PUSH_POP_OP_MASK 0x0fff0000
748
749/* Opcodes for pushing/poping registers to/from the stack. */
750#define A1_OPCODE_PUSH 0x092d0000
751#define A2_OPCODE_PUSH 0x052d0004
752#define A2_OPCODE_POP 0x049d0004
753
a737bd4d
NC
754/* Codes to distinguish the arithmetic instructions. */
755#define OPCODE_AND 0
756#define OPCODE_EOR 1
757#define OPCODE_SUB 2
758#define OPCODE_RSB 3
759#define OPCODE_ADD 4
760#define OPCODE_ADC 5
761#define OPCODE_SBC 6
762#define OPCODE_RSC 7
763#define OPCODE_TST 8
764#define OPCODE_TEQ 9
765#define OPCODE_CMP 10
766#define OPCODE_CMN 11
767#define OPCODE_ORR 12
768#define OPCODE_MOV 13
769#define OPCODE_BIC 14
770#define OPCODE_MVN 15
90e4755a 771
ef8d22e6
PB
772#define T2_OPCODE_AND 0
773#define T2_OPCODE_BIC 1
774#define T2_OPCODE_ORR 2
775#define T2_OPCODE_ORN 3
776#define T2_OPCODE_EOR 4
777#define T2_OPCODE_ADD 8
778#define T2_OPCODE_ADC 10
779#define T2_OPCODE_SBC 11
780#define T2_OPCODE_SUB 13
781#define T2_OPCODE_RSB 14
782
a737bd4d
NC
783#define T_OPCODE_MUL 0x4340
784#define T_OPCODE_TST 0x4200
785#define T_OPCODE_CMN 0x42c0
786#define T_OPCODE_NEG 0x4240
787#define T_OPCODE_MVN 0x43c0
90e4755a 788
a737bd4d
NC
789#define T_OPCODE_ADD_R3 0x1800
790#define T_OPCODE_SUB_R3 0x1a00
791#define T_OPCODE_ADD_HI 0x4400
792#define T_OPCODE_ADD_ST 0xb000
793#define T_OPCODE_SUB_ST 0xb080
794#define T_OPCODE_ADD_SP 0xa800
795#define T_OPCODE_ADD_PC 0xa000
796#define T_OPCODE_ADD_I8 0x3000
797#define T_OPCODE_SUB_I8 0x3800
798#define T_OPCODE_ADD_I3 0x1c00
799#define T_OPCODE_SUB_I3 0x1e00
b99bd4ef 800
a737bd4d
NC
801#define T_OPCODE_ASR_R 0x4100
802#define T_OPCODE_LSL_R 0x4080
c19d1205
ZW
803#define T_OPCODE_LSR_R 0x40c0
804#define T_OPCODE_ROR_R 0x41c0
a737bd4d
NC
805#define T_OPCODE_ASR_I 0x1000
806#define T_OPCODE_LSL_I 0x0000
807#define T_OPCODE_LSR_I 0x0800
b99bd4ef 808
a737bd4d
NC
809#define T_OPCODE_MOV_I8 0x2000
810#define T_OPCODE_CMP_I8 0x2800
811#define T_OPCODE_CMP_LR 0x4280
812#define T_OPCODE_MOV_HR 0x4600
813#define T_OPCODE_CMP_HR 0x4500
b99bd4ef 814
a737bd4d
NC
815#define T_OPCODE_LDR_PC 0x4800
816#define T_OPCODE_LDR_SP 0x9800
817#define T_OPCODE_STR_SP 0x9000
818#define T_OPCODE_LDR_IW 0x6800
819#define T_OPCODE_STR_IW 0x6000
820#define T_OPCODE_LDR_IH 0x8800
821#define T_OPCODE_STR_IH 0x8000
822#define T_OPCODE_LDR_IB 0x7800
823#define T_OPCODE_STR_IB 0x7000
824#define T_OPCODE_LDR_RW 0x5800
825#define T_OPCODE_STR_RW 0x5000
826#define T_OPCODE_LDR_RH 0x5a00
827#define T_OPCODE_STR_RH 0x5200
828#define T_OPCODE_LDR_RB 0x5c00
829#define T_OPCODE_STR_RB 0x5400
c9b604bd 830
a737bd4d
NC
831#define T_OPCODE_PUSH 0xb400
832#define T_OPCODE_POP 0xbc00
b99bd4ef 833
2fc8bdac 834#define T_OPCODE_BRANCH 0xe000
b99bd4ef 835
a737bd4d 836#define THUMB_SIZE 2 /* Size of thumb instruction. */
a737bd4d 837#define THUMB_PP_PC_LR 0x0100
c19d1205 838#define THUMB_LOAD_BIT 0x0800
53365c0d 839#define THUMB2_LOAD_BIT 0x00100000
c19d1205
ZW
840
841#define BAD_ARGS _("bad arguments to instruction")
fdfde340 842#define BAD_SP _("r13 not allowed here")
c19d1205
ZW
843#define BAD_PC _("r15 not allowed here")
844#define BAD_COND _("instruction cannot be conditional")
845#define BAD_OVERLAP _("registers may not be the same")
846#define BAD_HIREG _("lo register required")
847#define BAD_THUMB32 _("instruction not supported in Thumb16 mode")
01cfc07f 848#define BAD_ADDR_MODE _("instruction does not accept this addressing mode");
dfa9f0d5 849#define BAD_BRANCH _("branch must be last instruction in IT block")
e12437dc 850#define BAD_BRANCH_OFF _("branch out of range or not a multiple of 2")
dfa9f0d5 851#define BAD_NOT_IT _("instruction not allowed in IT block")
037e8744 852#define BAD_FPU _("selected FPU does not support instruction")
e07e6e58
NC
853#define BAD_OUT_IT _("thumb conditional instruction should be in IT block")
854#define BAD_IT_COND _("incorrect condition in IT block")
855#define BAD_IT_IT _("IT falling in the range of a previous IT block")
921e5f0a 856#define MISSING_FNSTART _("missing .fnstart before unwinding directive")
5be8be5d
DG
857#define BAD_PC_ADDRESSING \
858 _("cannot use register index with PC-relative addressing")
859#define BAD_PC_WRITEBACK \
860 _("cannot use writeback with PC-relative addressing")
9db2f6b4
RL
861#define BAD_RANGE _("branch out of range")
862#define BAD_FP16 _("selected processor does not support fp16 instruction")
dd5181d5 863#define UNPRED_REG(R) _("using " R " results in unpredictable behaviour")
a9f02af8 864#define THUMB1_RELOC_ONLY _("relocation valid in thumb1 code only")
c19d1205 865
c921be7d
NC
866static struct hash_control * arm_ops_hsh;
867static struct hash_control * arm_cond_hsh;
868static struct hash_control * arm_shift_hsh;
869static struct hash_control * arm_psr_hsh;
870static struct hash_control * arm_v7m_psr_hsh;
871static struct hash_control * arm_reg_hsh;
872static struct hash_control * arm_reloc_hsh;
873static struct hash_control * arm_barrier_opt_hsh;
b99bd4ef 874
b99bd4ef
NC
875/* Stuff needed to resolve the label ambiguity
876 As:
877 ...
878 label: <insn>
879 may differ from:
880 ...
881 label:
5f4273c7 882 <insn> */
b99bd4ef
NC
883
884symbolS * last_label_seen;
b34976b6 885static int label_is_thumb_function_name = FALSE;
e07e6e58 886
3d0c9500
NC
887/* Literal pool structure. Held on a per-section
888 and per-sub-section basis. */
a737bd4d 889
c19d1205 890#define MAX_LITERAL_POOL_SIZE 1024
3d0c9500 891typedef struct literal_pool
b99bd4ef 892{
c921be7d
NC
893 expressionS literals [MAX_LITERAL_POOL_SIZE];
894 unsigned int next_free_entry;
895 unsigned int id;
896 symbolS * symbol;
897 segT section;
898 subsegT sub_section;
a8040cf2
NC
899#ifdef OBJ_ELF
900 struct dwarf2_line_info locs [MAX_LITERAL_POOL_SIZE];
901#endif
c921be7d 902 struct literal_pool * next;
8335d6aa 903 unsigned int alignment;
3d0c9500 904} literal_pool;
b99bd4ef 905
3d0c9500
NC
906/* Pointer to a linked list of literal pools. */
907literal_pool * list_of_pools = NULL;
e27ec89e 908
2e6976a8
DG
909typedef enum asmfunc_states
910{
911 OUTSIDE_ASMFUNC,
912 WAITING_ASMFUNC_NAME,
913 WAITING_ENDASMFUNC
914} asmfunc_states;
915
916static asmfunc_states asmfunc_state = OUTSIDE_ASMFUNC;
917
e07e6e58
NC
918#ifdef OBJ_ELF
919# define now_it seg_info (now_seg)->tc_segment_info_data.current_it
920#else
921static struct current_it now_it;
922#endif
923
924static inline int
925now_it_compatible (int cond)
926{
927 return (cond & ~1) == (now_it.cc & ~1);
928}
929
930static inline int
931conditional_insn (void)
932{
933 return inst.cond != COND_ALWAYS;
934}
935
936static int in_it_block (void);
937
938static int handle_it_state (void);
939
940static void force_automatic_it_block_close (void);
941
c921be7d
NC
942static void it_fsm_post_encode (void);
943
e07e6e58
NC
944#define set_it_insn_type(type) \
945 do \
946 { \
947 inst.it_insn_type = type; \
948 if (handle_it_state () == FAIL) \
477330fc 949 return; \
e07e6e58
NC
950 } \
951 while (0)
952
c921be7d
NC
953#define set_it_insn_type_nonvoid(type, failret) \
954 do \
955 { \
956 inst.it_insn_type = type; \
957 if (handle_it_state () == FAIL) \
477330fc 958 return failret; \
c921be7d
NC
959 } \
960 while(0)
961
e07e6e58
NC
962#define set_it_insn_type_last() \
963 do \
964 { \
965 if (inst.cond == COND_ALWAYS) \
477330fc 966 set_it_insn_type (IF_INSIDE_IT_LAST_INSN); \
e07e6e58 967 else \
477330fc 968 set_it_insn_type (INSIDE_IT_LAST_INSN); \
e07e6e58
NC
969 } \
970 while (0)
971
c19d1205 972/* Pure syntax. */
b99bd4ef 973
c19d1205
ZW
974/* This array holds the chars that always start a comment. If the
975 pre-processor is disabled, these aren't very useful. */
2e6976a8 976char arm_comment_chars[] = "@";
3d0c9500 977
c19d1205
ZW
978/* This array holds the chars that only start a comment at the beginning of
979 a line. If the line seems to have the form '# 123 filename'
980 .line and .file directives will appear in the pre-processed output. */
981/* Note that input_file.c hand checks for '#' at the beginning of the
982 first line of the input file. This is because the compiler outputs
983 #NO_APP at the beginning of its output. */
984/* Also note that comments like this one will always work. */
985const char line_comment_chars[] = "#";
3d0c9500 986
2e6976a8 987char arm_line_separator_chars[] = ";";
b99bd4ef 988
c19d1205
ZW
989/* Chars that can be used to separate mant
990 from exp in floating point numbers. */
991const char EXP_CHARS[] = "eE";
3d0c9500 992
c19d1205
ZW
993/* Chars that mean this number is a floating point constant. */
994/* As in 0f12.456 */
995/* or 0d1.2345e12 */
b99bd4ef 996
c19d1205 997const char FLT_CHARS[] = "rRsSfFdDxXeEpP";
3d0c9500 998
c19d1205
ZW
999/* Prefix characters that indicate the start of an immediate
1000 value. */
1001#define is_immediate_prefix(C) ((C) == '#' || (C) == '$')
3d0c9500 1002
c19d1205
ZW
1003/* Separator character handling. */
1004
1005#define skip_whitespace(str) do { if (*(str) == ' ') ++(str); } while (0)
1006
1007static inline int
1008skip_past_char (char ** str, char c)
1009{
8ab8155f
NC
1010 /* PR gas/14987: Allow for whitespace before the expected character. */
1011 skip_whitespace (*str);
427d0db6 1012
c19d1205
ZW
1013 if (**str == c)
1014 {
1015 (*str)++;
1016 return SUCCESS;
3d0c9500 1017 }
c19d1205
ZW
1018 else
1019 return FAIL;
1020}
c921be7d 1021
c19d1205 1022#define skip_past_comma(str) skip_past_char (str, ',')
3d0c9500 1023
c19d1205
ZW
1024/* Arithmetic expressions (possibly involving symbols). */
1025
1026/* Return TRUE if anything in the expression is a bignum. */
1027
0198d5e6 1028static bfd_boolean
c19d1205
ZW
1029walk_no_bignums (symbolS * sp)
1030{
1031 if (symbol_get_value_expression (sp)->X_op == O_big)
0198d5e6 1032 return TRUE;
c19d1205
ZW
1033
1034 if (symbol_get_value_expression (sp)->X_add_symbol)
3d0c9500 1035 {
c19d1205
ZW
1036 return (walk_no_bignums (symbol_get_value_expression (sp)->X_add_symbol)
1037 || (symbol_get_value_expression (sp)->X_op_symbol
1038 && walk_no_bignums (symbol_get_value_expression (sp)->X_op_symbol)));
3d0c9500
NC
1039 }
1040
0198d5e6 1041 return FALSE;
3d0c9500
NC
1042}
1043
0198d5e6 1044static bfd_boolean in_my_get_expression = FALSE;
c19d1205
ZW
1045
1046/* Third argument to my_get_expression. */
1047#define GE_NO_PREFIX 0
1048#define GE_IMM_PREFIX 1
1049#define GE_OPT_PREFIX 2
5287ad62
JB
1050/* This is a bit of a hack. Use an optional prefix, and also allow big (64-bit)
1051 immediates, as can be used in Neon VMVN and VMOV immediate instructions. */
1052#define GE_OPT_PREFIX_BIG 3
a737bd4d 1053
b99bd4ef 1054static int
c19d1205 1055my_get_expression (expressionS * ep, char ** str, int prefix_mode)
b99bd4ef 1056{
c19d1205 1057 char * save_in;
b99bd4ef 1058
c19d1205
ZW
1059 /* In unified syntax, all prefixes are optional. */
1060 if (unified_syntax)
5287ad62 1061 prefix_mode = (prefix_mode == GE_OPT_PREFIX_BIG) ? prefix_mode
477330fc 1062 : GE_OPT_PREFIX;
b99bd4ef 1063
c19d1205 1064 switch (prefix_mode)
b99bd4ef 1065 {
c19d1205
ZW
1066 case GE_NO_PREFIX: break;
1067 case GE_IMM_PREFIX:
1068 if (!is_immediate_prefix (**str))
1069 {
1070 inst.error = _("immediate expression requires a # prefix");
1071 return FAIL;
1072 }
1073 (*str)++;
1074 break;
1075 case GE_OPT_PREFIX:
5287ad62 1076 case GE_OPT_PREFIX_BIG:
c19d1205
ZW
1077 if (is_immediate_prefix (**str))
1078 (*str)++;
1079 break;
0198d5e6
TC
1080 default:
1081 abort ();
c19d1205 1082 }
b99bd4ef 1083
c19d1205 1084 memset (ep, 0, sizeof (expressionS));
b99bd4ef 1085
c19d1205
ZW
1086 save_in = input_line_pointer;
1087 input_line_pointer = *str;
0198d5e6 1088 in_my_get_expression = TRUE;
2ac93be7 1089 expression (ep);
0198d5e6 1090 in_my_get_expression = FALSE;
c19d1205 1091
f86adc07 1092 if (ep->X_op == O_illegal || ep->X_op == O_absent)
b99bd4ef 1093 {
f86adc07 1094 /* We found a bad or missing expression in md_operand(). */
c19d1205
ZW
1095 *str = input_line_pointer;
1096 input_line_pointer = save_in;
1097 if (inst.error == NULL)
f86adc07
NS
1098 inst.error = (ep->X_op == O_absent
1099 ? _("missing expression") :_("bad expression"));
c19d1205
ZW
1100 return 1;
1101 }
b99bd4ef 1102
c19d1205
ZW
1103 /* Get rid of any bignums now, so that we don't generate an error for which
1104 we can't establish a line number later on. Big numbers are never valid
1105 in instructions, which is where this routine is always called. */
5287ad62
JB
1106 if (prefix_mode != GE_OPT_PREFIX_BIG
1107 && (ep->X_op == O_big
477330fc 1108 || (ep->X_add_symbol
5287ad62 1109 && (walk_no_bignums (ep->X_add_symbol)
477330fc 1110 || (ep->X_op_symbol
5287ad62 1111 && walk_no_bignums (ep->X_op_symbol))))))
c19d1205
ZW
1112 {
1113 inst.error = _("invalid constant");
1114 *str = input_line_pointer;
1115 input_line_pointer = save_in;
1116 return 1;
1117 }
b99bd4ef 1118
c19d1205
ZW
1119 *str = input_line_pointer;
1120 input_line_pointer = save_in;
0198d5e6 1121 return SUCCESS;
b99bd4ef
NC
1122}
1123
c19d1205
ZW
1124/* Turn a string in input_line_pointer into a floating point constant
1125 of type TYPE, and store the appropriate bytes in *LITP. The number
1126 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1127 returned, or NULL on OK.
b99bd4ef 1128
c19d1205
ZW
1129 Note that fp constants aren't represent in the normal way on the ARM.
1130 In big endian mode, things are as expected. However, in little endian
1131 mode fp constants are big-endian word-wise, and little-endian byte-wise
1132 within the words. For example, (double) 1.1 in big endian mode is
1133 the byte sequence 3f f1 99 99 99 99 99 9a, and in little endian mode is
1134 the byte sequence 99 99 f1 3f 9a 99 99 99.
b99bd4ef 1135
c19d1205 1136 ??? The format of 12 byte floats is uncertain according to gcc's arm.h. */
b99bd4ef 1137
6d4af3c2 1138const char *
c19d1205
ZW
1139md_atof (int type, char * litP, int * sizeP)
1140{
1141 int prec;
1142 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1143 char *t;
1144 int i;
b99bd4ef 1145
c19d1205
ZW
1146 switch (type)
1147 {
1148 case 'f':
1149 case 'F':
1150 case 's':
1151 case 'S':
1152 prec = 2;
1153 break;
b99bd4ef 1154
c19d1205
ZW
1155 case 'd':
1156 case 'D':
1157 case 'r':
1158 case 'R':
1159 prec = 4;
1160 break;
b99bd4ef 1161
c19d1205
ZW
1162 case 'x':
1163 case 'X':
499ac353 1164 prec = 5;
c19d1205 1165 break;
b99bd4ef 1166
c19d1205
ZW
1167 case 'p':
1168 case 'P':
499ac353 1169 prec = 5;
c19d1205 1170 break;
a737bd4d 1171
c19d1205
ZW
1172 default:
1173 *sizeP = 0;
499ac353 1174 return _("Unrecognized or unsupported floating point constant");
c19d1205 1175 }
b99bd4ef 1176
c19d1205
ZW
1177 t = atof_ieee (input_line_pointer, type, words);
1178 if (t)
1179 input_line_pointer = t;
499ac353 1180 *sizeP = prec * sizeof (LITTLENUM_TYPE);
b99bd4ef 1181
c19d1205
ZW
1182 if (target_big_endian)
1183 {
1184 for (i = 0; i < prec; i++)
1185 {
499ac353
NC
1186 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1187 litP += sizeof (LITTLENUM_TYPE);
c19d1205
ZW
1188 }
1189 }
1190 else
1191 {
e74cfd16 1192 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
c19d1205
ZW
1193 for (i = prec - 1; i >= 0; i--)
1194 {
499ac353
NC
1195 md_number_to_chars (litP, (valueT) words[i], sizeof (LITTLENUM_TYPE));
1196 litP += sizeof (LITTLENUM_TYPE);
c19d1205
ZW
1197 }
1198 else
1199 /* For a 4 byte float the order of elements in `words' is 1 0.
1200 For an 8 byte float the order is 1 0 3 2. */
1201 for (i = 0; i < prec; i += 2)
1202 {
499ac353
NC
1203 md_number_to_chars (litP, (valueT) words[i + 1],
1204 sizeof (LITTLENUM_TYPE));
1205 md_number_to_chars (litP + sizeof (LITTLENUM_TYPE),
1206 (valueT) words[i], sizeof (LITTLENUM_TYPE));
1207 litP += 2 * sizeof (LITTLENUM_TYPE);
c19d1205
ZW
1208 }
1209 }
b99bd4ef 1210
499ac353 1211 return NULL;
c19d1205 1212}
b99bd4ef 1213
c19d1205
ZW
1214/* We handle all bad expressions here, so that we can report the faulty
1215 instruction in the error message. */
0198d5e6 1216
c19d1205 1217void
91d6fa6a 1218md_operand (expressionS * exp)
c19d1205
ZW
1219{
1220 if (in_my_get_expression)
91d6fa6a 1221 exp->X_op = O_illegal;
b99bd4ef
NC
1222}
1223
c19d1205 1224/* Immediate values. */
b99bd4ef 1225
0198d5e6 1226#ifdef OBJ_ELF
c19d1205
ZW
1227/* Generic immediate-value read function for use in directives.
1228 Accepts anything that 'expression' can fold to a constant.
1229 *val receives the number. */
0198d5e6 1230
c19d1205
ZW
1231static int
1232immediate_for_directive (int *val)
b99bd4ef 1233{
c19d1205
ZW
1234 expressionS exp;
1235 exp.X_op = O_illegal;
b99bd4ef 1236
c19d1205
ZW
1237 if (is_immediate_prefix (*input_line_pointer))
1238 {
1239 input_line_pointer++;
1240 expression (&exp);
1241 }
b99bd4ef 1242
c19d1205
ZW
1243 if (exp.X_op != O_constant)
1244 {
1245 as_bad (_("expected #constant"));
1246 ignore_rest_of_line ();
1247 return FAIL;
1248 }
1249 *val = exp.X_add_number;
1250 return SUCCESS;
b99bd4ef 1251}
c19d1205 1252#endif
b99bd4ef 1253
c19d1205 1254/* Register parsing. */
b99bd4ef 1255
c19d1205
ZW
1256/* Generic register parser. CCP points to what should be the
1257 beginning of a register name. If it is indeed a valid register
1258 name, advance CCP over it and return the reg_entry structure;
1259 otherwise return NULL. Does not issue diagnostics. */
1260
1261static struct reg_entry *
1262arm_reg_parse_multi (char **ccp)
b99bd4ef 1263{
c19d1205
ZW
1264 char *start = *ccp;
1265 char *p;
1266 struct reg_entry *reg;
b99bd4ef 1267
477330fc
RM
1268 skip_whitespace (start);
1269
c19d1205
ZW
1270#ifdef REGISTER_PREFIX
1271 if (*start != REGISTER_PREFIX)
01cfc07f 1272 return NULL;
c19d1205
ZW
1273 start++;
1274#endif
1275#ifdef OPTIONAL_REGISTER_PREFIX
1276 if (*start == OPTIONAL_REGISTER_PREFIX)
1277 start++;
1278#endif
b99bd4ef 1279
c19d1205
ZW
1280 p = start;
1281 if (!ISALPHA (*p) || !is_name_beginner (*p))
1282 return NULL;
b99bd4ef 1283
c19d1205
ZW
1284 do
1285 p++;
1286 while (ISALPHA (*p) || ISDIGIT (*p) || *p == '_');
1287
1288 reg = (struct reg_entry *) hash_find_n (arm_reg_hsh, start, p - start);
1289
1290 if (!reg)
1291 return NULL;
1292
1293 *ccp = p;
1294 return reg;
b99bd4ef
NC
1295}
1296
1297static int
dcbf9037 1298arm_reg_alt_syntax (char **ccp, char *start, struct reg_entry *reg,
477330fc 1299 enum arm_reg_type type)
b99bd4ef 1300{
c19d1205
ZW
1301 /* Alternative syntaxes are accepted for a few register classes. */
1302 switch (type)
1303 {
1304 case REG_TYPE_MVF:
1305 case REG_TYPE_MVD:
1306 case REG_TYPE_MVFX:
1307 case REG_TYPE_MVDX:
1308 /* Generic coprocessor register names are allowed for these. */
79134647 1309 if (reg && reg->type == REG_TYPE_CN)
c19d1205
ZW
1310 return reg->number;
1311 break;
69b97547 1312
c19d1205
ZW
1313 case REG_TYPE_CP:
1314 /* For backward compatibility, a bare number is valid here. */
1315 {
1316 unsigned long processor = strtoul (start, ccp, 10);
1317 if (*ccp != start && processor <= 15)
1318 return processor;
1319 }
1a0670f3 1320 /* Fall through. */
6057a28f 1321
c19d1205
ZW
1322 case REG_TYPE_MMXWC:
1323 /* WC includes WCG. ??? I'm not sure this is true for all
1324 instructions that take WC registers. */
79134647 1325 if (reg && reg->type == REG_TYPE_MMXWCG)
c19d1205 1326 return reg->number;
6057a28f 1327 break;
c19d1205 1328
6057a28f 1329 default:
c19d1205 1330 break;
6057a28f
NC
1331 }
1332
dcbf9037
JB
1333 return FAIL;
1334}
1335
1336/* As arm_reg_parse_multi, but the register must be of type TYPE, and the
1337 return value is the register number or FAIL. */
1338
1339static int
1340arm_reg_parse (char **ccp, enum arm_reg_type type)
1341{
1342 char *start = *ccp;
1343 struct reg_entry *reg = arm_reg_parse_multi (ccp);
1344 int ret;
1345
1346 /* Do not allow a scalar (reg+index) to parse as a register. */
1347 if (reg && reg->neon && (reg->neon->defined & NTA_HASINDEX))
1348 return FAIL;
1349
1350 if (reg && reg->type == type)
1351 return reg->number;
1352
1353 if ((ret = arm_reg_alt_syntax (ccp, start, reg, type)) != FAIL)
1354 return ret;
1355
c19d1205
ZW
1356 *ccp = start;
1357 return FAIL;
1358}
69b97547 1359
dcbf9037
JB
1360/* Parse a Neon type specifier. *STR should point at the leading '.'
1361 character. Does no verification at this stage that the type fits the opcode
1362 properly. E.g.,
1363
1364 .i32.i32.s16
1365 .s32.f32
1366 .u16
1367
1368 Can all be legally parsed by this function.
1369
1370 Fills in neon_type struct pointer with parsed information, and updates STR
1371 to point after the parsed type specifier. Returns SUCCESS if this was a legal
1372 type, FAIL if not. */
1373
1374static int
1375parse_neon_type (struct neon_type *type, char **str)
1376{
1377 char *ptr = *str;
1378
1379 if (type)
1380 type->elems = 0;
1381
1382 while (type->elems < NEON_MAX_TYPE_ELS)
1383 {
1384 enum neon_el_type thistype = NT_untyped;
1385 unsigned thissize = -1u;
1386
1387 if (*ptr != '.')
1388 break;
1389
1390 ptr++;
1391
1392 /* Just a size without an explicit type. */
1393 if (ISDIGIT (*ptr))
1394 goto parsesize;
1395
1396 switch (TOLOWER (*ptr))
1397 {
1398 case 'i': thistype = NT_integer; break;
1399 case 'f': thistype = NT_float; break;
1400 case 'p': thistype = NT_poly; break;
1401 case 's': thistype = NT_signed; break;
1402 case 'u': thistype = NT_unsigned; break;
477330fc
RM
1403 case 'd':
1404 thistype = NT_float;
1405 thissize = 64;
1406 ptr++;
1407 goto done;
dcbf9037
JB
1408 default:
1409 as_bad (_("unexpected character `%c' in type specifier"), *ptr);
1410 return FAIL;
1411 }
1412
1413 ptr++;
1414
1415 /* .f is an abbreviation for .f32. */
1416 if (thistype == NT_float && !ISDIGIT (*ptr))
1417 thissize = 32;
1418 else
1419 {
1420 parsesize:
1421 thissize = strtoul (ptr, &ptr, 10);
1422
1423 if (thissize != 8 && thissize != 16 && thissize != 32
477330fc
RM
1424 && thissize != 64)
1425 {
1426 as_bad (_("bad size %d in type specifier"), thissize);
dcbf9037
JB
1427 return FAIL;
1428 }
1429 }
1430
037e8744 1431 done:
dcbf9037 1432 if (type)
477330fc
RM
1433 {
1434 type->el[type->elems].type = thistype;
dcbf9037
JB
1435 type->el[type->elems].size = thissize;
1436 type->elems++;
1437 }
1438 }
1439
1440 /* Empty/missing type is not a successful parse. */
1441 if (type->elems == 0)
1442 return FAIL;
1443
1444 *str = ptr;
1445
1446 return SUCCESS;
1447}
1448
1449/* Errors may be set multiple times during parsing or bit encoding
1450 (particularly in the Neon bits), but usually the earliest error which is set
1451 will be the most meaningful. Avoid overwriting it with later (cascading)
1452 errors by calling this function. */
1453
1454static void
1455first_error (const char *err)
1456{
1457 if (!inst.error)
1458 inst.error = err;
1459}
1460
1461/* Parse a single type, e.g. ".s32", leading period included. */
1462static int
1463parse_neon_operand_type (struct neon_type_el *vectype, char **ccp)
1464{
1465 char *str = *ccp;
1466 struct neon_type optype;
1467
1468 if (*str == '.')
1469 {
1470 if (parse_neon_type (&optype, &str) == SUCCESS)
477330fc
RM
1471 {
1472 if (optype.elems == 1)
1473 *vectype = optype.el[0];
1474 else
1475 {
1476 first_error (_("only one type should be specified for operand"));
1477 return FAIL;
1478 }
1479 }
dcbf9037 1480 else
477330fc
RM
1481 {
1482 first_error (_("vector type expected"));
1483 return FAIL;
1484 }
dcbf9037
JB
1485 }
1486 else
1487 return FAIL;
5f4273c7 1488
dcbf9037 1489 *ccp = str;
5f4273c7 1490
dcbf9037
JB
1491 return SUCCESS;
1492}
1493
1494/* Special meanings for indices (which have a range of 0-7), which will fit into
1495 a 4-bit integer. */
1496
1497#define NEON_ALL_LANES 15
1498#define NEON_INTERLEAVE_LANES 14
1499
1500/* Parse either a register or a scalar, with an optional type. Return the
1501 register number, and optionally fill in the actual type of the register
1502 when multiple alternatives were given (NEON_TYPE_NDQ) in *RTYPE, and
1503 type/index information in *TYPEINFO. */
1504
1505static int
1506parse_typed_reg_or_scalar (char **ccp, enum arm_reg_type type,
477330fc
RM
1507 enum arm_reg_type *rtype,
1508 struct neon_typed_alias *typeinfo)
dcbf9037
JB
1509{
1510 char *str = *ccp;
1511 struct reg_entry *reg = arm_reg_parse_multi (&str);
1512 struct neon_typed_alias atype;
1513 struct neon_type_el parsetype;
1514
1515 atype.defined = 0;
1516 atype.index = -1;
1517 atype.eltype.type = NT_invtype;
1518 atype.eltype.size = -1;
1519
1520 /* Try alternate syntax for some types of register. Note these are mutually
1521 exclusive with the Neon syntax extensions. */
1522 if (reg == NULL)
1523 {
1524 int altreg = arm_reg_alt_syntax (&str, *ccp, reg, type);
1525 if (altreg != FAIL)
477330fc 1526 *ccp = str;
dcbf9037 1527 if (typeinfo)
477330fc 1528 *typeinfo = atype;
dcbf9037
JB
1529 return altreg;
1530 }
1531
037e8744
JB
1532 /* Undo polymorphism when a set of register types may be accepted. */
1533 if ((type == REG_TYPE_NDQ
1534 && (reg->type == REG_TYPE_NQ || reg->type == REG_TYPE_VFD))
1535 || (type == REG_TYPE_VFSD
477330fc 1536 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
037e8744 1537 || (type == REG_TYPE_NSDQ
477330fc
RM
1538 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD
1539 || reg->type == REG_TYPE_NQ))
dec41383
JW
1540 || (type == REG_TYPE_NSD
1541 && (reg->type == REG_TYPE_VFS || reg->type == REG_TYPE_VFD))
f512f76f
NC
1542 || (type == REG_TYPE_MMXWC
1543 && (reg->type == REG_TYPE_MMXWCG)))
21d799b5 1544 type = (enum arm_reg_type) reg->type;
dcbf9037
JB
1545
1546 if (type != reg->type)
1547 return FAIL;
1548
1549 if (reg->neon)
1550 atype = *reg->neon;
5f4273c7 1551
dcbf9037
JB
1552 if (parse_neon_operand_type (&parsetype, &str) == SUCCESS)
1553 {
1554 if ((atype.defined & NTA_HASTYPE) != 0)
477330fc
RM
1555 {
1556 first_error (_("can't redefine type for operand"));
1557 return FAIL;
1558 }
dcbf9037
JB
1559 atype.defined |= NTA_HASTYPE;
1560 atype.eltype = parsetype;
1561 }
5f4273c7 1562
dcbf9037
JB
1563 if (skip_past_char (&str, '[') == SUCCESS)
1564 {
dec41383
JW
1565 if (type != REG_TYPE_VFD
1566 && !(type == REG_TYPE_VFS
1567 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8_2)))
477330fc
RM
1568 {
1569 first_error (_("only D registers may be indexed"));
1570 return FAIL;
1571 }
5f4273c7 1572
dcbf9037 1573 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
1574 {
1575 first_error (_("can't change index for operand"));
1576 return FAIL;
1577 }
dcbf9037
JB
1578
1579 atype.defined |= NTA_HASINDEX;
1580
1581 if (skip_past_char (&str, ']') == SUCCESS)
477330fc 1582 atype.index = NEON_ALL_LANES;
dcbf9037 1583 else
477330fc
RM
1584 {
1585 expressionS exp;
dcbf9037 1586
477330fc 1587 my_get_expression (&exp, &str, GE_NO_PREFIX);
dcbf9037 1588
477330fc
RM
1589 if (exp.X_op != O_constant)
1590 {
1591 first_error (_("constant expression required"));
1592 return FAIL;
1593 }
dcbf9037 1594
477330fc
RM
1595 if (skip_past_char (&str, ']') == FAIL)
1596 return FAIL;
dcbf9037 1597
477330fc
RM
1598 atype.index = exp.X_add_number;
1599 }
dcbf9037 1600 }
5f4273c7 1601
dcbf9037
JB
1602 if (typeinfo)
1603 *typeinfo = atype;
5f4273c7 1604
dcbf9037
JB
1605 if (rtype)
1606 *rtype = type;
5f4273c7 1607
dcbf9037 1608 *ccp = str;
5f4273c7 1609
dcbf9037
JB
1610 return reg->number;
1611}
1612
efd6b359 1613/* Like arm_reg_parse, but also allow the following extra features:
dcbf9037
JB
1614 - If RTYPE is non-zero, return the (possibly restricted) type of the
1615 register (e.g. Neon double or quad reg when either has been requested).
1616 - If this is a Neon vector type with additional type information, fill
1617 in the struct pointed to by VECTYPE (if non-NULL).
5f4273c7 1618 This function will fault on encountering a scalar. */
dcbf9037
JB
1619
1620static int
1621arm_typed_reg_parse (char **ccp, enum arm_reg_type type,
477330fc 1622 enum arm_reg_type *rtype, struct neon_type_el *vectype)
dcbf9037
JB
1623{
1624 struct neon_typed_alias atype;
1625 char *str = *ccp;
1626 int reg = parse_typed_reg_or_scalar (&str, type, rtype, &atype);
1627
1628 if (reg == FAIL)
1629 return FAIL;
1630
0855e32b
NS
1631 /* Do not allow regname(... to parse as a register. */
1632 if (*str == '(')
1633 return FAIL;
1634
dcbf9037
JB
1635 /* Do not allow a scalar (reg+index) to parse as a register. */
1636 if ((atype.defined & NTA_HASINDEX) != 0)
1637 {
1638 first_error (_("register operand expected, but got scalar"));
1639 return FAIL;
1640 }
1641
1642 if (vectype)
1643 *vectype = atype.eltype;
1644
1645 *ccp = str;
1646
1647 return reg;
1648}
1649
1650#define NEON_SCALAR_REG(X) ((X) >> 4)
1651#define NEON_SCALAR_INDEX(X) ((X) & 15)
1652
5287ad62
JB
1653/* Parse a Neon scalar. Most of the time when we're parsing a scalar, we don't
1654 have enough information to be able to do a good job bounds-checking. So, we
1655 just do easy checks here, and do further checks later. */
1656
1657static int
dcbf9037 1658parse_scalar (char **ccp, int elsize, struct neon_type_el *type)
5287ad62 1659{
dcbf9037 1660 int reg;
5287ad62 1661 char *str = *ccp;
dcbf9037 1662 struct neon_typed_alias atype;
dec41383
JW
1663 enum arm_reg_type reg_type = REG_TYPE_VFD;
1664
1665 if (elsize == 4)
1666 reg_type = REG_TYPE_VFS;
5f4273c7 1667
dec41383 1668 reg = parse_typed_reg_or_scalar (&str, reg_type, NULL, &atype);
5f4273c7 1669
dcbf9037 1670 if (reg == FAIL || (atype.defined & NTA_HASINDEX) == 0)
5287ad62 1671 return FAIL;
5f4273c7 1672
dcbf9037 1673 if (atype.index == NEON_ALL_LANES)
5287ad62 1674 {
dcbf9037 1675 first_error (_("scalar must have an index"));
5287ad62
JB
1676 return FAIL;
1677 }
dcbf9037 1678 else if (atype.index >= 64 / elsize)
5287ad62 1679 {
dcbf9037 1680 first_error (_("scalar index out of range"));
5287ad62
JB
1681 return FAIL;
1682 }
5f4273c7 1683
dcbf9037
JB
1684 if (type)
1685 *type = atype.eltype;
5f4273c7 1686
5287ad62 1687 *ccp = str;
5f4273c7 1688
dcbf9037 1689 return reg * 16 + atype.index;
5287ad62
JB
1690}
1691
4b5a202f
AV
1692/* Types of registers in a list. */
1693
1694enum reg_list_els
1695{
1696 REGLIST_RN,
1697 REGLIST_CLRM,
1698 REGLIST_VFP_S,
efd6b359 1699 REGLIST_VFP_S_VPR,
4b5a202f 1700 REGLIST_VFP_D,
efd6b359 1701 REGLIST_VFP_D_VPR,
4b5a202f
AV
1702 REGLIST_NEON_D
1703};
1704
c19d1205 1705/* Parse an ARM register list. Returns the bitmask, or FAIL. */
e07e6e58 1706
c19d1205 1707static long
4b5a202f 1708parse_reg_list (char ** strp, enum reg_list_els etype)
c19d1205 1709{
4b5a202f
AV
1710 char *str = *strp;
1711 long range = 0;
1712 int another_range;
1713
1714 gas_assert (etype == REGLIST_RN || etype == REGLIST_CLRM);
a737bd4d 1715
c19d1205
ZW
1716 /* We come back here if we get ranges concatenated by '+' or '|'. */
1717 do
6057a28f 1718 {
477330fc
RM
1719 skip_whitespace (str);
1720
c19d1205 1721 another_range = 0;
a737bd4d 1722
c19d1205
ZW
1723 if (*str == '{')
1724 {
1725 int in_range = 0;
1726 int cur_reg = -1;
a737bd4d 1727
c19d1205
ZW
1728 str++;
1729 do
1730 {
1731 int reg;
4b5a202f
AV
1732 const char apsr_str[] = "apsr";
1733 int apsr_str_len = strlen (apsr_str);
6057a28f 1734
4b5a202f
AV
1735 reg = arm_reg_parse (&str, REGLIST_RN);
1736 if (etype == REGLIST_CLRM)
c19d1205 1737 {
4b5a202f
AV
1738 if (reg == REG_SP || reg == REG_PC)
1739 reg = FAIL;
1740 else if (reg == FAIL
1741 && !strncasecmp (str, apsr_str, apsr_str_len)
1742 && !ISALPHA (*(str + apsr_str_len)))
1743 {
1744 reg = 15;
1745 str += apsr_str_len;
1746 }
1747
1748 if (reg == FAIL)
1749 {
1750 first_error (_("r0-r12, lr or APSR expected"));
1751 return FAIL;
1752 }
1753 }
1754 else /* etype == REGLIST_RN. */
1755 {
1756 if (reg == FAIL)
1757 {
1758 first_error (_(reg_expected_msgs[REGLIST_RN]));
1759 return FAIL;
1760 }
c19d1205 1761 }
a737bd4d 1762
c19d1205
ZW
1763 if (in_range)
1764 {
1765 int i;
a737bd4d 1766
c19d1205
ZW
1767 if (reg <= cur_reg)
1768 {
dcbf9037 1769 first_error (_("bad range in register list"));
c19d1205
ZW
1770 return FAIL;
1771 }
40a18ebd 1772
c19d1205
ZW
1773 for (i = cur_reg + 1; i < reg; i++)
1774 {
1775 if (range & (1 << i))
1776 as_tsktsk
1777 (_("Warning: duplicated register (r%d) in register list"),
1778 i);
1779 else
1780 range |= 1 << i;
1781 }
1782 in_range = 0;
1783 }
a737bd4d 1784
c19d1205
ZW
1785 if (range & (1 << reg))
1786 as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
1787 reg);
1788 else if (reg <= cur_reg)
1789 as_tsktsk (_("Warning: register range not in ascending order"));
a737bd4d 1790
c19d1205
ZW
1791 range |= 1 << reg;
1792 cur_reg = reg;
1793 }
1794 while (skip_past_comma (&str) != FAIL
1795 || (in_range = 1, *str++ == '-'));
1796 str--;
a737bd4d 1797
d996d970 1798 if (skip_past_char (&str, '}') == FAIL)
c19d1205 1799 {
dcbf9037 1800 first_error (_("missing `}'"));
c19d1205
ZW
1801 return FAIL;
1802 }
1803 }
4b5a202f 1804 else if (etype == REGLIST_RN)
c19d1205 1805 {
91d6fa6a 1806 expressionS exp;
40a18ebd 1807
91d6fa6a 1808 if (my_get_expression (&exp, &str, GE_NO_PREFIX))
c19d1205 1809 return FAIL;
40a18ebd 1810
91d6fa6a 1811 if (exp.X_op == O_constant)
c19d1205 1812 {
91d6fa6a
NC
1813 if (exp.X_add_number
1814 != (exp.X_add_number & 0x0000ffff))
c19d1205
ZW
1815 {
1816 inst.error = _("invalid register mask");
1817 return FAIL;
1818 }
a737bd4d 1819
91d6fa6a 1820 if ((range & exp.X_add_number) != 0)
c19d1205 1821 {
91d6fa6a 1822 int regno = range & exp.X_add_number;
a737bd4d 1823
c19d1205
ZW
1824 regno &= -regno;
1825 regno = (1 << regno) - 1;
1826 as_tsktsk
1827 (_("Warning: duplicated register (r%d) in register list"),
1828 regno);
1829 }
a737bd4d 1830
91d6fa6a 1831 range |= exp.X_add_number;
c19d1205
ZW
1832 }
1833 else
1834 {
e2b0ab59 1835 if (inst.relocs[0].type != 0)
c19d1205
ZW
1836 {
1837 inst.error = _("expression too complex");
1838 return FAIL;
1839 }
a737bd4d 1840
e2b0ab59
AV
1841 memcpy (&inst.relocs[0].exp, &exp, sizeof (expressionS));
1842 inst.relocs[0].type = BFD_RELOC_ARM_MULTI;
1843 inst.relocs[0].pc_rel = 0;
c19d1205
ZW
1844 }
1845 }
a737bd4d 1846
c19d1205
ZW
1847 if (*str == '|' || *str == '+')
1848 {
1849 str++;
1850 another_range = 1;
1851 }
a737bd4d 1852 }
c19d1205 1853 while (another_range);
a737bd4d 1854
c19d1205
ZW
1855 *strp = str;
1856 return range;
a737bd4d
NC
1857}
1858
c19d1205
ZW
1859/* Parse a VFP register list. If the string is invalid return FAIL.
1860 Otherwise return the number of registers, and set PBASE to the first
5287ad62
JB
1861 register. Parses registers of type ETYPE.
1862 If REGLIST_NEON_D is used, several syntax enhancements are enabled:
1863 - Q registers can be used to specify pairs of D registers
1864 - { } can be omitted from around a singleton register list
477330fc
RM
1865 FIXME: This is not implemented, as it would require backtracking in
1866 some cases, e.g.:
1867 vtbl.8 d3,d4,d5
1868 This could be done (the meaning isn't really ambiguous), but doesn't
1869 fit in well with the current parsing framework.
dcbf9037
JB
1870 - 32 D registers may be used (also true for VFPv3).
1871 FIXME: Types are ignored in these register lists, which is probably a
1872 bug. */
6057a28f 1873
c19d1205 1874static int
efd6b359
AV
1875parse_vfp_reg_list (char **ccp, unsigned int *pbase, enum reg_list_els etype,
1876 bfd_boolean *partial_match)
6057a28f 1877{
037e8744 1878 char *str = *ccp;
c19d1205
ZW
1879 int base_reg;
1880 int new_base;
21d799b5 1881 enum arm_reg_type regtype = (enum arm_reg_type) 0;
5287ad62 1882 int max_regs = 0;
c19d1205
ZW
1883 int count = 0;
1884 int warned = 0;
1885 unsigned long mask = 0;
a737bd4d 1886 int i;
efd6b359
AV
1887 bfd_boolean vpr_seen = FALSE;
1888 bfd_boolean expect_vpr =
1889 (etype == REGLIST_VFP_S_VPR) || (etype == REGLIST_VFP_D_VPR);
6057a28f 1890
477330fc 1891 if (skip_past_char (&str, '{') == FAIL)
5287ad62
JB
1892 {
1893 inst.error = _("expecting {");
1894 return FAIL;
1895 }
6057a28f 1896
5287ad62 1897 switch (etype)
c19d1205 1898 {
5287ad62 1899 case REGLIST_VFP_S:
efd6b359 1900 case REGLIST_VFP_S_VPR:
c19d1205
ZW
1901 regtype = REG_TYPE_VFS;
1902 max_regs = 32;
5287ad62 1903 break;
5f4273c7 1904
5287ad62 1905 case REGLIST_VFP_D:
efd6b359 1906 case REGLIST_VFP_D_VPR:
5287ad62 1907 regtype = REG_TYPE_VFD;
b7fc2769 1908 break;
5f4273c7 1909
b7fc2769
JB
1910 case REGLIST_NEON_D:
1911 regtype = REG_TYPE_NDQ;
1912 break;
4b5a202f
AV
1913
1914 default:
1915 gas_assert (0);
b7fc2769
JB
1916 }
1917
efd6b359 1918 if (etype != REGLIST_VFP_S && etype != REGLIST_VFP_S_VPR)
b7fc2769 1919 {
b1cc4aeb
PB
1920 /* VFPv3 allows 32 D registers, except for the VFPv3-D16 variant. */
1921 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
1922 {
1923 max_regs = 32;
1924 if (thumb_mode)
1925 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
1926 fpu_vfp_ext_d32);
1927 else
1928 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
1929 fpu_vfp_ext_d32);
1930 }
5287ad62 1931 else
477330fc 1932 max_regs = 16;
c19d1205 1933 }
6057a28f 1934
c19d1205 1935 base_reg = max_regs;
efd6b359 1936 *partial_match = FALSE;
a737bd4d 1937
c19d1205
ZW
1938 do
1939 {
5287ad62 1940 int setmask = 1, addregs = 1;
efd6b359
AV
1941 const char vpr_str[] = "vpr";
1942 int vpr_str_len = strlen (vpr_str);
dcbf9037 1943
037e8744 1944 new_base = arm_typed_reg_parse (&str, regtype, &regtype, NULL);
dcbf9037 1945
efd6b359
AV
1946 if (expect_vpr)
1947 {
1948 if (new_base == FAIL
1949 && !strncasecmp (str, vpr_str, vpr_str_len)
1950 && !ISALPHA (*(str + vpr_str_len))
1951 && !vpr_seen)
1952 {
1953 vpr_seen = TRUE;
1954 str += vpr_str_len;
1955 if (count == 0)
1956 base_reg = 0; /* Canonicalize VPR only on d0 with 0 regs. */
1957 }
1958 else if (vpr_seen)
1959 {
1960 first_error (_("VPR expected last"));
1961 return FAIL;
1962 }
1963 else if (new_base == FAIL)
1964 {
1965 if (regtype == REG_TYPE_VFS)
1966 first_error (_("VFP single precision register or VPR "
1967 "expected"));
1968 else /* regtype == REG_TYPE_VFD. */
1969 first_error (_("VFP/Neon double precision register or VPR "
1970 "expected"));
1971 return FAIL;
1972 }
1973 }
1974 else if (new_base == FAIL)
a737bd4d 1975 {
dcbf9037 1976 first_error (_(reg_expected_msgs[regtype]));
c19d1205
ZW
1977 return FAIL;
1978 }
5f4273c7 1979
efd6b359
AV
1980 *partial_match = TRUE;
1981 if (vpr_seen)
1982 continue;
1983
b7fc2769 1984 if (new_base >= max_regs)
477330fc
RM
1985 {
1986 first_error (_("register out of range in list"));
1987 return FAIL;
1988 }
5f4273c7 1989
5287ad62
JB
1990 /* Note: a value of 2 * n is returned for the register Q<n>. */
1991 if (regtype == REG_TYPE_NQ)
477330fc
RM
1992 {
1993 setmask = 3;
1994 addregs = 2;
1995 }
5287ad62 1996
c19d1205
ZW
1997 if (new_base < base_reg)
1998 base_reg = new_base;
a737bd4d 1999
5287ad62 2000 if (mask & (setmask << new_base))
c19d1205 2001 {
dcbf9037 2002 first_error (_("invalid register list"));
c19d1205 2003 return FAIL;
a737bd4d 2004 }
a737bd4d 2005
efd6b359 2006 if ((mask >> new_base) != 0 && ! warned && !vpr_seen)
c19d1205
ZW
2007 {
2008 as_tsktsk (_("register list not in ascending order"));
2009 warned = 1;
2010 }
0bbf2aa4 2011
5287ad62
JB
2012 mask |= setmask << new_base;
2013 count += addregs;
0bbf2aa4 2014
037e8744 2015 if (*str == '-') /* We have the start of a range expression */
c19d1205
ZW
2016 {
2017 int high_range;
0bbf2aa4 2018
037e8744 2019 str++;
0bbf2aa4 2020
037e8744 2021 if ((high_range = arm_typed_reg_parse (&str, regtype, NULL, NULL))
477330fc 2022 == FAIL)
c19d1205
ZW
2023 {
2024 inst.error = gettext (reg_expected_msgs[regtype]);
2025 return FAIL;
2026 }
0bbf2aa4 2027
477330fc
RM
2028 if (high_range >= max_regs)
2029 {
2030 first_error (_("register out of range in list"));
2031 return FAIL;
2032 }
b7fc2769 2033
477330fc
RM
2034 if (regtype == REG_TYPE_NQ)
2035 high_range = high_range + 1;
5287ad62 2036
c19d1205
ZW
2037 if (high_range <= new_base)
2038 {
2039 inst.error = _("register range not in ascending order");
2040 return FAIL;
2041 }
0bbf2aa4 2042
5287ad62 2043 for (new_base += addregs; new_base <= high_range; new_base += addregs)
0bbf2aa4 2044 {
5287ad62 2045 if (mask & (setmask << new_base))
0bbf2aa4 2046 {
c19d1205
ZW
2047 inst.error = _("invalid register list");
2048 return FAIL;
0bbf2aa4 2049 }
c19d1205 2050
5287ad62
JB
2051 mask |= setmask << new_base;
2052 count += addregs;
0bbf2aa4 2053 }
0bbf2aa4 2054 }
0bbf2aa4 2055 }
037e8744 2056 while (skip_past_comma (&str) != FAIL);
0bbf2aa4 2057
037e8744 2058 str++;
0bbf2aa4 2059
c19d1205 2060 /* Sanity check -- should have raised a parse error above. */
efd6b359 2061 if ((!vpr_seen && count == 0) || count > max_regs)
c19d1205
ZW
2062 abort ();
2063
2064 *pbase = base_reg;
2065
efd6b359
AV
2066 if (expect_vpr && !vpr_seen)
2067 {
2068 first_error (_("VPR expected last"));
2069 return FAIL;
2070 }
2071
c19d1205
ZW
2072 /* Final test -- the registers must be consecutive. */
2073 mask >>= base_reg;
2074 for (i = 0; i < count; i++)
2075 {
2076 if ((mask & (1u << i)) == 0)
2077 {
2078 inst.error = _("non-contiguous register range");
2079 return FAIL;
2080 }
2081 }
2082
037e8744
JB
2083 *ccp = str;
2084
c19d1205 2085 return count;
b99bd4ef
NC
2086}
2087
dcbf9037
JB
2088/* True if two alias types are the same. */
2089
c921be7d 2090static bfd_boolean
dcbf9037
JB
2091neon_alias_types_same (struct neon_typed_alias *a, struct neon_typed_alias *b)
2092{
2093 if (!a && !b)
c921be7d 2094 return TRUE;
5f4273c7 2095
dcbf9037 2096 if (!a || !b)
c921be7d 2097 return FALSE;
dcbf9037
JB
2098
2099 if (a->defined != b->defined)
c921be7d 2100 return FALSE;
5f4273c7 2101
dcbf9037
JB
2102 if ((a->defined & NTA_HASTYPE) != 0
2103 && (a->eltype.type != b->eltype.type
477330fc 2104 || a->eltype.size != b->eltype.size))
c921be7d 2105 return FALSE;
dcbf9037
JB
2106
2107 if ((a->defined & NTA_HASINDEX) != 0
2108 && (a->index != b->index))
c921be7d 2109 return FALSE;
5f4273c7 2110
c921be7d 2111 return TRUE;
dcbf9037
JB
2112}
2113
5287ad62
JB
2114/* Parse element/structure lists for Neon VLD<n> and VST<n> instructions.
2115 The base register is put in *PBASE.
dcbf9037 2116 The lane (or one of the NEON_*_LANES constants) is placed in bits [3:0] of
5287ad62
JB
2117 the return value.
2118 The register stride (minus one) is put in bit 4 of the return value.
dcbf9037
JB
2119 Bits [6:5] encode the list length (minus one).
2120 The type of the list elements is put in *ELTYPE, if non-NULL. */
5287ad62 2121
5287ad62 2122#define NEON_LANE(X) ((X) & 0xf)
dcbf9037 2123#define NEON_REG_STRIDE(X) ((((X) >> 4) & 1) + 1)
5287ad62
JB
2124#define NEON_REGLIST_LENGTH(X) ((((X) >> 5) & 3) + 1)
2125
2126static int
dcbf9037 2127parse_neon_el_struct_list (char **str, unsigned *pbase,
477330fc 2128 struct neon_type_el *eltype)
5287ad62
JB
2129{
2130 char *ptr = *str;
2131 int base_reg = -1;
2132 int reg_incr = -1;
2133 int count = 0;
2134 int lane = -1;
2135 int leading_brace = 0;
2136 enum arm_reg_type rtype = REG_TYPE_NDQ;
20203fb9
NC
2137 const char *const incr_error = _("register stride must be 1 or 2");
2138 const char *const type_error = _("mismatched element/structure types in list");
dcbf9037 2139 struct neon_typed_alias firsttype;
f85d59c3
KT
2140 firsttype.defined = 0;
2141 firsttype.eltype.type = NT_invtype;
2142 firsttype.eltype.size = -1;
2143 firsttype.index = -1;
5f4273c7 2144
5287ad62
JB
2145 if (skip_past_char (&ptr, '{') == SUCCESS)
2146 leading_brace = 1;
5f4273c7 2147
5287ad62
JB
2148 do
2149 {
dcbf9037
JB
2150 struct neon_typed_alias atype;
2151 int getreg = parse_typed_reg_or_scalar (&ptr, rtype, &rtype, &atype);
2152
5287ad62 2153 if (getreg == FAIL)
477330fc
RM
2154 {
2155 first_error (_(reg_expected_msgs[rtype]));
2156 return FAIL;
2157 }
5f4273c7 2158
5287ad62 2159 if (base_reg == -1)
477330fc
RM
2160 {
2161 base_reg = getreg;
2162 if (rtype == REG_TYPE_NQ)
2163 {
2164 reg_incr = 1;
2165 }
2166 firsttype = atype;
2167 }
5287ad62 2168 else if (reg_incr == -1)
477330fc
RM
2169 {
2170 reg_incr = getreg - base_reg;
2171 if (reg_incr < 1 || reg_incr > 2)
2172 {
2173 first_error (_(incr_error));
2174 return FAIL;
2175 }
2176 }
5287ad62 2177 else if (getreg != base_reg + reg_incr * count)
477330fc
RM
2178 {
2179 first_error (_(incr_error));
2180 return FAIL;
2181 }
dcbf9037 2182
c921be7d 2183 if (! neon_alias_types_same (&atype, &firsttype))
477330fc
RM
2184 {
2185 first_error (_(type_error));
2186 return FAIL;
2187 }
5f4273c7 2188
5287ad62 2189 /* Handle Dn-Dm or Qn-Qm syntax. Can only be used with non-indexed list
477330fc 2190 modes. */
5287ad62 2191 if (ptr[0] == '-')
477330fc
RM
2192 {
2193 struct neon_typed_alias htype;
2194 int hireg, dregs = (rtype == REG_TYPE_NQ) ? 2 : 1;
2195 if (lane == -1)
2196 lane = NEON_INTERLEAVE_LANES;
2197 else if (lane != NEON_INTERLEAVE_LANES)
2198 {
2199 first_error (_(type_error));
2200 return FAIL;
2201 }
2202 if (reg_incr == -1)
2203 reg_incr = 1;
2204 else if (reg_incr != 1)
2205 {
2206 first_error (_("don't use Rn-Rm syntax with non-unit stride"));
2207 return FAIL;
2208 }
2209 ptr++;
2210 hireg = parse_typed_reg_or_scalar (&ptr, rtype, NULL, &htype);
2211 if (hireg == FAIL)
2212 {
2213 first_error (_(reg_expected_msgs[rtype]));
2214 return FAIL;
2215 }
2216 if (! neon_alias_types_same (&htype, &firsttype))
2217 {
2218 first_error (_(type_error));
2219 return FAIL;
2220 }
2221 count += hireg + dregs - getreg;
2222 continue;
2223 }
5f4273c7 2224
5287ad62
JB
2225 /* If we're using Q registers, we can't use [] or [n] syntax. */
2226 if (rtype == REG_TYPE_NQ)
477330fc
RM
2227 {
2228 count += 2;
2229 continue;
2230 }
5f4273c7 2231
dcbf9037 2232 if ((atype.defined & NTA_HASINDEX) != 0)
477330fc
RM
2233 {
2234 if (lane == -1)
2235 lane = atype.index;
2236 else if (lane != atype.index)
2237 {
2238 first_error (_(type_error));
2239 return FAIL;
2240 }
2241 }
5287ad62 2242 else if (lane == -1)
477330fc 2243 lane = NEON_INTERLEAVE_LANES;
5287ad62 2244 else if (lane != NEON_INTERLEAVE_LANES)
477330fc
RM
2245 {
2246 first_error (_(type_error));
2247 return FAIL;
2248 }
5287ad62
JB
2249 count++;
2250 }
2251 while ((count != 1 || leading_brace) && skip_past_comma (&ptr) != FAIL);
5f4273c7 2252
5287ad62
JB
2253 /* No lane set by [x]. We must be interleaving structures. */
2254 if (lane == -1)
2255 lane = NEON_INTERLEAVE_LANES;
5f4273c7 2256
5287ad62
JB
2257 /* Sanity check. */
2258 if (lane == -1 || base_reg == -1 || count < 1 || count > 4
2259 || (count > 1 && reg_incr == -1))
2260 {
dcbf9037 2261 first_error (_("error parsing element/structure list"));
5287ad62
JB
2262 return FAIL;
2263 }
2264
2265 if ((count > 1 || leading_brace) && skip_past_char (&ptr, '}') == FAIL)
2266 {
dcbf9037 2267 first_error (_("expected }"));
5287ad62
JB
2268 return FAIL;
2269 }
5f4273c7 2270
5287ad62
JB
2271 if (reg_incr == -1)
2272 reg_incr = 1;
2273
dcbf9037
JB
2274 if (eltype)
2275 *eltype = firsttype.eltype;
2276
5287ad62
JB
2277 *pbase = base_reg;
2278 *str = ptr;
5f4273c7 2279
5287ad62
JB
2280 return lane | ((reg_incr - 1) << 4) | ((count - 1) << 5);
2281}
2282
c19d1205
ZW
2283/* Parse an explicit relocation suffix on an expression. This is
2284 either nothing, or a word in parentheses. Note that if !OBJ_ELF,
2285 arm_reloc_hsh contains no entries, so this function can only
2286 succeed if there is no () after the word. Returns -1 on error,
2287 BFD_RELOC_UNUSED if there wasn't any suffix. */
3da1d841 2288
c19d1205
ZW
2289static int
2290parse_reloc (char **str)
b99bd4ef 2291{
c19d1205
ZW
2292 struct reloc_entry *r;
2293 char *p, *q;
b99bd4ef 2294
c19d1205
ZW
2295 if (**str != '(')
2296 return BFD_RELOC_UNUSED;
b99bd4ef 2297
c19d1205
ZW
2298 p = *str + 1;
2299 q = p;
2300
2301 while (*q && *q != ')' && *q != ',')
2302 q++;
2303 if (*q != ')')
2304 return -1;
2305
21d799b5
NC
2306 if ((r = (struct reloc_entry *)
2307 hash_find_n (arm_reloc_hsh, p, q - p)) == NULL)
c19d1205
ZW
2308 return -1;
2309
2310 *str = q + 1;
2311 return r->reloc;
b99bd4ef
NC
2312}
2313
c19d1205
ZW
2314/* Directives: register aliases. */
2315
dcbf9037 2316static struct reg_entry *
90ec0d68 2317insert_reg_alias (char *str, unsigned number, int type)
b99bd4ef 2318{
d3ce72d0 2319 struct reg_entry *new_reg;
c19d1205 2320 const char *name;
b99bd4ef 2321
d3ce72d0 2322 if ((new_reg = (struct reg_entry *) hash_find (arm_reg_hsh, str)) != 0)
c19d1205 2323 {
d3ce72d0 2324 if (new_reg->builtin)
c19d1205 2325 as_warn (_("ignoring attempt to redefine built-in register '%s'"), str);
b99bd4ef 2326
c19d1205
ZW
2327 /* Only warn about a redefinition if it's not defined as the
2328 same register. */
d3ce72d0 2329 else if (new_reg->number != number || new_reg->type != type)
c19d1205 2330 as_warn (_("ignoring redefinition of register alias '%s'"), str);
69b97547 2331
d929913e 2332 return NULL;
c19d1205 2333 }
b99bd4ef 2334
c19d1205 2335 name = xstrdup (str);
325801bd 2336 new_reg = XNEW (struct reg_entry);
b99bd4ef 2337
d3ce72d0
NC
2338 new_reg->name = name;
2339 new_reg->number = number;
2340 new_reg->type = type;
2341 new_reg->builtin = FALSE;
2342 new_reg->neon = NULL;
b99bd4ef 2343
d3ce72d0 2344 if (hash_insert (arm_reg_hsh, name, (void *) new_reg))
c19d1205 2345 abort ();
5f4273c7 2346
d3ce72d0 2347 return new_reg;
dcbf9037
JB
2348}
2349
2350static void
2351insert_neon_reg_alias (char *str, int number, int type,
477330fc 2352 struct neon_typed_alias *atype)
dcbf9037
JB
2353{
2354 struct reg_entry *reg = insert_reg_alias (str, number, type);
5f4273c7 2355
dcbf9037
JB
2356 if (!reg)
2357 {
2358 first_error (_("attempt to redefine typed alias"));
2359 return;
2360 }
5f4273c7 2361
dcbf9037
JB
2362 if (atype)
2363 {
325801bd 2364 reg->neon = XNEW (struct neon_typed_alias);
dcbf9037
JB
2365 *reg->neon = *atype;
2366 }
c19d1205 2367}
b99bd4ef 2368
c19d1205 2369/* Look for the .req directive. This is of the form:
b99bd4ef 2370
c19d1205 2371 new_register_name .req existing_register_name
b99bd4ef 2372
c19d1205 2373 If we find one, or if it looks sufficiently like one that we want to
d929913e 2374 handle any error here, return TRUE. Otherwise return FALSE. */
b99bd4ef 2375
d929913e 2376static bfd_boolean
c19d1205
ZW
2377create_register_alias (char * newname, char *p)
2378{
2379 struct reg_entry *old;
2380 char *oldname, *nbuf;
2381 size_t nlen;
b99bd4ef 2382
c19d1205
ZW
2383 /* The input scrubber ensures that whitespace after the mnemonic is
2384 collapsed to single spaces. */
2385 oldname = p;
2386 if (strncmp (oldname, " .req ", 6) != 0)
d929913e 2387 return FALSE;
b99bd4ef 2388
c19d1205
ZW
2389 oldname += 6;
2390 if (*oldname == '\0')
d929913e 2391 return FALSE;
b99bd4ef 2392
21d799b5 2393 old = (struct reg_entry *) hash_find (arm_reg_hsh, oldname);
c19d1205 2394 if (!old)
b99bd4ef 2395 {
c19d1205 2396 as_warn (_("unknown register '%s' -- .req ignored"), oldname);
d929913e 2397 return TRUE;
b99bd4ef
NC
2398 }
2399
c19d1205
ZW
2400 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2401 the desired alias name, and p points to its end. If not, then
2402 the desired alias name is in the global original_case_string. */
2403#ifdef TC_CASE_SENSITIVE
2404 nlen = p - newname;
2405#else
2406 newname = original_case_string;
2407 nlen = strlen (newname);
2408#endif
b99bd4ef 2409
29a2809e 2410 nbuf = xmemdup0 (newname, nlen);
b99bd4ef 2411
c19d1205
ZW
2412 /* Create aliases under the new name as stated; an all-lowercase
2413 version of the new name; and an all-uppercase version of the new
2414 name. */
d929913e
NC
2415 if (insert_reg_alias (nbuf, old->number, old->type) != NULL)
2416 {
2417 for (p = nbuf; *p; p++)
2418 *p = TOUPPER (*p);
c19d1205 2419
d929913e
NC
2420 if (strncmp (nbuf, newname, nlen))
2421 {
2422 /* If this attempt to create an additional alias fails, do not bother
2423 trying to create the all-lower case alias. We will fail and issue
2424 a second, duplicate error message. This situation arises when the
2425 programmer does something like:
2426 foo .req r0
2427 Foo .req r1
2428 The second .req creates the "Foo" alias but then fails to create
5f4273c7 2429 the artificial FOO alias because it has already been created by the
d929913e
NC
2430 first .req. */
2431 if (insert_reg_alias (nbuf, old->number, old->type) == NULL)
e1fa0163
NC
2432 {
2433 free (nbuf);
2434 return TRUE;
2435 }
d929913e 2436 }
c19d1205 2437
d929913e
NC
2438 for (p = nbuf; *p; p++)
2439 *p = TOLOWER (*p);
c19d1205 2440
d929913e
NC
2441 if (strncmp (nbuf, newname, nlen))
2442 insert_reg_alias (nbuf, old->number, old->type);
2443 }
c19d1205 2444
e1fa0163 2445 free (nbuf);
d929913e 2446 return TRUE;
b99bd4ef
NC
2447}
2448
dcbf9037
JB
2449/* Create a Neon typed/indexed register alias using directives, e.g.:
2450 X .dn d5.s32[1]
2451 Y .qn 6.s16
2452 Z .dn d7
2453 T .dn Z[0]
2454 These typed registers can be used instead of the types specified after the
2455 Neon mnemonic, so long as all operands given have types. Types can also be
2456 specified directly, e.g.:
5f4273c7 2457 vadd d0.s32, d1.s32, d2.s32 */
dcbf9037 2458
c921be7d 2459static bfd_boolean
dcbf9037
JB
2460create_neon_reg_alias (char *newname, char *p)
2461{
2462 enum arm_reg_type basetype;
2463 struct reg_entry *basereg;
2464 struct reg_entry mybasereg;
2465 struct neon_type ntype;
2466 struct neon_typed_alias typeinfo;
12d6b0b7 2467 char *namebuf, *nameend ATTRIBUTE_UNUSED;
dcbf9037 2468 int namelen;
5f4273c7 2469
dcbf9037
JB
2470 typeinfo.defined = 0;
2471 typeinfo.eltype.type = NT_invtype;
2472 typeinfo.eltype.size = -1;
2473 typeinfo.index = -1;
5f4273c7 2474
dcbf9037 2475 nameend = p;
5f4273c7 2476
dcbf9037
JB
2477 if (strncmp (p, " .dn ", 5) == 0)
2478 basetype = REG_TYPE_VFD;
2479 else if (strncmp (p, " .qn ", 5) == 0)
2480 basetype = REG_TYPE_NQ;
2481 else
c921be7d 2482 return FALSE;
5f4273c7 2483
dcbf9037 2484 p += 5;
5f4273c7 2485
dcbf9037 2486 if (*p == '\0')
c921be7d 2487 return FALSE;
5f4273c7 2488
dcbf9037
JB
2489 basereg = arm_reg_parse_multi (&p);
2490
2491 if (basereg && basereg->type != basetype)
2492 {
2493 as_bad (_("bad type for register"));
c921be7d 2494 return FALSE;
dcbf9037
JB
2495 }
2496
2497 if (basereg == NULL)
2498 {
2499 expressionS exp;
2500 /* Try parsing as an integer. */
2501 my_get_expression (&exp, &p, GE_NO_PREFIX);
2502 if (exp.X_op != O_constant)
477330fc
RM
2503 {
2504 as_bad (_("expression must be constant"));
2505 return FALSE;
2506 }
dcbf9037
JB
2507 basereg = &mybasereg;
2508 basereg->number = (basetype == REG_TYPE_NQ) ? exp.X_add_number * 2
477330fc 2509 : exp.X_add_number;
dcbf9037
JB
2510 basereg->neon = 0;
2511 }
2512
2513 if (basereg->neon)
2514 typeinfo = *basereg->neon;
2515
2516 if (parse_neon_type (&ntype, &p) == SUCCESS)
2517 {
2518 /* We got a type. */
2519 if (typeinfo.defined & NTA_HASTYPE)
477330fc
RM
2520 {
2521 as_bad (_("can't redefine the type of a register alias"));
2522 return FALSE;
2523 }
5f4273c7 2524
dcbf9037
JB
2525 typeinfo.defined |= NTA_HASTYPE;
2526 if (ntype.elems != 1)
477330fc
RM
2527 {
2528 as_bad (_("you must specify a single type only"));
2529 return FALSE;
2530 }
dcbf9037
JB
2531 typeinfo.eltype = ntype.el[0];
2532 }
5f4273c7 2533
dcbf9037
JB
2534 if (skip_past_char (&p, '[') == SUCCESS)
2535 {
2536 expressionS exp;
2537 /* We got a scalar index. */
5f4273c7 2538
dcbf9037 2539 if (typeinfo.defined & NTA_HASINDEX)
477330fc
RM
2540 {
2541 as_bad (_("can't redefine the index of a scalar alias"));
2542 return FALSE;
2543 }
5f4273c7 2544
dcbf9037 2545 my_get_expression (&exp, &p, GE_NO_PREFIX);
5f4273c7 2546
dcbf9037 2547 if (exp.X_op != O_constant)
477330fc
RM
2548 {
2549 as_bad (_("scalar index must be constant"));
2550 return FALSE;
2551 }
5f4273c7 2552
dcbf9037
JB
2553 typeinfo.defined |= NTA_HASINDEX;
2554 typeinfo.index = exp.X_add_number;
5f4273c7 2555
dcbf9037 2556 if (skip_past_char (&p, ']') == FAIL)
477330fc
RM
2557 {
2558 as_bad (_("expecting ]"));
2559 return FALSE;
2560 }
dcbf9037
JB
2561 }
2562
15735687
NS
2563 /* If TC_CASE_SENSITIVE is defined, then newname already points to
2564 the desired alias name, and p points to its end. If not, then
2565 the desired alias name is in the global original_case_string. */
2566#ifdef TC_CASE_SENSITIVE
dcbf9037 2567 namelen = nameend - newname;
15735687
NS
2568#else
2569 newname = original_case_string;
2570 namelen = strlen (newname);
2571#endif
2572
29a2809e 2573 namebuf = xmemdup0 (newname, namelen);
5f4273c7 2574
dcbf9037 2575 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2576 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2577
dcbf9037
JB
2578 /* Insert name in all uppercase. */
2579 for (p = namebuf; *p; p++)
2580 *p = TOUPPER (*p);
5f4273c7 2581
dcbf9037
JB
2582 if (strncmp (namebuf, newname, namelen))
2583 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2584 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2585
dcbf9037
JB
2586 /* Insert name in all lowercase. */
2587 for (p = namebuf; *p; p++)
2588 *p = TOLOWER (*p);
5f4273c7 2589
dcbf9037
JB
2590 if (strncmp (namebuf, newname, namelen))
2591 insert_neon_reg_alias (namebuf, basereg->number, basetype,
477330fc 2592 typeinfo.defined != 0 ? &typeinfo : NULL);
5f4273c7 2593
e1fa0163 2594 free (namebuf);
c921be7d 2595 return TRUE;
dcbf9037
JB
2596}
2597
c19d1205
ZW
2598/* Should never be called, as .req goes between the alias and the
2599 register name, not at the beginning of the line. */
c921be7d 2600
b99bd4ef 2601static void
c19d1205 2602s_req (int a ATTRIBUTE_UNUSED)
b99bd4ef 2603{
c19d1205
ZW
2604 as_bad (_("invalid syntax for .req directive"));
2605}
b99bd4ef 2606
dcbf9037
JB
2607static void
2608s_dn (int a ATTRIBUTE_UNUSED)
2609{
2610 as_bad (_("invalid syntax for .dn directive"));
2611}
2612
2613static void
2614s_qn (int a ATTRIBUTE_UNUSED)
2615{
2616 as_bad (_("invalid syntax for .qn directive"));
2617}
2618
c19d1205
ZW
2619/* The .unreq directive deletes an alias which was previously defined
2620 by .req. For example:
b99bd4ef 2621
c19d1205
ZW
2622 my_alias .req r11
2623 .unreq my_alias */
b99bd4ef
NC
2624
2625static void
c19d1205 2626s_unreq (int a ATTRIBUTE_UNUSED)
b99bd4ef 2627{
c19d1205
ZW
2628 char * name;
2629 char saved_char;
b99bd4ef 2630
c19d1205
ZW
2631 name = input_line_pointer;
2632
2633 while (*input_line_pointer != 0
2634 && *input_line_pointer != ' '
2635 && *input_line_pointer != '\n')
2636 ++input_line_pointer;
2637
2638 saved_char = *input_line_pointer;
2639 *input_line_pointer = 0;
2640
2641 if (!*name)
2642 as_bad (_("invalid syntax for .unreq directive"));
2643 else
2644 {
21d799b5 2645 struct reg_entry *reg = (struct reg_entry *) hash_find (arm_reg_hsh,
477330fc 2646 name);
c19d1205
ZW
2647
2648 if (!reg)
2649 as_bad (_("unknown register alias '%s'"), name);
2650 else if (reg->builtin)
a1727c1a 2651 as_warn (_("ignoring attempt to use .unreq on fixed register name: '%s'"),
c19d1205
ZW
2652 name);
2653 else
2654 {
d929913e
NC
2655 char * p;
2656 char * nbuf;
2657
db0bc284 2658 hash_delete (arm_reg_hsh, name, FALSE);
c19d1205 2659 free ((char *) reg->name);
477330fc
RM
2660 if (reg->neon)
2661 free (reg->neon);
c19d1205 2662 free (reg);
d929913e
NC
2663
2664 /* Also locate the all upper case and all lower case versions.
2665 Do not complain if we cannot find one or the other as it
2666 was probably deleted above. */
5f4273c7 2667
d929913e
NC
2668 nbuf = strdup (name);
2669 for (p = nbuf; *p; p++)
2670 *p = TOUPPER (*p);
21d799b5 2671 reg = (struct reg_entry *) hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2672 if (reg)
2673 {
db0bc284 2674 hash_delete (arm_reg_hsh, nbuf, FALSE);
d929913e
NC
2675 free ((char *) reg->name);
2676 if (reg->neon)
2677 free (reg->neon);
2678 free (reg);
2679 }
2680
2681 for (p = nbuf; *p; p++)
2682 *p = TOLOWER (*p);
21d799b5 2683 reg = (struct reg_entry *) hash_find (arm_reg_hsh, nbuf);
d929913e
NC
2684 if (reg)
2685 {
db0bc284 2686 hash_delete (arm_reg_hsh, nbuf, FALSE);
d929913e
NC
2687 free ((char *) reg->name);
2688 if (reg->neon)
2689 free (reg->neon);
2690 free (reg);
2691 }
2692
2693 free (nbuf);
c19d1205
ZW
2694 }
2695 }
b99bd4ef 2696
c19d1205 2697 *input_line_pointer = saved_char;
b99bd4ef
NC
2698 demand_empty_rest_of_line ();
2699}
2700
c19d1205
ZW
2701/* Directives: Instruction set selection. */
2702
2703#ifdef OBJ_ELF
2704/* This code is to handle mapping symbols as defined in the ARM ELF spec.
2705 (See "Mapping symbols", section 4.5.5, ARM AAELF version 1.0).
2706 Note that previously, $a and $t has type STT_FUNC (BSF_OBJECT flag),
2707 and $d has type STT_OBJECT (BSF_OBJECT flag). Now all three are untyped. */
2708
cd000bff
DJ
2709/* Create a new mapping symbol for the transition to STATE. */
2710
2711static void
2712make_mapping_symbol (enum mstate state, valueT value, fragS *frag)
b99bd4ef 2713{
a737bd4d 2714 symbolS * symbolP;
c19d1205
ZW
2715 const char * symname;
2716 int type;
b99bd4ef 2717
c19d1205 2718 switch (state)
b99bd4ef 2719 {
c19d1205
ZW
2720 case MAP_DATA:
2721 symname = "$d";
2722 type = BSF_NO_FLAGS;
2723 break;
2724 case MAP_ARM:
2725 symname = "$a";
2726 type = BSF_NO_FLAGS;
2727 break;
2728 case MAP_THUMB:
2729 symname = "$t";
2730 type = BSF_NO_FLAGS;
2731 break;
c19d1205
ZW
2732 default:
2733 abort ();
2734 }
2735
cd000bff 2736 symbolP = symbol_new (symname, now_seg, value, frag);
c19d1205
ZW
2737 symbol_get_bfdsym (symbolP)->flags |= type | BSF_LOCAL;
2738
2739 switch (state)
2740 {
2741 case MAP_ARM:
2742 THUMB_SET_FUNC (symbolP, 0);
2743 ARM_SET_THUMB (symbolP, 0);
2744 ARM_SET_INTERWORK (symbolP, support_interwork);
2745 break;
2746
2747 case MAP_THUMB:
2748 THUMB_SET_FUNC (symbolP, 1);
2749 ARM_SET_THUMB (symbolP, 1);
2750 ARM_SET_INTERWORK (symbolP, support_interwork);
2751 break;
2752
2753 case MAP_DATA:
2754 default:
cd000bff
DJ
2755 break;
2756 }
2757
2758 /* Save the mapping symbols for future reference. Also check that
2759 we do not place two mapping symbols at the same offset within a
2760 frag. We'll handle overlap between frags in
2de7820f
JZ
2761 check_mapping_symbols.
2762
2763 If .fill or other data filling directive generates zero sized data,
2764 the mapping symbol for the following code will have the same value
2765 as the one generated for the data filling directive. In this case,
2766 we replace the old symbol with the new one at the same address. */
cd000bff
DJ
2767 if (value == 0)
2768 {
2de7820f
JZ
2769 if (frag->tc_frag_data.first_map != NULL)
2770 {
2771 know (S_GET_VALUE (frag->tc_frag_data.first_map) == 0);
2772 symbol_remove (frag->tc_frag_data.first_map, &symbol_rootP, &symbol_lastP);
2773 }
cd000bff
DJ
2774 frag->tc_frag_data.first_map = symbolP;
2775 }
2776 if (frag->tc_frag_data.last_map != NULL)
0f020cef
JZ
2777 {
2778 know (S_GET_VALUE (frag->tc_frag_data.last_map) <= S_GET_VALUE (symbolP));
0f020cef
JZ
2779 if (S_GET_VALUE (frag->tc_frag_data.last_map) == S_GET_VALUE (symbolP))
2780 symbol_remove (frag->tc_frag_data.last_map, &symbol_rootP, &symbol_lastP);
2781 }
cd000bff
DJ
2782 frag->tc_frag_data.last_map = symbolP;
2783}
2784
2785/* We must sometimes convert a region marked as code to data during
2786 code alignment, if an odd number of bytes have to be padded. The
2787 code mapping symbol is pushed to an aligned address. */
2788
2789static void
2790insert_data_mapping_symbol (enum mstate state,
2791 valueT value, fragS *frag, offsetT bytes)
2792{
2793 /* If there was already a mapping symbol, remove it. */
2794 if (frag->tc_frag_data.last_map != NULL
2795 && S_GET_VALUE (frag->tc_frag_data.last_map) == frag->fr_address + value)
2796 {
2797 symbolS *symp = frag->tc_frag_data.last_map;
2798
2799 if (value == 0)
2800 {
2801 know (frag->tc_frag_data.first_map == symp);
2802 frag->tc_frag_data.first_map = NULL;
2803 }
2804 frag->tc_frag_data.last_map = NULL;
2805 symbol_remove (symp, &symbol_rootP, &symbol_lastP);
c19d1205 2806 }
cd000bff
DJ
2807
2808 make_mapping_symbol (MAP_DATA, value, frag);
2809 make_mapping_symbol (state, value + bytes, frag);
2810}
2811
2812static void mapping_state_2 (enum mstate state, int max_chars);
2813
2814/* Set the mapping state to STATE. Only call this when about to
2815 emit some STATE bytes to the file. */
2816
4e9aaefb 2817#define TRANSITION(from, to) (mapstate == (from) && state == (to))
cd000bff
DJ
2818void
2819mapping_state (enum mstate state)
2820{
940b5ce0
DJ
2821 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
2822
cd000bff
DJ
2823 if (mapstate == state)
2824 /* The mapping symbol has already been emitted.
2825 There is nothing else to do. */
2826 return;
49c62a33
NC
2827
2828 if (state == MAP_ARM || state == MAP_THUMB)
2829 /* PR gas/12931
2830 All ARM instructions require 4-byte alignment.
2831 (Almost) all Thumb instructions require 2-byte alignment.
2832
2833 When emitting instructions into any section, mark the section
2834 appropriately.
2835
2836 Some Thumb instructions are alignment-sensitive modulo 4 bytes,
2837 but themselves require 2-byte alignment; this applies to some
33eaf5de 2838 PC- relative forms. However, these cases will involve implicit
49c62a33
NC
2839 literal pool generation or an explicit .align >=2, both of
2840 which will cause the section to me marked with sufficient
2841 alignment. Thus, we don't handle those cases here. */
2842 record_alignment (now_seg, state == MAP_ARM ? 2 : 1);
2843
2844 if (TRANSITION (MAP_UNDEFINED, MAP_DATA))
4e9aaefb 2845 /* This case will be evaluated later. */
cd000bff 2846 return;
cd000bff
DJ
2847
2848 mapping_state_2 (state, 0);
cd000bff
DJ
2849}
2850
2851/* Same as mapping_state, but MAX_CHARS bytes have already been
2852 allocated. Put the mapping symbol that far back. */
2853
2854static void
2855mapping_state_2 (enum mstate state, int max_chars)
2856{
940b5ce0
DJ
2857 enum mstate mapstate = seg_info (now_seg)->tc_segment_info_data.mapstate;
2858
2859 if (!SEG_NORMAL (now_seg))
2860 return;
2861
cd000bff
DJ
2862 if (mapstate == state)
2863 /* The mapping symbol has already been emitted.
2864 There is nothing else to do. */
2865 return;
2866
4e9aaefb
SA
2867 if (TRANSITION (MAP_UNDEFINED, MAP_ARM)
2868 || TRANSITION (MAP_UNDEFINED, MAP_THUMB))
2869 {
2870 struct frag * const frag_first = seg_info (now_seg)->frchainP->frch_root;
2871 const int add_symbol = (frag_now != frag_first) || (frag_now_fix () > 0);
2872
2873 if (add_symbol)
2874 make_mapping_symbol (MAP_DATA, (valueT) 0, frag_first);
2875 }
2876
cd000bff
DJ
2877 seg_info (now_seg)->tc_segment_info_data.mapstate = state;
2878 make_mapping_symbol (state, (valueT) frag_now_fix () - max_chars, frag_now);
c19d1205 2879}
4e9aaefb 2880#undef TRANSITION
c19d1205 2881#else
d3106081
NS
2882#define mapping_state(x) ((void)0)
2883#define mapping_state_2(x, y) ((void)0)
c19d1205
ZW
2884#endif
2885
2886/* Find the real, Thumb encoded start of a Thumb function. */
2887
4343666d 2888#ifdef OBJ_COFF
c19d1205
ZW
2889static symbolS *
2890find_real_start (symbolS * symbolP)
2891{
2892 char * real_start;
2893 const char * name = S_GET_NAME (symbolP);
2894 symbolS * new_target;
2895
2896 /* This definition must agree with the one in gcc/config/arm/thumb.c. */
2897#define STUB_NAME ".real_start_of"
2898
2899 if (name == NULL)
2900 abort ();
2901
37f6032b
ZW
2902 /* The compiler may generate BL instructions to local labels because
2903 it needs to perform a branch to a far away location. These labels
2904 do not have a corresponding ".real_start_of" label. We check
2905 both for S_IS_LOCAL and for a leading dot, to give a way to bypass
2906 the ".real_start_of" convention for nonlocal branches. */
2907 if (S_IS_LOCAL (symbolP) || name[0] == '.')
c19d1205
ZW
2908 return symbolP;
2909
e1fa0163 2910 real_start = concat (STUB_NAME, name, NULL);
c19d1205 2911 new_target = symbol_find (real_start);
e1fa0163 2912 free (real_start);
c19d1205
ZW
2913
2914 if (new_target == NULL)
2915 {
bd3ba5d1 2916 as_warn (_("Failed to find real start of function: %s\n"), name);
c19d1205
ZW
2917 new_target = symbolP;
2918 }
2919
c19d1205
ZW
2920 return new_target;
2921}
4343666d 2922#endif
c19d1205
ZW
2923
2924static void
2925opcode_select (int width)
2926{
2927 switch (width)
2928 {
2929 case 16:
2930 if (! thumb_mode)
2931 {
e74cfd16 2932 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
c19d1205
ZW
2933 as_bad (_("selected processor does not support THUMB opcodes"));
2934
2935 thumb_mode = 1;
2936 /* No need to force the alignment, since we will have been
2937 coming from ARM mode, which is word-aligned. */
2938 record_alignment (now_seg, 1);
2939 }
c19d1205
ZW
2940 break;
2941
2942 case 32:
2943 if (thumb_mode)
2944 {
e74cfd16 2945 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205
ZW
2946 as_bad (_("selected processor does not support ARM opcodes"));
2947
2948 thumb_mode = 0;
2949
2950 if (!need_pass_2)
2951 frag_align (2, 0, 0);
2952
2953 record_alignment (now_seg, 1);
2954 }
c19d1205
ZW
2955 break;
2956
2957 default:
2958 as_bad (_("invalid instruction size selected (%d)"), width);
2959 }
2960}
2961
2962static void
2963s_arm (int ignore ATTRIBUTE_UNUSED)
2964{
2965 opcode_select (32);
2966 demand_empty_rest_of_line ();
2967}
2968
2969static void
2970s_thumb (int ignore ATTRIBUTE_UNUSED)
2971{
2972 opcode_select (16);
2973 demand_empty_rest_of_line ();
2974}
2975
2976static void
2977s_code (int unused ATTRIBUTE_UNUSED)
2978{
2979 int temp;
2980
2981 temp = get_absolute_expression ();
2982 switch (temp)
2983 {
2984 case 16:
2985 case 32:
2986 opcode_select (temp);
2987 break;
2988
2989 default:
2990 as_bad (_("invalid operand to .code directive (%d) (expecting 16 or 32)"), temp);
2991 }
2992}
2993
2994static void
2995s_force_thumb (int ignore ATTRIBUTE_UNUSED)
2996{
2997 /* If we are not already in thumb mode go into it, EVEN if
2998 the target processor does not support thumb instructions.
2999 This is used by gcc/config/arm/lib1funcs.asm for example
3000 to compile interworking support functions even if the
3001 target processor should not support interworking. */
3002 if (! thumb_mode)
3003 {
3004 thumb_mode = 2;
3005 record_alignment (now_seg, 1);
3006 }
3007
3008 demand_empty_rest_of_line ();
3009}
3010
3011static void
3012s_thumb_func (int ignore ATTRIBUTE_UNUSED)
3013{
3014 s_thumb (0);
3015
3016 /* The following label is the name/address of the start of a Thumb function.
3017 We need to know this for the interworking support. */
3018 label_is_thumb_function_name = TRUE;
3019}
3020
3021/* Perform a .set directive, but also mark the alias as
3022 being a thumb function. */
3023
3024static void
3025s_thumb_set (int equiv)
3026{
3027 /* XXX the following is a duplicate of the code for s_set() in read.c
3028 We cannot just call that code as we need to get at the symbol that
3029 is created. */
3030 char * name;
3031 char delim;
3032 char * end_name;
3033 symbolS * symbolP;
3034
3035 /* Especial apologies for the random logic:
3036 This just grew, and could be parsed much more simply!
3037 Dean - in haste. */
d02603dc 3038 delim = get_symbol_name (& name);
c19d1205 3039 end_name = input_line_pointer;
d02603dc 3040 (void) restore_line_pointer (delim);
c19d1205
ZW
3041
3042 if (*input_line_pointer != ',')
3043 {
3044 *end_name = 0;
3045 as_bad (_("expected comma after name \"%s\""), name);
b99bd4ef
NC
3046 *end_name = delim;
3047 ignore_rest_of_line ();
3048 return;
3049 }
3050
3051 input_line_pointer++;
3052 *end_name = 0;
3053
3054 if (name[0] == '.' && name[1] == '\0')
3055 {
3056 /* XXX - this should not happen to .thumb_set. */
3057 abort ();
3058 }
3059
3060 if ((symbolP = symbol_find (name)) == NULL
3061 && (symbolP = md_undefined_symbol (name)) == NULL)
3062 {
3063#ifndef NO_LISTING
3064 /* When doing symbol listings, play games with dummy fragments living
3065 outside the normal fragment chain to record the file and line info
c19d1205 3066 for this symbol. */
b99bd4ef
NC
3067 if (listing & LISTING_SYMBOLS)
3068 {
3069 extern struct list_info_struct * listing_tail;
21d799b5 3070 fragS * dummy_frag = (fragS * ) xmalloc (sizeof (fragS));
b99bd4ef
NC
3071
3072 memset (dummy_frag, 0, sizeof (fragS));
3073 dummy_frag->fr_type = rs_fill;
3074 dummy_frag->line = listing_tail;
3075 symbolP = symbol_new (name, undefined_section, 0, dummy_frag);
3076 dummy_frag->fr_symbol = symbolP;
3077 }
3078 else
3079#endif
3080 symbolP = symbol_new (name, undefined_section, 0, &zero_address_frag);
3081
3082#ifdef OBJ_COFF
3083 /* "set" symbols are local unless otherwise specified. */
3084 SF_SET_LOCAL (symbolP);
3085#endif /* OBJ_COFF */
3086 } /* Make a new symbol. */
3087
3088 symbol_table_insert (symbolP);
3089
3090 * end_name = delim;
3091
3092 if (equiv
3093 && S_IS_DEFINED (symbolP)
3094 && S_GET_SEGMENT (symbolP) != reg_section)
3095 as_bad (_("symbol `%s' already defined"), S_GET_NAME (symbolP));
3096
3097 pseudo_set (symbolP);
3098
3099 demand_empty_rest_of_line ();
3100
c19d1205 3101 /* XXX Now we come to the Thumb specific bit of code. */
b99bd4ef
NC
3102
3103 THUMB_SET_FUNC (symbolP, 1);
3104 ARM_SET_THUMB (symbolP, 1);
3105#if defined OBJ_ELF || defined OBJ_COFF
3106 ARM_SET_INTERWORK (symbolP, support_interwork);
3107#endif
3108}
3109
c19d1205 3110/* Directives: Mode selection. */
b99bd4ef 3111
c19d1205
ZW
3112/* .syntax [unified|divided] - choose the new unified syntax
3113 (same for Arm and Thumb encoding, modulo slight differences in what
3114 can be represented) or the old divergent syntax for each mode. */
b99bd4ef 3115static void
c19d1205 3116s_syntax (int unused ATTRIBUTE_UNUSED)
b99bd4ef 3117{
c19d1205
ZW
3118 char *name, delim;
3119
d02603dc 3120 delim = get_symbol_name (& name);
c19d1205
ZW
3121
3122 if (!strcasecmp (name, "unified"))
3123 unified_syntax = TRUE;
3124 else if (!strcasecmp (name, "divided"))
3125 unified_syntax = FALSE;
3126 else
3127 {
3128 as_bad (_("unrecognized syntax mode \"%s\""), name);
3129 return;
3130 }
d02603dc 3131 (void) restore_line_pointer (delim);
b99bd4ef
NC
3132 demand_empty_rest_of_line ();
3133}
3134
c19d1205
ZW
3135/* Directives: sectioning and alignment. */
3136
c19d1205
ZW
3137static void
3138s_bss (int ignore ATTRIBUTE_UNUSED)
b99bd4ef 3139{
c19d1205
ZW
3140 /* We don't support putting frags in the BSS segment, we fake it by
3141 marking in_bss, then looking at s_skip for clues. */
3142 subseg_set (bss_section, 0);
3143 demand_empty_rest_of_line ();
cd000bff
DJ
3144
3145#ifdef md_elf_section_change_hook
3146 md_elf_section_change_hook ();
3147#endif
c19d1205 3148}
b99bd4ef 3149
c19d1205
ZW
3150static void
3151s_even (int ignore ATTRIBUTE_UNUSED)
3152{
3153 /* Never make frag if expect extra pass. */
3154 if (!need_pass_2)
3155 frag_align (1, 0, 0);
b99bd4ef 3156
c19d1205 3157 record_alignment (now_seg, 1);
b99bd4ef 3158
c19d1205 3159 demand_empty_rest_of_line ();
b99bd4ef
NC
3160}
3161
2e6976a8
DG
3162/* Directives: CodeComposer Studio. */
3163
3164/* .ref (for CodeComposer Studio syntax only). */
3165static void
3166s_ccs_ref (int unused ATTRIBUTE_UNUSED)
3167{
3168 if (codecomposer_syntax)
3169 ignore_rest_of_line ();
3170 else
3171 as_bad (_(".ref pseudo-op only available with -mccs flag."));
3172}
3173
3174/* If name is not NULL, then it is used for marking the beginning of a
2b0f3761 3175 function, whereas if it is NULL then it means the function end. */
2e6976a8
DG
3176static void
3177asmfunc_debug (const char * name)
3178{
3179 static const char * last_name = NULL;
3180
3181 if (name != NULL)
3182 {
3183 gas_assert (last_name == NULL);
3184 last_name = name;
3185
3186 if (debug_type == DEBUG_STABS)
3187 stabs_generate_asm_func (name, name);
3188 }
3189 else
3190 {
3191 gas_assert (last_name != NULL);
3192
3193 if (debug_type == DEBUG_STABS)
3194 stabs_generate_asm_endfunc (last_name, last_name);
3195
3196 last_name = NULL;
3197 }
3198}
3199
3200static void
3201s_ccs_asmfunc (int unused ATTRIBUTE_UNUSED)
3202{
3203 if (codecomposer_syntax)
3204 {
3205 switch (asmfunc_state)
3206 {
3207 case OUTSIDE_ASMFUNC:
3208 asmfunc_state = WAITING_ASMFUNC_NAME;
3209 break;
3210
3211 case WAITING_ASMFUNC_NAME:
3212 as_bad (_(".asmfunc repeated."));
3213 break;
3214
3215 case WAITING_ENDASMFUNC:
3216 as_bad (_(".asmfunc without function."));
3217 break;
3218 }
3219 demand_empty_rest_of_line ();
3220 }
3221 else
3222 as_bad (_(".asmfunc pseudo-op only available with -mccs flag."));
3223}
3224
3225static void
3226s_ccs_endasmfunc (int unused ATTRIBUTE_UNUSED)
3227{
3228 if (codecomposer_syntax)
3229 {
3230 switch (asmfunc_state)
3231 {
3232 case OUTSIDE_ASMFUNC:
3233 as_bad (_(".endasmfunc without a .asmfunc."));
3234 break;
3235
3236 case WAITING_ASMFUNC_NAME:
3237 as_bad (_(".endasmfunc without function."));
3238 break;
3239
3240 case WAITING_ENDASMFUNC:
3241 asmfunc_state = OUTSIDE_ASMFUNC;
3242 asmfunc_debug (NULL);
3243 break;
3244 }
3245 demand_empty_rest_of_line ();
3246 }
3247 else
3248 as_bad (_(".endasmfunc pseudo-op only available with -mccs flag."));
3249}
3250
3251static void
3252s_ccs_def (int name)
3253{
3254 if (codecomposer_syntax)
3255 s_globl (name);
3256 else
3257 as_bad (_(".def pseudo-op only available with -mccs flag."));
3258}
3259
c19d1205 3260/* Directives: Literal pools. */
a737bd4d 3261
c19d1205
ZW
3262static literal_pool *
3263find_literal_pool (void)
a737bd4d 3264{
c19d1205 3265 literal_pool * pool;
a737bd4d 3266
c19d1205 3267 for (pool = list_of_pools; pool != NULL; pool = pool->next)
a737bd4d 3268 {
c19d1205
ZW
3269 if (pool->section == now_seg
3270 && pool->sub_section == now_subseg)
3271 break;
a737bd4d
NC
3272 }
3273
c19d1205 3274 return pool;
a737bd4d
NC
3275}
3276
c19d1205
ZW
3277static literal_pool *
3278find_or_make_literal_pool (void)
a737bd4d 3279{
c19d1205
ZW
3280 /* Next literal pool ID number. */
3281 static unsigned int latest_pool_num = 1;
3282 literal_pool * pool;
a737bd4d 3283
c19d1205 3284 pool = find_literal_pool ();
a737bd4d 3285
c19d1205 3286 if (pool == NULL)
a737bd4d 3287 {
c19d1205 3288 /* Create a new pool. */
325801bd 3289 pool = XNEW (literal_pool);
c19d1205
ZW
3290 if (! pool)
3291 return NULL;
a737bd4d 3292
c19d1205
ZW
3293 pool->next_free_entry = 0;
3294 pool->section = now_seg;
3295 pool->sub_section = now_subseg;
3296 pool->next = list_of_pools;
3297 pool->symbol = NULL;
8335d6aa 3298 pool->alignment = 2;
c19d1205
ZW
3299
3300 /* Add it to the list. */
3301 list_of_pools = pool;
a737bd4d 3302 }
a737bd4d 3303
c19d1205
ZW
3304 /* New pools, and emptied pools, will have a NULL symbol. */
3305 if (pool->symbol == NULL)
a737bd4d 3306 {
c19d1205
ZW
3307 pool->symbol = symbol_create (FAKE_LABEL_NAME, undefined_section,
3308 (valueT) 0, &zero_address_frag);
3309 pool->id = latest_pool_num ++;
a737bd4d
NC
3310 }
3311
c19d1205
ZW
3312 /* Done. */
3313 return pool;
a737bd4d
NC
3314}
3315
c19d1205 3316/* Add the literal in the global 'inst'
5f4273c7 3317 structure to the relevant literal pool. */
b99bd4ef
NC
3318
3319static int
8335d6aa 3320add_to_lit_pool (unsigned int nbytes)
b99bd4ef 3321{
8335d6aa
JW
3322#define PADDING_SLOT 0x1
3323#define LIT_ENTRY_SIZE_MASK 0xFF
c19d1205 3324 literal_pool * pool;
8335d6aa
JW
3325 unsigned int entry, pool_size = 0;
3326 bfd_boolean padding_slot_p = FALSE;
e56c722b 3327 unsigned imm1 = 0;
8335d6aa
JW
3328 unsigned imm2 = 0;
3329
3330 if (nbytes == 8)
3331 {
3332 imm1 = inst.operands[1].imm;
3333 imm2 = (inst.operands[1].regisimm ? inst.operands[1].reg
e2b0ab59 3334 : inst.relocs[0].exp.X_unsigned ? 0
2569ceb0 3335 : ((bfd_int64_t) inst.operands[1].imm) >> 32);
8335d6aa
JW
3336 if (target_big_endian)
3337 {
3338 imm1 = imm2;
3339 imm2 = inst.operands[1].imm;
3340 }
3341 }
b99bd4ef 3342
c19d1205
ZW
3343 pool = find_or_make_literal_pool ();
3344
3345 /* Check if this literal value is already in the pool. */
3346 for (entry = 0; entry < pool->next_free_entry; entry ++)
b99bd4ef 3347 {
8335d6aa
JW
3348 if (nbytes == 4)
3349 {
e2b0ab59
AV
3350 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3351 && (inst.relocs[0].exp.X_op == O_constant)
8335d6aa 3352 && (pool->literals[entry].X_add_number
e2b0ab59 3353 == inst.relocs[0].exp.X_add_number)
8335d6aa
JW
3354 && (pool->literals[entry].X_md == nbytes)
3355 && (pool->literals[entry].X_unsigned
e2b0ab59 3356 == inst.relocs[0].exp.X_unsigned))
8335d6aa
JW
3357 break;
3358
e2b0ab59
AV
3359 if ((pool->literals[entry].X_op == inst.relocs[0].exp.X_op)
3360 && (inst.relocs[0].exp.X_op == O_symbol)
8335d6aa 3361 && (pool->literals[entry].X_add_number
e2b0ab59 3362 == inst.relocs[0].exp.X_add_number)
8335d6aa 3363 && (pool->literals[entry].X_add_symbol
e2b0ab59 3364 == inst.relocs[0].exp.X_add_symbol)
8335d6aa 3365 && (pool->literals[entry].X_op_symbol
e2b0ab59 3366 == inst.relocs[0].exp.X_op_symbol)
8335d6aa
JW
3367 && (pool->literals[entry].X_md == nbytes))
3368 break;
3369 }
3370 else if ((nbytes == 8)
3371 && !(pool_size & 0x7)
3372 && ((entry + 1) != pool->next_free_entry)
3373 && (pool->literals[entry].X_op == O_constant)
19f2f6a9 3374 && (pool->literals[entry].X_add_number == (offsetT) imm1)
8335d6aa 3375 && (pool->literals[entry].X_unsigned
e2b0ab59 3376 == inst.relocs[0].exp.X_unsigned)
8335d6aa 3377 && (pool->literals[entry + 1].X_op == O_constant)
19f2f6a9 3378 && (pool->literals[entry + 1].X_add_number == (offsetT) imm2)
8335d6aa 3379 && (pool->literals[entry + 1].X_unsigned
e2b0ab59 3380 == inst.relocs[0].exp.X_unsigned))
c19d1205
ZW
3381 break;
3382
8335d6aa
JW
3383 padding_slot_p = ((pool->literals[entry].X_md >> 8) == PADDING_SLOT);
3384 if (padding_slot_p && (nbytes == 4))
c19d1205 3385 break;
8335d6aa
JW
3386
3387 pool_size += 4;
b99bd4ef
NC
3388 }
3389
c19d1205
ZW
3390 /* Do we need to create a new entry? */
3391 if (entry == pool->next_free_entry)
3392 {
3393 if (entry >= MAX_LITERAL_POOL_SIZE)
3394 {
3395 inst.error = _("literal pool overflow");
3396 return FAIL;
3397 }
3398
8335d6aa
JW
3399 if (nbytes == 8)
3400 {
3401 /* For 8-byte entries, we align to an 8-byte boundary,
3402 and split it into two 4-byte entries, because on 32-bit
3403 host, 8-byte constants are treated as big num, thus
3404 saved in "generic_bignum" which will be overwritten
3405 by later assignments.
3406
3407 We also need to make sure there is enough space for
3408 the split.
3409
3410 We also check to make sure the literal operand is a
3411 constant number. */
e2b0ab59
AV
3412 if (!(inst.relocs[0].exp.X_op == O_constant
3413 || inst.relocs[0].exp.X_op == O_big))
8335d6aa
JW
3414 {
3415 inst.error = _("invalid type for literal pool");
3416 return FAIL;
3417 }
3418 else if (pool_size & 0x7)
3419 {
3420 if ((entry + 2) >= MAX_LITERAL_POOL_SIZE)
3421 {
3422 inst.error = _("literal pool overflow");
3423 return FAIL;
3424 }
3425
e2b0ab59 3426 pool->literals[entry] = inst.relocs[0].exp;
a6684f0d 3427 pool->literals[entry].X_op = O_constant;
8335d6aa
JW
3428 pool->literals[entry].X_add_number = 0;
3429 pool->literals[entry++].X_md = (PADDING_SLOT << 8) | 4;
3430 pool->next_free_entry += 1;
3431 pool_size += 4;
3432 }
3433 else if ((entry + 1) >= MAX_LITERAL_POOL_SIZE)
3434 {
3435 inst.error = _("literal pool overflow");
3436 return FAIL;
3437 }
3438
e2b0ab59 3439 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3440 pool->literals[entry].X_op = O_constant;
3441 pool->literals[entry].X_add_number = imm1;
e2b0ab59 3442 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa 3443 pool->literals[entry++].X_md = 4;
e2b0ab59 3444 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3445 pool->literals[entry].X_op = O_constant;
3446 pool->literals[entry].X_add_number = imm2;
e2b0ab59 3447 pool->literals[entry].X_unsigned = inst.relocs[0].exp.X_unsigned;
8335d6aa
JW
3448 pool->literals[entry].X_md = 4;
3449 pool->alignment = 3;
3450 pool->next_free_entry += 1;
3451 }
3452 else
3453 {
e2b0ab59 3454 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3455 pool->literals[entry].X_md = 4;
3456 }
3457
a8040cf2
NC
3458#ifdef OBJ_ELF
3459 /* PR ld/12974: Record the location of the first source line to reference
3460 this entry in the literal pool. If it turns out during linking that the
3461 symbol does not exist we will be able to give an accurate line number for
3462 the (first use of the) missing reference. */
3463 if (debug_type == DEBUG_DWARF2)
3464 dwarf2_where (pool->locs + entry);
3465#endif
c19d1205
ZW
3466 pool->next_free_entry += 1;
3467 }
8335d6aa
JW
3468 else if (padding_slot_p)
3469 {
e2b0ab59 3470 pool->literals[entry] = inst.relocs[0].exp;
8335d6aa
JW
3471 pool->literals[entry].X_md = nbytes;
3472 }
b99bd4ef 3473
e2b0ab59
AV
3474 inst.relocs[0].exp.X_op = O_symbol;
3475 inst.relocs[0].exp.X_add_number = pool_size;
3476 inst.relocs[0].exp.X_add_symbol = pool->symbol;
b99bd4ef 3477
c19d1205 3478 return SUCCESS;
b99bd4ef
NC
3479}
3480
2e6976a8 3481bfd_boolean
2e57ce7b 3482tc_start_label_without_colon (void)
2e6976a8
DG
3483{
3484 bfd_boolean ret = TRUE;
3485
3486 if (codecomposer_syntax && asmfunc_state == WAITING_ASMFUNC_NAME)
3487 {
2e57ce7b 3488 const char *label = input_line_pointer;
2e6976a8
DG
3489
3490 while (!is_end_of_line[(int) label[-1]])
3491 --label;
3492
3493 if (*label == '.')
3494 {
3495 as_bad (_("Invalid label '%s'"), label);
3496 ret = FALSE;
3497 }
3498
3499 asmfunc_debug (label);
3500
3501 asmfunc_state = WAITING_ENDASMFUNC;
3502 }
3503
3504 return ret;
3505}
3506
c19d1205 3507/* Can't use symbol_new here, so have to create a symbol and then at
33eaf5de 3508 a later date assign it a value. That's what these functions do. */
e16bb312 3509
c19d1205
ZW
3510static void
3511symbol_locate (symbolS * symbolP,
3512 const char * name, /* It is copied, the caller can modify. */
3513 segT segment, /* Segment identifier (SEG_<something>). */
3514 valueT valu, /* Symbol value. */
3515 fragS * frag) /* Associated fragment. */
3516{
e57e6ddc 3517 size_t name_length;
c19d1205 3518 char * preserved_copy_of_name;
e16bb312 3519
c19d1205
ZW
3520 name_length = strlen (name) + 1; /* +1 for \0. */
3521 obstack_grow (&notes, name, name_length);
21d799b5 3522 preserved_copy_of_name = (char *) obstack_finish (&notes);
e16bb312 3523
c19d1205
ZW
3524#ifdef tc_canonicalize_symbol_name
3525 preserved_copy_of_name =
3526 tc_canonicalize_symbol_name (preserved_copy_of_name);
3527#endif
b99bd4ef 3528
c19d1205 3529 S_SET_NAME (symbolP, preserved_copy_of_name);
b99bd4ef 3530
c19d1205
ZW
3531 S_SET_SEGMENT (symbolP, segment);
3532 S_SET_VALUE (symbolP, valu);
3533 symbol_clear_list_pointers (symbolP);
b99bd4ef 3534
c19d1205 3535 symbol_set_frag (symbolP, frag);
b99bd4ef 3536
c19d1205
ZW
3537 /* Link to end of symbol chain. */
3538 {
3539 extern int symbol_table_frozen;
b99bd4ef 3540
c19d1205
ZW
3541 if (symbol_table_frozen)
3542 abort ();
3543 }
b99bd4ef 3544
c19d1205 3545 symbol_append (symbolP, symbol_lastP, & symbol_rootP, & symbol_lastP);
b99bd4ef 3546
c19d1205 3547 obj_symbol_new_hook (symbolP);
b99bd4ef 3548
c19d1205
ZW
3549#ifdef tc_symbol_new_hook
3550 tc_symbol_new_hook (symbolP);
3551#endif
3552
3553#ifdef DEBUG_SYMS
3554 verify_symbol_chain (symbol_rootP, symbol_lastP);
3555#endif /* DEBUG_SYMS */
b99bd4ef
NC
3556}
3557
c19d1205
ZW
3558static void
3559s_ltorg (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 3560{
c19d1205
ZW
3561 unsigned int entry;
3562 literal_pool * pool;
3563 char sym_name[20];
b99bd4ef 3564
c19d1205
ZW
3565 pool = find_literal_pool ();
3566 if (pool == NULL
3567 || pool->symbol == NULL
3568 || pool->next_free_entry == 0)
3569 return;
b99bd4ef 3570
c19d1205
ZW
3571 /* Align pool as you have word accesses.
3572 Only make a frag if we have to. */
3573 if (!need_pass_2)
8335d6aa 3574 frag_align (pool->alignment, 0, 0);
b99bd4ef 3575
c19d1205 3576 record_alignment (now_seg, 2);
b99bd4ef 3577
aaca88ef 3578#ifdef OBJ_ELF
47fc6e36
WN
3579 seg_info (now_seg)->tc_segment_info_data.mapstate = MAP_DATA;
3580 make_mapping_symbol (MAP_DATA, (valueT) frag_now_fix (), frag_now);
aaca88ef 3581#endif
c19d1205 3582 sprintf (sym_name, "$$lit_\002%x", pool->id);
b99bd4ef 3583
c19d1205
ZW
3584 symbol_locate (pool->symbol, sym_name, now_seg,
3585 (valueT) frag_now_fix (), frag_now);
3586 symbol_table_insert (pool->symbol);
b99bd4ef 3587
c19d1205 3588 ARM_SET_THUMB (pool->symbol, thumb_mode);
b99bd4ef 3589
c19d1205
ZW
3590#if defined OBJ_COFF || defined OBJ_ELF
3591 ARM_SET_INTERWORK (pool->symbol, support_interwork);
3592#endif
6c43fab6 3593
c19d1205 3594 for (entry = 0; entry < pool->next_free_entry; entry ++)
a8040cf2
NC
3595 {
3596#ifdef OBJ_ELF
3597 if (debug_type == DEBUG_DWARF2)
3598 dwarf2_gen_line_info (frag_now_fix (), pool->locs + entry);
3599#endif
3600 /* First output the expression in the instruction to the pool. */
8335d6aa
JW
3601 emit_expr (&(pool->literals[entry]),
3602 pool->literals[entry].X_md & LIT_ENTRY_SIZE_MASK);
a8040cf2 3603 }
b99bd4ef 3604
c19d1205
ZW
3605 /* Mark the pool as empty. */
3606 pool->next_free_entry = 0;
3607 pool->symbol = NULL;
b99bd4ef
NC
3608}
3609
c19d1205
ZW
3610#ifdef OBJ_ELF
3611/* Forward declarations for functions below, in the MD interface
3612 section. */
3613static void fix_new_arm (fragS *, int, short, expressionS *, int, int);
3614static valueT create_unwind_entry (int);
3615static void start_unwind_section (const segT, int);
3616static void add_unwind_opcode (valueT, int);
3617static void flush_pending_unwind (void);
b99bd4ef 3618
c19d1205 3619/* Directives: Data. */
b99bd4ef 3620
c19d1205
ZW
3621static void
3622s_arm_elf_cons (int nbytes)
3623{
3624 expressionS exp;
b99bd4ef 3625
c19d1205
ZW
3626#ifdef md_flush_pending_output
3627 md_flush_pending_output ();
3628#endif
b99bd4ef 3629
c19d1205 3630 if (is_it_end_of_statement ())
b99bd4ef 3631 {
c19d1205
ZW
3632 demand_empty_rest_of_line ();
3633 return;
b99bd4ef
NC
3634 }
3635
c19d1205
ZW
3636#ifdef md_cons_align
3637 md_cons_align (nbytes);
3638#endif
b99bd4ef 3639
c19d1205
ZW
3640 mapping_state (MAP_DATA);
3641 do
b99bd4ef 3642 {
c19d1205
ZW
3643 int reloc;
3644 char *base = input_line_pointer;
b99bd4ef 3645
c19d1205 3646 expression (& exp);
b99bd4ef 3647
c19d1205
ZW
3648 if (exp.X_op != O_symbol)
3649 emit_expr (&exp, (unsigned int) nbytes);
3650 else
3651 {
3652 char *before_reloc = input_line_pointer;
3653 reloc = parse_reloc (&input_line_pointer);
3654 if (reloc == -1)
3655 {
3656 as_bad (_("unrecognized relocation suffix"));
3657 ignore_rest_of_line ();
3658 return;
3659 }
3660 else if (reloc == BFD_RELOC_UNUSED)
3661 emit_expr (&exp, (unsigned int) nbytes);
3662 else
3663 {
21d799b5 3664 reloc_howto_type *howto = (reloc_howto_type *)
477330fc
RM
3665 bfd_reloc_type_lookup (stdoutput,
3666 (bfd_reloc_code_real_type) reloc);
c19d1205 3667 int size = bfd_get_reloc_size (howto);
b99bd4ef 3668
2fc8bdac
ZW
3669 if (reloc == BFD_RELOC_ARM_PLT32)
3670 {
3671 as_bad (_("(plt) is only valid on branch targets"));
3672 reloc = BFD_RELOC_UNUSED;
3673 size = 0;
3674 }
3675
c19d1205 3676 if (size > nbytes)
992a06ee
AM
3677 as_bad (ngettext ("%s relocations do not fit in %d byte",
3678 "%s relocations do not fit in %d bytes",
3679 nbytes),
c19d1205
ZW
3680 howto->name, nbytes);
3681 else
3682 {
3683 /* We've parsed an expression stopping at O_symbol.
3684 But there may be more expression left now that we
3685 have parsed the relocation marker. Parse it again.
3686 XXX Surely there is a cleaner way to do this. */
3687 char *p = input_line_pointer;
3688 int offset;
325801bd 3689 char *save_buf = XNEWVEC (char, input_line_pointer - base);
e1fa0163 3690
c19d1205
ZW
3691 memcpy (save_buf, base, input_line_pointer - base);
3692 memmove (base + (input_line_pointer - before_reloc),
3693 base, before_reloc - base);
3694
3695 input_line_pointer = base + (input_line_pointer-before_reloc);
3696 expression (&exp);
3697 memcpy (base, save_buf, p - base);
3698
3699 offset = nbytes - size;
4b1a927e
AM
3700 p = frag_more (nbytes);
3701 memset (p, 0, nbytes);
c19d1205 3702 fix_new_exp (frag_now, p - frag_now->fr_literal + offset,
21d799b5 3703 size, &exp, 0, (enum bfd_reloc_code_real) reloc);
e1fa0163 3704 free (save_buf);
c19d1205
ZW
3705 }
3706 }
3707 }
b99bd4ef 3708 }
c19d1205 3709 while (*input_line_pointer++ == ',');
b99bd4ef 3710
c19d1205
ZW
3711 /* Put terminator back into stream. */
3712 input_line_pointer --;
3713 demand_empty_rest_of_line ();
b99bd4ef
NC
3714}
3715
c921be7d
NC
3716/* Emit an expression containing a 32-bit thumb instruction.
3717 Implementation based on put_thumb32_insn. */
3718
3719static void
3720emit_thumb32_expr (expressionS * exp)
3721{
3722 expressionS exp_high = *exp;
3723
3724 exp_high.X_add_number = (unsigned long)exp_high.X_add_number >> 16;
3725 emit_expr (& exp_high, (unsigned int) THUMB_SIZE);
3726 exp->X_add_number &= 0xffff;
3727 emit_expr (exp, (unsigned int) THUMB_SIZE);
3728}
3729
3730/* Guess the instruction size based on the opcode. */
3731
3732static int
3733thumb_insn_size (int opcode)
3734{
3735 if ((unsigned int) opcode < 0xe800u)
3736 return 2;
3737 else if ((unsigned int) opcode >= 0xe8000000u)
3738 return 4;
3739 else
3740 return 0;
3741}
3742
3743static bfd_boolean
3744emit_insn (expressionS *exp, int nbytes)
3745{
3746 int size = 0;
3747
3748 if (exp->X_op == O_constant)
3749 {
3750 size = nbytes;
3751
3752 if (size == 0)
3753 size = thumb_insn_size (exp->X_add_number);
3754
3755 if (size != 0)
3756 {
3757 if (size == 2 && (unsigned int)exp->X_add_number > 0xffffu)
3758 {
3759 as_bad (_(".inst.n operand too big. "\
3760 "Use .inst.w instead"));
3761 size = 0;
3762 }
3763 else
3764 {
3765 if (now_it.state == AUTOMATIC_IT_BLOCK)
3766 set_it_insn_type_nonvoid (OUTSIDE_IT_INSN, 0);
3767 else
3768 set_it_insn_type_nonvoid (NEUTRAL_IT_INSN, 0);
3769
3770 if (thumb_mode && (size > THUMB_SIZE) && !target_big_endian)
3771 emit_thumb32_expr (exp);
3772 else
3773 emit_expr (exp, (unsigned int) size);
3774
3775 it_fsm_post_encode ();
3776 }
3777 }
3778 else
3779 as_bad (_("cannot determine Thumb instruction size. " \
3780 "Use .inst.n/.inst.w instead"));
3781 }
3782 else
3783 as_bad (_("constant expression required"));
3784
3785 return (size != 0);
3786}
3787
3788/* Like s_arm_elf_cons but do not use md_cons_align and
3789 set the mapping state to MAP_ARM/MAP_THUMB. */
3790
3791static void
3792s_arm_elf_inst (int nbytes)
3793{
3794 if (is_it_end_of_statement ())
3795 {
3796 demand_empty_rest_of_line ();
3797 return;
3798 }
3799
3800 /* Calling mapping_state () here will not change ARM/THUMB,
3801 but will ensure not to be in DATA state. */
3802
3803 if (thumb_mode)
3804 mapping_state (MAP_THUMB);
3805 else
3806 {
3807 if (nbytes != 0)
3808 {
3809 as_bad (_("width suffixes are invalid in ARM mode"));
3810 ignore_rest_of_line ();
3811 return;
3812 }
3813
3814 nbytes = 4;
3815
3816 mapping_state (MAP_ARM);
3817 }
3818
3819 do
3820 {
3821 expressionS exp;
3822
3823 expression (& exp);
3824
3825 if (! emit_insn (& exp, nbytes))
3826 {
3827 ignore_rest_of_line ();
3828 return;
3829 }
3830 }
3831 while (*input_line_pointer++ == ',');
3832
3833 /* Put terminator back into stream. */
3834 input_line_pointer --;
3835 demand_empty_rest_of_line ();
3836}
b99bd4ef 3837
c19d1205 3838/* Parse a .rel31 directive. */
b99bd4ef 3839
c19d1205
ZW
3840static void
3841s_arm_rel31 (int ignored ATTRIBUTE_UNUSED)
3842{
3843 expressionS exp;
3844 char *p;
3845 valueT highbit;
b99bd4ef 3846
c19d1205
ZW
3847 highbit = 0;
3848 if (*input_line_pointer == '1')
3849 highbit = 0x80000000;
3850 else if (*input_line_pointer != '0')
3851 as_bad (_("expected 0 or 1"));
b99bd4ef 3852
c19d1205
ZW
3853 input_line_pointer++;
3854 if (*input_line_pointer != ',')
3855 as_bad (_("missing comma"));
3856 input_line_pointer++;
b99bd4ef 3857
c19d1205
ZW
3858#ifdef md_flush_pending_output
3859 md_flush_pending_output ();
3860#endif
b99bd4ef 3861
c19d1205
ZW
3862#ifdef md_cons_align
3863 md_cons_align (4);
3864#endif
b99bd4ef 3865
c19d1205 3866 mapping_state (MAP_DATA);
b99bd4ef 3867
c19d1205 3868 expression (&exp);
b99bd4ef 3869
c19d1205
ZW
3870 p = frag_more (4);
3871 md_number_to_chars (p, highbit, 4);
3872 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 1,
3873 BFD_RELOC_ARM_PREL31);
b99bd4ef 3874
c19d1205 3875 demand_empty_rest_of_line ();
b99bd4ef
NC
3876}
3877
c19d1205 3878/* Directives: AEABI stack-unwind tables. */
b99bd4ef 3879
c19d1205 3880/* Parse an unwind_fnstart directive. Simply records the current location. */
b99bd4ef 3881
c19d1205
ZW
3882static void
3883s_arm_unwind_fnstart (int ignored ATTRIBUTE_UNUSED)
3884{
3885 demand_empty_rest_of_line ();
921e5f0a
PB
3886 if (unwind.proc_start)
3887 {
c921be7d 3888 as_bad (_("duplicate .fnstart directive"));
921e5f0a
PB
3889 return;
3890 }
3891
c19d1205
ZW
3892 /* Mark the start of the function. */
3893 unwind.proc_start = expr_build_dot ();
b99bd4ef 3894
c19d1205
ZW
3895 /* Reset the rest of the unwind info. */
3896 unwind.opcode_count = 0;
3897 unwind.table_entry = NULL;
3898 unwind.personality_routine = NULL;
3899 unwind.personality_index = -1;
3900 unwind.frame_size = 0;
3901 unwind.fp_offset = 0;
fdfde340 3902 unwind.fp_reg = REG_SP;
c19d1205
ZW
3903 unwind.fp_used = 0;
3904 unwind.sp_restored = 0;
3905}
b99bd4ef 3906
b99bd4ef 3907
c19d1205
ZW
3908/* Parse a handlerdata directive. Creates the exception handling table entry
3909 for the function. */
b99bd4ef 3910
c19d1205
ZW
3911static void
3912s_arm_unwind_handlerdata (int ignored ATTRIBUTE_UNUSED)
3913{
3914 demand_empty_rest_of_line ();
921e5f0a 3915 if (!unwind.proc_start)
c921be7d 3916 as_bad (MISSING_FNSTART);
921e5f0a 3917
c19d1205 3918 if (unwind.table_entry)
6decc662 3919 as_bad (_("duplicate .handlerdata directive"));
f02232aa 3920
c19d1205
ZW
3921 create_unwind_entry (1);
3922}
a737bd4d 3923
c19d1205 3924/* Parse an unwind_fnend directive. Generates the index table entry. */
b99bd4ef 3925
c19d1205
ZW
3926static void
3927s_arm_unwind_fnend (int ignored ATTRIBUTE_UNUSED)
3928{
3929 long where;
3930 char *ptr;
3931 valueT val;
940b5ce0 3932 unsigned int marked_pr_dependency;
f02232aa 3933
c19d1205 3934 demand_empty_rest_of_line ();
f02232aa 3935
921e5f0a
PB
3936 if (!unwind.proc_start)
3937 {
c921be7d 3938 as_bad (_(".fnend directive without .fnstart"));
921e5f0a
PB
3939 return;
3940 }
3941
c19d1205
ZW
3942 /* Add eh table entry. */
3943 if (unwind.table_entry == NULL)
3944 val = create_unwind_entry (0);
3945 else
3946 val = 0;
f02232aa 3947
c19d1205
ZW
3948 /* Add index table entry. This is two words. */
3949 start_unwind_section (unwind.saved_seg, 1);
3950 frag_align (2, 0, 0);
3951 record_alignment (now_seg, 2);
b99bd4ef 3952
c19d1205 3953 ptr = frag_more (8);
5011093d 3954 memset (ptr, 0, 8);
c19d1205 3955 where = frag_now_fix () - 8;
f02232aa 3956
c19d1205
ZW
3957 /* Self relative offset of the function start. */
3958 fix_new (frag_now, where, 4, unwind.proc_start, 0, 1,
3959 BFD_RELOC_ARM_PREL31);
f02232aa 3960
c19d1205
ZW
3961 /* Indicate dependency on EHABI-defined personality routines to the
3962 linker, if it hasn't been done already. */
940b5ce0
DJ
3963 marked_pr_dependency
3964 = seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency;
c19d1205
ZW
3965 if (unwind.personality_index >= 0 && unwind.personality_index < 3
3966 && !(marked_pr_dependency & (1 << unwind.personality_index)))
3967 {
5f4273c7
NC
3968 static const char *const name[] =
3969 {
3970 "__aeabi_unwind_cpp_pr0",
3971 "__aeabi_unwind_cpp_pr1",
3972 "__aeabi_unwind_cpp_pr2"
3973 };
c19d1205
ZW
3974 symbolS *pr = symbol_find_or_make (name[unwind.personality_index]);
3975 fix_new (frag_now, where, 0, pr, 0, 1, BFD_RELOC_NONE);
c19d1205 3976 seg_info (now_seg)->tc_segment_info_data.marked_pr_dependency
940b5ce0 3977 |= 1 << unwind.personality_index;
c19d1205 3978 }
f02232aa 3979
c19d1205
ZW
3980 if (val)
3981 /* Inline exception table entry. */
3982 md_number_to_chars (ptr + 4, val, 4);
3983 else
3984 /* Self relative offset of the table entry. */
3985 fix_new (frag_now, where + 4, 4, unwind.table_entry, 0, 1,
3986 BFD_RELOC_ARM_PREL31);
f02232aa 3987
c19d1205
ZW
3988 /* Restore the original section. */
3989 subseg_set (unwind.saved_seg, unwind.saved_subseg);
921e5f0a
PB
3990
3991 unwind.proc_start = NULL;
c19d1205 3992}
f02232aa 3993
f02232aa 3994
c19d1205 3995/* Parse an unwind_cantunwind directive. */
b99bd4ef 3996
c19d1205
ZW
3997static void
3998s_arm_unwind_cantunwind (int ignored ATTRIBUTE_UNUSED)
3999{
4000 demand_empty_rest_of_line ();
921e5f0a 4001 if (!unwind.proc_start)
c921be7d 4002 as_bad (MISSING_FNSTART);
921e5f0a 4003
c19d1205
ZW
4004 if (unwind.personality_routine || unwind.personality_index != -1)
4005 as_bad (_("personality routine specified for cantunwind frame"));
b99bd4ef 4006
c19d1205
ZW
4007 unwind.personality_index = -2;
4008}
b99bd4ef 4009
b99bd4ef 4010
c19d1205 4011/* Parse a personalityindex directive. */
b99bd4ef 4012
c19d1205
ZW
4013static void
4014s_arm_unwind_personalityindex (int ignored ATTRIBUTE_UNUSED)
4015{
4016 expressionS exp;
b99bd4ef 4017
921e5f0a 4018 if (!unwind.proc_start)
c921be7d 4019 as_bad (MISSING_FNSTART);
921e5f0a 4020
c19d1205
ZW
4021 if (unwind.personality_routine || unwind.personality_index != -1)
4022 as_bad (_("duplicate .personalityindex directive"));
b99bd4ef 4023
c19d1205 4024 expression (&exp);
b99bd4ef 4025
c19d1205
ZW
4026 if (exp.X_op != O_constant
4027 || exp.X_add_number < 0 || exp.X_add_number > 15)
b99bd4ef 4028 {
c19d1205
ZW
4029 as_bad (_("bad personality routine number"));
4030 ignore_rest_of_line ();
4031 return;
b99bd4ef
NC
4032 }
4033
c19d1205 4034 unwind.personality_index = exp.X_add_number;
b99bd4ef 4035
c19d1205
ZW
4036 demand_empty_rest_of_line ();
4037}
e16bb312 4038
e16bb312 4039
c19d1205 4040/* Parse a personality directive. */
e16bb312 4041
c19d1205
ZW
4042static void
4043s_arm_unwind_personality (int ignored ATTRIBUTE_UNUSED)
4044{
4045 char *name, *p, c;
a737bd4d 4046
921e5f0a 4047 if (!unwind.proc_start)
c921be7d 4048 as_bad (MISSING_FNSTART);
921e5f0a 4049
c19d1205
ZW
4050 if (unwind.personality_routine || unwind.personality_index != -1)
4051 as_bad (_("duplicate .personality directive"));
a737bd4d 4052
d02603dc 4053 c = get_symbol_name (& name);
c19d1205 4054 p = input_line_pointer;
d02603dc
NC
4055 if (c == '"')
4056 ++ input_line_pointer;
c19d1205
ZW
4057 unwind.personality_routine = symbol_find_or_make (name);
4058 *p = c;
4059 demand_empty_rest_of_line ();
4060}
e16bb312 4061
e16bb312 4062
c19d1205 4063/* Parse a directive saving core registers. */
e16bb312 4064
c19d1205
ZW
4065static void
4066s_arm_unwind_save_core (void)
e16bb312 4067{
c19d1205
ZW
4068 valueT op;
4069 long range;
4070 int n;
e16bb312 4071
4b5a202f 4072 range = parse_reg_list (&input_line_pointer, REGLIST_RN);
c19d1205 4073 if (range == FAIL)
e16bb312 4074 {
c19d1205
ZW
4075 as_bad (_("expected register list"));
4076 ignore_rest_of_line ();
4077 return;
4078 }
e16bb312 4079
c19d1205 4080 demand_empty_rest_of_line ();
e16bb312 4081
c19d1205
ZW
4082 /* Turn .unwind_movsp ip followed by .unwind_save {..., ip, ...}
4083 into .unwind_save {..., sp...}. We aren't bothered about the value of
4084 ip because it is clobbered by calls. */
4085 if (unwind.sp_restored && unwind.fp_reg == 12
4086 && (range & 0x3000) == 0x1000)
4087 {
4088 unwind.opcode_count--;
4089 unwind.sp_restored = 0;
4090 range = (range | 0x2000) & ~0x1000;
4091 unwind.pending_offset = 0;
4092 }
e16bb312 4093
01ae4198
DJ
4094 /* Pop r4-r15. */
4095 if (range & 0xfff0)
c19d1205 4096 {
01ae4198
DJ
4097 /* See if we can use the short opcodes. These pop a block of up to 8
4098 registers starting with r4, plus maybe r14. */
4099 for (n = 0; n < 8; n++)
4100 {
4101 /* Break at the first non-saved register. */
4102 if ((range & (1 << (n + 4))) == 0)
4103 break;
4104 }
4105 /* See if there are any other bits set. */
4106 if (n == 0 || (range & (0xfff0 << n) & 0xbff0) != 0)
4107 {
4108 /* Use the long form. */
4109 op = 0x8000 | ((range >> 4) & 0xfff);
4110 add_unwind_opcode (op, 2);
4111 }
0dd132b6 4112 else
01ae4198
DJ
4113 {
4114 /* Use the short form. */
4115 if (range & 0x4000)
4116 op = 0xa8; /* Pop r14. */
4117 else
4118 op = 0xa0; /* Do not pop r14. */
4119 op |= (n - 1);
4120 add_unwind_opcode (op, 1);
4121 }
c19d1205 4122 }
0dd132b6 4123
c19d1205
ZW
4124 /* Pop r0-r3. */
4125 if (range & 0xf)
4126 {
4127 op = 0xb100 | (range & 0xf);
4128 add_unwind_opcode (op, 2);
0dd132b6
NC
4129 }
4130
c19d1205
ZW
4131 /* Record the number of bytes pushed. */
4132 for (n = 0; n < 16; n++)
4133 {
4134 if (range & (1 << n))
4135 unwind.frame_size += 4;
4136 }
0dd132b6
NC
4137}
4138
c19d1205
ZW
4139
4140/* Parse a directive saving FPA registers. */
b99bd4ef
NC
4141
4142static void
c19d1205 4143s_arm_unwind_save_fpa (int reg)
b99bd4ef 4144{
c19d1205
ZW
4145 expressionS exp;
4146 int num_regs;
4147 valueT op;
b99bd4ef 4148
c19d1205
ZW
4149 /* Get Number of registers to transfer. */
4150 if (skip_past_comma (&input_line_pointer) != FAIL)
4151 expression (&exp);
4152 else
4153 exp.X_op = O_illegal;
b99bd4ef 4154
c19d1205 4155 if (exp.X_op != O_constant)
b99bd4ef 4156 {
c19d1205
ZW
4157 as_bad (_("expected , <constant>"));
4158 ignore_rest_of_line ();
b99bd4ef
NC
4159 return;
4160 }
4161
c19d1205
ZW
4162 num_regs = exp.X_add_number;
4163
4164 if (num_regs < 1 || num_regs > 4)
b99bd4ef 4165 {
c19d1205
ZW
4166 as_bad (_("number of registers must be in the range [1:4]"));
4167 ignore_rest_of_line ();
b99bd4ef
NC
4168 return;
4169 }
4170
c19d1205 4171 demand_empty_rest_of_line ();
b99bd4ef 4172
c19d1205
ZW
4173 if (reg == 4)
4174 {
4175 /* Short form. */
4176 op = 0xb4 | (num_regs - 1);
4177 add_unwind_opcode (op, 1);
4178 }
b99bd4ef
NC
4179 else
4180 {
c19d1205
ZW
4181 /* Long form. */
4182 op = 0xc800 | (reg << 4) | (num_regs - 1);
4183 add_unwind_opcode (op, 2);
b99bd4ef 4184 }
c19d1205 4185 unwind.frame_size += num_regs * 12;
b99bd4ef
NC
4186}
4187
c19d1205 4188
fa073d69
MS
4189/* Parse a directive saving VFP registers for ARMv6 and above. */
4190
4191static void
4192s_arm_unwind_save_vfp_armv6 (void)
4193{
4194 int count;
4195 unsigned int start;
4196 valueT op;
4197 int num_vfpv3_regs = 0;
4198 int num_regs_below_16;
efd6b359 4199 bfd_boolean partial_match;
fa073d69 4200
efd6b359
AV
4201 count = parse_vfp_reg_list (&input_line_pointer, &start, REGLIST_VFP_D,
4202 &partial_match);
fa073d69
MS
4203 if (count == FAIL)
4204 {
4205 as_bad (_("expected register list"));
4206 ignore_rest_of_line ();
4207 return;
4208 }
4209
4210 demand_empty_rest_of_line ();
4211
4212 /* We always generate FSTMD/FLDMD-style unwinding opcodes (rather
4213 than FSTMX/FLDMX-style ones). */
4214
4215 /* Generate opcode for (VFPv3) registers numbered in the range 16 .. 31. */
4216 if (start >= 16)
4217 num_vfpv3_regs = count;
4218 else if (start + count > 16)
4219 num_vfpv3_regs = start + count - 16;
4220
4221 if (num_vfpv3_regs > 0)
4222 {
4223 int start_offset = start > 16 ? start - 16 : 0;
4224 op = 0xc800 | (start_offset << 4) | (num_vfpv3_regs - 1);
4225 add_unwind_opcode (op, 2);
4226 }
4227
4228 /* Generate opcode for registers numbered in the range 0 .. 15. */
4229 num_regs_below_16 = num_vfpv3_regs > 0 ? 16 - (int) start : count;
9c2799c2 4230 gas_assert (num_regs_below_16 + num_vfpv3_regs == count);
fa073d69
MS
4231 if (num_regs_below_16 > 0)
4232 {
4233 op = 0xc900 | (start << 4) | (num_regs_below_16 - 1);
4234 add_unwind_opcode (op, 2);
4235 }
4236
4237 unwind.frame_size += count * 8;
4238}
4239
4240
4241/* Parse a directive saving VFP registers for pre-ARMv6. */
b99bd4ef
NC
4242
4243static void
c19d1205 4244s_arm_unwind_save_vfp (void)
b99bd4ef 4245{
c19d1205 4246 int count;
ca3f61f7 4247 unsigned int reg;
c19d1205 4248 valueT op;
efd6b359 4249 bfd_boolean partial_match;
b99bd4ef 4250
efd6b359
AV
4251 count = parse_vfp_reg_list (&input_line_pointer, &reg, REGLIST_VFP_D,
4252 &partial_match);
c19d1205 4253 if (count == FAIL)
b99bd4ef 4254 {
c19d1205
ZW
4255 as_bad (_("expected register list"));
4256 ignore_rest_of_line ();
b99bd4ef
NC
4257 return;
4258 }
4259
c19d1205 4260 demand_empty_rest_of_line ();
b99bd4ef 4261
c19d1205 4262 if (reg == 8)
b99bd4ef 4263 {
c19d1205
ZW
4264 /* Short form. */
4265 op = 0xb8 | (count - 1);
4266 add_unwind_opcode (op, 1);
b99bd4ef 4267 }
c19d1205 4268 else
b99bd4ef 4269 {
c19d1205
ZW
4270 /* Long form. */
4271 op = 0xb300 | (reg << 4) | (count - 1);
4272 add_unwind_opcode (op, 2);
b99bd4ef 4273 }
c19d1205
ZW
4274 unwind.frame_size += count * 8 + 4;
4275}
b99bd4ef 4276
b99bd4ef 4277
c19d1205
ZW
4278/* Parse a directive saving iWMMXt data registers. */
4279
4280static void
4281s_arm_unwind_save_mmxwr (void)
4282{
4283 int reg;
4284 int hi_reg;
4285 int i;
4286 unsigned mask = 0;
4287 valueT op;
b99bd4ef 4288
c19d1205
ZW
4289 if (*input_line_pointer == '{')
4290 input_line_pointer++;
b99bd4ef 4291
c19d1205 4292 do
b99bd4ef 4293 {
dcbf9037 4294 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
b99bd4ef 4295
c19d1205 4296 if (reg == FAIL)
b99bd4ef 4297 {
9b7132d3 4298 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205 4299 goto error;
b99bd4ef
NC
4300 }
4301
c19d1205
ZW
4302 if (mask >> reg)
4303 as_tsktsk (_("register list not in ascending order"));
4304 mask |= 1 << reg;
b99bd4ef 4305
c19d1205
ZW
4306 if (*input_line_pointer == '-')
4307 {
4308 input_line_pointer++;
dcbf9037 4309 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWR);
c19d1205
ZW
4310 if (hi_reg == FAIL)
4311 {
9b7132d3 4312 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWR]));
c19d1205
ZW
4313 goto error;
4314 }
4315 else if (reg >= hi_reg)
4316 {
4317 as_bad (_("bad register range"));
4318 goto error;
4319 }
4320 for (; reg < hi_reg; reg++)
4321 mask |= 1 << reg;
4322 }
4323 }
4324 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4325
d996d970 4326 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4327
c19d1205 4328 demand_empty_rest_of_line ();
b99bd4ef 4329
708587a4 4330 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4331 the list. */
4332 flush_pending_unwind ();
b99bd4ef 4333
c19d1205 4334 for (i = 0; i < 16; i++)
b99bd4ef 4335 {
c19d1205
ZW
4336 if (mask & (1 << i))
4337 unwind.frame_size += 8;
b99bd4ef
NC
4338 }
4339
c19d1205
ZW
4340 /* Attempt to combine with a previous opcode. We do this because gcc
4341 likes to output separate unwind directives for a single block of
4342 registers. */
4343 if (unwind.opcode_count > 0)
b99bd4ef 4344 {
c19d1205
ZW
4345 i = unwind.opcodes[unwind.opcode_count - 1];
4346 if ((i & 0xf8) == 0xc0)
4347 {
4348 i &= 7;
4349 /* Only merge if the blocks are contiguous. */
4350 if (i < 6)
4351 {
4352 if ((mask & 0xfe00) == (1 << 9))
4353 {
4354 mask |= ((1 << (i + 11)) - 1) & 0xfc00;
4355 unwind.opcode_count--;
4356 }
4357 }
4358 else if (i == 6 && unwind.opcode_count >= 2)
4359 {
4360 i = unwind.opcodes[unwind.opcode_count - 2];
4361 reg = i >> 4;
4362 i &= 0xf;
b99bd4ef 4363
c19d1205
ZW
4364 op = 0xffff << (reg - 1);
4365 if (reg > 0
87a1fd79 4366 && ((mask & op) == (1u << (reg - 1))))
c19d1205
ZW
4367 {
4368 op = (1 << (reg + i + 1)) - 1;
4369 op &= ~((1 << reg) - 1);
4370 mask |= op;
4371 unwind.opcode_count -= 2;
4372 }
4373 }
4374 }
b99bd4ef
NC
4375 }
4376
c19d1205
ZW
4377 hi_reg = 15;
4378 /* We want to generate opcodes in the order the registers have been
4379 saved, ie. descending order. */
4380 for (reg = 15; reg >= -1; reg--)
b99bd4ef 4381 {
c19d1205
ZW
4382 /* Save registers in blocks. */
4383 if (reg < 0
4384 || !(mask & (1 << reg)))
4385 {
4386 /* We found an unsaved reg. Generate opcodes to save the
5f4273c7 4387 preceding block. */
c19d1205
ZW
4388 if (reg != hi_reg)
4389 {
4390 if (reg == 9)
4391 {
4392 /* Short form. */
4393 op = 0xc0 | (hi_reg - 10);
4394 add_unwind_opcode (op, 1);
4395 }
4396 else
4397 {
4398 /* Long form. */
4399 op = 0xc600 | ((reg + 1) << 4) | ((hi_reg - reg) - 1);
4400 add_unwind_opcode (op, 2);
4401 }
4402 }
4403 hi_reg = reg - 1;
4404 }
b99bd4ef
NC
4405 }
4406
c19d1205
ZW
4407 return;
4408error:
4409 ignore_rest_of_line ();
b99bd4ef
NC
4410}
4411
4412static void
c19d1205 4413s_arm_unwind_save_mmxwcg (void)
b99bd4ef 4414{
c19d1205
ZW
4415 int reg;
4416 int hi_reg;
4417 unsigned mask = 0;
4418 valueT op;
b99bd4ef 4419
c19d1205
ZW
4420 if (*input_line_pointer == '{')
4421 input_line_pointer++;
b99bd4ef 4422
477330fc
RM
4423 skip_whitespace (input_line_pointer);
4424
c19d1205 4425 do
b99bd4ef 4426 {
dcbf9037 4427 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
b99bd4ef 4428
c19d1205
ZW
4429 if (reg == FAIL)
4430 {
9b7132d3 4431 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4432 goto error;
4433 }
b99bd4ef 4434
c19d1205
ZW
4435 reg -= 8;
4436 if (mask >> reg)
4437 as_tsktsk (_("register list not in ascending order"));
4438 mask |= 1 << reg;
b99bd4ef 4439
c19d1205
ZW
4440 if (*input_line_pointer == '-')
4441 {
4442 input_line_pointer++;
dcbf9037 4443 hi_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_MMXWCG);
c19d1205
ZW
4444 if (hi_reg == FAIL)
4445 {
9b7132d3 4446 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_MMXWCG]));
c19d1205
ZW
4447 goto error;
4448 }
4449 else if (reg >= hi_reg)
4450 {
4451 as_bad (_("bad register range"));
4452 goto error;
4453 }
4454 for (; reg < hi_reg; reg++)
4455 mask |= 1 << reg;
4456 }
b99bd4ef 4457 }
c19d1205 4458 while (skip_past_comma (&input_line_pointer) != FAIL);
b99bd4ef 4459
d996d970 4460 skip_past_char (&input_line_pointer, '}');
b99bd4ef 4461
c19d1205
ZW
4462 demand_empty_rest_of_line ();
4463
708587a4 4464 /* Generate any deferred opcodes because we're going to be looking at
c19d1205
ZW
4465 the list. */
4466 flush_pending_unwind ();
b99bd4ef 4467
c19d1205 4468 for (reg = 0; reg < 16; reg++)
b99bd4ef 4469 {
c19d1205
ZW
4470 if (mask & (1 << reg))
4471 unwind.frame_size += 4;
b99bd4ef 4472 }
c19d1205
ZW
4473 op = 0xc700 | mask;
4474 add_unwind_opcode (op, 2);
4475 return;
4476error:
4477 ignore_rest_of_line ();
b99bd4ef
NC
4478}
4479
c19d1205 4480
fa073d69
MS
4481/* Parse an unwind_save directive.
4482 If the argument is non-zero, this is a .vsave directive. */
c19d1205 4483
b99bd4ef 4484static void
fa073d69 4485s_arm_unwind_save (int arch_v6)
b99bd4ef 4486{
c19d1205
ZW
4487 char *peek;
4488 struct reg_entry *reg;
4489 bfd_boolean had_brace = FALSE;
b99bd4ef 4490
921e5f0a 4491 if (!unwind.proc_start)
c921be7d 4492 as_bad (MISSING_FNSTART);
921e5f0a 4493
c19d1205
ZW
4494 /* Figure out what sort of save we have. */
4495 peek = input_line_pointer;
b99bd4ef 4496
c19d1205 4497 if (*peek == '{')
b99bd4ef 4498 {
c19d1205
ZW
4499 had_brace = TRUE;
4500 peek++;
b99bd4ef
NC
4501 }
4502
c19d1205 4503 reg = arm_reg_parse_multi (&peek);
b99bd4ef 4504
c19d1205 4505 if (!reg)
b99bd4ef 4506 {
c19d1205
ZW
4507 as_bad (_("register expected"));
4508 ignore_rest_of_line ();
b99bd4ef
NC
4509 return;
4510 }
4511
c19d1205 4512 switch (reg->type)
b99bd4ef 4513 {
c19d1205
ZW
4514 case REG_TYPE_FN:
4515 if (had_brace)
4516 {
4517 as_bad (_("FPA .unwind_save does not take a register list"));
4518 ignore_rest_of_line ();
4519 return;
4520 }
93ac2687 4521 input_line_pointer = peek;
c19d1205 4522 s_arm_unwind_save_fpa (reg->number);
b99bd4ef 4523 return;
c19d1205 4524
1f5afe1c
NC
4525 case REG_TYPE_RN:
4526 s_arm_unwind_save_core ();
4527 return;
4528
fa073d69
MS
4529 case REG_TYPE_VFD:
4530 if (arch_v6)
477330fc 4531 s_arm_unwind_save_vfp_armv6 ();
fa073d69 4532 else
477330fc 4533 s_arm_unwind_save_vfp ();
fa073d69 4534 return;
1f5afe1c
NC
4535
4536 case REG_TYPE_MMXWR:
4537 s_arm_unwind_save_mmxwr ();
4538 return;
4539
4540 case REG_TYPE_MMXWCG:
4541 s_arm_unwind_save_mmxwcg ();
4542 return;
c19d1205
ZW
4543
4544 default:
4545 as_bad (_(".unwind_save does not support this kind of register"));
4546 ignore_rest_of_line ();
b99bd4ef 4547 }
c19d1205 4548}
b99bd4ef 4549
b99bd4ef 4550
c19d1205
ZW
4551/* Parse an unwind_movsp directive. */
4552
4553static void
4554s_arm_unwind_movsp (int ignored ATTRIBUTE_UNUSED)
4555{
4556 int reg;
4557 valueT op;
4fa3602b 4558 int offset;
c19d1205 4559
921e5f0a 4560 if (!unwind.proc_start)
c921be7d 4561 as_bad (MISSING_FNSTART);
921e5f0a 4562
dcbf9037 4563 reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205 4564 if (reg == FAIL)
b99bd4ef 4565 {
9b7132d3 4566 as_bad ("%s", _(reg_expected_msgs[REG_TYPE_RN]));
c19d1205 4567 ignore_rest_of_line ();
b99bd4ef
NC
4568 return;
4569 }
4fa3602b
PB
4570
4571 /* Optional constant. */
4572 if (skip_past_comma (&input_line_pointer) != FAIL)
4573 {
4574 if (immediate_for_directive (&offset) == FAIL)
4575 return;
4576 }
4577 else
4578 offset = 0;
4579
c19d1205 4580 demand_empty_rest_of_line ();
b99bd4ef 4581
c19d1205 4582 if (reg == REG_SP || reg == REG_PC)
b99bd4ef 4583 {
c19d1205 4584 as_bad (_("SP and PC not permitted in .unwind_movsp directive"));
b99bd4ef
NC
4585 return;
4586 }
4587
c19d1205
ZW
4588 if (unwind.fp_reg != REG_SP)
4589 as_bad (_("unexpected .unwind_movsp directive"));
b99bd4ef 4590
c19d1205
ZW
4591 /* Generate opcode to restore the value. */
4592 op = 0x90 | reg;
4593 add_unwind_opcode (op, 1);
4594
4595 /* Record the information for later. */
4596 unwind.fp_reg = reg;
4fa3602b 4597 unwind.fp_offset = unwind.frame_size - offset;
c19d1205 4598 unwind.sp_restored = 1;
b05fe5cf
ZW
4599}
4600
c19d1205
ZW
4601/* Parse an unwind_pad directive. */
4602
b05fe5cf 4603static void
c19d1205 4604s_arm_unwind_pad (int ignored ATTRIBUTE_UNUSED)
b05fe5cf 4605{
c19d1205 4606 int offset;
b05fe5cf 4607
921e5f0a 4608 if (!unwind.proc_start)
c921be7d 4609 as_bad (MISSING_FNSTART);
921e5f0a 4610
c19d1205
ZW
4611 if (immediate_for_directive (&offset) == FAIL)
4612 return;
b99bd4ef 4613
c19d1205
ZW
4614 if (offset & 3)
4615 {
4616 as_bad (_("stack increment must be multiple of 4"));
4617 ignore_rest_of_line ();
4618 return;
4619 }
b99bd4ef 4620
c19d1205
ZW
4621 /* Don't generate any opcodes, just record the details for later. */
4622 unwind.frame_size += offset;
4623 unwind.pending_offset += offset;
4624
4625 demand_empty_rest_of_line ();
4626}
4627
4628/* Parse an unwind_setfp directive. */
4629
4630static void
4631s_arm_unwind_setfp (int ignored ATTRIBUTE_UNUSED)
b99bd4ef 4632{
c19d1205
ZW
4633 int sp_reg;
4634 int fp_reg;
4635 int offset;
4636
921e5f0a 4637 if (!unwind.proc_start)
c921be7d 4638 as_bad (MISSING_FNSTART);
921e5f0a 4639
dcbf9037 4640 fp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
c19d1205
ZW
4641 if (skip_past_comma (&input_line_pointer) == FAIL)
4642 sp_reg = FAIL;
4643 else
dcbf9037 4644 sp_reg = arm_reg_parse (&input_line_pointer, REG_TYPE_RN);
b99bd4ef 4645
c19d1205
ZW
4646 if (fp_reg == FAIL || sp_reg == FAIL)
4647 {
4648 as_bad (_("expected <reg>, <reg>"));
4649 ignore_rest_of_line ();
4650 return;
4651 }
b99bd4ef 4652
c19d1205
ZW
4653 /* Optional constant. */
4654 if (skip_past_comma (&input_line_pointer) != FAIL)
4655 {
4656 if (immediate_for_directive (&offset) == FAIL)
4657 return;
4658 }
4659 else
4660 offset = 0;
a737bd4d 4661
c19d1205 4662 demand_empty_rest_of_line ();
a737bd4d 4663
fdfde340 4664 if (sp_reg != REG_SP && sp_reg != unwind.fp_reg)
a737bd4d 4665 {
c19d1205
ZW
4666 as_bad (_("register must be either sp or set by a previous"
4667 "unwind_movsp directive"));
4668 return;
a737bd4d
NC
4669 }
4670
c19d1205
ZW
4671 /* Don't generate any opcodes, just record the information for later. */
4672 unwind.fp_reg = fp_reg;
4673 unwind.fp_used = 1;
fdfde340 4674 if (sp_reg == REG_SP)
c19d1205
ZW
4675 unwind.fp_offset = unwind.frame_size - offset;
4676 else
4677 unwind.fp_offset -= offset;
a737bd4d
NC
4678}
4679
c19d1205
ZW
4680/* Parse an unwind_raw directive. */
4681
4682static void
4683s_arm_unwind_raw (int ignored ATTRIBUTE_UNUSED)
a737bd4d 4684{
c19d1205 4685 expressionS exp;
708587a4 4686 /* This is an arbitrary limit. */
c19d1205
ZW
4687 unsigned char op[16];
4688 int count;
a737bd4d 4689
921e5f0a 4690 if (!unwind.proc_start)
c921be7d 4691 as_bad (MISSING_FNSTART);
921e5f0a 4692
c19d1205
ZW
4693 expression (&exp);
4694 if (exp.X_op == O_constant
4695 && skip_past_comma (&input_line_pointer) != FAIL)
a737bd4d 4696 {
c19d1205
ZW
4697 unwind.frame_size += exp.X_add_number;
4698 expression (&exp);
4699 }
4700 else
4701 exp.X_op = O_illegal;
a737bd4d 4702
c19d1205
ZW
4703 if (exp.X_op != O_constant)
4704 {
4705 as_bad (_("expected <offset>, <opcode>"));
4706 ignore_rest_of_line ();
4707 return;
4708 }
a737bd4d 4709
c19d1205 4710 count = 0;
a737bd4d 4711
c19d1205
ZW
4712 /* Parse the opcode. */
4713 for (;;)
4714 {
4715 if (count >= 16)
4716 {
4717 as_bad (_("unwind opcode too long"));
4718 ignore_rest_of_line ();
a737bd4d 4719 }
c19d1205 4720 if (exp.X_op != O_constant || exp.X_add_number & ~0xff)
a737bd4d 4721 {
c19d1205
ZW
4722 as_bad (_("invalid unwind opcode"));
4723 ignore_rest_of_line ();
4724 return;
a737bd4d 4725 }
c19d1205 4726 op[count++] = exp.X_add_number;
a737bd4d 4727
c19d1205
ZW
4728 /* Parse the next byte. */
4729 if (skip_past_comma (&input_line_pointer) == FAIL)
4730 break;
a737bd4d 4731
c19d1205
ZW
4732 expression (&exp);
4733 }
b99bd4ef 4734
c19d1205
ZW
4735 /* Add the opcode bytes in reverse order. */
4736 while (count--)
4737 add_unwind_opcode (op[count], 1);
b99bd4ef 4738
c19d1205 4739 demand_empty_rest_of_line ();
b99bd4ef 4740}
ee065d83
PB
4741
4742
4743/* Parse a .eabi_attribute directive. */
4744
4745static void
4746s_arm_eabi_attribute (int ignored ATTRIBUTE_UNUSED)
4747{
0420f52b 4748 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
ee3c0378 4749
3076e594 4750 if (tag >= 0 && tag < NUM_KNOWN_OBJ_ATTRIBUTES)
ee3c0378 4751 attributes_set_explicitly[tag] = 1;
ee065d83
PB
4752}
4753
0855e32b
NS
4754/* Emit a tls fix for the symbol. */
4755
4756static void
4757s_arm_tls_descseq (int ignored ATTRIBUTE_UNUSED)
4758{
4759 char *p;
4760 expressionS exp;
4761#ifdef md_flush_pending_output
4762 md_flush_pending_output ();
4763#endif
4764
4765#ifdef md_cons_align
4766 md_cons_align (4);
4767#endif
4768
4769 /* Since we're just labelling the code, there's no need to define a
4770 mapping symbol. */
4771 expression (&exp);
4772 p = obstack_next_free (&frchain_now->frch_obstack);
4773 fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
4774 thumb_mode ? BFD_RELOC_ARM_THM_TLS_DESCSEQ
4775 : BFD_RELOC_ARM_TLS_DESCSEQ);
4776}
cdf9ccec 4777#endif /* OBJ_ELF */
0855e32b 4778
ee065d83 4779static void s_arm_arch (int);
7a1d4c38 4780static void s_arm_object_arch (int);
ee065d83
PB
4781static void s_arm_cpu (int);
4782static void s_arm_fpu (int);
69133863 4783static void s_arm_arch_extension (int);
b99bd4ef 4784
f0927246
NC
4785#ifdef TE_PE
4786
4787static void
5f4273c7 4788pe_directive_secrel (int dummy ATTRIBUTE_UNUSED)
f0927246
NC
4789{
4790 expressionS exp;
4791
4792 do
4793 {
4794 expression (&exp);
4795 if (exp.X_op == O_symbol)
4796 exp.X_op = O_secrel;
4797
4798 emit_expr (&exp, 4);
4799 }
4800 while (*input_line_pointer++ == ',');
4801
4802 input_line_pointer--;
4803 demand_empty_rest_of_line ();
4804}
4805#endif /* TE_PE */
4806
c19d1205
ZW
4807/* This table describes all the machine specific pseudo-ops the assembler
4808 has to support. The fields are:
4809 pseudo-op name without dot
4810 function to call to execute this pseudo-op
4811 Integer arg to pass to the function. */
b99bd4ef 4812
c19d1205 4813const pseudo_typeS md_pseudo_table[] =
b99bd4ef 4814{
c19d1205
ZW
4815 /* Never called because '.req' does not start a line. */
4816 { "req", s_req, 0 },
dcbf9037
JB
4817 /* Following two are likewise never called. */
4818 { "dn", s_dn, 0 },
4819 { "qn", s_qn, 0 },
c19d1205
ZW
4820 { "unreq", s_unreq, 0 },
4821 { "bss", s_bss, 0 },
db2ed2e0 4822 { "align", s_align_ptwo, 2 },
c19d1205
ZW
4823 { "arm", s_arm, 0 },
4824 { "thumb", s_thumb, 0 },
4825 { "code", s_code, 0 },
4826 { "force_thumb", s_force_thumb, 0 },
4827 { "thumb_func", s_thumb_func, 0 },
4828 { "thumb_set", s_thumb_set, 0 },
4829 { "even", s_even, 0 },
4830 { "ltorg", s_ltorg, 0 },
4831 { "pool", s_ltorg, 0 },
4832 { "syntax", s_syntax, 0 },
8463be01
PB
4833 { "cpu", s_arm_cpu, 0 },
4834 { "arch", s_arm_arch, 0 },
7a1d4c38 4835 { "object_arch", s_arm_object_arch, 0 },
8463be01 4836 { "fpu", s_arm_fpu, 0 },
69133863 4837 { "arch_extension", s_arm_arch_extension, 0 },
c19d1205 4838#ifdef OBJ_ELF
c921be7d
NC
4839 { "word", s_arm_elf_cons, 4 },
4840 { "long", s_arm_elf_cons, 4 },
4841 { "inst.n", s_arm_elf_inst, 2 },
4842 { "inst.w", s_arm_elf_inst, 4 },
4843 { "inst", s_arm_elf_inst, 0 },
4844 { "rel31", s_arm_rel31, 0 },
c19d1205
ZW
4845 { "fnstart", s_arm_unwind_fnstart, 0 },
4846 { "fnend", s_arm_unwind_fnend, 0 },
4847 { "cantunwind", s_arm_unwind_cantunwind, 0 },
4848 { "personality", s_arm_unwind_personality, 0 },
4849 { "personalityindex", s_arm_unwind_personalityindex, 0 },
4850 { "handlerdata", s_arm_unwind_handlerdata, 0 },
4851 { "save", s_arm_unwind_save, 0 },
fa073d69 4852 { "vsave", s_arm_unwind_save, 1 },
c19d1205
ZW
4853 { "movsp", s_arm_unwind_movsp, 0 },
4854 { "pad", s_arm_unwind_pad, 0 },
4855 { "setfp", s_arm_unwind_setfp, 0 },
4856 { "unwind_raw", s_arm_unwind_raw, 0 },
ee065d83 4857 { "eabi_attribute", s_arm_eabi_attribute, 0 },
0855e32b 4858 { "tlsdescseq", s_arm_tls_descseq, 0 },
c19d1205
ZW
4859#else
4860 { "word", cons, 4},
f0927246
NC
4861
4862 /* These are used for dwarf. */
4863 {"2byte", cons, 2},
4864 {"4byte", cons, 4},
4865 {"8byte", cons, 8},
4866 /* These are used for dwarf2. */
68d20676 4867 { "file", dwarf2_directive_file, 0 },
f0927246
NC
4868 { "loc", dwarf2_directive_loc, 0 },
4869 { "loc_mark_labels", dwarf2_directive_loc_mark_labels, 0 },
c19d1205
ZW
4870#endif
4871 { "extend", float_cons, 'x' },
4872 { "ldouble", float_cons, 'x' },
4873 { "packed", float_cons, 'p' },
f0927246
NC
4874#ifdef TE_PE
4875 {"secrel32", pe_directive_secrel, 0},
4876#endif
2e6976a8
DG
4877
4878 /* These are for compatibility with CodeComposer Studio. */
4879 {"ref", s_ccs_ref, 0},
4880 {"def", s_ccs_def, 0},
4881 {"asmfunc", s_ccs_asmfunc, 0},
4882 {"endasmfunc", s_ccs_endasmfunc, 0},
4883
c19d1205
ZW
4884 { 0, 0, 0 }
4885};
4886\f
4887/* Parser functions used exclusively in instruction operands. */
b99bd4ef 4888
c19d1205
ZW
4889/* Generic immediate-value read function for use in insn parsing.
4890 STR points to the beginning of the immediate (the leading #);
4891 VAL receives the value; if the value is outside [MIN, MAX]
4892 issue an error. PREFIX_OPT is true if the immediate prefix is
4893 optional. */
b99bd4ef 4894
c19d1205
ZW
4895static int
4896parse_immediate (char **str, int *val, int min, int max,
4897 bfd_boolean prefix_opt)
4898{
4899 expressionS exp;
0198d5e6 4900
c19d1205
ZW
4901 my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
4902 if (exp.X_op != O_constant)
b99bd4ef 4903 {
c19d1205
ZW
4904 inst.error = _("constant expression required");
4905 return FAIL;
4906 }
b99bd4ef 4907
c19d1205
ZW
4908 if (exp.X_add_number < min || exp.X_add_number > max)
4909 {
4910 inst.error = _("immediate value out of range");
4911 return FAIL;
4912 }
b99bd4ef 4913
c19d1205
ZW
4914 *val = exp.X_add_number;
4915 return SUCCESS;
4916}
b99bd4ef 4917
5287ad62 4918/* Less-generic immediate-value read function with the possibility of loading a
036dc3f7 4919 big (64-bit) immediate, as required by Neon VMOV, VMVN and logic immediate
5287ad62
JB
4920 instructions. Puts the result directly in inst.operands[i]. */
4921
4922static int
8335d6aa
JW
4923parse_big_immediate (char **str, int i, expressionS *in_exp,
4924 bfd_boolean allow_symbol_p)
5287ad62
JB
4925{
4926 expressionS exp;
8335d6aa 4927 expressionS *exp_p = in_exp ? in_exp : &exp;
5287ad62
JB
4928 char *ptr = *str;
4929
8335d6aa 4930 my_get_expression (exp_p, &ptr, GE_OPT_PREFIX_BIG);
5287ad62 4931
8335d6aa 4932 if (exp_p->X_op == O_constant)
036dc3f7 4933 {
8335d6aa 4934 inst.operands[i].imm = exp_p->X_add_number & 0xffffffff;
036dc3f7
PB
4935 /* If we're on a 64-bit host, then a 64-bit number can be returned using
4936 O_constant. We have to be careful not to break compilation for
4937 32-bit X_add_number, though. */
8335d6aa 4938 if ((exp_p->X_add_number & ~(offsetT)(0xffffffffU)) != 0)
036dc3f7 4939 {
8335d6aa
JW
4940 /* X >> 32 is illegal if sizeof (exp_p->X_add_number) == 4. */
4941 inst.operands[i].reg = (((exp_p->X_add_number >> 16) >> 16)
4942 & 0xffffffff);
036dc3f7
PB
4943 inst.operands[i].regisimm = 1;
4944 }
4945 }
8335d6aa
JW
4946 else if (exp_p->X_op == O_big
4947 && LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 32)
5287ad62
JB
4948 {
4949 unsigned parts = 32 / LITTLENUM_NUMBER_OF_BITS, j, idx = 0;
95b75c01 4950
5287ad62 4951 /* Bignums have their least significant bits in
477330fc
RM
4952 generic_bignum[0]. Make sure we put 32 bits in imm and
4953 32 bits in reg, in a (hopefully) portable way. */
9c2799c2 4954 gas_assert (parts != 0);
95b75c01
NC
4955
4956 /* Make sure that the number is not too big.
4957 PR 11972: Bignums can now be sign-extended to the
4958 size of a .octa so check that the out of range bits
4959 are all zero or all one. */
8335d6aa 4960 if (LITTLENUM_NUMBER_OF_BITS * exp_p->X_add_number > 64)
95b75c01
NC
4961 {
4962 LITTLENUM_TYPE m = -1;
4963
4964 if (generic_bignum[parts * 2] != 0
4965 && generic_bignum[parts * 2] != m)
4966 return FAIL;
4967
8335d6aa 4968 for (j = parts * 2 + 1; j < (unsigned) exp_p->X_add_number; j++)
95b75c01
NC
4969 if (generic_bignum[j] != generic_bignum[j-1])
4970 return FAIL;
4971 }
4972
5287ad62
JB
4973 inst.operands[i].imm = 0;
4974 for (j = 0; j < parts; j++, idx++)
477330fc
RM
4975 inst.operands[i].imm |= generic_bignum[idx]
4976 << (LITTLENUM_NUMBER_OF_BITS * j);
5287ad62
JB
4977 inst.operands[i].reg = 0;
4978 for (j = 0; j < parts; j++, idx++)
477330fc
RM
4979 inst.operands[i].reg |= generic_bignum[idx]
4980 << (LITTLENUM_NUMBER_OF_BITS * j);
5287ad62
JB
4981 inst.operands[i].regisimm = 1;
4982 }
8335d6aa 4983 else if (!(exp_p->X_op == O_symbol && allow_symbol_p))
5287ad62 4984 return FAIL;
5f4273c7 4985
5287ad62
JB
4986 *str = ptr;
4987
4988 return SUCCESS;
4989}
4990
c19d1205
ZW
4991/* Returns the pseudo-register number of an FPA immediate constant,
4992 or FAIL if there isn't a valid constant here. */
b99bd4ef 4993
c19d1205
ZW
4994static int
4995parse_fpa_immediate (char ** str)
4996{
4997 LITTLENUM_TYPE words[MAX_LITTLENUMS];
4998 char * save_in;
4999 expressionS exp;
5000 int i;
5001 int j;
b99bd4ef 5002
c19d1205
ZW
5003 /* First try and match exact strings, this is to guarantee
5004 that some formats will work even for cross assembly. */
b99bd4ef 5005
c19d1205
ZW
5006 for (i = 0; fp_const[i]; i++)
5007 {
5008 if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
b99bd4ef 5009 {
c19d1205 5010 char *start = *str;
b99bd4ef 5011
c19d1205
ZW
5012 *str += strlen (fp_const[i]);
5013 if (is_end_of_line[(unsigned char) **str])
5014 return i + 8;
5015 *str = start;
5016 }
5017 }
b99bd4ef 5018
c19d1205
ZW
5019 /* Just because we didn't get a match doesn't mean that the constant
5020 isn't valid, just that it is in a format that we don't
5021 automatically recognize. Try parsing it with the standard
5022 expression routines. */
b99bd4ef 5023
c19d1205 5024 memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
b99bd4ef 5025
c19d1205
ZW
5026 /* Look for a raw floating point number. */
5027 if ((save_in = atof_ieee (*str, 'x', words)) != NULL
5028 && is_end_of_line[(unsigned char) *save_in])
5029 {
5030 for (i = 0; i < NUM_FLOAT_VALS; i++)
5031 {
5032 for (j = 0; j < MAX_LITTLENUMS; j++)
b99bd4ef 5033 {
c19d1205
ZW
5034 if (words[j] != fp_values[i][j])
5035 break;
b99bd4ef
NC
5036 }
5037
c19d1205 5038 if (j == MAX_LITTLENUMS)
b99bd4ef 5039 {
c19d1205
ZW
5040 *str = save_in;
5041 return i + 8;
b99bd4ef
NC
5042 }
5043 }
5044 }
b99bd4ef 5045
c19d1205
ZW
5046 /* Try and parse a more complex expression, this will probably fail
5047 unless the code uses a floating point prefix (eg "0f"). */
5048 save_in = input_line_pointer;
5049 input_line_pointer = *str;
5050 if (expression (&exp) == absolute_section
5051 && exp.X_op == O_big
5052 && exp.X_add_number < 0)
5053 {
5054 /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
5055 Ditto for 15. */
ba592044
AM
5056#define X_PRECISION 5
5057#define E_PRECISION 15L
5058 if (gen_to_words (words, X_PRECISION, E_PRECISION) == 0)
c19d1205
ZW
5059 {
5060 for (i = 0; i < NUM_FLOAT_VALS; i++)
5061 {
5062 for (j = 0; j < MAX_LITTLENUMS; j++)
5063 {
5064 if (words[j] != fp_values[i][j])
5065 break;
5066 }
b99bd4ef 5067
c19d1205
ZW
5068 if (j == MAX_LITTLENUMS)
5069 {
5070 *str = input_line_pointer;
5071 input_line_pointer = save_in;
5072 return i + 8;
5073 }
5074 }
5075 }
b99bd4ef
NC
5076 }
5077
c19d1205
ZW
5078 *str = input_line_pointer;
5079 input_line_pointer = save_in;
5080 inst.error = _("invalid FPA immediate expression");
5081 return FAIL;
b99bd4ef
NC
5082}
5083
136da414
JB
5084/* Returns 1 if a number has "quarter-precision" float format
5085 0baBbbbbbc defgh000 00000000 00000000. */
5086
5087static int
5088is_quarter_float (unsigned imm)
5089{
5090 int bs = (imm & 0x20000000) ? 0x3e000000 : 0x40000000;
5091 return (imm & 0x7ffff) == 0 && ((imm & 0x7e000000) ^ bs) == 0;
5092}
5093
aacf0b33
KT
5094
5095/* Detect the presence of a floating point or integer zero constant,
5096 i.e. #0.0 or #0. */
5097
5098static bfd_boolean
5099parse_ifimm_zero (char **in)
5100{
5101 int error_code;
5102
5103 if (!is_immediate_prefix (**in))
3c6452ae
TP
5104 {
5105 /* In unified syntax, all prefixes are optional. */
5106 if (!unified_syntax)
5107 return FALSE;
5108 }
5109 else
5110 ++*in;
0900a05b
JW
5111
5112 /* Accept #0x0 as a synonym for #0. */
5113 if (strncmp (*in, "0x", 2) == 0)
5114 {
5115 int val;
5116 if (parse_immediate (in, &val, 0, 0, TRUE) == FAIL)
5117 return FALSE;
5118 return TRUE;
5119 }
5120
aacf0b33
KT
5121 error_code = atof_generic (in, ".", EXP_CHARS,
5122 &generic_floating_point_number);
5123
5124 if (!error_code
5125 && generic_floating_point_number.sign == '+'
5126 && (generic_floating_point_number.low
5127 > generic_floating_point_number.leader))
5128 return TRUE;
5129
5130 return FALSE;
5131}
5132
136da414
JB
5133/* Parse an 8-bit "quarter-precision" floating point number of the form:
5134 0baBbbbbbc defgh000 00000000 00000000.
c96612cc
JB
5135 The zero and minus-zero cases need special handling, since they can't be
5136 encoded in the "quarter-precision" float format, but can nonetheless be
5137 loaded as integer constants. */
136da414
JB
5138
5139static unsigned
5140parse_qfloat_immediate (char **ccp, int *immed)
5141{
5142 char *str = *ccp;
c96612cc 5143 char *fpnum;
136da414 5144 LITTLENUM_TYPE words[MAX_LITTLENUMS];
c96612cc 5145 int found_fpchar = 0;
5f4273c7 5146
136da414 5147 skip_past_char (&str, '#');
5f4273c7 5148
c96612cc
JB
5149 /* We must not accidentally parse an integer as a floating-point number. Make
5150 sure that the value we parse is not an integer by checking for special
5151 characters '.' or 'e'.
5152 FIXME: This is a horrible hack, but doing better is tricky because type
5153 information isn't in a very usable state at parse time. */
5154 fpnum = str;
5155 skip_whitespace (fpnum);
5156
5157 if (strncmp (fpnum, "0x", 2) == 0)
5158 return FAIL;
5159 else
5160 {
5161 for (; *fpnum != '\0' && *fpnum != ' ' && *fpnum != '\n'; fpnum++)
477330fc
RM
5162 if (*fpnum == '.' || *fpnum == 'e' || *fpnum == 'E')
5163 {
5164 found_fpchar = 1;
5165 break;
5166 }
c96612cc
JB
5167
5168 if (!found_fpchar)
477330fc 5169 return FAIL;
c96612cc 5170 }
5f4273c7 5171
136da414
JB
5172 if ((str = atof_ieee (str, 's', words)) != NULL)
5173 {
5174 unsigned fpword = 0;
5175 int i;
5f4273c7 5176
136da414
JB
5177 /* Our FP word must be 32 bits (single-precision FP). */
5178 for (i = 0; i < 32 / LITTLENUM_NUMBER_OF_BITS; i++)
477330fc
RM
5179 {
5180 fpword <<= LITTLENUM_NUMBER_OF_BITS;
5181 fpword |= words[i];
5182 }
5f4273c7 5183
c96612cc 5184 if (is_quarter_float (fpword) || (fpword & 0x7fffffff) == 0)
477330fc 5185 *immed = fpword;
136da414 5186 else
477330fc 5187 return FAIL;
136da414
JB
5188
5189 *ccp = str;
5f4273c7 5190
136da414
JB
5191 return SUCCESS;
5192 }
5f4273c7 5193
136da414
JB
5194 return FAIL;
5195}
5196
c19d1205
ZW
5197/* Shift operands. */
5198enum shift_kind
b99bd4ef 5199{
c19d1205
ZW
5200 SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX
5201};
b99bd4ef 5202
c19d1205
ZW
5203struct asm_shift_name
5204{
5205 const char *name;
5206 enum shift_kind kind;
5207};
b99bd4ef 5208
c19d1205
ZW
5209/* Third argument to parse_shift. */
5210enum parse_shift_mode
5211{
5212 NO_SHIFT_RESTRICT, /* Any kind of shift is accepted. */
5213 SHIFT_IMMEDIATE, /* Shift operand must be an immediate. */
5214 SHIFT_LSL_OR_ASR_IMMEDIATE, /* Shift must be LSL or ASR immediate. */
5215 SHIFT_ASR_IMMEDIATE, /* Shift must be ASR immediate. */
5216 SHIFT_LSL_IMMEDIATE, /* Shift must be LSL immediate. */
5217};
b99bd4ef 5218
c19d1205
ZW
5219/* Parse a <shift> specifier on an ARM data processing instruction.
5220 This has three forms:
b99bd4ef 5221
c19d1205
ZW
5222 (LSL|LSR|ASL|ASR|ROR) Rs
5223 (LSL|LSR|ASL|ASR|ROR) #imm
5224 RRX
b99bd4ef 5225
c19d1205
ZW
5226 Note that ASL is assimilated to LSL in the instruction encoding, and
5227 RRX to ROR #0 (which cannot be written as such). */
b99bd4ef 5228
c19d1205
ZW
5229static int
5230parse_shift (char **str, int i, enum parse_shift_mode mode)
b99bd4ef 5231{
c19d1205
ZW
5232 const struct asm_shift_name *shift_name;
5233 enum shift_kind shift;
5234 char *s = *str;
5235 char *p = s;
5236 int reg;
b99bd4ef 5237
c19d1205
ZW
5238 for (p = *str; ISALPHA (*p); p++)
5239 ;
b99bd4ef 5240
c19d1205 5241 if (p == *str)
b99bd4ef 5242 {
c19d1205
ZW
5243 inst.error = _("shift expression expected");
5244 return FAIL;
b99bd4ef
NC
5245 }
5246
21d799b5 5247 shift_name = (const struct asm_shift_name *) hash_find_n (arm_shift_hsh, *str,
477330fc 5248 p - *str);
c19d1205
ZW
5249
5250 if (shift_name == NULL)
b99bd4ef 5251 {
c19d1205
ZW
5252 inst.error = _("shift expression expected");
5253 return FAIL;
b99bd4ef
NC
5254 }
5255
c19d1205 5256 shift = shift_name->kind;
b99bd4ef 5257
c19d1205
ZW
5258 switch (mode)
5259 {
5260 case NO_SHIFT_RESTRICT:
5261 case SHIFT_IMMEDIATE: break;
b99bd4ef 5262
c19d1205
ZW
5263 case SHIFT_LSL_OR_ASR_IMMEDIATE:
5264 if (shift != SHIFT_LSL && shift != SHIFT_ASR)
5265 {
5266 inst.error = _("'LSL' or 'ASR' required");
5267 return FAIL;
5268 }
5269 break;
b99bd4ef 5270
c19d1205
ZW
5271 case SHIFT_LSL_IMMEDIATE:
5272 if (shift != SHIFT_LSL)
5273 {
5274 inst.error = _("'LSL' required");
5275 return FAIL;
5276 }
5277 break;
b99bd4ef 5278
c19d1205
ZW
5279 case SHIFT_ASR_IMMEDIATE:
5280 if (shift != SHIFT_ASR)
5281 {
5282 inst.error = _("'ASR' required");
5283 return FAIL;
5284 }
5285 break;
b99bd4ef 5286
c19d1205
ZW
5287 default: abort ();
5288 }
b99bd4ef 5289
c19d1205
ZW
5290 if (shift != SHIFT_RRX)
5291 {
5292 /* Whitespace can appear here if the next thing is a bare digit. */
5293 skip_whitespace (p);
b99bd4ef 5294
c19d1205 5295 if (mode == NO_SHIFT_RESTRICT
dcbf9037 5296 && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5297 {
5298 inst.operands[i].imm = reg;
5299 inst.operands[i].immisreg = 1;
5300 }
e2b0ab59 5301 else if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
c19d1205
ZW
5302 return FAIL;
5303 }
5304 inst.operands[i].shift_kind = shift;
5305 inst.operands[i].shifted = 1;
5306 *str = p;
5307 return SUCCESS;
b99bd4ef
NC
5308}
5309
c19d1205 5310/* Parse a <shifter_operand> for an ARM data processing instruction:
b99bd4ef 5311
c19d1205
ZW
5312 #<immediate>
5313 #<immediate>, <rotate>
5314 <Rm>
5315 <Rm>, <shift>
b99bd4ef 5316
c19d1205
ZW
5317 where <shift> is defined by parse_shift above, and <rotate> is a
5318 multiple of 2 between 0 and 30. Validation of immediate operands
55cf6793 5319 is deferred to md_apply_fix. */
b99bd4ef 5320
c19d1205
ZW
5321static int
5322parse_shifter_operand (char **str, int i)
5323{
5324 int value;
91d6fa6a 5325 expressionS exp;
b99bd4ef 5326
dcbf9037 5327 if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
c19d1205
ZW
5328 {
5329 inst.operands[i].reg = value;
5330 inst.operands[i].isreg = 1;
b99bd4ef 5331
c19d1205 5332 /* parse_shift will override this if appropriate */
e2b0ab59
AV
5333 inst.relocs[0].exp.X_op = O_constant;
5334 inst.relocs[0].exp.X_add_number = 0;
b99bd4ef 5335
c19d1205
ZW
5336 if (skip_past_comma (str) == FAIL)
5337 return SUCCESS;
b99bd4ef 5338
c19d1205
ZW
5339 /* Shift operation on register. */
5340 return parse_shift (str, i, NO_SHIFT_RESTRICT);
b99bd4ef
NC
5341 }
5342
e2b0ab59 5343 if (my_get_expression (&inst.relocs[0].exp, str, GE_IMM_PREFIX))
c19d1205 5344 return FAIL;
b99bd4ef 5345
c19d1205 5346 if (skip_past_comma (str) == SUCCESS)
b99bd4ef 5347 {
c19d1205 5348 /* #x, y -- ie explicit rotation by Y. */
91d6fa6a 5349 if (my_get_expression (&exp, str, GE_NO_PREFIX))
c19d1205 5350 return FAIL;
b99bd4ef 5351
e2b0ab59 5352 if (exp.X_op != O_constant || inst.relocs[0].exp.X_op != O_constant)
c19d1205
ZW
5353 {
5354 inst.error = _("constant expression expected");
5355 return FAIL;
5356 }
b99bd4ef 5357
91d6fa6a 5358 value = exp.X_add_number;
c19d1205
ZW
5359 if (value < 0 || value > 30 || value % 2 != 0)
5360 {
5361 inst.error = _("invalid rotation");
5362 return FAIL;
5363 }
e2b0ab59
AV
5364 if (inst.relocs[0].exp.X_add_number < 0
5365 || inst.relocs[0].exp.X_add_number > 255)
c19d1205
ZW
5366 {
5367 inst.error = _("invalid constant");
5368 return FAIL;
5369 }
09d92015 5370
a415b1cd 5371 /* Encode as specified. */
e2b0ab59 5372 inst.operands[i].imm = inst.relocs[0].exp.X_add_number | value << 7;
a415b1cd 5373 return SUCCESS;
09d92015
MM
5374 }
5375
e2b0ab59
AV
5376 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
5377 inst.relocs[0].pc_rel = 0;
c19d1205 5378 return SUCCESS;
09d92015
MM
5379}
5380
4962c51a
MS
5381/* Group relocation information. Each entry in the table contains the
5382 textual name of the relocation as may appear in assembler source
5383 and must end with a colon.
5384 Along with this textual name are the relocation codes to be used if
5385 the corresponding instruction is an ALU instruction (ADD or SUB only),
5386 an LDR, an LDRS, or an LDC. */
5387
5388struct group_reloc_table_entry
5389{
5390 const char *name;
5391 int alu_code;
5392 int ldr_code;
5393 int ldrs_code;
5394 int ldc_code;
5395};
5396
5397typedef enum
5398{
5399 /* Varieties of non-ALU group relocation. */
5400
5401 GROUP_LDR,
5402 GROUP_LDRS,
5403 GROUP_LDC
5404} group_reloc_type;
5405
5406static struct group_reloc_table_entry group_reloc_table[] =
5407 { /* Program counter relative: */
5408 { "pc_g0_nc",
5409 BFD_RELOC_ARM_ALU_PC_G0_NC, /* ALU */
5410 0, /* LDR */
5411 0, /* LDRS */
5412 0 }, /* LDC */
5413 { "pc_g0",
5414 BFD_RELOC_ARM_ALU_PC_G0, /* ALU */
5415 BFD_RELOC_ARM_LDR_PC_G0, /* LDR */
5416 BFD_RELOC_ARM_LDRS_PC_G0, /* LDRS */
5417 BFD_RELOC_ARM_LDC_PC_G0 }, /* LDC */
5418 { "pc_g1_nc",
5419 BFD_RELOC_ARM_ALU_PC_G1_NC, /* ALU */
5420 0, /* LDR */
5421 0, /* LDRS */
5422 0 }, /* LDC */
5423 { "pc_g1",
5424 BFD_RELOC_ARM_ALU_PC_G1, /* ALU */
5425 BFD_RELOC_ARM_LDR_PC_G1, /* LDR */
5426 BFD_RELOC_ARM_LDRS_PC_G1, /* LDRS */
5427 BFD_RELOC_ARM_LDC_PC_G1 }, /* LDC */
5428 { "pc_g2",
5429 BFD_RELOC_ARM_ALU_PC_G2, /* ALU */
5430 BFD_RELOC_ARM_LDR_PC_G2, /* LDR */
5431 BFD_RELOC_ARM_LDRS_PC_G2, /* LDRS */
5432 BFD_RELOC_ARM_LDC_PC_G2 }, /* LDC */
5433 /* Section base relative */
5434 { "sb_g0_nc",
5435 BFD_RELOC_ARM_ALU_SB_G0_NC, /* ALU */
5436 0, /* LDR */
5437 0, /* LDRS */
5438 0 }, /* LDC */
5439 { "sb_g0",
5440 BFD_RELOC_ARM_ALU_SB_G0, /* ALU */
5441 BFD_RELOC_ARM_LDR_SB_G0, /* LDR */
5442 BFD_RELOC_ARM_LDRS_SB_G0, /* LDRS */
5443 BFD_RELOC_ARM_LDC_SB_G0 }, /* LDC */
5444 { "sb_g1_nc",
5445 BFD_RELOC_ARM_ALU_SB_G1_NC, /* ALU */
5446 0, /* LDR */
5447 0, /* LDRS */
5448 0 }, /* LDC */
5449 { "sb_g1",
5450 BFD_RELOC_ARM_ALU_SB_G1, /* ALU */
5451 BFD_RELOC_ARM_LDR_SB_G1, /* LDR */
5452 BFD_RELOC_ARM_LDRS_SB_G1, /* LDRS */
5453 BFD_RELOC_ARM_LDC_SB_G1 }, /* LDC */
5454 { "sb_g2",
5455 BFD_RELOC_ARM_ALU_SB_G2, /* ALU */
5456 BFD_RELOC_ARM_LDR_SB_G2, /* LDR */
5457 BFD_RELOC_ARM_LDRS_SB_G2, /* LDRS */
72d98d16
MG
5458 BFD_RELOC_ARM_LDC_SB_G2 }, /* LDC */
5459 /* Absolute thumb alu relocations. */
5460 { "lower0_7",
5461 BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU. */
5462 0, /* LDR. */
5463 0, /* LDRS. */
5464 0 }, /* LDC. */
5465 { "lower8_15",
5466 BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU. */
5467 0, /* LDR. */
5468 0, /* LDRS. */
5469 0 }, /* LDC. */
5470 { "upper0_7",
5471 BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU. */
5472 0, /* LDR. */
5473 0, /* LDRS. */
5474 0 }, /* LDC. */
5475 { "upper8_15",
5476 BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU. */
5477 0, /* LDR. */
5478 0, /* LDRS. */
5479 0 } }; /* LDC. */
4962c51a
MS
5480
5481/* Given the address of a pointer pointing to the textual name of a group
5482 relocation as may appear in assembler source, attempt to find its details
5483 in group_reloc_table. The pointer will be updated to the character after
5484 the trailing colon. On failure, FAIL will be returned; SUCCESS
5485 otherwise. On success, *entry will be updated to point at the relevant
5486 group_reloc_table entry. */
5487
5488static int
5489find_group_reloc_table_entry (char **str, struct group_reloc_table_entry **out)
5490{
5491 unsigned int i;
5492 for (i = 0; i < ARRAY_SIZE (group_reloc_table); i++)
5493 {
5494 int length = strlen (group_reloc_table[i].name);
5495
5f4273c7
NC
5496 if (strncasecmp (group_reloc_table[i].name, *str, length) == 0
5497 && (*str)[length] == ':')
477330fc
RM
5498 {
5499 *out = &group_reloc_table[i];
5500 *str += (length + 1);
5501 return SUCCESS;
5502 }
4962c51a
MS
5503 }
5504
5505 return FAIL;
5506}
5507
5508/* Parse a <shifter_operand> for an ARM data processing instruction
5509 (as for parse_shifter_operand) where group relocations are allowed:
5510
5511 #<immediate>
5512 #<immediate>, <rotate>
5513 #:<group_reloc>:<expression>
5514 <Rm>
5515 <Rm>, <shift>
5516
5517 where <group_reloc> is one of the strings defined in group_reloc_table.
5518 The hashes are optional.
5519
5520 Everything else is as for parse_shifter_operand. */
5521
5522static parse_operand_result
5523parse_shifter_operand_group_reloc (char **str, int i)
5524{
5525 /* Determine if we have the sequence of characters #: or just :
5526 coming next. If we do, then we check for a group relocation.
5527 If we don't, punt the whole lot to parse_shifter_operand. */
5528
5529 if (((*str)[0] == '#' && (*str)[1] == ':')
5530 || (*str)[0] == ':')
5531 {
5532 struct group_reloc_table_entry *entry;
5533
5534 if ((*str)[0] == '#')
477330fc 5535 (*str) += 2;
4962c51a 5536 else
477330fc 5537 (*str)++;
4962c51a
MS
5538
5539 /* Try to parse a group relocation. Anything else is an error. */
5540 if (find_group_reloc_table_entry (str, &entry) == FAIL)
477330fc
RM
5541 {
5542 inst.error = _("unknown group relocation");
5543 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5544 }
4962c51a
MS
5545
5546 /* We now have the group relocation table entry corresponding to
477330fc 5547 the name in the assembler source. Next, we parse the expression. */
e2b0ab59 5548 if (my_get_expression (&inst.relocs[0].exp, str, GE_NO_PREFIX))
477330fc 5549 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
4962c51a
MS
5550
5551 /* Record the relocation type (always the ALU variant here). */
e2b0ab59
AV
5552 inst.relocs[0].type = (bfd_reloc_code_real_type) entry->alu_code;
5553 gas_assert (inst.relocs[0].type != 0);
4962c51a
MS
5554
5555 return PARSE_OPERAND_SUCCESS;
5556 }
5557 else
5558 return parse_shifter_operand (str, i) == SUCCESS
477330fc 5559 ? PARSE_OPERAND_SUCCESS : PARSE_OPERAND_FAIL;
4962c51a
MS
5560
5561 /* Never reached. */
5562}
5563
8e560766
MGD
5564/* Parse a Neon alignment expression. Information is written to
5565 inst.operands[i]. We assume the initial ':' has been skipped.
fa94de6b 5566
8e560766
MGD
5567 align .imm = align << 8, .immisalign=1, .preind=0 */
5568static parse_operand_result
5569parse_neon_alignment (char **str, int i)
5570{
5571 char *p = *str;
5572 expressionS exp;
5573
5574 my_get_expression (&exp, &p, GE_NO_PREFIX);
5575
5576 if (exp.X_op != O_constant)
5577 {
5578 inst.error = _("alignment must be constant");
5579 return PARSE_OPERAND_FAIL;
5580 }
5581
5582 inst.operands[i].imm = exp.X_add_number << 8;
5583 inst.operands[i].immisalign = 1;
5584 /* Alignments are not pre-indexes. */
5585 inst.operands[i].preind = 0;
5586
5587 *str = p;
5588 return PARSE_OPERAND_SUCCESS;
5589}
5590
c19d1205 5591/* Parse all forms of an ARM address expression. Information is written
e2b0ab59 5592 to inst.operands[i] and/or inst.relocs[0].
09d92015 5593
c19d1205 5594 Preindexed addressing (.preind=1):
09d92015 5595
e2b0ab59 5596 [Rn, #offset] .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5597 [Rn, +/-Rm] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5598 [Rn, +/-Rm, shift] .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5599 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5600
c19d1205 5601 These three may have a trailing ! which causes .writeback to be set also.
09d92015 5602
c19d1205 5603 Postindexed addressing (.postind=1, .writeback=1):
09d92015 5604
e2b0ab59 5605 [Rn], #offset .reg=Rn .relocs[0].exp=offset
c19d1205
ZW
5606 [Rn], +/-Rm .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
5607 [Rn], +/-Rm, shift .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
e2b0ab59 5608 .shift_kind=shift .relocs[0].exp=shift_imm
09d92015 5609
c19d1205 5610 Unindexed addressing (.preind=0, .postind=0):
09d92015 5611
c19d1205 5612 [Rn], {option} .reg=Rn .imm=option .immisreg=0
09d92015 5613
c19d1205 5614 Other:
09d92015 5615
c19d1205 5616 [Rn]{!} shorthand for [Rn,#0]{!}
e2b0ab59
AV
5617 =immediate .isreg=0 .relocs[0].exp=immediate
5618 label .reg=PC .relocs[0].pc_rel=1 .relocs[0].exp=label
09d92015 5619
c19d1205 5620 It is the caller's responsibility to check for addressing modes not
e2b0ab59 5621 supported by the instruction, and to set inst.relocs[0].type. */
c19d1205 5622
4962c51a
MS
5623static parse_operand_result
5624parse_address_main (char **str, int i, int group_relocations,
477330fc 5625 group_reloc_type group_type)
09d92015 5626{
c19d1205
ZW
5627 char *p = *str;
5628 int reg;
09d92015 5629
c19d1205 5630 if (skip_past_char (&p, '[') == FAIL)
09d92015 5631 {
c19d1205
ZW
5632 if (skip_past_char (&p, '=') == FAIL)
5633 {
974da60d 5634 /* Bare address - translate to PC-relative offset. */
e2b0ab59 5635 inst.relocs[0].pc_rel = 1;
c19d1205
ZW
5636 inst.operands[i].reg = REG_PC;
5637 inst.operands[i].isreg = 1;
5638 inst.operands[i].preind = 1;
09d92015 5639
e2b0ab59 5640 if (my_get_expression (&inst.relocs[0].exp, &p, GE_OPT_PREFIX_BIG))
8335d6aa
JW
5641 return PARSE_OPERAND_FAIL;
5642 }
e2b0ab59 5643 else if (parse_big_immediate (&p, i, &inst.relocs[0].exp,
8335d6aa 5644 /*allow_symbol_p=*/TRUE))
4962c51a 5645 return PARSE_OPERAND_FAIL;
09d92015 5646
c19d1205 5647 *str = p;
4962c51a 5648 return PARSE_OPERAND_SUCCESS;
09d92015
MM
5649 }
5650
8ab8155f
NC
5651 /* PR gas/14887: Allow for whitespace after the opening bracket. */
5652 skip_whitespace (p);
5653
dcbf9037 5654 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
09d92015 5655 {
c19d1205 5656 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
4962c51a 5657 return PARSE_OPERAND_FAIL;
09d92015 5658 }
c19d1205
ZW
5659 inst.operands[i].reg = reg;
5660 inst.operands[i].isreg = 1;
09d92015 5661
c19d1205 5662 if (skip_past_comma (&p) == SUCCESS)
09d92015 5663 {
c19d1205 5664 inst.operands[i].preind = 1;
09d92015 5665
c19d1205
ZW
5666 if (*p == '+') p++;
5667 else if (*p == '-') p++, inst.operands[i].negative = 1;
5668
dcbf9037 5669 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
09d92015 5670 {
c19d1205
ZW
5671 inst.operands[i].imm = reg;
5672 inst.operands[i].immisreg = 1;
5673
5674 if (skip_past_comma (&p) == SUCCESS)
5675 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 5676 return PARSE_OPERAND_FAIL;
c19d1205 5677 }
5287ad62 5678 else if (skip_past_char (&p, ':') == SUCCESS)
8e560766
MGD
5679 {
5680 /* FIXME: '@' should be used here, but it's filtered out by generic
5681 code before we get to see it here. This may be subject to
5682 change. */
5683 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 5684
8e560766
MGD
5685 if (result != PARSE_OPERAND_SUCCESS)
5686 return result;
5687 }
c19d1205
ZW
5688 else
5689 {
5690 if (inst.operands[i].negative)
5691 {
5692 inst.operands[i].negative = 0;
5693 p--;
5694 }
4962c51a 5695
5f4273c7
NC
5696 if (group_relocations
5697 && ((*p == '#' && *(p + 1) == ':') || *p == ':'))
4962c51a
MS
5698 {
5699 struct group_reloc_table_entry *entry;
5700
477330fc
RM
5701 /* Skip over the #: or : sequence. */
5702 if (*p == '#')
5703 p += 2;
5704 else
5705 p++;
4962c51a
MS
5706
5707 /* Try to parse a group relocation. Anything else is an
477330fc 5708 error. */
4962c51a
MS
5709 if (find_group_reloc_table_entry (&p, &entry) == FAIL)
5710 {
5711 inst.error = _("unknown group relocation");
5712 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5713 }
5714
5715 /* We now have the group relocation table entry corresponding to
5716 the name in the assembler source. Next, we parse the
477330fc 5717 expression. */
e2b0ab59 5718 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
4962c51a
MS
5719 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5720
5721 /* Record the relocation type. */
477330fc
RM
5722 switch (group_type)
5723 {
5724 case GROUP_LDR:
e2b0ab59
AV
5725 inst.relocs[0].type
5726 = (bfd_reloc_code_real_type) entry->ldr_code;
477330fc 5727 break;
4962c51a 5728
477330fc 5729 case GROUP_LDRS:
e2b0ab59
AV
5730 inst.relocs[0].type
5731 = (bfd_reloc_code_real_type) entry->ldrs_code;
477330fc 5732 break;
4962c51a 5733
477330fc 5734 case GROUP_LDC:
e2b0ab59
AV
5735 inst.relocs[0].type
5736 = (bfd_reloc_code_real_type) entry->ldc_code;
477330fc 5737 break;
4962c51a 5738
477330fc
RM
5739 default:
5740 gas_assert (0);
5741 }
4962c51a 5742
e2b0ab59 5743 if (inst.relocs[0].type == 0)
4962c51a
MS
5744 {
5745 inst.error = _("this group relocation is not allowed on this instruction");
5746 return PARSE_OPERAND_FAIL_NO_BACKTRACK;
5747 }
477330fc
RM
5748 }
5749 else
26d97720
NS
5750 {
5751 char *q = p;
0198d5e6 5752
e2b0ab59 5753 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
26d97720
NS
5754 return PARSE_OPERAND_FAIL;
5755 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
5756 if (inst.relocs[0].exp.X_op == O_constant
5757 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
5758 {
5759 skip_whitespace (q);
5760 if (*q == '#')
5761 {
5762 q++;
5763 skip_whitespace (q);
5764 }
5765 if (*q == '-')
5766 inst.operands[i].negative = 1;
5767 }
5768 }
09d92015
MM
5769 }
5770 }
8e560766
MGD
5771 else if (skip_past_char (&p, ':') == SUCCESS)
5772 {
5773 /* FIXME: '@' should be used here, but it's filtered out by generic code
5774 before we get to see it here. This may be subject to change. */
5775 parse_operand_result result = parse_neon_alignment (&p, i);
fa94de6b 5776
8e560766
MGD
5777 if (result != PARSE_OPERAND_SUCCESS)
5778 return result;
5779 }
09d92015 5780
c19d1205 5781 if (skip_past_char (&p, ']') == FAIL)
09d92015 5782 {
c19d1205 5783 inst.error = _("']' expected");
4962c51a 5784 return PARSE_OPERAND_FAIL;
09d92015
MM
5785 }
5786
c19d1205
ZW
5787 if (skip_past_char (&p, '!') == SUCCESS)
5788 inst.operands[i].writeback = 1;
09d92015 5789
c19d1205 5790 else if (skip_past_comma (&p) == SUCCESS)
09d92015 5791 {
c19d1205
ZW
5792 if (skip_past_char (&p, '{') == SUCCESS)
5793 {
5794 /* [Rn], {expr} - unindexed, with option */
5795 if (parse_immediate (&p, &inst.operands[i].imm,
ca3f61f7 5796 0, 255, TRUE) == FAIL)
4962c51a 5797 return PARSE_OPERAND_FAIL;
09d92015 5798
c19d1205
ZW
5799 if (skip_past_char (&p, '}') == FAIL)
5800 {
5801 inst.error = _("'}' expected at end of 'option' field");
4962c51a 5802 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5803 }
5804 if (inst.operands[i].preind)
5805 {
5806 inst.error = _("cannot combine index with option");
4962c51a 5807 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5808 }
5809 *str = p;
4962c51a 5810 return PARSE_OPERAND_SUCCESS;
09d92015 5811 }
c19d1205
ZW
5812 else
5813 {
5814 inst.operands[i].postind = 1;
5815 inst.operands[i].writeback = 1;
09d92015 5816
c19d1205
ZW
5817 if (inst.operands[i].preind)
5818 {
5819 inst.error = _("cannot combine pre- and post-indexing");
4962c51a 5820 return PARSE_OPERAND_FAIL;
c19d1205 5821 }
09d92015 5822
c19d1205
ZW
5823 if (*p == '+') p++;
5824 else if (*p == '-') p++, inst.operands[i].negative = 1;
a737bd4d 5825
dcbf9037 5826 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
c19d1205 5827 {
477330fc
RM
5828 /* We might be using the immediate for alignment already. If we
5829 are, OR the register number into the low-order bits. */
5830 if (inst.operands[i].immisalign)
5831 inst.operands[i].imm |= reg;
5832 else
5833 inst.operands[i].imm = reg;
c19d1205 5834 inst.operands[i].immisreg = 1;
a737bd4d 5835
c19d1205
ZW
5836 if (skip_past_comma (&p) == SUCCESS)
5837 if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
4962c51a 5838 return PARSE_OPERAND_FAIL;
c19d1205
ZW
5839 }
5840 else
5841 {
26d97720 5842 char *q = p;
0198d5e6 5843
c19d1205
ZW
5844 if (inst.operands[i].negative)
5845 {
5846 inst.operands[i].negative = 0;
5847 p--;
5848 }
e2b0ab59 5849 if (my_get_expression (&inst.relocs[0].exp, &p, GE_IMM_PREFIX))
4962c51a 5850 return PARSE_OPERAND_FAIL;
26d97720 5851 /* If the offset is 0, find out if it's a +0 or -0. */
e2b0ab59
AV
5852 if (inst.relocs[0].exp.X_op == O_constant
5853 && inst.relocs[0].exp.X_add_number == 0)
26d97720
NS
5854 {
5855 skip_whitespace (q);
5856 if (*q == '#')
5857 {
5858 q++;
5859 skip_whitespace (q);
5860 }
5861 if (*q == '-')
5862 inst.operands[i].negative = 1;
5863 }
c19d1205
ZW
5864 }
5865 }
a737bd4d
NC
5866 }
5867
c19d1205
ZW
5868 /* If at this point neither .preind nor .postind is set, we have a
5869 bare [Rn]{!}, which is shorthand for [Rn,#0]{!}. */
5870 if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
5871 {
5872 inst.operands[i].preind = 1;
e2b0ab59
AV
5873 inst.relocs[0].exp.X_op = O_constant;
5874 inst.relocs[0].exp.X_add_number = 0;
c19d1205
ZW
5875 }
5876 *str = p;
4962c51a
MS
5877 return PARSE_OPERAND_SUCCESS;
5878}
5879
5880static int
5881parse_address (char **str, int i)
5882{
21d799b5 5883 return parse_address_main (str, i, 0, GROUP_LDR) == PARSE_OPERAND_SUCCESS
477330fc 5884 ? SUCCESS : FAIL;
4962c51a
MS
5885}
5886
5887static parse_operand_result
5888parse_address_group_reloc (char **str, int i, group_reloc_type type)
5889{
5890 return parse_address_main (str, i, 1, type);
a737bd4d
NC
5891}
5892
b6895b4f
PB
5893/* Parse an operand for a MOVW or MOVT instruction. */
5894static int
5895parse_half (char **str)
5896{
5897 char * p;
5f4273c7 5898
b6895b4f
PB
5899 p = *str;
5900 skip_past_char (&p, '#');
5f4273c7 5901 if (strncasecmp (p, ":lower16:", 9) == 0)
e2b0ab59 5902 inst.relocs[0].type = BFD_RELOC_ARM_MOVW;
b6895b4f 5903 else if (strncasecmp (p, ":upper16:", 9) == 0)
e2b0ab59 5904 inst.relocs[0].type = BFD_RELOC_ARM_MOVT;
b6895b4f 5905
e2b0ab59 5906 if (inst.relocs[0].type != BFD_RELOC_UNUSED)
b6895b4f
PB
5907 {
5908 p += 9;
5f4273c7 5909 skip_whitespace (p);
b6895b4f
PB
5910 }
5911
e2b0ab59 5912 if (my_get_expression (&inst.relocs[0].exp, &p, GE_NO_PREFIX))
b6895b4f
PB
5913 return FAIL;
5914
e2b0ab59 5915 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 5916 {
e2b0ab59 5917 if (inst.relocs[0].exp.X_op != O_constant)
b6895b4f
PB
5918 {
5919 inst.error = _("constant expression expected");
5920 return FAIL;
5921 }
e2b0ab59
AV
5922 if (inst.relocs[0].exp.X_add_number < 0
5923 || inst.relocs[0].exp.X_add_number > 0xffff)
b6895b4f
PB
5924 {
5925 inst.error = _("immediate value out of range");
5926 return FAIL;
5927 }
5928 }
5929 *str = p;
5930 return SUCCESS;
5931}
5932
c19d1205 5933/* Miscellaneous. */
a737bd4d 5934
c19d1205
ZW
5935/* Parse a PSR flag operand. The value returned is FAIL on syntax error,
5936 or a bitmask suitable to be or-ed into the ARM msr instruction. */
5937static int
d2cd1205 5938parse_psr (char **str, bfd_boolean lhs)
09d92015 5939{
c19d1205
ZW
5940 char *p;
5941 unsigned long psr_field;
62b3e311
PB
5942 const struct asm_psr *psr;
5943 char *start;
d2cd1205 5944 bfd_boolean is_apsr = FALSE;
ac7f631b 5945 bfd_boolean m_profile = ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m);
09d92015 5946
a4482bb6
NC
5947 /* PR gas/12698: If the user has specified -march=all then m_profile will
5948 be TRUE, but we want to ignore it in this case as we are building for any
5949 CPU type, including non-m variants. */
823d2571 5950 if (ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any))
a4482bb6
NC
5951 m_profile = FALSE;
5952
c19d1205
ZW
5953 /* CPSR's and SPSR's can now be lowercase. This is just a convenience
5954 feature for ease of use and backwards compatibility. */
5955 p = *str;
62b3e311 5956 if (strncasecmp (p, "SPSR", 4) == 0)
d2cd1205
JB
5957 {
5958 if (m_profile)
5959 goto unsupported_psr;
fa94de6b 5960
d2cd1205
JB
5961 psr_field = SPSR_BIT;
5962 }
5963 else if (strncasecmp (p, "CPSR", 4) == 0)
5964 {
5965 if (m_profile)
5966 goto unsupported_psr;
5967
5968 psr_field = 0;
5969 }
5970 else if (strncasecmp (p, "APSR", 4) == 0)
5971 {
5972 /* APSR[_<bits>] can be used as a synonym for CPSR[_<flags>] on ARMv7-A
5973 and ARMv7-R architecture CPUs. */
5974 is_apsr = TRUE;
5975 psr_field = 0;
5976 }
5977 else if (m_profile)
62b3e311
PB
5978 {
5979 start = p;
5980 do
5981 p++;
5982 while (ISALNUM (*p) || *p == '_');
5983
d2cd1205
JB
5984 if (strncasecmp (start, "iapsr", 5) == 0
5985 || strncasecmp (start, "eapsr", 5) == 0
5986 || strncasecmp (start, "xpsr", 4) == 0
5987 || strncasecmp (start, "psr", 3) == 0)
5988 p = start + strcspn (start, "rR") + 1;
5989
21d799b5 5990 psr = (const struct asm_psr *) hash_find_n (arm_v7m_psr_hsh, start,
477330fc 5991 p - start);
d2cd1205 5992
62b3e311
PB
5993 if (!psr)
5994 return FAIL;
09d92015 5995
d2cd1205
JB
5996 /* If APSR is being written, a bitfield may be specified. Note that
5997 APSR itself is handled above. */
5998 if (psr->field <= 3)
5999 {
6000 psr_field = psr->field;
6001 is_apsr = TRUE;
6002 goto check_suffix;
6003 }
6004
62b3e311 6005 *str = p;
d2cd1205
JB
6006 /* M-profile MSR instructions have the mask field set to "10", except
6007 *PSR variants which modify APSR, which may use a different mask (and
6008 have been handled already). Do that by setting the PSR_f field
6009 here. */
6010 return psr->field | (lhs ? PSR_f : 0);
62b3e311 6011 }
d2cd1205
JB
6012 else
6013 goto unsupported_psr;
09d92015 6014
62b3e311 6015 p += 4;
d2cd1205 6016check_suffix:
c19d1205
ZW
6017 if (*p == '_')
6018 {
6019 /* A suffix follows. */
c19d1205
ZW
6020 p++;
6021 start = p;
a737bd4d 6022
c19d1205
ZW
6023 do
6024 p++;
6025 while (ISALNUM (*p) || *p == '_');
a737bd4d 6026
d2cd1205
JB
6027 if (is_apsr)
6028 {
6029 /* APSR uses a notation for bits, rather than fields. */
6030 unsigned int nzcvq_bits = 0;
6031 unsigned int g_bit = 0;
6032 char *bit;
fa94de6b 6033
d2cd1205
JB
6034 for (bit = start; bit != p; bit++)
6035 {
6036 switch (TOLOWER (*bit))
477330fc 6037 {
d2cd1205
JB
6038 case 'n':
6039 nzcvq_bits |= (nzcvq_bits & 0x01) ? 0x20 : 0x01;
6040 break;
6041
6042 case 'z':
6043 nzcvq_bits |= (nzcvq_bits & 0x02) ? 0x20 : 0x02;
6044 break;
6045
6046 case 'c':
6047 nzcvq_bits |= (nzcvq_bits & 0x04) ? 0x20 : 0x04;
6048 break;
6049
6050 case 'v':
6051 nzcvq_bits |= (nzcvq_bits & 0x08) ? 0x20 : 0x08;
6052 break;
fa94de6b 6053
d2cd1205
JB
6054 case 'q':
6055 nzcvq_bits |= (nzcvq_bits & 0x10) ? 0x20 : 0x10;
6056 break;
fa94de6b 6057
d2cd1205
JB
6058 case 'g':
6059 g_bit |= (g_bit & 0x1) ? 0x2 : 0x1;
6060 break;
fa94de6b 6061
d2cd1205
JB
6062 default:
6063 inst.error = _("unexpected bit specified after APSR");
6064 return FAIL;
6065 }
6066 }
fa94de6b 6067
d2cd1205
JB
6068 if (nzcvq_bits == 0x1f)
6069 psr_field |= PSR_f;
fa94de6b 6070
d2cd1205
JB
6071 if (g_bit == 0x1)
6072 {
6073 if (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp))
477330fc 6074 {
d2cd1205
JB
6075 inst.error = _("selected processor does not "
6076 "support DSP extension");
6077 return FAIL;
6078 }
6079
6080 psr_field |= PSR_s;
6081 }
fa94de6b 6082
d2cd1205
JB
6083 if ((nzcvq_bits & 0x20) != 0
6084 || (nzcvq_bits != 0x1f && nzcvq_bits != 0)
6085 || (g_bit & 0x2) != 0)
6086 {
6087 inst.error = _("bad bitmask specified after APSR");
6088 return FAIL;
6089 }
6090 }
6091 else
477330fc 6092 {
d2cd1205 6093 psr = (const struct asm_psr *) hash_find_n (arm_psr_hsh, start,
477330fc 6094 p - start);
d2cd1205 6095 if (!psr)
477330fc 6096 goto error;
a737bd4d 6097
d2cd1205
JB
6098 psr_field |= psr->field;
6099 }
a737bd4d 6100 }
c19d1205 6101 else
a737bd4d 6102 {
c19d1205
ZW
6103 if (ISALNUM (*p))
6104 goto error; /* Garbage after "[CS]PSR". */
6105
d2cd1205 6106 /* Unadorned APSR is equivalent to APSR_nzcvq/CPSR_f (for writes). This
477330fc 6107 is deprecated, but allow it anyway. */
d2cd1205
JB
6108 if (is_apsr && lhs)
6109 {
6110 psr_field |= PSR_f;
6111 as_tsktsk (_("writing to APSR without specifying a bitmask is "
6112 "deprecated"));
6113 }
6114 else if (!m_profile)
6115 /* These bits are never right for M-profile devices: don't set them
6116 (only code paths which read/write APSR reach here). */
6117 psr_field |= (PSR_c | PSR_f);
a737bd4d 6118 }
c19d1205
ZW
6119 *str = p;
6120 return psr_field;
a737bd4d 6121
d2cd1205
JB
6122 unsupported_psr:
6123 inst.error = _("selected processor does not support requested special "
6124 "purpose register");
6125 return FAIL;
6126
c19d1205
ZW
6127 error:
6128 inst.error = _("flag for {c}psr instruction expected");
6129 return FAIL;
a737bd4d
NC
6130}
6131
32c36c3c
AV
6132static int
6133parse_sys_vldr_vstr (char **str)
6134{
6135 unsigned i;
6136 int val = FAIL;
6137 struct {
6138 const char *name;
6139 int regl;
6140 int regh;
6141 } sysregs[] = {
6142 {"FPSCR", 0x1, 0x0},
6143 {"FPSCR_nzcvqc", 0x2, 0x0},
6144 {"VPR", 0x4, 0x1},
6145 {"P0", 0x5, 0x1},
6146 {"FPCXTNS", 0x6, 0x1},
6147 {"FPCXTS", 0x7, 0x1}
6148 };
6149 char *op_end = strchr (*str, ',');
6150 size_t op_strlen = op_end - *str;
6151
6152 for (i = 0; i < sizeof (sysregs) / sizeof (sysregs[0]); i++)
6153 {
6154 if (!strncmp (*str, sysregs[i].name, op_strlen))
6155 {
6156 val = sysregs[i].regl | (sysregs[i].regh << 3);
6157 *str = op_end;
6158 break;
6159 }
6160 }
6161
6162 return val;
6163}
6164
c19d1205
ZW
6165/* Parse the flags argument to CPSI[ED]. Returns FAIL on error, or a
6166 value suitable for splatting into the AIF field of the instruction. */
a737bd4d 6167
c19d1205
ZW
6168static int
6169parse_cps_flags (char **str)
a737bd4d 6170{
c19d1205
ZW
6171 int val = 0;
6172 int saw_a_flag = 0;
6173 char *s = *str;
a737bd4d 6174
c19d1205
ZW
6175 for (;;)
6176 switch (*s++)
6177 {
6178 case '\0': case ',':
6179 goto done;
a737bd4d 6180
c19d1205
ZW
6181 case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
6182 case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
6183 case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
a737bd4d 6184
c19d1205
ZW
6185 default:
6186 inst.error = _("unrecognized CPS flag");
6187 return FAIL;
6188 }
a737bd4d 6189
c19d1205
ZW
6190 done:
6191 if (saw_a_flag == 0)
a737bd4d 6192 {
c19d1205
ZW
6193 inst.error = _("missing CPS flags");
6194 return FAIL;
a737bd4d 6195 }
a737bd4d 6196
c19d1205
ZW
6197 *str = s - 1;
6198 return val;
a737bd4d
NC
6199}
6200
c19d1205
ZW
6201/* Parse an endian specifier ("BE" or "LE", case insensitive);
6202 returns 0 for big-endian, 1 for little-endian, FAIL for an error. */
a737bd4d
NC
6203
6204static int
c19d1205 6205parse_endian_specifier (char **str)
a737bd4d 6206{
c19d1205
ZW
6207 int little_endian;
6208 char *s = *str;
a737bd4d 6209
c19d1205
ZW
6210 if (strncasecmp (s, "BE", 2))
6211 little_endian = 0;
6212 else if (strncasecmp (s, "LE", 2))
6213 little_endian = 1;
6214 else
a737bd4d 6215 {
c19d1205 6216 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6217 return FAIL;
6218 }
6219
c19d1205 6220 if (ISALNUM (s[2]) || s[2] == '_')
a737bd4d 6221 {
c19d1205 6222 inst.error = _("valid endian specifiers are be or le");
a737bd4d
NC
6223 return FAIL;
6224 }
6225
c19d1205
ZW
6226 *str = s + 2;
6227 return little_endian;
6228}
a737bd4d 6229
c19d1205
ZW
6230/* Parse a rotation specifier: ROR #0, #8, #16, #24. *val receives a
6231 value suitable for poking into the rotate field of an sxt or sxta
6232 instruction, or FAIL on error. */
6233
6234static int
6235parse_ror (char **str)
6236{
6237 int rot;
6238 char *s = *str;
6239
6240 if (strncasecmp (s, "ROR", 3) == 0)
6241 s += 3;
6242 else
a737bd4d 6243 {
c19d1205 6244 inst.error = _("missing rotation field after comma");
a737bd4d
NC
6245 return FAIL;
6246 }
c19d1205
ZW
6247
6248 if (parse_immediate (&s, &rot, 0, 24, FALSE) == FAIL)
6249 return FAIL;
6250
6251 switch (rot)
a737bd4d 6252 {
c19d1205
ZW
6253 case 0: *str = s; return 0x0;
6254 case 8: *str = s; return 0x1;
6255 case 16: *str = s; return 0x2;
6256 case 24: *str = s; return 0x3;
6257
6258 default:
6259 inst.error = _("rotation can only be 0, 8, 16, or 24");
a737bd4d
NC
6260 return FAIL;
6261 }
c19d1205 6262}
a737bd4d 6263
c19d1205
ZW
6264/* Parse a conditional code (from conds[] below). The value returned is in the
6265 range 0 .. 14, or FAIL. */
6266static int
6267parse_cond (char **str)
6268{
c462b453 6269 char *q;
c19d1205 6270 const struct asm_cond *c;
c462b453
PB
6271 int n;
6272 /* Condition codes are always 2 characters, so matching up to
6273 3 characters is sufficient. */
6274 char cond[3];
a737bd4d 6275
c462b453
PB
6276 q = *str;
6277 n = 0;
6278 while (ISALPHA (*q) && n < 3)
6279 {
e07e6e58 6280 cond[n] = TOLOWER (*q);
c462b453
PB
6281 q++;
6282 n++;
6283 }
a737bd4d 6284
21d799b5 6285 c = (const struct asm_cond *) hash_find_n (arm_cond_hsh, cond, n);
c19d1205 6286 if (!c)
a737bd4d 6287 {
c19d1205 6288 inst.error = _("condition required");
a737bd4d
NC
6289 return FAIL;
6290 }
6291
c19d1205
ZW
6292 *str = q;
6293 return c->value;
6294}
6295
643afb90
MW
6296/* Record a use of the given feature. */
6297static void
6298record_feature_use (const arm_feature_set *feature)
6299{
6300 if (thumb_mode)
6301 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used, *feature);
6302 else
6303 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, *feature);
6304}
6305
4d354d8b
TP
6306/* If the given feature is currently allowed, mark it as used and return TRUE.
6307 Return FALSE otherwise. */
e797f7e0
MGD
6308static bfd_boolean
6309mark_feature_used (const arm_feature_set *feature)
6310{
4d354d8b 6311 /* Ensure the option is currently allowed. */
e797f7e0
MGD
6312 if (!ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
6313 return FALSE;
6314
4d354d8b 6315 /* Add the appropriate architecture feature for the barrier option used. */
643afb90 6316 record_feature_use (feature);
e797f7e0
MGD
6317
6318 return TRUE;
6319}
6320
62b3e311
PB
6321/* Parse an option for a barrier instruction. Returns the encoding for the
6322 option, or FAIL. */
6323static int
6324parse_barrier (char **str)
6325{
6326 char *p, *q;
6327 const struct asm_barrier_opt *o;
6328
6329 p = q = *str;
6330 while (ISALPHA (*q))
6331 q++;
6332
21d799b5 6333 o = (const struct asm_barrier_opt *) hash_find_n (arm_barrier_opt_hsh, p,
477330fc 6334 q - p);
62b3e311
PB
6335 if (!o)
6336 return FAIL;
6337
e797f7e0
MGD
6338 if (!mark_feature_used (&o->arch))
6339 return FAIL;
6340
62b3e311
PB
6341 *str = q;
6342 return o->value;
6343}
6344
92e90b6e
PB
6345/* Parse the operands of a table branch instruction. Similar to a memory
6346 operand. */
6347static int
6348parse_tb (char **str)
6349{
6350 char * p = *str;
6351 int reg;
6352
6353 if (skip_past_char (&p, '[') == FAIL)
ab1eb5fe
PB
6354 {
6355 inst.error = _("'[' expected");
6356 return FAIL;
6357 }
92e90b6e 6358
dcbf9037 6359 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6360 {
6361 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6362 return FAIL;
6363 }
6364 inst.operands[0].reg = reg;
6365
6366 if (skip_past_comma (&p) == FAIL)
ab1eb5fe
PB
6367 {
6368 inst.error = _("',' expected");
6369 return FAIL;
6370 }
5f4273c7 6371
dcbf9037 6372 if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
92e90b6e
PB
6373 {
6374 inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
6375 return FAIL;
6376 }
6377 inst.operands[0].imm = reg;
6378
6379 if (skip_past_comma (&p) == SUCCESS)
6380 {
6381 if (parse_shift (&p, 0, SHIFT_LSL_IMMEDIATE) == FAIL)
6382 return FAIL;
e2b0ab59 6383 if (inst.relocs[0].exp.X_add_number != 1)
92e90b6e
PB
6384 {
6385 inst.error = _("invalid shift");
6386 return FAIL;
6387 }
6388 inst.operands[0].shifted = 1;
6389 }
6390
6391 if (skip_past_char (&p, ']') == FAIL)
6392 {
6393 inst.error = _("']' expected");
6394 return FAIL;
6395 }
6396 *str = p;
6397 return SUCCESS;
6398}
6399
5287ad62
JB
6400/* Parse the operands of a Neon VMOV instruction. See do_neon_mov for more
6401 information on the types the operands can take and how they are encoded.
037e8744
JB
6402 Up to four operands may be read; this function handles setting the
6403 ".present" field for each read operand itself.
5287ad62
JB
6404 Updates STR and WHICH_OPERAND if parsing is successful and returns SUCCESS,
6405 else returns FAIL. */
6406
6407static int
6408parse_neon_mov (char **str, int *which_operand)
6409{
6410 int i = *which_operand, val;
6411 enum arm_reg_type rtype;
6412 char *ptr = *str;
dcbf9037 6413 struct neon_type_el optype;
5f4273c7 6414
dcbf9037 6415 if ((val = parse_scalar (&ptr, 8, &optype)) != FAIL)
5287ad62
JB
6416 {
6417 /* Case 4: VMOV<c><q>.<size> <Dn[x]>, <Rd>. */
6418 inst.operands[i].reg = val;
6419 inst.operands[i].isscalar = 1;
dcbf9037 6420 inst.operands[i].vectype = optype;
5287ad62
JB
6421 inst.operands[i++].present = 1;
6422
6423 if (skip_past_comma (&ptr) == FAIL)
477330fc 6424 goto wanted_comma;
5f4273c7 6425
dcbf9037 6426 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
477330fc 6427 goto wanted_arm;
5f4273c7 6428
5287ad62
JB
6429 inst.operands[i].reg = val;
6430 inst.operands[i].isreg = 1;
6431 inst.operands[i].present = 1;
6432 }
037e8744 6433 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype, &optype))
477330fc 6434 != FAIL)
5287ad62
JB
6435 {
6436 /* Cases 0, 1, 2, 3, 5 (D only). */
6437 if (skip_past_comma (&ptr) == FAIL)
477330fc 6438 goto wanted_comma;
5f4273c7 6439
5287ad62
JB
6440 inst.operands[i].reg = val;
6441 inst.operands[i].isreg = 1;
6442 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
037e8744
JB
6443 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6444 inst.operands[i].isvec = 1;
dcbf9037 6445 inst.operands[i].vectype = optype;
5287ad62
JB
6446 inst.operands[i++].present = 1;
6447
dcbf9037 6448 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6449 {
6450 /* Case 5: VMOV<c><q> <Dm>, <Rd>, <Rn>.
6451 Case 13: VMOV <Sd>, <Rm> */
6452 inst.operands[i].reg = val;
6453 inst.operands[i].isreg = 1;
6454 inst.operands[i].present = 1;
6455
6456 if (rtype == REG_TYPE_NQ)
6457 {
6458 first_error (_("can't use Neon quad register here"));
6459 return FAIL;
6460 }
6461 else if (rtype != REG_TYPE_VFS)
6462 {
6463 i++;
6464 if (skip_past_comma (&ptr) == FAIL)
6465 goto wanted_comma;
6466 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6467 goto wanted_arm;
6468 inst.operands[i].reg = val;
6469 inst.operands[i].isreg = 1;
6470 inst.operands[i].present = 1;
6471 }
6472 }
037e8744 6473 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_NSDQ, &rtype,
477330fc
RM
6474 &optype)) != FAIL)
6475 {
6476 /* Case 0: VMOV<c><q> <Qd>, <Qm>
6477 Case 1: VMOV<c><q> <Dd>, <Dm>
6478 Case 8: VMOV.F32 <Sd>, <Sm>
6479 Case 15: VMOV <Sd>, <Se>, <Rn>, <Rm> */
6480
6481 inst.operands[i].reg = val;
6482 inst.operands[i].isreg = 1;
6483 inst.operands[i].isquad = (rtype == REG_TYPE_NQ);
6484 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6485 inst.operands[i].isvec = 1;
6486 inst.operands[i].vectype = optype;
6487 inst.operands[i].present = 1;
6488
6489 if (skip_past_comma (&ptr) == SUCCESS)
6490 {
6491 /* Case 15. */
6492 i++;
6493
6494 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6495 goto wanted_arm;
6496
6497 inst.operands[i].reg = val;
6498 inst.operands[i].isreg = 1;
6499 inst.operands[i++].present = 1;
6500
6501 if (skip_past_comma (&ptr) == FAIL)
6502 goto wanted_comma;
6503
6504 if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) == FAIL)
6505 goto wanted_arm;
6506
6507 inst.operands[i].reg = val;
6508 inst.operands[i].isreg = 1;
6509 inst.operands[i].present = 1;
6510 }
6511 }
4641781c 6512 else if (parse_qfloat_immediate (&ptr, &inst.operands[i].imm) == SUCCESS)
477330fc
RM
6513 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<float-imm>
6514 Case 3: VMOV<c><q>.<dt> <Dd>, #<float-imm>
6515 Case 10: VMOV.F32 <Sd>, #<imm>
6516 Case 11: VMOV.F64 <Dd>, #<imm> */
6517 inst.operands[i].immisfloat = 1;
8335d6aa
JW
6518 else if (parse_big_immediate (&ptr, i, NULL, /*allow_symbol_p=*/FALSE)
6519 == SUCCESS)
477330fc
RM
6520 /* Case 2: VMOV<c><q>.<dt> <Qd>, #<imm>
6521 Case 3: VMOV<c><q>.<dt> <Dd>, #<imm> */
6522 ;
5287ad62 6523 else
477330fc
RM
6524 {
6525 first_error (_("expected <Rm> or <Dm> or <Qm> operand"));
6526 return FAIL;
6527 }
5287ad62 6528 }
dcbf9037 6529 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
5287ad62
JB
6530 {
6531 /* Cases 6, 7. */
6532 inst.operands[i].reg = val;
6533 inst.operands[i].isreg = 1;
6534 inst.operands[i++].present = 1;
5f4273c7 6535
5287ad62 6536 if (skip_past_comma (&ptr) == FAIL)
477330fc 6537 goto wanted_comma;
5f4273c7 6538
dcbf9037 6539 if ((val = parse_scalar (&ptr, 8, &optype)) != FAIL)
477330fc
RM
6540 {
6541 /* Case 6: VMOV<c><q>.<dt> <Rd>, <Dn[x]> */
6542 inst.operands[i].reg = val;
6543 inst.operands[i].isscalar = 1;
6544 inst.operands[i].present = 1;
6545 inst.operands[i].vectype = optype;
6546 }
dcbf9037 6547 else if ((val = arm_reg_parse (&ptr, REG_TYPE_RN)) != FAIL)
477330fc
RM
6548 {
6549 /* Case 7: VMOV<c><q> <Rd>, <Rn>, <Dm> */
6550 inst.operands[i].reg = val;
6551 inst.operands[i].isreg = 1;
6552 inst.operands[i++].present = 1;
6553
6554 if (skip_past_comma (&ptr) == FAIL)
6555 goto wanted_comma;
6556
6557 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFSD, &rtype, &optype))
6558 == FAIL)
6559 {
6560 first_error (_(reg_expected_msgs[REG_TYPE_VFSD]));
6561 return FAIL;
6562 }
6563
6564 inst.operands[i].reg = val;
6565 inst.operands[i].isreg = 1;
6566 inst.operands[i].isvec = 1;
6567 inst.operands[i].issingle = (rtype == REG_TYPE_VFS);
6568 inst.operands[i].vectype = optype;
6569 inst.operands[i].present = 1;
6570
6571 if (rtype == REG_TYPE_VFS)
6572 {
6573 /* Case 14. */
6574 i++;
6575 if (skip_past_comma (&ptr) == FAIL)
6576 goto wanted_comma;
6577 if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL,
6578 &optype)) == FAIL)
6579 {
6580 first_error (_(reg_expected_msgs[REG_TYPE_VFS]));
6581 return FAIL;
6582 }
6583 inst.operands[i].reg = val;
6584 inst.operands[i].isreg = 1;
6585 inst.operands[i].isvec = 1;
6586 inst.operands[i].issingle = 1;
6587 inst.operands[i].vectype = optype;
6588 inst.operands[i].present = 1;
6589 }
6590 }
037e8744 6591 else if ((val = arm_typed_reg_parse (&ptr, REG_TYPE_VFS, NULL, &optype))
477330fc
RM
6592 != FAIL)
6593 {
6594 /* Case 13. */
6595 inst.operands[i].reg = val;
6596 inst.operands[i].isreg = 1;
6597 inst.operands[i].isvec = 1;
6598 inst.operands[i].issingle = 1;
6599 inst.operands[i].vectype = optype;
6600 inst.operands[i].present = 1;
6601 }
5287ad62
JB
6602 }
6603 else
6604 {
dcbf9037 6605 first_error (_("parse error"));
5287ad62
JB
6606 return FAIL;
6607 }
6608
6609 /* Successfully parsed the operands. Update args. */
6610 *which_operand = i;
6611 *str = ptr;
6612 return SUCCESS;
6613
5f4273c7 6614 wanted_comma:
dcbf9037 6615 first_error (_("expected comma"));
5287ad62 6616 return FAIL;
5f4273c7
NC
6617
6618 wanted_arm:
dcbf9037 6619 first_error (_(reg_expected_msgs[REG_TYPE_RN]));
5287ad62 6620 return FAIL;
5287ad62
JB
6621}
6622
5be8be5d
DG
6623/* Use this macro when the operand constraints are different
6624 for ARM and THUMB (e.g. ldrd). */
6625#define MIX_ARM_THUMB_OPERANDS(arm_operand, thumb_operand) \
6626 ((arm_operand) | ((thumb_operand) << 16))
6627
c19d1205
ZW
6628/* Matcher codes for parse_operands. */
6629enum operand_parse_code
6630{
6631 OP_stop, /* end of line */
6632
6633 OP_RR, /* ARM register */
6634 OP_RRnpc, /* ARM register, not r15 */
5be8be5d 6635 OP_RRnpcsp, /* ARM register, neither r15 nor r13 (a.k.a. 'BadReg') */
c19d1205 6636 OP_RRnpcb, /* ARM register, not r15, in square brackets */
fa94de6b 6637 OP_RRnpctw, /* ARM register, not r15 in Thumb-state or with writeback,
55881a11 6638 optional trailing ! */
c19d1205
ZW
6639 OP_RRw, /* ARM register, not r15, optional trailing ! */
6640 OP_RCP, /* Coprocessor number */
6641 OP_RCN, /* Coprocessor register */
6642 OP_RF, /* FPA register */
6643 OP_RVS, /* VFP single precision register */
5287ad62
JB
6644 OP_RVD, /* VFP double precision register (0..15) */
6645 OP_RND, /* Neon double precision register (0..31) */
6646 OP_RNQ, /* Neon quad precision register */
037e8744 6647 OP_RVSD, /* VFP single or double precision register */
dec41383 6648 OP_RNSD, /* Neon single or double precision register */
5287ad62 6649 OP_RNDQ, /* Neon double or quad precision register */
037e8744 6650 OP_RNSDQ, /* Neon single, double or quad precision register */
5287ad62 6651 OP_RNSC, /* Neon scalar D[X] */
c19d1205
ZW
6652 OP_RVC, /* VFP control register */
6653 OP_RMF, /* Maverick F register */
6654 OP_RMD, /* Maverick D register */
6655 OP_RMFX, /* Maverick FX register */
6656 OP_RMDX, /* Maverick DX register */
6657 OP_RMAX, /* Maverick AX register */
6658 OP_RMDS, /* Maverick DSPSC register */
6659 OP_RIWR, /* iWMMXt wR register */
6660 OP_RIWC, /* iWMMXt wC register */
6661 OP_RIWG, /* iWMMXt wCG register */
6662 OP_RXA, /* XScale accumulator register */
6663
60f993ce
AV
6664 /* New operands for Armv8.1-M Mainline. */
6665 OP_LR, /* ARM LR register */
6666 OP_RRnpcsp_I32, /* ARM register (no BadReg) or literal 1 .. 32 */
6667
c19d1205 6668 OP_REGLST, /* ARM register list */
4b5a202f 6669 OP_CLRMLST, /* CLRM register list */
c19d1205
ZW
6670 OP_VRSLST, /* VFP single-precision register list */
6671 OP_VRDLST, /* VFP double-precision register list */
037e8744 6672 OP_VRSDLST, /* VFP single or double-precision register list (& quad) */
5287ad62
JB
6673 OP_NRDLST, /* Neon double-precision register list (d0-d31, qN aliases) */
6674 OP_NSTRLST, /* Neon element/structure list */
efd6b359 6675 OP_VRSDVLST, /* VFP single or double-precision register list and VPR */
5287ad62 6676
5287ad62 6677 OP_RNDQ_I0, /* Neon D or Q reg, or immediate zero. */
037e8744 6678 OP_RVSD_I0, /* VFP S or D reg, or immediate zero. */
aacf0b33 6679 OP_RSVD_FI0, /* VFP S or D reg, or floating point immediate zero. */
5287ad62 6680 OP_RR_RNSC, /* ARM reg or Neon scalar. */
dec41383 6681 OP_RNSD_RNSC, /* Neon S or D reg, or Neon scalar. */
037e8744 6682 OP_RNSDQ_RNSC, /* Vector S, D or Q reg, or Neon scalar. */
5287ad62
JB
6683 OP_RNDQ_RNSC, /* Neon D or Q reg, or Neon scalar. */
6684 OP_RND_RNSC, /* Neon D reg, or Neon scalar. */
6685 OP_VMOV, /* Neon VMOV operands. */
4316f0d2 6686 OP_RNDQ_Ibig, /* Neon D or Q reg, or big immediate for logic and VMVN. */
5287ad62 6687 OP_RNDQ_I63b, /* Neon D or Q reg, or immediate for shift. */
2d447fca 6688 OP_RIWR_I32z, /* iWMMXt wR register, or immediate 0 .. 32 for iWMMXt2. */
32c36c3c 6689 OP_VLDR, /* VLDR operand. */
5287ad62
JB
6690
6691 OP_I0, /* immediate zero */
c19d1205
ZW
6692 OP_I7, /* immediate value 0 .. 7 */
6693 OP_I15, /* 0 .. 15 */
6694 OP_I16, /* 1 .. 16 */
5287ad62 6695 OP_I16z, /* 0 .. 16 */
c19d1205
ZW
6696 OP_I31, /* 0 .. 31 */
6697 OP_I31w, /* 0 .. 31, optional trailing ! */
6698 OP_I32, /* 1 .. 32 */
5287ad62
JB
6699 OP_I32z, /* 0 .. 32 */
6700 OP_I63, /* 0 .. 63 */
c19d1205 6701 OP_I63s, /* -64 .. 63 */
5287ad62
JB
6702 OP_I64, /* 1 .. 64 */
6703 OP_I64z, /* 0 .. 64 */
c19d1205 6704 OP_I255, /* 0 .. 255 */
c19d1205
ZW
6705
6706 OP_I4b, /* immediate, prefix optional, 1 .. 4 */
6707 OP_I7b, /* 0 .. 7 */
6708 OP_I15b, /* 0 .. 15 */
6709 OP_I31b, /* 0 .. 31 */
6710
6711 OP_SH, /* shifter operand */
4962c51a 6712 OP_SHG, /* shifter operand with possible group relocation */
c19d1205 6713 OP_ADDR, /* Memory address expression (any mode) */
4962c51a
MS
6714 OP_ADDRGLDR, /* Mem addr expr (any mode) with possible LDR group reloc */
6715 OP_ADDRGLDRS, /* Mem addr expr (any mode) with possible LDRS group reloc */
6716 OP_ADDRGLDC, /* Mem addr expr (any mode) with possible LDC group reloc */
c19d1205
ZW
6717 OP_EXP, /* arbitrary expression */
6718 OP_EXPi, /* same, with optional immediate prefix */
6719 OP_EXPr, /* same, with optional relocation suffix */
e2b0ab59 6720 OP_EXPs, /* same, with optional non-first operand relocation suffix */
b6895b4f 6721 OP_HALF, /* 0 .. 65535 or low/high reloc. */
c28eeff2
SN
6722 OP_IROT1, /* VCADD rotate immediate: 90, 270. */
6723 OP_IROT2, /* VCMLA rotate immediate: 0, 90, 180, 270. */
c19d1205
ZW
6724
6725 OP_CPSF, /* CPS flags */
6726 OP_ENDI, /* Endianness specifier */
d2cd1205
JB
6727 OP_wPSR, /* CPSR/SPSR/APSR mask for msr (writing). */
6728 OP_rPSR, /* CPSR/SPSR/APSR mask for msr (reading). */
c19d1205 6729 OP_COND, /* conditional code */
92e90b6e 6730 OP_TB, /* Table branch. */
c19d1205 6731
037e8744
JB
6732 OP_APSR_RR, /* ARM register or "APSR_nzcv". */
6733
c19d1205 6734 OP_RRnpc_I0, /* ARM register or literal 0 */
33eaf5de 6735 OP_RR_EXr, /* ARM register or expression with opt. reloc stuff. */
c19d1205
ZW
6736 OP_RR_EXi, /* ARM register or expression with imm prefix */
6737 OP_RF_IF, /* FPA register or immediate */
6738 OP_RIWR_RIWC, /* iWMMXt R or C reg */
41adaa5c 6739 OP_RIWC_RIWG, /* iWMMXt wC or wCG reg */
c19d1205
ZW
6740
6741 /* Optional operands. */
6742 OP_oI7b, /* immediate, prefix optional, 0 .. 7 */
6743 OP_oI31b, /* 0 .. 31 */
5287ad62 6744 OP_oI32b, /* 1 .. 32 */
5f1af56b 6745 OP_oI32z, /* 0 .. 32 */
c19d1205
ZW
6746 OP_oIffffb, /* 0 .. 65535 */
6747 OP_oI255c, /* curly-brace enclosed, 0 .. 255 */
6748
6749 OP_oRR, /* ARM register */
60f993ce 6750 OP_oLR, /* ARM LR register */
c19d1205 6751 OP_oRRnpc, /* ARM register, not the PC */
5be8be5d 6752 OP_oRRnpcsp, /* ARM register, neither the PC nor the SP (a.k.a. BadReg) */
b6702015 6753 OP_oRRw, /* ARM register, not r15, optional trailing ! */
5287ad62
JB
6754 OP_oRND, /* Optional Neon double precision register */
6755 OP_oRNQ, /* Optional Neon quad precision register */
6756 OP_oRNDQ, /* Optional Neon double or quad precision register */
037e8744 6757 OP_oRNSDQ, /* Optional single, double or quad precision vector register */
c19d1205
ZW
6758 OP_oSHll, /* LSL immediate */
6759 OP_oSHar, /* ASR immediate */
6760 OP_oSHllar, /* LSL or ASR immediate */
6761 OP_oROR, /* ROR 0/8/16/24 */
52e7f43d 6762 OP_oBARRIER_I15, /* Option argument for a barrier instruction. */
c19d1205 6763
5be8be5d
DG
6764 /* Some pre-defined mixed (ARM/THUMB) operands. */
6765 OP_RR_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RR, OP_RRnpcsp),
6766 OP_RRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_RRnpc, OP_RRnpcsp),
6767 OP_oRRnpc_npcsp = MIX_ARM_THUMB_OPERANDS (OP_oRRnpc, OP_oRRnpcsp),
6768
c19d1205
ZW
6769 OP_FIRST_OPTIONAL = OP_oI7b
6770};
a737bd4d 6771
c19d1205
ZW
6772/* Generic instruction operand parser. This does no encoding and no
6773 semantic validation; it merely squirrels values away in the inst
6774 structure. Returns SUCCESS or FAIL depending on whether the
6775 specified grammar matched. */
6776static int
5be8be5d 6777parse_operands (char *str, const unsigned int *pattern, bfd_boolean thumb)
c19d1205 6778{
5be8be5d 6779 unsigned const int *upat = pattern;
c19d1205
ZW
6780 char *backtrack_pos = 0;
6781 const char *backtrack_error = 0;
99aad254 6782 int i, val = 0, backtrack_index = 0;
5287ad62 6783 enum arm_reg_type rtype;
4962c51a 6784 parse_operand_result result;
5be8be5d 6785 unsigned int op_parse_code;
efd6b359 6786 bfd_boolean partial_match;
c19d1205 6787
e07e6e58
NC
6788#define po_char_or_fail(chr) \
6789 do \
6790 { \
6791 if (skip_past_char (&str, chr) == FAIL) \
477330fc 6792 goto bad_args; \
e07e6e58
NC
6793 } \
6794 while (0)
c19d1205 6795
e07e6e58
NC
6796#define po_reg_or_fail(regtype) \
6797 do \
dcbf9037 6798 { \
e07e6e58 6799 val = arm_typed_reg_parse (& str, regtype, & rtype, \
477330fc 6800 & inst.operands[i].vectype); \
e07e6e58 6801 if (val == FAIL) \
477330fc
RM
6802 { \
6803 first_error (_(reg_expected_msgs[regtype])); \
6804 goto failure; \
6805 } \
e07e6e58
NC
6806 inst.operands[i].reg = val; \
6807 inst.operands[i].isreg = 1; \
6808 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
6809 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
6810 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc
RM
6811 || rtype == REG_TYPE_VFD \
6812 || rtype == REG_TYPE_NQ); \
dcbf9037 6813 } \
e07e6e58
NC
6814 while (0)
6815
6816#define po_reg_or_goto(regtype, label) \
6817 do \
6818 { \
6819 val = arm_typed_reg_parse (& str, regtype, & rtype, \
6820 & inst.operands[i].vectype); \
6821 if (val == FAIL) \
6822 goto label; \
dcbf9037 6823 \
e07e6e58
NC
6824 inst.operands[i].reg = val; \
6825 inst.operands[i].isreg = 1; \
6826 inst.operands[i].isquad = (rtype == REG_TYPE_NQ); \
6827 inst.operands[i].issingle = (rtype == REG_TYPE_VFS); \
6828 inst.operands[i].isvec = (rtype == REG_TYPE_VFS \
477330fc 6829 || rtype == REG_TYPE_VFD \
e07e6e58
NC
6830 || rtype == REG_TYPE_NQ); \
6831 } \
6832 while (0)
6833
6834#define po_imm_or_fail(min, max, popt) \
6835 do \
6836 { \
6837 if (parse_immediate (&str, &val, min, max, popt) == FAIL) \
6838 goto failure; \
6839 inst.operands[i].imm = val; \
6840 } \
6841 while (0)
6842
6843#define po_scalar_or_goto(elsz, label) \
6844 do \
6845 { \
6846 val = parse_scalar (& str, elsz, & inst.operands[i].vectype); \
6847 if (val == FAIL) \
6848 goto label; \
6849 inst.operands[i].reg = val; \
6850 inst.operands[i].isscalar = 1; \
6851 } \
6852 while (0)
6853
6854#define po_misc_or_fail(expr) \
6855 do \
6856 { \
6857 if (expr) \
6858 goto failure; \
6859 } \
6860 while (0)
6861
6862#define po_misc_or_fail_no_backtrack(expr) \
6863 do \
6864 { \
6865 result = expr; \
6866 if (result == PARSE_OPERAND_FAIL_NO_BACKTRACK) \
6867 backtrack_pos = 0; \
6868 if (result != PARSE_OPERAND_SUCCESS) \
6869 goto failure; \
6870 } \
6871 while (0)
4962c51a 6872
52e7f43d
RE
6873#define po_barrier_or_imm(str) \
6874 do \
6875 { \
6876 val = parse_barrier (&str); \
ccb84d65
JB
6877 if (val == FAIL && ! ISALPHA (*str)) \
6878 goto immediate; \
6879 if (val == FAIL \
6880 /* ISB can only take SY as an option. */ \
6881 || ((inst.instruction & 0xf0) == 0x60 \
6882 && val != 0xf)) \
52e7f43d 6883 { \
ccb84d65
JB
6884 inst.error = _("invalid barrier type"); \
6885 backtrack_pos = 0; \
6886 goto failure; \
52e7f43d
RE
6887 } \
6888 } \
6889 while (0)
6890
c19d1205
ZW
6891 skip_whitespace (str);
6892
6893 for (i = 0; upat[i] != OP_stop; i++)
6894 {
5be8be5d
DG
6895 op_parse_code = upat[i];
6896 if (op_parse_code >= 1<<16)
6897 op_parse_code = thumb ? (op_parse_code >> 16)
6898 : (op_parse_code & ((1<<16)-1));
6899
6900 if (op_parse_code >= OP_FIRST_OPTIONAL)
c19d1205
ZW
6901 {
6902 /* Remember where we are in case we need to backtrack. */
9c2799c2 6903 gas_assert (!backtrack_pos);
c19d1205
ZW
6904 backtrack_pos = str;
6905 backtrack_error = inst.error;
6906 backtrack_index = i;
6907 }
6908
b6702015 6909 if (i > 0 && (i > 1 || inst.operands[0].present))
c19d1205
ZW
6910 po_char_or_fail (',');
6911
5be8be5d 6912 switch (op_parse_code)
c19d1205
ZW
6913 {
6914 /* Registers */
6915 case OP_oRRnpc:
5be8be5d 6916 case OP_oRRnpcsp:
c19d1205 6917 case OP_RRnpc:
5be8be5d 6918 case OP_RRnpcsp:
c19d1205 6919 case OP_oRR:
60f993ce
AV
6920 case OP_LR:
6921 case OP_oLR:
c19d1205
ZW
6922 case OP_RR: po_reg_or_fail (REG_TYPE_RN); break;
6923 case OP_RCP: po_reg_or_fail (REG_TYPE_CP); break;
6924 case OP_RCN: po_reg_or_fail (REG_TYPE_CN); break;
6925 case OP_RF: po_reg_or_fail (REG_TYPE_FN); break;
6926 case OP_RVS: po_reg_or_fail (REG_TYPE_VFS); break;
6927 case OP_RVD: po_reg_or_fail (REG_TYPE_VFD); break;
477330fc 6928 case OP_oRND:
5287ad62 6929 case OP_RND: po_reg_or_fail (REG_TYPE_VFD); break;
cd2cf30b
PB
6930 case OP_RVC:
6931 po_reg_or_goto (REG_TYPE_VFC, coproc_reg);
6932 break;
6933 /* Also accept generic coprocessor regs for unknown registers. */
6934 coproc_reg:
6935 po_reg_or_fail (REG_TYPE_CN);
6936 break;
c19d1205
ZW
6937 case OP_RMF: po_reg_or_fail (REG_TYPE_MVF); break;
6938 case OP_RMD: po_reg_or_fail (REG_TYPE_MVD); break;
6939 case OP_RMFX: po_reg_or_fail (REG_TYPE_MVFX); break;
6940 case OP_RMDX: po_reg_or_fail (REG_TYPE_MVDX); break;
6941 case OP_RMAX: po_reg_or_fail (REG_TYPE_MVAX); break;
6942 case OP_RMDS: po_reg_or_fail (REG_TYPE_DSPSC); break;
6943 case OP_RIWR: po_reg_or_fail (REG_TYPE_MMXWR); break;
6944 case OP_RIWC: po_reg_or_fail (REG_TYPE_MMXWC); break;
6945 case OP_RIWG: po_reg_or_fail (REG_TYPE_MMXWCG); break;
6946 case OP_RXA: po_reg_or_fail (REG_TYPE_XSCALE); break;
477330fc 6947 case OP_oRNQ:
5287ad62 6948 case OP_RNQ: po_reg_or_fail (REG_TYPE_NQ); break;
dec41383 6949 case OP_RNSD: po_reg_or_fail (REG_TYPE_NSD); break;
477330fc 6950 case OP_oRNDQ:
5287ad62 6951 case OP_RNDQ: po_reg_or_fail (REG_TYPE_NDQ); break;
477330fc
RM
6952 case OP_RVSD: po_reg_or_fail (REG_TYPE_VFSD); break;
6953 case OP_oRNSDQ:
6954 case OP_RNSDQ: po_reg_or_fail (REG_TYPE_NSDQ); break;
6955
6956 /* Neon scalar. Using an element size of 8 means that some invalid
6957 scalars are accepted here, so deal with those in later code. */
6958 case OP_RNSC: po_scalar_or_goto (8, failure); break;
6959
6960 case OP_RNDQ_I0:
6961 {
6962 po_reg_or_goto (REG_TYPE_NDQ, try_imm0);
6963 break;
6964 try_imm0:
6965 po_imm_or_fail (0, 0, TRUE);
6966 }
6967 break;
6968
6969 case OP_RVSD_I0:
6970 po_reg_or_goto (REG_TYPE_VFSD, try_imm0);
6971 break;
6972
aacf0b33
KT
6973 case OP_RSVD_FI0:
6974 {
6975 po_reg_or_goto (REG_TYPE_VFSD, try_ifimm0);
6976 break;
6977 try_ifimm0:
6978 if (parse_ifimm_zero (&str))
6979 inst.operands[i].imm = 0;
6980 else
6981 {
6982 inst.error
6983 = _("only floating point zero is allowed as immediate value");
6984 goto failure;
6985 }
6986 }
6987 break;
6988
477330fc
RM
6989 case OP_RR_RNSC:
6990 {
6991 po_scalar_or_goto (8, try_rr);
6992 break;
6993 try_rr:
6994 po_reg_or_fail (REG_TYPE_RN);
6995 }
6996 break;
6997
6998 case OP_RNSDQ_RNSC:
6999 {
7000 po_scalar_or_goto (8, try_nsdq);
7001 break;
7002 try_nsdq:
7003 po_reg_or_fail (REG_TYPE_NSDQ);
7004 }
7005 break;
7006
dec41383
JW
7007 case OP_RNSD_RNSC:
7008 {
7009 po_scalar_or_goto (8, try_s_scalar);
7010 break;
7011 try_s_scalar:
7012 po_scalar_or_goto (4, try_nsd);
7013 break;
7014 try_nsd:
7015 po_reg_or_fail (REG_TYPE_NSD);
7016 }
7017 break;
7018
477330fc
RM
7019 case OP_RNDQ_RNSC:
7020 {
7021 po_scalar_or_goto (8, try_ndq);
7022 break;
7023 try_ndq:
7024 po_reg_or_fail (REG_TYPE_NDQ);
7025 }
7026 break;
7027
7028 case OP_RND_RNSC:
7029 {
7030 po_scalar_or_goto (8, try_vfd);
7031 break;
7032 try_vfd:
7033 po_reg_or_fail (REG_TYPE_VFD);
7034 }
7035 break;
7036
7037 case OP_VMOV:
7038 /* WARNING: parse_neon_mov can move the operand counter, i. If we're
7039 not careful then bad things might happen. */
7040 po_misc_or_fail (parse_neon_mov (&str, &i) == FAIL);
7041 break;
7042
7043 case OP_RNDQ_Ibig:
7044 {
7045 po_reg_or_goto (REG_TYPE_NDQ, try_immbig);
7046 break;
7047 try_immbig:
7048 /* There's a possibility of getting a 64-bit immediate here, so
7049 we need special handling. */
8335d6aa
JW
7050 if (parse_big_immediate (&str, i, NULL, /*allow_symbol_p=*/FALSE)
7051 == FAIL)
477330fc
RM
7052 {
7053 inst.error = _("immediate value is out of range");
7054 goto failure;
7055 }
7056 }
7057 break;
7058
7059 case OP_RNDQ_I63b:
7060 {
7061 po_reg_or_goto (REG_TYPE_NDQ, try_shimm);
7062 break;
7063 try_shimm:
7064 po_imm_or_fail (0, 63, TRUE);
7065 }
7066 break;
c19d1205
ZW
7067
7068 case OP_RRnpcb:
7069 po_char_or_fail ('[');
7070 po_reg_or_fail (REG_TYPE_RN);
7071 po_char_or_fail (']');
7072 break;
a737bd4d 7073
55881a11 7074 case OP_RRnpctw:
c19d1205 7075 case OP_RRw:
b6702015 7076 case OP_oRRw:
c19d1205
ZW
7077 po_reg_or_fail (REG_TYPE_RN);
7078 if (skip_past_char (&str, '!') == SUCCESS)
7079 inst.operands[i].writeback = 1;
7080 break;
7081
7082 /* Immediates */
7083 case OP_I7: po_imm_or_fail ( 0, 7, FALSE); break;
7084 case OP_I15: po_imm_or_fail ( 0, 15, FALSE); break;
7085 case OP_I16: po_imm_or_fail ( 1, 16, FALSE); break;
477330fc 7086 case OP_I16z: po_imm_or_fail ( 0, 16, FALSE); break;
c19d1205
ZW
7087 case OP_I31: po_imm_or_fail ( 0, 31, FALSE); break;
7088 case OP_I32: po_imm_or_fail ( 1, 32, FALSE); break;
477330fc 7089 case OP_I32z: po_imm_or_fail ( 0, 32, FALSE); break;
c19d1205 7090 case OP_I63s: po_imm_or_fail (-64, 63, FALSE); break;
477330fc
RM
7091 case OP_I63: po_imm_or_fail ( 0, 63, FALSE); break;
7092 case OP_I64: po_imm_or_fail ( 1, 64, FALSE); break;
7093 case OP_I64z: po_imm_or_fail ( 0, 64, FALSE); break;
c19d1205 7094 case OP_I255: po_imm_or_fail ( 0, 255, FALSE); break;
c19d1205
ZW
7095
7096 case OP_I4b: po_imm_or_fail ( 1, 4, TRUE); break;
7097 case OP_oI7b:
7098 case OP_I7b: po_imm_or_fail ( 0, 7, TRUE); break;
7099 case OP_I15b: po_imm_or_fail ( 0, 15, TRUE); break;
7100 case OP_oI31b:
7101 case OP_I31b: po_imm_or_fail ( 0, 31, TRUE); break;
477330fc
RM
7102 case OP_oI32b: po_imm_or_fail ( 1, 32, TRUE); break;
7103 case OP_oI32z: po_imm_or_fail ( 0, 32, TRUE); break;
c19d1205
ZW
7104 case OP_oIffffb: po_imm_or_fail ( 0, 0xffff, TRUE); break;
7105
7106 /* Immediate variants */
7107 case OP_oI255c:
7108 po_char_or_fail ('{');
7109 po_imm_or_fail (0, 255, TRUE);
7110 po_char_or_fail ('}');
7111 break;
7112
7113 case OP_I31w:
7114 /* The expression parser chokes on a trailing !, so we have
7115 to find it first and zap it. */
7116 {
7117 char *s = str;
7118 while (*s && *s != ',')
7119 s++;
7120 if (s[-1] == '!')
7121 {
7122 s[-1] = '\0';
7123 inst.operands[i].writeback = 1;
7124 }
7125 po_imm_or_fail (0, 31, TRUE);
7126 if (str == s - 1)
7127 str = s;
7128 }
7129 break;
7130
7131 /* Expressions */
7132 case OP_EXPi: EXPi:
e2b0ab59 7133 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7134 GE_OPT_PREFIX));
7135 break;
7136
7137 case OP_EXP:
e2b0ab59 7138 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205
ZW
7139 GE_NO_PREFIX));
7140 break;
7141
7142 case OP_EXPr: EXPr:
e2b0ab59 7143 po_misc_or_fail (my_get_expression (&inst.relocs[0].exp, &str,
c19d1205 7144 GE_NO_PREFIX));
e2b0ab59 7145 if (inst.relocs[0].exp.X_op == O_symbol)
a737bd4d 7146 {
c19d1205
ZW
7147 val = parse_reloc (&str);
7148 if (val == -1)
7149 {
7150 inst.error = _("unrecognized relocation suffix");
7151 goto failure;
7152 }
7153 else if (val != BFD_RELOC_UNUSED)
7154 {
7155 inst.operands[i].imm = val;
7156 inst.operands[i].hasreloc = 1;
7157 }
a737bd4d 7158 }
c19d1205 7159 break;
a737bd4d 7160
e2b0ab59
AV
7161 case OP_EXPs:
7162 po_misc_or_fail (my_get_expression (&inst.relocs[i].exp, &str,
7163 GE_NO_PREFIX));
7164 if (inst.relocs[i].exp.X_op == O_symbol)
7165 {
7166 inst.operands[i].hasreloc = 1;
7167 }
7168 else if (inst.relocs[i].exp.X_op == O_constant)
7169 {
7170 inst.operands[i].imm = inst.relocs[i].exp.X_add_number;
7171 inst.operands[i].hasreloc = 0;
7172 }
7173 break;
7174
b6895b4f
PB
7175 /* Operand for MOVW or MOVT. */
7176 case OP_HALF:
7177 po_misc_or_fail (parse_half (&str));
7178 break;
7179
e07e6e58 7180 /* Register or expression. */
c19d1205
ZW
7181 case OP_RR_EXr: po_reg_or_goto (REG_TYPE_RN, EXPr); break;
7182 case OP_RR_EXi: po_reg_or_goto (REG_TYPE_RN, EXPi); break;
a737bd4d 7183
e07e6e58 7184 /* Register or immediate. */
c19d1205
ZW
7185 case OP_RRnpc_I0: po_reg_or_goto (REG_TYPE_RN, I0); break;
7186 I0: po_imm_or_fail (0, 0, FALSE); break;
a737bd4d 7187
c19d1205
ZW
7188 case OP_RF_IF: po_reg_or_goto (REG_TYPE_FN, IF); break;
7189 IF:
7190 if (!is_immediate_prefix (*str))
7191 goto bad_args;
7192 str++;
7193 val = parse_fpa_immediate (&str);
7194 if (val == FAIL)
7195 goto failure;
7196 /* FPA immediates are encoded as registers 8-15.
7197 parse_fpa_immediate has already applied the offset. */
7198 inst.operands[i].reg = val;
7199 inst.operands[i].isreg = 1;
7200 break;
09d92015 7201
2d447fca
JM
7202 case OP_RIWR_I32z: po_reg_or_goto (REG_TYPE_MMXWR, I32z); break;
7203 I32z: po_imm_or_fail (0, 32, FALSE); break;
7204
e07e6e58 7205 /* Two kinds of register. */
c19d1205
ZW
7206 case OP_RIWR_RIWC:
7207 {
7208 struct reg_entry *rege = arm_reg_parse_multi (&str);
97f87066
JM
7209 if (!rege
7210 || (rege->type != REG_TYPE_MMXWR
7211 && rege->type != REG_TYPE_MMXWC
7212 && rege->type != REG_TYPE_MMXWCG))
c19d1205
ZW
7213 {
7214 inst.error = _("iWMMXt data or control register expected");
7215 goto failure;
7216 }
7217 inst.operands[i].reg = rege->number;
7218 inst.operands[i].isreg = (rege->type == REG_TYPE_MMXWR);
7219 }
7220 break;
09d92015 7221
41adaa5c
JM
7222 case OP_RIWC_RIWG:
7223 {
7224 struct reg_entry *rege = arm_reg_parse_multi (&str);
7225 if (!rege
7226 || (rege->type != REG_TYPE_MMXWC
7227 && rege->type != REG_TYPE_MMXWCG))
7228 {
7229 inst.error = _("iWMMXt control register expected");
7230 goto failure;
7231 }
7232 inst.operands[i].reg = rege->number;
7233 inst.operands[i].isreg = 1;
7234 }
7235 break;
7236
c19d1205
ZW
7237 /* Misc */
7238 case OP_CPSF: val = parse_cps_flags (&str); break;
7239 case OP_ENDI: val = parse_endian_specifier (&str); break;
7240 case OP_oROR: val = parse_ror (&str); break;
c19d1205 7241 case OP_COND: val = parse_cond (&str); break;
52e7f43d
RE
7242 case OP_oBARRIER_I15:
7243 po_barrier_or_imm (str); break;
7244 immediate:
7245 if (parse_immediate (&str, &val, 0, 15, TRUE) == FAIL)
477330fc 7246 goto failure;
52e7f43d 7247 break;
c19d1205 7248
fa94de6b 7249 case OP_wPSR:
d2cd1205 7250 case OP_rPSR:
90ec0d68
MGD
7251 po_reg_or_goto (REG_TYPE_RNB, try_psr);
7252 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_virt))
7253 {
7254 inst.error = _("Banked registers are not available with this "
7255 "architecture.");
7256 goto failure;
7257 }
7258 break;
d2cd1205
JB
7259 try_psr:
7260 val = parse_psr (&str, op_parse_code == OP_wPSR);
7261 break;
037e8744 7262
32c36c3c
AV
7263 case OP_VLDR:
7264 po_reg_or_goto (REG_TYPE_VFSD, try_sysreg);
7265 break;
7266 try_sysreg:
7267 val = parse_sys_vldr_vstr (&str);
7268 break;
7269
477330fc
RM
7270 case OP_APSR_RR:
7271 po_reg_or_goto (REG_TYPE_RN, try_apsr);
7272 break;
7273 try_apsr:
7274 /* Parse "APSR_nvzc" operand (for FMSTAT-equivalent MRS
7275 instruction). */
7276 if (strncasecmp (str, "APSR_", 5) == 0)
7277 {
7278 unsigned found = 0;
7279 str += 5;
7280 while (found < 15)
7281 switch (*str++)
7282 {
7283 case 'c': found = (found & 1) ? 16 : found | 1; break;
7284 case 'n': found = (found & 2) ? 16 : found | 2; break;
7285 case 'z': found = (found & 4) ? 16 : found | 4; break;
7286 case 'v': found = (found & 8) ? 16 : found | 8; break;
7287 default: found = 16;
7288 }
7289 if (found != 15)
7290 goto failure;
7291 inst.operands[i].isvec = 1;
f7c21dc7
NC
7292 /* APSR_nzcv is encoded in instructions as if it were the REG_PC. */
7293 inst.operands[i].reg = REG_PC;
477330fc
RM
7294 }
7295 else
7296 goto failure;
7297 break;
037e8744 7298
92e90b6e
PB
7299 case OP_TB:
7300 po_misc_or_fail (parse_tb (&str));
7301 break;
7302
e07e6e58 7303 /* Register lists. */
c19d1205 7304 case OP_REGLST:
4b5a202f 7305 val = parse_reg_list (&str, REGLIST_RN);
c19d1205
ZW
7306 if (*str == '^')
7307 {
5e0d7f77 7308 inst.operands[i].writeback = 1;
c19d1205
ZW
7309 str++;
7310 }
7311 break;
09d92015 7312
4b5a202f
AV
7313 case OP_CLRMLST:
7314 val = parse_reg_list (&str, REGLIST_CLRM);
7315 break;
7316
c19d1205 7317 case OP_VRSLST:
efd6b359
AV
7318 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_S,
7319 &partial_match);
c19d1205 7320 break;
09d92015 7321
c19d1205 7322 case OP_VRDLST:
efd6b359
AV
7323 val = parse_vfp_reg_list (&str, &inst.operands[i].reg, REGLIST_VFP_D,
7324 &partial_match);
c19d1205 7325 break;
a737bd4d 7326
477330fc
RM
7327 case OP_VRSDLST:
7328 /* Allow Q registers too. */
7329 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7330 REGLIST_NEON_D, &partial_match);
477330fc
RM
7331 if (val == FAIL)
7332 {
7333 inst.error = NULL;
7334 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359
AV
7335 REGLIST_VFP_S, &partial_match);
7336 inst.operands[i].issingle = 1;
7337 }
7338 break;
7339
7340 case OP_VRSDVLST:
7341 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7342 REGLIST_VFP_D_VPR, &partial_match);
7343 if (val == FAIL && !partial_match)
7344 {
7345 inst.error = NULL;
7346 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
7347 REGLIST_VFP_S_VPR, &partial_match);
477330fc
RM
7348 inst.operands[i].issingle = 1;
7349 }
7350 break;
7351
7352 case OP_NRDLST:
7353 val = parse_vfp_reg_list (&str, &inst.operands[i].reg,
efd6b359 7354 REGLIST_NEON_D, &partial_match);
477330fc 7355 break;
5287ad62
JB
7356
7357 case OP_NSTRLST:
477330fc
RM
7358 val = parse_neon_el_struct_list (&str, &inst.operands[i].reg,
7359 &inst.operands[i].vectype);
7360 break;
5287ad62 7361
c19d1205
ZW
7362 /* Addressing modes */
7363 case OP_ADDR:
7364 po_misc_or_fail (parse_address (&str, i));
7365 break;
09d92015 7366
4962c51a
MS
7367 case OP_ADDRGLDR:
7368 po_misc_or_fail_no_backtrack (
477330fc 7369 parse_address_group_reloc (&str, i, GROUP_LDR));
4962c51a
MS
7370 break;
7371
7372 case OP_ADDRGLDRS:
7373 po_misc_or_fail_no_backtrack (
477330fc 7374 parse_address_group_reloc (&str, i, GROUP_LDRS));
4962c51a
MS
7375 break;
7376
7377 case OP_ADDRGLDC:
7378 po_misc_or_fail_no_backtrack (
477330fc 7379 parse_address_group_reloc (&str, i, GROUP_LDC));
4962c51a
MS
7380 break;
7381
c19d1205
ZW
7382 case OP_SH:
7383 po_misc_or_fail (parse_shifter_operand (&str, i));
7384 break;
09d92015 7385
4962c51a
MS
7386 case OP_SHG:
7387 po_misc_or_fail_no_backtrack (
477330fc 7388 parse_shifter_operand_group_reloc (&str, i));
4962c51a
MS
7389 break;
7390
c19d1205
ZW
7391 case OP_oSHll:
7392 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_IMMEDIATE));
7393 break;
09d92015 7394
c19d1205
ZW
7395 case OP_oSHar:
7396 po_misc_or_fail (parse_shift (&str, i, SHIFT_ASR_IMMEDIATE));
7397 break;
09d92015 7398
c19d1205
ZW
7399 case OP_oSHllar:
7400 po_misc_or_fail (parse_shift (&str, i, SHIFT_LSL_OR_ASR_IMMEDIATE));
7401 break;
09d92015 7402
c19d1205 7403 default:
5be8be5d 7404 as_fatal (_("unhandled operand code %d"), op_parse_code);
c19d1205 7405 }
09d92015 7406
c19d1205
ZW
7407 /* Various value-based sanity checks and shared operations. We
7408 do not signal immediate failures for the register constraints;
7409 this allows a syntax error to take precedence. */
5be8be5d 7410 switch (op_parse_code)
c19d1205
ZW
7411 {
7412 case OP_oRRnpc:
7413 case OP_RRnpc:
7414 case OP_RRnpcb:
7415 case OP_RRw:
b6702015 7416 case OP_oRRw:
c19d1205
ZW
7417 case OP_RRnpc_I0:
7418 if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
7419 inst.error = BAD_PC;
7420 break;
09d92015 7421
5be8be5d
DG
7422 case OP_oRRnpcsp:
7423 case OP_RRnpcsp:
7424 if (inst.operands[i].isreg)
7425 {
7426 if (inst.operands[i].reg == REG_PC)
7427 inst.error = BAD_PC;
5c8ed6a4
JW
7428 else if (inst.operands[i].reg == REG_SP
7429 /* The restriction on Rd/Rt/Rt2 on Thumb mode has been
7430 relaxed since ARMv8-A. */
7431 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
7432 {
7433 gas_assert (thumb);
7434 inst.error = BAD_SP;
7435 }
5be8be5d
DG
7436 }
7437 break;
7438
55881a11 7439 case OP_RRnpctw:
fa94de6b
RM
7440 if (inst.operands[i].isreg
7441 && inst.operands[i].reg == REG_PC
55881a11
MGD
7442 && (inst.operands[i].writeback || thumb))
7443 inst.error = BAD_PC;
7444 break;
7445
32c36c3c
AV
7446 case OP_VLDR:
7447 if (inst.operands[i].isreg)
7448 break;
7449 /* fall through. */
c19d1205
ZW
7450 case OP_CPSF:
7451 case OP_ENDI:
7452 case OP_oROR:
d2cd1205
JB
7453 case OP_wPSR:
7454 case OP_rPSR:
c19d1205 7455 case OP_COND:
52e7f43d 7456 case OP_oBARRIER_I15:
c19d1205 7457 case OP_REGLST:
4b5a202f 7458 case OP_CLRMLST:
c19d1205
ZW
7459 case OP_VRSLST:
7460 case OP_VRDLST:
477330fc 7461 case OP_VRSDLST:
efd6b359 7462 case OP_VRSDVLST:
477330fc
RM
7463 case OP_NRDLST:
7464 case OP_NSTRLST:
c19d1205
ZW
7465 if (val == FAIL)
7466 goto failure;
7467 inst.operands[i].imm = val;
7468 break;
a737bd4d 7469
60f993ce
AV
7470 case OP_LR:
7471 case OP_oLR:
7472 if (inst.operands[i].reg != REG_LR)
7473 inst.error = _("operand must be LR register");
7474 break;
7475
c19d1205
ZW
7476 default:
7477 break;
7478 }
09d92015 7479
c19d1205
ZW
7480 /* If we get here, this operand was successfully parsed. */
7481 inst.operands[i].present = 1;
7482 continue;
09d92015 7483
c19d1205 7484 bad_args:
09d92015 7485 inst.error = BAD_ARGS;
c19d1205
ZW
7486
7487 failure:
7488 if (!backtrack_pos)
d252fdde
PB
7489 {
7490 /* The parse routine should already have set inst.error, but set a
5f4273c7 7491 default here just in case. */
d252fdde
PB
7492 if (!inst.error)
7493 inst.error = _("syntax error");
7494 return FAIL;
7495 }
c19d1205
ZW
7496
7497 /* Do not backtrack over a trailing optional argument that
7498 absorbed some text. We will only fail again, with the
7499 'garbage following instruction' error message, which is
7500 probably less helpful than the current one. */
7501 if (backtrack_index == i && backtrack_pos != str
7502 && upat[i+1] == OP_stop)
d252fdde
PB
7503 {
7504 if (!inst.error)
7505 inst.error = _("syntax error");
7506 return FAIL;
7507 }
c19d1205
ZW
7508
7509 /* Try again, skipping the optional argument at backtrack_pos. */
7510 str = backtrack_pos;
7511 inst.error = backtrack_error;
7512 inst.operands[backtrack_index].present = 0;
7513 i = backtrack_index;
7514 backtrack_pos = 0;
09d92015 7515 }
09d92015 7516
c19d1205
ZW
7517 /* Check that we have parsed all the arguments. */
7518 if (*str != '\0' && !inst.error)
7519 inst.error = _("garbage following instruction");
09d92015 7520
c19d1205 7521 return inst.error ? FAIL : SUCCESS;
09d92015
MM
7522}
7523
c19d1205
ZW
7524#undef po_char_or_fail
7525#undef po_reg_or_fail
7526#undef po_reg_or_goto
7527#undef po_imm_or_fail
5287ad62 7528#undef po_scalar_or_fail
52e7f43d 7529#undef po_barrier_or_imm
e07e6e58 7530
c19d1205 7531/* Shorthand macro for instruction encoding functions issuing errors. */
e07e6e58
NC
7532#define constraint(expr, err) \
7533 do \
c19d1205 7534 { \
e07e6e58
NC
7535 if (expr) \
7536 { \
7537 inst.error = err; \
7538 return; \
7539 } \
c19d1205 7540 } \
e07e6e58 7541 while (0)
c19d1205 7542
fdfde340
JM
7543/* Reject "bad registers" for Thumb-2 instructions. Many Thumb-2
7544 instructions are unpredictable if these registers are used. This
5c8ed6a4
JW
7545 is the BadReg predicate in ARM's Thumb-2 documentation.
7546
7547 Before ARMv8-A, REG_PC and REG_SP were not allowed in quite a few
7548 places, while the restriction on REG_SP was relaxed since ARMv8-A. */
7549#define reject_bad_reg(reg) \
7550 do \
7551 if (reg == REG_PC) \
7552 { \
7553 inst.error = BAD_PC; \
7554 return; \
7555 } \
7556 else if (reg == REG_SP \
7557 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)) \
7558 { \
7559 inst.error = BAD_SP; \
7560 return; \
7561 } \
fdfde340
JM
7562 while (0)
7563
94206790
MM
7564/* If REG is R13 (the stack pointer), warn that its use is
7565 deprecated. */
7566#define warn_deprecated_sp(reg) \
7567 do \
7568 if (warn_on_deprecated && reg == REG_SP) \
5c3696f8 7569 as_tsktsk (_("use of r13 is deprecated")); \
94206790
MM
7570 while (0)
7571
c19d1205
ZW
7572/* Functions for operand encoding. ARM, then Thumb. */
7573
d840c081 7574#define rotate_left(v, n) (v << (n & 31) | v >> ((32 - n) & 31))
c19d1205 7575
9db2f6b4
RL
7576/* If the current inst is scalar ARMv8.2 fp16 instruction, do special encoding.
7577
7578 The only binary encoding difference is the Coprocessor number. Coprocessor
7579 9 is used for half-precision calculations or conversions. The format of the
2b0f3761 7580 instruction is the same as the equivalent Coprocessor 10 instruction that
9db2f6b4
RL
7581 exists for Single-Precision operation. */
7582
7583static void
7584do_scalar_fp16_v82_encode (void)
7585{
7586 if (inst.cond != COND_ALWAYS)
7587 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
7588 " the behaviour is UNPREDICTABLE"));
7589 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
7590 _(BAD_FP16));
7591
7592 inst.instruction = (inst.instruction & 0xfffff0ff) | 0x900;
7593 mark_feature_used (&arm_ext_fp16);
7594}
7595
c19d1205
ZW
7596/* If VAL can be encoded in the immediate field of an ARM instruction,
7597 return the encoded form. Otherwise, return FAIL. */
7598
7599static unsigned int
7600encode_arm_immediate (unsigned int val)
09d92015 7601{
c19d1205
ZW
7602 unsigned int a, i;
7603
4f1d6205
L
7604 if (val <= 0xff)
7605 return val;
7606
7607 for (i = 2; i < 32; i += 2)
c19d1205
ZW
7608 if ((a = rotate_left (val, i)) <= 0xff)
7609 return a | (i << 7); /* 12-bit pack: [shift-cnt,const]. */
7610
7611 return FAIL;
09d92015
MM
7612}
7613
c19d1205
ZW
7614/* If VAL can be encoded in the immediate field of a Thumb32 instruction,
7615 return the encoded form. Otherwise, return FAIL. */
7616static unsigned int
7617encode_thumb32_immediate (unsigned int val)
09d92015 7618{
c19d1205 7619 unsigned int a, i;
09d92015 7620
9c3c69f2 7621 if (val <= 0xff)
c19d1205 7622 return val;
a737bd4d 7623
9c3c69f2 7624 for (i = 1; i <= 24; i++)
09d92015 7625 {
9c3c69f2
PB
7626 a = val >> i;
7627 if ((val & ~(0xff << i)) == 0)
7628 return ((val >> i) & 0x7f) | ((32 - i) << 7);
09d92015 7629 }
a737bd4d 7630
c19d1205
ZW
7631 a = val & 0xff;
7632 if (val == ((a << 16) | a))
7633 return 0x100 | a;
7634 if (val == ((a << 24) | (a << 16) | (a << 8) | a))
7635 return 0x300 | a;
09d92015 7636
c19d1205
ZW
7637 a = val & 0xff00;
7638 if (val == ((a << 16) | a))
7639 return 0x200 | (a >> 8);
a737bd4d 7640
c19d1205 7641 return FAIL;
09d92015 7642}
5287ad62 7643/* Encode a VFP SP or DP register number into inst.instruction. */
09d92015
MM
7644
7645static void
5287ad62
JB
7646encode_arm_vfp_reg (int reg, enum vfp_reg_pos pos)
7647{
7648 if ((pos == VFP_REG_Dd || pos == VFP_REG_Dn || pos == VFP_REG_Dm)
7649 && reg > 15)
7650 {
b1cc4aeb 7651 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_d32))
477330fc
RM
7652 {
7653 if (thumb_mode)
7654 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
7655 fpu_vfp_ext_d32);
7656 else
7657 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
7658 fpu_vfp_ext_d32);
7659 }
5287ad62 7660 else
477330fc
RM
7661 {
7662 first_error (_("D register out of range for selected VFP version"));
7663 return;
7664 }
5287ad62
JB
7665 }
7666
c19d1205 7667 switch (pos)
09d92015 7668 {
c19d1205
ZW
7669 case VFP_REG_Sd:
7670 inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
7671 break;
7672
7673 case VFP_REG_Sn:
7674 inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
7675 break;
7676
7677 case VFP_REG_Sm:
7678 inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
7679 break;
7680
5287ad62
JB
7681 case VFP_REG_Dd:
7682 inst.instruction |= ((reg & 15) << 12) | ((reg >> 4) << 22);
7683 break;
5f4273c7 7684
5287ad62
JB
7685 case VFP_REG_Dn:
7686 inst.instruction |= ((reg & 15) << 16) | ((reg >> 4) << 7);
7687 break;
5f4273c7 7688
5287ad62
JB
7689 case VFP_REG_Dm:
7690 inst.instruction |= (reg & 15) | ((reg >> 4) << 5);
7691 break;
7692
c19d1205
ZW
7693 default:
7694 abort ();
09d92015 7695 }
09d92015
MM
7696}
7697
c19d1205 7698/* Encode a <shift> in an ARM-format instruction. The immediate,
55cf6793 7699 if any, is handled by md_apply_fix. */
09d92015 7700static void
c19d1205 7701encode_arm_shift (int i)
09d92015 7702{
008a97ef
RL
7703 /* register-shifted register. */
7704 if (inst.operands[i].immisreg)
7705 {
bf355b69
MR
7706 int op_index;
7707 for (op_index = 0; op_index <= i; ++op_index)
008a97ef 7708 {
5689c942
RL
7709 /* Check the operand only when it's presented. In pre-UAL syntax,
7710 if the destination register is the same as the first operand, two
7711 register form of the instruction can be used. */
bf355b69
MR
7712 if (inst.operands[op_index].present && inst.operands[op_index].isreg
7713 && inst.operands[op_index].reg == REG_PC)
008a97ef
RL
7714 as_warn (UNPRED_REG ("r15"));
7715 }
7716
7717 if (inst.operands[i].imm == REG_PC)
7718 as_warn (UNPRED_REG ("r15"));
7719 }
7720
c19d1205
ZW
7721 if (inst.operands[i].shift_kind == SHIFT_RRX)
7722 inst.instruction |= SHIFT_ROR << 5;
7723 else
09d92015 7724 {
c19d1205
ZW
7725 inst.instruction |= inst.operands[i].shift_kind << 5;
7726 if (inst.operands[i].immisreg)
7727 {
7728 inst.instruction |= SHIFT_BY_REG;
7729 inst.instruction |= inst.operands[i].imm << 8;
7730 }
7731 else
e2b0ab59 7732 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
09d92015 7733 }
c19d1205 7734}
09d92015 7735
c19d1205
ZW
7736static void
7737encode_arm_shifter_operand (int i)
7738{
7739 if (inst.operands[i].isreg)
09d92015 7740 {
c19d1205
ZW
7741 inst.instruction |= inst.operands[i].reg;
7742 encode_arm_shift (i);
09d92015 7743 }
c19d1205 7744 else
a415b1cd
JB
7745 {
7746 inst.instruction |= INST_IMMEDIATE;
e2b0ab59 7747 if (inst.relocs[0].type != BFD_RELOC_ARM_IMMEDIATE)
a415b1cd
JB
7748 inst.instruction |= inst.operands[i].imm;
7749 }
09d92015
MM
7750}
7751
c19d1205 7752/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3. */
09d92015 7753static void
c19d1205 7754encode_arm_addr_mode_common (int i, bfd_boolean is_t)
09d92015 7755{
2b2f5df9
NC
7756 /* PR 14260:
7757 Generate an error if the operand is not a register. */
7758 constraint (!inst.operands[i].isreg,
7759 _("Instruction does not support =N addresses"));
7760
c19d1205 7761 inst.instruction |= inst.operands[i].reg << 16;
a737bd4d 7762
c19d1205 7763 if (inst.operands[i].preind)
09d92015 7764 {
c19d1205
ZW
7765 if (is_t)
7766 {
7767 inst.error = _("instruction does not accept preindexed addressing");
7768 return;
7769 }
7770 inst.instruction |= PRE_INDEX;
7771 if (inst.operands[i].writeback)
7772 inst.instruction |= WRITE_BACK;
09d92015 7773
c19d1205
ZW
7774 }
7775 else if (inst.operands[i].postind)
7776 {
9c2799c2 7777 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
7778 if (is_t)
7779 inst.instruction |= WRITE_BACK;
7780 }
7781 else /* unindexed - only for coprocessor */
09d92015 7782 {
c19d1205 7783 inst.error = _("instruction does not accept unindexed addressing");
09d92015
MM
7784 return;
7785 }
7786
c19d1205
ZW
7787 if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
7788 && (((inst.instruction & 0x000f0000) >> 16)
7789 == ((inst.instruction & 0x0000f000) >> 12)))
7790 as_warn ((inst.instruction & LOAD_BIT)
7791 ? _("destination register same as write-back base")
7792 : _("source register same as write-back base"));
09d92015
MM
7793}
7794
c19d1205
ZW
7795/* inst.operands[i] was set up by parse_address. Encode it into an
7796 ARM-format mode 2 load or store instruction. If is_t is true,
7797 reject forms that cannot be used with a T instruction (i.e. not
7798 post-indexed). */
a737bd4d 7799static void
c19d1205 7800encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
09d92015 7801{
5be8be5d
DG
7802 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
7803
c19d1205 7804 encode_arm_addr_mode_common (i, is_t);
a737bd4d 7805
c19d1205 7806 if (inst.operands[i].immisreg)
09d92015 7807 {
5be8be5d
DG
7808 constraint ((inst.operands[i].imm == REG_PC
7809 || (is_pc && inst.operands[i].writeback)),
7810 BAD_PC_ADDRESSING);
c19d1205
ZW
7811 inst.instruction |= INST_IMMEDIATE; /* yes, this is backwards */
7812 inst.instruction |= inst.operands[i].imm;
7813 if (!inst.operands[i].negative)
7814 inst.instruction |= INDEX_UP;
7815 if (inst.operands[i].shifted)
7816 {
7817 if (inst.operands[i].shift_kind == SHIFT_RRX)
7818 inst.instruction |= SHIFT_ROR << 5;
7819 else
7820 {
7821 inst.instruction |= inst.operands[i].shift_kind << 5;
e2b0ab59 7822 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
c19d1205
ZW
7823 }
7824 }
09d92015 7825 }
e2b0ab59 7826 else /* immediate offset in inst.relocs[0] */
09d92015 7827 {
e2b0ab59 7828 if (is_pc && !inst.relocs[0].pc_rel)
5be8be5d
DG
7829 {
7830 const bfd_boolean is_load = ((inst.instruction & LOAD_BIT) != 0);
23a10334
JZ
7831
7832 /* If is_t is TRUE, it's called from do_ldstt. ldrt/strt
7833 cannot use PC in addressing.
7834 PC cannot be used in writeback addressing, either. */
7835 constraint ((is_t || inst.operands[i].writeback),
5be8be5d 7836 BAD_PC_ADDRESSING);
23a10334 7837
dc5ec521 7838 /* Use of PC in str is deprecated for ARMv7. */
23a10334
JZ
7839 if (warn_on_deprecated
7840 && !is_load
7841 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
5c3696f8 7842 as_tsktsk (_("use of PC in this instruction is deprecated"));
5be8be5d
DG
7843 }
7844
e2b0ab59 7845 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
7846 {
7847 /* Prefer + for zero encoded value. */
7848 if (!inst.operands[i].negative)
7849 inst.instruction |= INDEX_UP;
e2b0ab59 7850 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM;
26d97720 7851 }
09d92015 7852 }
09d92015
MM
7853}
7854
c19d1205
ZW
7855/* inst.operands[i] was set up by parse_address. Encode it into an
7856 ARM-format mode 3 load or store instruction. Reject forms that
7857 cannot be used with such instructions. If is_t is true, reject
7858 forms that cannot be used with a T instruction (i.e. not
7859 post-indexed). */
7860static void
7861encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
09d92015 7862{
c19d1205 7863 if (inst.operands[i].immisreg && inst.operands[i].shifted)
09d92015 7864 {
c19d1205
ZW
7865 inst.error = _("instruction does not accept scaled register index");
7866 return;
09d92015 7867 }
a737bd4d 7868
c19d1205 7869 encode_arm_addr_mode_common (i, is_t);
a737bd4d 7870
c19d1205
ZW
7871 if (inst.operands[i].immisreg)
7872 {
5be8be5d 7873 constraint ((inst.operands[i].imm == REG_PC
eb9f3f00 7874 || (is_t && inst.operands[i].reg == REG_PC)),
5be8be5d 7875 BAD_PC_ADDRESSING);
eb9f3f00
JB
7876 constraint (inst.operands[i].reg == REG_PC && inst.operands[i].writeback,
7877 BAD_PC_WRITEBACK);
c19d1205
ZW
7878 inst.instruction |= inst.operands[i].imm;
7879 if (!inst.operands[i].negative)
7880 inst.instruction |= INDEX_UP;
7881 }
e2b0ab59 7882 else /* immediate offset in inst.relocs[0] */
c19d1205 7883 {
e2b0ab59 7884 constraint ((inst.operands[i].reg == REG_PC && !inst.relocs[0].pc_rel
5be8be5d
DG
7885 && inst.operands[i].writeback),
7886 BAD_PC_WRITEBACK);
c19d1205 7887 inst.instruction |= HWOFFSET_IMM;
e2b0ab59 7888 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
26d97720
NS
7889 {
7890 /* Prefer + for zero encoded value. */
7891 if (!inst.operands[i].negative)
7892 inst.instruction |= INDEX_UP;
7893
e2b0ab59 7894 inst.relocs[0].type = BFD_RELOC_ARM_OFFSET_IMM8;
26d97720 7895 }
c19d1205 7896 }
a737bd4d
NC
7897}
7898
8335d6aa
JW
7899/* Write immediate bits [7:0] to the following locations:
7900
7901 |28/24|23 19|18 16|15 4|3 0|
7902 | a |x x x x x|b c d|x x x x x x x x x x x x|e f g h|
7903
7904 This function is used by VMOV/VMVN/VORR/VBIC. */
7905
7906static void
7907neon_write_immbits (unsigned immbits)
7908{
7909 inst.instruction |= immbits & 0xf;
7910 inst.instruction |= ((immbits >> 4) & 0x7) << 16;
7911 inst.instruction |= ((immbits >> 7) & 0x1) << (thumb_mode ? 28 : 24);
7912}
7913
7914/* Invert low-order SIZE bits of XHI:XLO. */
7915
7916static void
7917neon_invert_size (unsigned *xlo, unsigned *xhi, int size)
7918{
7919 unsigned immlo = xlo ? *xlo : 0;
7920 unsigned immhi = xhi ? *xhi : 0;
7921
7922 switch (size)
7923 {
7924 case 8:
7925 immlo = (~immlo) & 0xff;
7926 break;
7927
7928 case 16:
7929 immlo = (~immlo) & 0xffff;
7930 break;
7931
7932 case 64:
7933 immhi = (~immhi) & 0xffffffff;
7934 /* fall through. */
7935
7936 case 32:
7937 immlo = (~immlo) & 0xffffffff;
7938 break;
7939
7940 default:
7941 abort ();
7942 }
7943
7944 if (xlo)
7945 *xlo = immlo;
7946
7947 if (xhi)
7948 *xhi = immhi;
7949}
7950
7951/* True if IMM has form 0bAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD for bits
7952 A, B, C, D. */
09d92015 7953
c19d1205 7954static int
8335d6aa 7955neon_bits_same_in_bytes (unsigned imm)
09d92015 7956{
8335d6aa
JW
7957 return ((imm & 0x000000ff) == 0 || (imm & 0x000000ff) == 0x000000ff)
7958 && ((imm & 0x0000ff00) == 0 || (imm & 0x0000ff00) == 0x0000ff00)
7959 && ((imm & 0x00ff0000) == 0 || (imm & 0x00ff0000) == 0x00ff0000)
7960 && ((imm & 0xff000000) == 0 || (imm & 0xff000000) == 0xff000000);
7961}
a737bd4d 7962
8335d6aa 7963/* For immediate of above form, return 0bABCD. */
09d92015 7964
8335d6aa
JW
7965static unsigned
7966neon_squash_bits (unsigned imm)
7967{
7968 return (imm & 0x01) | ((imm & 0x0100) >> 7) | ((imm & 0x010000) >> 14)
7969 | ((imm & 0x01000000) >> 21);
7970}
7971
7972/* Compress quarter-float representation to 0b...000 abcdefgh. */
7973
7974static unsigned
7975neon_qfloat_bits (unsigned imm)
7976{
7977 return ((imm >> 19) & 0x7f) | ((imm >> 24) & 0x80);
7978}
7979
7980/* Returns CMODE. IMMBITS [7:0] is set to bits suitable for inserting into
7981 the instruction. *OP is passed as the initial value of the op field, and
7982 may be set to a different value depending on the constant (i.e.
7983 "MOV I64, 0bAAAAAAAABBBB..." which uses OP = 1 despite being MOV not
7984 MVN). If the immediate looks like a repeated pattern then also
7985 try smaller element sizes. */
7986
7987static int
7988neon_cmode_for_move_imm (unsigned immlo, unsigned immhi, int float_p,
7989 unsigned *immbits, int *op, int size,
7990 enum neon_el_type type)
7991{
7992 /* Only permit float immediates (including 0.0/-0.0) if the operand type is
7993 float. */
7994 if (type == NT_float && !float_p)
7995 return FAIL;
7996
7997 if (type == NT_float && is_quarter_float (immlo) && immhi == 0)
09d92015 7998 {
8335d6aa
JW
7999 if (size != 32 || *op == 1)
8000 return FAIL;
8001 *immbits = neon_qfloat_bits (immlo);
8002 return 0xf;
8003 }
8004
8005 if (size == 64)
8006 {
8007 if (neon_bits_same_in_bytes (immhi)
8008 && neon_bits_same_in_bytes (immlo))
c19d1205 8009 {
8335d6aa
JW
8010 if (*op == 1)
8011 return FAIL;
8012 *immbits = (neon_squash_bits (immhi) << 4)
8013 | neon_squash_bits (immlo);
8014 *op = 1;
8015 return 0xe;
c19d1205 8016 }
a737bd4d 8017
8335d6aa
JW
8018 if (immhi != immlo)
8019 return FAIL;
8020 }
a737bd4d 8021
8335d6aa 8022 if (size >= 32)
09d92015 8023 {
8335d6aa 8024 if (immlo == (immlo & 0x000000ff))
c19d1205 8025 {
8335d6aa
JW
8026 *immbits = immlo;
8027 return 0x0;
c19d1205 8028 }
8335d6aa 8029 else if (immlo == (immlo & 0x0000ff00))
c19d1205 8030 {
8335d6aa
JW
8031 *immbits = immlo >> 8;
8032 return 0x2;
c19d1205 8033 }
8335d6aa
JW
8034 else if (immlo == (immlo & 0x00ff0000))
8035 {
8036 *immbits = immlo >> 16;
8037 return 0x4;
8038 }
8039 else if (immlo == (immlo & 0xff000000))
8040 {
8041 *immbits = immlo >> 24;
8042 return 0x6;
8043 }
8044 else if (immlo == ((immlo & 0x0000ff00) | 0x000000ff))
8045 {
8046 *immbits = (immlo >> 8) & 0xff;
8047 return 0xc;
8048 }
8049 else if (immlo == ((immlo & 0x00ff0000) | 0x0000ffff))
8050 {
8051 *immbits = (immlo >> 16) & 0xff;
8052 return 0xd;
8053 }
8054
8055 if ((immlo & 0xffff) != (immlo >> 16))
8056 return FAIL;
8057 immlo &= 0xffff;
09d92015 8058 }
a737bd4d 8059
8335d6aa 8060 if (size >= 16)
4962c51a 8061 {
8335d6aa
JW
8062 if (immlo == (immlo & 0x000000ff))
8063 {
8064 *immbits = immlo;
8065 return 0x8;
8066 }
8067 else if (immlo == (immlo & 0x0000ff00))
8068 {
8069 *immbits = immlo >> 8;
8070 return 0xa;
8071 }
8072
8073 if ((immlo & 0xff) != (immlo >> 8))
8074 return FAIL;
8075 immlo &= 0xff;
4962c51a
MS
8076 }
8077
8335d6aa
JW
8078 if (immlo == (immlo & 0x000000ff))
8079 {
8080 /* Don't allow MVN with 8-bit immediate. */
8081 if (*op == 1)
8082 return FAIL;
8083 *immbits = immlo;
8084 return 0xe;
8085 }
26d97720 8086
8335d6aa 8087 return FAIL;
c19d1205 8088}
a737bd4d 8089
5fc177c8 8090#if defined BFD_HOST_64_BIT
ba592044
AM
8091/* Returns TRUE if double precision value V may be cast
8092 to single precision without loss of accuracy. */
8093
8094static bfd_boolean
5fc177c8 8095is_double_a_single (bfd_int64_t v)
ba592044 8096{
5fc177c8 8097 int exp = (int)((v >> 52) & 0x7FF);
8fe3f3d6 8098 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8099
8100 return (exp == 0 || exp == 0x7FF
8101 || (exp >= 1023 - 126 && exp <= 1023 + 127))
8102 && (mantissa & 0x1FFFFFFFl) == 0;
8103}
8104
3739860c 8105/* Returns a double precision value casted to single precision
ba592044
AM
8106 (ignoring the least significant bits in exponent and mantissa). */
8107
8108static int
5fc177c8 8109double_to_single (bfd_int64_t v)
ba592044
AM
8110{
8111 int sign = (int) ((v >> 63) & 1l);
5fc177c8 8112 int exp = (int) ((v >> 52) & 0x7FF);
8fe3f3d6 8113 bfd_int64_t mantissa = (v & (bfd_int64_t)0xFFFFFFFFFFFFFULL);
ba592044
AM
8114
8115 if (exp == 0x7FF)
8116 exp = 0xFF;
8117 else
8118 {
8119 exp = exp - 1023 + 127;
8120 if (exp >= 0xFF)
8121 {
8122 /* Infinity. */
8123 exp = 0x7F;
8124 mantissa = 0;
8125 }
8126 else if (exp < 0)
8127 {
8128 /* No denormalized numbers. */
8129 exp = 0;
8130 mantissa = 0;
8131 }
8132 }
8133 mantissa >>= 29;
8134 return (sign << 31) | (exp << 23) | mantissa;
8135}
5fc177c8 8136#endif /* BFD_HOST_64_BIT */
ba592044 8137
8335d6aa
JW
8138enum lit_type
8139{
8140 CONST_THUMB,
8141 CONST_ARM,
8142 CONST_VEC
8143};
8144
ba592044
AM
8145static void do_vfp_nsyn_opcode (const char *);
8146
e2b0ab59 8147/* inst.relocs[0].exp describes an "=expr" load pseudo-operation.
c19d1205
ZW
8148 Determine whether it can be performed with a move instruction; if
8149 it can, convert inst.instruction to that move instruction and
c921be7d
NC
8150 return TRUE; if it can't, convert inst.instruction to a literal-pool
8151 load and return FALSE. If this is not a valid thing to do in the
8152 current context, set inst.error and return TRUE.
a737bd4d 8153
c19d1205
ZW
8154 inst.operands[i] describes the destination register. */
8155
c921be7d 8156static bfd_boolean
8335d6aa 8157move_or_literal_pool (int i, enum lit_type t, bfd_boolean mode_3)
c19d1205 8158{
53365c0d 8159 unsigned long tbit;
8335d6aa
JW
8160 bfd_boolean thumb_p = (t == CONST_THUMB);
8161 bfd_boolean arm_p = (t == CONST_ARM);
53365c0d
PB
8162
8163 if (thumb_p)
8164 tbit = (inst.instruction > 0xffff) ? THUMB2_LOAD_BIT : THUMB_LOAD_BIT;
8165 else
8166 tbit = LOAD_BIT;
8167
8168 if ((inst.instruction & tbit) == 0)
09d92015 8169 {
c19d1205 8170 inst.error = _("invalid pseudo operation");
c921be7d 8171 return TRUE;
09d92015 8172 }
ba592044 8173
e2b0ab59
AV
8174 if (inst.relocs[0].exp.X_op != O_constant
8175 && inst.relocs[0].exp.X_op != O_symbol
8176 && inst.relocs[0].exp.X_op != O_big)
09d92015
MM
8177 {
8178 inst.error = _("constant expression expected");
c921be7d 8179 return TRUE;
09d92015 8180 }
ba592044 8181
e2b0ab59
AV
8182 if (inst.relocs[0].exp.X_op == O_constant
8183 || inst.relocs[0].exp.X_op == O_big)
8335d6aa 8184 {
5fc177c8
NC
8185#if defined BFD_HOST_64_BIT
8186 bfd_int64_t v;
8187#else
ba592044 8188 offsetT v;
5fc177c8 8189#endif
e2b0ab59 8190 if (inst.relocs[0].exp.X_op == O_big)
8335d6aa 8191 {
ba592044
AM
8192 LITTLENUM_TYPE w[X_PRECISION];
8193 LITTLENUM_TYPE * l;
8194
e2b0ab59 8195 if (inst.relocs[0].exp.X_add_number == -1)
8335d6aa 8196 {
ba592044
AM
8197 gen_to_words (w, X_PRECISION, E_PRECISION);
8198 l = w;
8199 /* FIXME: Should we check words w[2..5] ? */
8335d6aa 8200 }
ba592044
AM
8201 else
8202 l = generic_bignum;
3739860c 8203
5fc177c8
NC
8204#if defined BFD_HOST_64_BIT
8205 v =
8206 ((((((((bfd_int64_t) l[3] & LITTLENUM_MASK)
8207 << LITTLENUM_NUMBER_OF_BITS)
8208 | ((bfd_int64_t) l[2] & LITTLENUM_MASK))
8209 << LITTLENUM_NUMBER_OF_BITS)
8210 | ((bfd_int64_t) l[1] & LITTLENUM_MASK))
8211 << LITTLENUM_NUMBER_OF_BITS)
8212 | ((bfd_int64_t) l[0] & LITTLENUM_MASK));
8213#else
ba592044
AM
8214 v = ((l[1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS)
8215 | (l[0] & LITTLENUM_MASK);
5fc177c8 8216#endif
8335d6aa 8217 }
ba592044 8218 else
e2b0ab59 8219 v = inst.relocs[0].exp.X_add_number;
ba592044
AM
8220
8221 if (!inst.operands[i].issingle)
8335d6aa 8222 {
12569877 8223 if (thumb_p)
8335d6aa 8224 {
53445554
TP
8225 /* LDR should not use lead in a flag-setting instruction being
8226 chosen so we do not check whether movs can be used. */
12569877 8227
53445554 8228 if ((ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
ff8646ee 8229 || ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
53445554
TP
8230 && inst.operands[i].reg != 13
8231 && inst.operands[i].reg != 15)
12569877 8232 {
fc289b0a
TP
8233 /* Check if on thumb2 it can be done with a mov.w, mvn or
8234 movw instruction. */
12569877
AM
8235 unsigned int newimm;
8236 bfd_boolean isNegated;
8237
8238 newimm = encode_thumb32_immediate (v);
8239 if (newimm != (unsigned int) FAIL)
8240 isNegated = FALSE;
8241 else
8242 {
582cfe03 8243 newimm = encode_thumb32_immediate (~v);
12569877
AM
8244 if (newimm != (unsigned int) FAIL)
8245 isNegated = TRUE;
8246 }
8247
fc289b0a
TP
8248 /* The number can be loaded with a mov.w or mvn
8249 instruction. */
ff8646ee
TP
8250 if (newimm != (unsigned int) FAIL
8251 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
12569877 8252 {
fc289b0a 8253 inst.instruction = (0xf04f0000 /* MOV.W. */
582cfe03 8254 | (inst.operands[i].reg << 8));
fc289b0a 8255 /* Change to MOVN. */
582cfe03 8256 inst.instruction |= (isNegated ? 0x200000 : 0);
12569877
AM
8257 inst.instruction |= (newimm & 0x800) << 15;
8258 inst.instruction |= (newimm & 0x700) << 4;
8259 inst.instruction |= (newimm & 0x0ff);
8260 return TRUE;
8261 }
fc289b0a 8262 /* The number can be loaded with a movw instruction. */
ff8646ee
TP
8263 else if ((v & ~0xFFFF) == 0
8264 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m))
3739860c 8265 {
582cfe03 8266 int imm = v & 0xFFFF;
12569877 8267
582cfe03 8268 inst.instruction = 0xf2400000; /* MOVW. */
12569877
AM
8269 inst.instruction |= (inst.operands[i].reg << 8);
8270 inst.instruction |= (imm & 0xf000) << 4;
8271 inst.instruction |= (imm & 0x0800) << 15;
8272 inst.instruction |= (imm & 0x0700) << 4;
8273 inst.instruction |= (imm & 0x00ff);
8274 return TRUE;
8275 }
8276 }
8335d6aa 8277 }
12569877 8278 else if (arm_p)
ba592044
AM
8279 {
8280 int value = encode_arm_immediate (v);
12569877 8281
ba592044
AM
8282 if (value != FAIL)
8283 {
8284 /* This can be done with a mov instruction. */
8285 inst.instruction &= LITERAL_MASK;
8286 inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
8287 inst.instruction |= value & 0xfff;
8288 return TRUE;
8289 }
8335d6aa 8290
ba592044
AM
8291 value = encode_arm_immediate (~ v);
8292 if (value != FAIL)
8293 {
8294 /* This can be done with a mvn instruction. */
8295 inst.instruction &= LITERAL_MASK;
8296 inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
8297 inst.instruction |= value & 0xfff;
8298 return TRUE;
8299 }
8300 }
934c2632 8301 else if (t == CONST_VEC && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1))
8335d6aa 8302 {
ba592044
AM
8303 int op = 0;
8304 unsigned immbits = 0;
8305 unsigned immlo = inst.operands[1].imm;
8306 unsigned immhi = inst.operands[1].regisimm
8307 ? inst.operands[1].reg
e2b0ab59 8308 : inst.relocs[0].exp.X_unsigned
ba592044
AM
8309 ? 0
8310 : ((bfd_int64_t)((int) immlo)) >> 32;
8311 int cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8312 &op, 64, NT_invtype);
8313
8314 if (cmode == FAIL)
8315 {
8316 neon_invert_size (&immlo, &immhi, 64);
8317 op = !op;
8318 cmode = neon_cmode_for_move_imm (immlo, immhi, FALSE, &immbits,
8319 &op, 64, NT_invtype);
8320 }
8321
8322 if (cmode != FAIL)
8323 {
8324 inst.instruction = (inst.instruction & VLDR_VMOV_SAME)
8325 | (1 << 23)
8326 | (cmode << 8)
8327 | (op << 5)
8328 | (1 << 4);
8329
8330 /* Fill other bits in vmov encoding for both thumb and arm. */
8331 if (thumb_mode)
eff0bc54 8332 inst.instruction |= (0x7U << 29) | (0xF << 24);
ba592044 8333 else
eff0bc54 8334 inst.instruction |= (0xFU << 28) | (0x1 << 25);
ba592044
AM
8335 neon_write_immbits (immbits);
8336 return TRUE;
8337 }
8335d6aa
JW
8338 }
8339 }
8335d6aa 8340
ba592044
AM
8341 if (t == CONST_VEC)
8342 {
8343 /* Check if vldr Rx, =constant could be optimized to vmov Rx, #constant. */
8344 if (inst.operands[i].issingle
8345 && is_quarter_float (inst.operands[1].imm)
8346 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3xd))
8335d6aa 8347 {
ba592044
AM
8348 inst.operands[1].imm =
8349 neon_qfloat_bits (v);
8350 do_vfp_nsyn_opcode ("fconsts");
8351 return TRUE;
8335d6aa 8352 }
5fc177c8
NC
8353
8354 /* If our host does not support a 64-bit type then we cannot perform
8355 the following optimization. This mean that there will be a
8356 discrepancy between the output produced by an assembler built for
8357 a 32-bit-only host and the output produced from a 64-bit host, but
8358 this cannot be helped. */
8359#if defined BFD_HOST_64_BIT
ba592044
AM
8360 else if (!inst.operands[1].issingle
8361 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v3))
8335d6aa 8362 {
ba592044
AM
8363 if (is_double_a_single (v)
8364 && is_quarter_float (double_to_single (v)))
8365 {
8366 inst.operands[1].imm =
8367 neon_qfloat_bits (double_to_single (v));
8368 do_vfp_nsyn_opcode ("fconstd");
8369 return TRUE;
8370 }
8335d6aa 8371 }
5fc177c8 8372#endif
8335d6aa
JW
8373 }
8374 }
8375
8376 if (add_to_lit_pool ((!inst.operands[i].isvec
8377 || inst.operands[i].issingle) ? 4 : 8) == FAIL)
8378 return TRUE;
8379
8380 inst.operands[1].reg = REG_PC;
8381 inst.operands[1].isreg = 1;
8382 inst.operands[1].preind = 1;
e2b0ab59
AV
8383 inst.relocs[0].pc_rel = 1;
8384 inst.relocs[0].type = (thumb_p
8335d6aa
JW
8385 ? BFD_RELOC_ARM_THUMB_OFFSET
8386 : (mode_3
8387 ? BFD_RELOC_ARM_HWLITERAL
8388 : BFD_RELOC_ARM_LITERAL));
8389 return FALSE;
8390}
8391
8392/* inst.operands[i] was set up by parse_address. Encode it into an
8393 ARM-format instruction. Reject all forms which cannot be encoded
8394 into a coprocessor load/store instruction. If wb_ok is false,
8395 reject use of writeback; if unind_ok is false, reject use of
8396 unindexed addressing. If reloc_override is not 0, use it instead
8397 of BFD_ARM_CP_OFF_IMM, unless the initial relocation is a group one
8398 (in which case it is preserved). */
8399
8400static int
8401encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
8402{
8403 if (!inst.operands[i].isreg)
8404 {
99b2a2dd
NC
8405 /* PR 18256 */
8406 if (! inst.operands[0].isvec)
8407 {
8408 inst.error = _("invalid co-processor operand");
8409 return FAIL;
8410 }
8335d6aa
JW
8411 if (move_or_literal_pool (0, CONST_VEC, /*mode_3=*/FALSE))
8412 return SUCCESS;
8413 }
8414
8415 inst.instruction |= inst.operands[i].reg << 16;
8416
8417 gas_assert (!(inst.operands[i].preind && inst.operands[i].postind));
8418
8419 if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
8420 {
8421 gas_assert (!inst.operands[i].writeback);
8422 if (!unind_ok)
8423 {
8424 inst.error = _("instruction does not support unindexed addressing");
8425 return FAIL;
8426 }
8427 inst.instruction |= inst.operands[i].imm;
8428 inst.instruction |= INDEX_UP;
8429 return SUCCESS;
8430 }
8431
8432 if (inst.operands[i].preind)
8433 inst.instruction |= PRE_INDEX;
8434
8435 if (inst.operands[i].writeback)
09d92015 8436 {
8335d6aa 8437 if (inst.operands[i].reg == REG_PC)
c19d1205 8438 {
8335d6aa
JW
8439 inst.error = _("pc may not be used with write-back");
8440 return FAIL;
c19d1205 8441 }
8335d6aa 8442 if (!wb_ok)
c19d1205 8443 {
8335d6aa
JW
8444 inst.error = _("instruction does not support writeback");
8445 return FAIL;
c19d1205 8446 }
8335d6aa 8447 inst.instruction |= WRITE_BACK;
09d92015
MM
8448 }
8449
8335d6aa 8450 if (reloc_override)
e2b0ab59
AV
8451 inst.relocs[0].type = (bfd_reloc_code_real_type) reloc_override;
8452 else if ((inst.relocs[0].type < BFD_RELOC_ARM_ALU_PC_G0_NC
8453 || inst.relocs[0].type > BFD_RELOC_ARM_LDC_SB_G2)
8454 && inst.relocs[0].type != BFD_RELOC_ARM_LDR_PC_G0)
c19d1205 8455 {
8335d6aa 8456 if (thumb_mode)
e2b0ab59 8457 inst.relocs[0].type = BFD_RELOC_ARM_T32_CP_OFF_IMM;
8335d6aa 8458 else
e2b0ab59 8459 inst.relocs[0].type = BFD_RELOC_ARM_CP_OFF_IMM;
c19d1205 8460 }
8335d6aa
JW
8461
8462 /* Prefer + for zero encoded value. */
8463 if (!inst.operands[i].negative)
8464 inst.instruction |= INDEX_UP;
8465
8466 return SUCCESS;
09d92015
MM
8467}
8468
5f4273c7 8469/* Functions for instruction encoding, sorted by sub-architecture.
c19d1205
ZW
8470 First some generics; their names are taken from the conventional
8471 bit positions for register arguments in ARM format instructions. */
09d92015 8472
a737bd4d 8473static void
c19d1205 8474do_noargs (void)
09d92015 8475{
c19d1205 8476}
a737bd4d 8477
c19d1205
ZW
8478static void
8479do_rd (void)
8480{
8481 inst.instruction |= inst.operands[0].reg << 12;
8482}
a737bd4d 8483
16a1fa25
TP
8484static void
8485do_rn (void)
8486{
8487 inst.instruction |= inst.operands[0].reg << 16;
8488}
8489
c19d1205
ZW
8490static void
8491do_rd_rm (void)
8492{
8493 inst.instruction |= inst.operands[0].reg << 12;
8494 inst.instruction |= inst.operands[1].reg;
8495}
09d92015 8496
9eb6c0f1
MGD
8497static void
8498do_rm_rn (void)
8499{
8500 inst.instruction |= inst.operands[0].reg;
8501 inst.instruction |= inst.operands[1].reg << 16;
8502}
8503
c19d1205
ZW
8504static void
8505do_rd_rn (void)
8506{
8507 inst.instruction |= inst.operands[0].reg << 12;
8508 inst.instruction |= inst.operands[1].reg << 16;
8509}
a737bd4d 8510
c19d1205
ZW
8511static void
8512do_rn_rd (void)
8513{
8514 inst.instruction |= inst.operands[0].reg << 16;
8515 inst.instruction |= inst.operands[1].reg << 12;
8516}
09d92015 8517
4ed7ed8d
TP
8518static void
8519do_tt (void)
8520{
8521 inst.instruction |= inst.operands[0].reg << 8;
8522 inst.instruction |= inst.operands[1].reg << 16;
8523}
8524
59d09be6
MGD
8525static bfd_boolean
8526check_obsolete (const arm_feature_set *feature, const char *msg)
8527{
8528 if (ARM_CPU_IS_ANY (cpu_variant))
8529 {
5c3696f8 8530 as_tsktsk ("%s", msg);
59d09be6
MGD
8531 return TRUE;
8532 }
8533 else if (ARM_CPU_HAS_FEATURE (cpu_variant, *feature))
8534 {
8535 as_bad ("%s", msg);
8536 return TRUE;
8537 }
8538
8539 return FALSE;
8540}
8541
c19d1205
ZW
8542static void
8543do_rd_rm_rn (void)
8544{
9a64e435 8545 unsigned Rn = inst.operands[2].reg;
708587a4 8546 /* Enforce restrictions on SWP instruction. */
9a64e435 8547 if ((inst.instruction & 0x0fbfffff) == 0x01000090)
56adecf4
DG
8548 {
8549 constraint (Rn == inst.operands[0].reg || Rn == inst.operands[1].reg,
8550 _("Rn must not overlap other operands"));
8551
59d09be6
MGD
8552 /* SWP{b} is obsolete for ARMv8-A, and deprecated for ARMv6* and ARMv7.
8553 */
8554 if (!check_obsolete (&arm_ext_v8,
8555 _("swp{b} use is obsoleted for ARMv8 and later"))
8556 && warn_on_deprecated
8557 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6))
5c3696f8 8558 as_tsktsk (_("swp{b} use is deprecated for ARMv6 and ARMv7"));
56adecf4 8559 }
59d09be6 8560
c19d1205
ZW
8561 inst.instruction |= inst.operands[0].reg << 12;
8562 inst.instruction |= inst.operands[1].reg;
9a64e435 8563 inst.instruction |= Rn << 16;
c19d1205 8564}
09d92015 8565
c19d1205
ZW
8566static void
8567do_rd_rn_rm (void)
8568{
8569 inst.instruction |= inst.operands[0].reg << 12;
8570 inst.instruction |= inst.operands[1].reg << 16;
8571 inst.instruction |= inst.operands[2].reg;
8572}
a737bd4d 8573
c19d1205
ZW
8574static void
8575do_rm_rd_rn (void)
8576{
5be8be5d 8577 constraint ((inst.operands[2].reg == REG_PC), BAD_PC);
e2b0ab59
AV
8578 constraint (((inst.relocs[0].exp.X_op != O_constant
8579 && inst.relocs[0].exp.X_op != O_illegal)
8580 || inst.relocs[0].exp.X_add_number != 0),
5be8be5d 8581 BAD_ADDR_MODE);
c19d1205
ZW
8582 inst.instruction |= inst.operands[0].reg;
8583 inst.instruction |= inst.operands[1].reg << 12;
8584 inst.instruction |= inst.operands[2].reg << 16;
8585}
09d92015 8586
c19d1205
ZW
8587static void
8588do_imm0 (void)
8589{
8590 inst.instruction |= inst.operands[0].imm;
8591}
09d92015 8592
c19d1205
ZW
8593static void
8594do_rd_cpaddr (void)
8595{
8596 inst.instruction |= inst.operands[0].reg << 12;
8597 encode_arm_cp_address (1, TRUE, TRUE, 0);
09d92015 8598}
a737bd4d 8599
c19d1205
ZW
8600/* ARM instructions, in alphabetical order by function name (except
8601 that wrapper functions appear immediately after the function they
8602 wrap). */
09d92015 8603
c19d1205
ZW
8604/* This is a pseudo-op of the form "adr rd, label" to be converted
8605 into a relative address of the form "add rd, pc, #label-.-8". */
09d92015
MM
8606
8607static void
c19d1205 8608do_adr (void)
09d92015 8609{
c19d1205 8610 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 8611
c19d1205
ZW
8612 /* Frag hacking will turn this into a sub instruction if the offset turns
8613 out to be negative. */
e2b0ab59
AV
8614 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
8615 inst.relocs[0].pc_rel = 1;
8616 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 8617
fc6141f0 8618 if (support_interwork
e2b0ab59
AV
8619 && inst.relocs[0].exp.X_op == O_symbol
8620 && inst.relocs[0].exp.X_add_symbol != NULL
8621 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
8622 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
8623 inst.relocs[0].exp.X_add_number |= 1;
c19d1205 8624}
b99bd4ef 8625
c19d1205
ZW
8626/* This is a pseudo-op of the form "adrl rd, label" to be converted
8627 into a relative address of the form:
8628 add rd, pc, #low(label-.-8)"
8629 add rd, rd, #high(label-.-8)" */
b99bd4ef 8630
c19d1205
ZW
8631static void
8632do_adrl (void)
8633{
8634 inst.instruction |= (inst.operands[0].reg << 12); /* Rd */
a737bd4d 8635
c19d1205
ZW
8636 /* Frag hacking will turn this into a sub instruction if the offset turns
8637 out to be negative. */
e2b0ab59
AV
8638 inst.relocs[0].type = BFD_RELOC_ARM_ADRL_IMMEDIATE;
8639 inst.relocs[0].pc_rel = 1;
c19d1205 8640 inst.size = INSN_SIZE * 2;
e2b0ab59 8641 inst.relocs[0].exp.X_add_number -= 8;
52a86f84 8642
fc6141f0 8643 if (support_interwork
e2b0ab59
AV
8644 && inst.relocs[0].exp.X_op == O_symbol
8645 && inst.relocs[0].exp.X_add_symbol != NULL
8646 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
8647 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
8648 inst.relocs[0].exp.X_add_number |= 1;
b99bd4ef
NC
8649}
8650
b99bd4ef 8651static void
c19d1205 8652do_arit (void)
b99bd4ef 8653{
e2b0ab59
AV
8654 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
8655 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 8656 THUMB1_RELOC_ONLY);
c19d1205
ZW
8657 if (!inst.operands[1].present)
8658 inst.operands[1].reg = inst.operands[0].reg;
8659 inst.instruction |= inst.operands[0].reg << 12;
8660 inst.instruction |= inst.operands[1].reg << 16;
8661 encode_arm_shifter_operand (2);
8662}
b99bd4ef 8663
62b3e311
PB
8664static void
8665do_barrier (void)
8666{
8667 if (inst.operands[0].present)
ccb84d65 8668 inst.instruction |= inst.operands[0].imm;
62b3e311
PB
8669 else
8670 inst.instruction |= 0xf;
8671}
8672
c19d1205
ZW
8673static void
8674do_bfc (void)
8675{
8676 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
8677 constraint (msb > 32, _("bit-field extends past end of register"));
8678 /* The instruction encoding stores the LSB and MSB,
8679 not the LSB and width. */
8680 inst.instruction |= inst.operands[0].reg << 12;
8681 inst.instruction |= inst.operands[1].imm << 7;
8682 inst.instruction |= (msb - 1) << 16;
8683}
b99bd4ef 8684
c19d1205
ZW
8685static void
8686do_bfi (void)
8687{
8688 unsigned int msb;
b99bd4ef 8689
c19d1205
ZW
8690 /* #0 in second position is alternative syntax for bfc, which is
8691 the same instruction but with REG_PC in the Rm field. */
8692 if (!inst.operands[1].isreg)
8693 inst.operands[1].reg = REG_PC;
b99bd4ef 8694
c19d1205
ZW
8695 msb = inst.operands[2].imm + inst.operands[3].imm;
8696 constraint (msb > 32, _("bit-field extends past end of register"));
8697 /* The instruction encoding stores the LSB and MSB,
8698 not the LSB and width. */
8699 inst.instruction |= inst.operands[0].reg << 12;
8700 inst.instruction |= inst.operands[1].reg;
8701 inst.instruction |= inst.operands[2].imm << 7;
8702 inst.instruction |= (msb - 1) << 16;
b99bd4ef
NC
8703}
8704
b99bd4ef 8705static void
c19d1205 8706do_bfx (void)
b99bd4ef 8707{
c19d1205
ZW
8708 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
8709 _("bit-field extends past end of register"));
8710 inst.instruction |= inst.operands[0].reg << 12;
8711 inst.instruction |= inst.operands[1].reg;
8712 inst.instruction |= inst.operands[2].imm << 7;
8713 inst.instruction |= (inst.operands[3].imm - 1) << 16;
8714}
09d92015 8715
c19d1205
ZW
8716/* ARM V5 breakpoint instruction (argument parse)
8717 BKPT <16 bit unsigned immediate>
8718 Instruction is not conditional.
8719 The bit pattern given in insns[] has the COND_ALWAYS condition,
8720 and it is an error if the caller tried to override that. */
b99bd4ef 8721
c19d1205
ZW
8722static void
8723do_bkpt (void)
8724{
8725 /* Top 12 of 16 bits to bits 19:8. */
8726 inst.instruction |= (inst.operands[0].imm & 0xfff0) << 4;
09d92015 8727
c19d1205
ZW
8728 /* Bottom 4 of 16 bits to bits 3:0. */
8729 inst.instruction |= inst.operands[0].imm & 0xf;
8730}
09d92015 8731
c19d1205
ZW
8732static void
8733encode_branch (int default_reloc)
8734{
8735 if (inst.operands[0].hasreloc)
8736 {
0855e32b
NS
8737 constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
8738 && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
8739 _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
e2b0ab59 8740 inst.relocs[0].type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
0855e32b
NS
8741 ? BFD_RELOC_ARM_PLT32
8742 : thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
c19d1205 8743 }
b99bd4ef 8744 else
e2b0ab59
AV
8745 inst.relocs[0].type = (bfd_reloc_code_real_type) default_reloc;
8746 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
8747}
8748
b99bd4ef 8749static void
c19d1205 8750do_branch (void)
b99bd4ef 8751{
39b41c9c
PB
8752#ifdef OBJ_ELF
8753 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
8754 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
8755 else
8756#endif
8757 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
8758}
8759
8760static void
8761do_bl (void)
8762{
8763#ifdef OBJ_ELF
8764 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
8765 {
8766 if (inst.cond == COND_ALWAYS)
8767 encode_branch (BFD_RELOC_ARM_PCREL_CALL);
8768 else
8769 encode_branch (BFD_RELOC_ARM_PCREL_JUMP);
8770 }
8771 else
8772#endif
8773 encode_branch (BFD_RELOC_ARM_PCREL_BRANCH);
c19d1205 8774}
b99bd4ef 8775
c19d1205
ZW
8776/* ARM V5 branch-link-exchange instruction (argument parse)
8777 BLX <target_addr> ie BLX(1)
8778 BLX{<condition>} <Rm> ie BLX(2)
8779 Unfortunately, there are two different opcodes for this mnemonic.
8780 So, the insns[].value is not used, and the code here zaps values
8781 into inst.instruction.
8782 Also, the <target_addr> can be 25 bits, hence has its own reloc. */
b99bd4ef 8783
c19d1205
ZW
8784static void
8785do_blx (void)
8786{
8787 if (inst.operands[0].isreg)
b99bd4ef 8788 {
c19d1205
ZW
8789 /* Arg is a register; the opcode provided by insns[] is correct.
8790 It is not illegal to do "blx pc", just useless. */
8791 if (inst.operands[0].reg == REG_PC)
8792 as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
b99bd4ef 8793
c19d1205
ZW
8794 inst.instruction |= inst.operands[0].reg;
8795 }
8796 else
b99bd4ef 8797 {
c19d1205 8798 /* Arg is an address; this instruction cannot be executed
267bf995
RR
8799 conditionally, and the opcode must be adjusted.
8800 We retain the BFD_RELOC_ARM_PCREL_BLX till the very end
8801 where we generate out a BFD_RELOC_ARM_PCREL_CALL instead. */
c19d1205 8802 constraint (inst.cond != COND_ALWAYS, BAD_COND);
2fc8bdac 8803 inst.instruction = 0xfa000000;
267bf995 8804 encode_branch (BFD_RELOC_ARM_PCREL_BLX);
b99bd4ef 8805 }
c19d1205
ZW
8806}
8807
8808static void
8809do_bx (void)
8810{
845b51d6
PB
8811 bfd_boolean want_reloc;
8812
c19d1205
ZW
8813 if (inst.operands[0].reg == REG_PC)
8814 as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
b99bd4ef 8815
c19d1205 8816 inst.instruction |= inst.operands[0].reg;
845b51d6
PB
8817 /* Output R_ARM_V4BX relocations if is an EABI object that looks like
8818 it is for ARMv4t or earlier. */
8819 want_reloc = !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5);
4d354d8b
TP
8820 if (!ARM_FEATURE_ZERO (selected_object_arch)
8821 && !ARM_CPU_HAS_FEATURE (selected_object_arch, arm_ext_v5))
845b51d6
PB
8822 want_reloc = TRUE;
8823
5ad34203 8824#ifdef OBJ_ELF
845b51d6 8825 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
5ad34203 8826#endif
584206db 8827 want_reloc = FALSE;
845b51d6
PB
8828
8829 if (want_reloc)
e2b0ab59 8830 inst.relocs[0].type = BFD_RELOC_ARM_V4BX;
09d92015
MM
8831}
8832
c19d1205
ZW
8833
8834/* ARM v5TEJ. Jump to Jazelle code. */
a737bd4d
NC
8835
8836static void
c19d1205 8837do_bxj (void)
a737bd4d 8838{
c19d1205
ZW
8839 if (inst.operands[0].reg == REG_PC)
8840 as_tsktsk (_("use of r15 in bxj is not really useful"));
8841
8842 inst.instruction |= inst.operands[0].reg;
a737bd4d
NC
8843}
8844
c19d1205
ZW
8845/* Co-processor data operation:
8846 CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
8847 CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>} */
8848static void
8849do_cdp (void)
8850{
8851 inst.instruction |= inst.operands[0].reg << 8;
8852 inst.instruction |= inst.operands[1].imm << 20;
8853 inst.instruction |= inst.operands[2].reg << 12;
8854 inst.instruction |= inst.operands[3].reg << 16;
8855 inst.instruction |= inst.operands[4].reg;
8856 inst.instruction |= inst.operands[5].imm << 5;
8857}
a737bd4d
NC
8858
8859static void
c19d1205 8860do_cmp (void)
a737bd4d 8861{
c19d1205
ZW
8862 inst.instruction |= inst.operands[0].reg << 16;
8863 encode_arm_shifter_operand (1);
a737bd4d
NC
8864}
8865
c19d1205
ZW
8866/* Transfer between coprocessor and ARM registers.
8867 MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
8868 MRC2
8869 MCR{cond}
8870 MCR2
8871
8872 No special properties. */
09d92015 8873
dcbd0d71
MGD
8874struct deprecated_coproc_regs_s
8875{
8876 unsigned cp;
8877 int opc1;
8878 unsigned crn;
8879 unsigned crm;
8880 int opc2;
8881 arm_feature_set deprecated;
8882 arm_feature_set obsoleted;
8883 const char *dep_msg;
8884 const char *obs_msg;
8885};
8886
8887#define DEPR_ACCESS_V8 \
8888 N_("This coprocessor register access is deprecated in ARMv8")
8889
8890/* Table of all deprecated coprocessor registers. */
8891static struct deprecated_coproc_regs_s deprecated_coproc_regs[] =
8892{
8893 {15, 0, 7, 10, 5, /* CP15DMB. */
823d2571 8894 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8895 DEPR_ACCESS_V8, NULL},
8896 {15, 0, 7, 10, 4, /* CP15DSB. */
823d2571 8897 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8898 DEPR_ACCESS_V8, NULL},
8899 {15, 0, 7, 5, 4, /* CP15ISB. */
823d2571 8900 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8901 DEPR_ACCESS_V8, NULL},
8902 {14, 6, 1, 0, 0, /* TEEHBR. */
823d2571 8903 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8904 DEPR_ACCESS_V8, NULL},
8905 {14, 6, 0, 0, 0, /* TEECR. */
823d2571 8906 ARM_FEATURE_CORE_LOW (ARM_EXT_V8), ARM_ARCH_NONE,
dcbd0d71
MGD
8907 DEPR_ACCESS_V8, NULL},
8908};
8909
8910#undef DEPR_ACCESS_V8
8911
8912static const size_t deprecated_coproc_reg_count =
8913 sizeof (deprecated_coproc_regs) / sizeof (deprecated_coproc_regs[0]);
8914
09d92015 8915static void
c19d1205 8916do_co_reg (void)
09d92015 8917{
fdfde340 8918 unsigned Rd;
dcbd0d71 8919 size_t i;
fdfde340
JM
8920
8921 Rd = inst.operands[2].reg;
8922 if (thumb_mode)
8923 {
8924 if (inst.instruction == 0xee000010
8925 || inst.instruction == 0xfe000010)
8926 /* MCR, MCR2 */
8927 reject_bad_reg (Rd);
5c8ed6a4 8928 else if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
fdfde340
JM
8929 /* MRC, MRC2 */
8930 constraint (Rd == REG_SP, BAD_SP);
8931 }
8932 else
8933 {
8934 /* MCR */
8935 if (inst.instruction == 0xe000010)
8936 constraint (Rd == REG_PC, BAD_PC);
8937 }
8938
dcbd0d71
MGD
8939 for (i = 0; i < deprecated_coproc_reg_count; ++i)
8940 {
8941 const struct deprecated_coproc_regs_s *r =
8942 deprecated_coproc_regs + i;
8943
8944 if (inst.operands[0].reg == r->cp
8945 && inst.operands[1].imm == r->opc1
8946 && inst.operands[3].reg == r->crn
8947 && inst.operands[4].reg == r->crm
8948 && inst.operands[5].imm == r->opc2)
8949 {
b10bf8c5 8950 if (! ARM_CPU_IS_ANY (cpu_variant)
477330fc 8951 && warn_on_deprecated
dcbd0d71 8952 && ARM_CPU_HAS_FEATURE (cpu_variant, r->deprecated))
5c3696f8 8953 as_tsktsk ("%s", r->dep_msg);
dcbd0d71
MGD
8954 }
8955 }
fdfde340 8956
c19d1205
ZW
8957 inst.instruction |= inst.operands[0].reg << 8;
8958 inst.instruction |= inst.operands[1].imm << 21;
fdfde340 8959 inst.instruction |= Rd << 12;
c19d1205
ZW
8960 inst.instruction |= inst.operands[3].reg << 16;
8961 inst.instruction |= inst.operands[4].reg;
8962 inst.instruction |= inst.operands[5].imm << 5;
8963}
09d92015 8964
c19d1205
ZW
8965/* Transfer between coprocessor register and pair of ARM registers.
8966 MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
8967 MCRR2
8968 MRRC{cond}
8969 MRRC2
b99bd4ef 8970
c19d1205 8971 Two XScale instructions are special cases of these:
09d92015 8972
c19d1205
ZW
8973 MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
8974 MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
b99bd4ef 8975
5f4273c7 8976 Result unpredictable if Rd or Rn is R15. */
a737bd4d 8977
c19d1205
ZW
8978static void
8979do_co_reg2c (void)
8980{
fdfde340
JM
8981 unsigned Rd, Rn;
8982
8983 Rd = inst.operands[2].reg;
8984 Rn = inst.operands[3].reg;
8985
8986 if (thumb_mode)
8987 {
8988 reject_bad_reg (Rd);
8989 reject_bad_reg (Rn);
8990 }
8991 else
8992 {
8993 constraint (Rd == REG_PC, BAD_PC);
8994 constraint (Rn == REG_PC, BAD_PC);
8995 }
8996
873f10f0
TC
8997 /* Only check the MRRC{2} variants. */
8998 if ((inst.instruction & 0x0FF00000) == 0x0C500000)
8999 {
9000 /* If Rd == Rn, error that the operation is
9001 unpredictable (example MRRC p3,#1,r1,r1,c4). */
9002 constraint (Rd == Rn, BAD_OVERLAP);
9003 }
9004
c19d1205
ZW
9005 inst.instruction |= inst.operands[0].reg << 8;
9006 inst.instruction |= inst.operands[1].imm << 4;
fdfde340
JM
9007 inst.instruction |= Rd << 12;
9008 inst.instruction |= Rn << 16;
c19d1205 9009 inst.instruction |= inst.operands[4].reg;
b99bd4ef
NC
9010}
9011
c19d1205
ZW
9012static void
9013do_cpsi (void)
9014{
9015 inst.instruction |= inst.operands[0].imm << 6;
a028a6f5
PB
9016 if (inst.operands[1].present)
9017 {
9018 inst.instruction |= CPSI_MMOD;
9019 inst.instruction |= inst.operands[1].imm;
9020 }
c19d1205 9021}
b99bd4ef 9022
62b3e311
PB
9023static void
9024do_dbg (void)
9025{
9026 inst.instruction |= inst.operands[0].imm;
9027}
9028
eea54501
MGD
9029static void
9030do_div (void)
9031{
9032 unsigned Rd, Rn, Rm;
9033
9034 Rd = inst.operands[0].reg;
9035 Rn = (inst.operands[1].present
9036 ? inst.operands[1].reg : Rd);
9037 Rm = inst.operands[2].reg;
9038
9039 constraint ((Rd == REG_PC), BAD_PC);
9040 constraint ((Rn == REG_PC), BAD_PC);
9041 constraint ((Rm == REG_PC), BAD_PC);
9042
9043 inst.instruction |= Rd << 16;
9044 inst.instruction |= Rn << 0;
9045 inst.instruction |= Rm << 8;
9046}
9047
b99bd4ef 9048static void
c19d1205 9049do_it (void)
b99bd4ef 9050{
c19d1205 9051 /* There is no IT instruction in ARM mode. We
e07e6e58
NC
9052 process it to do the validation as if in
9053 thumb mode, just in case the code gets
9054 assembled for thumb using the unified syntax. */
9055
c19d1205 9056 inst.size = 0;
e07e6e58
NC
9057 if (unified_syntax)
9058 {
9059 set_it_insn_type (IT_INSN);
9060 now_it.mask = (inst.instruction & 0xf) | 0x10;
9061 now_it.cc = inst.operands[0].imm;
9062 }
09d92015 9063}
b99bd4ef 9064
6530b175
NC
9065/* If there is only one register in the register list,
9066 then return its register number. Otherwise return -1. */
9067static int
9068only_one_reg_in_list (int range)
9069{
9070 int i = ffs (range) - 1;
9071 return (i > 15 || range != (1 << i)) ? -1 : i;
9072}
9073
09d92015 9074static void
6530b175 9075encode_ldmstm(int from_push_pop_mnem)
ea6ef066 9076{
c19d1205
ZW
9077 int base_reg = inst.operands[0].reg;
9078 int range = inst.operands[1].imm;
6530b175 9079 int one_reg;
ea6ef066 9080
c19d1205
ZW
9081 inst.instruction |= base_reg << 16;
9082 inst.instruction |= range;
ea6ef066 9083
c19d1205
ZW
9084 if (inst.operands[1].writeback)
9085 inst.instruction |= LDM_TYPE_2_OR_3;
09d92015 9086
c19d1205 9087 if (inst.operands[0].writeback)
ea6ef066 9088 {
c19d1205
ZW
9089 inst.instruction |= WRITE_BACK;
9090 /* Check for unpredictable uses of writeback. */
9091 if (inst.instruction & LOAD_BIT)
09d92015 9092 {
c19d1205
ZW
9093 /* Not allowed in LDM type 2. */
9094 if ((inst.instruction & LDM_TYPE_2_OR_3)
9095 && ((range & (1 << REG_PC)) == 0))
9096 as_warn (_("writeback of base register is UNPREDICTABLE"));
9097 /* Only allowed if base reg not in list for other types. */
9098 else if (range & (1 << base_reg))
9099 as_warn (_("writeback of base register when in register list is UNPREDICTABLE"));
9100 }
9101 else /* STM. */
9102 {
9103 /* Not allowed for type 2. */
9104 if (inst.instruction & LDM_TYPE_2_OR_3)
9105 as_warn (_("writeback of base register is UNPREDICTABLE"));
9106 /* Only allowed if base reg not in list, or first in list. */
9107 else if ((range & (1 << base_reg))
9108 && (range & ((1 << base_reg) - 1)))
9109 as_warn (_("if writeback register is in list, it must be the lowest reg in the list"));
09d92015 9110 }
ea6ef066 9111 }
6530b175
NC
9112
9113 /* If PUSH/POP has only one register, then use the A2 encoding. */
9114 one_reg = only_one_reg_in_list (range);
9115 if (from_push_pop_mnem && one_reg >= 0)
9116 {
9117 int is_push = (inst.instruction & A_PUSH_POP_OP_MASK) == A1_OPCODE_PUSH;
9118
4f588891
NC
9119 if (is_push && one_reg == 13 /* SP */)
9120 /* PR 22483: The A2 encoding cannot be used when
9121 pushing the stack pointer as this is UNPREDICTABLE. */
9122 return;
9123
6530b175
NC
9124 inst.instruction &= A_COND_MASK;
9125 inst.instruction |= is_push ? A2_OPCODE_PUSH : A2_OPCODE_POP;
9126 inst.instruction |= one_reg << 12;
9127 }
9128}
9129
9130static void
9131do_ldmstm (void)
9132{
9133 encode_ldmstm (/*from_push_pop_mnem=*/FALSE);
a737bd4d
NC
9134}
9135
c19d1205
ZW
9136/* ARMv5TE load-consecutive (argument parse)
9137 Mode is like LDRH.
9138
9139 LDRccD R, mode
9140 STRccD R, mode. */
9141
a737bd4d 9142static void
c19d1205 9143do_ldrd (void)
a737bd4d 9144{
c19d1205 9145 constraint (inst.operands[0].reg % 2 != 0,
c56791bb 9146 _("first transfer register must be even"));
c19d1205
ZW
9147 constraint (inst.operands[1].present
9148 && inst.operands[1].reg != inst.operands[0].reg + 1,
c56791bb 9149 _("can only transfer two consecutive registers"));
c19d1205
ZW
9150 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
9151 constraint (!inst.operands[2].isreg, _("'[' expected"));
a737bd4d 9152
c19d1205
ZW
9153 if (!inst.operands[1].present)
9154 inst.operands[1].reg = inst.operands[0].reg + 1;
5f4273c7 9155
c56791bb
RE
9156 /* encode_arm_addr_mode_3 will diagnose overlap between the base
9157 register and the first register written; we have to diagnose
9158 overlap between the base and the second register written here. */
ea6ef066 9159
c56791bb
RE
9160 if (inst.operands[2].reg == inst.operands[1].reg
9161 && (inst.operands[2].writeback || inst.operands[2].postind))
9162 as_warn (_("base register written back, and overlaps "
9163 "second transfer register"));
b05fe5cf 9164
c56791bb
RE
9165 if (!(inst.instruction & V4_STR_BIT))
9166 {
c19d1205 9167 /* For an index-register load, the index register must not overlap the
c56791bb
RE
9168 destination (even if not write-back). */
9169 if (inst.operands[2].immisreg
9170 && ((unsigned) inst.operands[2].imm == inst.operands[0].reg
9171 || (unsigned) inst.operands[2].imm == inst.operands[1].reg))
9172 as_warn (_("index register overlaps transfer register"));
b05fe5cf 9173 }
c19d1205
ZW
9174 inst.instruction |= inst.operands[0].reg << 12;
9175 encode_arm_addr_mode_3 (2, /*is_t=*/FALSE);
b05fe5cf
ZW
9176}
9177
9178static void
c19d1205 9179do_ldrex (void)
b05fe5cf 9180{
c19d1205
ZW
9181 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
9182 || inst.operands[1].postind || inst.operands[1].writeback
9183 || inst.operands[1].immisreg || inst.operands[1].shifted
01cfc07f
NC
9184 || inst.operands[1].negative
9185 /* This can arise if the programmer has written
9186 strex rN, rM, foo
9187 or if they have mistakenly used a register name as the last
9188 operand, eg:
9189 strex rN, rM, rX
9190 It is very difficult to distinguish between these two cases
9191 because "rX" might actually be a label. ie the register
9192 name has been occluded by a symbol of the same name. So we
9193 just generate a general 'bad addressing mode' type error
9194 message and leave it up to the programmer to discover the
9195 true cause and fix their mistake. */
9196 || (inst.operands[1].reg == REG_PC),
9197 BAD_ADDR_MODE);
b05fe5cf 9198
e2b0ab59
AV
9199 constraint (inst.relocs[0].exp.X_op != O_constant
9200 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9201 _("offset must be zero in ARM encoding"));
b05fe5cf 9202
5be8be5d
DG
9203 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
9204
c19d1205
ZW
9205 inst.instruction |= inst.operands[0].reg << 12;
9206 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 9207 inst.relocs[0].type = BFD_RELOC_UNUSED;
b05fe5cf
ZW
9208}
9209
9210static void
c19d1205 9211do_ldrexd (void)
b05fe5cf 9212{
c19d1205
ZW
9213 constraint (inst.operands[0].reg % 2 != 0,
9214 _("even register required"));
9215 constraint (inst.operands[1].present
9216 && inst.operands[1].reg != inst.operands[0].reg + 1,
9217 _("can only load two consecutive registers"));
9218 /* If op 1 were present and equal to PC, this function wouldn't
9219 have been called in the first place. */
9220 constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
b05fe5cf 9221
c19d1205
ZW
9222 inst.instruction |= inst.operands[0].reg << 12;
9223 inst.instruction |= inst.operands[2].reg << 16;
b05fe5cf
ZW
9224}
9225
1be5fd2e
NC
9226/* In both ARM and thumb state 'ldr pc, #imm' with an immediate
9227 which is not a multiple of four is UNPREDICTABLE. */
9228static void
9229check_ldr_r15_aligned (void)
9230{
9231 constraint (!(inst.operands[1].immisreg)
9232 && (inst.operands[0].reg == REG_PC
9233 && inst.operands[1].reg == REG_PC
e2b0ab59 9234 && (inst.relocs[0].exp.X_add_number & 0x3)),
de194d85 9235 _("ldr to register 15 must be 4-byte aligned"));
1be5fd2e
NC
9236}
9237
b05fe5cf 9238static void
c19d1205 9239do_ldst (void)
b05fe5cf 9240{
c19d1205
ZW
9241 inst.instruction |= inst.operands[0].reg << 12;
9242 if (!inst.operands[1].isreg)
8335d6aa 9243 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/FALSE))
b05fe5cf 9244 return;
c19d1205 9245 encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
1be5fd2e 9246 check_ldr_r15_aligned ();
b05fe5cf
ZW
9247}
9248
9249static void
c19d1205 9250do_ldstt (void)
b05fe5cf 9251{
c19d1205
ZW
9252 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9253 reject [Rn,...]. */
9254 if (inst.operands[1].preind)
b05fe5cf 9255 {
e2b0ab59
AV
9256 constraint (inst.relocs[0].exp.X_op != O_constant
9257 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9258 _("this instruction requires a post-indexed address"));
b05fe5cf 9259
c19d1205
ZW
9260 inst.operands[1].preind = 0;
9261 inst.operands[1].postind = 1;
9262 inst.operands[1].writeback = 1;
b05fe5cf 9263 }
c19d1205
ZW
9264 inst.instruction |= inst.operands[0].reg << 12;
9265 encode_arm_addr_mode_2 (1, /*is_t=*/TRUE);
9266}
b05fe5cf 9267
c19d1205 9268/* Halfword and signed-byte load/store operations. */
b05fe5cf 9269
c19d1205
ZW
9270static void
9271do_ldstv4 (void)
9272{
ff4a8d2b 9273 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205
ZW
9274 inst.instruction |= inst.operands[0].reg << 12;
9275 if (!inst.operands[1].isreg)
8335d6aa 9276 if (move_or_literal_pool (0, CONST_ARM, /*mode_3=*/TRUE))
b05fe5cf 9277 return;
c19d1205 9278 encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
b05fe5cf
ZW
9279}
9280
9281static void
c19d1205 9282do_ldsttv4 (void)
b05fe5cf 9283{
c19d1205
ZW
9284 /* ldrt/strt always use post-indexed addressing. Turn [Rn] into [Rn]! and
9285 reject [Rn,...]. */
9286 if (inst.operands[1].preind)
b05fe5cf 9287 {
e2b0ab59
AV
9288 constraint (inst.relocs[0].exp.X_op != O_constant
9289 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9290 _("this instruction requires a post-indexed address"));
b05fe5cf 9291
c19d1205
ZW
9292 inst.operands[1].preind = 0;
9293 inst.operands[1].postind = 1;
9294 inst.operands[1].writeback = 1;
b05fe5cf 9295 }
c19d1205
ZW
9296 inst.instruction |= inst.operands[0].reg << 12;
9297 encode_arm_addr_mode_3 (1, /*is_t=*/TRUE);
9298}
b05fe5cf 9299
c19d1205
ZW
9300/* Co-processor register load/store.
9301 Format: <LDC|STC>{cond}[L] CP#,CRd,<address> */
9302static void
9303do_lstc (void)
9304{
9305 inst.instruction |= inst.operands[0].reg << 8;
9306 inst.instruction |= inst.operands[1].reg << 12;
9307 encode_arm_cp_address (2, TRUE, TRUE, 0);
b05fe5cf
ZW
9308}
9309
b05fe5cf 9310static void
c19d1205 9311do_mlas (void)
b05fe5cf 9312{
8fb9d7b9 9313 /* This restriction does not apply to mls (nor to mla in v6 or later). */
c19d1205 9314 if (inst.operands[0].reg == inst.operands[1].reg
8fb9d7b9 9315 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6)
c19d1205 9316 && !(inst.instruction & 0x00400000))
8fb9d7b9 9317 as_tsktsk (_("Rd and Rm should be different in mla"));
b05fe5cf 9318
c19d1205
ZW
9319 inst.instruction |= inst.operands[0].reg << 16;
9320 inst.instruction |= inst.operands[1].reg;
9321 inst.instruction |= inst.operands[2].reg << 8;
9322 inst.instruction |= inst.operands[3].reg << 12;
c19d1205 9323}
b05fe5cf 9324
c19d1205
ZW
9325static void
9326do_mov (void)
9327{
e2b0ab59
AV
9328 constraint (inst.relocs[0].type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
9329 && inst.relocs[0].type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC ,
a9f02af8 9330 THUMB1_RELOC_ONLY);
c19d1205
ZW
9331 inst.instruction |= inst.operands[0].reg << 12;
9332 encode_arm_shifter_operand (1);
9333}
b05fe5cf 9334
c19d1205
ZW
9335/* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>. */
9336static void
9337do_mov16 (void)
9338{
b6895b4f
PB
9339 bfd_vma imm;
9340 bfd_boolean top;
9341
9342 top = (inst.instruction & 0x00400000) != 0;
e2b0ab59 9343 constraint (top && inst.relocs[0].type == BFD_RELOC_ARM_MOVW,
33eaf5de 9344 _(":lower16: not allowed in this instruction"));
e2b0ab59 9345 constraint (!top && inst.relocs[0].type == BFD_RELOC_ARM_MOVT,
33eaf5de 9346 _(":upper16: not allowed in this instruction"));
c19d1205 9347 inst.instruction |= inst.operands[0].reg << 12;
e2b0ab59 9348 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 9349 {
e2b0ab59 9350 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
9351 /* The value is in two pieces: 0:11, 16:19. */
9352 inst.instruction |= (imm & 0x00000fff);
9353 inst.instruction |= (imm & 0x0000f000) << 4;
9354 }
b05fe5cf 9355}
b99bd4ef 9356
037e8744
JB
9357static int
9358do_vfp_nsyn_mrs (void)
9359{
9360 if (inst.operands[0].isvec)
9361 {
9362 if (inst.operands[1].reg != 1)
477330fc 9363 first_error (_("operand 1 must be FPSCR"));
037e8744
JB
9364 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
9365 memset (&inst.operands[1], '\0', sizeof (inst.operands[1]));
9366 do_vfp_nsyn_opcode ("fmstat");
9367 }
9368 else if (inst.operands[1].isvec)
9369 do_vfp_nsyn_opcode ("fmrx");
9370 else
9371 return FAIL;
5f4273c7 9372
037e8744
JB
9373 return SUCCESS;
9374}
9375
9376static int
9377do_vfp_nsyn_msr (void)
9378{
9379 if (inst.operands[0].isvec)
9380 do_vfp_nsyn_opcode ("fmxr");
9381 else
9382 return FAIL;
9383
9384 return SUCCESS;
9385}
9386
f7c21dc7
NC
9387static void
9388do_vmrs (void)
9389{
9390 unsigned Rt = inst.operands[0].reg;
fa94de6b 9391
16d02dc9 9392 if (thumb_mode && Rt == REG_SP)
f7c21dc7
NC
9393 {
9394 inst.error = BAD_SP;
9395 return;
9396 }
9397
40c7d507
RR
9398 /* MVFR2 is only valid at ARMv8-A. */
9399 if (inst.operands[1].reg == 5)
9400 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9401 _(BAD_FPU));
9402
f7c21dc7 9403 /* APSR_ sets isvec. All other refs to PC are illegal. */
16d02dc9 9404 if (!inst.operands[0].isvec && Rt == REG_PC)
f7c21dc7
NC
9405 {
9406 inst.error = BAD_PC;
9407 return;
9408 }
9409
16d02dc9
JB
9410 /* If we get through parsing the register name, we just insert the number
9411 generated into the instruction without further validation. */
9412 inst.instruction |= (inst.operands[1].reg << 16);
f7c21dc7
NC
9413 inst.instruction |= (Rt << 12);
9414}
9415
9416static void
9417do_vmsr (void)
9418{
9419 unsigned Rt = inst.operands[1].reg;
fa94de6b 9420
f7c21dc7
NC
9421 if (thumb_mode)
9422 reject_bad_reg (Rt);
9423 else if (Rt == REG_PC)
9424 {
9425 inst.error = BAD_PC;
9426 return;
9427 }
9428
40c7d507
RR
9429 /* MVFR2 is only valid for ARMv8-A. */
9430 if (inst.operands[0].reg == 5)
9431 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
9432 _(BAD_FPU));
9433
16d02dc9
JB
9434 /* If we get through parsing the register name, we just insert the number
9435 generated into the instruction without further validation. */
9436 inst.instruction |= (inst.operands[0].reg << 16);
f7c21dc7
NC
9437 inst.instruction |= (Rt << 12);
9438}
9439
b99bd4ef 9440static void
c19d1205 9441do_mrs (void)
b99bd4ef 9442{
90ec0d68
MGD
9443 unsigned br;
9444
037e8744
JB
9445 if (do_vfp_nsyn_mrs () == SUCCESS)
9446 return;
9447
ff4a8d2b 9448 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
c19d1205 9449 inst.instruction |= inst.operands[0].reg << 12;
90ec0d68
MGD
9450
9451 if (inst.operands[1].isreg)
9452 {
9453 br = inst.operands[1].reg;
806ab1c0 9454 if (((br & 0x200) == 0) && ((br & 0xf0000) != 0xf0000))
90ec0d68
MGD
9455 as_bad (_("bad register for mrs"));
9456 }
9457 else
9458 {
9459 /* mrs only accepts CPSR/SPSR/CPSR_all/SPSR_all. */
9460 constraint ((inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f))
9461 != (PSR_c|PSR_f),
d2cd1205 9462 _("'APSR', 'CPSR' or 'SPSR' expected"));
90ec0d68
MGD
9463 br = (15<<16) | (inst.operands[1].imm & SPSR_BIT);
9464 }
9465
9466 inst.instruction |= br;
c19d1205 9467}
b99bd4ef 9468
c19d1205
ZW
9469/* Two possible forms:
9470 "{C|S}PSR_<field>, Rm",
9471 "{C|S}PSR_f, #expression". */
b99bd4ef 9472
c19d1205
ZW
9473static void
9474do_msr (void)
9475{
037e8744
JB
9476 if (do_vfp_nsyn_msr () == SUCCESS)
9477 return;
9478
c19d1205
ZW
9479 inst.instruction |= inst.operands[0].imm;
9480 if (inst.operands[1].isreg)
9481 inst.instruction |= inst.operands[1].reg;
9482 else
b99bd4ef 9483 {
c19d1205 9484 inst.instruction |= INST_IMMEDIATE;
e2b0ab59
AV
9485 inst.relocs[0].type = BFD_RELOC_ARM_IMMEDIATE;
9486 inst.relocs[0].pc_rel = 0;
b99bd4ef 9487 }
b99bd4ef
NC
9488}
9489
c19d1205
ZW
9490static void
9491do_mul (void)
a737bd4d 9492{
ff4a8d2b
NC
9493 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
9494
c19d1205
ZW
9495 if (!inst.operands[2].present)
9496 inst.operands[2].reg = inst.operands[0].reg;
9497 inst.instruction |= inst.operands[0].reg << 16;
9498 inst.instruction |= inst.operands[1].reg;
9499 inst.instruction |= inst.operands[2].reg << 8;
a737bd4d 9500
8fb9d7b9
MS
9501 if (inst.operands[0].reg == inst.operands[1].reg
9502 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
9503 as_tsktsk (_("Rd and Rm should be different in mul"));
a737bd4d
NC
9504}
9505
c19d1205
ZW
9506/* Long Multiply Parser
9507 UMULL RdLo, RdHi, Rm, Rs
9508 SMULL RdLo, RdHi, Rm, Rs
9509 UMLAL RdLo, RdHi, Rm, Rs
9510 SMLAL RdLo, RdHi, Rm, Rs. */
b99bd4ef
NC
9511
9512static void
c19d1205 9513do_mull (void)
b99bd4ef 9514{
c19d1205
ZW
9515 inst.instruction |= inst.operands[0].reg << 12;
9516 inst.instruction |= inst.operands[1].reg << 16;
9517 inst.instruction |= inst.operands[2].reg;
9518 inst.instruction |= inst.operands[3].reg << 8;
b99bd4ef 9519
682b27ad
PB
9520 /* rdhi and rdlo must be different. */
9521 if (inst.operands[0].reg == inst.operands[1].reg)
9522 as_tsktsk (_("rdhi and rdlo must be different"));
9523
9524 /* rdhi, rdlo and rm must all be different before armv6. */
9525 if ((inst.operands[0].reg == inst.operands[2].reg
c19d1205 9526 || inst.operands[1].reg == inst.operands[2].reg)
682b27ad 9527 && !ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6))
c19d1205
ZW
9528 as_tsktsk (_("rdhi, rdlo and rm must all be different"));
9529}
b99bd4ef 9530
c19d1205
ZW
9531static void
9532do_nop (void)
9533{
e7495e45
NS
9534 if (inst.operands[0].present
9535 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6k))
c19d1205
ZW
9536 {
9537 /* Architectural NOP hints are CPSR sets with no bits selected. */
9538 inst.instruction &= 0xf0000000;
e7495e45
NS
9539 inst.instruction |= 0x0320f000;
9540 if (inst.operands[0].present)
9541 inst.instruction |= inst.operands[0].imm;
c19d1205 9542 }
b99bd4ef
NC
9543}
9544
c19d1205
ZW
9545/* ARM V6 Pack Halfword Bottom Top instruction (argument parse).
9546 PKHBT {<cond>} <Rd>, <Rn>, <Rm> {, LSL #<shift_imm>}
9547 Condition defaults to COND_ALWAYS.
9548 Error if Rd, Rn or Rm are R15. */
b99bd4ef
NC
9549
9550static void
c19d1205 9551do_pkhbt (void)
b99bd4ef 9552{
c19d1205
ZW
9553 inst.instruction |= inst.operands[0].reg << 12;
9554 inst.instruction |= inst.operands[1].reg << 16;
9555 inst.instruction |= inst.operands[2].reg;
9556 if (inst.operands[3].present)
9557 encode_arm_shift (3);
9558}
b99bd4ef 9559
c19d1205 9560/* ARM V6 PKHTB (Argument Parse). */
b99bd4ef 9561
c19d1205
ZW
9562static void
9563do_pkhtb (void)
9564{
9565 if (!inst.operands[3].present)
b99bd4ef 9566 {
c19d1205
ZW
9567 /* If the shift specifier is omitted, turn the instruction
9568 into pkhbt rd, rm, rn. */
9569 inst.instruction &= 0xfff00010;
9570 inst.instruction |= inst.operands[0].reg << 12;
9571 inst.instruction |= inst.operands[1].reg;
9572 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
9573 }
9574 else
9575 {
c19d1205
ZW
9576 inst.instruction |= inst.operands[0].reg << 12;
9577 inst.instruction |= inst.operands[1].reg << 16;
9578 inst.instruction |= inst.operands[2].reg;
9579 encode_arm_shift (3);
b99bd4ef
NC
9580 }
9581}
9582
c19d1205 9583/* ARMv5TE: Preload-Cache
60e5ef9f 9584 MP Extensions: Preload for write
c19d1205 9585
60e5ef9f 9586 PLD(W) <addr_mode>
c19d1205
ZW
9587
9588 Syntactically, like LDR with B=1, W=0, L=1. */
b99bd4ef
NC
9589
9590static void
c19d1205 9591do_pld (void)
b99bd4ef 9592{
c19d1205
ZW
9593 constraint (!inst.operands[0].isreg,
9594 _("'[' expected after PLD mnemonic"));
9595 constraint (inst.operands[0].postind,
9596 _("post-indexed expression used in preload instruction"));
9597 constraint (inst.operands[0].writeback,
9598 _("writeback used in preload instruction"));
9599 constraint (!inst.operands[0].preind,
9600 _("unindexed addressing used in preload instruction"));
c19d1205
ZW
9601 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
9602}
b99bd4ef 9603
62b3e311
PB
9604/* ARMv7: PLI <addr_mode> */
9605static void
9606do_pli (void)
9607{
9608 constraint (!inst.operands[0].isreg,
9609 _("'[' expected after PLI mnemonic"));
9610 constraint (inst.operands[0].postind,
9611 _("post-indexed expression used in preload instruction"));
9612 constraint (inst.operands[0].writeback,
9613 _("writeback used in preload instruction"));
9614 constraint (!inst.operands[0].preind,
9615 _("unindexed addressing used in preload instruction"));
9616 encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
9617 inst.instruction &= ~PRE_INDEX;
9618}
9619
c19d1205
ZW
9620static void
9621do_push_pop (void)
9622{
5e0d7f77
MP
9623 constraint (inst.operands[0].writeback,
9624 _("push/pop do not support {reglist}^"));
c19d1205
ZW
9625 inst.operands[1] = inst.operands[0];
9626 memset (&inst.operands[0], 0, sizeof inst.operands[0]);
9627 inst.operands[0].isreg = 1;
9628 inst.operands[0].writeback = 1;
9629 inst.operands[0].reg = REG_SP;
6530b175 9630 encode_ldmstm (/*from_push_pop_mnem=*/TRUE);
c19d1205 9631}
b99bd4ef 9632
c19d1205
ZW
9633/* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
9634 word at the specified address and the following word
9635 respectively.
9636 Unconditionally executed.
9637 Error if Rn is R15. */
b99bd4ef 9638
c19d1205
ZW
9639static void
9640do_rfe (void)
9641{
9642 inst.instruction |= inst.operands[0].reg << 16;
9643 if (inst.operands[0].writeback)
9644 inst.instruction |= WRITE_BACK;
9645}
b99bd4ef 9646
c19d1205 9647/* ARM V6 ssat (argument parse). */
b99bd4ef 9648
c19d1205
ZW
9649static void
9650do_ssat (void)
9651{
9652 inst.instruction |= inst.operands[0].reg << 12;
9653 inst.instruction |= (inst.operands[1].imm - 1) << 16;
9654 inst.instruction |= inst.operands[2].reg;
b99bd4ef 9655
c19d1205
ZW
9656 if (inst.operands[3].present)
9657 encode_arm_shift (3);
b99bd4ef
NC
9658}
9659
c19d1205 9660/* ARM V6 usat (argument parse). */
b99bd4ef
NC
9661
9662static void
c19d1205 9663do_usat (void)
b99bd4ef 9664{
c19d1205
ZW
9665 inst.instruction |= inst.operands[0].reg << 12;
9666 inst.instruction |= inst.operands[1].imm << 16;
9667 inst.instruction |= inst.operands[2].reg;
b99bd4ef 9668
c19d1205
ZW
9669 if (inst.operands[3].present)
9670 encode_arm_shift (3);
b99bd4ef
NC
9671}
9672
c19d1205 9673/* ARM V6 ssat16 (argument parse). */
09d92015
MM
9674
9675static void
c19d1205 9676do_ssat16 (void)
09d92015 9677{
c19d1205
ZW
9678 inst.instruction |= inst.operands[0].reg << 12;
9679 inst.instruction |= ((inst.operands[1].imm - 1) << 16);
9680 inst.instruction |= inst.operands[2].reg;
09d92015
MM
9681}
9682
c19d1205
ZW
9683static void
9684do_usat16 (void)
a737bd4d 9685{
c19d1205
ZW
9686 inst.instruction |= inst.operands[0].reg << 12;
9687 inst.instruction |= inst.operands[1].imm << 16;
9688 inst.instruction |= inst.operands[2].reg;
9689}
a737bd4d 9690
c19d1205
ZW
9691/* ARM V6 SETEND (argument parse). Sets the E bit in the CPSR while
9692 preserving the other bits.
a737bd4d 9693
c19d1205
ZW
9694 setend <endian_specifier>, where <endian_specifier> is either
9695 BE or LE. */
a737bd4d 9696
c19d1205
ZW
9697static void
9698do_setend (void)
9699{
12e37cbc
MGD
9700 if (warn_on_deprecated
9701 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 9702 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 9703
c19d1205
ZW
9704 if (inst.operands[0].imm)
9705 inst.instruction |= 0x200;
a737bd4d
NC
9706}
9707
9708static void
c19d1205 9709do_shift (void)
a737bd4d 9710{
c19d1205
ZW
9711 unsigned int Rm = (inst.operands[1].present
9712 ? inst.operands[1].reg
9713 : inst.operands[0].reg);
a737bd4d 9714
c19d1205
ZW
9715 inst.instruction |= inst.operands[0].reg << 12;
9716 inst.instruction |= Rm;
9717 if (inst.operands[2].isreg) /* Rd, {Rm,} Rs */
a737bd4d 9718 {
c19d1205
ZW
9719 inst.instruction |= inst.operands[2].reg << 8;
9720 inst.instruction |= SHIFT_BY_REG;
94342ec3
NC
9721 /* PR 12854: Error on extraneous shifts. */
9722 constraint (inst.operands[2].shifted,
9723 _("extraneous shift as part of operand to shift insn"));
a737bd4d
NC
9724 }
9725 else
e2b0ab59 9726 inst.relocs[0].type = BFD_RELOC_ARM_SHIFT_IMM;
a737bd4d
NC
9727}
9728
09d92015 9729static void
3eb17e6b 9730do_smc (void)
09d92015 9731{
e2b0ab59
AV
9732 inst.relocs[0].type = BFD_RELOC_ARM_SMC;
9733 inst.relocs[0].pc_rel = 0;
09d92015
MM
9734}
9735
90ec0d68
MGD
9736static void
9737do_hvc (void)
9738{
e2b0ab59
AV
9739 inst.relocs[0].type = BFD_RELOC_ARM_HVC;
9740 inst.relocs[0].pc_rel = 0;
90ec0d68
MGD
9741}
9742
09d92015 9743static void
c19d1205 9744do_swi (void)
09d92015 9745{
e2b0ab59
AV
9746 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
9747 inst.relocs[0].pc_rel = 0;
09d92015
MM
9748}
9749
ddfded2f
MW
9750static void
9751do_setpan (void)
9752{
9753 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
9754 _("selected processor does not support SETPAN instruction"));
9755
9756 inst.instruction |= ((inst.operands[0].imm & 1) << 9);
9757}
9758
9759static void
9760do_t_setpan (void)
9761{
9762 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_pan),
9763 _("selected processor does not support SETPAN instruction"));
9764
9765 inst.instruction |= (inst.operands[0].imm << 3);
9766}
9767
c19d1205
ZW
9768/* ARM V5E (El Segundo) signed-multiply-accumulate (argument parse)
9769 SMLAxy{cond} Rd,Rm,Rs,Rn
9770 SMLAWy{cond} Rd,Rm,Rs,Rn
9771 Error if any register is R15. */
e16bb312 9772
c19d1205
ZW
9773static void
9774do_smla (void)
e16bb312 9775{
c19d1205
ZW
9776 inst.instruction |= inst.operands[0].reg << 16;
9777 inst.instruction |= inst.operands[1].reg;
9778 inst.instruction |= inst.operands[2].reg << 8;
9779 inst.instruction |= inst.operands[3].reg << 12;
9780}
a737bd4d 9781
c19d1205
ZW
9782/* ARM V5E (El Segundo) signed-multiply-accumulate-long (argument parse)
9783 SMLALxy{cond} Rdlo,Rdhi,Rm,Rs
9784 Error if any register is R15.
9785 Warning if Rdlo == Rdhi. */
a737bd4d 9786
c19d1205
ZW
9787static void
9788do_smlal (void)
9789{
9790 inst.instruction |= inst.operands[0].reg << 12;
9791 inst.instruction |= inst.operands[1].reg << 16;
9792 inst.instruction |= inst.operands[2].reg;
9793 inst.instruction |= inst.operands[3].reg << 8;
a737bd4d 9794
c19d1205
ZW
9795 if (inst.operands[0].reg == inst.operands[1].reg)
9796 as_tsktsk (_("rdhi and rdlo must be different"));
9797}
a737bd4d 9798
c19d1205
ZW
9799/* ARM V5E (El Segundo) signed-multiply (argument parse)
9800 SMULxy{cond} Rd,Rm,Rs
9801 Error if any register is R15. */
a737bd4d 9802
c19d1205
ZW
9803static void
9804do_smul (void)
9805{
9806 inst.instruction |= inst.operands[0].reg << 16;
9807 inst.instruction |= inst.operands[1].reg;
9808 inst.instruction |= inst.operands[2].reg << 8;
9809}
a737bd4d 9810
b6702015
PB
9811/* ARM V6 srs (argument parse). The variable fields in the encoding are
9812 the same for both ARM and Thumb-2. */
a737bd4d 9813
c19d1205
ZW
9814static void
9815do_srs (void)
9816{
b6702015
PB
9817 int reg;
9818
9819 if (inst.operands[0].present)
9820 {
9821 reg = inst.operands[0].reg;
fdfde340 9822 constraint (reg != REG_SP, _("SRS base register must be r13"));
b6702015
PB
9823 }
9824 else
fdfde340 9825 reg = REG_SP;
b6702015
PB
9826
9827 inst.instruction |= reg << 16;
9828 inst.instruction |= inst.operands[1].imm;
9829 if (inst.operands[0].writeback || inst.operands[1].writeback)
c19d1205
ZW
9830 inst.instruction |= WRITE_BACK;
9831}
a737bd4d 9832
c19d1205 9833/* ARM V6 strex (argument parse). */
a737bd4d 9834
c19d1205
ZW
9835static void
9836do_strex (void)
9837{
9838 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
9839 || inst.operands[2].postind || inst.operands[2].writeback
9840 || inst.operands[2].immisreg || inst.operands[2].shifted
01cfc07f
NC
9841 || inst.operands[2].negative
9842 /* See comment in do_ldrex(). */
9843 || (inst.operands[2].reg == REG_PC),
9844 BAD_ADDR_MODE);
a737bd4d 9845
c19d1205
ZW
9846 constraint (inst.operands[0].reg == inst.operands[1].reg
9847 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
a737bd4d 9848
e2b0ab59
AV
9849 constraint (inst.relocs[0].exp.X_op != O_constant
9850 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 9851 _("offset must be zero in ARM encoding"));
a737bd4d 9852
c19d1205
ZW
9853 inst.instruction |= inst.operands[0].reg << 12;
9854 inst.instruction |= inst.operands[1].reg;
9855 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 9856 inst.relocs[0].type = BFD_RELOC_UNUSED;
e16bb312
NC
9857}
9858
877807f8
NC
9859static void
9860do_t_strexbh (void)
9861{
9862 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
9863 || inst.operands[2].postind || inst.operands[2].writeback
9864 || inst.operands[2].immisreg || inst.operands[2].shifted
9865 || inst.operands[2].negative,
9866 BAD_ADDR_MODE);
9867
9868 constraint (inst.operands[0].reg == inst.operands[1].reg
9869 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
9870
9871 do_rm_rd_rn ();
9872}
9873
e16bb312 9874static void
c19d1205 9875do_strexd (void)
e16bb312 9876{
c19d1205
ZW
9877 constraint (inst.operands[1].reg % 2 != 0,
9878 _("even register required"));
9879 constraint (inst.operands[2].present
9880 && inst.operands[2].reg != inst.operands[1].reg + 1,
9881 _("can only store two consecutive registers"));
9882 /* If op 2 were present and equal to PC, this function wouldn't
9883 have been called in the first place. */
9884 constraint (inst.operands[1].reg == REG_LR, _("r14 not allowed here"));
e16bb312 9885
c19d1205
ZW
9886 constraint (inst.operands[0].reg == inst.operands[1].reg
9887 || inst.operands[0].reg == inst.operands[1].reg + 1
9888 || inst.operands[0].reg == inst.operands[3].reg,
9889 BAD_OVERLAP);
e16bb312 9890
c19d1205
ZW
9891 inst.instruction |= inst.operands[0].reg << 12;
9892 inst.instruction |= inst.operands[1].reg;
9893 inst.instruction |= inst.operands[3].reg << 16;
e16bb312
NC
9894}
9895
9eb6c0f1
MGD
9896/* ARM V8 STRL. */
9897static void
4b8c8c02 9898do_stlex (void)
9eb6c0f1
MGD
9899{
9900 constraint (inst.operands[0].reg == inst.operands[1].reg
9901 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
9902
9903 do_rd_rm_rn ();
9904}
9905
9906static void
4b8c8c02 9907do_t_stlex (void)
9eb6c0f1
MGD
9908{
9909 constraint (inst.operands[0].reg == inst.operands[1].reg
9910 || inst.operands[0].reg == inst.operands[2].reg, BAD_OVERLAP);
9911
9912 do_rm_rd_rn ();
9913}
9914
c19d1205
ZW
9915/* ARM V6 SXTAH extracts a 16-bit value from a register, sign
9916 extends it to 32-bits, and adds the result to a value in another
9917 register. You can specify a rotation by 0, 8, 16, or 24 bits
9918 before extracting the 16-bit value.
9919 SXTAH{<cond>} <Rd>, <Rn>, <Rm>{, <rotation>}
9920 Condition defaults to COND_ALWAYS.
9921 Error if any register uses R15. */
9922
e16bb312 9923static void
c19d1205 9924do_sxtah (void)
e16bb312 9925{
c19d1205
ZW
9926 inst.instruction |= inst.operands[0].reg << 12;
9927 inst.instruction |= inst.operands[1].reg << 16;
9928 inst.instruction |= inst.operands[2].reg;
9929 inst.instruction |= inst.operands[3].imm << 10;
9930}
e16bb312 9931
c19d1205 9932/* ARM V6 SXTH.
e16bb312 9933
c19d1205
ZW
9934 SXTH {<cond>} <Rd>, <Rm>{, <rotation>}
9935 Condition defaults to COND_ALWAYS.
9936 Error if any register uses R15. */
e16bb312
NC
9937
9938static void
c19d1205 9939do_sxth (void)
e16bb312 9940{
c19d1205
ZW
9941 inst.instruction |= inst.operands[0].reg << 12;
9942 inst.instruction |= inst.operands[1].reg;
9943 inst.instruction |= inst.operands[2].imm << 10;
e16bb312 9944}
c19d1205
ZW
9945\f
9946/* VFP instructions. In a logical order: SP variant first, monad
9947 before dyad, arithmetic then move then load/store. */
e16bb312
NC
9948
9949static void
c19d1205 9950do_vfp_sp_monadic (void)
e16bb312 9951{
5287ad62
JB
9952 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
9953 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
9954}
9955
9956static void
c19d1205 9957do_vfp_sp_dyadic (void)
e16bb312 9958{
5287ad62
JB
9959 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
9960 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
9961 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
9962}
9963
9964static void
c19d1205 9965do_vfp_sp_compare_z (void)
e16bb312 9966{
5287ad62 9967 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
e16bb312
NC
9968}
9969
9970static void
c19d1205 9971do_vfp_dp_sp_cvt (void)
e16bb312 9972{
5287ad62
JB
9973 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
9974 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sm);
e16bb312
NC
9975}
9976
9977static void
c19d1205 9978do_vfp_sp_dp_cvt (void)
e16bb312 9979{
5287ad62
JB
9980 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
9981 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
e16bb312
NC
9982}
9983
9984static void
c19d1205 9985do_vfp_reg_from_sp (void)
e16bb312 9986{
c19d1205 9987 inst.instruction |= inst.operands[0].reg << 12;
5287ad62 9988 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sn);
e16bb312
NC
9989}
9990
9991static void
c19d1205 9992do_vfp_reg2_from_sp2 (void)
e16bb312 9993{
c19d1205
ZW
9994 constraint (inst.operands[2].imm != 2,
9995 _("only two consecutive VFP SP registers allowed here"));
9996 inst.instruction |= inst.operands[0].reg << 12;
9997 inst.instruction |= inst.operands[1].reg << 16;
5287ad62 9998 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Sm);
e16bb312
NC
9999}
10000
10001static void
c19d1205 10002do_vfp_sp_from_reg (void)
e16bb312 10003{
5287ad62 10004 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sn);
c19d1205 10005 inst.instruction |= inst.operands[1].reg << 12;
e16bb312
NC
10006}
10007
10008static void
c19d1205 10009do_vfp_sp2_from_reg2 (void)
e16bb312 10010{
c19d1205
ZW
10011 constraint (inst.operands[0].imm != 2,
10012 _("only two consecutive VFP SP registers allowed here"));
5287ad62 10013 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sm);
c19d1205
ZW
10014 inst.instruction |= inst.operands[1].reg << 12;
10015 inst.instruction |= inst.operands[2].reg << 16;
e16bb312
NC
10016}
10017
10018static void
c19d1205 10019do_vfp_sp_ldst (void)
e16bb312 10020{
5287ad62 10021 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
c19d1205 10022 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
10023}
10024
10025static void
c19d1205 10026do_vfp_dp_ldst (void)
e16bb312 10027{
5287ad62 10028 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
c19d1205 10029 encode_arm_cp_address (1, FALSE, TRUE, 0);
e16bb312
NC
10030}
10031
c19d1205 10032
e16bb312 10033static void
c19d1205 10034vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10035{
c19d1205
ZW
10036 if (inst.operands[0].writeback)
10037 inst.instruction |= WRITE_BACK;
10038 else
10039 constraint (ldstm_type != VFP_LDSTMIA,
10040 _("this addressing mode requires base-register writeback"));
10041 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10042 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Sd);
c19d1205 10043 inst.instruction |= inst.operands[1].imm;
e16bb312
NC
10044}
10045
10046static void
c19d1205 10047vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
e16bb312 10048{
c19d1205 10049 int count;
e16bb312 10050
c19d1205
ZW
10051 if (inst.operands[0].writeback)
10052 inst.instruction |= WRITE_BACK;
10053 else
10054 constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
10055 _("this addressing mode requires base-register writeback"));
e16bb312 10056
c19d1205 10057 inst.instruction |= inst.operands[0].reg << 16;
5287ad62 10058 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
e16bb312 10059
c19d1205
ZW
10060 count = inst.operands[1].imm << 1;
10061 if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
10062 count += 1;
e16bb312 10063
c19d1205 10064 inst.instruction |= count;
e16bb312
NC
10065}
10066
10067static void
c19d1205 10068do_vfp_sp_ldstmia (void)
e16bb312 10069{
c19d1205 10070 vfp_sp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10071}
10072
10073static void
c19d1205 10074do_vfp_sp_ldstmdb (void)
e16bb312 10075{
c19d1205 10076 vfp_sp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10077}
10078
10079static void
c19d1205 10080do_vfp_dp_ldstmia (void)
e16bb312 10081{
c19d1205 10082 vfp_dp_ldstm (VFP_LDSTMIA);
e16bb312
NC
10083}
10084
10085static void
c19d1205 10086do_vfp_dp_ldstmdb (void)
e16bb312 10087{
c19d1205 10088 vfp_dp_ldstm (VFP_LDSTMDB);
e16bb312
NC
10089}
10090
10091static void
c19d1205 10092do_vfp_xp_ldstmia (void)
e16bb312 10093{
c19d1205
ZW
10094 vfp_dp_ldstm (VFP_LDSTMIAX);
10095}
e16bb312 10096
c19d1205
ZW
10097static void
10098do_vfp_xp_ldstmdb (void)
10099{
10100 vfp_dp_ldstm (VFP_LDSTMDBX);
e16bb312 10101}
5287ad62
JB
10102
10103static void
10104do_vfp_dp_rd_rm (void)
10105{
10106 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10107 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dm);
10108}
10109
10110static void
10111do_vfp_dp_rn_rd (void)
10112{
10113 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dn);
10114 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10115}
10116
10117static void
10118do_vfp_dp_rd_rn (void)
10119{
10120 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10121 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10122}
10123
10124static void
10125do_vfp_dp_rd_rn_rm (void)
10126{
10127 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10128 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dn);
10129 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dm);
10130}
10131
10132static void
10133do_vfp_dp_rd (void)
10134{
10135 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10136}
10137
10138static void
10139do_vfp_dp_rm_rd_rn (void)
10140{
10141 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dm);
10142 encode_arm_vfp_reg (inst.operands[1].reg, VFP_REG_Dd);
10143 encode_arm_vfp_reg (inst.operands[2].reg, VFP_REG_Dn);
10144}
10145
10146/* VFPv3 instructions. */
10147static void
10148do_vfp_sp_const (void)
10149{
10150 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
00249aaa
PB
10151 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10152 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10153}
10154
10155static void
10156do_vfp_dp_const (void)
10157{
10158 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
00249aaa
PB
10159 inst.instruction |= (inst.operands[1].imm & 0xf0) << 12;
10160 inst.instruction |= (inst.operands[1].imm & 0x0f);
5287ad62
JB
10161}
10162
10163static void
10164vfp_conv (int srcsize)
10165{
5f1af56b
MGD
10166 int immbits = srcsize - inst.operands[1].imm;
10167
fa94de6b
RM
10168 if (srcsize == 16 && !(immbits >= 0 && immbits <= srcsize))
10169 {
5f1af56b 10170 /* If srcsize is 16, inst.operands[1].imm must be in the range 0-16.
477330fc 10171 i.e. immbits must be in range 0 - 16. */
5f1af56b
MGD
10172 inst.error = _("immediate value out of range, expected range [0, 16]");
10173 return;
10174 }
fa94de6b 10175 else if (srcsize == 32 && !(immbits >= 0 && immbits < srcsize))
5f1af56b
MGD
10176 {
10177 /* If srcsize is 32, inst.operands[1].imm must be in the range 1-32.
477330fc 10178 i.e. immbits must be in range 0 - 31. */
5f1af56b
MGD
10179 inst.error = _("immediate value out of range, expected range [1, 32]");
10180 return;
10181 }
10182
5287ad62
JB
10183 inst.instruction |= (immbits & 1) << 5;
10184 inst.instruction |= (immbits >> 1);
10185}
10186
10187static void
10188do_vfp_sp_conv_16 (void)
10189{
10190 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10191 vfp_conv (16);
10192}
10193
10194static void
10195do_vfp_dp_conv_16 (void)
10196{
10197 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10198 vfp_conv (16);
10199}
10200
10201static void
10202do_vfp_sp_conv_32 (void)
10203{
10204 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
10205 vfp_conv (32);
10206}
10207
10208static void
10209do_vfp_dp_conv_32 (void)
10210{
10211 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Dd);
10212 vfp_conv (32);
10213}
c19d1205
ZW
10214\f
10215/* FPA instructions. Also in a logical order. */
e16bb312 10216
c19d1205
ZW
10217static void
10218do_fpa_cmp (void)
10219{
10220 inst.instruction |= inst.operands[0].reg << 16;
10221 inst.instruction |= inst.operands[1].reg;
10222}
b99bd4ef
NC
10223
10224static void
c19d1205 10225do_fpa_ldmstm (void)
b99bd4ef 10226{
c19d1205
ZW
10227 inst.instruction |= inst.operands[0].reg << 12;
10228 switch (inst.operands[1].imm)
10229 {
10230 case 1: inst.instruction |= CP_T_X; break;
10231 case 2: inst.instruction |= CP_T_Y; break;
10232 case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
10233 case 4: break;
10234 default: abort ();
10235 }
b99bd4ef 10236
c19d1205
ZW
10237 if (inst.instruction & (PRE_INDEX | INDEX_UP))
10238 {
10239 /* The instruction specified "ea" or "fd", so we can only accept
10240 [Rn]{!}. The instruction does not really support stacking or
10241 unstacking, so we have to emulate these by setting appropriate
10242 bits and offsets. */
e2b0ab59
AV
10243 constraint (inst.relocs[0].exp.X_op != O_constant
10244 || inst.relocs[0].exp.X_add_number != 0,
c19d1205 10245 _("this instruction does not support indexing"));
b99bd4ef 10246
c19d1205 10247 if ((inst.instruction & PRE_INDEX) || inst.operands[2].writeback)
e2b0ab59 10248 inst.relocs[0].exp.X_add_number = 12 * inst.operands[1].imm;
b99bd4ef 10249
c19d1205 10250 if (!(inst.instruction & INDEX_UP))
e2b0ab59 10251 inst.relocs[0].exp.X_add_number = -inst.relocs[0].exp.X_add_number;
b99bd4ef 10252
c19d1205
ZW
10253 if (!(inst.instruction & PRE_INDEX) && inst.operands[2].writeback)
10254 {
10255 inst.operands[2].preind = 0;
10256 inst.operands[2].postind = 1;
10257 }
10258 }
b99bd4ef 10259
c19d1205 10260 encode_arm_cp_address (2, TRUE, TRUE, 0);
b99bd4ef 10261}
c19d1205
ZW
10262\f
10263/* iWMMXt instructions: strictly in alphabetical order. */
b99bd4ef 10264
c19d1205
ZW
10265static void
10266do_iwmmxt_tandorc (void)
10267{
10268 constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
10269}
b99bd4ef 10270
c19d1205
ZW
10271static void
10272do_iwmmxt_textrc (void)
10273{
10274 inst.instruction |= inst.operands[0].reg << 12;
10275 inst.instruction |= inst.operands[1].imm;
10276}
b99bd4ef
NC
10277
10278static void
c19d1205 10279do_iwmmxt_textrm (void)
b99bd4ef 10280{
c19d1205
ZW
10281 inst.instruction |= inst.operands[0].reg << 12;
10282 inst.instruction |= inst.operands[1].reg << 16;
10283 inst.instruction |= inst.operands[2].imm;
10284}
b99bd4ef 10285
c19d1205
ZW
10286static void
10287do_iwmmxt_tinsr (void)
10288{
10289 inst.instruction |= inst.operands[0].reg << 16;
10290 inst.instruction |= inst.operands[1].reg << 12;
10291 inst.instruction |= inst.operands[2].imm;
10292}
b99bd4ef 10293
c19d1205
ZW
10294static void
10295do_iwmmxt_tmia (void)
10296{
10297 inst.instruction |= inst.operands[0].reg << 5;
10298 inst.instruction |= inst.operands[1].reg;
10299 inst.instruction |= inst.operands[2].reg << 12;
10300}
b99bd4ef 10301
c19d1205
ZW
10302static void
10303do_iwmmxt_waligni (void)
10304{
10305 inst.instruction |= inst.operands[0].reg << 12;
10306 inst.instruction |= inst.operands[1].reg << 16;
10307 inst.instruction |= inst.operands[2].reg;
10308 inst.instruction |= inst.operands[3].imm << 20;
10309}
b99bd4ef 10310
2d447fca
JM
10311static void
10312do_iwmmxt_wmerge (void)
10313{
10314 inst.instruction |= inst.operands[0].reg << 12;
10315 inst.instruction |= inst.operands[1].reg << 16;
10316 inst.instruction |= inst.operands[2].reg;
10317 inst.instruction |= inst.operands[3].imm << 21;
10318}
10319
c19d1205
ZW
10320static void
10321do_iwmmxt_wmov (void)
10322{
10323 /* WMOV rD, rN is an alias for WOR rD, rN, rN. */
10324 inst.instruction |= inst.operands[0].reg << 12;
10325 inst.instruction |= inst.operands[1].reg << 16;
10326 inst.instruction |= inst.operands[1].reg;
10327}
b99bd4ef 10328
c19d1205
ZW
10329static void
10330do_iwmmxt_wldstbh (void)
10331{
8f06b2d8 10332 int reloc;
c19d1205 10333 inst.instruction |= inst.operands[0].reg << 12;
8f06b2d8
PB
10334 if (thumb_mode)
10335 reloc = BFD_RELOC_ARM_T32_CP_OFF_IMM_S2;
10336 else
10337 reloc = BFD_RELOC_ARM_CP_OFF_IMM_S2;
10338 encode_arm_cp_address (1, TRUE, FALSE, reloc);
b99bd4ef
NC
10339}
10340
c19d1205
ZW
10341static void
10342do_iwmmxt_wldstw (void)
10343{
10344 /* RIWR_RIWC clears .isreg for a control register. */
10345 if (!inst.operands[0].isreg)
10346 {
10347 constraint (inst.cond != COND_ALWAYS, BAD_COND);
10348 inst.instruction |= 0xf0000000;
10349 }
b99bd4ef 10350
c19d1205
ZW
10351 inst.instruction |= inst.operands[0].reg << 12;
10352 encode_arm_cp_address (1, TRUE, TRUE, 0);
10353}
b99bd4ef
NC
10354
10355static void
c19d1205 10356do_iwmmxt_wldstd (void)
b99bd4ef 10357{
c19d1205 10358 inst.instruction |= inst.operands[0].reg << 12;
2d447fca
JM
10359 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2)
10360 && inst.operands[1].immisreg)
10361 {
10362 inst.instruction &= ~0x1a000ff;
eff0bc54 10363 inst.instruction |= (0xfU << 28);
2d447fca
JM
10364 if (inst.operands[1].preind)
10365 inst.instruction |= PRE_INDEX;
10366 if (!inst.operands[1].negative)
10367 inst.instruction |= INDEX_UP;
10368 if (inst.operands[1].writeback)
10369 inst.instruction |= WRITE_BACK;
10370 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 10371 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
2d447fca
JM
10372 inst.instruction |= inst.operands[1].imm;
10373 }
10374 else
10375 encode_arm_cp_address (1, TRUE, FALSE, 0);
c19d1205 10376}
b99bd4ef 10377
c19d1205
ZW
10378static void
10379do_iwmmxt_wshufh (void)
10380{
10381 inst.instruction |= inst.operands[0].reg << 12;
10382 inst.instruction |= inst.operands[1].reg << 16;
10383 inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
10384 inst.instruction |= (inst.operands[2].imm & 0x0f);
10385}
b99bd4ef 10386
c19d1205
ZW
10387static void
10388do_iwmmxt_wzero (void)
10389{
10390 /* WZERO reg is an alias for WANDN reg, reg, reg. */
10391 inst.instruction |= inst.operands[0].reg;
10392 inst.instruction |= inst.operands[0].reg << 12;
10393 inst.instruction |= inst.operands[0].reg << 16;
10394}
2d447fca
JM
10395
10396static void
10397do_iwmmxt_wrwrwr_or_imm5 (void)
10398{
10399 if (inst.operands[2].isreg)
10400 do_rd_rn_rm ();
10401 else {
10402 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2),
10403 _("immediate operand requires iWMMXt2"));
10404 do_rd_rn ();
10405 if (inst.operands[2].imm == 0)
10406 {
10407 switch ((inst.instruction >> 20) & 0xf)
10408 {
10409 case 4:
10410 case 5:
10411 case 6:
5f4273c7 10412 case 7:
2d447fca
JM
10413 /* w...h wrd, wrn, #0 -> wrorh wrd, wrn, #16. */
10414 inst.operands[2].imm = 16;
10415 inst.instruction = (inst.instruction & 0xff0fffff) | (0x7 << 20);
10416 break;
10417 case 8:
10418 case 9:
10419 case 10:
10420 case 11:
10421 /* w...w wrd, wrn, #0 -> wrorw wrd, wrn, #32. */
10422 inst.operands[2].imm = 32;
10423 inst.instruction = (inst.instruction & 0xff0fffff) | (0xb << 20);
10424 break;
10425 case 12:
10426 case 13:
10427 case 14:
10428 case 15:
10429 {
10430 /* w...d wrd, wrn, #0 -> wor wrd, wrn, wrn. */
10431 unsigned long wrn;
10432 wrn = (inst.instruction >> 16) & 0xf;
10433 inst.instruction &= 0xff0fff0f;
10434 inst.instruction |= wrn;
10435 /* Bail out here; the instruction is now assembled. */
10436 return;
10437 }
10438 }
10439 }
10440 /* Map 32 -> 0, etc. */
10441 inst.operands[2].imm &= 0x1f;
eff0bc54 10442 inst.instruction |= (0xfU << 28) | ((inst.operands[2].imm & 0x10) << 4) | (inst.operands[2].imm & 0xf);
2d447fca
JM
10443 }
10444}
c19d1205
ZW
10445\f
10446/* Cirrus Maverick instructions. Simple 2-, 3-, and 4-register
10447 operations first, then control, shift, and load/store. */
b99bd4ef 10448
c19d1205 10449/* Insns like "foo X,Y,Z". */
b99bd4ef 10450
c19d1205
ZW
10451static void
10452do_mav_triple (void)
10453{
10454 inst.instruction |= inst.operands[0].reg << 16;
10455 inst.instruction |= inst.operands[1].reg;
10456 inst.instruction |= inst.operands[2].reg << 12;
10457}
b99bd4ef 10458
c19d1205
ZW
10459/* Insns like "foo W,X,Y,Z".
10460 where W=MVAX[0:3] and X,Y,Z=MVFX[0:15]. */
a737bd4d 10461
c19d1205
ZW
10462static void
10463do_mav_quad (void)
10464{
10465 inst.instruction |= inst.operands[0].reg << 5;
10466 inst.instruction |= inst.operands[1].reg << 12;
10467 inst.instruction |= inst.operands[2].reg << 16;
10468 inst.instruction |= inst.operands[3].reg;
a737bd4d
NC
10469}
10470
c19d1205
ZW
10471/* cfmvsc32<cond> DSPSC,MVDX[15:0]. */
10472static void
10473do_mav_dspsc (void)
a737bd4d 10474{
c19d1205
ZW
10475 inst.instruction |= inst.operands[1].reg << 12;
10476}
a737bd4d 10477
c19d1205
ZW
10478/* Maverick shift immediate instructions.
10479 cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
10480 cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0]. */
a737bd4d 10481
c19d1205
ZW
10482static void
10483do_mav_shift (void)
10484{
10485 int imm = inst.operands[2].imm;
a737bd4d 10486
c19d1205
ZW
10487 inst.instruction |= inst.operands[0].reg << 12;
10488 inst.instruction |= inst.operands[1].reg << 16;
a737bd4d 10489
c19d1205
ZW
10490 /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
10491 Bits 5-7 of the insn should have bits 4-6 of the immediate.
10492 Bit 4 should be 0. */
10493 imm = (imm & 0xf) | ((imm & 0x70) << 1);
a737bd4d 10494
c19d1205
ZW
10495 inst.instruction |= imm;
10496}
10497\f
10498/* XScale instructions. Also sorted arithmetic before move. */
a737bd4d 10499
c19d1205
ZW
10500/* Xscale multiply-accumulate (argument parse)
10501 MIAcc acc0,Rm,Rs
10502 MIAPHcc acc0,Rm,Rs
10503 MIAxycc acc0,Rm,Rs. */
a737bd4d 10504
c19d1205
ZW
10505static void
10506do_xsc_mia (void)
10507{
10508 inst.instruction |= inst.operands[1].reg;
10509 inst.instruction |= inst.operands[2].reg << 12;
10510}
a737bd4d 10511
c19d1205 10512/* Xscale move-accumulator-register (argument parse)
a737bd4d 10513
c19d1205 10514 MARcc acc0,RdLo,RdHi. */
b99bd4ef 10515
c19d1205
ZW
10516static void
10517do_xsc_mar (void)
10518{
10519 inst.instruction |= inst.operands[1].reg << 12;
10520 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
10521}
10522
c19d1205 10523/* Xscale move-register-accumulator (argument parse)
b99bd4ef 10524
c19d1205 10525 MRAcc RdLo,RdHi,acc0. */
b99bd4ef
NC
10526
10527static void
c19d1205 10528do_xsc_mra (void)
b99bd4ef 10529{
c19d1205
ZW
10530 constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
10531 inst.instruction |= inst.operands[0].reg << 12;
10532 inst.instruction |= inst.operands[1].reg << 16;
10533}
10534\f
10535/* Encoding functions relevant only to Thumb. */
b99bd4ef 10536
c19d1205
ZW
10537/* inst.operands[i] is a shifted-register operand; encode
10538 it into inst.instruction in the format used by Thumb32. */
10539
10540static void
10541encode_thumb32_shifted_operand (int i)
10542{
e2b0ab59 10543 unsigned int value = inst.relocs[0].exp.X_add_number;
c19d1205 10544 unsigned int shift = inst.operands[i].shift_kind;
b99bd4ef 10545
9c3c69f2
PB
10546 constraint (inst.operands[i].immisreg,
10547 _("shift by register not allowed in thumb mode"));
c19d1205
ZW
10548 inst.instruction |= inst.operands[i].reg;
10549 if (shift == SHIFT_RRX)
10550 inst.instruction |= SHIFT_ROR << 4;
10551 else
b99bd4ef 10552 {
e2b0ab59 10553 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
10554 _("expression too complex"));
10555
10556 constraint (value > 32
10557 || (value == 32 && (shift == SHIFT_LSL
10558 || shift == SHIFT_ROR)),
10559 _("shift expression is too large"));
10560
10561 if (value == 0)
10562 shift = SHIFT_LSL;
10563 else if (value == 32)
10564 value = 0;
10565
10566 inst.instruction |= shift << 4;
10567 inst.instruction |= (value & 0x1c) << 10;
10568 inst.instruction |= (value & 0x03) << 6;
b99bd4ef 10569 }
c19d1205 10570}
b99bd4ef 10571
b99bd4ef 10572
c19d1205
ZW
10573/* inst.operands[i] was set up by parse_address. Encode it into a
10574 Thumb32 format load or store instruction. Reject forms that cannot
10575 be used with such instructions. If is_t is true, reject forms that
10576 cannot be used with a T instruction; if is_d is true, reject forms
5be8be5d
DG
10577 that cannot be used with a D instruction. If it is a store insn,
10578 reject PC in Rn. */
b99bd4ef 10579
c19d1205
ZW
10580static void
10581encode_thumb32_addr_mode (int i, bfd_boolean is_t, bfd_boolean is_d)
10582{
5be8be5d 10583 const bfd_boolean is_pc = (inst.operands[i].reg == REG_PC);
c19d1205
ZW
10584
10585 constraint (!inst.operands[i].isreg,
53365c0d 10586 _("Instruction does not support =N addresses"));
b99bd4ef 10587
c19d1205
ZW
10588 inst.instruction |= inst.operands[i].reg << 16;
10589 if (inst.operands[i].immisreg)
b99bd4ef 10590 {
5be8be5d 10591 constraint (is_pc, BAD_PC_ADDRESSING);
c19d1205
ZW
10592 constraint (is_t || is_d, _("cannot use register index with this instruction"));
10593 constraint (inst.operands[i].negative,
10594 _("Thumb does not support negative register indexing"));
10595 constraint (inst.operands[i].postind,
10596 _("Thumb does not support register post-indexing"));
10597 constraint (inst.operands[i].writeback,
10598 _("Thumb does not support register indexing with writeback"));
10599 constraint (inst.operands[i].shifted && inst.operands[i].shift_kind != SHIFT_LSL,
10600 _("Thumb supports only LSL in shifted register indexing"));
b99bd4ef 10601
f40d1643 10602 inst.instruction |= inst.operands[i].imm;
c19d1205 10603 if (inst.operands[i].shifted)
b99bd4ef 10604 {
e2b0ab59 10605 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 10606 _("expression too complex"));
e2b0ab59
AV
10607 constraint (inst.relocs[0].exp.X_add_number < 0
10608 || inst.relocs[0].exp.X_add_number > 3,
c19d1205 10609 _("shift out of range"));
e2b0ab59 10610 inst.instruction |= inst.relocs[0].exp.X_add_number << 4;
c19d1205 10611 }
e2b0ab59 10612 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
10613 }
10614 else if (inst.operands[i].preind)
10615 {
5be8be5d 10616 constraint (is_pc && inst.operands[i].writeback, BAD_PC_WRITEBACK);
f40d1643 10617 constraint (is_t && inst.operands[i].writeback,
c19d1205 10618 _("cannot use writeback with this instruction"));
4755303e
WN
10619 constraint (is_pc && ((inst.instruction & THUMB2_LOAD_BIT) == 0),
10620 BAD_PC_ADDRESSING);
c19d1205
ZW
10621
10622 if (is_d)
10623 {
10624 inst.instruction |= 0x01000000;
10625 if (inst.operands[i].writeback)
10626 inst.instruction |= 0x00200000;
b99bd4ef 10627 }
c19d1205 10628 else
b99bd4ef 10629 {
c19d1205
ZW
10630 inst.instruction |= 0x00000c00;
10631 if (inst.operands[i].writeback)
10632 inst.instruction |= 0x00000100;
b99bd4ef 10633 }
e2b0ab59 10634 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
b99bd4ef 10635 }
c19d1205 10636 else if (inst.operands[i].postind)
b99bd4ef 10637 {
9c2799c2 10638 gas_assert (inst.operands[i].writeback);
c19d1205
ZW
10639 constraint (is_pc, _("cannot use post-indexing with PC-relative addressing"));
10640 constraint (is_t, _("cannot use post-indexing with this instruction"));
10641
10642 if (is_d)
10643 inst.instruction |= 0x00200000;
10644 else
10645 inst.instruction |= 0x00000900;
e2b0ab59 10646 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_IMM;
c19d1205
ZW
10647 }
10648 else /* unindexed - only for coprocessor */
10649 inst.error = _("instruction does not accept unindexed addressing");
10650}
10651
10652/* Table of Thumb instructions which exist in both 16- and 32-bit
10653 encodings (the latter only in post-V6T2 cores). The index is the
10654 value used in the insns table below. When there is more than one
10655 possible 16-bit encoding for the instruction, this table always
0110f2b8
PB
10656 holds variant (1).
10657 Also contains several pseudo-instructions used during relaxation. */
c19d1205 10658#define T16_32_TAB \
21d799b5
NC
10659 X(_adc, 4140, eb400000), \
10660 X(_adcs, 4140, eb500000), \
10661 X(_add, 1c00, eb000000), \
10662 X(_adds, 1c00, eb100000), \
10663 X(_addi, 0000, f1000000), \
10664 X(_addis, 0000, f1100000), \
10665 X(_add_pc,000f, f20f0000), \
10666 X(_add_sp,000d, f10d0000), \
10667 X(_adr, 000f, f20f0000), \
10668 X(_and, 4000, ea000000), \
10669 X(_ands, 4000, ea100000), \
10670 X(_asr, 1000, fa40f000), \
10671 X(_asrs, 1000, fa50f000), \
10672 X(_b, e000, f000b000), \
10673 X(_bcond, d000, f0008000), \
4389b29a 10674 X(_bf, 0000, f040e001), \
f6b2b12d 10675 X(_bfcsel,0000, f000e001), \
f1c7f421 10676 X(_bfx, 0000, f060e001), \
65d1bc05 10677 X(_bfl, 0000, f000c001), \
f1c7f421 10678 X(_bflx, 0000, f070e001), \
21d799b5
NC
10679 X(_bic, 4380, ea200000), \
10680 X(_bics, 4380, ea300000), \
10681 X(_cmn, 42c0, eb100f00), \
10682 X(_cmp, 2800, ebb00f00), \
10683 X(_cpsie, b660, f3af8400), \
10684 X(_cpsid, b670, f3af8600), \
10685 X(_cpy, 4600, ea4f0000), \
10686 X(_dec_sp,80dd, f1ad0d00), \
60f993ce 10687 X(_dls, 0000, f040e001), \
21d799b5
NC
10688 X(_eor, 4040, ea800000), \
10689 X(_eors, 4040, ea900000), \
10690 X(_inc_sp,00dd, f10d0d00), \
10691 X(_ldmia, c800, e8900000), \
10692 X(_ldr, 6800, f8500000), \
10693 X(_ldrb, 7800, f8100000), \
10694 X(_ldrh, 8800, f8300000), \
10695 X(_ldrsb, 5600, f9100000), \
10696 X(_ldrsh, 5e00, f9300000), \
10697 X(_ldr_pc,4800, f85f0000), \
10698 X(_ldr_pc2,4800, f85f0000), \
10699 X(_ldr_sp,9800, f85d0000), \
60f993ce 10700 X(_le, 0000, f00fc001), \
21d799b5
NC
10701 X(_lsl, 0000, fa00f000), \
10702 X(_lsls, 0000, fa10f000), \
10703 X(_lsr, 0800, fa20f000), \
10704 X(_lsrs, 0800, fa30f000), \
10705 X(_mov, 2000, ea4f0000), \
10706 X(_movs, 2000, ea5f0000), \
10707 X(_mul, 4340, fb00f000), \
10708 X(_muls, 4340, ffffffff), /* no 32b muls */ \
10709 X(_mvn, 43c0, ea6f0000), \
10710 X(_mvns, 43c0, ea7f0000), \
10711 X(_neg, 4240, f1c00000), /* rsb #0 */ \
10712 X(_negs, 4240, f1d00000), /* rsbs #0 */ \
10713 X(_orr, 4300, ea400000), \
10714 X(_orrs, 4300, ea500000), \
10715 X(_pop, bc00, e8bd0000), /* ldmia sp!,... */ \
10716 X(_push, b400, e92d0000), /* stmdb sp!,... */ \
10717 X(_rev, ba00, fa90f080), \
10718 X(_rev16, ba40, fa90f090), \
10719 X(_revsh, bac0, fa90f0b0), \
10720 X(_ror, 41c0, fa60f000), \
10721 X(_rors, 41c0, fa70f000), \
10722 X(_sbc, 4180, eb600000), \
10723 X(_sbcs, 4180, eb700000), \
10724 X(_stmia, c000, e8800000), \
10725 X(_str, 6000, f8400000), \
10726 X(_strb, 7000, f8000000), \
10727 X(_strh, 8000, f8200000), \
10728 X(_str_sp,9000, f84d0000), \
10729 X(_sub, 1e00, eba00000), \
10730 X(_subs, 1e00, ebb00000), \
10731 X(_subi, 8000, f1a00000), \
10732 X(_subis, 8000, f1b00000), \
10733 X(_sxtb, b240, fa4ff080), \
10734 X(_sxth, b200, fa0ff080), \
10735 X(_tst, 4200, ea100f00), \
10736 X(_uxtb, b2c0, fa5ff080), \
10737 X(_uxth, b280, fa1ff080), \
10738 X(_nop, bf00, f3af8000), \
10739 X(_yield, bf10, f3af8001), \
10740 X(_wfe, bf20, f3af8002), \
10741 X(_wfi, bf30, f3af8003), \
60f993ce 10742 X(_wls, 0000, f040c001), \
53c4b28b 10743 X(_sev, bf40, f3af8004), \
74db7efb
NC
10744 X(_sevl, bf50, f3af8005), \
10745 X(_udf, de00, f7f0a000)
c19d1205
ZW
10746
10747/* To catch errors in encoding functions, the codes are all offset by
10748 0xF800, putting them in one of the 32-bit prefix ranges, ergo undefined
10749 as 16-bit instructions. */
21d799b5 10750#define X(a,b,c) T_MNEM##a
c19d1205
ZW
10751enum t16_32_codes { T16_32_OFFSET = 0xF7FF, T16_32_TAB };
10752#undef X
10753
10754#define X(a,b,c) 0x##b
10755static const unsigned short thumb_op16[] = { T16_32_TAB };
10756#define THUMB_OP16(n) (thumb_op16[(n) - (T16_32_OFFSET + 1)])
10757#undef X
10758
10759#define X(a,b,c) 0x##c
10760static const unsigned int thumb_op32[] = { T16_32_TAB };
c921be7d
NC
10761#define THUMB_OP32(n) (thumb_op32[(n) - (T16_32_OFFSET + 1)])
10762#define THUMB_SETS_FLAGS(n) (THUMB_OP32 (n) & 0x00100000)
c19d1205
ZW
10763#undef X
10764#undef T16_32_TAB
10765
10766/* Thumb instruction encoders, in alphabetical order. */
10767
92e90b6e 10768/* ADDW or SUBW. */
c921be7d 10769
92e90b6e
PB
10770static void
10771do_t_add_sub_w (void)
10772{
10773 int Rd, Rn;
10774
10775 Rd = inst.operands[0].reg;
10776 Rn = inst.operands[1].reg;
10777
539d4391
NC
10778 /* If Rn is REG_PC, this is ADR; if Rn is REG_SP, then this
10779 is the SP-{plus,minus}-immediate form of the instruction. */
10780 if (Rn == REG_SP)
10781 constraint (Rd == REG_PC, BAD_PC);
10782 else
10783 reject_bad_reg (Rd);
fdfde340 10784
92e90b6e 10785 inst.instruction |= (Rn << 16) | (Rd << 8);
e2b0ab59 10786 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
92e90b6e
PB
10787}
10788
c19d1205 10789/* Parse an add or subtract instruction. We get here with inst.instruction
33eaf5de 10790 equaling any of THUMB_OPCODE_add, adds, sub, or subs. */
c19d1205
ZW
10791
10792static void
10793do_t_add_sub (void)
10794{
10795 int Rd, Rs, Rn;
10796
10797 Rd = inst.operands[0].reg;
10798 Rs = (inst.operands[1].present
10799 ? inst.operands[1].reg /* Rd, Rs, foo */
10800 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
10801
e07e6e58
NC
10802 if (Rd == REG_PC)
10803 set_it_insn_type_last ();
10804
c19d1205
ZW
10805 if (unified_syntax)
10806 {
0110f2b8
PB
10807 bfd_boolean flags;
10808 bfd_boolean narrow;
10809 int opcode;
10810
10811 flags = (inst.instruction == T_MNEM_adds
10812 || inst.instruction == T_MNEM_subs);
10813 if (flags)
e07e6e58 10814 narrow = !in_it_block ();
0110f2b8 10815 else
e07e6e58 10816 narrow = in_it_block ();
c19d1205 10817 if (!inst.operands[2].isreg)
b99bd4ef 10818 {
16805f35
PB
10819 int add;
10820
5c8ed6a4
JW
10821 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
10822 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340 10823
16805f35
PB
10824 add = (inst.instruction == T_MNEM_add
10825 || inst.instruction == T_MNEM_adds);
0110f2b8
PB
10826 opcode = 0;
10827 if (inst.size_req != 4)
10828 {
0110f2b8 10829 /* Attempt to use a narrow opcode, with relaxation if
477330fc 10830 appropriate. */
0110f2b8
PB
10831 if (Rd == REG_SP && Rs == REG_SP && !flags)
10832 opcode = add ? T_MNEM_inc_sp : T_MNEM_dec_sp;
10833 else if (Rd <= 7 && Rs == REG_SP && add && !flags)
10834 opcode = T_MNEM_add_sp;
10835 else if (Rd <= 7 && Rs == REG_PC && add && !flags)
10836 opcode = T_MNEM_add_pc;
10837 else if (Rd <= 7 && Rs <= 7 && narrow)
10838 {
10839 if (flags)
10840 opcode = add ? T_MNEM_addis : T_MNEM_subis;
10841 else
10842 opcode = add ? T_MNEM_addi : T_MNEM_subi;
10843 }
10844 if (opcode)
10845 {
10846 inst.instruction = THUMB_OP16(opcode);
10847 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59
AV
10848 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
10849 || (inst.relocs[0].type
10850 > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC))
a9f02af8
MG
10851 {
10852 if (inst.size_req == 2)
e2b0ab59 10853 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
a9f02af8
MG
10854 else
10855 inst.relax = opcode;
10856 }
0110f2b8
PB
10857 }
10858 else
10859 constraint (inst.size_req == 2, BAD_HIREG);
10860 }
10861 if (inst.size_req == 4
10862 || (inst.size_req != 2 && !opcode))
10863 {
e2b0ab59
AV
10864 constraint ((inst.relocs[0].type
10865 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
10866 && (inst.relocs[0].type
10867 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8 10868 THUMB1_RELOC_ONLY);
efd81785
PB
10869 if (Rd == REG_PC)
10870 {
fdfde340 10871 constraint (add, BAD_PC);
efd81785
PB
10872 constraint (Rs != REG_LR || inst.instruction != T_MNEM_subs,
10873 _("only SUBS PC, LR, #const allowed"));
e2b0ab59 10874 constraint (inst.relocs[0].exp.X_op != O_constant,
efd81785 10875 _("expression too complex"));
e2b0ab59
AV
10876 constraint (inst.relocs[0].exp.X_add_number < 0
10877 || inst.relocs[0].exp.X_add_number > 0xff,
efd81785
PB
10878 _("immediate value out of range"));
10879 inst.instruction = T2_SUBS_PC_LR
e2b0ab59
AV
10880 | inst.relocs[0].exp.X_add_number;
10881 inst.relocs[0].type = BFD_RELOC_UNUSED;
efd81785
PB
10882 return;
10883 }
10884 else if (Rs == REG_PC)
16805f35
PB
10885 {
10886 /* Always use addw/subw. */
10887 inst.instruction = add ? 0xf20f0000 : 0xf2af0000;
e2b0ab59 10888 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMM12;
16805f35
PB
10889 }
10890 else
10891 {
10892 inst.instruction = THUMB_OP32 (inst.instruction);
10893 inst.instruction = (inst.instruction & 0xe1ffffff)
10894 | 0x10000000;
10895 if (flags)
e2b0ab59 10896 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
16805f35 10897 else
e2b0ab59 10898 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_IMM;
16805f35 10899 }
dc4503c6
PB
10900 inst.instruction |= Rd << 8;
10901 inst.instruction |= Rs << 16;
0110f2b8 10902 }
b99bd4ef 10903 }
c19d1205
ZW
10904 else
10905 {
e2b0ab59 10906 unsigned int value = inst.relocs[0].exp.X_add_number;
5f4cb198
NC
10907 unsigned int shift = inst.operands[2].shift_kind;
10908
c19d1205
ZW
10909 Rn = inst.operands[2].reg;
10910 /* See if we can do this with a 16-bit instruction. */
10911 if (!inst.operands[2].shifted && inst.size_req != 4)
10912 {
e27ec89e
PB
10913 if (Rd > 7 || Rs > 7 || Rn > 7)
10914 narrow = FALSE;
10915
10916 if (narrow)
c19d1205 10917 {
e27ec89e
PB
10918 inst.instruction = ((inst.instruction == T_MNEM_adds
10919 || inst.instruction == T_MNEM_add)
c19d1205
ZW
10920 ? T_OPCODE_ADD_R3
10921 : T_OPCODE_SUB_R3);
10922 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
10923 return;
10924 }
b99bd4ef 10925
7e806470 10926 if (inst.instruction == T_MNEM_add && (Rd == Rs || Rd == Rn))
c19d1205 10927 {
7e806470
PB
10928 /* Thumb-1 cores (except v6-M) require at least one high
10929 register in a narrow non flag setting add. */
10930 if (Rd > 7 || Rn > 7
10931 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2)
10932 || ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_msr))
c19d1205 10933 {
7e806470
PB
10934 if (Rd == Rn)
10935 {
10936 Rn = Rs;
10937 Rs = Rd;
10938 }
c19d1205
ZW
10939 inst.instruction = T_OPCODE_ADD_HI;
10940 inst.instruction |= (Rd & 8) << 4;
10941 inst.instruction |= (Rd & 7);
10942 inst.instruction |= Rn << 3;
10943 return;
10944 }
c19d1205
ZW
10945 }
10946 }
c921be7d 10947
fdfde340 10948 constraint (Rd == REG_PC, BAD_PC);
5c8ed6a4
JW
10949 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
10950 constraint (Rd == REG_SP && Rs != REG_SP, BAD_SP);
fdfde340
JM
10951 constraint (Rs == REG_PC, BAD_PC);
10952 reject_bad_reg (Rn);
10953
c19d1205
ZW
10954 /* If we get here, it can't be done in 16 bits. */
10955 constraint (inst.operands[2].shifted && inst.operands[2].immisreg,
10956 _("shift must be constant"));
10957 inst.instruction = THUMB_OP32 (inst.instruction);
10958 inst.instruction |= Rd << 8;
10959 inst.instruction |= Rs << 16;
5f4cb198
NC
10960 constraint (Rd == REG_SP && Rs == REG_SP && value > 3,
10961 _("shift value over 3 not allowed in thumb mode"));
10962 constraint (Rd == REG_SP && Rs == REG_SP && shift != SHIFT_LSL,
10963 _("only LSL shift allowed in thumb mode"));
c19d1205
ZW
10964 encode_thumb32_shifted_operand (2);
10965 }
10966 }
10967 else
10968 {
10969 constraint (inst.instruction == T_MNEM_adds
10970 || inst.instruction == T_MNEM_subs,
10971 BAD_THUMB32);
b99bd4ef 10972
c19d1205 10973 if (!inst.operands[2].isreg) /* Rd, Rs, #imm */
b99bd4ef 10974 {
c19d1205
ZW
10975 constraint ((Rd > 7 && (Rd != REG_SP || Rs != REG_SP))
10976 || (Rs > 7 && Rs != REG_SP && Rs != REG_PC),
10977 BAD_HIREG);
10978
10979 inst.instruction = (inst.instruction == T_MNEM_add
10980 ? 0x0000 : 0x8000);
10981 inst.instruction |= (Rd << 4) | Rs;
e2b0ab59 10982 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
b99bd4ef
NC
10983 return;
10984 }
10985
c19d1205
ZW
10986 Rn = inst.operands[2].reg;
10987 constraint (inst.operands[2].shifted, _("unshifted register required"));
b99bd4ef 10988
c19d1205
ZW
10989 /* We now have Rd, Rs, and Rn set to registers. */
10990 if (Rd > 7 || Rs > 7 || Rn > 7)
b99bd4ef 10991 {
c19d1205
ZW
10992 /* Can't do this for SUB. */
10993 constraint (inst.instruction == T_MNEM_sub, BAD_HIREG);
10994 inst.instruction = T_OPCODE_ADD_HI;
10995 inst.instruction |= (Rd & 8) << 4;
10996 inst.instruction |= (Rd & 7);
10997 if (Rs == Rd)
10998 inst.instruction |= Rn << 3;
10999 else if (Rn == Rd)
11000 inst.instruction |= Rs << 3;
11001 else
11002 constraint (1, _("dest must overlap one source register"));
11003 }
11004 else
11005 {
11006 inst.instruction = (inst.instruction == T_MNEM_add
11007 ? T_OPCODE_ADD_R3 : T_OPCODE_SUB_R3);
11008 inst.instruction |= Rd | (Rs << 3) | (Rn << 6);
b99bd4ef 11009 }
b99bd4ef 11010 }
b99bd4ef
NC
11011}
11012
c19d1205
ZW
11013static void
11014do_t_adr (void)
11015{
fdfde340
JM
11016 unsigned Rd;
11017
11018 Rd = inst.operands[0].reg;
11019 reject_bad_reg (Rd);
11020
11021 if (unified_syntax && inst.size_req == 0 && Rd <= 7)
0110f2b8
PB
11022 {
11023 /* Defer to section relaxation. */
11024 inst.relax = inst.instruction;
11025 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 11026 inst.instruction |= Rd << 4;
0110f2b8
PB
11027 }
11028 else if (unified_syntax && inst.size_req != 2)
e9f89963 11029 {
0110f2b8 11030 /* Generate a 32-bit opcode. */
e9f89963 11031 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 11032 inst.instruction |= Rd << 8;
e2b0ab59
AV
11033 inst.relocs[0].type = BFD_RELOC_ARM_T32_ADD_PC12;
11034 inst.relocs[0].pc_rel = 1;
e9f89963
PB
11035 }
11036 else
11037 {
0110f2b8 11038 /* Generate a 16-bit opcode. */
e9f89963 11039 inst.instruction = THUMB_OP16 (inst.instruction);
e2b0ab59
AV
11040 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_ADD;
11041 inst.relocs[0].exp.X_add_number -= 4; /* PC relative adjust. */
11042 inst.relocs[0].pc_rel = 1;
fdfde340 11043 inst.instruction |= Rd << 4;
e9f89963 11044 }
52a86f84 11045
e2b0ab59
AV
11046 if (inst.relocs[0].exp.X_op == O_symbol
11047 && inst.relocs[0].exp.X_add_symbol != NULL
11048 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11049 && THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11050 inst.relocs[0].exp.X_add_number += 1;
c19d1205 11051}
b99bd4ef 11052
c19d1205
ZW
11053/* Arithmetic instructions for which there is just one 16-bit
11054 instruction encoding, and it allows only two low registers.
11055 For maximal compatibility with ARM syntax, we allow three register
11056 operands even when Thumb-32 instructions are not available, as long
11057 as the first two are identical. For instance, both "sbc r0,r1" and
11058 "sbc r0,r0,r1" are allowed. */
b99bd4ef 11059static void
c19d1205 11060do_t_arit3 (void)
b99bd4ef 11061{
c19d1205 11062 int Rd, Rs, Rn;
b99bd4ef 11063
c19d1205
ZW
11064 Rd = inst.operands[0].reg;
11065 Rs = (inst.operands[1].present
11066 ? inst.operands[1].reg /* Rd, Rs, foo */
11067 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11068 Rn = inst.operands[2].reg;
b99bd4ef 11069
fdfde340
JM
11070 reject_bad_reg (Rd);
11071 reject_bad_reg (Rs);
11072 if (inst.operands[2].isreg)
11073 reject_bad_reg (Rn);
11074
c19d1205 11075 if (unified_syntax)
b99bd4ef 11076 {
c19d1205
ZW
11077 if (!inst.operands[2].isreg)
11078 {
11079 /* For an immediate, we always generate a 32-bit opcode;
11080 section relaxation will shrink it later if possible. */
11081 inst.instruction = THUMB_OP32 (inst.instruction);
11082 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11083 inst.instruction |= Rd << 8;
11084 inst.instruction |= Rs << 16;
e2b0ab59 11085 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
c19d1205
ZW
11086 }
11087 else
11088 {
e27ec89e
PB
11089 bfd_boolean narrow;
11090
c19d1205 11091 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11092 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 11093 narrow = !in_it_block ();
e27ec89e 11094 else
e07e6e58 11095 narrow = in_it_block ();
e27ec89e
PB
11096
11097 if (Rd > 7 || Rn > 7 || Rs > 7)
11098 narrow = FALSE;
11099 if (inst.operands[2].shifted)
11100 narrow = FALSE;
11101 if (inst.size_req == 4)
11102 narrow = FALSE;
11103
11104 if (narrow
c19d1205
ZW
11105 && Rd == Rs)
11106 {
11107 inst.instruction = THUMB_OP16 (inst.instruction);
11108 inst.instruction |= Rd;
11109 inst.instruction |= Rn << 3;
11110 return;
11111 }
b99bd4ef 11112
c19d1205
ZW
11113 /* If we get here, it can't be done in 16 bits. */
11114 constraint (inst.operands[2].shifted
11115 && inst.operands[2].immisreg,
11116 _("shift must be constant"));
11117 inst.instruction = THUMB_OP32 (inst.instruction);
11118 inst.instruction |= Rd << 8;
11119 inst.instruction |= Rs << 16;
11120 encode_thumb32_shifted_operand (2);
11121 }
a737bd4d 11122 }
c19d1205 11123 else
b99bd4ef 11124 {
c19d1205
ZW
11125 /* On its face this is a lie - the instruction does set the
11126 flags. However, the only supported mnemonic in this mode
11127 says it doesn't. */
11128 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11129
c19d1205
ZW
11130 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11131 _("unshifted register required"));
11132 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11133 constraint (Rd != Rs,
11134 _("dest and source1 must be the same register"));
a737bd4d 11135
c19d1205
ZW
11136 inst.instruction = THUMB_OP16 (inst.instruction);
11137 inst.instruction |= Rd;
11138 inst.instruction |= Rn << 3;
b99bd4ef 11139 }
a737bd4d 11140}
b99bd4ef 11141
c19d1205
ZW
11142/* Similarly, but for instructions where the arithmetic operation is
11143 commutative, so we can allow either of them to be different from
11144 the destination operand in a 16-bit instruction. For instance, all
11145 three of "adc r0,r1", "adc r0,r0,r1", and "adc r0,r1,r0" are
11146 accepted. */
11147static void
11148do_t_arit3c (void)
a737bd4d 11149{
c19d1205 11150 int Rd, Rs, Rn;
b99bd4ef 11151
c19d1205
ZW
11152 Rd = inst.operands[0].reg;
11153 Rs = (inst.operands[1].present
11154 ? inst.operands[1].reg /* Rd, Rs, foo */
11155 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
11156 Rn = inst.operands[2].reg;
c921be7d 11157
fdfde340
JM
11158 reject_bad_reg (Rd);
11159 reject_bad_reg (Rs);
11160 if (inst.operands[2].isreg)
11161 reject_bad_reg (Rn);
a737bd4d 11162
c19d1205 11163 if (unified_syntax)
a737bd4d 11164 {
c19d1205 11165 if (!inst.operands[2].isreg)
b99bd4ef 11166 {
c19d1205
ZW
11167 /* For an immediate, we always generate a 32-bit opcode;
11168 section relaxation will shrink it later if possible. */
11169 inst.instruction = THUMB_OP32 (inst.instruction);
11170 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
11171 inst.instruction |= Rd << 8;
11172 inst.instruction |= Rs << 16;
e2b0ab59 11173 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 11174 }
c19d1205 11175 else
a737bd4d 11176 {
e27ec89e
PB
11177 bfd_boolean narrow;
11178
c19d1205 11179 /* See if we can do this with a 16-bit instruction. */
e27ec89e 11180 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 11181 narrow = !in_it_block ();
e27ec89e 11182 else
e07e6e58 11183 narrow = in_it_block ();
e27ec89e
PB
11184
11185 if (Rd > 7 || Rn > 7 || Rs > 7)
11186 narrow = FALSE;
11187 if (inst.operands[2].shifted)
11188 narrow = FALSE;
11189 if (inst.size_req == 4)
11190 narrow = FALSE;
11191
11192 if (narrow)
a737bd4d 11193 {
c19d1205 11194 if (Rd == Rs)
a737bd4d 11195 {
c19d1205
ZW
11196 inst.instruction = THUMB_OP16 (inst.instruction);
11197 inst.instruction |= Rd;
11198 inst.instruction |= Rn << 3;
11199 return;
a737bd4d 11200 }
c19d1205 11201 if (Rd == Rn)
a737bd4d 11202 {
c19d1205
ZW
11203 inst.instruction = THUMB_OP16 (inst.instruction);
11204 inst.instruction |= Rd;
11205 inst.instruction |= Rs << 3;
11206 return;
a737bd4d
NC
11207 }
11208 }
c19d1205
ZW
11209
11210 /* If we get here, it can't be done in 16 bits. */
11211 constraint (inst.operands[2].shifted
11212 && inst.operands[2].immisreg,
11213 _("shift must be constant"));
11214 inst.instruction = THUMB_OP32 (inst.instruction);
11215 inst.instruction |= Rd << 8;
11216 inst.instruction |= Rs << 16;
11217 encode_thumb32_shifted_operand (2);
a737bd4d 11218 }
b99bd4ef 11219 }
c19d1205
ZW
11220 else
11221 {
11222 /* On its face this is a lie - the instruction does set the
11223 flags. However, the only supported mnemonic in this mode
11224 says it doesn't. */
11225 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
a737bd4d 11226
c19d1205
ZW
11227 constraint (!inst.operands[2].isreg || inst.operands[2].shifted,
11228 _("unshifted register required"));
11229 constraint (Rd > 7 || Rs > 7 || Rn > 7, BAD_HIREG);
11230
11231 inst.instruction = THUMB_OP16 (inst.instruction);
11232 inst.instruction |= Rd;
11233
11234 if (Rd == Rs)
11235 inst.instruction |= Rn << 3;
11236 else if (Rd == Rn)
11237 inst.instruction |= Rs << 3;
11238 else
11239 constraint (1, _("dest must overlap one source register"));
11240 }
a737bd4d
NC
11241}
11242
c19d1205
ZW
11243static void
11244do_t_bfc (void)
a737bd4d 11245{
fdfde340 11246 unsigned Rd;
c19d1205
ZW
11247 unsigned int msb = inst.operands[1].imm + inst.operands[2].imm;
11248 constraint (msb > 32, _("bit-field extends past end of register"));
11249 /* The instruction encoding stores the LSB and MSB,
11250 not the LSB and width. */
fdfde340
JM
11251 Rd = inst.operands[0].reg;
11252 reject_bad_reg (Rd);
11253 inst.instruction |= Rd << 8;
c19d1205
ZW
11254 inst.instruction |= (inst.operands[1].imm & 0x1c) << 10;
11255 inst.instruction |= (inst.operands[1].imm & 0x03) << 6;
11256 inst.instruction |= msb - 1;
b99bd4ef
NC
11257}
11258
c19d1205
ZW
11259static void
11260do_t_bfi (void)
b99bd4ef 11261{
fdfde340 11262 int Rd, Rn;
c19d1205 11263 unsigned int msb;
b99bd4ef 11264
fdfde340
JM
11265 Rd = inst.operands[0].reg;
11266 reject_bad_reg (Rd);
11267
c19d1205
ZW
11268 /* #0 in second position is alternative syntax for bfc, which is
11269 the same instruction but with REG_PC in the Rm field. */
11270 if (!inst.operands[1].isreg)
fdfde340
JM
11271 Rn = REG_PC;
11272 else
11273 {
11274 Rn = inst.operands[1].reg;
11275 reject_bad_reg (Rn);
11276 }
b99bd4ef 11277
c19d1205
ZW
11278 msb = inst.operands[2].imm + inst.operands[3].imm;
11279 constraint (msb > 32, _("bit-field extends past end of register"));
11280 /* The instruction encoding stores the LSB and MSB,
11281 not the LSB and width. */
fdfde340
JM
11282 inst.instruction |= Rd << 8;
11283 inst.instruction |= Rn << 16;
c19d1205
ZW
11284 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11285 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11286 inst.instruction |= msb - 1;
b99bd4ef
NC
11287}
11288
c19d1205
ZW
11289static void
11290do_t_bfx (void)
b99bd4ef 11291{
fdfde340
JM
11292 unsigned Rd, Rn;
11293
11294 Rd = inst.operands[0].reg;
11295 Rn = inst.operands[1].reg;
11296
11297 reject_bad_reg (Rd);
11298 reject_bad_reg (Rn);
11299
c19d1205
ZW
11300 constraint (inst.operands[2].imm + inst.operands[3].imm > 32,
11301 _("bit-field extends past end of register"));
fdfde340
JM
11302 inst.instruction |= Rd << 8;
11303 inst.instruction |= Rn << 16;
c19d1205
ZW
11304 inst.instruction |= (inst.operands[2].imm & 0x1c) << 10;
11305 inst.instruction |= (inst.operands[2].imm & 0x03) << 6;
11306 inst.instruction |= inst.operands[3].imm - 1;
11307}
b99bd4ef 11308
c19d1205
ZW
11309/* ARM V5 Thumb BLX (argument parse)
11310 BLX <target_addr> which is BLX(1)
11311 BLX <Rm> which is BLX(2)
11312 Unfortunately, there are two different opcodes for this mnemonic.
11313 So, the insns[].value is not used, and the code here zaps values
11314 into inst.instruction.
b99bd4ef 11315
c19d1205
ZW
11316 ??? How to take advantage of the additional two bits of displacement
11317 available in Thumb32 mode? Need new relocation? */
b99bd4ef 11318
c19d1205
ZW
11319static void
11320do_t_blx (void)
11321{
e07e6e58
NC
11322 set_it_insn_type_last ();
11323
c19d1205 11324 if (inst.operands[0].isreg)
fdfde340
JM
11325 {
11326 constraint (inst.operands[0].reg == REG_PC, BAD_PC);
11327 /* We have a register, so this is BLX(2). */
11328 inst.instruction |= inst.operands[0].reg << 3;
11329 }
b99bd4ef
NC
11330 else
11331 {
c19d1205 11332 /* No register. This must be BLX(1). */
2fc8bdac 11333 inst.instruction = 0xf000e800;
0855e32b 11334 encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
b99bd4ef
NC
11335 }
11336}
11337
c19d1205
ZW
11338static void
11339do_t_branch (void)
b99bd4ef 11340{
0110f2b8 11341 int opcode;
dfa9f0d5 11342 int cond;
2fe88214 11343 bfd_reloc_code_real_type reloc;
dfa9f0d5 11344
e07e6e58
NC
11345 cond = inst.cond;
11346 set_it_insn_type (IF_INSIDE_IT_LAST_INSN);
11347
11348 if (in_it_block ())
dfa9f0d5
PB
11349 {
11350 /* Conditional branches inside IT blocks are encoded as unconditional
477330fc 11351 branches. */
dfa9f0d5 11352 cond = COND_ALWAYS;
dfa9f0d5
PB
11353 }
11354 else
11355 cond = inst.cond;
11356
11357 if (cond != COND_ALWAYS)
0110f2b8
PB
11358 opcode = T_MNEM_bcond;
11359 else
11360 opcode = inst.instruction;
11361
12d6b0b7
RS
11362 if (unified_syntax
11363 && (inst.size_req == 4
10960bfb
PB
11364 || (inst.size_req != 2
11365 && (inst.operands[0].hasreloc
e2b0ab59 11366 || inst.relocs[0].exp.X_op == O_constant))))
c19d1205 11367 {
0110f2b8 11368 inst.instruction = THUMB_OP32(opcode);
dfa9f0d5 11369 if (cond == COND_ALWAYS)
9ae92b05 11370 reloc = BFD_RELOC_THUMB_PCREL_BRANCH25;
c19d1205
ZW
11371 else
11372 {
ff8646ee
TP
11373 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2),
11374 _("selected architecture does not support "
11375 "wide conditional branch instruction"));
11376
9c2799c2 11377 gas_assert (cond != 0xF);
dfa9f0d5 11378 inst.instruction |= cond << 22;
9ae92b05 11379 reloc = BFD_RELOC_THUMB_PCREL_BRANCH20;
c19d1205
ZW
11380 }
11381 }
b99bd4ef
NC
11382 else
11383 {
0110f2b8 11384 inst.instruction = THUMB_OP16(opcode);
dfa9f0d5 11385 if (cond == COND_ALWAYS)
9ae92b05 11386 reloc = BFD_RELOC_THUMB_PCREL_BRANCH12;
c19d1205 11387 else
b99bd4ef 11388 {
dfa9f0d5 11389 inst.instruction |= cond << 8;
9ae92b05 11390 reloc = BFD_RELOC_THUMB_PCREL_BRANCH9;
b99bd4ef 11391 }
0110f2b8
PB
11392 /* Allow section relaxation. */
11393 if (unified_syntax && inst.size_req != 2)
11394 inst.relax = opcode;
b99bd4ef 11395 }
e2b0ab59
AV
11396 inst.relocs[0].type = reloc;
11397 inst.relocs[0].pc_rel = 1;
b99bd4ef
NC
11398}
11399
8884b720 11400/* Actually do the work for Thumb state bkpt and hlt. The only difference
bacebabc 11401 between the two is the maximum immediate allowed - which is passed in
8884b720 11402 RANGE. */
b99bd4ef 11403static void
8884b720 11404do_t_bkpt_hlt1 (int range)
b99bd4ef 11405{
dfa9f0d5
PB
11406 constraint (inst.cond != COND_ALWAYS,
11407 _("instruction is always unconditional"));
c19d1205 11408 if (inst.operands[0].present)
b99bd4ef 11409 {
8884b720 11410 constraint (inst.operands[0].imm > range,
c19d1205
ZW
11411 _("immediate value out of range"));
11412 inst.instruction |= inst.operands[0].imm;
b99bd4ef 11413 }
8884b720
MGD
11414
11415 set_it_insn_type (NEUTRAL_IT_INSN);
11416}
11417
11418static void
11419do_t_hlt (void)
11420{
11421 do_t_bkpt_hlt1 (63);
11422}
11423
11424static void
11425do_t_bkpt (void)
11426{
11427 do_t_bkpt_hlt1 (255);
b99bd4ef
NC
11428}
11429
11430static void
c19d1205 11431do_t_branch23 (void)
b99bd4ef 11432{
e07e6e58 11433 set_it_insn_type_last ();
0855e32b 11434 encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
fa94de6b 11435
0855e32b
NS
11436 /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
11437 this file. We used to simply ignore the PLT reloc type here --
11438 the branch encoding is now needed to deal with TLSCALL relocs.
11439 So if we see a PLT reloc now, put it back to how it used to be to
11440 keep the preexisting behaviour. */
e2b0ab59
AV
11441 if (inst.relocs[0].type == BFD_RELOC_ARM_PLT32)
11442 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH23;
90e4755a 11443
4343666d 11444#if defined(OBJ_COFF)
c19d1205
ZW
11445 /* If the destination of the branch is a defined symbol which does not have
11446 the THUMB_FUNC attribute, then we must be calling a function which has
11447 the (interfacearm) attribute. We look for the Thumb entry point to that
11448 function and change the branch to refer to that function instead. */
e2b0ab59
AV
11449 if ( inst.relocs[0].exp.X_op == O_symbol
11450 && inst.relocs[0].exp.X_add_symbol != NULL
11451 && S_IS_DEFINED (inst.relocs[0].exp.X_add_symbol)
11452 && ! THUMB_IS_FUNC (inst.relocs[0].exp.X_add_symbol))
11453 inst.relocs[0].exp.X_add_symbol
11454 = find_real_start (inst.relocs[0].exp.X_add_symbol);
4343666d 11455#endif
90e4755a
RE
11456}
11457
11458static void
c19d1205 11459do_t_bx (void)
90e4755a 11460{
e07e6e58 11461 set_it_insn_type_last ();
c19d1205
ZW
11462 inst.instruction |= inst.operands[0].reg << 3;
11463 /* ??? FIXME: Should add a hacky reloc here if reg is REG_PC. The reloc
11464 should cause the alignment to be checked once it is known. This is
11465 because BX PC only works if the instruction is word aligned. */
11466}
90e4755a 11467
c19d1205
ZW
11468static void
11469do_t_bxj (void)
11470{
fdfde340 11471 int Rm;
90e4755a 11472
e07e6e58 11473 set_it_insn_type_last ();
fdfde340
JM
11474 Rm = inst.operands[0].reg;
11475 reject_bad_reg (Rm);
11476 inst.instruction |= Rm << 16;
90e4755a
RE
11477}
11478
11479static void
c19d1205 11480do_t_clz (void)
90e4755a 11481{
fdfde340
JM
11482 unsigned Rd;
11483 unsigned Rm;
11484
11485 Rd = inst.operands[0].reg;
11486 Rm = inst.operands[1].reg;
11487
11488 reject_bad_reg (Rd);
11489 reject_bad_reg (Rm);
11490
11491 inst.instruction |= Rd << 8;
11492 inst.instruction |= Rm << 16;
11493 inst.instruction |= Rm;
c19d1205 11494}
90e4755a 11495
91d8b670
JG
11496static void
11497do_t_csdb (void)
11498{
11499 set_it_insn_type (OUTSIDE_IT_INSN);
11500}
11501
dfa9f0d5
PB
11502static void
11503do_t_cps (void)
11504{
e07e6e58 11505 set_it_insn_type (OUTSIDE_IT_INSN);
dfa9f0d5
PB
11506 inst.instruction |= inst.operands[0].imm;
11507}
11508
c19d1205
ZW
11509static void
11510do_t_cpsi (void)
11511{
e07e6e58 11512 set_it_insn_type (OUTSIDE_IT_INSN);
c19d1205 11513 if (unified_syntax
62b3e311
PB
11514 && (inst.operands[1].present || inst.size_req == 4)
11515 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6_notm))
90e4755a 11516 {
c19d1205
ZW
11517 unsigned int imod = (inst.instruction & 0x0030) >> 4;
11518 inst.instruction = 0xf3af8000;
11519 inst.instruction |= imod << 9;
11520 inst.instruction |= inst.operands[0].imm << 5;
11521 if (inst.operands[1].present)
11522 inst.instruction |= 0x100 | inst.operands[1].imm;
90e4755a 11523 }
c19d1205 11524 else
90e4755a 11525 {
62b3e311
PB
11526 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1)
11527 && (inst.operands[0].imm & 4),
11528 _("selected processor does not support 'A' form "
11529 "of this instruction"));
11530 constraint (inst.operands[1].present || inst.size_req == 4,
c19d1205
ZW
11531 _("Thumb does not support the 2-argument "
11532 "form of this instruction"));
11533 inst.instruction |= inst.operands[0].imm;
90e4755a 11534 }
90e4755a
RE
11535}
11536
c19d1205
ZW
11537/* THUMB CPY instruction (argument parse). */
11538
90e4755a 11539static void
c19d1205 11540do_t_cpy (void)
90e4755a 11541{
c19d1205 11542 if (inst.size_req == 4)
90e4755a 11543 {
c19d1205
ZW
11544 inst.instruction = THUMB_OP32 (T_MNEM_mov);
11545 inst.instruction |= inst.operands[0].reg << 8;
11546 inst.instruction |= inst.operands[1].reg;
90e4755a 11547 }
c19d1205 11548 else
90e4755a 11549 {
c19d1205
ZW
11550 inst.instruction |= (inst.operands[0].reg & 0x8) << 4;
11551 inst.instruction |= (inst.operands[0].reg & 0x7);
11552 inst.instruction |= inst.operands[1].reg << 3;
90e4755a 11553 }
90e4755a
RE
11554}
11555
90e4755a 11556static void
25fe350b 11557do_t_cbz (void)
90e4755a 11558{
e07e6e58 11559 set_it_insn_type (OUTSIDE_IT_INSN);
c19d1205
ZW
11560 constraint (inst.operands[0].reg > 7, BAD_HIREG);
11561 inst.instruction |= inst.operands[0].reg;
e2b0ab59
AV
11562 inst.relocs[0].pc_rel = 1;
11563 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH7;
c19d1205 11564}
90e4755a 11565
62b3e311
PB
11566static void
11567do_t_dbg (void)
11568{
11569 inst.instruction |= inst.operands[0].imm;
11570}
11571
11572static void
11573do_t_div (void)
11574{
fdfde340
JM
11575 unsigned Rd, Rn, Rm;
11576
11577 Rd = inst.operands[0].reg;
11578 Rn = (inst.operands[1].present
11579 ? inst.operands[1].reg : Rd);
11580 Rm = inst.operands[2].reg;
11581
11582 reject_bad_reg (Rd);
11583 reject_bad_reg (Rn);
11584 reject_bad_reg (Rm);
11585
11586 inst.instruction |= Rd << 8;
11587 inst.instruction |= Rn << 16;
11588 inst.instruction |= Rm;
62b3e311
PB
11589}
11590
c19d1205
ZW
11591static void
11592do_t_hint (void)
11593{
11594 if (unified_syntax && inst.size_req == 4)
11595 inst.instruction = THUMB_OP32 (inst.instruction);
11596 else
11597 inst.instruction = THUMB_OP16 (inst.instruction);
11598}
90e4755a 11599
c19d1205
ZW
11600static void
11601do_t_it (void)
11602{
11603 unsigned int cond = inst.operands[0].imm;
e27ec89e 11604
e07e6e58
NC
11605 set_it_insn_type (IT_INSN);
11606 now_it.mask = (inst.instruction & 0xf) | 0x10;
11607 now_it.cc = cond;
5a01bb1d 11608 now_it.warn_deprecated = FALSE;
e27ec89e
PB
11609
11610 /* If the condition is a negative condition, invert the mask. */
c19d1205 11611 if ((cond & 0x1) == 0x0)
90e4755a 11612 {
c19d1205 11613 unsigned int mask = inst.instruction & 0x000f;
90e4755a 11614
c19d1205 11615 if ((mask & 0x7) == 0)
5a01bb1d
MGD
11616 {
11617 /* No conversion needed. */
11618 now_it.block_length = 1;
11619 }
c19d1205 11620 else if ((mask & 0x3) == 0)
5a01bb1d
MGD
11621 {
11622 mask ^= 0x8;
11623 now_it.block_length = 2;
11624 }
e27ec89e 11625 else if ((mask & 0x1) == 0)
5a01bb1d
MGD
11626 {
11627 mask ^= 0xC;
11628 now_it.block_length = 3;
11629 }
c19d1205 11630 else
5a01bb1d
MGD
11631 {
11632 mask ^= 0xE;
11633 now_it.block_length = 4;
11634 }
90e4755a 11635
e27ec89e
PB
11636 inst.instruction &= 0xfff0;
11637 inst.instruction |= mask;
c19d1205 11638 }
90e4755a 11639
c19d1205
ZW
11640 inst.instruction |= cond << 4;
11641}
90e4755a 11642
3c707909
PB
11643/* Helper function used for both push/pop and ldm/stm. */
11644static void
4b5a202f
AV
11645encode_thumb2_multi (bfd_boolean do_io, int base, unsigned mask,
11646 bfd_boolean writeback)
3c707909 11647{
4b5a202f 11648 bfd_boolean load, store;
3c707909 11649
4b5a202f
AV
11650 gas_assert (base != -1 || !do_io);
11651 load = do_io && ((inst.instruction & (1 << 20)) != 0);
11652 store = do_io && !load;
3c707909
PB
11653
11654 if (mask & (1 << 13))
11655 inst.error = _("SP not allowed in register list");
1e5b0379 11656
4b5a202f 11657 if (do_io && (mask & (1 << base)) != 0
1e5b0379
NC
11658 && writeback)
11659 inst.error = _("having the base register in the register list when "
11660 "using write back is UNPREDICTABLE");
11661
3c707909
PB
11662 if (load)
11663 {
e07e6e58 11664 if (mask & (1 << 15))
477330fc
RM
11665 {
11666 if (mask & (1 << 14))
11667 inst.error = _("LR and PC should not both be in register list");
11668 else
11669 set_it_insn_type_last ();
11670 }
3c707909 11671 }
4b5a202f 11672 else if (store)
3c707909
PB
11673 {
11674 if (mask & (1 << 15))
11675 inst.error = _("PC not allowed in register list");
3c707909
PB
11676 }
11677
4b5a202f 11678 if (do_io && ((mask & (mask - 1)) == 0))
3c707909
PB
11679 {
11680 /* Single register transfers implemented as str/ldr. */
11681 if (writeback)
11682 {
11683 if (inst.instruction & (1 << 23))
11684 inst.instruction = 0x00000b04; /* ia! -> [base], #4 */
11685 else
11686 inst.instruction = 0x00000d04; /* db! -> [base, #-4]! */
11687 }
11688 else
11689 {
11690 if (inst.instruction & (1 << 23))
11691 inst.instruction = 0x00800000; /* ia -> [base] */
11692 else
11693 inst.instruction = 0x00000c04; /* db -> [base, #-4] */
11694 }
11695
11696 inst.instruction |= 0xf8400000;
11697 if (load)
11698 inst.instruction |= 0x00100000;
11699
5f4273c7 11700 mask = ffs (mask) - 1;
3c707909
PB
11701 mask <<= 12;
11702 }
11703 else if (writeback)
11704 inst.instruction |= WRITE_BACK;
11705
11706 inst.instruction |= mask;
4b5a202f
AV
11707 if (do_io)
11708 inst.instruction |= base << 16;
3c707909
PB
11709}
11710
c19d1205
ZW
11711static void
11712do_t_ldmstm (void)
11713{
11714 /* This really doesn't seem worth it. */
e2b0ab59 11715 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205
ZW
11716 _("expression too complex"));
11717 constraint (inst.operands[1].writeback,
11718 _("Thumb load/store multiple does not support {reglist}^"));
90e4755a 11719
c19d1205
ZW
11720 if (unified_syntax)
11721 {
3c707909
PB
11722 bfd_boolean narrow;
11723 unsigned mask;
11724
11725 narrow = FALSE;
c19d1205
ZW
11726 /* See if we can use a 16-bit instruction. */
11727 if (inst.instruction < 0xffff /* not ldmdb/stmdb */
11728 && inst.size_req != 4
3c707909 11729 && !(inst.operands[1].imm & ~0xff))
90e4755a 11730 {
3c707909 11731 mask = 1 << inst.operands[0].reg;
90e4755a 11732
eab4f823 11733 if (inst.operands[0].reg <= 7)
90e4755a 11734 {
3c707909 11735 if (inst.instruction == T_MNEM_stmia
eab4f823
MGD
11736 ? inst.operands[0].writeback
11737 : (inst.operands[0].writeback
11738 == !(inst.operands[1].imm & mask)))
477330fc 11739 {
eab4f823
MGD
11740 if (inst.instruction == T_MNEM_stmia
11741 && (inst.operands[1].imm & mask)
11742 && (inst.operands[1].imm & (mask - 1)))
11743 as_warn (_("value stored for r%d is UNKNOWN"),
11744 inst.operands[0].reg);
3c707909 11745
eab4f823
MGD
11746 inst.instruction = THUMB_OP16 (inst.instruction);
11747 inst.instruction |= inst.operands[0].reg << 8;
11748 inst.instruction |= inst.operands[1].imm;
11749 narrow = TRUE;
11750 }
11751 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
11752 {
11753 /* This means 1 register in reg list one of 3 situations:
11754 1. Instruction is stmia, but without writeback.
11755 2. lmdia without writeback, but with Rn not in
477330fc 11756 reglist.
eab4f823
MGD
11757 3. ldmia with writeback, but with Rn in reglist.
11758 Case 3 is UNPREDICTABLE behaviour, so we handle
11759 case 1 and 2 which can be converted into a 16-bit
11760 str or ldr. The SP cases are handled below. */
11761 unsigned long opcode;
11762 /* First, record an error for Case 3. */
11763 if (inst.operands[1].imm & mask
11764 && inst.operands[0].writeback)
fa94de6b 11765 inst.error =
eab4f823
MGD
11766 _("having the base register in the register list when "
11767 "using write back is UNPREDICTABLE");
fa94de6b
RM
11768
11769 opcode = (inst.instruction == T_MNEM_stmia ? T_MNEM_str
eab4f823
MGD
11770 : T_MNEM_ldr);
11771 inst.instruction = THUMB_OP16 (opcode);
11772 inst.instruction |= inst.operands[0].reg << 3;
11773 inst.instruction |= (ffs (inst.operands[1].imm)-1);
11774 narrow = TRUE;
11775 }
90e4755a 11776 }
eab4f823 11777 else if (inst.operands[0] .reg == REG_SP)
90e4755a 11778 {
eab4f823
MGD
11779 if (inst.operands[0].writeback)
11780 {
fa94de6b 11781 inst.instruction =
eab4f823 11782 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 11783 ? T_MNEM_push : T_MNEM_pop);
eab4f823 11784 inst.instruction |= inst.operands[1].imm;
477330fc 11785 narrow = TRUE;
eab4f823
MGD
11786 }
11787 else if ((inst.operands[1].imm & (inst.operands[1].imm-1)) == 0)
11788 {
fa94de6b 11789 inst.instruction =
eab4f823 11790 THUMB_OP16 (inst.instruction == T_MNEM_stmia
477330fc 11791 ? T_MNEM_str_sp : T_MNEM_ldr_sp);
eab4f823 11792 inst.instruction |= ((ffs (inst.operands[1].imm)-1) << 8);
477330fc 11793 narrow = TRUE;
eab4f823 11794 }
90e4755a 11795 }
3c707909
PB
11796 }
11797
11798 if (!narrow)
11799 {
c19d1205
ZW
11800 if (inst.instruction < 0xffff)
11801 inst.instruction = THUMB_OP32 (inst.instruction);
3c707909 11802
4b5a202f
AV
11803 encode_thumb2_multi (TRUE /* do_io */, inst.operands[0].reg,
11804 inst.operands[1].imm,
11805 inst.operands[0].writeback);
90e4755a
RE
11806 }
11807 }
c19d1205 11808 else
90e4755a 11809 {
c19d1205
ZW
11810 constraint (inst.operands[0].reg > 7
11811 || (inst.operands[1].imm & ~0xff), BAD_HIREG);
1198ca51
PB
11812 constraint (inst.instruction != T_MNEM_ldmia
11813 && inst.instruction != T_MNEM_stmia,
11814 _("Thumb-2 instruction only valid in unified syntax"));
c19d1205 11815 if (inst.instruction == T_MNEM_stmia)
f03698e6 11816 {
c19d1205
ZW
11817 if (!inst.operands[0].writeback)
11818 as_warn (_("this instruction will write back the base register"));
11819 if ((inst.operands[1].imm & (1 << inst.operands[0].reg))
11820 && (inst.operands[1].imm & ((1 << inst.operands[0].reg) - 1)))
1e5b0379 11821 as_warn (_("value stored for r%d is UNKNOWN"),
c19d1205 11822 inst.operands[0].reg);
f03698e6 11823 }
c19d1205 11824 else
90e4755a 11825 {
c19d1205
ZW
11826 if (!inst.operands[0].writeback
11827 && !(inst.operands[1].imm & (1 << inst.operands[0].reg)))
11828 as_warn (_("this instruction will write back the base register"));
11829 else if (inst.operands[0].writeback
11830 && (inst.operands[1].imm & (1 << inst.operands[0].reg)))
11831 as_warn (_("this instruction will not write back the base register"));
90e4755a
RE
11832 }
11833
c19d1205
ZW
11834 inst.instruction = THUMB_OP16 (inst.instruction);
11835 inst.instruction |= inst.operands[0].reg << 8;
11836 inst.instruction |= inst.operands[1].imm;
11837 }
11838}
e28cd48c 11839
c19d1205
ZW
11840static void
11841do_t_ldrex (void)
11842{
11843 constraint (!inst.operands[1].isreg || !inst.operands[1].preind
11844 || inst.operands[1].postind || inst.operands[1].writeback
11845 || inst.operands[1].immisreg || inst.operands[1].shifted
11846 || inst.operands[1].negative,
01cfc07f 11847 BAD_ADDR_MODE);
e28cd48c 11848
5be8be5d
DG
11849 constraint ((inst.operands[1].reg == REG_PC), BAD_PC);
11850
c19d1205
ZW
11851 inst.instruction |= inst.operands[0].reg << 12;
11852 inst.instruction |= inst.operands[1].reg << 16;
e2b0ab59 11853 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
c19d1205 11854}
e28cd48c 11855
c19d1205
ZW
11856static void
11857do_t_ldrexd (void)
11858{
11859 if (!inst.operands[1].present)
1cac9012 11860 {
c19d1205
ZW
11861 constraint (inst.operands[0].reg == REG_LR,
11862 _("r14 not allowed as first register "
11863 "when second register is omitted"));
11864 inst.operands[1].reg = inst.operands[0].reg + 1;
b99bd4ef 11865 }
c19d1205
ZW
11866 constraint (inst.operands[0].reg == inst.operands[1].reg,
11867 BAD_OVERLAP);
b99bd4ef 11868
c19d1205
ZW
11869 inst.instruction |= inst.operands[0].reg << 12;
11870 inst.instruction |= inst.operands[1].reg << 8;
11871 inst.instruction |= inst.operands[2].reg << 16;
b99bd4ef
NC
11872}
11873
11874static void
c19d1205 11875do_t_ldst (void)
b99bd4ef 11876{
0110f2b8
PB
11877 unsigned long opcode;
11878 int Rn;
11879
e07e6e58
NC
11880 if (inst.operands[0].isreg
11881 && !inst.operands[0].preind
11882 && inst.operands[0].reg == REG_PC)
11883 set_it_insn_type_last ();
11884
0110f2b8 11885 opcode = inst.instruction;
c19d1205 11886 if (unified_syntax)
b99bd4ef 11887 {
53365c0d
PB
11888 if (!inst.operands[1].isreg)
11889 {
11890 if (opcode <= 0xffff)
11891 inst.instruction = THUMB_OP32 (opcode);
8335d6aa 11892 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
53365c0d
PB
11893 return;
11894 }
0110f2b8
PB
11895 if (inst.operands[1].isreg
11896 && !inst.operands[1].writeback
c19d1205
ZW
11897 && !inst.operands[1].shifted && !inst.operands[1].postind
11898 && !inst.operands[1].negative && inst.operands[0].reg <= 7
0110f2b8
PB
11899 && opcode <= 0xffff
11900 && inst.size_req != 4)
c19d1205 11901 {
0110f2b8
PB
11902 /* Insn may have a 16-bit form. */
11903 Rn = inst.operands[1].reg;
11904 if (inst.operands[1].immisreg)
11905 {
11906 inst.instruction = THUMB_OP16 (opcode);
5f4273c7 11907 /* [Rn, Rik] */
0110f2b8
PB
11908 if (Rn <= 7 && inst.operands[1].imm <= 7)
11909 goto op16;
5be8be5d
DG
11910 else if (opcode != T_MNEM_ldr && opcode != T_MNEM_str)
11911 reject_bad_reg (inst.operands[1].imm);
0110f2b8
PB
11912 }
11913 else if ((Rn <= 7 && opcode != T_MNEM_ldrsh
11914 && opcode != T_MNEM_ldrsb)
11915 || ((Rn == REG_PC || Rn == REG_SP) && opcode == T_MNEM_ldr)
11916 || (Rn == REG_SP && opcode == T_MNEM_str))
11917 {
11918 /* [Rn, #const] */
11919 if (Rn > 7)
11920 {
11921 if (Rn == REG_PC)
11922 {
e2b0ab59 11923 if (inst.relocs[0].pc_rel)
0110f2b8
PB
11924 opcode = T_MNEM_ldr_pc2;
11925 else
11926 opcode = T_MNEM_ldr_pc;
11927 }
11928 else
11929 {
11930 if (opcode == T_MNEM_ldr)
11931 opcode = T_MNEM_ldr_sp;
11932 else
11933 opcode = T_MNEM_str_sp;
11934 }
11935 inst.instruction = inst.operands[0].reg << 8;
11936 }
11937 else
11938 {
11939 inst.instruction = inst.operands[0].reg;
11940 inst.instruction |= inst.operands[1].reg << 3;
11941 }
11942 inst.instruction |= THUMB_OP16 (opcode);
11943 if (inst.size_req == 2)
e2b0ab59 11944 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
0110f2b8
PB
11945 else
11946 inst.relax = opcode;
11947 return;
11948 }
c19d1205 11949 }
0110f2b8 11950 /* Definitely a 32-bit variant. */
5be8be5d 11951
8d67f500
NC
11952 /* Warning for Erratum 752419. */
11953 if (opcode == T_MNEM_ldr
11954 && inst.operands[0].reg == REG_SP
11955 && inst.operands[1].writeback == 1
11956 && !inst.operands[1].immisreg)
11957 {
11958 if (no_cpu_selected ()
11959 || (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7)
477330fc
RM
11960 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a)
11961 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7r)))
8d67f500
NC
11962 as_warn (_("This instruction may be unpredictable "
11963 "if executed on M-profile cores "
11964 "with interrupts enabled."));
11965 }
11966
5be8be5d 11967 /* Do some validations regarding addressing modes. */
1be5fd2e 11968 if (inst.operands[1].immisreg)
5be8be5d
DG
11969 reject_bad_reg (inst.operands[1].imm);
11970
1be5fd2e
NC
11971 constraint (inst.operands[1].writeback == 1
11972 && inst.operands[0].reg == inst.operands[1].reg,
11973 BAD_OVERLAP);
11974
0110f2b8 11975 inst.instruction = THUMB_OP32 (opcode);
c19d1205
ZW
11976 inst.instruction |= inst.operands[0].reg << 12;
11977 encode_thumb32_addr_mode (1, /*is_t=*/FALSE, /*is_d=*/FALSE);
1be5fd2e 11978 check_ldr_r15_aligned ();
b99bd4ef
NC
11979 return;
11980 }
11981
c19d1205
ZW
11982 constraint (inst.operands[0].reg > 7, BAD_HIREG);
11983
11984 if (inst.instruction == T_MNEM_ldrsh || inst.instruction == T_MNEM_ldrsb)
b99bd4ef 11985 {
c19d1205
ZW
11986 /* Only [Rn,Rm] is acceptable. */
11987 constraint (inst.operands[1].reg > 7 || inst.operands[1].imm > 7, BAD_HIREG);
11988 constraint (!inst.operands[1].isreg || !inst.operands[1].immisreg
11989 || inst.operands[1].postind || inst.operands[1].shifted
11990 || inst.operands[1].negative,
11991 _("Thumb does not support this addressing mode"));
11992 inst.instruction = THUMB_OP16 (inst.instruction);
11993 goto op16;
b99bd4ef 11994 }
5f4273c7 11995
c19d1205
ZW
11996 inst.instruction = THUMB_OP16 (inst.instruction);
11997 if (!inst.operands[1].isreg)
8335d6aa 11998 if (move_or_literal_pool (0, CONST_THUMB, /*mode_3=*/FALSE))
c19d1205 11999 return;
b99bd4ef 12000
c19d1205
ZW
12001 constraint (!inst.operands[1].preind
12002 || inst.operands[1].shifted
12003 || inst.operands[1].writeback,
12004 _("Thumb does not support this addressing mode"));
12005 if (inst.operands[1].reg == REG_PC || inst.operands[1].reg == REG_SP)
90e4755a 12006 {
c19d1205
ZW
12007 constraint (inst.instruction & 0x0600,
12008 _("byte or halfword not valid for base register"));
12009 constraint (inst.operands[1].reg == REG_PC
12010 && !(inst.instruction & THUMB_LOAD_BIT),
12011 _("r15 based store not allowed"));
12012 constraint (inst.operands[1].immisreg,
12013 _("invalid base register for register offset"));
b99bd4ef 12014
c19d1205
ZW
12015 if (inst.operands[1].reg == REG_PC)
12016 inst.instruction = T_OPCODE_LDR_PC;
12017 else if (inst.instruction & THUMB_LOAD_BIT)
12018 inst.instruction = T_OPCODE_LDR_SP;
12019 else
12020 inst.instruction = T_OPCODE_STR_SP;
b99bd4ef 12021
c19d1205 12022 inst.instruction |= inst.operands[0].reg << 8;
e2b0ab59 12023 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12024 return;
12025 }
90e4755a 12026
c19d1205
ZW
12027 constraint (inst.operands[1].reg > 7, BAD_HIREG);
12028 if (!inst.operands[1].immisreg)
12029 {
12030 /* Immediate offset. */
12031 inst.instruction |= inst.operands[0].reg;
12032 inst.instruction |= inst.operands[1].reg << 3;
e2b0ab59 12033 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_OFFSET;
c19d1205
ZW
12034 return;
12035 }
90e4755a 12036
c19d1205
ZW
12037 /* Register offset. */
12038 constraint (inst.operands[1].imm > 7, BAD_HIREG);
12039 constraint (inst.operands[1].negative,
12040 _("Thumb does not support this addressing mode"));
90e4755a 12041
c19d1205
ZW
12042 op16:
12043 switch (inst.instruction)
12044 {
12045 case T_OPCODE_STR_IW: inst.instruction = T_OPCODE_STR_RW; break;
12046 case T_OPCODE_STR_IH: inst.instruction = T_OPCODE_STR_RH; break;
12047 case T_OPCODE_STR_IB: inst.instruction = T_OPCODE_STR_RB; break;
12048 case T_OPCODE_LDR_IW: inst.instruction = T_OPCODE_LDR_RW; break;
12049 case T_OPCODE_LDR_IH: inst.instruction = T_OPCODE_LDR_RH; break;
12050 case T_OPCODE_LDR_IB: inst.instruction = T_OPCODE_LDR_RB; break;
12051 case 0x5600 /* ldrsb */:
12052 case 0x5e00 /* ldrsh */: break;
12053 default: abort ();
12054 }
90e4755a 12055
c19d1205
ZW
12056 inst.instruction |= inst.operands[0].reg;
12057 inst.instruction |= inst.operands[1].reg << 3;
12058 inst.instruction |= inst.operands[1].imm << 6;
12059}
90e4755a 12060
c19d1205
ZW
12061static void
12062do_t_ldstd (void)
12063{
12064 if (!inst.operands[1].present)
b99bd4ef 12065 {
c19d1205
ZW
12066 inst.operands[1].reg = inst.operands[0].reg + 1;
12067 constraint (inst.operands[0].reg == REG_LR,
12068 _("r14 not allowed here"));
bd340a04 12069 constraint (inst.operands[0].reg == REG_R12,
477330fc 12070 _("r12 not allowed here"));
b99bd4ef 12071 }
bd340a04
MGD
12072
12073 if (inst.operands[2].writeback
12074 && (inst.operands[0].reg == inst.operands[2].reg
12075 || inst.operands[1].reg == inst.operands[2].reg))
12076 as_warn (_("base register written back, and overlaps "
477330fc 12077 "one of transfer registers"));
bd340a04 12078
c19d1205
ZW
12079 inst.instruction |= inst.operands[0].reg << 12;
12080 inst.instruction |= inst.operands[1].reg << 8;
12081 encode_thumb32_addr_mode (2, /*is_t=*/FALSE, /*is_d=*/TRUE);
b99bd4ef
NC
12082}
12083
c19d1205
ZW
12084static void
12085do_t_ldstt (void)
12086{
12087 inst.instruction |= inst.operands[0].reg << 12;
12088 encode_thumb32_addr_mode (1, /*is_t=*/TRUE, /*is_d=*/FALSE);
12089}
a737bd4d 12090
b99bd4ef 12091static void
c19d1205 12092do_t_mla (void)
b99bd4ef 12093{
fdfde340 12094 unsigned Rd, Rn, Rm, Ra;
c921be7d 12095
fdfde340
JM
12096 Rd = inst.operands[0].reg;
12097 Rn = inst.operands[1].reg;
12098 Rm = inst.operands[2].reg;
12099 Ra = inst.operands[3].reg;
12100
12101 reject_bad_reg (Rd);
12102 reject_bad_reg (Rn);
12103 reject_bad_reg (Rm);
12104 reject_bad_reg (Ra);
12105
12106 inst.instruction |= Rd << 8;
12107 inst.instruction |= Rn << 16;
12108 inst.instruction |= Rm;
12109 inst.instruction |= Ra << 12;
c19d1205 12110}
b99bd4ef 12111
c19d1205
ZW
12112static void
12113do_t_mlal (void)
12114{
fdfde340
JM
12115 unsigned RdLo, RdHi, Rn, Rm;
12116
12117 RdLo = inst.operands[0].reg;
12118 RdHi = inst.operands[1].reg;
12119 Rn = inst.operands[2].reg;
12120 Rm = inst.operands[3].reg;
12121
12122 reject_bad_reg (RdLo);
12123 reject_bad_reg (RdHi);
12124 reject_bad_reg (Rn);
12125 reject_bad_reg (Rm);
12126
12127 inst.instruction |= RdLo << 12;
12128 inst.instruction |= RdHi << 8;
12129 inst.instruction |= Rn << 16;
12130 inst.instruction |= Rm;
c19d1205 12131}
b99bd4ef 12132
c19d1205
ZW
12133static void
12134do_t_mov_cmp (void)
12135{
fdfde340
JM
12136 unsigned Rn, Rm;
12137
12138 Rn = inst.operands[0].reg;
12139 Rm = inst.operands[1].reg;
12140
e07e6e58
NC
12141 if (Rn == REG_PC)
12142 set_it_insn_type_last ();
12143
c19d1205 12144 if (unified_syntax)
b99bd4ef 12145 {
c19d1205
ZW
12146 int r0off = (inst.instruction == T_MNEM_mov
12147 || inst.instruction == T_MNEM_movs) ? 8 : 16;
0110f2b8 12148 unsigned long opcode;
3d388997
PB
12149 bfd_boolean narrow;
12150 bfd_boolean low_regs;
12151
fdfde340 12152 low_regs = (Rn <= 7 && Rm <= 7);
0110f2b8 12153 opcode = inst.instruction;
e07e6e58 12154 if (in_it_block ())
0110f2b8 12155 narrow = opcode != T_MNEM_movs;
3d388997 12156 else
0110f2b8 12157 narrow = opcode != T_MNEM_movs || low_regs;
3d388997
PB
12158 if (inst.size_req == 4
12159 || inst.operands[1].shifted)
12160 narrow = FALSE;
12161
efd81785
PB
12162 /* MOVS PC, LR is encoded as SUBS PC, LR, #0. */
12163 if (opcode == T_MNEM_movs && inst.operands[1].isreg
12164 && !inst.operands[1].shifted
fdfde340
JM
12165 && Rn == REG_PC
12166 && Rm == REG_LR)
efd81785
PB
12167 {
12168 inst.instruction = T2_SUBS_PC_LR;
12169 return;
12170 }
12171
fdfde340
JM
12172 if (opcode == T_MNEM_cmp)
12173 {
12174 constraint (Rn == REG_PC, BAD_PC);
94206790
MM
12175 if (narrow)
12176 {
12177 /* In the Thumb-2 ISA, use of R13 as Rm is deprecated,
12178 but valid. */
12179 warn_deprecated_sp (Rm);
12180 /* R15 was documented as a valid choice for Rm in ARMv6,
12181 but as UNPREDICTABLE in ARMv7. ARM's proprietary
12182 tools reject R15, so we do too. */
12183 constraint (Rm == REG_PC, BAD_PC);
12184 }
12185 else
12186 reject_bad_reg (Rm);
fdfde340
JM
12187 }
12188 else if (opcode == T_MNEM_mov
12189 || opcode == T_MNEM_movs)
12190 {
12191 if (inst.operands[1].isreg)
12192 {
12193 if (opcode == T_MNEM_movs)
12194 {
12195 reject_bad_reg (Rn);
12196 reject_bad_reg (Rm);
12197 }
76fa04a4
MGD
12198 else if (narrow)
12199 {
12200 /* This is mov.n. */
12201 if ((Rn == REG_SP || Rn == REG_PC)
12202 && (Rm == REG_SP || Rm == REG_PC))
12203 {
5c3696f8 12204 as_tsktsk (_("Use of r%u as a source register is "
76fa04a4
MGD
12205 "deprecated when r%u is the destination "
12206 "register."), Rm, Rn);
12207 }
12208 }
12209 else
12210 {
12211 /* This is mov.w. */
12212 constraint (Rn == REG_PC, BAD_PC);
12213 constraint (Rm == REG_PC, BAD_PC);
5c8ed6a4
JW
12214 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
12215 constraint (Rn == REG_SP && Rm == REG_SP, BAD_SP);
76fa04a4 12216 }
fdfde340
JM
12217 }
12218 else
12219 reject_bad_reg (Rn);
12220 }
12221
c19d1205
ZW
12222 if (!inst.operands[1].isreg)
12223 {
0110f2b8 12224 /* Immediate operand. */
e07e6e58 12225 if (!in_it_block () && opcode == T_MNEM_mov)
0110f2b8
PB
12226 narrow = 0;
12227 if (low_regs && narrow)
12228 {
12229 inst.instruction = THUMB_OP16 (opcode);
fdfde340 12230 inst.instruction |= Rn << 8;
e2b0ab59
AV
12231 if (inst.relocs[0].type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
12232 || inst.relocs[0].type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
72d98d16 12233 {
a9f02af8 12234 if (inst.size_req == 2)
e2b0ab59 12235 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
a9f02af8
MG
12236 else
12237 inst.relax = opcode;
72d98d16 12238 }
0110f2b8
PB
12239 }
12240 else
12241 {
e2b0ab59
AV
12242 constraint ((inst.relocs[0].type
12243 >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC)
12244 && (inst.relocs[0].type
12245 <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC) ,
a9f02af8
MG
12246 THUMB1_RELOC_ONLY);
12247
0110f2b8
PB
12248 inst.instruction = THUMB_OP32 (inst.instruction);
12249 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12250 inst.instruction |= Rn << r0off;
e2b0ab59 12251 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8 12252 }
c19d1205 12253 }
728ca7c9
PB
12254 else if (inst.operands[1].shifted && inst.operands[1].immisreg
12255 && (inst.instruction == T_MNEM_mov
12256 || inst.instruction == T_MNEM_movs))
12257 {
12258 /* Register shifts are encoded as separate shift instructions. */
12259 bfd_boolean flags = (inst.instruction == T_MNEM_movs);
12260
e07e6e58 12261 if (in_it_block ())
728ca7c9
PB
12262 narrow = !flags;
12263 else
12264 narrow = flags;
12265
12266 if (inst.size_req == 4)
12267 narrow = FALSE;
12268
12269 if (!low_regs || inst.operands[1].imm > 7)
12270 narrow = FALSE;
12271
fdfde340 12272 if (Rn != Rm)
728ca7c9
PB
12273 narrow = FALSE;
12274
12275 switch (inst.operands[1].shift_kind)
12276 {
12277 case SHIFT_LSL:
12278 opcode = narrow ? T_OPCODE_LSL_R : THUMB_OP32 (T_MNEM_lsl);
12279 break;
12280 case SHIFT_ASR:
12281 opcode = narrow ? T_OPCODE_ASR_R : THUMB_OP32 (T_MNEM_asr);
12282 break;
12283 case SHIFT_LSR:
12284 opcode = narrow ? T_OPCODE_LSR_R : THUMB_OP32 (T_MNEM_lsr);
12285 break;
12286 case SHIFT_ROR:
12287 opcode = narrow ? T_OPCODE_ROR_R : THUMB_OP32 (T_MNEM_ror);
12288 break;
12289 default:
5f4273c7 12290 abort ();
728ca7c9
PB
12291 }
12292
12293 inst.instruction = opcode;
12294 if (narrow)
12295 {
fdfde340 12296 inst.instruction |= Rn;
728ca7c9
PB
12297 inst.instruction |= inst.operands[1].imm << 3;
12298 }
12299 else
12300 {
12301 if (flags)
12302 inst.instruction |= CONDS_BIT;
12303
fdfde340
JM
12304 inst.instruction |= Rn << 8;
12305 inst.instruction |= Rm << 16;
728ca7c9
PB
12306 inst.instruction |= inst.operands[1].imm;
12307 }
12308 }
3d388997 12309 else if (!narrow)
c19d1205 12310 {
728ca7c9
PB
12311 /* Some mov with immediate shift have narrow variants.
12312 Register shifts are handled above. */
12313 if (low_regs && inst.operands[1].shifted
12314 && (inst.instruction == T_MNEM_mov
12315 || inst.instruction == T_MNEM_movs))
12316 {
e07e6e58 12317 if (in_it_block ())
728ca7c9
PB
12318 narrow = (inst.instruction == T_MNEM_mov);
12319 else
12320 narrow = (inst.instruction == T_MNEM_movs);
12321 }
12322
12323 if (narrow)
12324 {
12325 switch (inst.operands[1].shift_kind)
12326 {
12327 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
12328 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
12329 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
12330 default: narrow = FALSE; break;
12331 }
12332 }
12333
12334 if (narrow)
12335 {
fdfde340
JM
12336 inst.instruction |= Rn;
12337 inst.instruction |= Rm << 3;
e2b0ab59 12338 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
728ca7c9
PB
12339 }
12340 else
12341 {
12342 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12343 inst.instruction |= Rn << r0off;
728ca7c9
PB
12344 encode_thumb32_shifted_operand (1);
12345 }
c19d1205
ZW
12346 }
12347 else
12348 switch (inst.instruction)
12349 {
12350 case T_MNEM_mov:
837b3435 12351 /* In v4t or v5t a move of two lowregs produces unpredictable
c6400f8a
MGD
12352 results. Don't allow this. */
12353 if (low_regs)
12354 {
12355 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6),
12356 "MOV Rd, Rs with two low registers is not "
12357 "permitted on this architecture");
fa94de6b 12358 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
c6400f8a
MGD
12359 arm_ext_v6);
12360 }
12361
c19d1205 12362 inst.instruction = T_OPCODE_MOV_HR;
fdfde340
JM
12363 inst.instruction |= (Rn & 0x8) << 4;
12364 inst.instruction |= (Rn & 0x7);
12365 inst.instruction |= Rm << 3;
c19d1205 12366 break;
b99bd4ef 12367
c19d1205
ZW
12368 case T_MNEM_movs:
12369 /* We know we have low registers at this point.
941a8a52
MGD
12370 Generate LSLS Rd, Rs, #0. */
12371 inst.instruction = T_OPCODE_LSL_I;
fdfde340
JM
12372 inst.instruction |= Rn;
12373 inst.instruction |= Rm << 3;
c19d1205
ZW
12374 break;
12375
12376 case T_MNEM_cmp:
3d388997 12377 if (low_regs)
c19d1205
ZW
12378 {
12379 inst.instruction = T_OPCODE_CMP_LR;
fdfde340
JM
12380 inst.instruction |= Rn;
12381 inst.instruction |= Rm << 3;
c19d1205
ZW
12382 }
12383 else
12384 {
12385 inst.instruction = T_OPCODE_CMP_HR;
fdfde340
JM
12386 inst.instruction |= (Rn & 0x8) << 4;
12387 inst.instruction |= (Rn & 0x7);
12388 inst.instruction |= Rm << 3;
c19d1205
ZW
12389 }
12390 break;
12391 }
b99bd4ef
NC
12392 return;
12393 }
12394
c19d1205 12395 inst.instruction = THUMB_OP16 (inst.instruction);
539d4391
NC
12396
12397 /* PR 10443: Do not silently ignore shifted operands. */
12398 constraint (inst.operands[1].shifted,
12399 _("shifts in CMP/MOV instructions are only supported in unified syntax"));
12400
c19d1205 12401 if (inst.operands[1].isreg)
b99bd4ef 12402 {
fdfde340 12403 if (Rn < 8 && Rm < 8)
b99bd4ef 12404 {
c19d1205
ZW
12405 /* A move of two lowregs is encoded as ADD Rd, Rs, #0
12406 since a MOV instruction produces unpredictable results. */
12407 if (inst.instruction == T_OPCODE_MOV_I8)
12408 inst.instruction = T_OPCODE_ADD_I3;
b99bd4ef 12409 else
c19d1205 12410 inst.instruction = T_OPCODE_CMP_LR;
b99bd4ef 12411
fdfde340
JM
12412 inst.instruction |= Rn;
12413 inst.instruction |= Rm << 3;
b99bd4ef
NC
12414 }
12415 else
12416 {
c19d1205
ZW
12417 if (inst.instruction == T_OPCODE_MOV_I8)
12418 inst.instruction = T_OPCODE_MOV_HR;
12419 else
12420 inst.instruction = T_OPCODE_CMP_HR;
12421 do_t_cpy ();
b99bd4ef
NC
12422 }
12423 }
c19d1205 12424 else
b99bd4ef 12425 {
fdfde340 12426 constraint (Rn > 7,
c19d1205 12427 _("only lo regs allowed with immediate"));
fdfde340 12428 inst.instruction |= Rn << 8;
e2b0ab59 12429 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_IMM;
c19d1205
ZW
12430 }
12431}
b99bd4ef 12432
c19d1205
ZW
12433static void
12434do_t_mov16 (void)
12435{
fdfde340 12436 unsigned Rd;
b6895b4f
PB
12437 bfd_vma imm;
12438 bfd_boolean top;
12439
12440 top = (inst.instruction & 0x00800000) != 0;
e2b0ab59 12441 if (inst.relocs[0].type == BFD_RELOC_ARM_MOVW)
b6895b4f 12442 {
33eaf5de 12443 constraint (top, _(":lower16: not allowed in this instruction"));
e2b0ab59 12444 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVW;
b6895b4f 12445 }
e2b0ab59 12446 else if (inst.relocs[0].type == BFD_RELOC_ARM_MOVT)
b6895b4f 12447 {
33eaf5de 12448 constraint (!top, _(":upper16: not allowed in this instruction"));
e2b0ab59 12449 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_MOVT;
b6895b4f
PB
12450 }
12451
fdfde340
JM
12452 Rd = inst.operands[0].reg;
12453 reject_bad_reg (Rd);
12454
12455 inst.instruction |= Rd << 8;
e2b0ab59 12456 if (inst.relocs[0].type == BFD_RELOC_UNUSED)
b6895b4f 12457 {
e2b0ab59 12458 imm = inst.relocs[0].exp.X_add_number;
b6895b4f
PB
12459 inst.instruction |= (imm & 0xf000) << 4;
12460 inst.instruction |= (imm & 0x0800) << 15;
12461 inst.instruction |= (imm & 0x0700) << 4;
12462 inst.instruction |= (imm & 0x00ff);
12463 }
c19d1205 12464}
b99bd4ef 12465
c19d1205
ZW
12466static void
12467do_t_mvn_tst (void)
12468{
fdfde340 12469 unsigned Rn, Rm;
c921be7d 12470
fdfde340
JM
12471 Rn = inst.operands[0].reg;
12472 Rm = inst.operands[1].reg;
12473
12474 if (inst.instruction == T_MNEM_cmp
12475 || inst.instruction == T_MNEM_cmn)
12476 constraint (Rn == REG_PC, BAD_PC);
12477 else
12478 reject_bad_reg (Rn);
12479 reject_bad_reg (Rm);
12480
c19d1205
ZW
12481 if (unified_syntax)
12482 {
12483 int r0off = (inst.instruction == T_MNEM_mvn
12484 || inst.instruction == T_MNEM_mvns) ? 8 : 16;
3d388997
PB
12485 bfd_boolean narrow;
12486
12487 if (inst.size_req == 4
12488 || inst.instruction > 0xffff
12489 || inst.operands[1].shifted
fdfde340 12490 || Rn > 7 || Rm > 7)
3d388997 12491 narrow = FALSE;
fe8b4cc3
KT
12492 else if (inst.instruction == T_MNEM_cmn
12493 || inst.instruction == T_MNEM_tst)
3d388997
PB
12494 narrow = TRUE;
12495 else if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 12496 narrow = !in_it_block ();
3d388997 12497 else
e07e6e58 12498 narrow = in_it_block ();
3d388997 12499
c19d1205 12500 if (!inst.operands[1].isreg)
b99bd4ef 12501 {
c19d1205
ZW
12502 /* For an immediate, we always generate a 32-bit opcode;
12503 section relaxation will shrink it later if possible. */
12504 if (inst.instruction < 0xffff)
12505 inst.instruction = THUMB_OP32 (inst.instruction);
12506 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
fdfde340 12507 inst.instruction |= Rn << r0off;
e2b0ab59 12508 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
b99bd4ef 12509 }
c19d1205 12510 else
b99bd4ef 12511 {
c19d1205 12512 /* See if we can do this with a 16-bit instruction. */
3d388997 12513 if (narrow)
b99bd4ef 12514 {
c19d1205 12515 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12516 inst.instruction |= Rn;
12517 inst.instruction |= Rm << 3;
b99bd4ef 12518 }
c19d1205 12519 else
b99bd4ef 12520 {
c19d1205
ZW
12521 constraint (inst.operands[1].shifted
12522 && inst.operands[1].immisreg,
12523 _("shift must be constant"));
12524 if (inst.instruction < 0xffff)
12525 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340 12526 inst.instruction |= Rn << r0off;
c19d1205 12527 encode_thumb32_shifted_operand (1);
b99bd4ef 12528 }
b99bd4ef
NC
12529 }
12530 }
12531 else
12532 {
c19d1205
ZW
12533 constraint (inst.instruction > 0xffff
12534 || inst.instruction == T_MNEM_mvns, BAD_THUMB32);
12535 constraint (!inst.operands[1].isreg || inst.operands[1].shifted,
12536 _("unshifted register required"));
fdfde340 12537 constraint (Rn > 7 || Rm > 7,
c19d1205 12538 BAD_HIREG);
b99bd4ef 12539
c19d1205 12540 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12541 inst.instruction |= Rn;
12542 inst.instruction |= Rm << 3;
b99bd4ef 12543 }
b99bd4ef
NC
12544}
12545
b05fe5cf 12546static void
c19d1205 12547do_t_mrs (void)
b05fe5cf 12548{
fdfde340 12549 unsigned Rd;
037e8744
JB
12550
12551 if (do_vfp_nsyn_mrs () == SUCCESS)
12552 return;
12553
90ec0d68
MGD
12554 Rd = inst.operands[0].reg;
12555 reject_bad_reg (Rd);
12556 inst.instruction |= Rd << 8;
12557
12558 if (inst.operands[1].isreg)
62b3e311 12559 {
90ec0d68
MGD
12560 unsigned br = inst.operands[1].reg;
12561 if (((br & 0x200) == 0) && ((br & 0xf000) != 0xf000))
12562 as_bad (_("bad register for mrs"));
12563
12564 inst.instruction |= br & (0xf << 16);
12565 inst.instruction |= (br & 0x300) >> 4;
12566 inst.instruction |= (br & SPSR_BIT) >> 2;
62b3e311
PB
12567 }
12568 else
12569 {
90ec0d68 12570 int flags = inst.operands[1].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
5f4273c7 12571
d2cd1205 12572 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
1a43faaf
NC
12573 {
12574 /* PR gas/12698: The constraint is only applied for m_profile.
12575 If the user has specified -march=all, we want to ignore it as
12576 we are building for any CPU type, including non-m variants. */
823d2571
TG
12577 bfd_boolean m_profile =
12578 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf
NC
12579 constraint ((flags != 0) && m_profile, _("selected processor does "
12580 "not support requested special purpose register"));
12581 }
90ec0d68 12582 else
d2cd1205
JB
12583 /* mrs only accepts APSR/CPSR/SPSR/CPSR_all/SPSR_all (for non-M profile
12584 devices). */
12585 constraint ((flags & ~SPSR_BIT) != (PSR_c|PSR_f),
12586 _("'APSR', 'CPSR' or 'SPSR' expected"));
fdfde340 12587
90ec0d68
MGD
12588 inst.instruction |= (flags & SPSR_BIT) >> 2;
12589 inst.instruction |= inst.operands[1].imm & 0xff;
12590 inst.instruction |= 0xf0000;
12591 }
c19d1205 12592}
b05fe5cf 12593
c19d1205
ZW
12594static void
12595do_t_msr (void)
12596{
62b3e311 12597 int flags;
fdfde340 12598 unsigned Rn;
62b3e311 12599
037e8744
JB
12600 if (do_vfp_nsyn_msr () == SUCCESS)
12601 return;
12602
c19d1205
ZW
12603 constraint (!inst.operands[1].isreg,
12604 _("Thumb encoding does not support an immediate here"));
90ec0d68
MGD
12605
12606 if (inst.operands[0].isreg)
12607 flags = (int)(inst.operands[0].reg);
12608 else
12609 flags = inst.operands[0].imm;
12610
d2cd1205 12611 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_m))
62b3e311 12612 {
d2cd1205
JB
12613 int bits = inst.operands[0].imm & (PSR_c|PSR_x|PSR_s|PSR_f|SPSR_BIT);
12614
1a43faaf 12615 /* PR gas/12698: The constraint is only applied for m_profile.
477330fc
RM
12616 If the user has specified -march=all, we want to ignore it as
12617 we are building for any CPU type, including non-m variants. */
823d2571
TG
12618 bfd_boolean m_profile =
12619 !ARM_FEATURE_CORE_EQUAL (selected_cpu, arm_arch_any);
1a43faaf 12620 constraint (((ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
477330fc
RM
12621 && (bits & ~(PSR_s | PSR_f)) != 0)
12622 || (!ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6_dsp)
12623 && bits != PSR_f)) && m_profile,
12624 _("selected processor does not support requested special "
12625 "purpose register"));
62b3e311
PB
12626 }
12627 else
d2cd1205
JB
12628 constraint ((flags & 0xff) != 0, _("selected processor does not support "
12629 "requested special purpose register"));
c921be7d 12630
fdfde340
JM
12631 Rn = inst.operands[1].reg;
12632 reject_bad_reg (Rn);
12633
62b3e311 12634 inst.instruction |= (flags & SPSR_BIT) >> 2;
90ec0d68
MGD
12635 inst.instruction |= (flags & 0xf0000) >> 8;
12636 inst.instruction |= (flags & 0x300) >> 4;
62b3e311 12637 inst.instruction |= (flags & 0xff);
fdfde340 12638 inst.instruction |= Rn << 16;
c19d1205 12639}
b05fe5cf 12640
c19d1205
ZW
12641static void
12642do_t_mul (void)
12643{
17828f45 12644 bfd_boolean narrow;
fdfde340 12645 unsigned Rd, Rn, Rm;
17828f45 12646
c19d1205
ZW
12647 if (!inst.operands[2].present)
12648 inst.operands[2].reg = inst.operands[0].reg;
b05fe5cf 12649
fdfde340
JM
12650 Rd = inst.operands[0].reg;
12651 Rn = inst.operands[1].reg;
12652 Rm = inst.operands[2].reg;
12653
17828f45 12654 if (unified_syntax)
b05fe5cf 12655 {
17828f45 12656 if (inst.size_req == 4
fdfde340
JM
12657 || (Rd != Rn
12658 && Rd != Rm)
12659 || Rn > 7
12660 || Rm > 7)
17828f45
JM
12661 narrow = FALSE;
12662 else if (inst.instruction == T_MNEM_muls)
e07e6e58 12663 narrow = !in_it_block ();
17828f45 12664 else
e07e6e58 12665 narrow = in_it_block ();
b05fe5cf 12666 }
c19d1205 12667 else
b05fe5cf 12668 {
17828f45 12669 constraint (inst.instruction == T_MNEM_muls, BAD_THUMB32);
fdfde340 12670 constraint (Rn > 7 || Rm > 7,
c19d1205 12671 BAD_HIREG);
17828f45
JM
12672 narrow = TRUE;
12673 }
b05fe5cf 12674
17828f45
JM
12675 if (narrow)
12676 {
12677 /* 16-bit MULS/Conditional MUL. */
c19d1205 12678 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340 12679 inst.instruction |= Rd;
b05fe5cf 12680
fdfde340
JM
12681 if (Rd == Rn)
12682 inst.instruction |= Rm << 3;
12683 else if (Rd == Rm)
12684 inst.instruction |= Rn << 3;
c19d1205
ZW
12685 else
12686 constraint (1, _("dest must overlap one source register"));
12687 }
17828f45
JM
12688 else
12689 {
e07e6e58
NC
12690 constraint (inst.instruction != T_MNEM_mul,
12691 _("Thumb-2 MUL must not set flags"));
17828f45
JM
12692 /* 32-bit MUL. */
12693 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
12694 inst.instruction |= Rd << 8;
12695 inst.instruction |= Rn << 16;
12696 inst.instruction |= Rm << 0;
12697
12698 reject_bad_reg (Rd);
12699 reject_bad_reg (Rn);
12700 reject_bad_reg (Rm);
17828f45 12701 }
c19d1205 12702}
b05fe5cf 12703
c19d1205
ZW
12704static void
12705do_t_mull (void)
12706{
fdfde340 12707 unsigned RdLo, RdHi, Rn, Rm;
b05fe5cf 12708
fdfde340
JM
12709 RdLo = inst.operands[0].reg;
12710 RdHi = inst.operands[1].reg;
12711 Rn = inst.operands[2].reg;
12712 Rm = inst.operands[3].reg;
12713
12714 reject_bad_reg (RdLo);
12715 reject_bad_reg (RdHi);
12716 reject_bad_reg (Rn);
12717 reject_bad_reg (Rm);
12718
12719 inst.instruction |= RdLo << 12;
12720 inst.instruction |= RdHi << 8;
12721 inst.instruction |= Rn << 16;
12722 inst.instruction |= Rm;
12723
12724 if (RdLo == RdHi)
c19d1205
ZW
12725 as_tsktsk (_("rdhi and rdlo must be different"));
12726}
b05fe5cf 12727
c19d1205
ZW
12728static void
12729do_t_nop (void)
12730{
e07e6e58
NC
12731 set_it_insn_type (NEUTRAL_IT_INSN);
12732
c19d1205
ZW
12733 if (unified_syntax)
12734 {
12735 if (inst.size_req == 4 || inst.operands[0].imm > 15)
b05fe5cf 12736 {
c19d1205
ZW
12737 inst.instruction = THUMB_OP32 (inst.instruction);
12738 inst.instruction |= inst.operands[0].imm;
12739 }
12740 else
12741 {
bc2d1808
NC
12742 /* PR9722: Check for Thumb2 availability before
12743 generating a thumb2 nop instruction. */
afa62d5e 12744 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v6t2))
bc2d1808
NC
12745 {
12746 inst.instruction = THUMB_OP16 (inst.instruction);
12747 inst.instruction |= inst.operands[0].imm << 4;
12748 }
12749 else
12750 inst.instruction = 0x46c0;
c19d1205
ZW
12751 }
12752 }
12753 else
12754 {
12755 constraint (inst.operands[0].present,
12756 _("Thumb does not support NOP with hints"));
12757 inst.instruction = 0x46c0;
12758 }
12759}
b05fe5cf 12760
c19d1205
ZW
12761static void
12762do_t_neg (void)
12763{
12764 if (unified_syntax)
12765 {
3d388997
PB
12766 bfd_boolean narrow;
12767
12768 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 12769 narrow = !in_it_block ();
3d388997 12770 else
e07e6e58 12771 narrow = in_it_block ();
3d388997
PB
12772 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
12773 narrow = FALSE;
12774 if (inst.size_req == 4)
12775 narrow = FALSE;
12776
12777 if (!narrow)
c19d1205
ZW
12778 {
12779 inst.instruction = THUMB_OP32 (inst.instruction);
12780 inst.instruction |= inst.operands[0].reg << 8;
12781 inst.instruction |= inst.operands[1].reg << 16;
b05fe5cf
ZW
12782 }
12783 else
12784 {
c19d1205
ZW
12785 inst.instruction = THUMB_OP16 (inst.instruction);
12786 inst.instruction |= inst.operands[0].reg;
12787 inst.instruction |= inst.operands[1].reg << 3;
b05fe5cf
ZW
12788 }
12789 }
12790 else
12791 {
c19d1205
ZW
12792 constraint (inst.operands[0].reg > 7 || inst.operands[1].reg > 7,
12793 BAD_HIREG);
12794 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
12795
12796 inst.instruction = THUMB_OP16 (inst.instruction);
12797 inst.instruction |= inst.operands[0].reg;
12798 inst.instruction |= inst.operands[1].reg << 3;
12799 }
12800}
12801
1c444d06
JM
12802static void
12803do_t_orn (void)
12804{
12805 unsigned Rd, Rn;
12806
12807 Rd = inst.operands[0].reg;
12808 Rn = inst.operands[1].present ? inst.operands[1].reg : Rd;
12809
fdfde340
JM
12810 reject_bad_reg (Rd);
12811 /* Rn == REG_SP is unpredictable; Rn == REG_PC is MVN. */
12812 reject_bad_reg (Rn);
12813
1c444d06
JM
12814 inst.instruction |= Rd << 8;
12815 inst.instruction |= Rn << 16;
12816
12817 if (!inst.operands[2].isreg)
12818 {
12819 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 12820 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
1c444d06
JM
12821 }
12822 else
12823 {
12824 unsigned Rm;
12825
12826 Rm = inst.operands[2].reg;
fdfde340 12827 reject_bad_reg (Rm);
1c444d06
JM
12828
12829 constraint (inst.operands[2].shifted
12830 && inst.operands[2].immisreg,
12831 _("shift must be constant"));
12832 encode_thumb32_shifted_operand (2);
12833 }
12834}
12835
c19d1205
ZW
12836static void
12837do_t_pkhbt (void)
12838{
fdfde340
JM
12839 unsigned Rd, Rn, Rm;
12840
12841 Rd = inst.operands[0].reg;
12842 Rn = inst.operands[1].reg;
12843 Rm = inst.operands[2].reg;
12844
12845 reject_bad_reg (Rd);
12846 reject_bad_reg (Rn);
12847 reject_bad_reg (Rm);
12848
12849 inst.instruction |= Rd << 8;
12850 inst.instruction |= Rn << 16;
12851 inst.instruction |= Rm;
c19d1205
ZW
12852 if (inst.operands[3].present)
12853 {
e2b0ab59
AV
12854 unsigned int val = inst.relocs[0].exp.X_add_number;
12855 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205
ZW
12856 _("expression too complex"));
12857 inst.instruction |= (val & 0x1c) << 10;
12858 inst.instruction |= (val & 0x03) << 6;
b05fe5cf 12859 }
c19d1205 12860}
b05fe5cf 12861
c19d1205
ZW
12862static void
12863do_t_pkhtb (void)
12864{
12865 if (!inst.operands[3].present)
1ef52f49
NC
12866 {
12867 unsigned Rtmp;
12868
12869 inst.instruction &= ~0x00000020;
12870
12871 /* PR 10168. Swap the Rm and Rn registers. */
12872 Rtmp = inst.operands[1].reg;
12873 inst.operands[1].reg = inst.operands[2].reg;
12874 inst.operands[2].reg = Rtmp;
12875 }
c19d1205 12876 do_t_pkhbt ();
b05fe5cf
ZW
12877}
12878
c19d1205
ZW
12879static void
12880do_t_pld (void)
12881{
fdfde340
JM
12882 if (inst.operands[0].immisreg)
12883 reject_bad_reg (inst.operands[0].imm);
12884
c19d1205
ZW
12885 encode_thumb32_addr_mode (0, /*is_t=*/FALSE, /*is_d=*/FALSE);
12886}
b05fe5cf 12887
c19d1205
ZW
12888static void
12889do_t_push_pop (void)
b99bd4ef 12890{
e9f89963 12891 unsigned mask;
5f4273c7 12892
c19d1205
ZW
12893 constraint (inst.operands[0].writeback,
12894 _("push/pop do not support {reglist}^"));
e2b0ab59 12895 constraint (inst.relocs[0].type != BFD_RELOC_UNUSED,
c19d1205 12896 _("expression too complex"));
b99bd4ef 12897
e9f89963 12898 mask = inst.operands[0].imm;
d3bfe16e 12899 if (inst.size_req != 4 && (mask & ~0xff) == 0)
3c707909 12900 inst.instruction = THUMB_OP16 (inst.instruction) | mask;
d3bfe16e 12901 else if (inst.size_req != 4
c6025a80 12902 && (mask & ~0xff) == (1U << (inst.instruction == T_MNEM_push
d3bfe16e 12903 ? REG_LR : REG_PC)))
b99bd4ef 12904 {
c19d1205
ZW
12905 inst.instruction = THUMB_OP16 (inst.instruction);
12906 inst.instruction |= THUMB_PP_PC_LR;
3c707909 12907 inst.instruction |= mask & 0xff;
c19d1205
ZW
12908 }
12909 else if (unified_syntax)
12910 {
3c707909 12911 inst.instruction = THUMB_OP32 (inst.instruction);
4b5a202f
AV
12912 encode_thumb2_multi (TRUE /* do_io */, 13, mask, TRUE);
12913 }
12914 else
12915 {
12916 inst.error = _("invalid register list to push/pop instruction");
12917 return;
c19d1205 12918 }
4b5a202f
AV
12919}
12920
12921static void
12922do_t_clrm (void)
12923{
12924 if (unified_syntax)
12925 encode_thumb2_multi (FALSE /* do_io */, -1, inst.operands[0].imm, FALSE);
c19d1205
ZW
12926 else
12927 {
12928 inst.error = _("invalid register list to push/pop instruction");
12929 return;
12930 }
c19d1205 12931}
b99bd4ef 12932
efd6b359
AV
12933static void
12934do_t_vscclrm (void)
12935{
12936 if (inst.operands[0].issingle)
12937 {
12938 inst.instruction |= (inst.operands[0].reg & 0x1) << 22;
12939 inst.instruction |= (inst.operands[0].reg & 0x1e) << 11;
12940 inst.instruction |= inst.operands[0].imm;
12941 }
12942 else
12943 {
12944 inst.instruction |= (inst.operands[0].reg & 0x10) << 18;
12945 inst.instruction |= (inst.operands[0].reg & 0xf) << 12;
12946 inst.instruction |= 1 << 8;
12947 inst.instruction |= inst.operands[0].imm << 1;
12948 }
12949}
12950
c19d1205
ZW
12951static void
12952do_t_rbit (void)
12953{
fdfde340
JM
12954 unsigned Rd, Rm;
12955
12956 Rd = inst.operands[0].reg;
12957 Rm = inst.operands[1].reg;
12958
12959 reject_bad_reg (Rd);
12960 reject_bad_reg (Rm);
12961
12962 inst.instruction |= Rd << 8;
12963 inst.instruction |= Rm << 16;
12964 inst.instruction |= Rm;
c19d1205 12965}
b99bd4ef 12966
c19d1205
ZW
12967static void
12968do_t_rev (void)
12969{
fdfde340
JM
12970 unsigned Rd, Rm;
12971
12972 Rd = inst.operands[0].reg;
12973 Rm = inst.operands[1].reg;
12974
12975 reject_bad_reg (Rd);
12976 reject_bad_reg (Rm);
12977
12978 if (Rd <= 7 && Rm <= 7
c19d1205
ZW
12979 && inst.size_req != 4)
12980 {
12981 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
12982 inst.instruction |= Rd;
12983 inst.instruction |= Rm << 3;
c19d1205
ZW
12984 }
12985 else if (unified_syntax)
12986 {
12987 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
12988 inst.instruction |= Rd << 8;
12989 inst.instruction |= Rm << 16;
12990 inst.instruction |= Rm;
c19d1205
ZW
12991 }
12992 else
12993 inst.error = BAD_HIREG;
12994}
b99bd4ef 12995
1c444d06
JM
12996static void
12997do_t_rrx (void)
12998{
12999 unsigned Rd, Rm;
13000
13001 Rd = inst.operands[0].reg;
13002 Rm = inst.operands[1].reg;
13003
fdfde340
JM
13004 reject_bad_reg (Rd);
13005 reject_bad_reg (Rm);
c921be7d 13006
1c444d06
JM
13007 inst.instruction |= Rd << 8;
13008 inst.instruction |= Rm;
13009}
13010
c19d1205
ZW
13011static void
13012do_t_rsb (void)
13013{
fdfde340 13014 unsigned Rd, Rs;
b99bd4ef 13015
c19d1205
ZW
13016 Rd = inst.operands[0].reg;
13017 Rs = (inst.operands[1].present
13018 ? inst.operands[1].reg /* Rd, Rs, foo */
13019 : inst.operands[0].reg); /* Rd, foo -> Rd, Rd, foo */
b99bd4ef 13020
fdfde340
JM
13021 reject_bad_reg (Rd);
13022 reject_bad_reg (Rs);
13023 if (inst.operands[2].isreg)
13024 reject_bad_reg (inst.operands[2].reg);
13025
c19d1205
ZW
13026 inst.instruction |= Rd << 8;
13027 inst.instruction |= Rs << 16;
13028 if (!inst.operands[2].isreg)
13029 {
026d3abb
PB
13030 bfd_boolean narrow;
13031
13032 if ((inst.instruction & 0x00100000) != 0)
e07e6e58 13033 narrow = !in_it_block ();
026d3abb 13034 else
e07e6e58 13035 narrow = in_it_block ();
026d3abb
PB
13036
13037 if (Rd > 7 || Rs > 7)
13038 narrow = FALSE;
13039
13040 if (inst.size_req == 4 || !unified_syntax)
13041 narrow = FALSE;
13042
e2b0ab59
AV
13043 if (inst.relocs[0].exp.X_op != O_constant
13044 || inst.relocs[0].exp.X_add_number != 0)
026d3abb
PB
13045 narrow = FALSE;
13046
13047 /* Turn rsb #0 into 16-bit neg. We should probably do this via
477330fc 13048 relaxation, but it doesn't seem worth the hassle. */
026d3abb
PB
13049 if (narrow)
13050 {
e2b0ab59 13051 inst.relocs[0].type = BFD_RELOC_UNUSED;
026d3abb
PB
13052 inst.instruction = THUMB_OP16 (T_MNEM_negs);
13053 inst.instruction |= Rs << 3;
13054 inst.instruction |= Rd;
13055 }
13056 else
13057 {
13058 inst.instruction = (inst.instruction & 0xe1ffffff) | 0x10000000;
e2b0ab59 13059 inst.relocs[0].type = BFD_RELOC_ARM_T32_IMMEDIATE;
026d3abb 13060 }
c19d1205
ZW
13061 }
13062 else
13063 encode_thumb32_shifted_operand (2);
13064}
b99bd4ef 13065
c19d1205
ZW
13066static void
13067do_t_setend (void)
13068{
12e37cbc
MGD
13069 if (warn_on_deprecated
13070 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
5c3696f8 13071 as_tsktsk (_("setend use is deprecated for ARMv8"));
12e37cbc 13072
e07e6e58 13073 set_it_insn_type (OUTSIDE_IT_INSN);
c19d1205
ZW
13074 if (inst.operands[0].imm)
13075 inst.instruction |= 0x8;
13076}
b99bd4ef 13077
c19d1205
ZW
13078static void
13079do_t_shift (void)
13080{
13081 if (!inst.operands[1].present)
13082 inst.operands[1].reg = inst.operands[0].reg;
13083
13084 if (unified_syntax)
13085 {
3d388997
PB
13086 bfd_boolean narrow;
13087 int shift_kind;
13088
13089 switch (inst.instruction)
13090 {
13091 case T_MNEM_asr:
13092 case T_MNEM_asrs: shift_kind = SHIFT_ASR; break;
13093 case T_MNEM_lsl:
13094 case T_MNEM_lsls: shift_kind = SHIFT_LSL; break;
13095 case T_MNEM_lsr:
13096 case T_MNEM_lsrs: shift_kind = SHIFT_LSR; break;
13097 case T_MNEM_ror:
13098 case T_MNEM_rors: shift_kind = SHIFT_ROR; break;
13099 default: abort ();
13100 }
13101
13102 if (THUMB_SETS_FLAGS (inst.instruction))
e07e6e58 13103 narrow = !in_it_block ();
3d388997 13104 else
e07e6e58 13105 narrow = in_it_block ();
3d388997
PB
13106 if (inst.operands[0].reg > 7 || inst.operands[1].reg > 7)
13107 narrow = FALSE;
13108 if (!inst.operands[2].isreg && shift_kind == SHIFT_ROR)
13109 narrow = FALSE;
13110 if (inst.operands[2].isreg
13111 && (inst.operands[1].reg != inst.operands[0].reg
13112 || inst.operands[2].reg > 7))
13113 narrow = FALSE;
13114 if (inst.size_req == 4)
13115 narrow = FALSE;
13116
fdfde340
JM
13117 reject_bad_reg (inst.operands[0].reg);
13118 reject_bad_reg (inst.operands[1].reg);
c921be7d 13119
3d388997 13120 if (!narrow)
c19d1205
ZW
13121 {
13122 if (inst.operands[2].isreg)
b99bd4ef 13123 {
fdfde340 13124 reject_bad_reg (inst.operands[2].reg);
c19d1205
ZW
13125 inst.instruction = THUMB_OP32 (inst.instruction);
13126 inst.instruction |= inst.operands[0].reg << 8;
13127 inst.instruction |= inst.operands[1].reg << 16;
13128 inst.instruction |= inst.operands[2].reg;
94342ec3
NC
13129
13130 /* PR 12854: Error on extraneous shifts. */
13131 constraint (inst.operands[2].shifted,
13132 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13133 }
13134 else
13135 {
13136 inst.operands[1].shifted = 1;
3d388997 13137 inst.operands[1].shift_kind = shift_kind;
c19d1205
ZW
13138 inst.instruction = THUMB_OP32 (THUMB_SETS_FLAGS (inst.instruction)
13139 ? T_MNEM_movs : T_MNEM_mov);
13140 inst.instruction |= inst.operands[0].reg << 8;
13141 encode_thumb32_shifted_operand (1);
13142 /* Prevent the incorrect generation of an ARM_IMMEDIATE fixup. */
e2b0ab59 13143 inst.relocs[0].type = BFD_RELOC_UNUSED;
b99bd4ef
NC
13144 }
13145 }
13146 else
13147 {
c19d1205 13148 if (inst.operands[2].isreg)
b99bd4ef 13149 {
3d388997 13150 switch (shift_kind)
b99bd4ef 13151 {
3d388997
PB
13152 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_R; break;
13153 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_R; break;
13154 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_R; break;
13155 case SHIFT_ROR: inst.instruction = T_OPCODE_ROR_R; break;
c19d1205 13156 default: abort ();
b99bd4ef 13157 }
5f4273c7 13158
c19d1205
ZW
13159 inst.instruction |= inst.operands[0].reg;
13160 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13161
13162 /* PR 12854: Error on extraneous shifts. */
13163 constraint (inst.operands[2].shifted,
13164 _("extraneous shift as part of operand to shift insn"));
b99bd4ef
NC
13165 }
13166 else
13167 {
3d388997 13168 switch (shift_kind)
b99bd4ef 13169 {
3d388997
PB
13170 case SHIFT_ASR: inst.instruction = T_OPCODE_ASR_I; break;
13171 case SHIFT_LSL: inst.instruction = T_OPCODE_LSL_I; break;
13172 case SHIFT_LSR: inst.instruction = T_OPCODE_LSR_I; break;
c19d1205 13173 default: abort ();
b99bd4ef 13174 }
e2b0ab59 13175 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13176 inst.instruction |= inst.operands[0].reg;
13177 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13178 }
13179 }
c19d1205
ZW
13180 }
13181 else
13182 {
13183 constraint (inst.operands[0].reg > 7
13184 || inst.operands[1].reg > 7, BAD_HIREG);
13185 constraint (THUMB_SETS_FLAGS (inst.instruction), BAD_THUMB32);
b99bd4ef 13186
c19d1205
ZW
13187 if (inst.operands[2].isreg) /* Rd, {Rs,} Rn */
13188 {
13189 constraint (inst.operands[2].reg > 7, BAD_HIREG);
13190 constraint (inst.operands[0].reg != inst.operands[1].reg,
13191 _("source1 and dest must be same register"));
b99bd4ef 13192
c19d1205
ZW
13193 switch (inst.instruction)
13194 {
13195 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_R; break;
13196 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_R; break;
13197 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_R; break;
13198 case T_MNEM_ror: inst.instruction = T_OPCODE_ROR_R; break;
13199 default: abort ();
13200 }
5f4273c7 13201
c19d1205
ZW
13202 inst.instruction |= inst.operands[0].reg;
13203 inst.instruction |= inst.operands[2].reg << 3;
af199b06
NC
13204
13205 /* PR 12854: Error on extraneous shifts. */
13206 constraint (inst.operands[2].shifted,
13207 _("extraneous shift as part of operand to shift insn"));
c19d1205
ZW
13208 }
13209 else
b99bd4ef 13210 {
c19d1205
ZW
13211 switch (inst.instruction)
13212 {
13213 case T_MNEM_asr: inst.instruction = T_OPCODE_ASR_I; break;
13214 case T_MNEM_lsl: inst.instruction = T_OPCODE_LSL_I; break;
13215 case T_MNEM_lsr: inst.instruction = T_OPCODE_LSR_I; break;
13216 case T_MNEM_ror: inst.error = _("ror #imm not supported"); return;
13217 default: abort ();
13218 }
e2b0ab59 13219 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_SHIFT;
c19d1205
ZW
13220 inst.instruction |= inst.operands[0].reg;
13221 inst.instruction |= inst.operands[1].reg << 3;
b99bd4ef
NC
13222 }
13223 }
b99bd4ef
NC
13224}
13225
13226static void
c19d1205 13227do_t_simd (void)
b99bd4ef 13228{
fdfde340
JM
13229 unsigned Rd, Rn, Rm;
13230
13231 Rd = inst.operands[0].reg;
13232 Rn = inst.operands[1].reg;
13233 Rm = inst.operands[2].reg;
13234
13235 reject_bad_reg (Rd);
13236 reject_bad_reg (Rn);
13237 reject_bad_reg (Rm);
13238
13239 inst.instruction |= Rd << 8;
13240 inst.instruction |= Rn << 16;
13241 inst.instruction |= Rm;
c19d1205 13242}
b99bd4ef 13243
03ee1b7f
NC
13244static void
13245do_t_simd2 (void)
13246{
13247 unsigned Rd, Rn, Rm;
13248
13249 Rd = inst.operands[0].reg;
13250 Rm = inst.operands[1].reg;
13251 Rn = inst.operands[2].reg;
13252
13253 reject_bad_reg (Rd);
13254 reject_bad_reg (Rn);
13255 reject_bad_reg (Rm);
13256
13257 inst.instruction |= Rd << 8;
13258 inst.instruction |= Rn << 16;
13259 inst.instruction |= Rm;
13260}
13261
c19d1205 13262static void
3eb17e6b 13263do_t_smc (void)
c19d1205 13264{
e2b0ab59 13265 unsigned int value = inst.relocs[0].exp.X_add_number;
f4c65163
MGD
13266 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v7a),
13267 _("SMC is not permitted on this architecture"));
e2b0ab59 13268 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13269 _("expression too complex"));
e2b0ab59 13270 inst.relocs[0].type = BFD_RELOC_UNUSED;
c19d1205
ZW
13271 inst.instruction |= (value & 0xf000) >> 12;
13272 inst.instruction |= (value & 0x0ff0);
13273 inst.instruction |= (value & 0x000f) << 16;
24382199
NC
13274 /* PR gas/15623: SMC instructions must be last in an IT block. */
13275 set_it_insn_type_last ();
c19d1205 13276}
b99bd4ef 13277
90ec0d68
MGD
13278static void
13279do_t_hvc (void)
13280{
e2b0ab59 13281 unsigned int value = inst.relocs[0].exp.X_add_number;
90ec0d68 13282
e2b0ab59 13283 inst.relocs[0].type = BFD_RELOC_UNUSED;
90ec0d68
MGD
13284 inst.instruction |= (value & 0x0fff);
13285 inst.instruction |= (value & 0xf000) << 4;
13286}
13287
c19d1205 13288static void
3a21c15a 13289do_t_ssat_usat (int bias)
c19d1205 13290{
fdfde340
JM
13291 unsigned Rd, Rn;
13292
13293 Rd = inst.operands[0].reg;
13294 Rn = inst.operands[2].reg;
13295
13296 reject_bad_reg (Rd);
13297 reject_bad_reg (Rn);
13298
13299 inst.instruction |= Rd << 8;
3a21c15a 13300 inst.instruction |= inst.operands[1].imm - bias;
fdfde340 13301 inst.instruction |= Rn << 16;
b99bd4ef 13302
c19d1205 13303 if (inst.operands[3].present)
b99bd4ef 13304 {
e2b0ab59 13305 offsetT shift_amount = inst.relocs[0].exp.X_add_number;
3a21c15a 13306
e2b0ab59 13307 inst.relocs[0].type = BFD_RELOC_UNUSED;
3a21c15a 13308
e2b0ab59 13309 constraint (inst.relocs[0].exp.X_op != O_constant,
c19d1205 13310 _("expression too complex"));
b99bd4ef 13311
3a21c15a 13312 if (shift_amount != 0)
6189168b 13313 {
3a21c15a
NC
13314 constraint (shift_amount > 31,
13315 _("shift expression is too large"));
13316
c19d1205 13317 if (inst.operands[3].shift_kind == SHIFT_ASR)
3a21c15a
NC
13318 inst.instruction |= 0x00200000; /* sh bit. */
13319
13320 inst.instruction |= (shift_amount & 0x1c) << 10;
13321 inst.instruction |= (shift_amount & 0x03) << 6;
6189168b
NC
13322 }
13323 }
b99bd4ef 13324}
c921be7d 13325
3a21c15a
NC
13326static void
13327do_t_ssat (void)
13328{
13329 do_t_ssat_usat (1);
13330}
b99bd4ef 13331
0dd132b6 13332static void
c19d1205 13333do_t_ssat16 (void)
0dd132b6 13334{
fdfde340
JM
13335 unsigned Rd, Rn;
13336
13337 Rd = inst.operands[0].reg;
13338 Rn = inst.operands[2].reg;
13339
13340 reject_bad_reg (Rd);
13341 reject_bad_reg (Rn);
13342
13343 inst.instruction |= Rd << 8;
c19d1205 13344 inst.instruction |= inst.operands[1].imm - 1;
fdfde340 13345 inst.instruction |= Rn << 16;
c19d1205 13346}
0dd132b6 13347
c19d1205
ZW
13348static void
13349do_t_strex (void)
13350{
13351 constraint (!inst.operands[2].isreg || !inst.operands[2].preind
13352 || inst.operands[2].postind || inst.operands[2].writeback
13353 || inst.operands[2].immisreg || inst.operands[2].shifted
13354 || inst.operands[2].negative,
01cfc07f 13355 BAD_ADDR_MODE);
0dd132b6 13356
5be8be5d
DG
13357 constraint (inst.operands[2].reg == REG_PC, BAD_PC);
13358
c19d1205
ZW
13359 inst.instruction |= inst.operands[0].reg << 8;
13360 inst.instruction |= inst.operands[1].reg << 12;
13361 inst.instruction |= inst.operands[2].reg << 16;
e2b0ab59 13362 inst.relocs[0].type = BFD_RELOC_ARM_T32_OFFSET_U8;
0dd132b6
NC
13363}
13364
b99bd4ef 13365static void
c19d1205 13366do_t_strexd (void)
b99bd4ef 13367{
c19d1205
ZW
13368 if (!inst.operands[2].present)
13369 inst.operands[2].reg = inst.operands[1].reg + 1;
b99bd4ef 13370
c19d1205
ZW
13371 constraint (inst.operands[0].reg == inst.operands[1].reg
13372 || inst.operands[0].reg == inst.operands[2].reg
f8a8e9d6 13373 || inst.operands[0].reg == inst.operands[3].reg,
c19d1205 13374 BAD_OVERLAP);
b99bd4ef 13375
c19d1205
ZW
13376 inst.instruction |= inst.operands[0].reg;
13377 inst.instruction |= inst.operands[1].reg << 12;
13378 inst.instruction |= inst.operands[2].reg << 8;
13379 inst.instruction |= inst.operands[3].reg << 16;
b99bd4ef
NC
13380}
13381
13382static void
c19d1205 13383do_t_sxtah (void)
b99bd4ef 13384{
fdfde340
JM
13385 unsigned Rd, Rn, Rm;
13386
13387 Rd = inst.operands[0].reg;
13388 Rn = inst.operands[1].reg;
13389 Rm = inst.operands[2].reg;
13390
13391 reject_bad_reg (Rd);
13392 reject_bad_reg (Rn);
13393 reject_bad_reg (Rm);
13394
13395 inst.instruction |= Rd << 8;
13396 inst.instruction |= Rn << 16;
13397 inst.instruction |= Rm;
c19d1205
ZW
13398 inst.instruction |= inst.operands[3].imm << 4;
13399}
b99bd4ef 13400
c19d1205
ZW
13401static void
13402do_t_sxth (void)
13403{
fdfde340
JM
13404 unsigned Rd, Rm;
13405
13406 Rd = inst.operands[0].reg;
13407 Rm = inst.operands[1].reg;
13408
13409 reject_bad_reg (Rd);
13410 reject_bad_reg (Rm);
c921be7d
NC
13411
13412 if (inst.instruction <= 0xffff
13413 && inst.size_req != 4
fdfde340 13414 && Rd <= 7 && Rm <= 7
c19d1205 13415 && (!inst.operands[2].present || inst.operands[2].imm == 0))
b99bd4ef 13416 {
c19d1205 13417 inst.instruction = THUMB_OP16 (inst.instruction);
fdfde340
JM
13418 inst.instruction |= Rd;
13419 inst.instruction |= Rm << 3;
b99bd4ef 13420 }
c19d1205 13421 else if (unified_syntax)
b99bd4ef 13422 {
c19d1205
ZW
13423 if (inst.instruction <= 0xffff)
13424 inst.instruction = THUMB_OP32 (inst.instruction);
fdfde340
JM
13425 inst.instruction |= Rd << 8;
13426 inst.instruction |= Rm;
c19d1205 13427 inst.instruction |= inst.operands[2].imm << 4;
b99bd4ef 13428 }
c19d1205 13429 else
b99bd4ef 13430 {
c19d1205
ZW
13431 constraint (inst.operands[2].present && inst.operands[2].imm != 0,
13432 _("Thumb encoding does not support rotation"));
13433 constraint (1, BAD_HIREG);
b99bd4ef 13434 }
c19d1205 13435}
b99bd4ef 13436
c19d1205
ZW
13437static void
13438do_t_swi (void)
13439{
e2b0ab59 13440 inst.relocs[0].type = BFD_RELOC_ARM_SWI;
c19d1205 13441}
b99bd4ef 13442
92e90b6e
PB
13443static void
13444do_t_tb (void)
13445{
fdfde340 13446 unsigned Rn, Rm;
92e90b6e
PB
13447 int half;
13448
13449 half = (inst.instruction & 0x10) != 0;
e07e6e58 13450 set_it_insn_type_last ();
dfa9f0d5
PB
13451 constraint (inst.operands[0].immisreg,
13452 _("instruction requires register index"));
fdfde340
JM
13453
13454 Rn = inst.operands[0].reg;
13455 Rm = inst.operands[0].imm;
c921be7d 13456
5c8ed6a4
JW
13457 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8))
13458 constraint (Rn == REG_SP, BAD_SP);
fdfde340
JM
13459 reject_bad_reg (Rm);
13460
92e90b6e
PB
13461 constraint (!half && inst.operands[0].shifted,
13462 _("instruction does not allow shifted index"));
fdfde340 13463 inst.instruction |= (Rn << 16) | Rm;
92e90b6e
PB
13464}
13465
74db7efb
NC
13466static void
13467do_t_udf (void)
13468{
13469 if (!inst.operands[0].present)
13470 inst.operands[0].imm = 0;
13471
13472 if ((unsigned int) inst.operands[0].imm > 255 || inst.size_req == 4)
13473 {
13474 constraint (inst.size_req == 2,
13475 _("immediate value out of range"));
13476 inst.instruction = THUMB_OP32 (inst.instruction);
13477 inst.instruction |= (inst.operands[0].imm & 0xf000u) << 4;
13478 inst.instruction |= (inst.operands[0].imm & 0x0fffu) << 0;
13479 }
13480 else
13481 {
13482 inst.instruction = THUMB_OP16 (inst.instruction);
13483 inst.instruction |= inst.operands[0].imm;
13484 }
13485
13486 set_it_insn_type (NEUTRAL_IT_INSN);
13487}
13488
13489
c19d1205
ZW
13490static void
13491do_t_usat (void)
13492{
3a21c15a 13493 do_t_ssat_usat (0);
b99bd4ef
NC
13494}
13495
13496static void
c19d1205 13497do_t_usat16 (void)
b99bd4ef 13498{
fdfde340
JM
13499 unsigned Rd, Rn;
13500
13501 Rd = inst.operands[0].reg;
13502 Rn = inst.operands[2].reg;
13503
13504 reject_bad_reg (Rd);
13505 reject_bad_reg (Rn);
13506
13507 inst.instruction |= Rd << 8;
c19d1205 13508 inst.instruction |= inst.operands[1].imm;
fdfde340 13509 inst.instruction |= Rn << 16;
b99bd4ef 13510}
c19d1205 13511
e12437dc
AV
13512/* Checking the range of the branch offset (VAL) with NBITS bits
13513 and IS_SIGNED signedness. Also checks the LSB to be 0. */
13514static int
13515v8_1_branch_value_check (int val, int nbits, int is_signed)
13516{
13517 gas_assert (nbits > 0 && nbits <= 32);
13518 if (is_signed)
13519 {
13520 int cmp = (1 << (nbits - 1));
13521 if ((val < -cmp) || (val >= cmp) || (val & 0x01))
13522 return FAIL;
13523 }
13524 else
13525 {
13526 if ((val <= 0) || (val >= (1 << nbits)) || (val & 0x1))
13527 return FAIL;
13528 }
13529 return SUCCESS;
13530}
13531
4389b29a
AV
13532/* For branches in Armv8.1-M Mainline. */
13533static void
13534do_t_branch_future (void)
13535{
13536 unsigned long insn = inst.instruction;
13537
13538 inst.instruction = THUMB_OP32 (inst.instruction);
13539 if (inst.operands[0].hasreloc == 0)
13540 {
13541 if (v8_1_branch_value_check (inst.operands[0].imm, 5, FALSE) == FAIL)
13542 as_bad (BAD_BRANCH_OFF);
13543
13544 inst.instruction |= ((inst.operands[0].imm & 0x1f) >> 1) << 23;
13545 }
13546 else
13547 {
13548 inst.relocs[0].type = BFD_RELOC_THUMB_PCREL_BRANCH5;
13549 inst.relocs[0].pc_rel = 1;
13550 }
13551
13552 switch (insn)
13553 {
13554 case T_MNEM_bf:
13555 if (inst.operands[1].hasreloc == 0)
13556 {
13557 int val = inst.operands[1].imm;
13558 if (v8_1_branch_value_check (inst.operands[1].imm, 17, TRUE) == FAIL)
13559 as_bad (BAD_BRANCH_OFF);
13560
13561 int immA = (val & 0x0001f000) >> 12;
13562 int immB = (val & 0x00000ffc) >> 2;
13563 int immC = (val & 0x00000002) >> 1;
13564 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
13565 }
13566 else
13567 {
13568 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF17;
13569 inst.relocs[1].pc_rel = 1;
13570 }
13571 break;
13572
65d1bc05
AV
13573 case T_MNEM_bfl:
13574 if (inst.operands[1].hasreloc == 0)
13575 {
13576 int val = inst.operands[1].imm;
13577 if (v8_1_branch_value_check (inst.operands[1].imm, 19, TRUE) == FAIL)
13578 as_bad (BAD_BRANCH_OFF);
13579
13580 int immA = (val & 0x0007f000) >> 12;
13581 int immB = (val & 0x00000ffc) >> 2;
13582 int immC = (val & 0x00000002) >> 1;
13583 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
13584 }
13585 else
13586 {
13587 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF19;
13588 inst.relocs[1].pc_rel = 1;
13589 }
13590 break;
13591
f6b2b12d
AV
13592 case T_MNEM_bfcsel:
13593 /* Operand 1. */
13594 if (inst.operands[1].hasreloc == 0)
13595 {
13596 int val = inst.operands[1].imm;
13597 int immA = (val & 0x00001000) >> 12;
13598 int immB = (val & 0x00000ffc) >> 2;
13599 int immC = (val & 0x00000002) >> 1;
13600 inst.instruction |= (immA << 16) | (immB << 1) | (immC << 11);
13601 }
13602 else
13603 {
13604 inst.relocs[1].type = BFD_RELOC_ARM_THUMB_BF13;
13605 inst.relocs[1].pc_rel = 1;
13606 }
13607
13608 /* Operand 2. */
13609 if (inst.operands[2].hasreloc == 0)
13610 {
13611 constraint ((inst.operands[0].hasreloc != 0), BAD_ARGS);
13612 int val2 = inst.operands[2].imm;
13613 int val0 = inst.operands[0].imm & 0x1f;
13614 int diff = val2 - val0;
13615 if (diff == 4)
13616 inst.instruction |= 1 << 17; /* T bit. */
13617 else if (diff != 2)
13618 as_bad (_("out of range label-relative fixup value"));
13619 }
13620 else
13621 {
13622 constraint ((inst.operands[0].hasreloc == 0), BAD_ARGS);
13623 inst.relocs[2].type = BFD_RELOC_THUMB_PCREL_BFCSEL;
13624 inst.relocs[2].pc_rel = 1;
13625 }
13626
13627 /* Operand 3. */
13628 constraint (inst.cond != COND_ALWAYS, BAD_COND);
13629 inst.instruction |= (inst.operands[3].imm & 0xf) << 18;
13630 break;
13631
f1c7f421
AV
13632 case T_MNEM_bfx:
13633 case T_MNEM_bflx:
13634 inst.instruction |= inst.operands[1].reg << 16;
13635 break;
13636
4389b29a
AV
13637 default: abort ();
13638 }
13639}
13640
60f993ce
AV
13641/* Helper function for do_t_loloop to handle relocations. */
13642static void
13643v8_1_loop_reloc (int is_le)
13644{
13645 if (inst.relocs[0].exp.X_op == O_constant)
13646 {
13647 int value = inst.relocs[0].exp.X_add_number;
13648 value = (is_le) ? -value : value;
13649
13650 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
13651 as_bad (BAD_BRANCH_OFF);
13652
13653 int imml, immh;
13654
13655 immh = (value & 0x00000ffc) >> 2;
13656 imml = (value & 0x00000002) >> 1;
13657
13658 inst.instruction |= (imml << 11) | (immh << 1);
13659 }
13660 else
13661 {
13662 inst.relocs[0].type = BFD_RELOC_ARM_THUMB_LOOP12;
13663 inst.relocs[0].pc_rel = 1;
13664 }
13665}
13666
13667/* To handle the Scalar Low Overhead Loop instructions
13668 in Armv8.1-M Mainline. */
13669static void
13670do_t_loloop (void)
13671{
13672 unsigned long insn = inst.instruction;
13673
13674 set_it_insn_type (OUTSIDE_IT_INSN);
13675 inst.instruction = THUMB_OP32 (inst.instruction);
13676
13677 switch (insn)
13678 {
13679 case T_MNEM_le:
13680 /* le <label>. */
13681 if (!inst.operands[0].present)
13682 inst.instruction |= 1 << 21;
13683
13684 v8_1_loop_reloc (TRUE);
13685 break;
13686
13687 case T_MNEM_wls:
13688 v8_1_loop_reloc (FALSE);
13689 /* Fall through. */
13690 case T_MNEM_dls:
13691 constraint (inst.operands[1].isreg != 1, BAD_ARGS);
13692 inst.instruction |= (inst.operands[1].reg << 16);
13693 break;
13694
13695 default: abort();
13696 }
13697}
13698
5287ad62 13699/* Neon instruction encoder helpers. */
5f4273c7 13700
5287ad62 13701/* Encodings for the different types for various Neon opcodes. */
b99bd4ef 13702
5287ad62
JB
13703/* An "invalid" code for the following tables. */
13704#define N_INV -1u
13705
13706struct neon_tab_entry
b99bd4ef 13707{
5287ad62
JB
13708 unsigned integer;
13709 unsigned float_or_poly;
13710 unsigned scalar_or_imm;
13711};
5f4273c7 13712
5287ad62
JB
13713/* Map overloaded Neon opcodes to their respective encodings. */
13714#define NEON_ENC_TAB \
13715 X(vabd, 0x0000700, 0x1200d00, N_INV), \
13716 X(vmax, 0x0000600, 0x0000f00, N_INV), \
13717 X(vmin, 0x0000610, 0x0200f00, N_INV), \
13718 X(vpadd, 0x0000b10, 0x1000d00, N_INV), \
13719 X(vpmax, 0x0000a00, 0x1000f00, N_INV), \
13720 X(vpmin, 0x0000a10, 0x1200f00, N_INV), \
13721 X(vadd, 0x0000800, 0x0000d00, N_INV), \
13722 X(vsub, 0x1000800, 0x0200d00, N_INV), \
13723 X(vceq, 0x1000810, 0x0000e00, 0x1b10100), \
13724 X(vcge, 0x0000310, 0x1000e00, 0x1b10080), \
13725 X(vcgt, 0x0000300, 0x1200e00, 0x1b10000), \
13726 /* Register variants of the following two instructions are encoded as
e07e6e58 13727 vcge / vcgt with the operands reversed. */ \
92559b5b
PB
13728 X(vclt, 0x0000300, 0x1200e00, 0x1b10200), \
13729 X(vcle, 0x0000310, 0x1000e00, 0x1b10180), \
62f3b8c8
PB
13730 X(vfma, N_INV, 0x0000c10, N_INV), \
13731 X(vfms, N_INV, 0x0200c10, N_INV), \
5287ad62
JB
13732 X(vmla, 0x0000900, 0x0000d10, 0x0800040), \
13733 X(vmls, 0x1000900, 0x0200d10, 0x0800440), \
13734 X(vmul, 0x0000910, 0x1000d10, 0x0800840), \
13735 X(vmull, 0x0800c00, 0x0800e00, 0x0800a40), /* polynomial not float. */ \
13736 X(vmlal, 0x0800800, N_INV, 0x0800240), \
13737 X(vmlsl, 0x0800a00, N_INV, 0x0800640), \
13738 X(vqdmlal, 0x0800900, N_INV, 0x0800340), \
13739 X(vqdmlsl, 0x0800b00, N_INV, 0x0800740), \
13740 X(vqdmull, 0x0800d00, N_INV, 0x0800b40), \
13741 X(vqdmulh, 0x0000b00, N_INV, 0x0800c40), \
13742 X(vqrdmulh, 0x1000b00, N_INV, 0x0800d40), \
d6b4b13e
MW
13743 X(vqrdmlah, 0x3000b10, N_INV, 0x0800e40), \
13744 X(vqrdmlsh, 0x3000c10, N_INV, 0x0800f40), \
5287ad62
JB
13745 X(vshl, 0x0000400, N_INV, 0x0800510), \
13746 X(vqshl, 0x0000410, N_INV, 0x0800710), \
13747 X(vand, 0x0000110, N_INV, 0x0800030), \
13748 X(vbic, 0x0100110, N_INV, 0x0800030), \
13749 X(veor, 0x1000110, N_INV, N_INV), \
13750 X(vorn, 0x0300110, N_INV, 0x0800010), \
13751 X(vorr, 0x0200110, N_INV, 0x0800010), \
13752 X(vmvn, 0x1b00580, N_INV, 0x0800030), \
13753 X(vshll, 0x1b20300, N_INV, 0x0800a10), /* max shift, immediate. */ \
13754 X(vcvt, 0x1b30600, N_INV, 0x0800e10), /* integer, fixed-point. */ \
13755 X(vdup, 0xe800b10, N_INV, 0x1b00c00), /* arm, scalar. */ \
13756 X(vld1, 0x0200000, 0x0a00000, 0x0a00c00), /* interlv, lane, dup. */ \
13757 X(vst1, 0x0000000, 0x0800000, N_INV), \
13758 X(vld2, 0x0200100, 0x0a00100, 0x0a00d00), \
13759 X(vst2, 0x0000100, 0x0800100, N_INV), \
13760 X(vld3, 0x0200200, 0x0a00200, 0x0a00e00), \
13761 X(vst3, 0x0000200, 0x0800200, N_INV), \
13762 X(vld4, 0x0200300, 0x0a00300, 0x0a00f00), \
13763 X(vst4, 0x0000300, 0x0800300, N_INV), \
13764 X(vmovn, 0x1b20200, N_INV, N_INV), \
13765 X(vtrn, 0x1b20080, N_INV, N_INV), \
13766 X(vqmovn, 0x1b20200, N_INV, N_INV), \
037e8744
JB
13767 X(vqmovun, 0x1b20240, N_INV, N_INV), \
13768 X(vnmul, 0xe200a40, 0xe200b40, N_INV), \
e6655fda
PB
13769 X(vnmla, 0xe100a40, 0xe100b40, N_INV), \
13770 X(vnmls, 0xe100a00, 0xe100b00, N_INV), \
62f3b8c8
PB
13771 X(vfnma, 0xe900a40, 0xe900b40, N_INV), \
13772 X(vfnms, 0xe900a00, 0xe900b00, N_INV), \
037e8744
JB
13773 X(vcmp, 0xeb40a40, 0xeb40b40, N_INV), \
13774 X(vcmpz, 0xeb50a40, 0xeb50b40, N_INV), \
13775 X(vcmpe, 0xeb40ac0, 0xeb40bc0, N_INV), \
33399f07
MGD
13776 X(vcmpez, 0xeb50ac0, 0xeb50bc0, N_INV), \
13777 X(vseleq, 0xe000a00, N_INV, N_INV), \
13778 X(vselvs, 0xe100a00, N_INV, N_INV), \
13779 X(vselge, 0xe200a00, N_INV, N_INV), \
73924fbc
MGD
13780 X(vselgt, 0xe300a00, N_INV, N_INV), \
13781 X(vmaxnm, 0xe800a00, 0x3000f10, N_INV), \
7e8e6784 13782 X(vminnm, 0xe800a40, 0x3200f10, N_INV), \
30bdf752
MGD
13783 X(vcvta, 0xebc0a40, 0x3bb0000, N_INV), \
13784 X(vrintr, 0xeb60a40, 0x3ba0400, N_INV), \
91ff7894 13785 X(vrinta, 0xeb80a40, 0x3ba0400, N_INV), \
48adcd8e 13786 X(aes, 0x3b00300, N_INV, N_INV), \
3c9017d2
MGD
13787 X(sha3op, 0x2000c00, N_INV, N_INV), \
13788 X(sha1h, 0x3b902c0, N_INV, N_INV), \
13789 X(sha2op, 0x3ba0380, N_INV, N_INV)
5287ad62
JB
13790
13791enum neon_opc
13792{
13793#define X(OPC,I,F,S) N_MNEM_##OPC
13794NEON_ENC_TAB
13795#undef X
13796};
b99bd4ef 13797
5287ad62
JB
13798static const struct neon_tab_entry neon_enc_tab[] =
13799{
13800#define X(OPC,I,F,S) { (I), (F), (S) }
13801NEON_ENC_TAB
13802#undef X
13803};
b99bd4ef 13804
88714cb8
DG
13805/* Do not use these macros; instead, use NEON_ENCODE defined below. */
13806#define NEON_ENC_INTEGER_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
13807#define NEON_ENC_ARMREG_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
13808#define NEON_ENC_POLY_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
13809#define NEON_ENC_FLOAT_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
13810#define NEON_ENC_SCALAR_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
13811#define NEON_ENC_IMMED_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
13812#define NEON_ENC_INTERLV_(X) (neon_enc_tab[(X) & 0x0fffffff].integer)
13813#define NEON_ENC_LANE_(X) (neon_enc_tab[(X) & 0x0fffffff].float_or_poly)
13814#define NEON_ENC_DUP_(X) (neon_enc_tab[(X) & 0x0fffffff].scalar_or_imm)
13815#define NEON_ENC_SINGLE_(X) \
037e8744 13816 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf0000000))
88714cb8 13817#define NEON_ENC_DOUBLE_(X) \
037e8744 13818 ((neon_enc_tab[(X) & 0x0fffffff].float_or_poly) | ((X) & 0xf0000000))
33399f07
MGD
13819#define NEON_ENC_FPV8_(X) \
13820 ((neon_enc_tab[(X) & 0x0fffffff].integer) | ((X) & 0xf000000))
5287ad62 13821
88714cb8
DG
13822#define NEON_ENCODE(type, inst) \
13823 do \
13824 { \
13825 inst.instruction = NEON_ENC_##type##_ (inst.instruction); \
13826 inst.is_neon = 1; \
13827 } \
13828 while (0)
13829
13830#define check_neon_suffixes \
13831 do \
13832 { \
13833 if (!inst.error && inst.vectype.elems > 0 && !inst.is_neon) \
13834 { \
13835 as_bad (_("invalid neon suffix for non neon instruction")); \
13836 return; \
13837 } \
13838 } \
13839 while (0)
13840
037e8744
JB
13841/* Define shapes for instruction operands. The following mnemonic characters
13842 are used in this table:
5287ad62 13843
037e8744 13844 F - VFP S<n> register
5287ad62
JB
13845 D - Neon D<n> register
13846 Q - Neon Q<n> register
13847 I - Immediate
13848 S - Scalar
13849 R - ARM register
13850 L - D<n> register list
5f4273c7 13851
037e8744
JB
13852 This table is used to generate various data:
13853 - enumerations of the form NS_DDR to be used as arguments to
13854 neon_select_shape.
13855 - a table classifying shapes into single, double, quad, mixed.
5f4273c7 13856 - a table used to drive neon_select_shape. */
b99bd4ef 13857
037e8744
JB
13858#define NEON_SHAPE_DEF \
13859 X(3, (D, D, D), DOUBLE), \
13860 X(3, (Q, Q, Q), QUAD), \
13861 X(3, (D, D, I), DOUBLE), \
13862 X(3, (Q, Q, I), QUAD), \
13863 X(3, (D, D, S), DOUBLE), \
13864 X(3, (Q, Q, S), QUAD), \
13865 X(2, (D, D), DOUBLE), \
13866 X(2, (Q, Q), QUAD), \
13867 X(2, (D, S), DOUBLE), \
13868 X(2, (Q, S), QUAD), \
13869 X(2, (D, R), DOUBLE), \
13870 X(2, (Q, R), QUAD), \
13871 X(2, (D, I), DOUBLE), \
13872 X(2, (Q, I), QUAD), \
13873 X(3, (D, L, D), DOUBLE), \
13874 X(2, (D, Q), MIXED), \
13875 X(2, (Q, D), MIXED), \
13876 X(3, (D, Q, I), MIXED), \
13877 X(3, (Q, D, I), MIXED), \
13878 X(3, (Q, D, D), MIXED), \
13879 X(3, (D, Q, Q), MIXED), \
13880 X(3, (Q, Q, D), MIXED), \
13881 X(3, (Q, D, S), MIXED), \
13882 X(3, (D, Q, S), MIXED), \
13883 X(4, (D, D, D, I), DOUBLE), \
13884 X(4, (Q, Q, Q, I), QUAD), \
c28eeff2
SN
13885 X(4, (D, D, S, I), DOUBLE), \
13886 X(4, (Q, Q, S, I), QUAD), \
037e8744
JB
13887 X(2, (F, F), SINGLE), \
13888 X(3, (F, F, F), SINGLE), \
13889 X(2, (F, I), SINGLE), \
13890 X(2, (F, D), MIXED), \
13891 X(2, (D, F), MIXED), \
13892 X(3, (F, F, I), MIXED), \
13893 X(4, (R, R, F, F), SINGLE), \
13894 X(4, (F, F, R, R), SINGLE), \
13895 X(3, (D, R, R), DOUBLE), \
13896 X(3, (R, R, D), DOUBLE), \
13897 X(2, (S, R), SINGLE), \
13898 X(2, (R, S), SINGLE), \
13899 X(2, (F, R), SINGLE), \
d54af2d0
RL
13900 X(2, (R, F), SINGLE), \
13901/* Half float shape supported so far. */\
13902 X (2, (H, D), MIXED), \
13903 X (2, (D, H), MIXED), \
13904 X (2, (H, F), MIXED), \
13905 X (2, (F, H), MIXED), \
13906 X (2, (H, H), HALF), \
13907 X (2, (H, R), HALF), \
13908 X (2, (R, H), HALF), \
13909 X (2, (H, I), HALF), \
13910 X (3, (H, H, H), HALF), \
13911 X (3, (H, F, I), MIXED), \
dec41383
JW
13912 X (3, (F, H, I), MIXED), \
13913 X (3, (D, H, H), MIXED), \
13914 X (3, (D, H, S), MIXED)
037e8744
JB
13915
13916#define S2(A,B) NS_##A##B
13917#define S3(A,B,C) NS_##A##B##C
13918#define S4(A,B,C,D) NS_##A##B##C##D
13919
13920#define X(N, L, C) S##N L
13921
5287ad62
JB
13922enum neon_shape
13923{
037e8744
JB
13924 NEON_SHAPE_DEF,
13925 NS_NULL
5287ad62 13926};
b99bd4ef 13927
037e8744
JB
13928#undef X
13929#undef S2
13930#undef S3
13931#undef S4
13932
13933enum neon_shape_class
13934{
d54af2d0 13935 SC_HALF,
037e8744
JB
13936 SC_SINGLE,
13937 SC_DOUBLE,
13938 SC_QUAD,
13939 SC_MIXED
13940};
13941
13942#define X(N, L, C) SC_##C
13943
13944static enum neon_shape_class neon_shape_class[] =
13945{
13946 NEON_SHAPE_DEF
13947};
13948
13949#undef X
13950
13951enum neon_shape_el
13952{
d54af2d0 13953 SE_H,
037e8744
JB
13954 SE_F,
13955 SE_D,
13956 SE_Q,
13957 SE_I,
13958 SE_S,
13959 SE_R,
13960 SE_L
13961};
13962
13963/* Register widths of above. */
13964static unsigned neon_shape_el_size[] =
13965{
d54af2d0 13966 16,
037e8744
JB
13967 32,
13968 64,
13969 128,
13970 0,
13971 32,
13972 32,
13973 0
13974};
13975
13976struct neon_shape_info
13977{
13978 unsigned els;
13979 enum neon_shape_el el[NEON_MAX_TYPE_ELS];
13980};
13981
13982#define S2(A,B) { SE_##A, SE_##B }
13983#define S3(A,B,C) { SE_##A, SE_##B, SE_##C }
13984#define S4(A,B,C,D) { SE_##A, SE_##B, SE_##C, SE_##D }
13985
13986#define X(N, L, C) { N, S##N L }
13987
13988static struct neon_shape_info neon_shape_tab[] =
13989{
13990 NEON_SHAPE_DEF
13991};
13992
13993#undef X
13994#undef S2
13995#undef S3
13996#undef S4
13997
5287ad62
JB
13998/* Bit masks used in type checking given instructions.
13999 'N_EQK' means the type must be the same as (or based on in some way) the key
14000 type, which itself is marked with the 'N_KEY' bit. If the 'N_EQK' bit is
14001 set, various other bits can be set as well in order to modify the meaning of
14002 the type constraint. */
14003
14004enum neon_type_mask
14005{
8e79c3df
CM
14006 N_S8 = 0x0000001,
14007 N_S16 = 0x0000002,
14008 N_S32 = 0x0000004,
14009 N_S64 = 0x0000008,
14010 N_U8 = 0x0000010,
14011 N_U16 = 0x0000020,
14012 N_U32 = 0x0000040,
14013 N_U64 = 0x0000080,
14014 N_I8 = 0x0000100,
14015 N_I16 = 0x0000200,
14016 N_I32 = 0x0000400,
14017 N_I64 = 0x0000800,
14018 N_8 = 0x0001000,
14019 N_16 = 0x0002000,
14020 N_32 = 0x0004000,
14021 N_64 = 0x0008000,
14022 N_P8 = 0x0010000,
14023 N_P16 = 0x0020000,
14024 N_F16 = 0x0040000,
14025 N_F32 = 0x0080000,
14026 N_F64 = 0x0100000,
4f51b4bd 14027 N_P64 = 0x0200000,
c921be7d
NC
14028 N_KEY = 0x1000000, /* Key element (main type specifier). */
14029 N_EQK = 0x2000000, /* Given operand has the same type & size as the key. */
8e79c3df 14030 N_VFP = 0x4000000, /* VFP mode: operand size must match register width. */
91ff7894 14031 N_UNT = 0x8000000, /* Must be explicitly untyped. */
c921be7d
NC
14032 N_DBL = 0x0000001, /* If N_EQK, this operand is twice the size. */
14033 N_HLF = 0x0000002, /* If N_EQK, this operand is half the size. */
14034 N_SGN = 0x0000004, /* If N_EQK, this operand is forced to be signed. */
14035 N_UNS = 0x0000008, /* If N_EQK, this operand is forced to be unsigned. */
14036 N_INT = 0x0000010, /* If N_EQK, this operand is forced to be integer. */
14037 N_FLT = 0x0000020, /* If N_EQK, this operand is forced to be float. */
14038 N_SIZ = 0x0000040, /* If N_EQK, this operand is forced to be size-only. */
5287ad62 14039 N_UTYP = 0,
4f51b4bd 14040 N_MAX_NONSPECIAL = N_P64
5287ad62
JB
14041};
14042
dcbf9037
JB
14043#define N_ALLMODS (N_DBL | N_HLF | N_SGN | N_UNS | N_INT | N_FLT | N_SIZ)
14044
5287ad62
JB
14045#define N_SU_ALL (N_S8 | N_S16 | N_S32 | N_S64 | N_U8 | N_U16 | N_U32 | N_U64)
14046#define N_SU_32 (N_S8 | N_S16 | N_S32 | N_U8 | N_U16 | N_U32)
14047#define N_SU_16_64 (N_S16 | N_S32 | N_S64 | N_U16 | N_U32 | N_U64)
cc933301
JW
14048#define N_S_32 (N_S8 | N_S16 | N_S32)
14049#define N_F_16_32 (N_F16 | N_F32)
14050#define N_SUF_32 (N_SU_32 | N_F_16_32)
5287ad62 14051#define N_I_ALL (N_I8 | N_I16 | N_I32 | N_I64)
cc933301 14052#define N_IF_32 (N_I8 | N_I16 | N_I32 | N_F16 | N_F32)
d54af2d0 14053#define N_F_ALL (N_F16 | N_F32 | N_F64)
5287ad62
JB
14054
14055/* Pass this as the first type argument to neon_check_type to ignore types
14056 altogether. */
14057#define N_IGNORE_TYPE (N_KEY | N_EQK)
14058
037e8744
JB
14059/* Select a "shape" for the current instruction (describing register types or
14060 sizes) from a list of alternatives. Return NS_NULL if the current instruction
14061 doesn't fit. For non-polymorphic shapes, checking is usually done as a
14062 function of operand parsing, so this function doesn't need to be called.
14063 Shapes should be listed in order of decreasing length. */
5287ad62
JB
14064
14065static enum neon_shape
037e8744 14066neon_select_shape (enum neon_shape shape, ...)
5287ad62 14067{
037e8744
JB
14068 va_list ap;
14069 enum neon_shape first_shape = shape;
5287ad62
JB
14070
14071 /* Fix missing optional operands. FIXME: we don't know at this point how
14072 many arguments we should have, so this makes the assumption that we have
14073 > 1. This is true of all current Neon opcodes, I think, but may not be
14074 true in the future. */
14075 if (!inst.operands[1].present)
14076 inst.operands[1] = inst.operands[0];
14077
037e8744 14078 va_start (ap, shape);
5f4273c7 14079
21d799b5 14080 for (; shape != NS_NULL; shape = (enum neon_shape) va_arg (ap, int))
037e8744
JB
14081 {
14082 unsigned j;
14083 int matches = 1;
14084
14085 for (j = 0; j < neon_shape_tab[shape].els; j++)
477330fc
RM
14086 {
14087 if (!inst.operands[j].present)
14088 {
14089 matches = 0;
14090 break;
14091 }
14092
14093 switch (neon_shape_tab[shape].el[j])
14094 {
d54af2d0
RL
14095 /* If a .f16, .16, .u16, .s16 type specifier is given over
14096 a VFP single precision register operand, it's essentially
14097 means only half of the register is used.
14098
14099 If the type specifier is given after the mnemonics, the
14100 information is stored in inst.vectype. If the type specifier
14101 is given after register operand, the information is stored
14102 in inst.operands[].vectype.
14103
14104 When there is only one type specifier, and all the register
14105 operands are the same type of hardware register, the type
14106 specifier applies to all register operands.
14107
14108 If no type specifier is given, the shape is inferred from
14109 operand information.
14110
14111 for example:
14112 vadd.f16 s0, s1, s2: NS_HHH
14113 vabs.f16 s0, s1: NS_HH
14114 vmov.f16 s0, r1: NS_HR
14115 vmov.f16 r0, s1: NS_RH
14116 vcvt.f16 r0, s1: NS_RH
14117 vcvt.f16.s32 s2, s2, #29: NS_HFI
14118 vcvt.f16.s32 s2, s2: NS_HF
14119 */
14120 case SE_H:
14121 if (!(inst.operands[j].isreg
14122 && inst.operands[j].isvec
14123 && inst.operands[j].issingle
14124 && !inst.operands[j].isquad
14125 && ((inst.vectype.elems == 1
14126 && inst.vectype.el[0].size == 16)
14127 || (inst.vectype.elems > 1
14128 && inst.vectype.el[j].size == 16)
14129 || (inst.vectype.elems == 0
14130 && inst.operands[j].vectype.type != NT_invtype
14131 && inst.operands[j].vectype.size == 16))))
14132 matches = 0;
14133 break;
14134
477330fc
RM
14135 case SE_F:
14136 if (!(inst.operands[j].isreg
14137 && inst.operands[j].isvec
14138 && inst.operands[j].issingle
d54af2d0
RL
14139 && !inst.operands[j].isquad
14140 && ((inst.vectype.elems == 1 && inst.vectype.el[0].size == 32)
14141 || (inst.vectype.elems > 1 && inst.vectype.el[j].size == 32)
14142 || (inst.vectype.elems == 0
14143 && (inst.operands[j].vectype.size == 32
14144 || inst.operands[j].vectype.type == NT_invtype)))))
477330fc
RM
14145 matches = 0;
14146 break;
14147
14148 case SE_D:
14149 if (!(inst.operands[j].isreg
14150 && inst.operands[j].isvec
14151 && !inst.operands[j].isquad
14152 && !inst.operands[j].issingle))
14153 matches = 0;
14154 break;
14155
14156 case SE_R:
14157 if (!(inst.operands[j].isreg
14158 && !inst.operands[j].isvec))
14159 matches = 0;
14160 break;
14161
14162 case SE_Q:
14163 if (!(inst.operands[j].isreg
14164 && inst.operands[j].isvec
14165 && inst.operands[j].isquad
14166 && !inst.operands[j].issingle))
14167 matches = 0;
14168 break;
14169
14170 case SE_I:
14171 if (!(!inst.operands[j].isreg
14172 && !inst.operands[j].isscalar))
14173 matches = 0;
14174 break;
14175
14176 case SE_S:
14177 if (!(!inst.operands[j].isreg
14178 && inst.operands[j].isscalar))
14179 matches = 0;
14180 break;
14181
14182 case SE_L:
14183 break;
14184 }
3fde54a2
JZ
14185 if (!matches)
14186 break;
477330fc 14187 }
ad6cec43
MGD
14188 if (matches && (j >= ARM_IT_MAX_OPERANDS || !inst.operands[j].present))
14189 /* We've matched all the entries in the shape table, and we don't
14190 have any left over operands which have not been matched. */
477330fc 14191 break;
037e8744 14192 }
5f4273c7 14193
037e8744 14194 va_end (ap);
5287ad62 14195
037e8744
JB
14196 if (shape == NS_NULL && first_shape != NS_NULL)
14197 first_error (_("invalid instruction shape"));
5287ad62 14198
037e8744
JB
14199 return shape;
14200}
5287ad62 14201
037e8744
JB
14202/* True if SHAPE is predominantly a quadword operation (most of the time, this
14203 means the Q bit should be set). */
14204
14205static int
14206neon_quad (enum neon_shape shape)
14207{
14208 return neon_shape_class[shape] == SC_QUAD;
5287ad62 14209}
037e8744 14210
5287ad62
JB
14211static void
14212neon_modify_type_size (unsigned typebits, enum neon_el_type *g_type,
477330fc 14213 unsigned *g_size)
5287ad62
JB
14214{
14215 /* Allow modification to be made to types which are constrained to be
14216 based on the key element, based on bits set alongside N_EQK. */
14217 if ((typebits & N_EQK) != 0)
14218 {
14219 if ((typebits & N_HLF) != 0)
14220 *g_size /= 2;
14221 else if ((typebits & N_DBL) != 0)
14222 *g_size *= 2;
14223 if ((typebits & N_SGN) != 0)
14224 *g_type = NT_signed;
14225 else if ((typebits & N_UNS) != 0)
477330fc 14226 *g_type = NT_unsigned;
5287ad62 14227 else if ((typebits & N_INT) != 0)
477330fc 14228 *g_type = NT_integer;
5287ad62 14229 else if ((typebits & N_FLT) != 0)
477330fc 14230 *g_type = NT_float;
dcbf9037 14231 else if ((typebits & N_SIZ) != 0)
477330fc 14232 *g_type = NT_untyped;
5287ad62
JB
14233 }
14234}
5f4273c7 14235
5287ad62
JB
14236/* Return operand OPNO promoted by bits set in THISARG. KEY should be the "key"
14237 operand type, i.e. the single type specified in a Neon instruction when it
14238 is the only one given. */
14239
14240static struct neon_type_el
14241neon_type_promote (struct neon_type_el *key, unsigned thisarg)
14242{
14243 struct neon_type_el dest = *key;
5f4273c7 14244
9c2799c2 14245 gas_assert ((thisarg & N_EQK) != 0);
5f4273c7 14246
5287ad62
JB
14247 neon_modify_type_size (thisarg, &dest.type, &dest.size);
14248
14249 return dest;
14250}
14251
14252/* Convert Neon type and size into compact bitmask representation. */
14253
14254static enum neon_type_mask
14255type_chk_of_el_type (enum neon_el_type type, unsigned size)
14256{
14257 switch (type)
14258 {
14259 case NT_untyped:
14260 switch (size)
477330fc
RM
14261 {
14262 case 8: return N_8;
14263 case 16: return N_16;
14264 case 32: return N_32;
14265 case 64: return N_64;
14266 default: ;
14267 }
5287ad62
JB
14268 break;
14269
14270 case NT_integer:
14271 switch (size)
477330fc
RM
14272 {
14273 case 8: return N_I8;
14274 case 16: return N_I16;
14275 case 32: return N_I32;
14276 case 64: return N_I64;
14277 default: ;
14278 }
5287ad62
JB
14279 break;
14280
14281 case NT_float:
037e8744 14282 switch (size)
477330fc 14283 {
8e79c3df 14284 case 16: return N_F16;
477330fc
RM
14285 case 32: return N_F32;
14286 case 64: return N_F64;
14287 default: ;
14288 }
5287ad62
JB
14289 break;
14290
14291 case NT_poly:
14292 switch (size)
477330fc
RM
14293 {
14294 case 8: return N_P8;
14295 case 16: return N_P16;
4f51b4bd 14296 case 64: return N_P64;
477330fc
RM
14297 default: ;
14298 }
5287ad62
JB
14299 break;
14300
14301 case NT_signed:
14302 switch (size)
477330fc
RM
14303 {
14304 case 8: return N_S8;
14305 case 16: return N_S16;
14306 case 32: return N_S32;
14307 case 64: return N_S64;
14308 default: ;
14309 }
5287ad62
JB
14310 break;
14311
14312 case NT_unsigned:
14313 switch (size)
477330fc
RM
14314 {
14315 case 8: return N_U8;
14316 case 16: return N_U16;
14317 case 32: return N_U32;
14318 case 64: return N_U64;
14319 default: ;
14320 }
5287ad62
JB
14321 break;
14322
14323 default: ;
14324 }
5f4273c7 14325
5287ad62
JB
14326 return N_UTYP;
14327}
14328
14329/* Convert compact Neon bitmask type representation to a type and size. Only
14330 handles the case where a single bit is set in the mask. */
14331
dcbf9037 14332static int
5287ad62 14333el_type_of_type_chk (enum neon_el_type *type, unsigned *size,
477330fc 14334 enum neon_type_mask mask)
5287ad62 14335{
dcbf9037
JB
14336 if ((mask & N_EQK) != 0)
14337 return FAIL;
14338
5287ad62
JB
14339 if ((mask & (N_S8 | N_U8 | N_I8 | N_8 | N_P8)) != 0)
14340 *size = 8;
c70a8987 14341 else if ((mask & (N_S16 | N_U16 | N_I16 | N_16 | N_F16 | N_P16)) != 0)
5287ad62 14342 *size = 16;
dcbf9037 14343 else if ((mask & (N_S32 | N_U32 | N_I32 | N_32 | N_F32)) != 0)
5287ad62 14344 *size = 32;
4f51b4bd 14345 else if ((mask & (N_S64 | N_U64 | N_I64 | N_64 | N_F64 | N_P64)) != 0)
5287ad62 14346 *size = 64;
dcbf9037
JB
14347 else
14348 return FAIL;
14349
5287ad62
JB
14350 if ((mask & (N_S8 | N_S16 | N_S32 | N_S64)) != 0)
14351 *type = NT_signed;
dcbf9037 14352 else if ((mask & (N_U8 | N_U16 | N_U32 | N_U64)) != 0)
5287ad62 14353 *type = NT_unsigned;
dcbf9037 14354 else if ((mask & (N_I8 | N_I16 | N_I32 | N_I64)) != 0)
5287ad62 14355 *type = NT_integer;
dcbf9037 14356 else if ((mask & (N_8 | N_16 | N_32 | N_64)) != 0)
5287ad62 14357 *type = NT_untyped;
4f51b4bd 14358 else if ((mask & (N_P8 | N_P16 | N_P64)) != 0)
5287ad62 14359 *type = NT_poly;
d54af2d0 14360 else if ((mask & (N_F_ALL)) != 0)
5287ad62 14361 *type = NT_float;
dcbf9037
JB
14362 else
14363 return FAIL;
5f4273c7 14364
dcbf9037 14365 return SUCCESS;
5287ad62
JB
14366}
14367
14368/* Modify a bitmask of allowed types. This is only needed for type
14369 relaxation. */
14370
14371static unsigned
14372modify_types_allowed (unsigned allowed, unsigned mods)
14373{
14374 unsigned size;
14375 enum neon_el_type type;
14376 unsigned destmask;
14377 int i;
5f4273c7 14378
5287ad62 14379 destmask = 0;
5f4273c7 14380
5287ad62
JB
14381 for (i = 1; i <= N_MAX_NONSPECIAL; i <<= 1)
14382 {
21d799b5 14383 if (el_type_of_type_chk (&type, &size,
477330fc
RM
14384 (enum neon_type_mask) (allowed & i)) == SUCCESS)
14385 {
14386 neon_modify_type_size (mods, &type, &size);
14387 destmask |= type_chk_of_el_type (type, size);
14388 }
5287ad62 14389 }
5f4273c7 14390
5287ad62
JB
14391 return destmask;
14392}
14393
14394/* Check type and return type classification.
14395 The manual states (paraphrase): If one datatype is given, it indicates the
14396 type given in:
14397 - the second operand, if there is one
14398 - the operand, if there is no second operand
14399 - the result, if there are no operands.
14400 This isn't quite good enough though, so we use a concept of a "key" datatype
14401 which is set on a per-instruction basis, which is the one which matters when
14402 only one data type is written.
14403 Note: this function has side-effects (e.g. filling in missing operands). All
037e8744 14404 Neon instructions should call it before performing bit encoding. */
5287ad62
JB
14405
14406static struct neon_type_el
14407neon_check_type (unsigned els, enum neon_shape ns, ...)
14408{
14409 va_list ap;
14410 unsigned i, pass, key_el = 0;
14411 unsigned types[NEON_MAX_TYPE_ELS];
14412 enum neon_el_type k_type = NT_invtype;
14413 unsigned k_size = -1u;
14414 struct neon_type_el badtype = {NT_invtype, -1};
14415 unsigned key_allowed = 0;
14416
14417 /* Optional registers in Neon instructions are always (not) in operand 1.
14418 Fill in the missing operand here, if it was omitted. */
14419 if (els > 1 && !inst.operands[1].present)
14420 inst.operands[1] = inst.operands[0];
14421
14422 /* Suck up all the varargs. */
14423 va_start (ap, ns);
14424 for (i = 0; i < els; i++)
14425 {
14426 unsigned thisarg = va_arg (ap, unsigned);
14427 if (thisarg == N_IGNORE_TYPE)
477330fc
RM
14428 {
14429 va_end (ap);
14430 return badtype;
14431 }
5287ad62
JB
14432 types[i] = thisarg;
14433 if ((thisarg & N_KEY) != 0)
477330fc 14434 key_el = i;
5287ad62
JB
14435 }
14436 va_end (ap);
14437
dcbf9037
JB
14438 if (inst.vectype.elems > 0)
14439 for (i = 0; i < els; i++)
14440 if (inst.operands[i].vectype.type != NT_invtype)
477330fc
RM
14441 {
14442 first_error (_("types specified in both the mnemonic and operands"));
14443 return badtype;
14444 }
dcbf9037 14445
5287ad62
JB
14446 /* Duplicate inst.vectype elements here as necessary.
14447 FIXME: No idea if this is exactly the same as the ARM assembler,
14448 particularly when an insn takes one register and one non-register
14449 operand. */
14450 if (inst.vectype.elems == 1 && els > 1)
14451 {
14452 unsigned j;
14453 inst.vectype.elems = els;
14454 inst.vectype.el[key_el] = inst.vectype.el[0];
14455 for (j = 0; j < els; j++)
477330fc
RM
14456 if (j != key_el)
14457 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14458 types[j]);
dcbf9037
JB
14459 }
14460 else if (inst.vectype.elems == 0 && els > 0)
14461 {
14462 unsigned j;
14463 /* No types were given after the mnemonic, so look for types specified
477330fc
RM
14464 after each operand. We allow some flexibility here; as long as the
14465 "key" operand has a type, we can infer the others. */
dcbf9037 14466 for (j = 0; j < els; j++)
477330fc
RM
14467 if (inst.operands[j].vectype.type != NT_invtype)
14468 inst.vectype.el[j] = inst.operands[j].vectype;
dcbf9037
JB
14469
14470 if (inst.operands[key_el].vectype.type != NT_invtype)
477330fc
RM
14471 {
14472 for (j = 0; j < els; j++)
14473 if (inst.operands[j].vectype.type == NT_invtype)
14474 inst.vectype.el[j] = neon_type_promote (&inst.vectype.el[key_el],
14475 types[j]);
14476 }
dcbf9037 14477 else
477330fc
RM
14478 {
14479 first_error (_("operand types can't be inferred"));
14480 return badtype;
14481 }
5287ad62
JB
14482 }
14483 else if (inst.vectype.elems != els)
14484 {
dcbf9037 14485 first_error (_("type specifier has the wrong number of parts"));
5287ad62
JB
14486 return badtype;
14487 }
14488
14489 for (pass = 0; pass < 2; pass++)
14490 {
14491 for (i = 0; i < els; i++)
477330fc
RM
14492 {
14493 unsigned thisarg = types[i];
14494 unsigned types_allowed = ((thisarg & N_EQK) != 0 && pass != 0)
14495 ? modify_types_allowed (key_allowed, thisarg) : thisarg;
14496 enum neon_el_type g_type = inst.vectype.el[i].type;
14497 unsigned g_size = inst.vectype.el[i].size;
14498
14499 /* Decay more-specific signed & unsigned types to sign-insensitive
5287ad62 14500 integer types if sign-specific variants are unavailable. */
477330fc 14501 if ((g_type == NT_signed || g_type == NT_unsigned)
5287ad62
JB
14502 && (types_allowed & N_SU_ALL) == 0)
14503 g_type = NT_integer;
14504
477330fc 14505 /* If only untyped args are allowed, decay any more specific types to
5287ad62
JB
14506 them. Some instructions only care about signs for some element
14507 sizes, so handle that properly. */
477330fc 14508 if (((types_allowed & N_UNT) == 0)
91ff7894
MGD
14509 && ((g_size == 8 && (types_allowed & N_8) != 0)
14510 || (g_size == 16 && (types_allowed & N_16) != 0)
14511 || (g_size == 32 && (types_allowed & N_32) != 0)
14512 || (g_size == 64 && (types_allowed & N_64) != 0)))
5287ad62
JB
14513 g_type = NT_untyped;
14514
477330fc
RM
14515 if (pass == 0)
14516 {
14517 if ((thisarg & N_KEY) != 0)
14518 {
14519 k_type = g_type;
14520 k_size = g_size;
14521 key_allowed = thisarg & ~N_KEY;
cc933301
JW
14522
14523 /* Check architecture constraint on FP16 extension. */
14524 if (k_size == 16
14525 && k_type == NT_float
14526 && ! ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
14527 {
14528 inst.error = _(BAD_FP16);
14529 return badtype;
14530 }
477330fc
RM
14531 }
14532 }
14533 else
14534 {
14535 if ((thisarg & N_VFP) != 0)
14536 {
14537 enum neon_shape_el regshape;
14538 unsigned regwidth, match;
99b253c5
NC
14539
14540 /* PR 11136: Catch the case where we are passed a shape of NS_NULL. */
14541 if (ns == NS_NULL)
14542 {
14543 first_error (_("invalid instruction shape"));
14544 return badtype;
14545 }
477330fc
RM
14546 regshape = neon_shape_tab[ns].el[i];
14547 regwidth = neon_shape_el_size[regshape];
14548
14549 /* In VFP mode, operands must match register widths. If we
14550 have a key operand, use its width, else use the width of
14551 the current operand. */
14552 if (k_size != -1u)
14553 match = k_size;
14554 else
14555 match = g_size;
14556
9db2f6b4
RL
14557 /* FP16 will use a single precision register. */
14558 if (regwidth == 32 && match == 16)
14559 {
14560 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16))
14561 match = regwidth;
14562 else
14563 {
14564 inst.error = _(BAD_FP16);
14565 return badtype;
14566 }
14567 }
14568
477330fc
RM
14569 if (regwidth != match)
14570 {
14571 first_error (_("operand size must match register width"));
14572 return badtype;
14573 }
14574 }
14575
14576 if ((thisarg & N_EQK) == 0)
14577 {
14578 unsigned given_type = type_chk_of_el_type (g_type, g_size);
14579
14580 if ((given_type & types_allowed) == 0)
14581 {
14582 first_error (_("bad type in Neon instruction"));
14583 return badtype;
14584 }
14585 }
14586 else
14587 {
14588 enum neon_el_type mod_k_type = k_type;
14589 unsigned mod_k_size = k_size;
14590 neon_modify_type_size (thisarg, &mod_k_type, &mod_k_size);
14591 if (g_type != mod_k_type || g_size != mod_k_size)
14592 {
14593 first_error (_("inconsistent types in Neon instruction"));
14594 return badtype;
14595 }
14596 }
14597 }
14598 }
5287ad62
JB
14599 }
14600
14601 return inst.vectype.el[key_el];
14602}
14603
037e8744 14604/* Neon-style VFP instruction forwarding. */
5287ad62 14605
037e8744
JB
14606/* Thumb VFP instructions have 0xE in the condition field. */
14607
14608static void
14609do_vfp_cond_or_thumb (void)
5287ad62 14610{
88714cb8
DG
14611 inst.is_neon = 1;
14612
5287ad62 14613 if (thumb_mode)
037e8744 14614 inst.instruction |= 0xe0000000;
5287ad62 14615 else
037e8744 14616 inst.instruction |= inst.cond << 28;
5287ad62
JB
14617}
14618
037e8744
JB
14619/* Look up and encode a simple mnemonic, for use as a helper function for the
14620 Neon-style VFP syntax. This avoids duplication of bits of the insns table,
14621 etc. It is assumed that operand parsing has already been done, and that the
14622 operands are in the form expected by the given opcode (this isn't necessarily
14623 the same as the form in which they were parsed, hence some massaging must
14624 take place before this function is called).
14625 Checks current arch version against that in the looked-up opcode. */
5287ad62 14626
037e8744
JB
14627static void
14628do_vfp_nsyn_opcode (const char *opname)
5287ad62 14629{
037e8744 14630 const struct asm_opcode *opcode;
5f4273c7 14631
21d799b5 14632 opcode = (const struct asm_opcode *) hash_find (arm_ops_hsh, opname);
5287ad62 14633
037e8744
JB
14634 if (!opcode)
14635 abort ();
5287ad62 14636
037e8744 14637 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant,
477330fc
RM
14638 thumb_mode ? *opcode->tvariant : *opcode->avariant),
14639 _(BAD_FPU));
5287ad62 14640
88714cb8
DG
14641 inst.is_neon = 1;
14642
037e8744
JB
14643 if (thumb_mode)
14644 {
14645 inst.instruction = opcode->tvalue;
14646 opcode->tencode ();
14647 }
14648 else
14649 {
14650 inst.instruction = (inst.cond << 28) | opcode->avalue;
14651 opcode->aencode ();
14652 }
14653}
5287ad62
JB
14654
14655static void
037e8744 14656do_vfp_nsyn_add_sub (enum neon_shape rs)
5287ad62 14657{
037e8744
JB
14658 int is_add = (inst.instruction & 0x0fffffff) == N_MNEM_vadd;
14659
9db2f6b4 14660 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
14661 {
14662 if (is_add)
477330fc 14663 do_vfp_nsyn_opcode ("fadds");
037e8744 14664 else
477330fc 14665 do_vfp_nsyn_opcode ("fsubs");
9db2f6b4
RL
14666
14667 /* ARMv8.2 fp16 instruction. */
14668 if (rs == NS_HHH)
14669 do_scalar_fp16_v82_encode ();
037e8744
JB
14670 }
14671 else
14672 {
14673 if (is_add)
477330fc 14674 do_vfp_nsyn_opcode ("faddd");
037e8744 14675 else
477330fc 14676 do_vfp_nsyn_opcode ("fsubd");
037e8744
JB
14677 }
14678}
14679
14680/* Check operand types to see if this is a VFP instruction, and if so call
14681 PFN (). */
14682
14683static int
14684try_vfp_nsyn (int args, void (*pfn) (enum neon_shape))
14685{
14686 enum neon_shape rs;
14687 struct neon_type_el et;
14688
14689 switch (args)
14690 {
14691 case 2:
9db2f6b4
RL
14692 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
14693 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
037e8744 14694 break;
5f4273c7 14695
037e8744 14696 case 3:
9db2f6b4
RL
14697 rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
14698 et = neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
14699 N_F_ALL | N_KEY | N_VFP);
037e8744
JB
14700 break;
14701
14702 default:
14703 abort ();
14704 }
14705
14706 if (et.type != NT_invtype)
14707 {
14708 pfn (rs);
14709 return SUCCESS;
14710 }
037e8744 14711
99b253c5 14712 inst.error = NULL;
037e8744
JB
14713 return FAIL;
14714}
14715
14716static void
14717do_vfp_nsyn_mla_mls (enum neon_shape rs)
14718{
14719 int is_mla = (inst.instruction & 0x0fffffff) == N_MNEM_vmla;
5f4273c7 14720
9db2f6b4 14721 if (rs == NS_FFF || rs == NS_HHH)
037e8744
JB
14722 {
14723 if (is_mla)
477330fc 14724 do_vfp_nsyn_opcode ("fmacs");
037e8744 14725 else
477330fc 14726 do_vfp_nsyn_opcode ("fnmacs");
9db2f6b4
RL
14727
14728 /* ARMv8.2 fp16 instruction. */
14729 if (rs == NS_HHH)
14730 do_scalar_fp16_v82_encode ();
037e8744
JB
14731 }
14732 else
14733 {
14734 if (is_mla)
477330fc 14735 do_vfp_nsyn_opcode ("fmacd");
037e8744 14736 else
477330fc 14737 do_vfp_nsyn_opcode ("fnmacd");
037e8744
JB
14738 }
14739}
14740
62f3b8c8
PB
14741static void
14742do_vfp_nsyn_fma_fms (enum neon_shape rs)
14743{
14744 int is_fma = (inst.instruction & 0x0fffffff) == N_MNEM_vfma;
14745
9db2f6b4 14746 if (rs == NS_FFF || rs == NS_HHH)
62f3b8c8
PB
14747 {
14748 if (is_fma)
477330fc 14749 do_vfp_nsyn_opcode ("ffmas");
62f3b8c8 14750 else
477330fc 14751 do_vfp_nsyn_opcode ("ffnmas");
9db2f6b4
RL
14752
14753 /* ARMv8.2 fp16 instruction. */
14754 if (rs == NS_HHH)
14755 do_scalar_fp16_v82_encode ();
62f3b8c8
PB
14756 }
14757 else
14758 {
14759 if (is_fma)
477330fc 14760 do_vfp_nsyn_opcode ("ffmad");
62f3b8c8 14761 else
477330fc 14762 do_vfp_nsyn_opcode ("ffnmad");
62f3b8c8
PB
14763 }
14764}
14765
037e8744
JB
14766static void
14767do_vfp_nsyn_mul (enum neon_shape rs)
14768{
9db2f6b4
RL
14769 if (rs == NS_FFF || rs == NS_HHH)
14770 {
14771 do_vfp_nsyn_opcode ("fmuls");
14772
14773 /* ARMv8.2 fp16 instruction. */
14774 if (rs == NS_HHH)
14775 do_scalar_fp16_v82_encode ();
14776 }
037e8744
JB
14777 else
14778 do_vfp_nsyn_opcode ("fmuld");
14779}
14780
14781static void
14782do_vfp_nsyn_abs_neg (enum neon_shape rs)
14783{
14784 int is_neg = (inst.instruction & 0x80) != 0;
9db2f6b4 14785 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_VFP | N_KEY);
037e8744 14786
9db2f6b4 14787 if (rs == NS_FF || rs == NS_HH)
037e8744
JB
14788 {
14789 if (is_neg)
477330fc 14790 do_vfp_nsyn_opcode ("fnegs");
037e8744 14791 else
477330fc 14792 do_vfp_nsyn_opcode ("fabss");
9db2f6b4
RL
14793
14794 /* ARMv8.2 fp16 instruction. */
14795 if (rs == NS_HH)
14796 do_scalar_fp16_v82_encode ();
037e8744
JB
14797 }
14798 else
14799 {
14800 if (is_neg)
477330fc 14801 do_vfp_nsyn_opcode ("fnegd");
037e8744 14802 else
477330fc 14803 do_vfp_nsyn_opcode ("fabsd");
037e8744
JB
14804 }
14805}
14806
14807/* Encode single-precision (only!) VFP fldm/fstm instructions. Double precision
14808 insns belong to Neon, and are handled elsewhere. */
14809
14810static void
14811do_vfp_nsyn_ldm_stm (int is_dbmode)
14812{
14813 int is_ldm = (inst.instruction & (1 << 20)) != 0;
14814 if (is_ldm)
14815 {
14816 if (is_dbmode)
477330fc 14817 do_vfp_nsyn_opcode ("fldmdbs");
037e8744 14818 else
477330fc 14819 do_vfp_nsyn_opcode ("fldmias");
037e8744
JB
14820 }
14821 else
14822 {
14823 if (is_dbmode)
477330fc 14824 do_vfp_nsyn_opcode ("fstmdbs");
037e8744 14825 else
477330fc 14826 do_vfp_nsyn_opcode ("fstmias");
037e8744
JB
14827 }
14828}
14829
037e8744
JB
14830static void
14831do_vfp_nsyn_sqrt (void)
14832{
9db2f6b4
RL
14833 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
14834 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 14835
9db2f6b4
RL
14836 if (rs == NS_FF || rs == NS_HH)
14837 {
14838 do_vfp_nsyn_opcode ("fsqrts");
14839
14840 /* ARMv8.2 fp16 instruction. */
14841 if (rs == NS_HH)
14842 do_scalar_fp16_v82_encode ();
14843 }
037e8744
JB
14844 else
14845 do_vfp_nsyn_opcode ("fsqrtd");
14846}
14847
14848static void
14849do_vfp_nsyn_div (void)
14850{
9db2f6b4 14851 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 14852 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 14853 N_F_ALL | N_KEY | N_VFP);
5f4273c7 14854
9db2f6b4
RL
14855 if (rs == NS_FFF || rs == NS_HHH)
14856 {
14857 do_vfp_nsyn_opcode ("fdivs");
14858
14859 /* ARMv8.2 fp16 instruction. */
14860 if (rs == NS_HHH)
14861 do_scalar_fp16_v82_encode ();
14862 }
037e8744
JB
14863 else
14864 do_vfp_nsyn_opcode ("fdivd");
14865}
14866
14867static void
14868do_vfp_nsyn_nmul (void)
14869{
9db2f6b4 14870 enum neon_shape rs = neon_select_shape (NS_HHH, NS_FFF, NS_DDD, NS_NULL);
037e8744 14871 neon_check_type (3, rs, N_EQK | N_VFP, N_EQK | N_VFP,
9db2f6b4 14872 N_F_ALL | N_KEY | N_VFP);
5f4273c7 14873
9db2f6b4 14874 if (rs == NS_FFF || rs == NS_HHH)
037e8744 14875 {
88714cb8 14876 NEON_ENCODE (SINGLE, inst);
037e8744 14877 do_vfp_sp_dyadic ();
9db2f6b4
RL
14878
14879 /* ARMv8.2 fp16 instruction. */
14880 if (rs == NS_HHH)
14881 do_scalar_fp16_v82_encode ();
037e8744
JB
14882 }
14883 else
14884 {
88714cb8 14885 NEON_ENCODE (DOUBLE, inst);
037e8744
JB
14886 do_vfp_dp_rd_rn_rm ();
14887 }
14888 do_vfp_cond_or_thumb ();
9db2f6b4 14889
037e8744
JB
14890}
14891
14892static void
14893do_vfp_nsyn_cmp (void)
14894{
9db2f6b4 14895 enum neon_shape rs;
037e8744
JB
14896 if (inst.operands[1].isreg)
14897 {
9db2f6b4
RL
14898 rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_NULL);
14899 neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY | N_VFP);
5f4273c7 14900
9db2f6b4 14901 if (rs == NS_FF || rs == NS_HH)
477330fc
RM
14902 {
14903 NEON_ENCODE (SINGLE, inst);
14904 do_vfp_sp_monadic ();
14905 }
037e8744 14906 else
477330fc
RM
14907 {
14908 NEON_ENCODE (DOUBLE, inst);
14909 do_vfp_dp_rd_rm ();
14910 }
037e8744
JB
14911 }
14912 else
14913 {
9db2f6b4
RL
14914 rs = neon_select_shape (NS_HI, NS_FI, NS_DI, NS_NULL);
14915 neon_check_type (2, rs, N_F_ALL | N_KEY | N_VFP, N_EQK);
037e8744
JB
14916
14917 switch (inst.instruction & 0x0fffffff)
477330fc
RM
14918 {
14919 case N_MNEM_vcmp:
14920 inst.instruction += N_MNEM_vcmpz - N_MNEM_vcmp;
14921 break;
14922 case N_MNEM_vcmpe:
14923 inst.instruction += N_MNEM_vcmpez - N_MNEM_vcmpe;
14924 break;
14925 default:
14926 abort ();
14927 }
5f4273c7 14928
9db2f6b4 14929 if (rs == NS_FI || rs == NS_HI)
477330fc
RM
14930 {
14931 NEON_ENCODE (SINGLE, inst);
14932 do_vfp_sp_compare_z ();
14933 }
037e8744 14934 else
477330fc
RM
14935 {
14936 NEON_ENCODE (DOUBLE, inst);
14937 do_vfp_dp_rd ();
14938 }
037e8744
JB
14939 }
14940 do_vfp_cond_or_thumb ();
9db2f6b4
RL
14941
14942 /* ARMv8.2 fp16 instruction. */
14943 if (rs == NS_HI || rs == NS_HH)
14944 do_scalar_fp16_v82_encode ();
037e8744
JB
14945}
14946
14947static void
14948nsyn_insert_sp (void)
14949{
14950 inst.operands[1] = inst.operands[0];
14951 memset (&inst.operands[0], '\0', sizeof (inst.operands[0]));
fdfde340 14952 inst.operands[0].reg = REG_SP;
037e8744
JB
14953 inst.operands[0].isreg = 1;
14954 inst.operands[0].writeback = 1;
14955 inst.operands[0].present = 1;
14956}
14957
14958static void
14959do_vfp_nsyn_push (void)
14960{
14961 nsyn_insert_sp ();
b126985e
NC
14962
14963 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
14964 _("register list must contain at least 1 and at most 16 "
14965 "registers"));
14966
037e8744
JB
14967 if (inst.operands[1].issingle)
14968 do_vfp_nsyn_opcode ("fstmdbs");
14969 else
14970 do_vfp_nsyn_opcode ("fstmdbd");
14971}
14972
14973static void
14974do_vfp_nsyn_pop (void)
14975{
14976 nsyn_insert_sp ();
b126985e
NC
14977
14978 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
14979 _("register list must contain at least 1 and at most 16 "
14980 "registers"));
14981
037e8744 14982 if (inst.operands[1].issingle)
22b5b651 14983 do_vfp_nsyn_opcode ("fldmias");
037e8744 14984 else
22b5b651 14985 do_vfp_nsyn_opcode ("fldmiad");
037e8744
JB
14986}
14987
14988/* Fix up Neon data-processing instructions, ORing in the correct bits for
14989 ARM mode or Thumb mode and moving the encoded bit 24 to bit 28. */
14990
88714cb8
DG
14991static void
14992neon_dp_fixup (struct arm_it* insn)
037e8744 14993{
88714cb8
DG
14994 unsigned int i = insn->instruction;
14995 insn->is_neon = 1;
14996
037e8744
JB
14997 if (thumb_mode)
14998 {
14999 /* The U bit is at bit 24 by default. Move to bit 28 in Thumb mode. */
15000 if (i & (1 << 24))
477330fc 15001 i |= 1 << 28;
5f4273c7 15002
037e8744 15003 i &= ~(1 << 24);
5f4273c7 15004
037e8744
JB
15005 i |= 0xef000000;
15006 }
15007 else
15008 i |= 0xf2000000;
5f4273c7 15009
88714cb8 15010 insn->instruction = i;
037e8744
JB
15011}
15012
15013/* Turn a size (8, 16, 32, 64) into the respective bit number minus 3
15014 (0, 1, 2, 3). */
15015
15016static unsigned
15017neon_logbits (unsigned x)
15018{
15019 return ffs (x) - 4;
15020}
15021
15022#define LOW4(R) ((R) & 0xf)
15023#define HI1(R) (((R) >> 4) & 1)
15024
15025/* Encode insns with bit pattern:
15026
15027 |28/24|23|22 |21 20|19 16|15 12|11 8|7|6|5|4|3 0|
15028 | U |x |D |size | Rn | Rd |x x x x|N|Q|M|x| Rm |
5f4273c7 15029
037e8744
JB
15030 SIZE is passed in bits. -1 means size field isn't changed, in case it has a
15031 different meaning for some instruction. */
15032
15033static void
15034neon_three_same (int isquad, int ubit, int size)
15035{
15036 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15037 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15038 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15039 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15040 inst.instruction |= LOW4 (inst.operands[2].reg);
15041 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
15042 inst.instruction |= (isquad != 0) << 6;
15043 inst.instruction |= (ubit != 0) << 24;
15044 if (size != -1)
15045 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 15046
88714cb8 15047 neon_dp_fixup (&inst);
037e8744
JB
15048}
15049
15050/* Encode instructions of the form:
15051
15052 |28/24|23|22|21 20|19 18|17 16|15 12|11 7|6|5|4|3 0|
15053 | U |x |D |x x |size |x x | Rd |x x x x x|Q|M|x| Rm |
5287ad62
JB
15054
15055 Don't write size if SIZE == -1. */
15056
15057static void
15058neon_two_same (int qbit, int ubit, int size)
15059{
15060 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15061 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15062 inst.instruction |= LOW4 (inst.operands[1].reg);
15063 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15064 inst.instruction |= (qbit != 0) << 6;
15065 inst.instruction |= (ubit != 0) << 24;
15066
15067 if (size != -1)
15068 inst.instruction |= neon_logbits (size) << 18;
15069
88714cb8 15070 neon_dp_fixup (&inst);
5287ad62
JB
15071}
15072
15073/* Neon instruction encoders, in approximate order of appearance. */
15074
15075static void
15076do_neon_dyadic_i_su (void)
15077{
037e8744 15078 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
15079 struct neon_type_el et = neon_check_type (3, rs,
15080 N_EQK, N_EQK, N_SU_32 | N_KEY);
037e8744 15081 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
15082}
15083
15084static void
15085do_neon_dyadic_i64_su (void)
15086{
037e8744 15087 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
15088 struct neon_type_el et = neon_check_type (3, rs,
15089 N_EQK, N_EQK, N_SU_ALL | N_KEY);
037e8744 15090 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
15091}
15092
15093static void
15094neon_imm_shift (int write_ubit, int uval, int isquad, struct neon_type_el et,
477330fc 15095 unsigned immbits)
5287ad62
JB
15096{
15097 unsigned size = et.size >> 3;
15098 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15099 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15100 inst.instruction |= LOW4 (inst.operands[1].reg);
15101 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15102 inst.instruction |= (isquad != 0) << 6;
15103 inst.instruction |= immbits << 16;
15104 inst.instruction |= (size >> 3) << 7;
15105 inst.instruction |= (size & 0x7) << 19;
15106 if (write_ubit)
15107 inst.instruction |= (uval != 0) << 24;
15108
88714cb8 15109 neon_dp_fixup (&inst);
5287ad62
JB
15110}
15111
15112static void
15113do_neon_shl_imm (void)
15114{
15115 if (!inst.operands[2].isreg)
15116 {
037e8744 15117 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62 15118 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_KEY | N_I_ALL);
cb3b1e65
JB
15119 int imm = inst.operands[2].imm;
15120
15121 constraint (imm < 0 || (unsigned)imm >= et.size,
15122 _("immediate out of range for shift"));
88714cb8 15123 NEON_ENCODE (IMMED, inst);
cb3b1e65 15124 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
15125 }
15126 else
15127 {
037e8744 15128 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 15129 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15130 N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
627907b7
JB
15131 unsigned int tmp;
15132
15133 /* VSHL/VQSHL 3-register variants have syntax such as:
477330fc
RM
15134 vshl.xx Dd, Dm, Dn
15135 whereas other 3-register operations encoded by neon_three_same have
15136 syntax like:
15137 vadd.xx Dd, Dn, Dm
15138 (i.e. with Dn & Dm reversed). Swap operands[1].reg and operands[2].reg
15139 here. */
627907b7
JB
15140 tmp = inst.operands[2].reg;
15141 inst.operands[2].reg = inst.operands[1].reg;
15142 inst.operands[1].reg = tmp;
88714cb8 15143 NEON_ENCODE (INTEGER, inst);
037e8744 15144 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
15145 }
15146}
15147
15148static void
15149do_neon_qshl_imm (void)
15150{
15151 if (!inst.operands[2].isreg)
15152 {
037e8744 15153 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62 15154 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
cb3b1e65 15155 int imm = inst.operands[2].imm;
627907b7 15156
cb3b1e65
JB
15157 constraint (imm < 0 || (unsigned)imm >= et.size,
15158 _("immediate out of range for shift"));
88714cb8 15159 NEON_ENCODE (IMMED, inst);
cb3b1e65 15160 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et, imm);
5287ad62
JB
15161 }
15162 else
15163 {
037e8744 15164 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 15165 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15166 N_EQK, N_SU_ALL | N_KEY, N_EQK | N_SGN);
627907b7
JB
15167 unsigned int tmp;
15168
15169 /* See note in do_neon_shl_imm. */
15170 tmp = inst.operands[2].reg;
15171 inst.operands[2].reg = inst.operands[1].reg;
15172 inst.operands[1].reg = tmp;
88714cb8 15173 NEON_ENCODE (INTEGER, inst);
037e8744 15174 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
5287ad62
JB
15175 }
15176}
15177
627907b7
JB
15178static void
15179do_neon_rshl (void)
15180{
15181 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
15182 struct neon_type_el et = neon_check_type (3, rs,
15183 N_EQK, N_EQK, N_SU_ALL | N_KEY);
15184 unsigned int tmp;
15185
15186 tmp = inst.operands[2].reg;
15187 inst.operands[2].reg = inst.operands[1].reg;
15188 inst.operands[1].reg = tmp;
15189 neon_three_same (neon_quad (rs), et.type == NT_unsigned, et.size);
15190}
15191
5287ad62
JB
15192static int
15193neon_cmode_for_logic_imm (unsigned immediate, unsigned *immbits, int size)
15194{
036dc3f7
PB
15195 /* Handle .I8 pseudo-instructions. */
15196 if (size == 8)
5287ad62 15197 {
5287ad62 15198 /* Unfortunately, this will make everything apart from zero out-of-range.
477330fc
RM
15199 FIXME is this the intended semantics? There doesn't seem much point in
15200 accepting .I8 if so. */
5287ad62
JB
15201 immediate |= immediate << 8;
15202 size = 16;
036dc3f7
PB
15203 }
15204
15205 if (size >= 32)
15206 {
15207 if (immediate == (immediate & 0x000000ff))
15208 {
15209 *immbits = immediate;
15210 return 0x1;
15211 }
15212 else if (immediate == (immediate & 0x0000ff00))
15213 {
15214 *immbits = immediate >> 8;
15215 return 0x3;
15216 }
15217 else if (immediate == (immediate & 0x00ff0000))
15218 {
15219 *immbits = immediate >> 16;
15220 return 0x5;
15221 }
15222 else if (immediate == (immediate & 0xff000000))
15223 {
15224 *immbits = immediate >> 24;
15225 return 0x7;
15226 }
15227 if ((immediate & 0xffff) != (immediate >> 16))
15228 goto bad_immediate;
15229 immediate &= 0xffff;
5287ad62
JB
15230 }
15231
15232 if (immediate == (immediate & 0x000000ff))
15233 {
15234 *immbits = immediate;
036dc3f7 15235 return 0x9;
5287ad62
JB
15236 }
15237 else if (immediate == (immediate & 0x0000ff00))
15238 {
15239 *immbits = immediate >> 8;
036dc3f7 15240 return 0xb;
5287ad62
JB
15241 }
15242
15243 bad_immediate:
dcbf9037 15244 first_error (_("immediate value out of range"));
5287ad62
JB
15245 return FAIL;
15246}
15247
5287ad62
JB
15248static void
15249do_neon_logic (void)
15250{
15251 if (inst.operands[2].present && inst.operands[2].isreg)
15252 {
037e8744 15253 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
15254 neon_check_type (3, rs, N_IGNORE_TYPE);
15255 /* U bit and size field were set as part of the bitmask. */
88714cb8 15256 NEON_ENCODE (INTEGER, inst);
037e8744 15257 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
15258 }
15259 else
15260 {
4316f0d2
DG
15261 const int three_ops_form = (inst.operands[2].present
15262 && !inst.operands[2].isreg);
15263 const int immoperand = (three_ops_form ? 2 : 1);
15264 enum neon_shape rs = (three_ops_form
15265 ? neon_select_shape (NS_DDI, NS_QQI, NS_NULL)
15266 : neon_select_shape (NS_DI, NS_QI, NS_NULL));
037e8744 15267 struct neon_type_el et = neon_check_type (2, rs,
477330fc 15268 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
21d799b5 15269 enum neon_opc opcode = (enum neon_opc) inst.instruction & 0x0fffffff;
5287ad62
JB
15270 unsigned immbits;
15271 int cmode;
5f4273c7 15272
5287ad62 15273 if (et.type == NT_invtype)
477330fc 15274 return;
5f4273c7 15275
4316f0d2
DG
15276 if (three_ops_form)
15277 constraint (inst.operands[0].reg != inst.operands[1].reg,
15278 _("first and second operands shall be the same register"));
15279
88714cb8 15280 NEON_ENCODE (IMMED, inst);
5287ad62 15281
4316f0d2 15282 immbits = inst.operands[immoperand].imm;
036dc3f7
PB
15283 if (et.size == 64)
15284 {
15285 /* .i64 is a pseudo-op, so the immediate must be a repeating
15286 pattern. */
4316f0d2
DG
15287 if (immbits != (inst.operands[immoperand].regisimm ?
15288 inst.operands[immoperand].reg : 0))
036dc3f7
PB
15289 {
15290 /* Set immbits to an invalid constant. */
15291 immbits = 0xdeadbeef;
15292 }
15293 }
15294
5287ad62 15295 switch (opcode)
477330fc
RM
15296 {
15297 case N_MNEM_vbic:
15298 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15299 break;
15300
15301 case N_MNEM_vorr:
15302 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15303 break;
15304
15305 case N_MNEM_vand:
15306 /* Pseudo-instruction for VBIC. */
15307 neon_invert_size (&immbits, 0, et.size);
15308 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15309 break;
15310
15311 case N_MNEM_vorn:
15312 /* Pseudo-instruction for VORR. */
15313 neon_invert_size (&immbits, 0, et.size);
15314 cmode = neon_cmode_for_logic_imm (immbits, &immbits, et.size);
15315 break;
15316
15317 default:
15318 abort ();
15319 }
5287ad62
JB
15320
15321 if (cmode == FAIL)
477330fc 15322 return;
5287ad62 15323
037e8744 15324 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
15325 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15326 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15327 inst.instruction |= cmode << 8;
15328 neon_write_immbits (immbits);
5f4273c7 15329
88714cb8 15330 neon_dp_fixup (&inst);
5287ad62
JB
15331 }
15332}
15333
15334static void
15335do_neon_bitfield (void)
15336{
037e8744 15337 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 15338 neon_check_type (3, rs, N_IGNORE_TYPE);
037e8744 15339 neon_three_same (neon_quad (rs), 0, -1);
5287ad62
JB
15340}
15341
15342static void
dcbf9037 15343neon_dyadic_misc (enum neon_el_type ubit_meaning, unsigned types,
477330fc 15344 unsigned destbits)
5287ad62 15345{
037e8744 15346 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
dcbf9037 15347 struct neon_type_el et = neon_check_type (3, rs, N_EQK | destbits, N_EQK,
477330fc 15348 types | N_KEY);
5287ad62
JB
15349 if (et.type == NT_float)
15350 {
88714cb8 15351 NEON_ENCODE (FLOAT, inst);
cc933301 15352 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
15353 }
15354 else
15355 {
88714cb8 15356 NEON_ENCODE (INTEGER, inst);
037e8744 15357 neon_three_same (neon_quad (rs), et.type == ubit_meaning, et.size);
5287ad62
JB
15358 }
15359}
15360
15361static void
15362do_neon_dyadic_if_su (void)
15363{
dcbf9037 15364 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
15365}
15366
15367static void
15368do_neon_dyadic_if_su_d (void)
15369{
15370 /* This version only allow D registers, but that constraint is enforced during
15371 operand parsing so we don't need to do anything extra here. */
dcbf9037 15372 neon_dyadic_misc (NT_unsigned, N_SUF_32, 0);
5287ad62
JB
15373}
15374
5287ad62
JB
15375static void
15376do_neon_dyadic_if_i_d (void)
15377{
428e3f1f
PB
15378 /* The "untyped" case can't happen. Do this to stop the "U" bit being
15379 affected if we specify unsigned args. */
15380 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
5287ad62
JB
15381}
15382
037e8744
JB
15383enum vfp_or_neon_is_neon_bits
15384{
15385 NEON_CHECK_CC = 1,
73924fbc
MGD
15386 NEON_CHECK_ARCH = 2,
15387 NEON_CHECK_ARCH8 = 4
037e8744
JB
15388};
15389
15390/* Call this function if an instruction which may have belonged to the VFP or
15391 Neon instruction sets, but turned out to be a Neon instruction (due to the
15392 operand types involved, etc.). We have to check and/or fix-up a couple of
15393 things:
15394
15395 - Make sure the user hasn't attempted to make a Neon instruction
15396 conditional.
15397 - Alter the value in the condition code field if necessary.
15398 - Make sure that the arch supports Neon instructions.
15399
15400 Which of these operations take place depends on bits from enum
15401 vfp_or_neon_is_neon_bits.
15402
15403 WARNING: This function has side effects! If NEON_CHECK_CC is used and the
15404 current instruction's condition is COND_ALWAYS, the condition field is
15405 changed to inst.uncond_value. This is necessary because instructions shared
15406 between VFP and Neon may be conditional for the VFP variants only, and the
15407 unconditional Neon version must have, e.g., 0xF in the condition field. */
15408
15409static int
15410vfp_or_neon_is_neon (unsigned check)
15411{
15412 /* Conditions are always legal in Thumb mode (IT blocks). */
15413 if (!thumb_mode && (check & NEON_CHECK_CC))
15414 {
15415 if (inst.cond != COND_ALWAYS)
477330fc
RM
15416 {
15417 first_error (_(BAD_COND));
15418 return FAIL;
15419 }
037e8744 15420 if (inst.uncond_value != -1)
477330fc 15421 inst.instruction |= inst.uncond_value << 28;
037e8744 15422 }
5f4273c7 15423
037e8744 15424 if ((check & NEON_CHECK_ARCH)
73924fbc
MGD
15425 && !mark_feature_used (&fpu_neon_ext_v1))
15426 {
15427 first_error (_(BAD_FPU));
15428 return FAIL;
15429 }
15430
15431 if ((check & NEON_CHECK_ARCH8)
15432 && !mark_feature_used (&fpu_neon_ext_armv8))
037e8744
JB
15433 {
15434 first_error (_(BAD_FPU));
15435 return FAIL;
15436 }
5f4273c7 15437
037e8744
JB
15438 return SUCCESS;
15439}
15440
5287ad62
JB
15441static void
15442do_neon_addsub_if_i (void)
15443{
037e8744
JB
15444 if (try_vfp_nsyn (3, do_vfp_nsyn_add_sub) == SUCCESS)
15445 return;
15446
15447 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15448 return;
15449
5287ad62
JB
15450 /* The "untyped" case can't happen. Do this to stop the "U" bit being
15451 affected if we specify unsigned args. */
dcbf9037 15452 neon_dyadic_misc (NT_untyped, N_IF_32 | N_I64, 0);
5287ad62
JB
15453}
15454
15455/* Swaps operands 1 and 2. If operand 1 (optional arg) was omitted, we want the
15456 result to be:
15457 V<op> A,B (A is operand 0, B is operand 2)
15458 to mean:
15459 V<op> A,B,A
15460 not:
15461 V<op> A,B,B
15462 so handle that case specially. */
15463
15464static void
15465neon_exchange_operands (void)
15466{
5287ad62
JB
15467 if (inst.operands[1].present)
15468 {
e1fa0163
NC
15469 void *scratch = xmalloc (sizeof (inst.operands[0]));
15470
5287ad62
JB
15471 /* Swap operands[1] and operands[2]. */
15472 memcpy (scratch, &inst.operands[1], sizeof (inst.operands[0]));
15473 inst.operands[1] = inst.operands[2];
15474 memcpy (&inst.operands[2], scratch, sizeof (inst.operands[0]));
e1fa0163 15475 free (scratch);
5287ad62
JB
15476 }
15477 else
15478 {
15479 inst.operands[1] = inst.operands[2];
15480 inst.operands[2] = inst.operands[0];
15481 }
15482}
15483
15484static void
15485neon_compare (unsigned regtypes, unsigned immtypes, int invert)
15486{
15487 if (inst.operands[2].isreg)
15488 {
15489 if (invert)
477330fc 15490 neon_exchange_operands ();
dcbf9037 15491 neon_dyadic_misc (NT_unsigned, regtypes, N_SIZ);
5287ad62
JB
15492 }
15493 else
15494 {
037e8744 15495 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
dcbf9037 15496 struct neon_type_el et = neon_check_type (2, rs,
477330fc 15497 N_EQK | N_SIZ, immtypes | N_KEY);
5287ad62 15498
88714cb8 15499 NEON_ENCODE (IMMED, inst);
5287ad62
JB
15500 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15501 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15502 inst.instruction |= LOW4 (inst.operands[1].reg);
15503 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 15504 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
15505 inst.instruction |= (et.type == NT_float) << 10;
15506 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 15507
88714cb8 15508 neon_dp_fixup (&inst);
5287ad62
JB
15509 }
15510}
15511
15512static void
15513do_neon_cmp (void)
15514{
cc933301 15515 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, FALSE);
5287ad62
JB
15516}
15517
15518static void
15519do_neon_cmp_inv (void)
15520{
cc933301 15521 neon_compare (N_SUF_32, N_S_32 | N_F_16_32, TRUE);
5287ad62
JB
15522}
15523
15524static void
15525do_neon_ceq (void)
15526{
15527 neon_compare (N_IF_32, N_IF_32, FALSE);
15528}
15529
15530/* For multiply instructions, we have the possibility of 16-bit or 32-bit
15531 scalars, which are encoded in 5 bits, M : Rm.
15532 For 16-bit scalars, the register is encoded in Rm[2:0] and the index in
15533 M:Rm[3], and for 32-bit scalars, the register is encoded in Rm[3:0] and the
c604a79a
JW
15534 index in M.
15535
15536 Dot Product instructions are similar to multiply instructions except elsize
15537 should always be 32.
15538
15539 This function translates SCALAR, which is GAS's internal encoding of indexed
15540 scalar register, to raw encoding. There is also register and index range
15541 check based on ELSIZE. */
5287ad62
JB
15542
15543static unsigned
15544neon_scalar_for_mul (unsigned scalar, unsigned elsize)
15545{
dcbf9037
JB
15546 unsigned regno = NEON_SCALAR_REG (scalar);
15547 unsigned elno = NEON_SCALAR_INDEX (scalar);
5287ad62
JB
15548
15549 switch (elsize)
15550 {
15551 case 16:
15552 if (regno > 7 || elno > 3)
477330fc 15553 goto bad_scalar;
5287ad62 15554 return regno | (elno << 3);
5f4273c7 15555
5287ad62
JB
15556 case 32:
15557 if (regno > 15 || elno > 1)
477330fc 15558 goto bad_scalar;
5287ad62
JB
15559 return regno | (elno << 4);
15560
15561 default:
15562 bad_scalar:
dcbf9037 15563 first_error (_("scalar out of range for multiply instruction"));
5287ad62
JB
15564 }
15565
15566 return 0;
15567}
15568
15569/* Encode multiply / multiply-accumulate scalar instructions. */
15570
15571static void
15572neon_mul_mac (struct neon_type_el et, int ubit)
15573{
dcbf9037
JB
15574 unsigned scalar;
15575
15576 /* Give a more helpful error message if we have an invalid type. */
15577 if (et.type == NT_invtype)
15578 return;
5f4273c7 15579
dcbf9037 15580 scalar = neon_scalar_for_mul (inst.operands[2].reg, et.size);
5287ad62
JB
15581 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15582 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15583 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
15584 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
15585 inst.instruction |= LOW4 (scalar);
15586 inst.instruction |= HI1 (scalar) << 5;
15587 inst.instruction |= (et.type == NT_float) << 8;
15588 inst.instruction |= neon_logbits (et.size) << 20;
15589 inst.instruction |= (ubit != 0) << 24;
15590
88714cb8 15591 neon_dp_fixup (&inst);
5287ad62
JB
15592}
15593
15594static void
15595do_neon_mac_maybe_scalar (void)
15596{
037e8744
JB
15597 if (try_vfp_nsyn (3, do_vfp_nsyn_mla_mls) == SUCCESS)
15598 return;
15599
15600 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15601 return;
15602
5287ad62
JB
15603 if (inst.operands[2].isscalar)
15604 {
037e8744 15605 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 15606 struct neon_type_el et = neon_check_type (3, rs,
589a7d88 15607 N_EQK, N_EQK, N_I16 | N_I32 | N_F_16_32 | N_KEY);
88714cb8 15608 NEON_ENCODE (SCALAR, inst);
037e8744 15609 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
15610 }
15611 else
428e3f1f
PB
15612 {
15613 /* The "untyped" case can't happen. Do this to stop the "U" bit being
15614 affected if we specify unsigned args. */
15615 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
15616 }
5287ad62
JB
15617}
15618
62f3b8c8
PB
15619static void
15620do_neon_fmac (void)
15621{
15622 if (try_vfp_nsyn (3, do_vfp_nsyn_fma_fms) == SUCCESS)
15623 return;
15624
15625 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15626 return;
15627
15628 neon_dyadic_misc (NT_untyped, N_IF_32, 0);
15629}
15630
5287ad62
JB
15631static void
15632do_neon_tst (void)
15633{
037e8744 15634 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62
JB
15635 struct neon_type_el et = neon_check_type (3, rs,
15636 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_KEY);
037e8744 15637 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
15638}
15639
15640/* VMUL with 3 registers allows the P8 type. The scalar version supports the
15641 same types as the MAC equivalents. The polynomial type for this instruction
15642 is encoded the same as the integer type. */
15643
15644static void
15645do_neon_mul (void)
15646{
037e8744
JB
15647 if (try_vfp_nsyn (3, do_vfp_nsyn_mul) == SUCCESS)
15648 return;
15649
15650 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15651 return;
15652
5287ad62
JB
15653 if (inst.operands[2].isscalar)
15654 do_neon_mac_maybe_scalar ();
15655 else
cc933301 15656 neon_dyadic_misc (NT_poly, N_I8 | N_I16 | N_I32 | N_F16 | N_F32 | N_P8, 0);
5287ad62
JB
15657}
15658
15659static void
15660do_neon_qdmulh (void)
15661{
15662 if (inst.operands[2].isscalar)
15663 {
037e8744 15664 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
5287ad62 15665 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15666 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 15667 NEON_ENCODE (SCALAR, inst);
037e8744 15668 neon_mul_mac (et, neon_quad (rs));
5287ad62
JB
15669 }
15670 else
15671 {
037e8744 15672 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
5287ad62 15673 struct neon_type_el et = neon_check_type (3, rs,
477330fc 15674 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
88714cb8 15675 NEON_ENCODE (INTEGER, inst);
5287ad62 15676 /* The U bit (rounding) comes from bit mask. */
037e8744 15677 neon_three_same (neon_quad (rs), 0, et.size);
5287ad62
JB
15678 }
15679}
15680
643afb90
MW
15681static void
15682do_neon_qrdmlah (void)
15683{
15684 /* Check we're on the correct architecture. */
15685 if (!mark_feature_used (&fpu_neon_ext_armv8))
15686 inst.error =
15687 _("instruction form not available on this architecture.");
15688 else if (!mark_feature_used (&fpu_neon_ext_v8_1))
15689 {
15690 as_warn (_("this instruction implies use of ARMv8.1 AdvSIMD."));
15691 record_feature_use (&fpu_neon_ext_v8_1);
15692 }
15693
15694 if (inst.operands[2].isscalar)
15695 {
15696 enum neon_shape rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
15697 struct neon_type_el et = neon_check_type (3, rs,
15698 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
15699 NEON_ENCODE (SCALAR, inst);
15700 neon_mul_mac (et, neon_quad (rs));
15701 }
15702 else
15703 {
15704 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
15705 struct neon_type_el et = neon_check_type (3, rs,
15706 N_EQK, N_EQK, N_S16 | N_S32 | N_KEY);
15707 NEON_ENCODE (INTEGER, inst);
15708 /* The U bit (rounding) comes from bit mask. */
15709 neon_three_same (neon_quad (rs), 0, et.size);
15710 }
15711}
15712
5287ad62
JB
15713static void
15714do_neon_fcmp_absolute (void)
15715{
037e8744 15716 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
15717 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
15718 N_F_16_32 | N_KEY);
5287ad62 15719 /* Size field comes from bit mask. */
cc933301 15720 neon_three_same (neon_quad (rs), 1, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
15721}
15722
15723static void
15724do_neon_fcmp_absolute_inv (void)
15725{
15726 neon_exchange_operands ();
15727 do_neon_fcmp_absolute ();
15728}
15729
15730static void
15731do_neon_step (void)
15732{
037e8744 15733 enum neon_shape rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
cc933301
JW
15734 struct neon_type_el et = neon_check_type (3, rs, N_EQK, N_EQK,
15735 N_F_16_32 | N_KEY);
15736 neon_three_same (neon_quad (rs), 0, et.size == 16 ? (int) et.size : -1);
5287ad62
JB
15737}
15738
15739static void
15740do_neon_abs_neg (void)
15741{
037e8744
JB
15742 enum neon_shape rs;
15743 struct neon_type_el et;
5f4273c7 15744
037e8744
JB
15745 if (try_vfp_nsyn (2, do_vfp_nsyn_abs_neg) == SUCCESS)
15746 return;
15747
15748 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
15749 return;
15750
15751 rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
cc933301 15752 et = neon_check_type (2, rs, N_EQK, N_S_32 | N_F_16_32 | N_KEY);
5f4273c7 15753
5287ad62
JB
15754 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15755 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15756 inst.instruction |= LOW4 (inst.operands[1].reg);
15757 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 15758 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
15759 inst.instruction |= (et.type == NT_float) << 10;
15760 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 15761
88714cb8 15762 neon_dp_fixup (&inst);
5287ad62
JB
15763}
15764
15765static void
15766do_neon_sli (void)
15767{
037e8744 15768 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
15769 struct neon_type_el et = neon_check_type (2, rs,
15770 N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
15771 int imm = inst.operands[2].imm;
15772 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 15773 _("immediate out of range for insert"));
037e8744 15774 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
15775}
15776
15777static void
15778do_neon_sri (void)
15779{
037e8744 15780 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
15781 struct neon_type_el et = neon_check_type (2, rs,
15782 N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
15783 int imm = inst.operands[2].imm;
15784 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15785 _("immediate out of range for insert"));
037e8744 15786 neon_imm_shift (FALSE, 0, neon_quad (rs), et, et.size - imm);
5287ad62
JB
15787}
15788
15789static void
15790do_neon_qshlu_imm (void)
15791{
037e8744 15792 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
15793 struct neon_type_el et = neon_check_type (2, rs,
15794 N_EQK | N_UNS, N_S8 | N_S16 | N_S32 | N_S64 | N_KEY);
15795 int imm = inst.operands[2].imm;
15796 constraint (imm < 0 || (unsigned)imm >= et.size,
477330fc 15797 _("immediate out of range for shift"));
5287ad62
JB
15798 /* Only encodes the 'U present' variant of the instruction.
15799 In this case, signed types have OP (bit 8) set to 0.
15800 Unsigned types have OP set to 1. */
15801 inst.instruction |= (et.type == NT_unsigned) << 8;
15802 /* The rest of the bits are the same as other immediate shifts. */
037e8744 15803 neon_imm_shift (FALSE, 0, neon_quad (rs), et, imm);
5287ad62
JB
15804}
15805
15806static void
15807do_neon_qmovn (void)
15808{
15809 struct neon_type_el et = neon_check_type (2, NS_DQ,
15810 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
15811 /* Saturating move where operands can be signed or unsigned, and the
15812 destination has the same signedness. */
88714cb8 15813 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15814 if (et.type == NT_unsigned)
15815 inst.instruction |= 0xc0;
15816 else
15817 inst.instruction |= 0x80;
15818 neon_two_same (0, 1, et.size / 2);
15819}
15820
15821static void
15822do_neon_qmovun (void)
15823{
15824 struct neon_type_el et = neon_check_type (2, NS_DQ,
15825 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
15826 /* Saturating move with unsigned results. Operands must be signed. */
88714cb8 15827 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15828 neon_two_same (0, 1, et.size / 2);
15829}
15830
15831static void
15832do_neon_rshift_sat_narrow (void)
15833{
15834 /* FIXME: Types for narrowing. If operands are signed, results can be signed
15835 or unsigned. If operands are unsigned, results must also be unsigned. */
15836 struct neon_type_el et = neon_check_type (2, NS_DQI,
15837 N_EQK | N_HLF, N_SU_16_64 | N_KEY);
15838 int imm = inst.operands[2].imm;
15839 /* This gets the bounds check, size encoding and immediate bits calculation
15840 right. */
15841 et.size /= 2;
5f4273c7 15842
5287ad62
JB
15843 /* VQ{R}SHRN.I<size> <Dd>, <Qm>, #0 is a synonym for
15844 VQMOVN.I<size> <Dd>, <Qm>. */
15845 if (imm == 0)
15846 {
15847 inst.operands[2].present = 0;
15848 inst.instruction = N_MNEM_vqmovn;
15849 do_neon_qmovn ();
15850 return;
15851 }
5f4273c7 15852
5287ad62 15853 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15854 _("immediate out of range"));
5287ad62
JB
15855 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, et.size - imm);
15856}
15857
15858static void
15859do_neon_rshift_sat_narrow_u (void)
15860{
15861 /* FIXME: Types for narrowing. If operands are signed, results can be signed
15862 or unsigned. If operands are unsigned, results must also be unsigned. */
15863 struct neon_type_el et = neon_check_type (2, NS_DQI,
15864 N_EQK | N_HLF | N_UNS, N_S16 | N_S32 | N_S64 | N_KEY);
15865 int imm = inst.operands[2].imm;
15866 /* This gets the bounds check, size encoding and immediate bits calculation
15867 right. */
15868 et.size /= 2;
15869
15870 /* VQSHRUN.I<size> <Dd>, <Qm>, #0 is a synonym for
15871 VQMOVUN.I<size> <Dd>, <Qm>. */
15872 if (imm == 0)
15873 {
15874 inst.operands[2].present = 0;
15875 inst.instruction = N_MNEM_vqmovun;
15876 do_neon_qmovun ();
15877 return;
15878 }
15879
15880 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15881 _("immediate out of range"));
5287ad62
JB
15882 /* FIXME: The manual is kind of unclear about what value U should have in
15883 VQ{R}SHRUN instructions, but U=0, op=0 definitely encodes VRSHR, so it
15884 must be 1. */
15885 neon_imm_shift (TRUE, 1, 0, et, et.size - imm);
15886}
15887
15888static void
15889do_neon_movn (void)
15890{
15891 struct neon_type_el et = neon_check_type (2, NS_DQ,
15892 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
88714cb8 15893 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15894 neon_two_same (0, 1, et.size / 2);
15895}
15896
15897static void
15898do_neon_rshift_narrow (void)
15899{
15900 struct neon_type_el et = neon_check_type (2, NS_DQI,
15901 N_EQK | N_HLF, N_I16 | N_I32 | N_I64 | N_KEY);
15902 int imm = inst.operands[2].imm;
15903 /* This gets the bounds check, size encoding and immediate bits calculation
15904 right. */
15905 et.size /= 2;
5f4273c7 15906
5287ad62
JB
15907 /* If immediate is zero then we are a pseudo-instruction for
15908 VMOVN.I<size> <Dd>, <Qm> */
15909 if (imm == 0)
15910 {
15911 inst.operands[2].present = 0;
15912 inst.instruction = N_MNEM_vmovn;
15913 do_neon_movn ();
15914 return;
15915 }
5f4273c7 15916
5287ad62 15917 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 15918 _("immediate out of range for narrowing operation"));
5287ad62
JB
15919 neon_imm_shift (FALSE, 0, 0, et, et.size - imm);
15920}
15921
15922static void
15923do_neon_shll (void)
15924{
15925 /* FIXME: Type checking when lengthening. */
15926 struct neon_type_el et = neon_check_type (2, NS_QDI,
15927 N_EQK | N_DBL, N_I8 | N_I16 | N_I32 | N_KEY);
15928 unsigned imm = inst.operands[2].imm;
15929
15930 if (imm == et.size)
15931 {
15932 /* Maximum shift variant. */
88714cb8 15933 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
15934 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
15935 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
15936 inst.instruction |= LOW4 (inst.operands[1].reg);
15937 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
15938 inst.instruction |= neon_logbits (et.size) << 18;
5f4273c7 15939
88714cb8 15940 neon_dp_fixup (&inst);
5287ad62
JB
15941 }
15942 else
15943 {
15944 /* A more-specific type check for non-max versions. */
15945 et = neon_check_type (2, NS_QDI,
477330fc 15946 N_EQK | N_DBL, N_SU_32 | N_KEY);
88714cb8 15947 NEON_ENCODE (IMMED, inst);
5287ad62
JB
15948 neon_imm_shift (TRUE, et.type == NT_unsigned, 0, et, imm);
15949 }
15950}
15951
037e8744 15952/* Check the various types for the VCVT instruction, and return which version
5287ad62
JB
15953 the current instruction is. */
15954
6b9a8b67
MGD
15955#define CVT_FLAVOUR_VAR \
15956 CVT_VAR (s32_f32, N_S32, N_F32, whole_reg, "ftosls", "ftosis", "ftosizs") \
15957 CVT_VAR (u32_f32, N_U32, N_F32, whole_reg, "ftouls", "ftouis", "ftouizs") \
15958 CVT_VAR (f32_s32, N_F32, N_S32, whole_reg, "fsltos", "fsitos", NULL) \
15959 CVT_VAR (f32_u32, N_F32, N_U32, whole_reg, "fultos", "fuitos", NULL) \
15960 /* Half-precision conversions. */ \
cc933301
JW
15961 CVT_VAR (s16_f16, N_S16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
15962 CVT_VAR (u16_f16, N_U16, N_F16 | N_KEY, whole_reg, NULL, NULL, NULL) \
15963 CVT_VAR (f16_s16, N_F16 | N_KEY, N_S16, whole_reg, NULL, NULL, NULL) \
15964 CVT_VAR (f16_u16, N_F16 | N_KEY, N_U16, whole_reg, NULL, NULL, NULL) \
6b9a8b67
MGD
15965 CVT_VAR (f32_f16, N_F32, N_F16, whole_reg, NULL, NULL, NULL) \
15966 CVT_VAR (f16_f32, N_F16, N_F32, whole_reg, NULL, NULL, NULL) \
9db2f6b4
RL
15967 /* New VCVT instructions introduced by ARMv8.2 fp16 extension. \
15968 Compared with single/double precision variants, only the co-processor \
15969 field is different, so the encoding flow is reused here. */ \
15970 CVT_VAR (f16_s32, N_F16 | N_KEY, N_S32, N_VFP, "fsltos", "fsitos", NULL) \
15971 CVT_VAR (f16_u32, N_F16 | N_KEY, N_U32, N_VFP, "fultos", "fuitos", NULL) \
15972 CVT_VAR (u32_f16, N_U32, N_F16 | N_KEY, N_VFP, "ftouls", "ftouis", "ftouizs")\
15973 CVT_VAR (s32_f16, N_S32, N_F16 | N_KEY, N_VFP, "ftosls", "ftosis", "ftosizs")\
6b9a8b67
MGD
15974 /* VFP instructions. */ \
15975 CVT_VAR (f32_f64, N_F32, N_F64, N_VFP, NULL, "fcvtsd", NULL) \
15976 CVT_VAR (f64_f32, N_F64, N_F32, N_VFP, NULL, "fcvtds", NULL) \
15977 CVT_VAR (s32_f64, N_S32, N_F64 | key, N_VFP, "ftosld", "ftosid", "ftosizd") \
15978 CVT_VAR (u32_f64, N_U32, N_F64 | key, N_VFP, "ftould", "ftouid", "ftouizd") \
15979 CVT_VAR (f64_s32, N_F64 | key, N_S32, N_VFP, "fsltod", "fsitod", NULL) \
15980 CVT_VAR (f64_u32, N_F64 | key, N_U32, N_VFP, "fultod", "fuitod", NULL) \
15981 /* VFP instructions with bitshift. */ \
15982 CVT_VAR (f32_s16, N_F32 | key, N_S16, N_VFP, "fshtos", NULL, NULL) \
15983 CVT_VAR (f32_u16, N_F32 | key, N_U16, N_VFP, "fuhtos", NULL, NULL) \
15984 CVT_VAR (f64_s16, N_F64 | key, N_S16, N_VFP, "fshtod", NULL, NULL) \
15985 CVT_VAR (f64_u16, N_F64 | key, N_U16, N_VFP, "fuhtod", NULL, NULL) \
15986 CVT_VAR (s16_f32, N_S16, N_F32 | key, N_VFP, "ftoshs", NULL, NULL) \
15987 CVT_VAR (u16_f32, N_U16, N_F32 | key, N_VFP, "ftouhs", NULL, NULL) \
15988 CVT_VAR (s16_f64, N_S16, N_F64 | key, N_VFP, "ftoshd", NULL, NULL) \
15989 CVT_VAR (u16_f64, N_U16, N_F64 | key, N_VFP, "ftouhd", NULL, NULL)
15990
15991#define CVT_VAR(C, X, Y, R, BSN, CN, ZN) \
15992 neon_cvt_flavour_##C,
15993
15994/* The different types of conversions we can do. */
15995enum neon_cvt_flavour
15996{
15997 CVT_FLAVOUR_VAR
15998 neon_cvt_flavour_invalid,
15999 neon_cvt_flavour_first_fp = neon_cvt_flavour_f32_f64
16000};
16001
16002#undef CVT_VAR
16003
16004static enum neon_cvt_flavour
16005get_neon_cvt_flavour (enum neon_shape rs)
5287ad62 16006{
6b9a8b67
MGD
16007#define CVT_VAR(C,X,Y,R,BSN,CN,ZN) \
16008 et = neon_check_type (2, rs, (R) | (X), (R) | (Y)); \
16009 if (et.type != NT_invtype) \
16010 { \
16011 inst.error = NULL; \
16012 return (neon_cvt_flavour_##C); \
5287ad62 16013 }
6b9a8b67 16014
5287ad62 16015 struct neon_type_el et;
037e8744 16016 unsigned whole_reg = (rs == NS_FFI || rs == NS_FD || rs == NS_DF
477330fc 16017 || rs == NS_FF) ? N_VFP : 0;
037e8744
JB
16018 /* The instruction versions which take an immediate take one register
16019 argument, which is extended to the width of the full register. Thus the
16020 "source" and "destination" registers must have the same width. Hack that
16021 here by making the size equal to the key (wider, in this case) operand. */
16022 unsigned key = (rs == NS_QQI || rs == NS_DDI || rs == NS_FFI) ? N_KEY : 0;
5f4273c7 16023
6b9a8b67
MGD
16024 CVT_FLAVOUR_VAR;
16025
16026 return neon_cvt_flavour_invalid;
5287ad62
JB
16027#undef CVT_VAR
16028}
16029
7e8e6784
MGD
16030enum neon_cvt_mode
16031{
16032 neon_cvt_mode_a,
16033 neon_cvt_mode_n,
16034 neon_cvt_mode_p,
16035 neon_cvt_mode_m,
16036 neon_cvt_mode_z,
30bdf752
MGD
16037 neon_cvt_mode_x,
16038 neon_cvt_mode_r
7e8e6784
MGD
16039};
16040
037e8744
JB
16041/* Neon-syntax VFP conversions. */
16042
5287ad62 16043static void
6b9a8b67 16044do_vfp_nsyn_cvt (enum neon_shape rs, enum neon_cvt_flavour flavour)
5287ad62 16045{
037e8744 16046 const char *opname = 0;
5f4273c7 16047
d54af2d0
RL
16048 if (rs == NS_DDI || rs == NS_QQI || rs == NS_FFI
16049 || rs == NS_FHI || rs == NS_HFI)
5287ad62 16050 {
037e8744
JB
16051 /* Conversions with immediate bitshift. */
16052 const char *enc[] =
477330fc 16053 {
6b9a8b67
MGD
16054#define CVT_VAR(C,A,B,R,BSN,CN,ZN) BSN,
16055 CVT_FLAVOUR_VAR
16056 NULL
16057#undef CVT_VAR
477330fc 16058 };
037e8744 16059
6b9a8b67 16060 if (flavour < (int) ARRAY_SIZE (enc))
477330fc
RM
16061 {
16062 opname = enc[flavour];
16063 constraint (inst.operands[0].reg != inst.operands[1].reg,
16064 _("operands 0 and 1 must be the same register"));
16065 inst.operands[1] = inst.operands[2];
16066 memset (&inst.operands[2], '\0', sizeof (inst.operands[2]));
16067 }
5287ad62
JB
16068 }
16069 else
16070 {
037e8744
JB
16071 /* Conversions without bitshift. */
16072 const char *enc[] =
477330fc 16073 {
6b9a8b67
MGD
16074#define CVT_VAR(C,A,B,R,BSN,CN,ZN) CN,
16075 CVT_FLAVOUR_VAR
16076 NULL
16077#undef CVT_VAR
477330fc 16078 };
037e8744 16079
6b9a8b67 16080 if (flavour < (int) ARRAY_SIZE (enc))
477330fc 16081 opname = enc[flavour];
037e8744
JB
16082 }
16083
16084 if (opname)
16085 do_vfp_nsyn_opcode (opname);
9db2f6b4
RL
16086
16087 /* ARMv8.2 fp16 VCVT instruction. */
16088 if (flavour == neon_cvt_flavour_s32_f16
16089 || flavour == neon_cvt_flavour_u32_f16
16090 || flavour == neon_cvt_flavour_f16_u32
16091 || flavour == neon_cvt_flavour_f16_s32)
16092 do_scalar_fp16_v82_encode ();
037e8744
JB
16093}
16094
16095static void
16096do_vfp_nsyn_cvtz (void)
16097{
d54af2d0 16098 enum neon_shape rs = neon_select_shape (NS_FH, NS_FF, NS_FD, NS_NULL);
6b9a8b67 16099 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744
JB
16100 const char *enc[] =
16101 {
6b9a8b67
MGD
16102#define CVT_VAR(C,A,B,R,BSN,CN,ZN) ZN,
16103 CVT_FLAVOUR_VAR
16104 NULL
16105#undef CVT_VAR
037e8744
JB
16106 };
16107
6b9a8b67 16108 if (flavour < (int) ARRAY_SIZE (enc) && enc[flavour])
037e8744
JB
16109 do_vfp_nsyn_opcode (enc[flavour]);
16110}
f31fef98 16111
037e8744 16112static void
bacebabc 16113do_vfp_nsyn_cvt_fpv8 (enum neon_cvt_flavour flavour,
7e8e6784
MGD
16114 enum neon_cvt_mode mode)
16115{
16116 int sz, op;
16117 int rm;
16118
a715796b
TG
16119 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
16120 D register operands. */
16121 if (flavour == neon_cvt_flavour_s32_f64
16122 || flavour == neon_cvt_flavour_u32_f64)
16123 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
16124 _(BAD_FPU));
16125
9db2f6b4
RL
16126 if (flavour == neon_cvt_flavour_s32_f16
16127 || flavour == neon_cvt_flavour_u32_f16)
16128 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16),
16129 _(BAD_FP16));
16130
7e8e6784
MGD
16131 set_it_insn_type (OUTSIDE_IT_INSN);
16132
16133 switch (flavour)
16134 {
16135 case neon_cvt_flavour_s32_f64:
16136 sz = 1;
827f64ff 16137 op = 1;
7e8e6784
MGD
16138 break;
16139 case neon_cvt_flavour_s32_f32:
16140 sz = 0;
16141 op = 1;
16142 break;
9db2f6b4
RL
16143 case neon_cvt_flavour_s32_f16:
16144 sz = 0;
16145 op = 1;
16146 break;
7e8e6784
MGD
16147 case neon_cvt_flavour_u32_f64:
16148 sz = 1;
16149 op = 0;
16150 break;
16151 case neon_cvt_flavour_u32_f32:
16152 sz = 0;
16153 op = 0;
16154 break;
9db2f6b4
RL
16155 case neon_cvt_flavour_u32_f16:
16156 sz = 0;
16157 op = 0;
16158 break;
7e8e6784
MGD
16159 default:
16160 first_error (_("invalid instruction shape"));
16161 return;
16162 }
16163
16164 switch (mode)
16165 {
16166 case neon_cvt_mode_a: rm = 0; break;
16167 case neon_cvt_mode_n: rm = 1; break;
16168 case neon_cvt_mode_p: rm = 2; break;
16169 case neon_cvt_mode_m: rm = 3; break;
16170 default: first_error (_("invalid rounding mode")); return;
16171 }
16172
16173 NEON_ENCODE (FPV8, inst);
16174 encode_arm_vfp_reg (inst.operands[0].reg, VFP_REG_Sd);
16175 encode_arm_vfp_reg (inst.operands[1].reg, sz == 1 ? VFP_REG_Dm : VFP_REG_Sm);
16176 inst.instruction |= sz << 8;
9db2f6b4
RL
16177
16178 /* ARMv8.2 fp16 VCVT instruction. */
16179 if (flavour == neon_cvt_flavour_s32_f16
16180 ||flavour == neon_cvt_flavour_u32_f16)
16181 do_scalar_fp16_v82_encode ();
7e8e6784
MGD
16182 inst.instruction |= op << 7;
16183 inst.instruction |= rm << 16;
16184 inst.instruction |= 0xf0000000;
16185 inst.is_neon = TRUE;
16186}
16187
16188static void
16189do_neon_cvt_1 (enum neon_cvt_mode mode)
037e8744
JB
16190{
16191 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_FFI, NS_DD, NS_QQ,
d54af2d0
RL
16192 NS_FD, NS_DF, NS_FF, NS_QD, NS_DQ,
16193 NS_FH, NS_HF, NS_FHI, NS_HFI,
16194 NS_NULL);
6b9a8b67 16195 enum neon_cvt_flavour flavour = get_neon_cvt_flavour (rs);
037e8744 16196
cc933301
JW
16197 if (flavour == neon_cvt_flavour_invalid)
16198 return;
16199
e3e535bc 16200 /* PR11109: Handle round-to-zero for VCVT conversions. */
7e8e6784 16201 if (mode == neon_cvt_mode_z
e3e535bc 16202 && ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_vfp_v2)
cc933301
JW
16203 && (flavour == neon_cvt_flavour_s16_f16
16204 || flavour == neon_cvt_flavour_u16_f16
16205 || flavour == neon_cvt_flavour_s32_f32
bacebabc
RM
16206 || flavour == neon_cvt_flavour_u32_f32
16207 || flavour == neon_cvt_flavour_s32_f64
6b9a8b67 16208 || flavour == neon_cvt_flavour_u32_f64)
e3e535bc
NC
16209 && (rs == NS_FD || rs == NS_FF))
16210 {
16211 do_vfp_nsyn_cvtz ();
16212 return;
16213 }
16214
9db2f6b4
RL
16215 /* ARMv8.2 fp16 VCVT conversions. */
16216 if (mode == neon_cvt_mode_z
16217 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16)
16218 && (flavour == neon_cvt_flavour_s32_f16
16219 || flavour == neon_cvt_flavour_u32_f16)
16220 && (rs == NS_FH))
16221 {
16222 do_vfp_nsyn_cvtz ();
16223 do_scalar_fp16_v82_encode ();
16224 return;
16225 }
16226
037e8744 16227 /* VFP rather than Neon conversions. */
6b9a8b67 16228 if (flavour >= neon_cvt_flavour_first_fp)
037e8744 16229 {
7e8e6784
MGD
16230 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
16231 do_vfp_nsyn_cvt (rs, flavour);
16232 else
16233 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
16234
037e8744
JB
16235 return;
16236 }
16237
16238 switch (rs)
16239 {
16240 case NS_DDI:
16241 case NS_QQI:
16242 {
477330fc 16243 unsigned immbits;
cc933301
JW
16244 unsigned enctab[] = {0x0000100, 0x1000100, 0x0, 0x1000000,
16245 0x0000100, 0x1000100, 0x0, 0x1000000};
35997600 16246
477330fc
RM
16247 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16248 return;
037e8744 16249
477330fc
RM
16250 /* Fixed-point conversion with #0 immediate is encoded as an
16251 integer conversion. */
16252 if (inst.operands[2].present && inst.operands[2].imm == 0)
16253 goto int_encode;
477330fc
RM
16254 NEON_ENCODE (IMMED, inst);
16255 if (flavour != neon_cvt_flavour_invalid)
16256 inst.instruction |= enctab[flavour];
16257 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16258 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16259 inst.instruction |= LOW4 (inst.operands[1].reg);
16260 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16261 inst.instruction |= neon_quad (rs) << 6;
16262 inst.instruction |= 1 << 21;
cc933301
JW
16263 if (flavour < neon_cvt_flavour_s16_f16)
16264 {
16265 inst.instruction |= 1 << 21;
16266 immbits = 32 - inst.operands[2].imm;
16267 inst.instruction |= immbits << 16;
16268 }
16269 else
16270 {
16271 inst.instruction |= 3 << 20;
16272 immbits = 16 - inst.operands[2].imm;
16273 inst.instruction |= immbits << 16;
16274 inst.instruction &= ~(1 << 9);
16275 }
477330fc
RM
16276
16277 neon_dp_fixup (&inst);
037e8744
JB
16278 }
16279 break;
16280
16281 case NS_DD:
16282 case NS_QQ:
7e8e6784
MGD
16283 if (mode != neon_cvt_mode_x && mode != neon_cvt_mode_z)
16284 {
16285 NEON_ENCODE (FLOAT, inst);
16286 set_it_insn_type (OUTSIDE_IT_INSN);
16287
16288 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
16289 return;
16290
16291 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16292 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16293 inst.instruction |= LOW4 (inst.operands[1].reg);
16294 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16295 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
16296 inst.instruction |= (flavour == neon_cvt_flavour_u16_f16
16297 || flavour == neon_cvt_flavour_u32_f32) << 7;
7e8e6784 16298 inst.instruction |= mode << 8;
cc933301
JW
16299 if (flavour == neon_cvt_flavour_u16_f16
16300 || flavour == neon_cvt_flavour_s16_f16)
16301 /* Mask off the original size bits and reencode them. */
16302 inst.instruction = ((inst.instruction & 0xfff3ffff) | (1 << 18));
16303
7e8e6784
MGD
16304 if (thumb_mode)
16305 inst.instruction |= 0xfc000000;
16306 else
16307 inst.instruction |= 0xf0000000;
16308 }
16309 else
16310 {
037e8744 16311 int_encode:
7e8e6784 16312 {
cc933301
JW
16313 unsigned enctab[] = { 0x100, 0x180, 0x0, 0x080,
16314 0x100, 0x180, 0x0, 0x080};
037e8744 16315
7e8e6784 16316 NEON_ENCODE (INTEGER, inst);
037e8744 16317
7e8e6784
MGD
16318 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16319 return;
037e8744 16320
7e8e6784
MGD
16321 if (flavour != neon_cvt_flavour_invalid)
16322 inst.instruction |= enctab[flavour];
037e8744 16323
7e8e6784
MGD
16324 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16325 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16326 inst.instruction |= LOW4 (inst.operands[1].reg);
16327 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16328 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
16329 if (flavour >= neon_cvt_flavour_s16_f16
16330 && flavour <= neon_cvt_flavour_f16_u16)
16331 /* Half precision. */
16332 inst.instruction |= 1 << 18;
16333 else
16334 inst.instruction |= 2 << 18;
037e8744 16335
7e8e6784
MGD
16336 neon_dp_fixup (&inst);
16337 }
16338 }
16339 break;
037e8744 16340
8e79c3df
CM
16341 /* Half-precision conversions for Advanced SIMD -- neon. */
16342 case NS_QD:
16343 case NS_DQ:
bc52d49c
MM
16344 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16345 return;
8e79c3df
CM
16346
16347 if ((rs == NS_DQ)
16348 && (inst.vectype.el[0].size != 16 || inst.vectype.el[1].size != 32))
16349 {
16350 as_bad (_("operand size must match register width"));
16351 break;
16352 }
16353
16354 if ((rs == NS_QD)
16355 && ((inst.vectype.el[0].size != 32 || inst.vectype.el[1].size != 16)))
16356 {
16357 as_bad (_("operand size must match register width"));
16358 break;
16359 }
16360
16361 if (rs == NS_DQ)
477330fc 16362 inst.instruction = 0x3b60600;
8e79c3df
CM
16363 else
16364 inst.instruction = 0x3b60700;
16365
16366 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16367 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16368 inst.instruction |= LOW4 (inst.operands[1].reg);
16369 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
88714cb8 16370 neon_dp_fixup (&inst);
8e79c3df
CM
16371 break;
16372
037e8744
JB
16373 default:
16374 /* Some VFP conversions go here (s32 <-> f32, u32 <-> f32). */
7e8e6784
MGD
16375 if (mode == neon_cvt_mode_x || mode == neon_cvt_mode_z)
16376 do_vfp_nsyn_cvt (rs, flavour);
16377 else
16378 do_vfp_nsyn_cvt_fpv8 (flavour, mode);
5287ad62 16379 }
5287ad62
JB
16380}
16381
e3e535bc
NC
16382static void
16383do_neon_cvtr (void)
16384{
7e8e6784 16385 do_neon_cvt_1 (neon_cvt_mode_x);
e3e535bc
NC
16386}
16387
16388static void
16389do_neon_cvt (void)
16390{
7e8e6784
MGD
16391 do_neon_cvt_1 (neon_cvt_mode_z);
16392}
16393
16394static void
16395do_neon_cvta (void)
16396{
16397 do_neon_cvt_1 (neon_cvt_mode_a);
16398}
16399
16400static void
16401do_neon_cvtn (void)
16402{
16403 do_neon_cvt_1 (neon_cvt_mode_n);
16404}
16405
16406static void
16407do_neon_cvtp (void)
16408{
16409 do_neon_cvt_1 (neon_cvt_mode_p);
16410}
16411
16412static void
16413do_neon_cvtm (void)
16414{
16415 do_neon_cvt_1 (neon_cvt_mode_m);
e3e535bc
NC
16416}
16417
8e79c3df 16418static void
c70a8987 16419do_neon_cvttb_2 (bfd_boolean t, bfd_boolean to, bfd_boolean is_double)
8e79c3df 16420{
c70a8987
MGD
16421 if (is_double)
16422 mark_feature_used (&fpu_vfp_ext_armv8);
8e79c3df 16423
c70a8987
MGD
16424 encode_arm_vfp_reg (inst.operands[0].reg,
16425 (is_double && !to) ? VFP_REG_Dd : VFP_REG_Sd);
16426 encode_arm_vfp_reg (inst.operands[1].reg,
16427 (is_double && to) ? VFP_REG_Dm : VFP_REG_Sm);
16428 inst.instruction |= to ? 0x10000 : 0;
16429 inst.instruction |= t ? 0x80 : 0;
16430 inst.instruction |= is_double ? 0x100 : 0;
16431 do_vfp_cond_or_thumb ();
16432}
8e79c3df 16433
c70a8987
MGD
16434static void
16435do_neon_cvttb_1 (bfd_boolean t)
16436{
d54af2d0
RL
16437 enum neon_shape rs = neon_select_shape (NS_HF, NS_HD, NS_FH, NS_FF, NS_FD,
16438 NS_DF, NS_DH, NS_NULL);
8e79c3df 16439
c70a8987
MGD
16440 if (rs == NS_NULL)
16441 return;
16442 else if (neon_check_type (2, rs, N_F16, N_F32 | N_VFP).type != NT_invtype)
16443 {
16444 inst.error = NULL;
16445 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/FALSE);
16446 }
16447 else if (neon_check_type (2, rs, N_F32 | N_VFP, N_F16).type != NT_invtype)
16448 {
16449 inst.error = NULL;
16450 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/FALSE);
16451 }
16452 else if (neon_check_type (2, rs, N_F16, N_F64 | N_VFP).type != NT_invtype)
16453 {
a715796b
TG
16454 /* The VCVTB and VCVTT instructions with D-register operands
16455 don't work for SP only targets. */
16456 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
16457 _(BAD_FPU));
16458
c70a8987
MGD
16459 inst.error = NULL;
16460 do_neon_cvttb_2 (t, /*to=*/TRUE, /*is_double=*/TRUE);
16461 }
16462 else if (neon_check_type (2, rs, N_F64 | N_VFP, N_F16).type != NT_invtype)
16463 {
a715796b
TG
16464 /* The VCVTB and VCVTT instructions with D-register operands
16465 don't work for SP only targets. */
16466 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
16467 _(BAD_FPU));
16468
c70a8987
MGD
16469 inst.error = NULL;
16470 do_neon_cvttb_2 (t, /*to=*/FALSE, /*is_double=*/TRUE);
16471 }
16472 else
16473 return;
16474}
16475
16476static void
16477do_neon_cvtb (void)
16478{
16479 do_neon_cvttb_1 (FALSE);
8e79c3df
CM
16480}
16481
16482
16483static void
16484do_neon_cvtt (void)
16485{
c70a8987 16486 do_neon_cvttb_1 (TRUE);
8e79c3df
CM
16487}
16488
5287ad62
JB
16489static void
16490neon_move_immediate (void)
16491{
037e8744
JB
16492 enum neon_shape rs = neon_select_shape (NS_DI, NS_QI, NS_NULL);
16493 struct neon_type_el et = neon_check_type (2, rs,
16494 N_I8 | N_I16 | N_I32 | N_I64 | N_F32 | N_KEY, N_EQK);
5287ad62 16495 unsigned immlo, immhi = 0, immbits;
c96612cc 16496 int op, cmode, float_p;
5287ad62 16497
037e8744 16498 constraint (et.type == NT_invtype,
477330fc 16499 _("operand size must be specified for immediate VMOV"));
037e8744 16500
5287ad62
JB
16501 /* We start out as an MVN instruction if OP = 1, MOV otherwise. */
16502 op = (inst.instruction & (1 << 5)) != 0;
16503
16504 immlo = inst.operands[1].imm;
16505 if (inst.operands[1].regisimm)
16506 immhi = inst.operands[1].reg;
16507
16508 constraint (et.size < 32 && (immlo & ~((1 << et.size) - 1)) != 0,
477330fc 16509 _("immediate has bits set outside the operand size"));
5287ad62 16510
c96612cc
JB
16511 float_p = inst.operands[1].immisfloat;
16512
16513 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits, &op,
477330fc 16514 et.size, et.type)) == FAIL)
5287ad62
JB
16515 {
16516 /* Invert relevant bits only. */
16517 neon_invert_size (&immlo, &immhi, et.size);
16518 /* Flip from VMOV/VMVN to VMVN/VMOV. Some immediate types are unavailable
477330fc
RM
16519 with one or the other; those cases are caught by
16520 neon_cmode_for_move_imm. */
5287ad62 16521 op = !op;
c96612cc
JB
16522 if ((cmode = neon_cmode_for_move_imm (immlo, immhi, float_p, &immbits,
16523 &op, et.size, et.type)) == FAIL)
477330fc
RM
16524 {
16525 first_error (_("immediate out of range"));
16526 return;
16527 }
5287ad62
JB
16528 }
16529
16530 inst.instruction &= ~(1 << 5);
16531 inst.instruction |= op << 5;
16532
16533 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16534 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
037e8744 16535 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16536 inst.instruction |= cmode << 8;
16537
16538 neon_write_immbits (immbits);
16539}
16540
16541static void
16542do_neon_mvn (void)
16543{
16544 if (inst.operands[1].isreg)
16545 {
037e8744 16546 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5f4273c7 16547
88714cb8 16548 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
16549 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16550 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16551 inst.instruction |= LOW4 (inst.operands[1].reg);
16552 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
037e8744 16553 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16554 }
16555 else
16556 {
88714cb8 16557 NEON_ENCODE (IMMED, inst);
5287ad62
JB
16558 neon_move_immediate ();
16559 }
16560
88714cb8 16561 neon_dp_fixup (&inst);
5287ad62
JB
16562}
16563
16564/* Encode instructions of form:
16565
16566 |28/24|23|22|21 20|19 16|15 12|11 8|7|6|5|4|3 0|
5f4273c7 16567 | U |x |D |size | Rn | Rd |x x x x|N|x|M|x| Rm | */
5287ad62
JB
16568
16569static void
16570neon_mixed_length (struct neon_type_el et, unsigned size)
16571{
16572 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16573 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16574 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16575 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16576 inst.instruction |= LOW4 (inst.operands[2].reg);
16577 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
16578 inst.instruction |= (et.type == NT_unsigned) << 24;
16579 inst.instruction |= neon_logbits (size) << 20;
5f4273c7 16580
88714cb8 16581 neon_dp_fixup (&inst);
5287ad62
JB
16582}
16583
16584static void
16585do_neon_dyadic_long (void)
16586{
16587 /* FIXME: Type checking for lengthening op. */
16588 struct neon_type_el et = neon_check_type (3, NS_QDD,
16589 N_EQK | N_DBL, N_EQK, N_SU_32 | N_KEY);
16590 neon_mixed_length (et, et.size);
16591}
16592
16593static void
16594do_neon_abal (void)
16595{
16596 struct neon_type_el et = neon_check_type (3, NS_QDD,
16597 N_EQK | N_INT | N_DBL, N_EQK, N_SU_32 | N_KEY);
16598 neon_mixed_length (et, et.size);
16599}
16600
16601static void
16602neon_mac_reg_scalar_long (unsigned regtypes, unsigned scalartypes)
16603{
16604 if (inst.operands[2].isscalar)
16605 {
dcbf9037 16606 struct neon_type_el et = neon_check_type (3, NS_QDS,
477330fc 16607 N_EQK | N_DBL, N_EQK, regtypes | N_KEY);
88714cb8 16608 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
16609 neon_mul_mac (et, et.type == NT_unsigned);
16610 }
16611 else
16612 {
16613 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 16614 N_EQK | N_DBL, N_EQK, scalartypes | N_KEY);
88714cb8 16615 NEON_ENCODE (INTEGER, inst);
5287ad62
JB
16616 neon_mixed_length (et, et.size);
16617 }
16618}
16619
16620static void
16621do_neon_mac_maybe_scalar_long (void)
16622{
16623 neon_mac_reg_scalar_long (N_S16 | N_S32 | N_U16 | N_U32, N_SU_32);
16624}
16625
dec41383
JW
16626/* Like neon_scalar_for_mul, this function generate Rm encoding from GAS's
16627 internal SCALAR. QUAD_P is 1 if it's for Q format, otherwise it's 0. */
16628
16629static unsigned
16630neon_scalar_for_fmac_fp16_long (unsigned scalar, unsigned quad_p)
16631{
16632 unsigned regno = NEON_SCALAR_REG (scalar);
16633 unsigned elno = NEON_SCALAR_INDEX (scalar);
16634
16635 if (quad_p)
16636 {
16637 if (regno > 7 || elno > 3)
16638 goto bad_scalar;
16639
16640 return ((regno & 0x7)
16641 | ((elno & 0x1) << 3)
16642 | (((elno >> 1) & 0x1) << 5));
16643 }
16644 else
16645 {
16646 if (regno > 15 || elno > 1)
16647 goto bad_scalar;
16648
16649 return (((regno & 0x1) << 5)
16650 | ((regno >> 1) & 0x7)
16651 | ((elno & 0x1) << 3));
16652 }
16653
16654bad_scalar:
16655 first_error (_("scalar out of range for multiply instruction"));
16656 return 0;
16657}
16658
16659static void
16660do_neon_fmac_maybe_scalar_long (int subtype)
16661{
16662 enum neon_shape rs;
16663 int high8;
16664 /* NOTE: vfmal/vfmsl use slightly different NEON three-same encoding. 'size"
16665 field (bits[21:20]) has different meaning. For scalar index variant, it's
16666 used to differentiate add and subtract, otherwise it's with fixed value
16667 0x2. */
16668 int size = -1;
16669
16670 if (inst.cond != COND_ALWAYS)
16671 as_warn (_("vfmal/vfmsl with FP16 type cannot be conditional, the "
16672 "behaviour is UNPREDICTABLE"));
16673
01f48020 16674 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_fp16_fml),
dec41383
JW
16675 _(BAD_FP16));
16676
16677 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
16678 _(BAD_FPU));
16679
16680 /* vfmal/vfmsl are in three-same D/Q register format or the third operand can
16681 be a scalar index register. */
16682 if (inst.operands[2].isscalar)
16683 {
16684 high8 = 0xfe000000;
16685 if (subtype)
16686 size = 16;
16687 rs = neon_select_shape (NS_DHS, NS_QDS, NS_NULL);
16688 }
16689 else
16690 {
16691 high8 = 0xfc000000;
16692 size = 32;
16693 if (subtype)
16694 inst.instruction |= (0x1 << 23);
16695 rs = neon_select_shape (NS_DHH, NS_QDD, NS_NULL);
16696 }
16697
16698 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_F16);
16699
16700 /* "opcode" from template has included "ubit", so simply pass 0 here. Also,
16701 the "S" bit in size field has been reused to differentiate vfmal and vfmsl,
16702 so we simply pass -1 as size. */
16703 unsigned quad_p = (rs == NS_QDD || rs == NS_QDS);
16704 neon_three_same (quad_p, 0, size);
16705
16706 /* Undo neon_dp_fixup. Redo the high eight bits. */
16707 inst.instruction &= 0x00ffffff;
16708 inst.instruction |= high8;
16709
16710#define LOW1(R) ((R) & 0x1)
16711#define HI4(R) (((R) >> 1) & 0xf)
16712 /* Unlike usually NEON three-same, encoding for Vn and Vm will depend on
16713 whether the instruction is in Q form and whether Vm is a scalar indexed
16714 operand. */
16715 if (inst.operands[2].isscalar)
16716 {
16717 unsigned rm
16718 = neon_scalar_for_fmac_fp16_long (inst.operands[2].reg, quad_p);
16719 inst.instruction &= 0xffffffd0;
16720 inst.instruction |= rm;
16721
16722 if (!quad_p)
16723 {
16724 /* Redo Rn as well. */
16725 inst.instruction &= 0xfff0ff7f;
16726 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
16727 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
16728 }
16729 }
16730 else if (!quad_p)
16731 {
16732 /* Redo Rn and Rm. */
16733 inst.instruction &= 0xfff0ff50;
16734 inst.instruction |= HI4 (inst.operands[1].reg) << 16;
16735 inst.instruction |= LOW1 (inst.operands[1].reg) << 7;
16736 inst.instruction |= HI4 (inst.operands[2].reg);
16737 inst.instruction |= LOW1 (inst.operands[2].reg) << 5;
16738 }
16739}
16740
16741static void
16742do_neon_vfmal (void)
16743{
16744 return do_neon_fmac_maybe_scalar_long (0);
16745}
16746
16747static void
16748do_neon_vfmsl (void)
16749{
16750 return do_neon_fmac_maybe_scalar_long (1);
16751}
16752
5287ad62
JB
16753static void
16754do_neon_dyadic_wide (void)
16755{
16756 struct neon_type_el et = neon_check_type (3, NS_QQD,
16757 N_EQK | N_DBL, N_EQK | N_DBL, N_SU_32 | N_KEY);
16758 neon_mixed_length (et, et.size);
16759}
16760
16761static void
16762do_neon_dyadic_narrow (void)
16763{
16764 struct neon_type_el et = neon_check_type (3, NS_QDD,
16765 N_EQK | N_DBL, N_EQK, N_I16 | N_I32 | N_I64 | N_KEY);
428e3f1f
PB
16766 /* Operand sign is unimportant, and the U bit is part of the opcode,
16767 so force the operand type to integer. */
16768 et.type = NT_integer;
5287ad62
JB
16769 neon_mixed_length (et, et.size / 2);
16770}
16771
16772static void
16773do_neon_mul_sat_scalar_long (void)
16774{
16775 neon_mac_reg_scalar_long (N_S16 | N_S32, N_S16 | N_S32);
16776}
16777
16778static void
16779do_neon_vmull (void)
16780{
16781 if (inst.operands[2].isscalar)
16782 do_neon_mac_maybe_scalar_long ();
16783 else
16784 {
16785 struct neon_type_el et = neon_check_type (3, NS_QDD,
477330fc 16786 N_EQK | N_DBL, N_EQK, N_SU_32 | N_P8 | N_P64 | N_KEY);
4f51b4bd 16787
5287ad62 16788 if (et.type == NT_poly)
477330fc 16789 NEON_ENCODE (POLY, inst);
5287ad62 16790 else
477330fc 16791 NEON_ENCODE (INTEGER, inst);
4f51b4bd
MGD
16792
16793 /* For polynomial encoding the U bit must be zero, and the size must
16794 be 8 (encoded as 0b00) or, on ARMv8 or later 64 (encoded, non
16795 obviously, as 0b10). */
16796 if (et.size == 64)
16797 {
16798 /* Check we're on the correct architecture. */
16799 if (!mark_feature_used (&fpu_crypto_ext_armv8))
16800 inst.error =
16801 _("Instruction form not available on this architecture.");
16802
16803 et.size = 32;
16804 }
16805
5287ad62
JB
16806 neon_mixed_length (et, et.size);
16807 }
16808}
16809
16810static void
16811do_neon_ext (void)
16812{
037e8744 16813 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
5287ad62
JB
16814 struct neon_type_el et = neon_check_type (3, rs,
16815 N_EQK, N_EQK, N_8 | N_16 | N_32 | N_64 | N_KEY);
16816 unsigned imm = (inst.operands[3].imm * et.size) / 8;
35997600
NC
16817
16818 constraint (imm >= (unsigned) (neon_quad (rs) ? 16 : 8),
16819 _("shift out of range"));
5287ad62
JB
16820 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16821 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16822 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16823 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16824 inst.instruction |= LOW4 (inst.operands[2].reg);
16825 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
037e8744 16826 inst.instruction |= neon_quad (rs) << 6;
5287ad62 16827 inst.instruction |= imm << 8;
5f4273c7 16828
88714cb8 16829 neon_dp_fixup (&inst);
5287ad62
JB
16830}
16831
16832static void
16833do_neon_rev (void)
16834{
037e8744 16835 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
16836 struct neon_type_el et = neon_check_type (2, rs,
16837 N_EQK, N_8 | N_16 | N_32 | N_KEY);
16838 unsigned op = (inst.instruction >> 7) & 3;
16839 /* N (width of reversed regions) is encoded as part of the bitmask. We
16840 extract it here to check the elements to be reversed are smaller.
16841 Otherwise we'd get a reserved instruction. */
16842 unsigned elsize = (op == 2) ? 16 : (op == 1) ? 32 : (op == 0) ? 64 : 0;
9c2799c2 16843 gas_assert (elsize != 0);
5287ad62 16844 constraint (et.size >= elsize,
477330fc 16845 _("elements must be smaller than reversal region"));
037e8744 16846 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
16847}
16848
16849static void
16850do_neon_dup (void)
16851{
16852 if (inst.operands[1].isscalar)
16853 {
037e8744 16854 enum neon_shape rs = neon_select_shape (NS_DS, NS_QS, NS_NULL);
dcbf9037 16855 struct neon_type_el et = neon_check_type (2, rs,
477330fc 16856 N_EQK, N_8 | N_16 | N_32 | N_KEY);
5287ad62 16857 unsigned sizebits = et.size >> 3;
dcbf9037 16858 unsigned dm = NEON_SCALAR_REG (inst.operands[1].reg);
5287ad62 16859 int logsize = neon_logbits (et.size);
dcbf9037 16860 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg) << logsize;
037e8744
JB
16861
16862 if (vfp_or_neon_is_neon (NEON_CHECK_CC) == FAIL)
477330fc 16863 return;
037e8744 16864
88714cb8 16865 NEON_ENCODE (SCALAR, inst);
5287ad62
JB
16866 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16867 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16868 inst.instruction |= LOW4 (dm);
16869 inst.instruction |= HI1 (dm) << 5;
037e8744 16870 inst.instruction |= neon_quad (rs) << 6;
5287ad62
JB
16871 inst.instruction |= x << 17;
16872 inst.instruction |= sizebits << 16;
5f4273c7 16873
88714cb8 16874 neon_dp_fixup (&inst);
5287ad62
JB
16875 }
16876 else
16877 {
037e8744
JB
16878 enum neon_shape rs = neon_select_shape (NS_DR, NS_QR, NS_NULL);
16879 struct neon_type_el et = neon_check_type (2, rs,
477330fc 16880 N_8 | N_16 | N_32 | N_KEY, N_EQK);
5287ad62 16881 /* Duplicate ARM register to lanes of vector. */
88714cb8 16882 NEON_ENCODE (ARMREG, inst);
5287ad62 16883 switch (et.size)
477330fc
RM
16884 {
16885 case 8: inst.instruction |= 0x400000; break;
16886 case 16: inst.instruction |= 0x000020; break;
16887 case 32: inst.instruction |= 0x000000; break;
16888 default: break;
16889 }
5287ad62
JB
16890 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
16891 inst.instruction |= LOW4 (inst.operands[0].reg) << 16;
16892 inst.instruction |= HI1 (inst.operands[0].reg) << 7;
037e8744 16893 inst.instruction |= neon_quad (rs) << 21;
5287ad62 16894 /* The encoding for this instruction is identical for the ARM and Thumb
477330fc 16895 variants, except for the condition field. */
037e8744 16896 do_vfp_cond_or_thumb ();
5287ad62
JB
16897 }
16898}
16899
16900/* VMOV has particularly many variations. It can be one of:
16901 0. VMOV<c><q> <Qd>, <Qm>
16902 1. VMOV<c><q> <Dd>, <Dm>
16903 (Register operations, which are VORR with Rm = Rn.)
16904 2. VMOV<c><q>.<dt> <Qd>, #<imm>
16905 3. VMOV<c><q>.<dt> <Dd>, #<imm>
16906 (Immediate loads.)
16907 4. VMOV<c><q>.<size> <Dn[x]>, <Rd>
16908 (ARM register to scalar.)
16909 5. VMOV<c><q> <Dm>, <Rd>, <Rn>
16910 (Two ARM registers to vector.)
16911 6. VMOV<c><q>.<dt> <Rd>, <Dn[x]>
16912 (Scalar to ARM register.)
16913 7. VMOV<c><q> <Rd>, <Rn>, <Dm>
16914 (Vector to two ARM registers.)
037e8744
JB
16915 8. VMOV.F32 <Sd>, <Sm>
16916 9. VMOV.F64 <Dd>, <Dm>
16917 (VFP register moves.)
16918 10. VMOV.F32 <Sd>, #imm
16919 11. VMOV.F64 <Dd>, #imm
16920 (VFP float immediate load.)
16921 12. VMOV <Rd>, <Sm>
16922 (VFP single to ARM reg.)
16923 13. VMOV <Sd>, <Rm>
16924 (ARM reg to VFP single.)
16925 14. VMOV <Rd>, <Re>, <Sn>, <Sm>
16926 (Two ARM regs to two VFP singles.)
16927 15. VMOV <Sd>, <Se>, <Rn>, <Rm>
16928 (Two VFP singles to two ARM regs.)
5f4273c7 16929
037e8744
JB
16930 These cases can be disambiguated using neon_select_shape, except cases 1/9
16931 and 3/11 which depend on the operand type too.
5f4273c7 16932
5287ad62 16933 All the encoded bits are hardcoded by this function.
5f4273c7 16934
b7fc2769
JB
16935 Cases 4, 6 may be used with VFPv1 and above (only 32-bit transfers!).
16936 Cases 5, 7 may be used with VFPv2 and above.
5f4273c7 16937
5287ad62 16938 FIXME: Some of the checking may be a bit sloppy (in a couple of cases you
5f4273c7 16939 can specify a type where it doesn't make sense to, and is ignored). */
5287ad62
JB
16940
16941static void
16942do_neon_mov (void)
16943{
037e8744 16944 enum neon_shape rs = neon_select_shape (NS_RRFF, NS_FFRR, NS_DRR, NS_RRD,
9db2f6b4
RL
16945 NS_QQ, NS_DD, NS_QI, NS_DI, NS_SR,
16946 NS_RS, NS_FF, NS_FI, NS_RF, NS_FR,
16947 NS_HR, NS_RH, NS_HI, NS_NULL);
037e8744
JB
16948 struct neon_type_el et;
16949 const char *ldconst = 0;
5287ad62 16950
037e8744 16951 switch (rs)
5287ad62 16952 {
037e8744
JB
16953 case NS_DD: /* case 1/9. */
16954 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
16955 /* It is not an error here if no type is given. */
16956 inst.error = NULL;
16957 if (et.type == NT_float && et.size == 64)
477330fc
RM
16958 {
16959 do_vfp_nsyn_opcode ("fcpyd");
16960 break;
16961 }
037e8744 16962 /* fall through. */
5287ad62 16963
037e8744
JB
16964 case NS_QQ: /* case 0/1. */
16965 {
477330fc
RM
16966 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
16967 return;
16968 /* The architecture manual I have doesn't explicitly state which
16969 value the U bit should have for register->register moves, but
16970 the equivalent VORR instruction has U = 0, so do that. */
16971 inst.instruction = 0x0200110;
16972 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
16973 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
16974 inst.instruction |= LOW4 (inst.operands[1].reg);
16975 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
16976 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
16977 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
16978 inst.instruction |= neon_quad (rs) << 6;
16979
16980 neon_dp_fixup (&inst);
037e8744
JB
16981 }
16982 break;
5f4273c7 16983
037e8744
JB
16984 case NS_DI: /* case 3/11. */
16985 et = neon_check_type (2, rs, N_EQK, N_F64 | N_KEY);
16986 inst.error = NULL;
16987 if (et.type == NT_float && et.size == 64)
477330fc
RM
16988 {
16989 /* case 11 (fconstd). */
16990 ldconst = "fconstd";
16991 goto encode_fconstd;
16992 }
037e8744
JB
16993 /* fall through. */
16994
16995 case NS_QI: /* case 2/3. */
16996 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH) == FAIL)
477330fc 16997 return;
037e8744
JB
16998 inst.instruction = 0x0800010;
16999 neon_move_immediate ();
88714cb8 17000 neon_dp_fixup (&inst);
5287ad62 17001 break;
5f4273c7 17002
037e8744
JB
17003 case NS_SR: /* case 4. */
17004 {
477330fc
RM
17005 unsigned bcdebits = 0;
17006 int logsize;
17007 unsigned dn = NEON_SCALAR_REG (inst.operands[0].reg);
17008 unsigned x = NEON_SCALAR_INDEX (inst.operands[0].reg);
037e8744 17009
05ac0ffb
JB
17010 /* .<size> is optional here, defaulting to .32. */
17011 if (inst.vectype.elems == 0
17012 && inst.operands[0].vectype.type == NT_invtype
17013 && inst.operands[1].vectype.type == NT_invtype)
17014 {
17015 inst.vectype.el[0].type = NT_untyped;
17016 inst.vectype.el[0].size = 32;
17017 inst.vectype.elems = 1;
17018 }
17019
477330fc
RM
17020 et = neon_check_type (2, NS_NULL, N_8 | N_16 | N_32 | N_KEY, N_EQK);
17021 logsize = neon_logbits (et.size);
17022
17023 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1),
17024 _(BAD_FPU));
17025 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1)
17026 && et.size != 32, _(BAD_FPU));
17027 constraint (et.type == NT_invtype, _("bad type for scalar"));
17028 constraint (x >= 64 / et.size, _("scalar index out of range"));
17029
17030 switch (et.size)
17031 {
17032 case 8: bcdebits = 0x8; break;
17033 case 16: bcdebits = 0x1; break;
17034 case 32: bcdebits = 0x0; break;
17035 default: ;
17036 }
17037
17038 bcdebits |= x << logsize;
17039
17040 inst.instruction = 0xe000b10;
17041 do_vfp_cond_or_thumb ();
17042 inst.instruction |= LOW4 (dn) << 16;
17043 inst.instruction |= HI1 (dn) << 7;
17044 inst.instruction |= inst.operands[1].reg << 12;
17045 inst.instruction |= (bcdebits & 3) << 5;
17046 inst.instruction |= (bcdebits >> 2) << 21;
037e8744
JB
17047 }
17048 break;
5f4273c7 17049
037e8744 17050 case NS_DRR: /* case 5 (fmdrr). */
b7fc2769 17051 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2),
477330fc 17052 _(BAD_FPU));
b7fc2769 17053
037e8744
JB
17054 inst.instruction = 0xc400b10;
17055 do_vfp_cond_or_thumb ();
17056 inst.instruction |= LOW4 (inst.operands[0].reg);
17057 inst.instruction |= HI1 (inst.operands[0].reg) << 5;
17058 inst.instruction |= inst.operands[1].reg << 12;
17059 inst.instruction |= inst.operands[2].reg << 16;
17060 break;
5f4273c7 17061
037e8744
JB
17062 case NS_RS: /* case 6. */
17063 {
477330fc
RM
17064 unsigned logsize;
17065 unsigned dn = NEON_SCALAR_REG (inst.operands[1].reg);
17066 unsigned x = NEON_SCALAR_INDEX (inst.operands[1].reg);
17067 unsigned abcdebits = 0;
037e8744 17068
05ac0ffb
JB
17069 /* .<dt> is optional here, defaulting to .32. */
17070 if (inst.vectype.elems == 0
17071 && inst.operands[0].vectype.type == NT_invtype
17072 && inst.operands[1].vectype.type == NT_invtype)
17073 {
17074 inst.vectype.el[0].type = NT_untyped;
17075 inst.vectype.el[0].size = 32;
17076 inst.vectype.elems = 1;
17077 }
17078
91d6fa6a
NC
17079 et = neon_check_type (2, NS_NULL,
17080 N_EQK, N_S8 | N_S16 | N_U8 | N_U16 | N_32 | N_KEY);
477330fc
RM
17081 logsize = neon_logbits (et.size);
17082
17083 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v1),
17084 _(BAD_FPU));
17085 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_v1)
17086 && et.size != 32, _(BAD_FPU));
17087 constraint (et.type == NT_invtype, _("bad type for scalar"));
17088 constraint (x >= 64 / et.size, _("scalar index out of range"));
17089
17090 switch (et.size)
17091 {
17092 case 8: abcdebits = (et.type == NT_signed) ? 0x08 : 0x18; break;
17093 case 16: abcdebits = (et.type == NT_signed) ? 0x01 : 0x11; break;
17094 case 32: abcdebits = 0x00; break;
17095 default: ;
17096 }
17097
17098 abcdebits |= x << logsize;
17099 inst.instruction = 0xe100b10;
17100 do_vfp_cond_or_thumb ();
17101 inst.instruction |= LOW4 (dn) << 16;
17102 inst.instruction |= HI1 (dn) << 7;
17103 inst.instruction |= inst.operands[0].reg << 12;
17104 inst.instruction |= (abcdebits & 3) << 5;
17105 inst.instruction |= (abcdebits >> 2) << 21;
037e8744
JB
17106 }
17107 break;
5f4273c7 17108
037e8744
JB
17109 case NS_RRD: /* case 7 (fmrrd). */
17110 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_v2),
477330fc 17111 _(BAD_FPU));
037e8744
JB
17112
17113 inst.instruction = 0xc500b10;
17114 do_vfp_cond_or_thumb ();
17115 inst.instruction |= inst.operands[0].reg << 12;
17116 inst.instruction |= inst.operands[1].reg << 16;
17117 inst.instruction |= LOW4 (inst.operands[2].reg);
17118 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
17119 break;
5f4273c7 17120
037e8744
JB
17121 case NS_FF: /* case 8 (fcpys). */
17122 do_vfp_nsyn_opcode ("fcpys");
17123 break;
5f4273c7 17124
9db2f6b4 17125 case NS_HI:
037e8744
JB
17126 case NS_FI: /* case 10 (fconsts). */
17127 ldconst = "fconsts";
4ef4710f 17128 encode_fconstd:
58ed5c38
TC
17129 if (!inst.operands[1].immisfloat)
17130 {
4ef4710f 17131 unsigned new_imm;
58ed5c38 17132 /* Immediate has to fit in 8 bits so float is enough. */
4ef4710f
NC
17133 float imm = (float) inst.operands[1].imm;
17134 memcpy (&new_imm, &imm, sizeof (float));
17135 /* But the assembly may have been written to provide an integer
17136 bit pattern that equates to a float, so check that the
17137 conversion has worked. */
17138 if (is_quarter_float (new_imm))
17139 {
17140 if (is_quarter_float (inst.operands[1].imm))
17141 as_warn (_("immediate constant is valid both as a bit-pattern and a floating point value (using the fp value)"));
17142
17143 inst.operands[1].imm = new_imm;
17144 inst.operands[1].immisfloat = 1;
17145 }
58ed5c38
TC
17146 }
17147
037e8744 17148 if (is_quarter_float (inst.operands[1].imm))
477330fc
RM
17149 {
17150 inst.operands[1].imm = neon_qfloat_bits (inst.operands[1].imm);
17151 do_vfp_nsyn_opcode (ldconst);
9db2f6b4
RL
17152
17153 /* ARMv8.2 fp16 vmov.f16 instruction. */
17154 if (rs == NS_HI)
17155 do_scalar_fp16_v82_encode ();
477330fc 17156 }
5287ad62 17157 else
477330fc 17158 first_error (_("immediate out of range"));
037e8744 17159 break;
5f4273c7 17160
9db2f6b4 17161 case NS_RH:
037e8744
JB
17162 case NS_RF: /* case 12 (fmrs). */
17163 do_vfp_nsyn_opcode ("fmrs");
9db2f6b4
RL
17164 /* ARMv8.2 fp16 vmov.f16 instruction. */
17165 if (rs == NS_RH)
17166 do_scalar_fp16_v82_encode ();
037e8744 17167 break;
5f4273c7 17168
9db2f6b4 17169 case NS_HR:
037e8744
JB
17170 case NS_FR: /* case 13 (fmsr). */
17171 do_vfp_nsyn_opcode ("fmsr");
9db2f6b4
RL
17172 /* ARMv8.2 fp16 vmov.f16 instruction. */
17173 if (rs == NS_HR)
17174 do_scalar_fp16_v82_encode ();
037e8744 17175 break;
5f4273c7 17176
037e8744
JB
17177 /* The encoders for the fmrrs and fmsrr instructions expect three operands
17178 (one of which is a list), but we have parsed four. Do some fiddling to
17179 make the operands what do_vfp_reg2_from_sp2 and do_vfp_sp2_from_reg2
17180 expect. */
17181 case NS_RRFF: /* case 14 (fmrrs). */
17182 constraint (inst.operands[3].reg != inst.operands[2].reg + 1,
477330fc 17183 _("VFP registers must be adjacent"));
037e8744
JB
17184 inst.operands[2].imm = 2;
17185 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
17186 do_vfp_nsyn_opcode ("fmrrs");
17187 break;
5f4273c7 17188
037e8744
JB
17189 case NS_FFRR: /* case 15 (fmsrr). */
17190 constraint (inst.operands[1].reg != inst.operands[0].reg + 1,
477330fc 17191 _("VFP registers must be adjacent"));
037e8744
JB
17192 inst.operands[1] = inst.operands[2];
17193 inst.operands[2] = inst.operands[3];
17194 inst.operands[0].imm = 2;
17195 memset (&inst.operands[3], '\0', sizeof (inst.operands[3]));
17196 do_vfp_nsyn_opcode ("fmsrr");
5287ad62 17197 break;
5f4273c7 17198
4c261dff
NC
17199 case NS_NULL:
17200 /* neon_select_shape has determined that the instruction
17201 shape is wrong and has already set the error message. */
17202 break;
17203
5287ad62
JB
17204 default:
17205 abort ();
17206 }
17207}
17208
17209static void
17210do_neon_rshift_round_imm (void)
17211{
037e8744 17212 enum neon_shape rs = neon_select_shape (NS_DDI, NS_QQI, NS_NULL);
5287ad62
JB
17213 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_ALL | N_KEY);
17214 int imm = inst.operands[2].imm;
17215
17216 /* imm == 0 case is encoded as VMOV for V{R}SHR. */
17217 if (imm == 0)
17218 {
17219 inst.operands[2].present = 0;
17220 do_neon_mov ();
17221 return;
17222 }
17223
17224 constraint (imm < 1 || (unsigned)imm > et.size,
477330fc 17225 _("immediate out of range for shift"));
037e8744 17226 neon_imm_shift (TRUE, et.type == NT_unsigned, neon_quad (rs), et,
477330fc 17227 et.size - imm);
5287ad62
JB
17228}
17229
9db2f6b4
RL
17230static void
17231do_neon_movhf (void)
17232{
17233 enum neon_shape rs = neon_select_shape (NS_HH, NS_NULL);
17234 constraint (rs != NS_HH, _("invalid suffix"));
17235
7bdf778b
ASDV
17236 if (inst.cond != COND_ALWAYS)
17237 {
17238 if (thumb_mode)
17239 {
17240 as_warn (_("ARMv8.2 scalar fp16 instruction cannot be conditional,"
17241 " the behaviour is UNPREDICTABLE"));
17242 }
17243 else
17244 {
17245 inst.error = BAD_COND;
17246 return;
17247 }
17248 }
17249
9db2f6b4
RL
17250 do_vfp_sp_monadic ();
17251
17252 inst.is_neon = 1;
17253 inst.instruction |= 0xf0000000;
17254}
17255
5287ad62
JB
17256static void
17257do_neon_movl (void)
17258{
17259 struct neon_type_el et = neon_check_type (2, NS_QD,
17260 N_EQK | N_DBL, N_SU_32 | N_KEY);
17261 unsigned sizebits = et.size >> 3;
17262 inst.instruction |= sizebits << 19;
17263 neon_two_same (0, et.type == NT_unsigned, -1);
17264}
17265
17266static void
17267do_neon_trn (void)
17268{
037e8744 17269 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17270 struct neon_type_el et = neon_check_type (2, rs,
17271 N_EQK, N_8 | N_16 | N_32 | N_KEY);
88714cb8 17272 NEON_ENCODE (INTEGER, inst);
037e8744 17273 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17274}
17275
17276static void
17277do_neon_zip_uzp (void)
17278{
037e8744 17279 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17280 struct neon_type_el et = neon_check_type (2, rs,
17281 N_EQK, N_8 | N_16 | N_32 | N_KEY);
17282 if (rs == NS_DD && et.size == 32)
17283 {
17284 /* Special case: encode as VTRN.32 <Dd>, <Dm>. */
17285 inst.instruction = N_MNEM_vtrn;
17286 do_neon_trn ();
17287 return;
17288 }
037e8744 17289 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17290}
17291
17292static void
17293do_neon_sat_abs_neg (void)
17294{
037e8744 17295 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17296 struct neon_type_el et = neon_check_type (2, rs,
17297 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 17298 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17299}
17300
17301static void
17302do_neon_pair_long (void)
17303{
037e8744 17304 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17305 struct neon_type_el et = neon_check_type (2, rs, N_EQK, N_SU_32 | N_KEY);
17306 /* Unsigned is encoded in OP field (bit 7) for these instruction. */
17307 inst.instruction |= (et.type == NT_unsigned) << 7;
037e8744 17308 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17309}
17310
17311static void
17312do_neon_recip_est (void)
17313{
037e8744 17314 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62 17315 struct neon_type_el et = neon_check_type (2, rs,
cc933301 17316 N_EQK | N_FLT, N_F_16_32 | N_U32 | N_KEY);
5287ad62 17317 inst.instruction |= (et.type == NT_float) << 8;
037e8744 17318 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17319}
17320
17321static void
17322do_neon_cls (void)
17323{
037e8744 17324 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17325 struct neon_type_el et = neon_check_type (2, rs,
17326 N_EQK, N_S8 | N_S16 | N_S32 | N_KEY);
037e8744 17327 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17328}
17329
17330static void
17331do_neon_clz (void)
17332{
037e8744 17333 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17334 struct neon_type_el et = neon_check_type (2, rs,
17335 N_EQK, N_I8 | N_I16 | N_I32 | N_KEY);
037e8744 17336 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17337}
17338
17339static void
17340do_neon_cnt (void)
17341{
037e8744 17342 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
5287ad62
JB
17343 struct neon_type_el et = neon_check_type (2, rs,
17344 N_EQK | N_INT, N_8 | N_KEY);
037e8744 17345 neon_two_same (neon_quad (rs), 1, et.size);
5287ad62
JB
17346}
17347
17348static void
17349do_neon_swp (void)
17350{
037e8744
JB
17351 enum neon_shape rs = neon_select_shape (NS_DD, NS_QQ, NS_NULL);
17352 neon_two_same (neon_quad (rs), 1, -1);
5287ad62
JB
17353}
17354
17355static void
17356do_neon_tbl_tbx (void)
17357{
17358 unsigned listlenbits;
dcbf9037 17359 neon_check_type (3, NS_DLD, N_EQK, N_EQK, N_8 | N_KEY);
5f4273c7 17360
5287ad62
JB
17361 if (inst.operands[1].imm < 1 || inst.operands[1].imm > 4)
17362 {
dcbf9037 17363 first_error (_("bad list length for table lookup"));
5287ad62
JB
17364 return;
17365 }
5f4273c7 17366
5287ad62
JB
17367 listlenbits = inst.operands[1].imm - 1;
17368 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17369 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17370 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
17371 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
17372 inst.instruction |= LOW4 (inst.operands[2].reg);
17373 inst.instruction |= HI1 (inst.operands[2].reg) << 5;
17374 inst.instruction |= listlenbits << 8;
5f4273c7 17375
88714cb8 17376 neon_dp_fixup (&inst);
5287ad62
JB
17377}
17378
17379static void
17380do_neon_ldm_stm (void)
17381{
17382 /* P, U and L bits are part of bitmask. */
17383 int is_dbmode = (inst.instruction & (1 << 24)) != 0;
17384 unsigned offsetbits = inst.operands[1].imm * 2;
17385
037e8744
JB
17386 if (inst.operands[1].issingle)
17387 {
17388 do_vfp_nsyn_ldm_stm (is_dbmode);
17389 return;
17390 }
17391
5287ad62 17392 constraint (is_dbmode && !inst.operands[0].writeback,
477330fc 17393 _("writeback (!) must be used for VLDMDB and VSTMDB"));
5287ad62
JB
17394
17395 constraint (inst.operands[1].imm < 1 || inst.operands[1].imm > 16,
477330fc
RM
17396 _("register list must contain at least 1 and at most 16 "
17397 "registers"));
5287ad62
JB
17398
17399 inst.instruction |= inst.operands[0].reg << 16;
17400 inst.instruction |= inst.operands[0].writeback << 21;
17401 inst.instruction |= LOW4 (inst.operands[1].reg) << 12;
17402 inst.instruction |= HI1 (inst.operands[1].reg) << 22;
17403
17404 inst.instruction |= offsetbits;
5f4273c7 17405
037e8744 17406 do_vfp_cond_or_thumb ();
5287ad62
JB
17407}
17408
17409static void
17410do_neon_ldr_str (void)
17411{
5287ad62 17412 int is_ldr = (inst.instruction & (1 << 20)) != 0;
5f4273c7 17413
6844b2c2
MGD
17414 /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
17415 And is UNPREDICTABLE in thumb mode. */
fa94de6b 17416 if (!is_ldr
6844b2c2 17417 && inst.operands[1].reg == REG_PC
ba86b375 17418 && (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7) || thumb_mode))
6844b2c2 17419 {
94dcf8bf 17420 if (thumb_mode)
6844b2c2 17421 inst.error = _("Use of PC here is UNPREDICTABLE");
94dcf8bf 17422 else if (warn_on_deprecated)
5c3696f8 17423 as_tsktsk (_("Use of PC here is deprecated"));
6844b2c2
MGD
17424 }
17425
037e8744
JB
17426 if (inst.operands[0].issingle)
17427 {
cd2f129f 17428 if (is_ldr)
477330fc 17429 do_vfp_nsyn_opcode ("flds");
cd2f129f 17430 else
477330fc 17431 do_vfp_nsyn_opcode ("fsts");
9db2f6b4
RL
17432
17433 /* ARMv8.2 vldr.16/vstr.16 instruction. */
17434 if (inst.vectype.el[0].size == 16)
17435 do_scalar_fp16_v82_encode ();
5287ad62
JB
17436 }
17437 else
5287ad62 17438 {
cd2f129f 17439 if (is_ldr)
477330fc 17440 do_vfp_nsyn_opcode ("fldd");
5287ad62 17441 else
477330fc 17442 do_vfp_nsyn_opcode ("fstd");
5287ad62 17443 }
5287ad62
JB
17444}
17445
32c36c3c
AV
17446static void
17447do_t_vldr_vstr_sysreg (void)
17448{
17449 int fp_vldr_bitno = 20, sysreg_vldr_bitno = 20;
17450 bfd_boolean is_vldr = ((inst.instruction & (1 << fp_vldr_bitno)) != 0);
17451
17452 /* Use of PC is UNPREDICTABLE. */
17453 if (inst.operands[1].reg == REG_PC)
17454 inst.error = _("Use of PC here is UNPREDICTABLE");
17455
17456 if (inst.operands[1].immisreg)
17457 inst.error = _("instruction does not accept register index");
17458
17459 if (!inst.operands[1].isreg)
17460 inst.error = _("instruction does not accept PC-relative addressing");
17461
17462 if (abs (inst.operands[1].imm) >= (1 << 7))
17463 inst.error = _("immediate value out of range");
17464
17465 inst.instruction = 0xec000f80;
17466 if (is_vldr)
17467 inst.instruction |= 1 << sysreg_vldr_bitno;
17468 encode_arm_cp_address (1, TRUE, FALSE, BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM);
17469 inst.instruction |= (inst.operands[0].imm & 0x7) << 13;
17470 inst.instruction |= (inst.operands[0].imm & 0x8) << 19;
17471}
17472
17473static void
17474do_vldr_vstr (void)
17475{
17476 bfd_boolean sysreg_op = !inst.operands[0].isreg;
17477
17478 /* VLDR/VSTR (System Register). */
17479 if (sysreg_op)
17480 {
17481 if (!mark_feature_used (&arm_ext_v8_1m_main))
17482 as_bad (_("Instruction not permitted on this architecture"));
17483
17484 do_t_vldr_vstr_sysreg ();
17485 }
17486 /* VLDR/VSTR. */
17487 else
17488 {
17489 if (!mark_feature_used (&fpu_vfp_ext_v1xd))
17490 as_bad (_("Instruction not permitted on this architecture"));
17491 do_neon_ldr_str ();
17492 }
17493}
17494
5287ad62
JB
17495/* "interleave" version also handles non-interleaving register VLD1/VST1
17496 instructions. */
17497
17498static void
17499do_neon_ld_st_interleave (void)
17500{
037e8744 17501 struct neon_type_el et = neon_check_type (1, NS_NULL,
477330fc 17502 N_8 | N_16 | N_32 | N_64);
5287ad62
JB
17503 unsigned alignbits = 0;
17504 unsigned idx;
17505 /* The bits in this table go:
17506 0: register stride of one (0) or two (1)
17507 1,2: register list length, minus one (1, 2, 3, 4).
17508 3,4: <n> in instruction type, minus one (VLD<n> / VST<n>).
17509 We use -1 for invalid entries. */
17510 const int typetable[] =
17511 {
17512 0x7, -1, 0xa, -1, 0x6, -1, 0x2, -1, /* VLD1 / VST1. */
17513 -1, -1, 0x8, 0x9, -1, -1, 0x3, -1, /* VLD2 / VST2. */
17514 -1, -1, -1, -1, 0x4, 0x5, -1, -1, /* VLD3 / VST3. */
17515 -1, -1, -1, -1, -1, -1, 0x0, 0x1 /* VLD4 / VST4. */
17516 };
17517 int typebits;
17518
dcbf9037
JB
17519 if (et.type == NT_invtype)
17520 return;
17521
5287ad62
JB
17522 if (inst.operands[1].immisalign)
17523 switch (inst.operands[1].imm >> 8)
17524 {
17525 case 64: alignbits = 1; break;
17526 case 128:
477330fc 17527 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2
e23c0ad8 17528 && NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
477330fc
RM
17529 goto bad_alignment;
17530 alignbits = 2;
17531 break;
5287ad62 17532 case 256:
477330fc
RM
17533 if (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4)
17534 goto bad_alignment;
17535 alignbits = 3;
17536 break;
5287ad62
JB
17537 default:
17538 bad_alignment:
477330fc
RM
17539 first_error (_("bad alignment"));
17540 return;
5287ad62
JB
17541 }
17542
17543 inst.instruction |= alignbits << 4;
17544 inst.instruction |= neon_logbits (et.size) << 6;
17545
17546 /* Bits [4:6] of the immediate in a list specifier encode register stride
17547 (minus 1) in bit 4, and list length in bits [5:6]. We put the <n> of
17548 VLD<n>/VST<n> in bits [9:8] of the initial bitmask. Suck it out here, look
17549 up the right value for "type" in a table based on this value and the given
17550 list style, then stick it back. */
17551 idx = ((inst.operands[0].imm >> 4) & 7)
477330fc 17552 | (((inst.instruction >> 8) & 3) << 3);
5287ad62
JB
17553
17554 typebits = typetable[idx];
5f4273c7 17555
5287ad62 17556 constraint (typebits == -1, _("bad list type for instruction"));
1d50d57c
WN
17557 constraint (((inst.instruction >> 8) & 3) && et.size == 64,
17558 _("bad element type for instruction"));
5287ad62
JB
17559
17560 inst.instruction &= ~0xf00;
17561 inst.instruction |= typebits << 8;
17562}
17563
17564/* Check alignment is valid for do_neon_ld_st_lane and do_neon_ld_dup.
17565 *DO_ALIGN is set to 1 if the relevant alignment bit should be set, 0
17566 otherwise. The variable arguments are a list of pairs of legal (size, align)
17567 values, terminated with -1. */
17568
17569static int
aa8a0863 17570neon_alignment_bit (int size, int align, int *do_alignment, ...)
5287ad62
JB
17571{
17572 va_list ap;
17573 int result = FAIL, thissize, thisalign;
5f4273c7 17574
5287ad62
JB
17575 if (!inst.operands[1].immisalign)
17576 {
aa8a0863 17577 *do_alignment = 0;
5287ad62
JB
17578 return SUCCESS;
17579 }
5f4273c7 17580
aa8a0863 17581 va_start (ap, do_alignment);
5287ad62
JB
17582
17583 do
17584 {
17585 thissize = va_arg (ap, int);
17586 if (thissize == -1)
477330fc 17587 break;
5287ad62
JB
17588 thisalign = va_arg (ap, int);
17589
17590 if (size == thissize && align == thisalign)
477330fc 17591 result = SUCCESS;
5287ad62
JB
17592 }
17593 while (result != SUCCESS);
17594
17595 va_end (ap);
17596
17597 if (result == SUCCESS)
aa8a0863 17598 *do_alignment = 1;
5287ad62 17599 else
dcbf9037 17600 first_error (_("unsupported alignment for instruction"));
5f4273c7 17601
5287ad62
JB
17602 return result;
17603}
17604
17605static void
17606do_neon_ld_st_lane (void)
17607{
037e8744 17608 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 17609 int align_good, do_alignment = 0;
5287ad62
JB
17610 int logsize = neon_logbits (et.size);
17611 int align = inst.operands[1].imm >> 8;
17612 int n = (inst.instruction >> 8) & 3;
17613 int max_el = 64 / et.size;
5f4273c7 17614
dcbf9037
JB
17615 if (et.type == NT_invtype)
17616 return;
5f4273c7 17617
5287ad62 17618 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != n + 1,
477330fc 17619 _("bad list length"));
5287ad62 17620 constraint (NEON_LANE (inst.operands[0].imm) >= max_el,
477330fc 17621 _("scalar index out of range"));
5287ad62 17622 constraint (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2
477330fc
RM
17623 && et.size == 8,
17624 _("stride of 2 unavailable when element size is 8"));
5f4273c7 17625
5287ad62
JB
17626 switch (n)
17627 {
17628 case 0: /* VLD1 / VST1. */
aa8a0863 17629 align_good = neon_alignment_bit (et.size, align, &do_alignment, 16, 16,
477330fc 17630 32, 32, -1);
5287ad62 17631 if (align_good == FAIL)
477330fc 17632 return;
aa8a0863 17633 if (do_alignment)
477330fc
RM
17634 {
17635 unsigned alignbits = 0;
17636 switch (et.size)
17637 {
17638 case 16: alignbits = 0x1; break;
17639 case 32: alignbits = 0x3; break;
17640 default: ;
17641 }
17642 inst.instruction |= alignbits << 4;
17643 }
5287ad62
JB
17644 break;
17645
17646 case 1: /* VLD2 / VST2. */
aa8a0863
TS
17647 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 16,
17648 16, 32, 32, 64, -1);
5287ad62 17649 if (align_good == FAIL)
477330fc 17650 return;
aa8a0863 17651 if (do_alignment)
477330fc 17652 inst.instruction |= 1 << 4;
5287ad62
JB
17653 break;
17654
17655 case 2: /* VLD3 / VST3. */
17656 constraint (inst.operands[1].immisalign,
477330fc 17657 _("can't use alignment with this instruction"));
5287ad62
JB
17658 break;
17659
17660 case 3: /* VLD4 / VST4. */
aa8a0863 17661 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc 17662 16, 64, 32, 64, 32, 128, -1);
5287ad62 17663 if (align_good == FAIL)
477330fc 17664 return;
aa8a0863 17665 if (do_alignment)
477330fc
RM
17666 {
17667 unsigned alignbits = 0;
17668 switch (et.size)
17669 {
17670 case 8: alignbits = 0x1; break;
17671 case 16: alignbits = 0x1; break;
17672 case 32: alignbits = (align == 64) ? 0x1 : 0x2; break;
17673 default: ;
17674 }
17675 inst.instruction |= alignbits << 4;
17676 }
5287ad62
JB
17677 break;
17678
17679 default: ;
17680 }
17681
17682 /* Reg stride of 2 is encoded in bit 5 when size==16, bit 6 when size==32. */
17683 if (n != 0 && NEON_REG_STRIDE (inst.operands[0].imm) == 2)
17684 inst.instruction |= 1 << (4 + logsize);
5f4273c7 17685
5287ad62
JB
17686 inst.instruction |= NEON_LANE (inst.operands[0].imm) << (logsize + 5);
17687 inst.instruction |= logsize << 10;
17688}
17689
17690/* Encode single n-element structure to all lanes VLD<n> instructions. */
17691
17692static void
17693do_neon_ld_dup (void)
17694{
037e8744 17695 struct neon_type_el et = neon_check_type (1, NS_NULL, N_8 | N_16 | N_32);
aa8a0863 17696 int align_good, do_alignment = 0;
5287ad62 17697
dcbf9037
JB
17698 if (et.type == NT_invtype)
17699 return;
17700
5287ad62
JB
17701 switch ((inst.instruction >> 8) & 3)
17702 {
17703 case 0: /* VLD1. */
9c2799c2 17704 gas_assert (NEON_REG_STRIDE (inst.operands[0].imm) != 2);
5287ad62 17705 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863 17706 &do_alignment, 16, 16, 32, 32, -1);
5287ad62 17707 if (align_good == FAIL)
477330fc 17708 return;
5287ad62 17709 switch (NEON_REGLIST_LENGTH (inst.operands[0].imm))
477330fc
RM
17710 {
17711 case 1: break;
17712 case 2: inst.instruction |= 1 << 5; break;
17713 default: first_error (_("bad list length")); return;
17714 }
5287ad62
JB
17715 inst.instruction |= neon_logbits (et.size) << 6;
17716 break;
17717
17718 case 1: /* VLD2. */
17719 align_good = neon_alignment_bit (et.size, inst.operands[1].imm >> 8,
aa8a0863
TS
17720 &do_alignment, 8, 16, 16, 32, 32, 64,
17721 -1);
5287ad62 17722 if (align_good == FAIL)
477330fc 17723 return;
5287ad62 17724 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 2,
477330fc 17725 _("bad list length"));
5287ad62 17726 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 17727 inst.instruction |= 1 << 5;
5287ad62
JB
17728 inst.instruction |= neon_logbits (et.size) << 6;
17729 break;
17730
17731 case 2: /* VLD3. */
17732 constraint (inst.operands[1].immisalign,
477330fc 17733 _("can't use alignment with this instruction"));
5287ad62 17734 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 3,
477330fc 17735 _("bad list length"));
5287ad62 17736 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
477330fc 17737 inst.instruction |= 1 << 5;
5287ad62
JB
17738 inst.instruction |= neon_logbits (et.size) << 6;
17739 break;
17740
17741 case 3: /* VLD4. */
17742 {
477330fc 17743 int align = inst.operands[1].imm >> 8;
aa8a0863 17744 align_good = neon_alignment_bit (et.size, align, &do_alignment, 8, 32,
477330fc
RM
17745 16, 64, 32, 64, 32, 128, -1);
17746 if (align_good == FAIL)
17747 return;
17748 constraint (NEON_REGLIST_LENGTH (inst.operands[0].imm) != 4,
17749 _("bad list length"));
17750 if (NEON_REG_STRIDE (inst.operands[0].imm) == 2)
17751 inst.instruction |= 1 << 5;
17752 if (et.size == 32 && align == 128)
17753 inst.instruction |= 0x3 << 6;
17754 else
17755 inst.instruction |= neon_logbits (et.size) << 6;
5287ad62
JB
17756 }
17757 break;
17758
17759 default: ;
17760 }
17761
aa8a0863 17762 inst.instruction |= do_alignment << 4;
5287ad62
JB
17763}
17764
17765/* Disambiguate VLD<n> and VST<n> instructions, and fill in common bits (those
17766 apart from bits [11:4]. */
17767
17768static void
17769do_neon_ldx_stx (void)
17770{
b1a769ed
DG
17771 if (inst.operands[1].isreg)
17772 constraint (inst.operands[1].reg == REG_PC, BAD_PC);
17773
5287ad62
JB
17774 switch (NEON_LANE (inst.operands[0].imm))
17775 {
17776 case NEON_INTERLEAVE_LANES:
88714cb8 17777 NEON_ENCODE (INTERLV, inst);
5287ad62
JB
17778 do_neon_ld_st_interleave ();
17779 break;
5f4273c7 17780
5287ad62 17781 case NEON_ALL_LANES:
88714cb8 17782 NEON_ENCODE (DUP, inst);
2d51fb74
JB
17783 if (inst.instruction == N_INV)
17784 {
17785 first_error ("only loads support such operands");
17786 break;
17787 }
5287ad62
JB
17788 do_neon_ld_dup ();
17789 break;
5f4273c7 17790
5287ad62 17791 default:
88714cb8 17792 NEON_ENCODE (LANE, inst);
5287ad62
JB
17793 do_neon_ld_st_lane ();
17794 }
17795
17796 /* L bit comes from bit mask. */
17797 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17798 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17799 inst.instruction |= inst.operands[1].reg << 16;
5f4273c7 17800
5287ad62
JB
17801 if (inst.operands[1].postind)
17802 {
17803 int postreg = inst.operands[1].imm & 0xf;
17804 constraint (!inst.operands[1].immisreg,
477330fc 17805 _("post-index must be a register"));
5287ad62 17806 constraint (postreg == 0xd || postreg == 0xf,
477330fc 17807 _("bad register for post-index"));
5287ad62
JB
17808 inst.instruction |= postreg;
17809 }
4f2374c7 17810 else
5287ad62 17811 {
4f2374c7 17812 constraint (inst.operands[1].immisreg, BAD_ADDR_MODE);
e2b0ab59
AV
17813 constraint (inst.relocs[0].exp.X_op != O_constant
17814 || inst.relocs[0].exp.X_add_number != 0,
4f2374c7
WN
17815 BAD_ADDR_MODE);
17816
17817 if (inst.operands[1].writeback)
17818 {
17819 inst.instruction |= 0xd;
17820 }
17821 else
17822 inst.instruction |= 0xf;
5287ad62 17823 }
5f4273c7 17824
5287ad62
JB
17825 if (thumb_mode)
17826 inst.instruction |= 0xf9000000;
17827 else
17828 inst.instruction |= 0xf4000000;
17829}
33399f07
MGD
17830
17831/* FP v8. */
17832static void
17833do_vfp_nsyn_fpv8 (enum neon_shape rs)
17834{
a715796b
TG
17835 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
17836 D register operands. */
17837 if (neon_shape_class[rs] == SC_DOUBLE)
17838 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
17839 _(BAD_FPU));
17840
33399f07
MGD
17841 NEON_ENCODE (FPV8, inst);
17842
9db2f6b4
RL
17843 if (rs == NS_FFF || rs == NS_HHH)
17844 {
17845 do_vfp_sp_dyadic ();
17846
17847 /* ARMv8.2 fp16 instruction. */
17848 if (rs == NS_HHH)
17849 do_scalar_fp16_v82_encode ();
17850 }
33399f07
MGD
17851 else
17852 do_vfp_dp_rd_rn_rm ();
17853
17854 if (rs == NS_DDD)
17855 inst.instruction |= 0x100;
17856
17857 inst.instruction |= 0xf0000000;
17858}
17859
17860static void
17861do_vsel (void)
17862{
17863 set_it_insn_type (OUTSIDE_IT_INSN);
17864
17865 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) != SUCCESS)
17866 first_error (_("invalid instruction shape"));
17867}
17868
73924fbc
MGD
17869static void
17870do_vmaxnm (void)
17871{
17872 set_it_insn_type (OUTSIDE_IT_INSN);
17873
17874 if (try_vfp_nsyn (3, do_vfp_nsyn_fpv8) == SUCCESS)
17875 return;
17876
17877 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
17878 return;
17879
cc933301 17880 neon_dyadic_misc (NT_untyped, N_F_16_32, 0);
73924fbc
MGD
17881}
17882
30bdf752
MGD
17883static void
17884do_vrint_1 (enum neon_cvt_mode mode)
17885{
9db2f6b4 17886 enum neon_shape rs = neon_select_shape (NS_HH, NS_FF, NS_DD, NS_QQ, NS_NULL);
30bdf752
MGD
17887 struct neon_type_el et;
17888
17889 if (rs == NS_NULL)
17890 return;
17891
a715796b
TG
17892 /* Targets like FPv5-SP-D16 don't support FP v8 instructions with
17893 D register operands. */
17894 if (neon_shape_class[rs] == SC_DOUBLE)
17895 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
17896 _(BAD_FPU));
17897
9db2f6b4
RL
17898 et = neon_check_type (2, rs, N_EQK | N_VFP, N_F_ALL | N_KEY
17899 | N_VFP);
30bdf752
MGD
17900 if (et.type != NT_invtype)
17901 {
17902 /* VFP encodings. */
17903 if (mode == neon_cvt_mode_a || mode == neon_cvt_mode_n
17904 || mode == neon_cvt_mode_p || mode == neon_cvt_mode_m)
17905 set_it_insn_type (OUTSIDE_IT_INSN);
17906
17907 NEON_ENCODE (FPV8, inst);
9db2f6b4 17908 if (rs == NS_FF || rs == NS_HH)
30bdf752
MGD
17909 do_vfp_sp_monadic ();
17910 else
17911 do_vfp_dp_rd_rm ();
17912
17913 switch (mode)
17914 {
17915 case neon_cvt_mode_r: inst.instruction |= 0x00000000; break;
17916 case neon_cvt_mode_z: inst.instruction |= 0x00000080; break;
17917 case neon_cvt_mode_x: inst.instruction |= 0x00010000; break;
17918 case neon_cvt_mode_a: inst.instruction |= 0xf0000000; break;
17919 case neon_cvt_mode_n: inst.instruction |= 0xf0010000; break;
17920 case neon_cvt_mode_p: inst.instruction |= 0xf0020000; break;
17921 case neon_cvt_mode_m: inst.instruction |= 0xf0030000; break;
17922 default: abort ();
17923 }
17924
17925 inst.instruction |= (rs == NS_DD) << 8;
17926 do_vfp_cond_or_thumb ();
9db2f6b4
RL
17927
17928 /* ARMv8.2 fp16 vrint instruction. */
17929 if (rs == NS_HH)
17930 do_scalar_fp16_v82_encode ();
30bdf752
MGD
17931 }
17932 else
17933 {
17934 /* Neon encodings (or something broken...). */
17935 inst.error = NULL;
cc933301 17936 et = neon_check_type (2, rs, N_EQK, N_F_16_32 | N_KEY);
30bdf752
MGD
17937
17938 if (et.type == NT_invtype)
17939 return;
17940
17941 set_it_insn_type (OUTSIDE_IT_INSN);
17942 NEON_ENCODE (FLOAT, inst);
17943
17944 if (vfp_or_neon_is_neon (NEON_CHECK_CC | NEON_CHECK_ARCH8) == FAIL)
17945 return;
17946
17947 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
17948 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
17949 inst.instruction |= LOW4 (inst.operands[1].reg);
17950 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
17951 inst.instruction |= neon_quad (rs) << 6;
cc933301
JW
17952 /* Mask off the original size bits and reencode them. */
17953 inst.instruction = ((inst.instruction & 0xfff3ffff)
17954 | neon_logbits (et.size) << 18);
17955
30bdf752
MGD
17956 switch (mode)
17957 {
17958 case neon_cvt_mode_z: inst.instruction |= 3 << 7; break;
17959 case neon_cvt_mode_x: inst.instruction |= 1 << 7; break;
17960 case neon_cvt_mode_a: inst.instruction |= 2 << 7; break;
17961 case neon_cvt_mode_n: inst.instruction |= 0 << 7; break;
17962 case neon_cvt_mode_p: inst.instruction |= 7 << 7; break;
17963 case neon_cvt_mode_m: inst.instruction |= 5 << 7; break;
17964 case neon_cvt_mode_r: inst.error = _("invalid rounding mode"); break;
17965 default: abort ();
17966 }
17967
17968 if (thumb_mode)
17969 inst.instruction |= 0xfc000000;
17970 else
17971 inst.instruction |= 0xf0000000;
17972 }
17973}
17974
17975static void
17976do_vrintx (void)
17977{
17978 do_vrint_1 (neon_cvt_mode_x);
17979}
17980
17981static void
17982do_vrintz (void)
17983{
17984 do_vrint_1 (neon_cvt_mode_z);
17985}
17986
17987static void
17988do_vrintr (void)
17989{
17990 do_vrint_1 (neon_cvt_mode_r);
17991}
17992
17993static void
17994do_vrinta (void)
17995{
17996 do_vrint_1 (neon_cvt_mode_a);
17997}
17998
17999static void
18000do_vrintn (void)
18001{
18002 do_vrint_1 (neon_cvt_mode_n);
18003}
18004
18005static void
18006do_vrintp (void)
18007{
18008 do_vrint_1 (neon_cvt_mode_p);
18009}
18010
18011static void
18012do_vrintm (void)
18013{
18014 do_vrint_1 (neon_cvt_mode_m);
18015}
18016
c28eeff2
SN
18017static unsigned
18018neon_scalar_for_vcmla (unsigned opnd, unsigned elsize)
18019{
18020 unsigned regno = NEON_SCALAR_REG (opnd);
18021 unsigned elno = NEON_SCALAR_INDEX (opnd);
18022
18023 if (elsize == 16 && elno < 2 && regno < 16)
18024 return regno | (elno << 4);
18025 else if (elsize == 32 && elno == 0)
18026 return regno;
18027
18028 first_error (_("scalar out of range"));
18029 return 0;
18030}
18031
18032static void
18033do_vcmla (void)
18034{
18035 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
18036 _(BAD_FPU));
e2b0ab59
AV
18037 constraint (inst.relocs[0].exp.X_op != O_constant,
18038 _("expression too complex"));
18039 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
18040 constraint (rot != 0 && rot != 90 && rot != 180 && rot != 270,
18041 _("immediate out of range"));
18042 rot /= 90;
18043 if (inst.operands[2].isscalar)
18044 {
18045 enum neon_shape rs = neon_select_shape (NS_DDSI, NS_QQSI, NS_NULL);
18046 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
18047 N_KEY | N_F16 | N_F32).size;
18048 unsigned m = neon_scalar_for_vcmla (inst.operands[2].reg, size);
18049 inst.is_neon = 1;
18050 inst.instruction = 0xfe000800;
18051 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18052 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18053 inst.instruction |= LOW4 (inst.operands[1].reg) << 16;
18054 inst.instruction |= HI1 (inst.operands[1].reg) << 7;
18055 inst.instruction |= LOW4 (m);
18056 inst.instruction |= HI1 (m) << 5;
18057 inst.instruction |= neon_quad (rs) << 6;
18058 inst.instruction |= rot << 20;
18059 inst.instruction |= (size == 32) << 23;
18060 }
18061 else
18062 {
18063 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
18064 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
18065 N_KEY | N_F16 | N_F32).size;
18066 neon_three_same (neon_quad (rs), 0, -1);
18067 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
18068 inst.instruction |= 0xfc200800;
18069 inst.instruction |= rot << 23;
18070 inst.instruction |= (size == 32) << 20;
18071 }
18072}
18073
18074static void
18075do_vcadd (void)
18076{
18077 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
18078 _(BAD_FPU));
e2b0ab59
AV
18079 constraint (inst.relocs[0].exp.X_op != O_constant,
18080 _("expression too complex"));
18081 unsigned rot = inst.relocs[0].exp.X_add_number;
c28eeff2
SN
18082 constraint (rot != 90 && rot != 270, _("immediate out of range"));
18083 enum neon_shape rs = neon_select_shape (NS_DDDI, NS_QQQI, NS_NULL);
18084 unsigned size = neon_check_type (3, rs, N_EQK, N_EQK,
18085 N_KEY | N_F16 | N_F32).size;
18086 neon_three_same (neon_quad (rs), 0, -1);
18087 inst.instruction &= 0x00ffffff; /* Undo neon_dp_fixup. */
18088 inst.instruction |= 0xfc800800;
18089 inst.instruction |= (rot == 270) << 24;
18090 inst.instruction |= (size == 32) << 20;
18091}
18092
c604a79a
JW
18093/* Dot Product instructions encoding support. */
18094
18095static void
18096do_neon_dotproduct (int unsigned_p)
18097{
18098 enum neon_shape rs;
18099 unsigned scalar_oprd2 = 0;
18100 int high8;
18101
18102 if (inst.cond != COND_ALWAYS)
18103 as_warn (_("Dot Product instructions cannot be conditional, the behaviour "
18104 "is UNPREDICTABLE"));
18105
18106 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_neon_ext_armv8),
18107 _(BAD_FPU));
18108
18109 /* Dot Product instructions are in three-same D/Q register format or the third
18110 operand can be a scalar index register. */
18111 if (inst.operands[2].isscalar)
18112 {
18113 scalar_oprd2 = neon_scalar_for_mul (inst.operands[2].reg, 32);
18114 high8 = 0xfe000000;
18115 rs = neon_select_shape (NS_DDS, NS_QQS, NS_NULL);
18116 }
18117 else
18118 {
18119 high8 = 0xfc000000;
18120 rs = neon_select_shape (NS_DDD, NS_QQQ, NS_NULL);
18121 }
18122
18123 if (unsigned_p)
18124 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_U8);
18125 else
18126 neon_check_type (3, rs, N_EQK, N_EQK, N_KEY | N_S8);
18127
18128 /* The "U" bit in traditional Three Same encoding is fixed to 0 for Dot
18129 Product instruction, so we pass 0 as the "ubit" parameter. And the
18130 "Size" field are fixed to 0x2, so we pass 32 as the "size" parameter. */
18131 neon_three_same (neon_quad (rs), 0, 32);
18132
18133 /* Undo neon_dp_fixup. Dot Product instructions are using a slightly
18134 different NEON three-same encoding. */
18135 inst.instruction &= 0x00ffffff;
18136 inst.instruction |= high8;
18137 /* Encode 'U' bit which indicates signedness. */
18138 inst.instruction |= (unsigned_p ? 1 : 0) << 4;
18139 /* Re-encode operand2 if it's indexed scalar operand. What has been encoded
18140 from inst.operand[2].reg in neon_three_same is GAS's internal encoding, not
18141 the instruction encoding. */
18142 if (inst.operands[2].isscalar)
18143 {
18144 inst.instruction &= 0xffffffd0;
18145 inst.instruction |= LOW4 (scalar_oprd2);
18146 inst.instruction |= HI1 (scalar_oprd2) << 5;
18147 }
18148}
18149
18150/* Dot Product instructions for signed integer. */
18151
18152static void
18153do_neon_dotproduct_s (void)
18154{
18155 return do_neon_dotproduct (0);
18156}
18157
18158/* Dot Product instructions for unsigned integer. */
18159
18160static void
18161do_neon_dotproduct_u (void)
18162{
18163 return do_neon_dotproduct (1);
18164}
18165
91ff7894
MGD
18166/* Crypto v1 instructions. */
18167static void
18168do_crypto_2op_1 (unsigned elttype, int op)
18169{
18170 set_it_insn_type (OUTSIDE_IT_INSN);
18171
18172 if (neon_check_type (2, NS_QQ, N_EQK | N_UNT, elttype | N_UNT | N_KEY).type
18173 == NT_invtype)
18174 return;
18175
18176 inst.error = NULL;
18177
18178 NEON_ENCODE (INTEGER, inst);
18179 inst.instruction |= LOW4 (inst.operands[0].reg) << 12;
18180 inst.instruction |= HI1 (inst.operands[0].reg) << 22;
18181 inst.instruction |= LOW4 (inst.operands[1].reg);
18182 inst.instruction |= HI1 (inst.operands[1].reg) << 5;
18183 if (op != -1)
18184 inst.instruction |= op << 6;
18185
18186 if (thumb_mode)
18187 inst.instruction |= 0xfc000000;
18188 else
18189 inst.instruction |= 0xf0000000;
18190}
18191
48adcd8e
MGD
18192static void
18193do_crypto_3op_1 (int u, int op)
18194{
18195 set_it_insn_type (OUTSIDE_IT_INSN);
18196
18197 if (neon_check_type (3, NS_QQQ, N_EQK | N_UNT, N_EQK | N_UNT,
18198 N_32 | N_UNT | N_KEY).type == NT_invtype)
18199 return;
18200
18201 inst.error = NULL;
18202
18203 NEON_ENCODE (INTEGER, inst);
18204 neon_three_same (1, u, 8 << op);
18205}
18206
91ff7894
MGD
18207static void
18208do_aese (void)
18209{
18210 do_crypto_2op_1 (N_8, 0);
18211}
18212
18213static void
18214do_aesd (void)
18215{
18216 do_crypto_2op_1 (N_8, 1);
18217}
18218
18219static void
18220do_aesmc (void)
18221{
18222 do_crypto_2op_1 (N_8, 2);
18223}
18224
18225static void
18226do_aesimc (void)
18227{
18228 do_crypto_2op_1 (N_8, 3);
18229}
18230
48adcd8e
MGD
18231static void
18232do_sha1c (void)
18233{
18234 do_crypto_3op_1 (0, 0);
18235}
18236
18237static void
18238do_sha1p (void)
18239{
18240 do_crypto_3op_1 (0, 1);
18241}
18242
18243static void
18244do_sha1m (void)
18245{
18246 do_crypto_3op_1 (0, 2);
18247}
18248
18249static void
18250do_sha1su0 (void)
18251{
18252 do_crypto_3op_1 (0, 3);
18253}
91ff7894 18254
48adcd8e
MGD
18255static void
18256do_sha256h (void)
18257{
18258 do_crypto_3op_1 (1, 0);
18259}
18260
18261static void
18262do_sha256h2 (void)
18263{
18264 do_crypto_3op_1 (1, 1);
18265}
18266
18267static void
18268do_sha256su1 (void)
18269{
18270 do_crypto_3op_1 (1, 2);
18271}
3c9017d2
MGD
18272
18273static void
18274do_sha1h (void)
18275{
18276 do_crypto_2op_1 (N_32, -1);
18277}
18278
18279static void
18280do_sha1su1 (void)
18281{
18282 do_crypto_2op_1 (N_32, 0);
18283}
18284
18285static void
18286do_sha256su0 (void)
18287{
18288 do_crypto_2op_1 (N_32, 1);
18289}
dd5181d5
KT
18290
18291static void
18292do_crc32_1 (unsigned int poly, unsigned int sz)
18293{
18294 unsigned int Rd = inst.operands[0].reg;
18295 unsigned int Rn = inst.operands[1].reg;
18296 unsigned int Rm = inst.operands[2].reg;
18297
18298 set_it_insn_type (OUTSIDE_IT_INSN);
18299 inst.instruction |= LOW4 (Rd) << (thumb_mode ? 8 : 12);
18300 inst.instruction |= LOW4 (Rn) << 16;
18301 inst.instruction |= LOW4 (Rm);
18302 inst.instruction |= sz << (thumb_mode ? 4 : 21);
18303 inst.instruction |= poly << (thumb_mode ? 20 : 9);
18304
18305 if (Rd == REG_PC || Rn == REG_PC || Rm == REG_PC)
18306 as_warn (UNPRED_REG ("r15"));
dd5181d5
KT
18307}
18308
18309static void
18310do_crc32b (void)
18311{
18312 do_crc32_1 (0, 0);
18313}
18314
18315static void
18316do_crc32h (void)
18317{
18318 do_crc32_1 (0, 1);
18319}
18320
18321static void
18322do_crc32w (void)
18323{
18324 do_crc32_1 (0, 2);
18325}
18326
18327static void
18328do_crc32cb (void)
18329{
18330 do_crc32_1 (1, 0);
18331}
18332
18333static void
18334do_crc32ch (void)
18335{
18336 do_crc32_1 (1, 1);
18337}
18338
18339static void
18340do_crc32cw (void)
18341{
18342 do_crc32_1 (1, 2);
18343}
18344
49e8a725
SN
18345static void
18346do_vjcvt (void)
18347{
18348 constraint (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_vfp_ext_armv8),
18349 _(BAD_FPU));
18350 neon_check_type (2, NS_FD, N_S32, N_F64);
18351 do_vfp_sp_dp_cvt ();
18352 do_vfp_cond_or_thumb ();
18353}
18354
5287ad62
JB
18355\f
18356/* Overall per-instruction processing. */
18357
18358/* We need to be able to fix up arbitrary expressions in some statements.
18359 This is so that we can handle symbols that are an arbitrary distance from
18360 the pc. The most common cases are of the form ((+/-sym -/+ . - 8) & mask),
18361 which returns part of an address in a form which will be valid for
18362 a data instruction. We do this by pushing the expression into a symbol
18363 in the expr_section, and creating a fix for that. */
18364
18365static void
18366fix_new_arm (fragS * frag,
18367 int where,
18368 short int size,
18369 expressionS * exp,
18370 int pc_rel,
18371 int reloc)
18372{
18373 fixS * new_fix;
18374
18375 switch (exp->X_op)
18376 {
18377 case O_constant:
6e7ce2cd
PB
18378 if (pc_rel)
18379 {
18380 /* Create an absolute valued symbol, so we have something to
477330fc
RM
18381 refer to in the object file. Unfortunately for us, gas's
18382 generic expression parsing will already have folded out
18383 any use of .set foo/.type foo %function that may have
18384 been used to set type information of the target location,
18385 that's being specified symbolically. We have to presume
18386 the user knows what they are doing. */
6e7ce2cd
PB
18387 char name[16 + 8];
18388 symbolS *symbol;
18389
18390 sprintf (name, "*ABS*0x%lx", (unsigned long)exp->X_add_number);
18391
18392 symbol = symbol_find_or_make (name);
18393 S_SET_SEGMENT (symbol, absolute_section);
18394 symbol_set_frag (symbol, &zero_address_frag);
18395 S_SET_VALUE (symbol, exp->X_add_number);
18396 exp->X_op = O_symbol;
18397 exp->X_add_symbol = symbol;
18398 exp->X_add_number = 0;
18399 }
18400 /* FALLTHROUGH */
5287ad62
JB
18401 case O_symbol:
18402 case O_add:
18403 case O_subtract:
21d799b5 18404 new_fix = fix_new_exp (frag, where, size, exp, pc_rel,
477330fc 18405 (enum bfd_reloc_code_real) reloc);
5287ad62
JB
18406 break;
18407
18408 default:
21d799b5 18409 new_fix = (fixS *) fix_new (frag, where, size, make_expr_symbol (exp), 0,
477330fc 18410 pc_rel, (enum bfd_reloc_code_real) reloc);
5287ad62
JB
18411 break;
18412 }
18413
18414 /* Mark whether the fix is to a THUMB instruction, or an ARM
18415 instruction. */
18416 new_fix->tc_fix_data = thumb_mode;
18417}
18418
18419/* Create a frg for an instruction requiring relaxation. */
18420static void
18421output_relax_insn (void)
18422{
18423 char * to;
18424 symbolS *sym;
0110f2b8
PB
18425 int offset;
18426
6e1cb1a6
PB
18427 /* The size of the instruction is unknown, so tie the debug info to the
18428 start of the instruction. */
18429 dwarf2_emit_insn (0);
6e1cb1a6 18430
e2b0ab59 18431 switch (inst.relocs[0].exp.X_op)
0110f2b8
PB
18432 {
18433 case O_symbol:
e2b0ab59
AV
18434 sym = inst.relocs[0].exp.X_add_symbol;
18435 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
18436 break;
18437 case O_constant:
18438 sym = NULL;
e2b0ab59 18439 offset = inst.relocs[0].exp.X_add_number;
0110f2b8
PB
18440 break;
18441 default:
e2b0ab59 18442 sym = make_expr_symbol (&inst.relocs[0].exp);
0110f2b8
PB
18443 offset = 0;
18444 break;
18445 }
18446 to = frag_var (rs_machine_dependent, INSN_SIZE, THUMB_SIZE,
18447 inst.relax, sym, offset, NULL/*offset, opcode*/);
18448 md_number_to_chars (to, inst.instruction, THUMB_SIZE);
0110f2b8
PB
18449}
18450
18451/* Write a 32-bit thumb instruction to buf. */
18452static void
18453put_thumb32_insn (char * buf, unsigned long insn)
18454{
18455 md_number_to_chars (buf, insn >> 16, THUMB_SIZE);
18456 md_number_to_chars (buf + THUMB_SIZE, insn, THUMB_SIZE);
18457}
18458
b99bd4ef 18459static void
c19d1205 18460output_inst (const char * str)
b99bd4ef 18461{
c19d1205 18462 char * to = NULL;
b99bd4ef 18463
c19d1205 18464 if (inst.error)
b99bd4ef 18465 {
c19d1205 18466 as_bad ("%s -- `%s'", inst.error, str);
b99bd4ef
NC
18467 return;
18468 }
5f4273c7
NC
18469 if (inst.relax)
18470 {
18471 output_relax_insn ();
0110f2b8 18472 return;
5f4273c7 18473 }
c19d1205
ZW
18474 if (inst.size == 0)
18475 return;
b99bd4ef 18476
c19d1205 18477 to = frag_more (inst.size);
8dc2430f
NC
18478 /* PR 9814: Record the thumb mode into the current frag so that we know
18479 what type of NOP padding to use, if necessary. We override any previous
18480 setting so that if the mode has changed then the NOPS that we use will
18481 match the encoding of the last instruction in the frag. */
cd000bff 18482 frag_now->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
c19d1205
ZW
18483
18484 if (thumb_mode && (inst.size > THUMB_SIZE))
b99bd4ef 18485 {
9c2799c2 18486 gas_assert (inst.size == (2 * THUMB_SIZE));
0110f2b8 18487 put_thumb32_insn (to, inst.instruction);
b99bd4ef 18488 }
c19d1205 18489 else if (inst.size > INSN_SIZE)
b99bd4ef 18490 {
9c2799c2 18491 gas_assert (inst.size == (2 * INSN_SIZE));
c19d1205
ZW
18492 md_number_to_chars (to, inst.instruction, INSN_SIZE);
18493 md_number_to_chars (to + INSN_SIZE, inst.instruction, INSN_SIZE);
b99bd4ef 18494 }
c19d1205
ZW
18495 else
18496 md_number_to_chars (to, inst.instruction, inst.size);
b99bd4ef 18497
e2b0ab59
AV
18498 int r;
18499 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
18500 {
18501 if (inst.relocs[r].type != BFD_RELOC_UNUSED)
18502 fix_new_arm (frag_now, to - frag_now->fr_literal,
18503 inst.size, & inst.relocs[r].exp, inst.relocs[r].pc_rel,
18504 inst.relocs[r].type);
18505 }
b99bd4ef 18506
c19d1205 18507 dwarf2_emit_insn (inst.size);
c19d1205 18508}
b99bd4ef 18509
e07e6e58
NC
18510static char *
18511output_it_inst (int cond, int mask, char * to)
18512{
18513 unsigned long instruction = 0xbf00;
18514
18515 mask &= 0xf;
18516 instruction |= mask;
18517 instruction |= cond << 4;
18518
18519 if (to == NULL)
18520 {
18521 to = frag_more (2);
18522#ifdef OBJ_ELF
18523 dwarf2_emit_insn (2);
18524#endif
18525 }
18526
18527 md_number_to_chars (to, instruction, 2);
18528
18529 return to;
18530}
18531
c19d1205
ZW
18532/* Tag values used in struct asm_opcode's tag field. */
18533enum opcode_tag
18534{
18535 OT_unconditional, /* Instruction cannot be conditionalized.
18536 The ARM condition field is still 0xE. */
18537 OT_unconditionalF, /* Instruction cannot be conditionalized
18538 and carries 0xF in its ARM condition field. */
18539 OT_csuffix, /* Instruction takes a conditional suffix. */
037e8744 18540 OT_csuffixF, /* Some forms of the instruction take a conditional
477330fc
RM
18541 suffix, others place 0xF where the condition field
18542 would be. */
c19d1205
ZW
18543 OT_cinfix3, /* Instruction takes a conditional infix,
18544 beginning at character index 3. (In
18545 unified mode, it becomes a suffix.) */
088fa78e
KH
18546 OT_cinfix3_deprecated, /* The same as OT_cinfix3. This is used for
18547 tsts, cmps, cmns, and teqs. */
e3cb604e
PB
18548 OT_cinfix3_legacy, /* Legacy instruction takes a conditional infix at
18549 character index 3, even in unified mode. Used for
18550 legacy instructions where suffix and infix forms
18551 may be ambiguous. */
c19d1205 18552 OT_csuf_or_in3, /* Instruction takes either a conditional
e3cb604e 18553 suffix or an infix at character index 3. */
c19d1205
ZW
18554 OT_odd_infix_unc, /* This is the unconditional variant of an
18555 instruction that takes a conditional infix
18556 at an unusual position. In unified mode,
18557 this variant will accept a suffix. */
18558 OT_odd_infix_0 /* Values greater than or equal to OT_odd_infix_0
18559 are the conditional variants of instructions that
18560 take conditional infixes in unusual positions.
18561 The infix appears at character index
18562 (tag - OT_odd_infix_0). These are not accepted
18563 in unified mode. */
18564};
b99bd4ef 18565
c19d1205
ZW
18566/* Subroutine of md_assemble, responsible for looking up the primary
18567 opcode from the mnemonic the user wrote. STR points to the
18568 beginning of the mnemonic.
18569
18570 This is not simply a hash table lookup, because of conditional
18571 variants. Most instructions have conditional variants, which are
18572 expressed with a _conditional affix_ to the mnemonic. If we were
18573 to encode each conditional variant as a literal string in the opcode
18574 table, it would have approximately 20,000 entries.
18575
18576 Most mnemonics take this affix as a suffix, and in unified syntax,
18577 'most' is upgraded to 'all'. However, in the divided syntax, some
18578 instructions take the affix as an infix, notably the s-variants of
18579 the arithmetic instructions. Of those instructions, all but six
18580 have the infix appear after the third character of the mnemonic.
18581
18582 Accordingly, the algorithm for looking up primary opcodes given
18583 an identifier is:
18584
18585 1. Look up the identifier in the opcode table.
18586 If we find a match, go to step U.
18587
18588 2. Look up the last two characters of the identifier in the
18589 conditions table. If we find a match, look up the first N-2
18590 characters of the identifier in the opcode table. If we
18591 find a match, go to step CE.
18592
18593 3. Look up the fourth and fifth characters of the identifier in
18594 the conditions table. If we find a match, extract those
18595 characters from the identifier, and look up the remaining
18596 characters in the opcode table. If we find a match, go
18597 to step CM.
18598
18599 4. Fail.
18600
18601 U. Examine the tag field of the opcode structure, in case this is
18602 one of the six instructions with its conditional infix in an
18603 unusual place. If it is, the tag tells us where to find the
18604 infix; look it up in the conditions table and set inst.cond
18605 accordingly. Otherwise, this is an unconditional instruction.
18606 Again set inst.cond accordingly. Return the opcode structure.
18607
18608 CE. Examine the tag field to make sure this is an instruction that
18609 should receive a conditional suffix. If it is not, fail.
18610 Otherwise, set inst.cond from the suffix we already looked up,
18611 and return the opcode structure.
18612
18613 CM. Examine the tag field to make sure this is an instruction that
18614 should receive a conditional infix after the third character.
18615 If it is not, fail. Otherwise, undo the edits to the current
18616 line of input and proceed as for case CE. */
18617
18618static const struct asm_opcode *
18619opcode_lookup (char **str)
18620{
18621 char *end, *base;
18622 char *affix;
18623 const struct asm_opcode *opcode;
18624 const struct asm_cond *cond;
e3cb604e 18625 char save[2];
c19d1205
ZW
18626
18627 /* Scan up to the end of the mnemonic, which must end in white space,
721a8186 18628 '.' (in unified mode, or for Neon/VFP instructions), or end of string. */
c19d1205 18629 for (base = end = *str; *end != '\0'; end++)
721a8186 18630 if (*end == ' ' || *end == '.')
c19d1205 18631 break;
b99bd4ef 18632
c19d1205 18633 if (end == base)
c921be7d 18634 return NULL;
b99bd4ef 18635
5287ad62 18636 /* Handle a possible width suffix and/or Neon type suffix. */
c19d1205 18637 if (end[0] == '.')
b99bd4ef 18638 {
5287ad62 18639 int offset = 2;
5f4273c7 18640
267d2029 18641 /* The .w and .n suffixes are only valid if the unified syntax is in
477330fc 18642 use. */
267d2029 18643 if (unified_syntax && end[1] == 'w')
c19d1205 18644 inst.size_req = 4;
267d2029 18645 else if (unified_syntax && end[1] == 'n')
c19d1205
ZW
18646 inst.size_req = 2;
18647 else
477330fc 18648 offset = 0;
5287ad62
JB
18649
18650 inst.vectype.elems = 0;
18651
18652 *str = end + offset;
b99bd4ef 18653
5f4273c7 18654 if (end[offset] == '.')
5287ad62 18655 {
267d2029 18656 /* See if we have a Neon type suffix (possible in either unified or
477330fc
RM
18657 non-unified ARM syntax mode). */
18658 if (parse_neon_type (&inst.vectype, str) == FAIL)
c921be7d 18659 return NULL;
477330fc 18660 }
5287ad62 18661 else if (end[offset] != '\0' && end[offset] != ' ')
477330fc 18662 return NULL;
b99bd4ef 18663 }
c19d1205
ZW
18664 else
18665 *str = end;
b99bd4ef 18666
c19d1205 18667 /* Look for unaffixed or special-case affixed mnemonic. */
21d799b5 18668 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 18669 end - base);
c19d1205 18670 if (opcode)
b99bd4ef 18671 {
c19d1205
ZW
18672 /* step U */
18673 if (opcode->tag < OT_odd_infix_0)
b99bd4ef 18674 {
c19d1205
ZW
18675 inst.cond = COND_ALWAYS;
18676 return opcode;
b99bd4ef 18677 }
b99bd4ef 18678
278df34e 18679 if (warn_on_deprecated && unified_syntax)
5c3696f8 18680 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205 18681 affix = base + (opcode->tag - OT_odd_infix_0);
21d799b5 18682 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
9c2799c2 18683 gas_assert (cond);
b99bd4ef 18684
c19d1205
ZW
18685 inst.cond = cond->value;
18686 return opcode;
18687 }
b99bd4ef 18688
c19d1205
ZW
18689 /* Cannot have a conditional suffix on a mnemonic of less than two
18690 characters. */
18691 if (end - base < 3)
c921be7d 18692 return NULL;
b99bd4ef 18693
c19d1205
ZW
18694 /* Look for suffixed mnemonic. */
18695 affix = end - 2;
21d799b5
NC
18696 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
18697 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 18698 affix - base);
c19d1205
ZW
18699 if (opcode && cond)
18700 {
18701 /* step CE */
18702 switch (opcode->tag)
18703 {
e3cb604e
PB
18704 case OT_cinfix3_legacy:
18705 /* Ignore conditional suffixes matched on infix only mnemonics. */
18706 break;
18707
c19d1205 18708 case OT_cinfix3:
088fa78e 18709 case OT_cinfix3_deprecated:
c19d1205
ZW
18710 case OT_odd_infix_unc:
18711 if (!unified_syntax)
0198d5e6 18712 return NULL;
1a0670f3 18713 /* Fall through. */
c19d1205
ZW
18714
18715 case OT_csuffix:
477330fc 18716 case OT_csuffixF:
c19d1205
ZW
18717 case OT_csuf_or_in3:
18718 inst.cond = cond->value;
18719 return opcode;
18720
18721 case OT_unconditional:
18722 case OT_unconditionalF:
dfa9f0d5 18723 if (thumb_mode)
c921be7d 18724 inst.cond = cond->value;
dfa9f0d5
PB
18725 else
18726 {
c921be7d 18727 /* Delayed diagnostic. */
dfa9f0d5
PB
18728 inst.error = BAD_COND;
18729 inst.cond = COND_ALWAYS;
18730 }
c19d1205 18731 return opcode;
b99bd4ef 18732
c19d1205 18733 default:
c921be7d 18734 return NULL;
c19d1205
ZW
18735 }
18736 }
b99bd4ef 18737
c19d1205
ZW
18738 /* Cannot have a usual-position infix on a mnemonic of less than
18739 six characters (five would be a suffix). */
18740 if (end - base < 6)
c921be7d 18741 return NULL;
b99bd4ef 18742
c19d1205
ZW
18743 /* Look for infixed mnemonic in the usual position. */
18744 affix = base + 3;
21d799b5 18745 cond = (const struct asm_cond *) hash_find_n (arm_cond_hsh, affix, 2);
e3cb604e 18746 if (!cond)
c921be7d 18747 return NULL;
e3cb604e
PB
18748
18749 memcpy (save, affix, 2);
18750 memmove (affix, affix + 2, (end - affix) - 2);
21d799b5 18751 opcode = (const struct asm_opcode *) hash_find_n (arm_ops_hsh, base,
477330fc 18752 (end - base) - 2);
e3cb604e
PB
18753 memmove (affix + 2, affix, (end - affix) - 2);
18754 memcpy (affix, save, 2);
18755
088fa78e
KH
18756 if (opcode
18757 && (opcode->tag == OT_cinfix3
18758 || opcode->tag == OT_cinfix3_deprecated
18759 || opcode->tag == OT_csuf_or_in3
18760 || opcode->tag == OT_cinfix3_legacy))
b99bd4ef 18761 {
c921be7d 18762 /* Step CM. */
278df34e 18763 if (warn_on_deprecated && unified_syntax
088fa78e
KH
18764 && (opcode->tag == OT_cinfix3
18765 || opcode->tag == OT_cinfix3_deprecated))
5c3696f8 18766 as_tsktsk (_("conditional infixes are deprecated in unified syntax"));
c19d1205
ZW
18767
18768 inst.cond = cond->value;
18769 return opcode;
b99bd4ef
NC
18770 }
18771
c921be7d 18772 return NULL;
b99bd4ef
NC
18773}
18774
e07e6e58
NC
18775/* This function generates an initial IT instruction, leaving its block
18776 virtually open for the new instructions. Eventually,
18777 the mask will be updated by now_it_add_mask () each time
18778 a new instruction needs to be included in the IT block.
18779 Finally, the block is closed with close_automatic_it_block ().
18780 The block closure can be requested either from md_assemble (),
18781 a tencode (), or due to a label hook. */
18782
18783static void
18784new_automatic_it_block (int cond)
18785{
18786 now_it.state = AUTOMATIC_IT_BLOCK;
18787 now_it.mask = 0x18;
18788 now_it.cc = cond;
18789 now_it.block_length = 1;
cd000bff 18790 mapping_state (MAP_THUMB);
e07e6e58 18791 now_it.insn = output_it_inst (cond, now_it.mask, NULL);
5a01bb1d
MGD
18792 now_it.warn_deprecated = FALSE;
18793 now_it.insn_cond = TRUE;
e07e6e58
NC
18794}
18795
18796/* Close an automatic IT block.
18797 See comments in new_automatic_it_block (). */
18798
18799static void
18800close_automatic_it_block (void)
18801{
18802 now_it.mask = 0x10;
18803 now_it.block_length = 0;
18804}
18805
18806/* Update the mask of the current automatically-generated IT
18807 instruction. See comments in new_automatic_it_block (). */
18808
18809static void
18810now_it_add_mask (int cond)
18811{
18812#define CLEAR_BIT(value, nbit) ((value) & ~(1 << (nbit)))
18813#define SET_BIT_VALUE(value, bitvalue, nbit) (CLEAR_BIT (value, nbit) \
477330fc 18814 | ((bitvalue) << (nbit)))
e07e6e58 18815 const int resulting_bit = (cond & 1);
c921be7d 18816
e07e6e58
NC
18817 now_it.mask &= 0xf;
18818 now_it.mask = SET_BIT_VALUE (now_it.mask,
477330fc
RM
18819 resulting_bit,
18820 (5 - now_it.block_length));
e07e6e58 18821 now_it.mask = SET_BIT_VALUE (now_it.mask,
477330fc
RM
18822 1,
18823 ((5 - now_it.block_length) - 1) );
e07e6e58
NC
18824 output_it_inst (now_it.cc, now_it.mask, now_it.insn);
18825
18826#undef CLEAR_BIT
18827#undef SET_BIT_VALUE
e07e6e58
NC
18828}
18829
18830/* The IT blocks handling machinery is accessed through the these functions:
18831 it_fsm_pre_encode () from md_assemble ()
18832 set_it_insn_type () optional, from the tencode functions
18833 set_it_insn_type_last () ditto
18834 in_it_block () ditto
18835 it_fsm_post_encode () from md_assemble ()
33eaf5de 18836 force_automatic_it_block_close () from label handling functions
e07e6e58
NC
18837
18838 Rationale:
18839 1) md_assemble () calls it_fsm_pre_encode () before calling tencode (),
477330fc
RM
18840 initializing the IT insn type with a generic initial value depending
18841 on the inst.condition.
e07e6e58 18842 2) During the tencode function, two things may happen:
477330fc
RM
18843 a) The tencode function overrides the IT insn type by
18844 calling either set_it_insn_type (type) or set_it_insn_type_last ().
18845 b) The tencode function queries the IT block state by
18846 calling in_it_block () (i.e. to determine narrow/not narrow mode).
18847
18848 Both set_it_insn_type and in_it_block run the internal FSM state
18849 handling function (handle_it_state), because: a) setting the IT insn
18850 type may incur in an invalid state (exiting the function),
18851 and b) querying the state requires the FSM to be updated.
18852 Specifically we want to avoid creating an IT block for conditional
18853 branches, so it_fsm_pre_encode is actually a guess and we can't
18854 determine whether an IT block is required until the tencode () routine
18855 has decided what type of instruction this actually it.
18856 Because of this, if set_it_insn_type and in_it_block have to be used,
18857 set_it_insn_type has to be called first.
18858
18859 set_it_insn_type_last () is a wrapper of set_it_insn_type (type), that
18860 determines the insn IT type depending on the inst.cond code.
18861 When a tencode () routine encodes an instruction that can be
18862 either outside an IT block, or, in the case of being inside, has to be
18863 the last one, set_it_insn_type_last () will determine the proper
18864 IT instruction type based on the inst.cond code. Otherwise,
18865 set_it_insn_type can be called for overriding that logic or
18866 for covering other cases.
18867
18868 Calling handle_it_state () may not transition the IT block state to
2b0f3761 18869 OUTSIDE_IT_BLOCK immediately, since the (current) state could be
477330fc
RM
18870 still queried. Instead, if the FSM determines that the state should
18871 be transitioned to OUTSIDE_IT_BLOCK, a flag is marked to be closed
18872 after the tencode () function: that's what it_fsm_post_encode () does.
18873
18874 Since in_it_block () calls the state handling function to get an
18875 updated state, an error may occur (due to invalid insns combination).
18876 In that case, inst.error is set.
18877 Therefore, inst.error has to be checked after the execution of
18878 the tencode () routine.
e07e6e58
NC
18879
18880 3) Back in md_assemble(), it_fsm_post_encode () is called to commit
477330fc
RM
18881 any pending state change (if any) that didn't take place in
18882 handle_it_state () as explained above. */
e07e6e58
NC
18883
18884static void
18885it_fsm_pre_encode (void)
18886{
18887 if (inst.cond != COND_ALWAYS)
18888 inst.it_insn_type = INSIDE_IT_INSN;
18889 else
18890 inst.it_insn_type = OUTSIDE_IT_INSN;
18891
18892 now_it.state_handled = 0;
18893}
18894
18895/* IT state FSM handling function. */
18896
18897static int
18898handle_it_state (void)
18899{
18900 now_it.state_handled = 1;
5a01bb1d 18901 now_it.insn_cond = FALSE;
e07e6e58
NC
18902
18903 switch (now_it.state)
18904 {
18905 case OUTSIDE_IT_BLOCK:
18906 switch (inst.it_insn_type)
18907 {
18908 case OUTSIDE_IT_INSN:
18909 break;
18910
18911 case INSIDE_IT_INSN:
18912 case INSIDE_IT_LAST_INSN:
18913 if (thumb_mode == 0)
18914 {
c921be7d 18915 if (unified_syntax
e07e6e58
NC
18916 && !(implicit_it_mode & IMPLICIT_IT_MODE_ARM))
18917 as_tsktsk (_("Warning: conditional outside an IT block"\
18918 " for Thumb."));
18919 }
18920 else
18921 {
18922 if ((implicit_it_mode & IMPLICIT_IT_MODE_THUMB)
fc289b0a 18923 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
e07e6e58
NC
18924 {
18925 /* Automatically generate the IT instruction. */
18926 new_automatic_it_block (inst.cond);
18927 if (inst.it_insn_type == INSIDE_IT_LAST_INSN)
18928 close_automatic_it_block ();
18929 }
18930 else
18931 {
18932 inst.error = BAD_OUT_IT;
18933 return FAIL;
18934 }
18935 }
18936 break;
18937
18938 case IF_INSIDE_IT_LAST_INSN:
18939 case NEUTRAL_IT_INSN:
18940 break;
18941
18942 case IT_INSN:
18943 now_it.state = MANUAL_IT_BLOCK;
18944 now_it.block_length = 0;
18945 break;
18946 }
18947 break;
18948
18949 case AUTOMATIC_IT_BLOCK:
18950 /* Three things may happen now:
18951 a) We should increment current it block size;
18952 b) We should close current it block (closing insn or 4 insns);
18953 c) We should close current it block and start a new one (due
18954 to incompatible conditions or
18955 4 insns-length block reached). */
18956
18957 switch (inst.it_insn_type)
18958 {
18959 case OUTSIDE_IT_INSN:
2b0f3761 18960 /* The closure of the block shall happen immediately,
e07e6e58
NC
18961 so any in_it_block () call reports the block as closed. */
18962 force_automatic_it_block_close ();
18963 break;
18964
18965 case INSIDE_IT_INSN:
18966 case INSIDE_IT_LAST_INSN:
18967 case IF_INSIDE_IT_LAST_INSN:
18968 now_it.block_length++;
18969
18970 if (now_it.block_length > 4
18971 || !now_it_compatible (inst.cond))
18972 {
18973 force_automatic_it_block_close ();
18974 if (inst.it_insn_type != IF_INSIDE_IT_LAST_INSN)
18975 new_automatic_it_block (inst.cond);
18976 }
18977 else
18978 {
5a01bb1d 18979 now_it.insn_cond = TRUE;
e07e6e58
NC
18980 now_it_add_mask (inst.cond);
18981 }
18982
18983 if (now_it.state == AUTOMATIC_IT_BLOCK
18984 && (inst.it_insn_type == INSIDE_IT_LAST_INSN
18985 || inst.it_insn_type == IF_INSIDE_IT_LAST_INSN))
18986 close_automatic_it_block ();
18987 break;
18988
18989 case NEUTRAL_IT_INSN:
18990 now_it.block_length++;
5a01bb1d 18991 now_it.insn_cond = TRUE;
e07e6e58
NC
18992
18993 if (now_it.block_length > 4)
18994 force_automatic_it_block_close ();
18995 else
18996 now_it_add_mask (now_it.cc & 1);
18997 break;
18998
18999 case IT_INSN:
19000 close_automatic_it_block ();
19001 now_it.state = MANUAL_IT_BLOCK;
19002 break;
19003 }
19004 break;
19005
19006 case MANUAL_IT_BLOCK:
19007 {
19008 /* Check conditional suffixes. */
19009 const int cond = now_it.cc ^ ((now_it.mask >> 4) & 1) ^ 1;
19010 int is_last;
19011 now_it.mask <<= 1;
19012 now_it.mask &= 0x1f;
19013 is_last = (now_it.mask == 0x10);
5a01bb1d 19014 now_it.insn_cond = TRUE;
e07e6e58
NC
19015
19016 switch (inst.it_insn_type)
19017 {
19018 case OUTSIDE_IT_INSN:
19019 inst.error = BAD_NOT_IT;
19020 return FAIL;
19021
19022 case INSIDE_IT_INSN:
19023 if (cond != inst.cond)
19024 {
19025 inst.error = BAD_IT_COND;
19026 return FAIL;
19027 }
19028 break;
19029
19030 case INSIDE_IT_LAST_INSN:
19031 case IF_INSIDE_IT_LAST_INSN:
19032 if (cond != inst.cond)
19033 {
19034 inst.error = BAD_IT_COND;
19035 return FAIL;
19036 }
19037 if (!is_last)
19038 {
19039 inst.error = BAD_BRANCH;
19040 return FAIL;
19041 }
19042 break;
19043
19044 case NEUTRAL_IT_INSN:
19045 /* The BKPT instruction is unconditional even in an IT block. */
19046 break;
19047
19048 case IT_INSN:
19049 inst.error = BAD_IT_IT;
19050 return FAIL;
19051 }
19052 }
19053 break;
19054 }
19055
19056 return SUCCESS;
19057}
19058
5a01bb1d
MGD
19059struct depr_insn_mask
19060{
19061 unsigned long pattern;
19062 unsigned long mask;
19063 const char* description;
19064};
19065
19066/* List of 16-bit instruction patterns deprecated in an IT block in
19067 ARMv8. */
19068static const struct depr_insn_mask depr_it_insns[] = {
19069 { 0xc000, 0xc000, N_("Short branches, Undefined, SVC, LDM/STM") },
19070 { 0xb000, 0xb000, N_("Miscellaneous 16-bit instructions") },
19071 { 0xa000, 0xb800, N_("ADR") },
19072 { 0x4800, 0xf800, N_("Literal loads") },
19073 { 0x4478, 0xf478, N_("Hi-register ADD, MOV, CMP, BX, BLX using pc") },
19074 { 0x4487, 0xfc87, N_("Hi-register ADD, MOV, CMP using pc") },
c8de034b
JW
19075 /* NOTE: 0x00dd is not the real encoding, instead, it is the 'tvalue'
19076 field in asm_opcode. 'tvalue' is used at the stage this check happen. */
19077 { 0x00dd, 0x7fff, N_("ADD/SUB sp, sp #imm") },
5a01bb1d
MGD
19078 { 0, 0, NULL }
19079};
19080
e07e6e58
NC
19081static void
19082it_fsm_post_encode (void)
19083{
19084 int is_last;
19085
19086 if (!now_it.state_handled)
19087 handle_it_state ();
19088
5a01bb1d
MGD
19089 if (now_it.insn_cond
19090 && !now_it.warn_deprecated
19091 && warn_on_deprecated
df9909b8
TP
19092 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v8)
19093 && !ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_m))
5a01bb1d
MGD
19094 {
19095 if (inst.instruction >= 0x10000)
19096 {
5c3696f8 19097 as_tsktsk (_("IT blocks containing 32-bit Thumb instructions are "
df9909b8 19098 "performance deprecated in ARMv8-A and ARMv8-R"));
5a01bb1d
MGD
19099 now_it.warn_deprecated = TRUE;
19100 }
19101 else
19102 {
19103 const struct depr_insn_mask *p = depr_it_insns;
19104
19105 while (p->mask != 0)
19106 {
19107 if ((inst.instruction & p->mask) == p->pattern)
19108 {
df9909b8
TP
19109 as_tsktsk (_("IT blocks containing 16-bit Thumb "
19110 "instructions of the following class are "
19111 "performance deprecated in ARMv8-A and "
19112 "ARMv8-R: %s"), p->description);
5a01bb1d
MGD
19113 now_it.warn_deprecated = TRUE;
19114 break;
19115 }
19116
19117 ++p;
19118 }
19119 }
19120
19121 if (now_it.block_length > 1)
19122 {
5c3696f8 19123 as_tsktsk (_("IT blocks containing more than one conditional "
df9909b8
TP
19124 "instruction are performance deprecated in ARMv8-A and "
19125 "ARMv8-R"));
5a01bb1d
MGD
19126 now_it.warn_deprecated = TRUE;
19127 }
19128 }
19129
e07e6e58
NC
19130 is_last = (now_it.mask == 0x10);
19131 if (is_last)
19132 {
19133 now_it.state = OUTSIDE_IT_BLOCK;
19134 now_it.mask = 0;
19135 }
19136}
19137
19138static void
19139force_automatic_it_block_close (void)
19140{
19141 if (now_it.state == AUTOMATIC_IT_BLOCK)
19142 {
19143 close_automatic_it_block ();
19144 now_it.state = OUTSIDE_IT_BLOCK;
19145 now_it.mask = 0;
19146 }
19147}
19148
19149static int
19150in_it_block (void)
19151{
19152 if (!now_it.state_handled)
19153 handle_it_state ();
19154
19155 return now_it.state != OUTSIDE_IT_BLOCK;
19156}
19157
ff8646ee
TP
19158/* Whether OPCODE only has T32 encoding. Since this function is only used by
19159 t32_insn_ok, OPCODE enabled by v6t2 extension bit do not need to be listed
19160 here, hence the "known" in the function name. */
fc289b0a
TP
19161
19162static bfd_boolean
ff8646ee 19163known_t32_only_insn (const struct asm_opcode *opcode)
fc289b0a
TP
19164{
19165 /* Original Thumb-1 wide instruction. */
19166 if (opcode->tencode == do_t_blx
19167 || opcode->tencode == do_t_branch23
19168 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_msr)
19169 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_barrier))
19170 return TRUE;
19171
16a1fa25
TP
19172 /* Wide-only instruction added to ARMv8-M Baseline. */
19173 if (ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v8m_m_only)
ff8646ee
TP
19174 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_atomics)
19175 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_v6t2_v8m)
19176 || ARM_CPU_HAS_FEATURE (*opcode->tvariant, arm_ext_div))
19177 return TRUE;
19178
19179 return FALSE;
19180}
19181
19182/* Whether wide instruction variant can be used if available for a valid OPCODE
19183 in ARCH. */
19184
19185static bfd_boolean
19186t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode)
19187{
19188 if (known_t32_only_insn (opcode))
19189 return TRUE;
19190
19191 /* Instruction with narrow and wide encoding added to ARMv8-M. Availability
19192 of variant T3 of B.W is checked in do_t_branch. */
19193 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
19194 && opcode->tencode == do_t_branch)
19195 return TRUE;
19196
bada4342
JW
19197 /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */
19198 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m)
19199 && opcode->tencode == do_t_mov_cmp
19200 /* Make sure CMP instruction is not affected. */
19201 && opcode->aencode == do_mov)
19202 return TRUE;
19203
ff8646ee
TP
19204 /* Wide instruction variants of all instructions with narrow *and* wide
19205 variants become available with ARMv6t2. Other opcodes are either
19206 narrow-only or wide-only and are thus available if OPCODE is valid. */
19207 if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v6t2))
19208 return TRUE;
19209
19210 /* OPCODE with narrow only instruction variant or wide variant not
19211 available. */
fc289b0a
TP
19212 return FALSE;
19213}
19214
c19d1205
ZW
19215void
19216md_assemble (char *str)
b99bd4ef 19217{
c19d1205
ZW
19218 char *p = str;
19219 const struct asm_opcode * opcode;
b99bd4ef 19220
c19d1205
ZW
19221 /* Align the previous label if needed. */
19222 if (last_label_seen != NULL)
b99bd4ef 19223 {
c19d1205
ZW
19224 symbol_set_frag (last_label_seen, frag_now);
19225 S_SET_VALUE (last_label_seen, (valueT) frag_now_fix ());
19226 S_SET_SEGMENT (last_label_seen, now_seg);
b99bd4ef
NC
19227 }
19228
c19d1205 19229 memset (&inst, '\0', sizeof (inst));
e2b0ab59
AV
19230 int r;
19231 for (r = 0; r < ARM_IT_MAX_RELOCS; r++)
19232 inst.relocs[r].type = BFD_RELOC_UNUSED;
b99bd4ef 19233
c19d1205
ZW
19234 opcode = opcode_lookup (&p);
19235 if (!opcode)
b99bd4ef 19236 {
c19d1205 19237 /* It wasn't an instruction, but it might be a register alias of
dcbf9037 19238 the form alias .req reg, or a Neon .dn/.qn directive. */
c921be7d 19239 if (! create_register_alias (str, p)
477330fc 19240 && ! create_neon_reg_alias (str, p))
c19d1205 19241 as_bad (_("bad instruction `%s'"), str);
b99bd4ef 19242
b99bd4ef
NC
19243 return;
19244 }
19245
278df34e 19246 if (warn_on_deprecated && opcode->tag == OT_cinfix3_deprecated)
5c3696f8 19247 as_tsktsk (_("s suffix on comparison instruction is deprecated"));
088fa78e 19248
037e8744
JB
19249 /* The value which unconditional instructions should have in place of the
19250 condition field. */
19251 inst.uncond_value = (opcode->tag == OT_csuffixF) ? 0xf : -1;
19252
c19d1205 19253 if (thumb_mode)
b99bd4ef 19254 {
e74cfd16 19255 arm_feature_set variant;
8f06b2d8
PB
19256
19257 variant = cpu_variant;
19258 /* Only allow coprocessor instructions on Thumb-2 capable devices. */
e74cfd16
PB
19259 if (!ARM_CPU_HAS_FEATURE (variant, arm_arch_t2))
19260 ARM_CLEAR_FEATURE (variant, variant, fpu_any_hard);
c19d1205 19261 /* Check that this instruction is supported for this CPU. */
62b3e311
PB
19262 if (!opcode->tvariant
19263 || (thumb_mode == 1
19264 && !ARM_CPU_HAS_FEATURE (variant, *opcode->tvariant)))
b99bd4ef 19265 {
173205ca
TP
19266 if (opcode->tencode == do_t_swi)
19267 as_bad (_("SVC is not permitted on this architecture"));
19268 else
19269 as_bad (_("selected processor does not support `%s' in Thumb mode"), str);
b99bd4ef
NC
19270 return;
19271 }
c19d1205
ZW
19272 if (inst.cond != COND_ALWAYS && !unified_syntax
19273 && opcode->tencode != do_t_branch)
b99bd4ef 19274 {
c19d1205 19275 as_bad (_("Thumb does not support conditional execution"));
b99bd4ef
NC
19276 return;
19277 }
19278
fc289b0a
TP
19279 /* Two things are addressed here:
19280 1) Implicit require narrow instructions on Thumb-1.
19281 This avoids relaxation accidentally introducing Thumb-2
19282 instructions.
19283 2) Reject wide instructions in non Thumb-2 cores.
19284
19285 Only instructions with narrow and wide variants need to be handled
19286 but selecting all non wide-only instructions is easier. */
19287 if (!ARM_CPU_HAS_FEATURE (variant, arm_ext_v6t2)
ff8646ee 19288 && !t32_insn_ok (variant, opcode))
076d447c 19289 {
fc289b0a
TP
19290 if (inst.size_req == 0)
19291 inst.size_req = 2;
19292 else if (inst.size_req == 4)
752d5da4 19293 {
ff8646ee
TP
19294 if (ARM_CPU_HAS_FEATURE (variant, arm_ext_v8m))
19295 as_bad (_("selected processor does not support 32bit wide "
19296 "variant of instruction `%s'"), str);
19297 else
19298 as_bad (_("selected processor does not support `%s' in "
19299 "Thumb-2 mode"), str);
fc289b0a 19300 return;
752d5da4 19301 }
076d447c
PB
19302 }
19303
c19d1205
ZW
19304 inst.instruction = opcode->tvalue;
19305
5be8be5d 19306 if (!parse_operands (p, opcode->operands, /*thumb=*/TRUE))
477330fc
RM
19307 {
19308 /* Prepare the it_insn_type for those encodings that don't set
19309 it. */
19310 it_fsm_pre_encode ();
c19d1205 19311
477330fc 19312 opcode->tencode ();
e07e6e58 19313
477330fc
RM
19314 it_fsm_post_encode ();
19315 }
e27ec89e 19316
0110f2b8 19317 if (!(inst.error || inst.relax))
b99bd4ef 19318 {
9c2799c2 19319 gas_assert (inst.instruction < 0xe800 || inst.instruction > 0xffff);
c19d1205
ZW
19320 inst.size = (inst.instruction > 0xffff ? 4 : 2);
19321 if (inst.size_req && inst.size_req != inst.size)
b99bd4ef 19322 {
c19d1205 19323 as_bad (_("cannot honor width suffix -- `%s'"), str);
b99bd4ef
NC
19324 return;
19325 }
19326 }
076d447c
PB
19327
19328 /* Something has gone badly wrong if we try to relax a fixed size
477330fc 19329 instruction. */
9c2799c2 19330 gas_assert (inst.size_req == 0 || !inst.relax);
076d447c 19331
e74cfd16
PB
19332 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
19333 *opcode->tvariant);
ee065d83 19334 /* Many Thumb-2 instructions also have Thumb-1 variants, so explicitly
fc289b0a
TP
19335 set those bits when Thumb-2 32-bit instructions are seen. The impact
19336 of relaxable instructions will be considered later after we finish all
19337 relaxation. */
ff8646ee
TP
19338 if (ARM_FEATURE_CORE_EQUAL (cpu_variant, arm_arch_any))
19339 variant = arm_arch_none;
19340 else
19341 variant = cpu_variant;
19342 if (inst.size == 4 && !t32_insn_ok (variant, opcode))
e74cfd16
PB
19343 ARM_MERGE_FEATURE_SETS (thumb_arch_used, thumb_arch_used,
19344 arm_ext_v6t2);
cd000bff 19345
88714cb8
DG
19346 check_neon_suffixes;
19347
cd000bff 19348 if (!inst.error)
c877a2f2
NC
19349 {
19350 mapping_state (MAP_THUMB);
19351 }
c19d1205 19352 }
3e9e4fcf 19353 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
c19d1205 19354 {
845b51d6
PB
19355 bfd_boolean is_bx;
19356
19357 /* bx is allowed on v5 cores, and sometimes on v4 cores. */
19358 is_bx = (opcode->aencode == do_bx);
19359
c19d1205 19360 /* Check that this instruction is supported for this CPU. */
845b51d6
PB
19361 if (!(is_bx && fix_v4bx)
19362 && !(opcode->avariant &&
19363 ARM_CPU_HAS_FEATURE (cpu_variant, *opcode->avariant)))
b99bd4ef 19364 {
84b52b66 19365 as_bad (_("selected processor does not support `%s' in ARM mode"), str);
c19d1205 19366 return;
b99bd4ef 19367 }
c19d1205 19368 if (inst.size_req)
b99bd4ef 19369 {
c19d1205
ZW
19370 as_bad (_("width suffixes are invalid in ARM mode -- `%s'"), str);
19371 return;
b99bd4ef
NC
19372 }
19373
c19d1205
ZW
19374 inst.instruction = opcode->avalue;
19375 if (opcode->tag == OT_unconditionalF)
eff0bc54 19376 inst.instruction |= 0xFU << 28;
c19d1205
ZW
19377 else
19378 inst.instruction |= inst.cond << 28;
19379 inst.size = INSN_SIZE;
5be8be5d 19380 if (!parse_operands (p, opcode->operands, /*thumb=*/FALSE))
477330fc
RM
19381 {
19382 it_fsm_pre_encode ();
19383 opcode->aencode ();
19384 it_fsm_post_encode ();
19385 }
ee065d83 19386 /* Arm mode bx is marked as both v4T and v5 because it's still required
477330fc 19387 on a hypothetical non-thumb v5 core. */
845b51d6 19388 if (is_bx)
e74cfd16 19389 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used, arm_ext_v4t);
ee065d83 19390 else
e74cfd16
PB
19391 ARM_MERGE_FEATURE_SETS (arm_arch_used, arm_arch_used,
19392 *opcode->avariant);
88714cb8
DG
19393
19394 check_neon_suffixes;
19395
cd000bff 19396 if (!inst.error)
c877a2f2
NC
19397 {
19398 mapping_state (MAP_ARM);
19399 }
b99bd4ef 19400 }
3e9e4fcf
JB
19401 else
19402 {
19403 as_bad (_("attempt to use an ARM instruction on a Thumb-only processor "
19404 "-- `%s'"), str);
19405 return;
19406 }
c19d1205
ZW
19407 output_inst (str);
19408}
b99bd4ef 19409
e07e6e58
NC
19410static void
19411check_it_blocks_finished (void)
19412{
19413#ifdef OBJ_ELF
19414 asection *sect;
19415
19416 for (sect = stdoutput->sections; sect != NULL; sect = sect->next)
19417 if (seg_info (sect)->tc_segment_info_data.current_it.state
19418 == MANUAL_IT_BLOCK)
19419 {
19420 as_warn (_("section '%s' finished with an open IT block."),
19421 sect->name);
19422 }
19423#else
19424 if (now_it.state == MANUAL_IT_BLOCK)
19425 as_warn (_("file finished with an open IT block."));
19426#endif
19427}
19428
c19d1205
ZW
19429/* Various frobbings of labels and their addresses. */
19430
19431void
19432arm_start_line_hook (void)
19433{
19434 last_label_seen = NULL;
b99bd4ef
NC
19435}
19436
c19d1205
ZW
19437void
19438arm_frob_label (symbolS * sym)
b99bd4ef 19439{
c19d1205 19440 last_label_seen = sym;
b99bd4ef 19441
c19d1205 19442 ARM_SET_THUMB (sym, thumb_mode);
b99bd4ef 19443
c19d1205
ZW
19444#if defined OBJ_COFF || defined OBJ_ELF
19445 ARM_SET_INTERWORK (sym, support_interwork);
19446#endif
b99bd4ef 19447
e07e6e58
NC
19448 force_automatic_it_block_close ();
19449
5f4273c7 19450 /* Note - do not allow local symbols (.Lxxx) to be labelled
c19d1205
ZW
19451 as Thumb functions. This is because these labels, whilst
19452 they exist inside Thumb code, are not the entry points for
19453 possible ARM->Thumb calls. Also, these labels can be used
19454 as part of a computed goto or switch statement. eg gcc
19455 can generate code that looks like this:
b99bd4ef 19456
c19d1205
ZW
19457 ldr r2, [pc, .Laaa]
19458 lsl r3, r3, #2
19459 ldr r2, [r3, r2]
19460 mov pc, r2
b99bd4ef 19461
c19d1205
ZW
19462 .Lbbb: .word .Lxxx
19463 .Lccc: .word .Lyyy
19464 ..etc...
19465 .Laaa: .word Lbbb
b99bd4ef 19466
c19d1205
ZW
19467 The first instruction loads the address of the jump table.
19468 The second instruction converts a table index into a byte offset.
19469 The third instruction gets the jump address out of the table.
19470 The fourth instruction performs the jump.
b99bd4ef 19471
c19d1205
ZW
19472 If the address stored at .Laaa is that of a symbol which has the
19473 Thumb_Func bit set, then the linker will arrange for this address
19474 to have the bottom bit set, which in turn would mean that the
19475 address computation performed by the third instruction would end
19476 up with the bottom bit set. Since the ARM is capable of unaligned
19477 word loads, the instruction would then load the incorrect address
19478 out of the jump table, and chaos would ensue. */
19479 if (label_is_thumb_function_name
19480 && (S_GET_NAME (sym)[0] != '.' || S_GET_NAME (sym)[1] != 'L')
19481 && (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
b99bd4ef 19482 {
c19d1205
ZW
19483 /* When the address of a Thumb function is taken the bottom
19484 bit of that address should be set. This will allow
19485 interworking between Arm and Thumb functions to work
19486 correctly. */
b99bd4ef 19487
c19d1205 19488 THUMB_SET_FUNC (sym, 1);
b99bd4ef 19489
c19d1205 19490 label_is_thumb_function_name = FALSE;
b99bd4ef 19491 }
07a53e5c 19492
07a53e5c 19493 dwarf2_emit_label (sym);
b99bd4ef
NC
19494}
19495
c921be7d 19496bfd_boolean
c19d1205 19497arm_data_in_code (void)
b99bd4ef 19498{
c19d1205 19499 if (thumb_mode && ! strncmp (input_line_pointer + 1, "data:", 5))
b99bd4ef 19500 {
c19d1205
ZW
19501 *input_line_pointer = '/';
19502 input_line_pointer += 5;
19503 *input_line_pointer = 0;
c921be7d 19504 return TRUE;
b99bd4ef
NC
19505 }
19506
c921be7d 19507 return FALSE;
b99bd4ef
NC
19508}
19509
c19d1205
ZW
19510char *
19511arm_canonicalize_symbol_name (char * name)
b99bd4ef 19512{
c19d1205 19513 int len;
b99bd4ef 19514
c19d1205
ZW
19515 if (thumb_mode && (len = strlen (name)) > 5
19516 && streq (name + len - 5, "/data"))
19517 *(name + len - 5) = 0;
b99bd4ef 19518
c19d1205 19519 return name;
b99bd4ef 19520}
c19d1205
ZW
19521\f
19522/* Table of all register names defined by default. The user can
19523 define additional names with .req. Note that all register names
19524 should appear in both upper and lowercase variants. Some registers
19525 also have mixed-case names. */
b99bd4ef 19526
dcbf9037 19527#define REGDEF(s,n,t) { #s, n, REG_TYPE_##t, TRUE, 0 }
c19d1205 19528#define REGNUM(p,n,t) REGDEF(p##n, n, t)
5287ad62 19529#define REGNUM2(p,n,t) REGDEF(p##n, 2 * n, t)
c19d1205
ZW
19530#define REGSET(p,t) \
19531 REGNUM(p, 0,t), REGNUM(p, 1,t), REGNUM(p, 2,t), REGNUM(p, 3,t), \
19532 REGNUM(p, 4,t), REGNUM(p, 5,t), REGNUM(p, 6,t), REGNUM(p, 7,t), \
19533 REGNUM(p, 8,t), REGNUM(p, 9,t), REGNUM(p,10,t), REGNUM(p,11,t), \
19534 REGNUM(p,12,t), REGNUM(p,13,t), REGNUM(p,14,t), REGNUM(p,15,t)
5287ad62
JB
19535#define REGSETH(p,t) \
19536 REGNUM(p,16,t), REGNUM(p,17,t), REGNUM(p,18,t), REGNUM(p,19,t), \
19537 REGNUM(p,20,t), REGNUM(p,21,t), REGNUM(p,22,t), REGNUM(p,23,t), \
19538 REGNUM(p,24,t), REGNUM(p,25,t), REGNUM(p,26,t), REGNUM(p,27,t), \
19539 REGNUM(p,28,t), REGNUM(p,29,t), REGNUM(p,30,t), REGNUM(p,31,t)
19540#define REGSET2(p,t) \
19541 REGNUM2(p, 0,t), REGNUM2(p, 1,t), REGNUM2(p, 2,t), REGNUM2(p, 3,t), \
19542 REGNUM2(p, 4,t), REGNUM2(p, 5,t), REGNUM2(p, 6,t), REGNUM2(p, 7,t), \
19543 REGNUM2(p, 8,t), REGNUM2(p, 9,t), REGNUM2(p,10,t), REGNUM2(p,11,t), \
19544 REGNUM2(p,12,t), REGNUM2(p,13,t), REGNUM2(p,14,t), REGNUM2(p,15,t)
90ec0d68
MGD
19545#define SPLRBANK(base,bank,t) \
19546 REGDEF(lr_##bank, 768|((base+0)<<16), t), \
19547 REGDEF(sp_##bank, 768|((base+1)<<16), t), \
19548 REGDEF(spsr_##bank, 768|(base<<16)|SPSR_BIT, t), \
19549 REGDEF(LR_##bank, 768|((base+0)<<16), t), \
19550 REGDEF(SP_##bank, 768|((base+1)<<16), t), \
19551 REGDEF(SPSR_##bank, 768|(base<<16)|SPSR_BIT, t)
7ed4c4c5 19552
c19d1205 19553static const struct reg_entry reg_names[] =
7ed4c4c5 19554{
c19d1205
ZW
19555 /* ARM integer registers. */
19556 REGSET(r, RN), REGSET(R, RN),
7ed4c4c5 19557
c19d1205
ZW
19558 /* ATPCS synonyms. */
19559 REGDEF(a1,0,RN), REGDEF(a2,1,RN), REGDEF(a3, 2,RN), REGDEF(a4, 3,RN),
19560 REGDEF(v1,4,RN), REGDEF(v2,5,RN), REGDEF(v3, 6,RN), REGDEF(v4, 7,RN),
19561 REGDEF(v5,8,RN), REGDEF(v6,9,RN), REGDEF(v7,10,RN), REGDEF(v8,11,RN),
7ed4c4c5 19562
c19d1205
ZW
19563 REGDEF(A1,0,RN), REGDEF(A2,1,RN), REGDEF(A3, 2,RN), REGDEF(A4, 3,RN),
19564 REGDEF(V1,4,RN), REGDEF(V2,5,RN), REGDEF(V3, 6,RN), REGDEF(V4, 7,RN),
19565 REGDEF(V5,8,RN), REGDEF(V6,9,RN), REGDEF(V7,10,RN), REGDEF(V8,11,RN),
7ed4c4c5 19566
c19d1205
ZW
19567 /* Well-known aliases. */
19568 REGDEF(wr, 7,RN), REGDEF(sb, 9,RN), REGDEF(sl,10,RN), REGDEF(fp,11,RN),
19569 REGDEF(ip,12,RN), REGDEF(sp,13,RN), REGDEF(lr,14,RN), REGDEF(pc,15,RN),
19570
19571 REGDEF(WR, 7,RN), REGDEF(SB, 9,RN), REGDEF(SL,10,RN), REGDEF(FP,11,RN),
19572 REGDEF(IP,12,RN), REGDEF(SP,13,RN), REGDEF(LR,14,RN), REGDEF(PC,15,RN),
19573
19574 /* Coprocessor numbers. */
19575 REGSET(p, CP), REGSET(P, CP),
19576
19577 /* Coprocessor register numbers. The "cr" variants are for backward
19578 compatibility. */
19579 REGSET(c, CN), REGSET(C, CN),
19580 REGSET(cr, CN), REGSET(CR, CN),
19581
90ec0d68
MGD
19582 /* ARM banked registers. */
19583 REGDEF(R8_usr,512|(0<<16),RNB), REGDEF(r8_usr,512|(0<<16),RNB),
19584 REGDEF(R9_usr,512|(1<<16),RNB), REGDEF(r9_usr,512|(1<<16),RNB),
19585 REGDEF(R10_usr,512|(2<<16),RNB), REGDEF(r10_usr,512|(2<<16),RNB),
19586 REGDEF(R11_usr,512|(3<<16),RNB), REGDEF(r11_usr,512|(3<<16),RNB),
19587 REGDEF(R12_usr,512|(4<<16),RNB), REGDEF(r12_usr,512|(4<<16),RNB),
19588 REGDEF(SP_usr,512|(5<<16),RNB), REGDEF(sp_usr,512|(5<<16),RNB),
19589 REGDEF(LR_usr,512|(6<<16),RNB), REGDEF(lr_usr,512|(6<<16),RNB),
19590
19591 REGDEF(R8_fiq,512|(8<<16),RNB), REGDEF(r8_fiq,512|(8<<16),RNB),
19592 REGDEF(R9_fiq,512|(9<<16),RNB), REGDEF(r9_fiq,512|(9<<16),RNB),
19593 REGDEF(R10_fiq,512|(10<<16),RNB), REGDEF(r10_fiq,512|(10<<16),RNB),
19594 REGDEF(R11_fiq,512|(11<<16),RNB), REGDEF(r11_fiq,512|(11<<16),RNB),
19595 REGDEF(R12_fiq,512|(12<<16),RNB), REGDEF(r12_fiq,512|(12<<16),RNB),
1472d06f 19596 REGDEF(SP_fiq,512|(13<<16),RNB), REGDEF(sp_fiq,512|(13<<16),RNB),
90ec0d68
MGD
19597 REGDEF(LR_fiq,512|(14<<16),RNB), REGDEF(lr_fiq,512|(14<<16),RNB),
19598 REGDEF(SPSR_fiq,512|(14<<16)|SPSR_BIT,RNB), REGDEF(spsr_fiq,512|(14<<16)|SPSR_BIT,RNB),
19599
19600 SPLRBANK(0,IRQ,RNB), SPLRBANK(0,irq,RNB),
19601 SPLRBANK(2,SVC,RNB), SPLRBANK(2,svc,RNB),
19602 SPLRBANK(4,ABT,RNB), SPLRBANK(4,abt,RNB),
19603 SPLRBANK(6,UND,RNB), SPLRBANK(6,und,RNB),
19604 SPLRBANK(12,MON,RNB), SPLRBANK(12,mon,RNB),
19605 REGDEF(elr_hyp,768|(14<<16),RNB), REGDEF(ELR_hyp,768|(14<<16),RNB),
19606 REGDEF(sp_hyp,768|(15<<16),RNB), REGDEF(SP_hyp,768|(15<<16),RNB),
fa94de6b 19607 REGDEF(spsr_hyp,768|(14<<16)|SPSR_BIT,RNB),
90ec0d68
MGD
19608 REGDEF(SPSR_hyp,768|(14<<16)|SPSR_BIT,RNB),
19609
c19d1205
ZW
19610 /* FPA registers. */
19611 REGNUM(f,0,FN), REGNUM(f,1,FN), REGNUM(f,2,FN), REGNUM(f,3,FN),
19612 REGNUM(f,4,FN), REGNUM(f,5,FN), REGNUM(f,6,FN), REGNUM(f,7, FN),
19613
19614 REGNUM(F,0,FN), REGNUM(F,1,FN), REGNUM(F,2,FN), REGNUM(F,3,FN),
19615 REGNUM(F,4,FN), REGNUM(F,5,FN), REGNUM(F,6,FN), REGNUM(F,7, FN),
19616
19617 /* VFP SP registers. */
5287ad62
JB
19618 REGSET(s,VFS), REGSET(S,VFS),
19619 REGSETH(s,VFS), REGSETH(S,VFS),
c19d1205
ZW
19620
19621 /* VFP DP Registers. */
5287ad62
JB
19622 REGSET(d,VFD), REGSET(D,VFD),
19623 /* Extra Neon DP registers. */
19624 REGSETH(d,VFD), REGSETH(D,VFD),
19625
19626 /* Neon QP registers. */
19627 REGSET2(q,NQ), REGSET2(Q,NQ),
c19d1205
ZW
19628
19629 /* VFP control registers. */
19630 REGDEF(fpsid,0,VFC), REGDEF(fpscr,1,VFC), REGDEF(fpexc,8,VFC),
19631 REGDEF(FPSID,0,VFC), REGDEF(FPSCR,1,VFC), REGDEF(FPEXC,8,VFC),
cd2cf30b
PB
19632 REGDEF(fpinst,9,VFC), REGDEF(fpinst2,10,VFC),
19633 REGDEF(FPINST,9,VFC), REGDEF(FPINST2,10,VFC),
19634 REGDEF(mvfr0,7,VFC), REGDEF(mvfr1,6,VFC),
19635 REGDEF(MVFR0,7,VFC), REGDEF(MVFR1,6,VFC),
40c7d507 19636 REGDEF(mvfr2,5,VFC), REGDEF(MVFR2,5,VFC),
c19d1205
ZW
19637
19638 /* Maverick DSP coprocessor registers. */
19639 REGSET(mvf,MVF), REGSET(mvd,MVD), REGSET(mvfx,MVFX), REGSET(mvdx,MVDX),
19640 REGSET(MVF,MVF), REGSET(MVD,MVD), REGSET(MVFX,MVFX), REGSET(MVDX,MVDX),
19641
19642 REGNUM(mvax,0,MVAX), REGNUM(mvax,1,MVAX),
19643 REGNUM(mvax,2,MVAX), REGNUM(mvax,3,MVAX),
19644 REGDEF(dspsc,0,DSPSC),
19645
19646 REGNUM(MVAX,0,MVAX), REGNUM(MVAX,1,MVAX),
19647 REGNUM(MVAX,2,MVAX), REGNUM(MVAX,3,MVAX),
19648 REGDEF(DSPSC,0,DSPSC),
19649
19650 /* iWMMXt data registers - p0, c0-15. */
19651 REGSET(wr,MMXWR), REGSET(wR,MMXWR), REGSET(WR, MMXWR),
19652
19653 /* iWMMXt control registers - p1, c0-3. */
19654 REGDEF(wcid, 0,MMXWC), REGDEF(wCID, 0,MMXWC), REGDEF(WCID, 0,MMXWC),
19655 REGDEF(wcon, 1,MMXWC), REGDEF(wCon, 1,MMXWC), REGDEF(WCON, 1,MMXWC),
19656 REGDEF(wcssf, 2,MMXWC), REGDEF(wCSSF, 2,MMXWC), REGDEF(WCSSF, 2,MMXWC),
19657 REGDEF(wcasf, 3,MMXWC), REGDEF(wCASF, 3,MMXWC), REGDEF(WCASF, 3,MMXWC),
19658
19659 /* iWMMXt scalar (constant/offset) registers - p1, c8-11. */
19660 REGDEF(wcgr0, 8,MMXWCG), REGDEF(wCGR0, 8,MMXWCG), REGDEF(WCGR0, 8,MMXWCG),
19661 REGDEF(wcgr1, 9,MMXWCG), REGDEF(wCGR1, 9,MMXWCG), REGDEF(WCGR1, 9,MMXWCG),
19662 REGDEF(wcgr2,10,MMXWCG), REGDEF(wCGR2,10,MMXWCG), REGDEF(WCGR2,10,MMXWCG),
19663 REGDEF(wcgr3,11,MMXWCG), REGDEF(wCGR3,11,MMXWCG), REGDEF(WCGR3,11,MMXWCG),
19664
19665 /* XScale accumulator registers. */
19666 REGNUM(acc,0,XSCALE), REGNUM(ACC,0,XSCALE),
19667};
19668#undef REGDEF
19669#undef REGNUM
19670#undef REGSET
7ed4c4c5 19671
c19d1205
ZW
19672/* Table of all PSR suffixes. Bare "CPSR" and "SPSR" are handled
19673 within psr_required_here. */
19674static const struct asm_psr psrs[] =
19675{
19676 /* Backward compatibility notation. Note that "all" is no longer
19677 truly all possible PSR bits. */
19678 {"all", PSR_c | PSR_f},
19679 {"flg", PSR_f},
19680 {"ctl", PSR_c},
19681
19682 /* Individual flags. */
19683 {"f", PSR_f},
19684 {"c", PSR_c},
19685 {"x", PSR_x},
19686 {"s", PSR_s},
59b42a0d 19687
c19d1205
ZW
19688 /* Combinations of flags. */
19689 {"fs", PSR_f | PSR_s},
19690 {"fx", PSR_f | PSR_x},
19691 {"fc", PSR_f | PSR_c},
19692 {"sf", PSR_s | PSR_f},
19693 {"sx", PSR_s | PSR_x},
19694 {"sc", PSR_s | PSR_c},
19695 {"xf", PSR_x | PSR_f},
19696 {"xs", PSR_x | PSR_s},
19697 {"xc", PSR_x | PSR_c},
19698 {"cf", PSR_c | PSR_f},
19699 {"cs", PSR_c | PSR_s},
19700 {"cx", PSR_c | PSR_x},
19701 {"fsx", PSR_f | PSR_s | PSR_x},
19702 {"fsc", PSR_f | PSR_s | PSR_c},
19703 {"fxs", PSR_f | PSR_x | PSR_s},
19704 {"fxc", PSR_f | PSR_x | PSR_c},
19705 {"fcs", PSR_f | PSR_c | PSR_s},
19706 {"fcx", PSR_f | PSR_c | PSR_x},
19707 {"sfx", PSR_s | PSR_f | PSR_x},
19708 {"sfc", PSR_s | PSR_f | PSR_c},
19709 {"sxf", PSR_s | PSR_x | PSR_f},
19710 {"sxc", PSR_s | PSR_x | PSR_c},
19711 {"scf", PSR_s | PSR_c | PSR_f},
19712 {"scx", PSR_s | PSR_c | PSR_x},
19713 {"xfs", PSR_x | PSR_f | PSR_s},
19714 {"xfc", PSR_x | PSR_f | PSR_c},
19715 {"xsf", PSR_x | PSR_s | PSR_f},
19716 {"xsc", PSR_x | PSR_s | PSR_c},
19717 {"xcf", PSR_x | PSR_c | PSR_f},
19718 {"xcs", PSR_x | PSR_c | PSR_s},
19719 {"cfs", PSR_c | PSR_f | PSR_s},
19720 {"cfx", PSR_c | PSR_f | PSR_x},
19721 {"csf", PSR_c | PSR_s | PSR_f},
19722 {"csx", PSR_c | PSR_s | PSR_x},
19723 {"cxf", PSR_c | PSR_x | PSR_f},
19724 {"cxs", PSR_c | PSR_x | PSR_s},
19725 {"fsxc", PSR_f | PSR_s | PSR_x | PSR_c},
19726 {"fscx", PSR_f | PSR_s | PSR_c | PSR_x},
19727 {"fxsc", PSR_f | PSR_x | PSR_s | PSR_c},
19728 {"fxcs", PSR_f | PSR_x | PSR_c | PSR_s},
19729 {"fcsx", PSR_f | PSR_c | PSR_s | PSR_x},
19730 {"fcxs", PSR_f | PSR_c | PSR_x | PSR_s},
19731 {"sfxc", PSR_s | PSR_f | PSR_x | PSR_c},
19732 {"sfcx", PSR_s | PSR_f | PSR_c | PSR_x},
19733 {"sxfc", PSR_s | PSR_x | PSR_f | PSR_c},
19734 {"sxcf", PSR_s | PSR_x | PSR_c | PSR_f},
19735 {"scfx", PSR_s | PSR_c | PSR_f | PSR_x},
19736 {"scxf", PSR_s | PSR_c | PSR_x | PSR_f},
19737 {"xfsc", PSR_x | PSR_f | PSR_s | PSR_c},
19738 {"xfcs", PSR_x | PSR_f | PSR_c | PSR_s},
19739 {"xsfc", PSR_x | PSR_s | PSR_f | PSR_c},
19740 {"xscf", PSR_x | PSR_s | PSR_c | PSR_f},
19741 {"xcfs", PSR_x | PSR_c | PSR_f | PSR_s},
19742 {"xcsf", PSR_x | PSR_c | PSR_s | PSR_f},
19743 {"cfsx", PSR_c | PSR_f | PSR_s | PSR_x},
19744 {"cfxs", PSR_c | PSR_f | PSR_x | PSR_s},
19745 {"csfx", PSR_c | PSR_s | PSR_f | PSR_x},
19746 {"csxf", PSR_c | PSR_s | PSR_x | PSR_f},
19747 {"cxfs", PSR_c | PSR_x | PSR_f | PSR_s},
19748 {"cxsf", PSR_c | PSR_x | PSR_s | PSR_f},
19749};
19750
62b3e311
PB
19751/* Table of V7M psr names. */
19752static const struct asm_psr v7m_psrs[] =
19753{
1a336194
TP
19754 {"apsr", 0x0 }, {"APSR", 0x0 },
19755 {"iapsr", 0x1 }, {"IAPSR", 0x1 },
19756 {"eapsr", 0x2 }, {"EAPSR", 0x2 },
19757 {"psr", 0x3 }, {"PSR", 0x3 },
19758 {"xpsr", 0x3 }, {"XPSR", 0x3 }, {"xPSR", 3 },
19759 {"ipsr", 0x5 }, {"IPSR", 0x5 },
19760 {"epsr", 0x6 }, {"EPSR", 0x6 },
19761 {"iepsr", 0x7 }, {"IEPSR", 0x7 },
19762 {"msp", 0x8 }, {"MSP", 0x8 },
19763 {"psp", 0x9 }, {"PSP", 0x9 },
19764 {"msplim", 0xa }, {"MSPLIM", 0xa },
19765 {"psplim", 0xb }, {"PSPLIM", 0xb },
19766 {"primask", 0x10}, {"PRIMASK", 0x10},
19767 {"basepri", 0x11}, {"BASEPRI", 0x11},
19768 {"basepri_max", 0x12}, {"BASEPRI_MAX", 0x12},
1a336194
TP
19769 {"faultmask", 0x13}, {"FAULTMASK", 0x13},
19770 {"control", 0x14}, {"CONTROL", 0x14},
19771 {"msp_ns", 0x88}, {"MSP_NS", 0x88},
19772 {"psp_ns", 0x89}, {"PSP_NS", 0x89},
19773 {"msplim_ns", 0x8a}, {"MSPLIM_NS", 0x8a},
19774 {"psplim_ns", 0x8b}, {"PSPLIM_NS", 0x8b},
19775 {"primask_ns", 0x90}, {"PRIMASK_NS", 0x90},
19776 {"basepri_ns", 0x91}, {"BASEPRI_NS", 0x91},
19777 {"faultmask_ns", 0x93}, {"FAULTMASK_NS", 0x93},
19778 {"control_ns", 0x94}, {"CONTROL_NS", 0x94},
19779 {"sp_ns", 0x98}, {"SP_NS", 0x98 }
62b3e311
PB
19780};
19781
c19d1205
ZW
19782/* Table of all shift-in-operand names. */
19783static const struct asm_shift_name shift_names [] =
b99bd4ef 19784{
c19d1205
ZW
19785 { "asl", SHIFT_LSL }, { "ASL", SHIFT_LSL },
19786 { "lsl", SHIFT_LSL }, { "LSL", SHIFT_LSL },
19787 { "lsr", SHIFT_LSR }, { "LSR", SHIFT_LSR },
19788 { "asr", SHIFT_ASR }, { "ASR", SHIFT_ASR },
19789 { "ror", SHIFT_ROR }, { "ROR", SHIFT_ROR },
19790 { "rrx", SHIFT_RRX }, { "RRX", SHIFT_RRX }
19791};
b99bd4ef 19792
c19d1205
ZW
19793/* Table of all explicit relocation names. */
19794#ifdef OBJ_ELF
19795static struct reloc_entry reloc_names[] =
19796{
19797 { "got", BFD_RELOC_ARM_GOT32 }, { "GOT", BFD_RELOC_ARM_GOT32 },
19798 { "gotoff", BFD_RELOC_ARM_GOTOFF }, { "GOTOFF", BFD_RELOC_ARM_GOTOFF },
19799 { "plt", BFD_RELOC_ARM_PLT32 }, { "PLT", BFD_RELOC_ARM_PLT32 },
19800 { "target1", BFD_RELOC_ARM_TARGET1 }, { "TARGET1", BFD_RELOC_ARM_TARGET1 },
19801 { "target2", BFD_RELOC_ARM_TARGET2 }, { "TARGET2", BFD_RELOC_ARM_TARGET2 },
19802 { "sbrel", BFD_RELOC_ARM_SBREL32 }, { "SBREL", BFD_RELOC_ARM_SBREL32 },
19803 { "tlsgd", BFD_RELOC_ARM_TLS_GD32}, { "TLSGD", BFD_RELOC_ARM_TLS_GD32},
19804 { "tlsldm", BFD_RELOC_ARM_TLS_LDM32}, { "TLSLDM", BFD_RELOC_ARM_TLS_LDM32},
19805 { "tlsldo", BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO", BFD_RELOC_ARM_TLS_LDO32},
19806 { "gottpoff",BFD_RELOC_ARM_TLS_IE32}, { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
b43420e6 19807 { "tpoff", BFD_RELOC_ARM_TLS_LE32}, { "TPOFF", BFD_RELOC_ARM_TLS_LE32},
0855e32b
NS
19808 { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
19809 { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
477330fc 19810 { "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
0855e32b 19811 { "tlscall", BFD_RELOC_ARM_TLS_CALL},
477330fc 19812 { "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
0855e32b 19813 { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
188fd7ae
CL
19814 { "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ},
19815 { "gotfuncdesc", BFD_RELOC_ARM_GOTFUNCDESC },
19816 { "GOTFUNCDESC", BFD_RELOC_ARM_GOTFUNCDESC },
19817 { "gotofffuncdesc", BFD_RELOC_ARM_GOTOFFFUNCDESC },
19818 { "GOTOFFFUNCDESC", BFD_RELOC_ARM_GOTOFFFUNCDESC },
19819 { "funcdesc", BFD_RELOC_ARM_FUNCDESC },
5c5a4843
CL
19820 { "FUNCDESC", BFD_RELOC_ARM_FUNCDESC },
19821 { "tlsgd_fdpic", BFD_RELOC_ARM_TLS_GD32_FDPIC }, { "TLSGD_FDPIC", BFD_RELOC_ARM_TLS_GD32_FDPIC },
19822 { "tlsldm_fdpic", BFD_RELOC_ARM_TLS_LDM32_FDPIC }, { "TLSLDM_FDPIC", BFD_RELOC_ARM_TLS_LDM32_FDPIC },
19823 { "gottpoff_fdpic", BFD_RELOC_ARM_TLS_IE32_FDPIC }, { "GOTTPOFF_FDIC", BFD_RELOC_ARM_TLS_IE32_FDPIC },
c19d1205
ZW
19824};
19825#endif
b99bd4ef 19826
c19d1205
ZW
19827/* Table of all conditional affixes. 0xF is not defined as a condition code. */
19828static const struct asm_cond conds[] =
19829{
19830 {"eq", 0x0},
19831 {"ne", 0x1},
19832 {"cs", 0x2}, {"hs", 0x2},
19833 {"cc", 0x3}, {"ul", 0x3}, {"lo", 0x3},
19834 {"mi", 0x4},
19835 {"pl", 0x5},
19836 {"vs", 0x6},
19837 {"vc", 0x7},
19838 {"hi", 0x8},
19839 {"ls", 0x9},
19840 {"ge", 0xa},
19841 {"lt", 0xb},
19842 {"gt", 0xc},
19843 {"le", 0xd},
19844 {"al", 0xe}
19845};
bfae80f2 19846
e797f7e0 19847#define UL_BARRIER(L,U,CODE,FEAT) \
823d2571
TG
19848 { L, CODE, ARM_FEATURE_CORE_LOW (FEAT) }, \
19849 { U, CODE, ARM_FEATURE_CORE_LOW (FEAT) }
e797f7e0 19850
62b3e311
PB
19851static struct asm_barrier_opt barrier_opt_names[] =
19852{
e797f7e0
MGD
19853 UL_BARRIER ("sy", "SY", 0xf, ARM_EXT_BARRIER),
19854 UL_BARRIER ("st", "ST", 0xe, ARM_EXT_BARRIER),
19855 UL_BARRIER ("ld", "LD", 0xd, ARM_EXT_V8),
19856 UL_BARRIER ("ish", "ISH", 0xb, ARM_EXT_BARRIER),
19857 UL_BARRIER ("sh", "SH", 0xb, ARM_EXT_BARRIER),
19858 UL_BARRIER ("ishst", "ISHST", 0xa, ARM_EXT_BARRIER),
19859 UL_BARRIER ("shst", "SHST", 0xa, ARM_EXT_BARRIER),
19860 UL_BARRIER ("ishld", "ISHLD", 0x9, ARM_EXT_V8),
19861 UL_BARRIER ("un", "UN", 0x7, ARM_EXT_BARRIER),
19862 UL_BARRIER ("nsh", "NSH", 0x7, ARM_EXT_BARRIER),
19863 UL_BARRIER ("unst", "UNST", 0x6, ARM_EXT_BARRIER),
19864 UL_BARRIER ("nshst", "NSHST", 0x6, ARM_EXT_BARRIER),
19865 UL_BARRIER ("nshld", "NSHLD", 0x5, ARM_EXT_V8),
19866 UL_BARRIER ("osh", "OSH", 0x3, ARM_EXT_BARRIER),
19867 UL_BARRIER ("oshst", "OSHST", 0x2, ARM_EXT_BARRIER),
19868 UL_BARRIER ("oshld", "OSHLD", 0x1, ARM_EXT_V8)
62b3e311
PB
19869};
19870
e797f7e0
MGD
19871#undef UL_BARRIER
19872
c19d1205
ZW
19873/* Table of ARM-format instructions. */
19874
19875/* Macros for gluing together operand strings. N.B. In all cases
19876 other than OPS0, the trailing OP_stop comes from default
19877 zero-initialization of the unspecified elements of the array. */
19878#define OPS0() { OP_stop, }
19879#define OPS1(a) { OP_##a, }
19880#define OPS2(a,b) { OP_##a,OP_##b, }
19881#define OPS3(a,b,c) { OP_##a,OP_##b,OP_##c, }
19882#define OPS4(a,b,c,d) { OP_##a,OP_##b,OP_##c,OP_##d, }
19883#define OPS5(a,b,c,d,e) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e, }
19884#define OPS6(a,b,c,d,e,f) { OP_##a,OP_##b,OP_##c,OP_##d,OP_##e,OP_##f, }
19885
5be8be5d
DG
19886/* These macros are similar to the OPSn, but do not prepend the OP_ prefix.
19887 This is useful when mixing operands for ARM and THUMB, i.e. using the
19888 MIX_ARM_THUMB_OPERANDS macro.
19889 In order to use these macros, prefix the number of operands with _
19890 e.g. _3. */
19891#define OPS_1(a) { a, }
19892#define OPS_2(a,b) { a,b, }
19893#define OPS_3(a,b,c) { a,b,c, }
19894#define OPS_4(a,b,c,d) { a,b,c,d, }
19895#define OPS_5(a,b,c,d,e) { a,b,c,d,e, }
19896#define OPS_6(a,b,c,d,e,f) { a,b,c,d,e,f, }
19897
c19d1205
ZW
19898/* These macros abstract out the exact format of the mnemonic table and
19899 save some repeated characters. */
19900
19901/* The normal sort of mnemonic; has a Thumb variant; takes a conditional suffix. */
19902#define TxCE(mnem, op, top, nops, ops, ae, te) \
21d799b5 19903 { mnem, OPS##nops ops, OT_csuffix, 0x##op, top, ARM_VARIANT, \
1887dd22 19904 THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
19905
19906/* Two variants of the above - TCE for a numeric Thumb opcode, tCE for
19907 a T_MNEM_xyz enumerator. */
19908#define TCE(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 19909 TxCE (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 19910#define tCE(mnem, aop, top, nops, ops, ae, te) \
21d799b5 19911 TxCE (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205
ZW
19912
19913/* Second most common sort of mnemonic: has a Thumb variant, takes a conditional
19914 infix after the third character. */
19915#define TxC3(mnem, op, top, nops, ops, ae, te) \
21d799b5 19916 { mnem, OPS##nops ops, OT_cinfix3, 0x##op, top, ARM_VARIANT, \
1887dd22 19917 THUMB_VARIANT, do_##ae, do_##te }
088fa78e 19918#define TxC3w(mnem, op, top, nops, ops, ae, te) \
21d799b5 19919 { mnem, OPS##nops ops, OT_cinfix3_deprecated, 0x##op, top, ARM_VARIANT, \
088fa78e 19920 THUMB_VARIANT, do_##ae, do_##te }
c19d1205 19921#define TC3(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 19922 TxC3 (mnem, aop, 0x##top, nops, ops, ae, te)
088fa78e 19923#define TC3w(mnem, aop, top, nops, ops, ae, te) \
e07e6e58 19924 TxC3w (mnem, aop, 0x##top, nops, ops, ae, te)
c19d1205 19925#define tC3(mnem, aop, top, nops, ops, ae, te) \
21d799b5 19926 TxC3 (mnem, aop, T_MNEM##top, nops, ops, ae, te)
088fa78e 19927#define tC3w(mnem, aop, top, nops, ops, ae, te) \
21d799b5 19928 TxC3w (mnem, aop, T_MNEM##top, nops, ops, ae, te)
c19d1205 19929
c19d1205 19930/* Mnemonic that cannot be conditionalized. The ARM condition-code
dfa9f0d5
PB
19931 field is still 0xE. Many of the Thumb variants can be executed
19932 conditionally, so this is checked separately. */
c19d1205 19933#define TUE(mnem, op, top, nops, ops, ae, te) \
21d799b5 19934 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
1887dd22 19935 THUMB_VARIANT, do_##ae, do_##te }
c19d1205 19936
dd5181d5
KT
19937/* Same as TUE but the encoding function for ARM and Thumb modes is the same.
19938 Used by mnemonics that have very minimal differences in the encoding for
19939 ARM and Thumb variants and can be handled in a common function. */
19940#define TUEc(mnem, op, top, nops, ops, en) \
19941 { mnem, OPS##nops ops, OT_unconditional, 0x##op, 0x##top, ARM_VARIANT, \
19942 THUMB_VARIANT, do_##en, do_##en }
19943
c19d1205
ZW
19944/* Mnemonic that cannot be conditionalized, and bears 0xF in its ARM
19945 condition code field. */
19946#define TUF(mnem, op, top, nops, ops, ae, te) \
21d799b5 19947 { mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##top, ARM_VARIANT, \
1887dd22 19948 THUMB_VARIANT, do_##ae, do_##te }
c19d1205
ZW
19949
19950/* ARM-only variants of all the above. */
6a86118a 19951#define CE(mnem, op, nops, ops, ae) \
21d799b5 19952 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
6a86118a
NC
19953
19954#define C3(mnem, op, nops, ops, ae) \
19955 { #mnem, OPS##nops ops, OT_cinfix3, 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
19956
cf3cf39d
TP
19957/* Thumb-only variants of TCE and TUE. */
19958#define ToC(mnem, top, nops, ops, te) \
19959 { mnem, OPS##nops ops, OT_csuffix, 0x0, 0x##top, 0, THUMB_VARIANT, NULL, \
19960 do_##te }
cf3cf39d
TP
19961
19962#define ToU(mnem, top, nops, ops, te) \
19963 { mnem, OPS##nops ops, OT_unconditional, 0x0, 0x##top, 0, THUMB_VARIANT, \
19964 NULL, do_##te }
cf3cf39d 19965
4389b29a
AV
19966/* T_MNEM_xyz enumerator variants of ToC. */
19967#define toC(mnem, top, nops, ops, te) \
19968 { mnem, OPS##nops ops, OT_csuffix, 0x0, T_MNEM##top, 0, THUMB_VARIANT, NULL, \
19969 do_##te }
19970
f6b2b12d
AV
19971/* T_MNEM_xyz enumerator variants of ToU. */
19972#define toU(mnem, top, nops, ops, te) \
19973 { mnem, OPS##nops ops, OT_unconditional, 0x0, T_MNEM##top, 0, THUMB_VARIANT, \
19974 NULL, do_##te }
19975
e3cb604e
PB
19976/* Legacy mnemonics that always have conditional infix after the third
19977 character. */
19978#define CL(mnem, op, nops, ops, ae) \
21d799b5 19979 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
e3cb604e
PB
19980 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
19981
8f06b2d8
PB
19982/* Coprocessor instructions. Isomorphic between Arm and Thumb-2. */
19983#define cCE(mnem, op, nops, ops, ae) \
21d799b5 19984 { mnem, OPS##nops ops, OT_csuffix, 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
8f06b2d8 19985
e3cb604e
PB
19986/* Legacy coprocessor instructions where conditional infix and conditional
19987 suffix are ambiguous. For consistency this includes all FPA instructions,
19988 not just the potentially ambiguous ones. */
19989#define cCL(mnem, op, nops, ops, ae) \
21d799b5 19990 { mnem, OPS##nops ops, OT_cinfix3_legacy, \
e3cb604e
PB
19991 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
19992
19993/* Coprocessor, takes either a suffix or a position-3 infix
19994 (for an FPA corner case). */
19995#define C3E(mnem, op, nops, ops, ae) \
21d799b5 19996 { mnem, OPS##nops ops, OT_csuf_or_in3, \
e3cb604e 19997 0x##op, 0xe##op, ARM_VARIANT, ARM_VARIANT, do_##ae, do_##ae }
8f06b2d8 19998
6a86118a 19999#define xCM_(m1, m2, m3, op, nops, ops, ae) \
21d799b5
NC
20000 { m1 #m2 m3, OPS##nops ops, \
20001 sizeof (#m2) == 1 ? OT_odd_infix_unc : OT_odd_infix_0 + sizeof (m1) - 1, \
6a86118a
NC
20002 0x##op, 0x0, ARM_VARIANT, 0, do_##ae, NULL }
20003
20004#define CM(m1, m2, op, nops, ops, ae) \
e07e6e58
NC
20005 xCM_ (m1, , m2, op, nops, ops, ae), \
20006 xCM_ (m1, eq, m2, op, nops, ops, ae), \
20007 xCM_ (m1, ne, m2, op, nops, ops, ae), \
20008 xCM_ (m1, cs, m2, op, nops, ops, ae), \
20009 xCM_ (m1, hs, m2, op, nops, ops, ae), \
20010 xCM_ (m1, cc, m2, op, nops, ops, ae), \
20011 xCM_ (m1, ul, m2, op, nops, ops, ae), \
20012 xCM_ (m1, lo, m2, op, nops, ops, ae), \
20013 xCM_ (m1, mi, m2, op, nops, ops, ae), \
20014 xCM_ (m1, pl, m2, op, nops, ops, ae), \
20015 xCM_ (m1, vs, m2, op, nops, ops, ae), \
20016 xCM_ (m1, vc, m2, op, nops, ops, ae), \
20017 xCM_ (m1, hi, m2, op, nops, ops, ae), \
20018 xCM_ (m1, ls, m2, op, nops, ops, ae), \
20019 xCM_ (m1, ge, m2, op, nops, ops, ae), \
20020 xCM_ (m1, lt, m2, op, nops, ops, ae), \
20021 xCM_ (m1, gt, m2, op, nops, ops, ae), \
20022 xCM_ (m1, le, m2, op, nops, ops, ae), \
20023 xCM_ (m1, al, m2, op, nops, ops, ae)
6a86118a
NC
20024
20025#define UE(mnem, op, nops, ops, ae) \
20026 { #mnem, OPS##nops ops, OT_unconditional, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL }
20027
20028#define UF(mnem, op, nops, ops, ae) \
20029 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0, ARM_VARIANT, 0, do_##ae, NULL }
20030
5287ad62
JB
20031/* Neon data-processing. ARM versions are unconditional with cond=0xf.
20032 The Thumb and ARM variants are mostly the same (bits 0-23 and 24/28), so we
20033 use the same encoding function for each. */
20034#define NUF(mnem, op, nops, ops, enc) \
20035 { #mnem, OPS##nops ops, OT_unconditionalF, 0x##op, 0x##op, \
20036 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
20037
20038/* Neon data processing, version which indirects through neon_enc_tab for
20039 the various overloaded versions of opcodes. */
20040#define nUF(mnem, op, nops, ops, enc) \
21d799b5 20041 { #mnem, OPS##nops ops, OT_unconditionalF, N_MNEM##op, N_MNEM##op, \
5287ad62
JB
20042 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
20043
20044/* Neon insn with conditional suffix for the ARM version, non-overloaded
20045 version. */
037e8744
JB
20046#define NCE_tag(mnem, op, nops, ops, enc, tag) \
20047 { #mnem, OPS##nops ops, tag, 0x##op, 0x##op, ARM_VARIANT, \
5287ad62
JB
20048 THUMB_VARIANT, do_##enc, do_##enc }
20049
037e8744 20050#define NCE(mnem, op, nops, ops, enc) \
e07e6e58 20051 NCE_tag (mnem, op, nops, ops, enc, OT_csuffix)
037e8744
JB
20052
20053#define NCEF(mnem, op, nops, ops, enc) \
e07e6e58 20054 NCE_tag (mnem, op, nops, ops, enc, OT_csuffixF)
037e8744 20055
5287ad62 20056/* Neon insn with conditional suffix for the ARM version, overloaded types. */
037e8744 20057#define nCE_tag(mnem, op, nops, ops, enc, tag) \
21d799b5 20058 { #mnem, OPS##nops ops, tag, N_MNEM##op, N_MNEM##op, \
5287ad62
JB
20059 ARM_VARIANT, THUMB_VARIANT, do_##enc, do_##enc }
20060
037e8744 20061#define nCE(mnem, op, nops, ops, enc) \
e07e6e58 20062 nCE_tag (mnem, op, nops, ops, enc, OT_csuffix)
037e8744
JB
20063
20064#define nCEF(mnem, op, nops, ops, enc) \
e07e6e58 20065 nCE_tag (mnem, op, nops, ops, enc, OT_csuffixF)
037e8744 20066
c19d1205
ZW
20067#define do_0 0
20068
c19d1205 20069static const struct asm_opcode insns[] =
bfae80f2 20070{
74db7efb
NC
20071#define ARM_VARIANT & arm_ext_v1 /* Core ARM Instructions. */
20072#define THUMB_VARIANT & arm_ext_v4t
21d799b5
NC
20073 tCE("and", 0000000, _and, 3, (RR, oRR, SH), arit, t_arit3c),
20074 tC3("ands", 0100000, _ands, 3, (RR, oRR, SH), arit, t_arit3c),
20075 tCE("eor", 0200000, _eor, 3, (RR, oRR, SH), arit, t_arit3c),
20076 tC3("eors", 0300000, _eors, 3, (RR, oRR, SH), arit, t_arit3c),
20077 tCE("sub", 0400000, _sub, 3, (RR, oRR, SH), arit, t_add_sub),
20078 tC3("subs", 0500000, _subs, 3, (RR, oRR, SH), arit, t_add_sub),
20079 tCE("add", 0800000, _add, 3, (RR, oRR, SHG), arit, t_add_sub),
20080 tC3("adds", 0900000, _adds, 3, (RR, oRR, SHG), arit, t_add_sub),
20081 tCE("adc", 0a00000, _adc, 3, (RR, oRR, SH), arit, t_arit3c),
20082 tC3("adcs", 0b00000, _adcs, 3, (RR, oRR, SH), arit, t_arit3c),
20083 tCE("sbc", 0c00000, _sbc, 3, (RR, oRR, SH), arit, t_arit3),
20084 tC3("sbcs", 0d00000, _sbcs, 3, (RR, oRR, SH), arit, t_arit3),
20085 tCE("orr", 1800000, _orr, 3, (RR, oRR, SH), arit, t_arit3c),
20086 tC3("orrs", 1900000, _orrs, 3, (RR, oRR, SH), arit, t_arit3c),
20087 tCE("bic", 1c00000, _bic, 3, (RR, oRR, SH), arit, t_arit3),
20088 tC3("bics", 1d00000, _bics, 3, (RR, oRR, SH), arit, t_arit3),
c19d1205
ZW
20089
20090 /* The p-variants of tst/cmp/cmn/teq (below) are the pre-V6 mechanism
20091 for setting PSR flag bits. They are obsolete in V6 and do not
20092 have Thumb equivalents. */
21d799b5
NC
20093 tCE("tst", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
20094 tC3w("tsts", 1100000, _tst, 2, (RR, SH), cmp, t_mvn_tst),
20095 CL("tstp", 110f000, 2, (RR, SH), cmp),
20096 tCE("cmp", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
20097 tC3w("cmps", 1500000, _cmp, 2, (RR, SH), cmp, t_mov_cmp),
20098 CL("cmpp", 150f000, 2, (RR, SH), cmp),
20099 tCE("cmn", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
20100 tC3w("cmns", 1700000, _cmn, 2, (RR, SH), cmp, t_mvn_tst),
20101 CL("cmnp", 170f000, 2, (RR, SH), cmp),
20102
20103 tCE("mov", 1a00000, _mov, 2, (RR, SH), mov, t_mov_cmp),
72d98d16 20104 tC3("movs", 1b00000, _movs, 2, (RR, SHG), mov, t_mov_cmp),
21d799b5
NC
20105 tCE("mvn", 1e00000, _mvn, 2, (RR, SH), mov, t_mvn_tst),
20106 tC3("mvns", 1f00000, _mvns, 2, (RR, SH), mov, t_mvn_tst),
20107
20108 tCE("ldr", 4100000, _ldr, 2, (RR, ADDRGLDR),ldst, t_ldst),
5be8be5d
DG
20109 tC3("ldrb", 4500000, _ldrb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
20110 tCE("str", 4000000, _str, _2, (MIX_ARM_THUMB_OPERANDS (OP_RR,
20111 OP_RRnpc),
20112 OP_ADDRGLDR),ldst, t_ldst),
20113 tC3("strb", 4400000, _strb, 2, (RRnpc_npcsp, ADDRGLDR),ldst, t_ldst),
21d799b5
NC
20114
20115 tCE("stm", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20116 tC3("stmia", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20117 tC3("stmea", 8800000, _stmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20118 tCE("ldm", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20119 tC3("ldmia", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20120 tC3("ldmfd", 8900000, _ldmia, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20121
21d799b5
NC
20122 tCE("b", a000000, _b, 1, (EXPr), branch, t_branch),
20123 TCE("bl", b000000, f000f800, 1, (EXPr), bl, t_branch23),
bfae80f2 20124
c19d1205 20125 /* Pseudo ops. */
21d799b5 20126 tCE("adr", 28f0000, _adr, 2, (RR, EXP), adr, t_adr),
2fc8bdac 20127 C3(adrl, 28f0000, 2, (RR, EXP), adrl),
21d799b5 20128 tCE("nop", 1a00000, _nop, 1, (oI255c), nop, t_nop),
74db7efb 20129 tCE("udf", 7f000f0, _udf, 1, (oIffffb), bkpt, t_udf),
c19d1205
ZW
20130
20131 /* Thumb-compatibility pseudo ops. */
21d799b5
NC
20132 tCE("lsl", 1a00000, _lsl, 3, (RR, oRR, SH), shift, t_shift),
20133 tC3("lsls", 1b00000, _lsls, 3, (RR, oRR, SH), shift, t_shift),
20134 tCE("lsr", 1a00020, _lsr, 3, (RR, oRR, SH), shift, t_shift),
20135 tC3("lsrs", 1b00020, _lsrs, 3, (RR, oRR, SH), shift, t_shift),
20136 tCE("asr", 1a00040, _asr, 3, (RR, oRR, SH), shift, t_shift),
20137 tC3("asrs", 1b00040, _asrs, 3, (RR, oRR, SH), shift, t_shift),
20138 tCE("ror", 1a00060, _ror, 3, (RR, oRR, SH), shift, t_shift),
20139 tC3("rors", 1b00060, _rors, 3, (RR, oRR, SH), shift, t_shift),
20140 tCE("neg", 2600000, _neg, 2, (RR, RR), rd_rn, t_neg),
20141 tC3("negs", 2700000, _negs, 2, (RR, RR), rd_rn, t_neg),
20142 tCE("push", 92d0000, _push, 1, (REGLST), push_pop, t_push_pop),
20143 tCE("pop", 8bd0000, _pop, 1, (REGLST), push_pop, t_push_pop),
c19d1205 20144
16a4cf17 20145 /* These may simplify to neg. */
21d799b5
NC
20146 TCE("rsb", 0600000, ebc00000, 3, (RR, oRR, SH), arit, t_rsb),
20147 TC3("rsbs", 0700000, ebd00000, 3, (RR, oRR, SH), arit, t_rsb),
16a4cf17 20148
173205ca
TP
20149#undef THUMB_VARIANT
20150#define THUMB_VARIANT & arm_ext_os
20151
20152 TCE("swi", f000000, df00, 1, (EXPi), swi, t_swi),
20153 TCE("svc", f000000, df00, 1, (EXPi), swi, t_swi),
20154
c921be7d
NC
20155#undef THUMB_VARIANT
20156#define THUMB_VARIANT & arm_ext_v6
20157
21d799b5 20158 TCE("cpy", 1a00000, 4600, 2, (RR, RR), rd_rm, t_cpy),
c19d1205
ZW
20159
20160 /* V1 instructions with no Thumb analogue prior to V6T2. */
c921be7d
NC
20161#undef THUMB_VARIANT
20162#define THUMB_VARIANT & arm_ext_v6t2
20163
21d799b5
NC
20164 TCE("teq", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
20165 TC3w("teqs", 1300000, ea900f00, 2, (RR, SH), cmp, t_mvn_tst),
20166 CL("teqp", 130f000, 2, (RR, SH), cmp),
c19d1205 20167
5be8be5d
DG
20168 TC3("ldrt", 4300000, f8500e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
20169 TC3("ldrbt", 4700000, f8100e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
20170 TC3("strt", 4200000, f8400e00, 2, (RR_npcsp, ADDR), ldstt, t_ldstt),
20171 TC3("strbt", 4600000, f8000e00, 2, (RRnpc_npcsp, ADDR),ldstt, t_ldstt),
c19d1205 20172
21d799b5
NC
20173 TC3("stmdb", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20174 TC3("stmfd", 9000000, e9000000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205 20175
21d799b5
NC
20176 TC3("ldmdb", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
20177 TC3("ldmea", 9100000, e9100000, 2, (RRw, REGLST), ldmstm, t_ldmstm),
c19d1205
ZW
20178
20179 /* V1 instructions with no Thumb analogue at all. */
21d799b5 20180 CE("rsc", 0e00000, 3, (RR, oRR, SH), arit),
c19d1205
ZW
20181 C3(rscs, 0f00000, 3, (RR, oRR, SH), arit),
20182
20183 C3(stmib, 9800000, 2, (RRw, REGLST), ldmstm),
20184 C3(stmfa, 9800000, 2, (RRw, REGLST), ldmstm),
20185 C3(stmda, 8000000, 2, (RRw, REGLST), ldmstm),
20186 C3(stmed, 8000000, 2, (RRw, REGLST), ldmstm),
20187 C3(ldmib, 9900000, 2, (RRw, REGLST), ldmstm),
20188 C3(ldmed, 9900000, 2, (RRw, REGLST), ldmstm),
20189 C3(ldmda, 8100000, 2, (RRw, REGLST), ldmstm),
20190 C3(ldmfa, 8100000, 2, (RRw, REGLST), ldmstm),
20191
c921be7d
NC
20192#undef ARM_VARIANT
20193#define ARM_VARIANT & arm_ext_v2 /* ARM 2 - multiplies. */
20194#undef THUMB_VARIANT
20195#define THUMB_VARIANT & arm_ext_v4t
20196
21d799b5
NC
20197 tCE("mul", 0000090, _mul, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
20198 tC3("muls", 0100090, _muls, 3, (RRnpc, RRnpc, oRR), mul, t_mul),
c19d1205 20199
c921be7d
NC
20200#undef THUMB_VARIANT
20201#define THUMB_VARIANT & arm_ext_v6t2
20202
21d799b5 20203 TCE("mla", 0200090, fb000000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
c19d1205
ZW
20204 C3(mlas, 0300090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas),
20205
20206 /* Generic coprocessor instructions. */
21d799b5
NC
20207 TCE("cdp", e000000, ee000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
20208 TCE("ldc", c100000, ec100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20209 TC3("ldcl", c500000, ec500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20210 TCE("stc", c000000, ec000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20211 TC3("stcl", c400000, ec400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20212 TCE("mcr", e000010, ee000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
db472d6f 20213 TCE("mrc", e100010, ee100010, 6, (RCP, I7b, APSR_RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 20214
c921be7d
NC
20215#undef ARM_VARIANT
20216#define ARM_VARIANT & arm_ext_v2s /* ARM 3 - swp instructions. */
20217
21d799b5 20218 CE("swp", 1000090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
c19d1205
ZW
20219 C3(swpb, 1400090, 3, (RRnpc, RRnpc, RRnpcb), rd_rm_rn),
20220
c921be7d
NC
20221#undef ARM_VARIANT
20222#define ARM_VARIANT & arm_ext_v3 /* ARM 6 Status register instructions. */
20223#undef THUMB_VARIANT
20224#define THUMB_VARIANT & arm_ext_msr
20225
d2cd1205
JB
20226 TCE("mrs", 1000000, f3e08000, 2, (RRnpc, rPSR), mrs, t_mrs),
20227 TCE("msr", 120f000, f3808000, 2, (wPSR, RR_EXi), msr, t_msr),
c19d1205 20228
c921be7d
NC
20229#undef ARM_VARIANT
20230#define ARM_VARIANT & arm_ext_v3m /* ARM 7M long multiplies. */
20231#undef THUMB_VARIANT
20232#define THUMB_VARIANT & arm_ext_v6t2
20233
21d799b5
NC
20234 TCE("smull", 0c00090, fb800000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20235 CM("smull","s", 0d00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
20236 TCE("umull", 0800090, fba00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20237 CM("umull","s", 0900090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
20238 TCE("smlal", 0e00090, fbc00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20239 CM("smlal","s", 0f00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
20240 TCE("umlal", 0a00090, fbe00000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull, t_mull),
20241 CM("umlal","s", 0b00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mull),
c19d1205 20242
c921be7d
NC
20243#undef ARM_VARIANT
20244#define ARM_VARIANT & arm_ext_v4 /* ARM Architecture 4. */
20245#undef THUMB_VARIANT
20246#define THUMB_VARIANT & arm_ext_v4t
20247
5be8be5d
DG
20248 tC3("ldrh", 01000b0, _ldrh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20249 tC3("strh", 00000b0, _strh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20250 tC3("ldrsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20251 tC3("ldrsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
56c0a61f
RE
20252 tC3("ldsh", 01000f0, _ldrsh, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
20253 tC3("ldsb", 01000d0, _ldrsb, 2, (RRnpc_npcsp, ADDRGLDRS), ldstv4, t_ldst),
c19d1205 20254
c921be7d
NC
20255#undef ARM_VARIANT
20256#define ARM_VARIANT & arm_ext_v4t_5
20257
c19d1205
ZW
20258 /* ARM Architecture 4T. */
20259 /* Note: bx (and blx) are required on V5, even if the processor does
20260 not support Thumb. */
21d799b5 20261 TCE("bx", 12fff10, 4700, 1, (RR), bx, t_bx),
c19d1205 20262
c921be7d
NC
20263#undef ARM_VARIANT
20264#define ARM_VARIANT & arm_ext_v5 /* ARM Architecture 5T. */
20265#undef THUMB_VARIANT
20266#define THUMB_VARIANT & arm_ext_v5t
20267
c19d1205
ZW
20268 /* Note: blx has 2 variants; the .value coded here is for
20269 BLX(2). Only this variant has conditional execution. */
21d799b5
NC
20270 TCE("blx", 12fff30, 4780, 1, (RR_EXr), blx, t_blx),
20271 TUE("bkpt", 1200070, be00, 1, (oIffffb), bkpt, t_bkpt),
c19d1205 20272
c921be7d
NC
20273#undef THUMB_VARIANT
20274#define THUMB_VARIANT & arm_ext_v6t2
20275
21d799b5
NC
20276 TCE("clz", 16f0f10, fab0f080, 2, (RRnpc, RRnpc), rd_rm, t_clz),
20277 TUF("ldc2", c100000, fc100000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20278 TUF("ldc2l", c500000, fc500000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20279 TUF("stc2", c000000, fc000000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20280 TUF("stc2l", c400000, fc400000, 3, (RCP, RCN, ADDRGLDC), lstc, lstc),
20281 TUF("cdp2", e000000, fe000000, 6, (RCP, I15b, RCN, RCN, RCN, oI7b), cdp, cdp),
20282 TUF("mcr2", e000010, fe000010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
20283 TUF("mrc2", e100010, fe100010, 6, (RCP, I7b, RR, RCN, RCN, oI7b), co_reg, co_reg),
c19d1205 20284
c921be7d 20285#undef ARM_VARIANT
74db7efb
NC
20286#define ARM_VARIANT & arm_ext_v5exp /* ARM Architecture 5TExP. */
20287#undef THUMB_VARIANT
20288#define THUMB_VARIANT & arm_ext_v5exp
c921be7d 20289
21d799b5
NC
20290 TCE("smlabb", 1000080, fb100000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20291 TCE("smlatb", 10000a0, fb100020, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20292 TCE("smlabt", 10000c0, fb100010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20293 TCE("smlatt", 10000e0, fb100030, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 20294
21d799b5
NC
20295 TCE("smlawb", 1200080, fb300000, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
20296 TCE("smlawt", 12000c0, fb300010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smla, t_mla),
c19d1205 20297
21d799b5
NC
20298 TCE("smlalbb", 1400080, fbc00080, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
20299 TCE("smlaltb", 14000a0, fbc000a0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
20300 TCE("smlalbt", 14000c0, fbc00090, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
20301 TCE("smlaltt", 14000e0, fbc000b0, 4, (RRnpc, RRnpc, RRnpc, RRnpc), smlal, t_mlal),
c19d1205 20302
21d799b5
NC
20303 TCE("smulbb", 1600080, fb10f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20304 TCE("smultb", 16000a0, fb10f020, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20305 TCE("smulbt", 16000c0, fb10f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20306 TCE("smultt", 16000e0, fb10f030, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 20307
21d799b5
NC
20308 TCE("smulwb", 12000a0, fb30f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20309 TCE("smulwt", 12000e0, fb30f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
c19d1205 20310
03ee1b7f
NC
20311 TCE("qadd", 1000050, fa80f080, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
20312 TCE("qdadd", 1400050, fa80f090, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
20313 TCE("qsub", 1200050, fa80f0a0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
20314 TCE("qdsub", 1600050, fa80f0b0, 3, (RRnpc, RRnpc, RRnpc), rd_rm_rn, t_simd2),
c19d1205 20315
c921be7d 20316#undef ARM_VARIANT
74db7efb
NC
20317#define ARM_VARIANT & arm_ext_v5e /* ARM Architecture 5TE. */
20318#undef THUMB_VARIANT
20319#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 20320
21d799b5 20321 TUF("pld", 450f000, f810f000, 1, (ADDR), pld, t_pld),
5be8be5d
DG
20322 TC3("ldrd", 00000d0, e8500000, 3, (RRnpc_npcsp, oRRnpc_npcsp, ADDRGLDRS),
20323 ldrd, t_ldstd),
20324 TC3("strd", 00000f0, e8400000, 3, (RRnpc_npcsp, oRRnpc_npcsp,
20325 ADDRGLDRS), ldrd, t_ldstd),
c19d1205 20326
21d799b5
NC
20327 TCE("mcrr", c400000, ec400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
20328 TCE("mrrc", c500000, ec500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
c19d1205 20329
c921be7d
NC
20330#undef ARM_VARIANT
20331#define ARM_VARIANT & arm_ext_v5j /* ARM Architecture 5TEJ. */
20332
21d799b5 20333 TCE("bxj", 12fff20, f3c08f00, 1, (RR), bxj, t_bxj),
c19d1205 20334
c921be7d
NC
20335#undef ARM_VARIANT
20336#define ARM_VARIANT & arm_ext_v6 /* ARM V6. */
20337#undef THUMB_VARIANT
20338#define THUMB_VARIANT & arm_ext_v6
20339
21d799b5
NC
20340 TUF("cpsie", 1080000, b660, 2, (CPSF, oI31b), cpsi, t_cpsi),
20341 TUF("cpsid", 10c0000, b670, 2, (CPSF, oI31b), cpsi, t_cpsi),
20342 tCE("rev", 6bf0f30, _rev, 2, (RRnpc, RRnpc), rd_rm, t_rev),
20343 tCE("rev16", 6bf0fb0, _rev16, 2, (RRnpc, RRnpc), rd_rm, t_rev),
20344 tCE("revsh", 6ff0fb0, _revsh, 2, (RRnpc, RRnpc), rd_rm, t_rev),
20345 tCE("sxth", 6bf0070, _sxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20346 tCE("uxth", 6ff0070, _uxth, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20347 tCE("sxtb", 6af0070, _sxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20348 tCE("uxtb", 6ef0070, _uxtb, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20349 TUF("setend", 1010000, b650, 1, (ENDI), setend, t_setend),
c19d1205 20350
c921be7d 20351#undef THUMB_VARIANT
ff8646ee 20352#define THUMB_VARIANT & arm_ext_v6t2_v8m
c921be7d 20353
5be8be5d
DG
20354 TCE("ldrex", 1900f9f, e8500f00, 2, (RRnpc_npcsp, ADDR), ldrex, t_ldrex),
20355 TCE("strex", 1800f90, e8400000, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
20356 strex, t_strex),
ff8646ee
TP
20357#undef THUMB_VARIANT
20358#define THUMB_VARIANT & arm_ext_v6t2
20359
21d799b5
NC
20360 TUF("mcrr2", c400000, fc400000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
20361 TUF("mrrc2", c500000, fc500000, 5, (RCP, I15b, RRnpc, RRnpc, RCN), co_reg2c, co_reg2c),
62b3e311 20362
21d799b5
NC
20363 TCE("ssat", 6a00010, f3000000, 4, (RRnpc, I32, RRnpc, oSHllar),ssat, t_ssat),
20364 TCE("usat", 6e00010, f3800000, 4, (RRnpc, I31, RRnpc, oSHllar),usat, t_usat),
62b3e311 20365
9e3c6df6 20366/* ARM V6 not included in V7M. */
c921be7d
NC
20367#undef THUMB_VARIANT
20368#define THUMB_VARIANT & arm_ext_v6_notm
9e3c6df6 20369 TUF("rfeia", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6 20370 TUF("rfe", 8900a00, e990c000, 1, (RRw), rfe, rfe),
9e3c6df6
PB
20371 UF(rfeib, 9900a00, 1, (RRw), rfe),
20372 UF(rfeda, 8100a00, 1, (RRw), rfe),
20373 TUF("rfedb", 9100a00, e810c000, 1, (RRw), rfe, rfe),
20374 TUF("rfefd", 8900a00, e990c000, 1, (RRw), rfe, rfe),
d709e4e6
RE
20375 UF(rfefa, 8100a00, 1, (RRw), rfe),
20376 TUF("rfeea", 9100a00, e810c000, 1, (RRw), rfe, rfe),
20377 UF(rfeed, 9900a00, 1, (RRw), rfe),
9e3c6df6 20378 TUF("srsia", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
d709e4e6
RE
20379 TUF("srs", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
20380 TUF("srsea", 8c00500, e980c000, 2, (oRRw, I31w), srs, srs),
9e3c6df6 20381 UF(srsib, 9c00500, 2, (oRRw, I31w), srs),
d709e4e6 20382 UF(srsfa, 9c00500, 2, (oRRw, I31w), srs),
9e3c6df6 20383 UF(srsda, 8400500, 2, (oRRw, I31w), srs),
d709e4e6 20384 UF(srsed, 8400500, 2, (oRRw, I31w), srs),
9e3c6df6 20385 TUF("srsdb", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
d709e4e6 20386 TUF("srsfd", 9400500, e800c000, 2, (oRRw, I31w), srs, srs),
941c9cad 20387 TUF("cps", 1020000, f3af8100, 1, (I31b), imm0, t_cps),
c921be7d 20388
9e3c6df6
PB
20389/* ARM V6 not included in V7M (eg. integer SIMD). */
20390#undef THUMB_VARIANT
20391#define THUMB_VARIANT & arm_ext_v6_dsp
21d799b5
NC
20392 TCE("pkhbt", 6800010, eac00000, 4, (RRnpc, RRnpc, RRnpc, oSHll), pkhbt, t_pkhbt),
20393 TCE("pkhtb", 6800050, eac00020, 4, (RRnpc, RRnpc, RRnpc, oSHar), pkhtb, t_pkhtb),
20394 TCE("qadd16", 6200f10, fa90f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20395 TCE("qadd8", 6200f90, fa80f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20396 TCE("qasx", 6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20397 /* Old name for QASX. */
74db7efb 20398 TCE("qaddsubx",6200f30, faa0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 20399 TCE("qsax", 6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20400 /* Old name for QSAX. */
74db7efb 20401 TCE("qsubaddx",6200f50, fae0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20402 TCE("qsub16", 6200f70, fad0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20403 TCE("qsub8", 6200ff0, fac0f010, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20404 TCE("sadd16", 6100f10, fa90f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20405 TCE("sadd8", 6100f90, fa80f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20406 TCE("sasx", 6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20407 /* Old name for SASX. */
74db7efb 20408 TCE("saddsubx",6100f30, faa0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20409 TCE("shadd16", 6300f10, fa90f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20410 TCE("shadd8", 6300f90, fa80f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20411 TCE("shasx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20412 /* Old name for SHASX. */
21d799b5 20413 TCE("shaddsubx", 6300f30, faa0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20414 TCE("shsax", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20415 /* Old name for SHSAX. */
21d799b5
NC
20416 TCE("shsubaddx", 6300f50, fae0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20417 TCE("shsub16", 6300f70, fad0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20418 TCE("shsub8", 6300ff0, fac0f020, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20419 TCE("ssax", 6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20420 /* Old name for SSAX. */
74db7efb 20421 TCE("ssubaddx",6100f50, fae0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20422 TCE("ssub16", 6100f70, fad0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20423 TCE("ssub8", 6100ff0, fac0f000, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20424 TCE("uadd16", 6500f10, fa90f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20425 TCE("uadd8", 6500f90, fa80f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20426 TCE("uasx", 6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20427 /* Old name for UASX. */
74db7efb 20428 TCE("uaddsubx",6500f30, faa0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20429 TCE("uhadd16", 6700f10, fa90f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20430 TCE("uhadd8", 6700f90, fa80f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20431 TCE("uhasx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20432 /* Old name for UHASX. */
21d799b5
NC
20433 TCE("uhaddsubx", 6700f30, faa0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20434 TCE("uhsax", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20435 /* Old name for UHSAX. */
21d799b5
NC
20436 TCE("uhsubaddx", 6700f50, fae0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20437 TCE("uhsub16", 6700f70, fad0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20438 TCE("uhsub8", 6700ff0, fac0f060, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20439 TCE("uqadd16", 6600f10, fa90f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20440 TCE("uqadd8", 6600f90, fa80f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
74db7efb 20441 TCE("uqasx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20442 /* Old name for UQASX. */
21d799b5
NC
20443 TCE("uqaddsubx", 6600f30, faa0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20444 TCE("uqsax", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20445 /* Old name for UQSAX. */
21d799b5
NC
20446 TCE("uqsubaddx", 6600f50, fae0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20447 TCE("uqsub16", 6600f70, fad0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20448 TCE("uqsub8", 6600ff0, fac0f050, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20449 TCE("usub16", 6500f70, fad0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20450 TCE("usax", 6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
4f80ef3e 20451 /* Old name for USAX. */
74db7efb 20452 TCE("usubaddx",6500f50, fae0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5 20453 TCE("usub8", 6500ff0, fac0f040, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
21d799b5
NC
20454 TCE("sxtah", 6b00070, fa00f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20455 TCE("sxtab16", 6800070, fa20f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20456 TCE("sxtab", 6a00070, fa40f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20457 TCE("sxtb16", 68f0070, fa2ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20458 TCE("uxtah", 6f00070, fa10f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20459 TCE("uxtab16", 6c00070, fa30f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20460 TCE("uxtab", 6e00070, fa50f080, 4, (RRnpc, RRnpc, RRnpc, oROR), sxtah, t_sxtah),
20461 TCE("uxtb16", 6cf0070, fa3ff080, 3, (RRnpc, RRnpc, oROR), sxth, t_sxth),
20462 TCE("sel", 6800fb0, faa0f080, 3, (RRnpc, RRnpc, RRnpc), rd_rn_rm, t_simd),
20463 TCE("smlad", 7000010, fb200000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20464 TCE("smladx", 7000030, fb200010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20465 TCE("smlald", 7400010, fbc000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20466 TCE("smlaldx", 7400030, fbc000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20467 TCE("smlsd", 7000050, fb400000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20468 TCE("smlsdx", 7000070, fb400010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20469 TCE("smlsld", 7400050, fbd000c0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20470 TCE("smlsldx", 7400070, fbd000d0, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal,t_mlal),
20471 TCE("smmla", 7500010, fb500000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20472 TCE("smmlar", 7500030, fb500010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20473 TCE("smmls", 75000d0, fb600000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20474 TCE("smmlsr", 75000f0, fb600010, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20475 TCE("smmul", 750f010, fb50f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20476 TCE("smmulr", 750f030, fb50f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20477 TCE("smuad", 700f010, fb20f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20478 TCE("smuadx", 700f030, fb20f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20479 TCE("smusd", 700f050, fb40f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20480 TCE("smusdx", 700f070, fb40f010, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
21d799b5
NC
20481 TCE("ssat16", 6a00f30, f3200000, 3, (RRnpc, I16, RRnpc), ssat16, t_ssat16),
20482 TCE("umaal", 0400090, fbe00060, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smlal, t_mlal),
20483 TCE("usad8", 780f010, fb70f000, 3, (RRnpc, RRnpc, RRnpc), smul, t_simd),
20484 TCE("usada8", 7800010, fb700000, 4, (RRnpc, RRnpc, RRnpc, RRnpc),smla, t_mla),
20485 TCE("usat16", 6e00f30, f3a00000, 3, (RRnpc, I15, RRnpc), usat16, t_usat16),
c19d1205 20486
c921be7d 20487#undef ARM_VARIANT
55e8aae7 20488#define ARM_VARIANT & arm_ext_v6k_v6t2
c921be7d 20489#undef THUMB_VARIANT
55e8aae7 20490#define THUMB_VARIANT & arm_ext_v6k_v6t2
c921be7d 20491
21d799b5
NC
20492 tCE("yield", 320f001, _yield, 0, (), noargs, t_hint),
20493 tCE("wfe", 320f002, _wfe, 0, (), noargs, t_hint),
20494 tCE("wfi", 320f003, _wfi, 0, (), noargs, t_hint),
20495 tCE("sev", 320f004, _sev, 0, (), noargs, t_hint),
c19d1205 20496
c921be7d
NC
20497#undef THUMB_VARIANT
20498#define THUMB_VARIANT & arm_ext_v6_notm
5be8be5d
DG
20499 TCE("ldrexd", 1b00f9f, e8d0007f, 3, (RRnpc_npcsp, oRRnpc_npcsp, RRnpcb),
20500 ldrexd, t_ldrexd),
20501 TCE("strexd", 1a00f90, e8c00070, 4, (RRnpc_npcsp, RRnpc_npcsp, oRRnpc_npcsp,
20502 RRnpcb), strexd, t_strexd),
ebdca51a 20503
c921be7d 20504#undef THUMB_VARIANT
ff8646ee 20505#define THUMB_VARIANT & arm_ext_v6t2_v8m
5be8be5d
DG
20506 TCE("ldrexb", 1d00f9f, e8d00f4f, 2, (RRnpc_npcsp,RRnpcb),
20507 rd_rn, rd_rn),
20508 TCE("ldrexh", 1f00f9f, e8d00f5f, 2, (RRnpc_npcsp, RRnpcb),
20509 rd_rn, rd_rn),
20510 TCE("strexb", 1c00f90, e8c00f40, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 20511 strex, t_strexbh),
5be8be5d 20512 TCE("strexh", 1e00f90, e8c00f50, 3, (RRnpc_npcsp, RRnpc_npcsp, ADDR),
877807f8 20513 strex, t_strexbh),
21d799b5 20514 TUF("clrex", 57ff01f, f3bf8f2f, 0, (), noargs, noargs),
c19d1205 20515
c921be7d 20516#undef ARM_VARIANT
f4c65163 20517#define ARM_VARIANT & arm_ext_sec
74db7efb 20518#undef THUMB_VARIANT
f4c65163 20519#define THUMB_VARIANT & arm_ext_sec
c921be7d 20520
21d799b5 20521 TCE("smc", 1600070, f7f08000, 1, (EXPi), smc, t_smc),
c19d1205 20522
90ec0d68
MGD
20523#undef ARM_VARIANT
20524#define ARM_VARIANT & arm_ext_virt
20525#undef THUMB_VARIANT
20526#define THUMB_VARIANT & arm_ext_virt
20527
20528 TCE("hvc", 1400070, f7e08000, 1, (EXPi), hvc, t_hvc),
20529 TCE("eret", 160006e, f3de8f00, 0, (), noargs, noargs),
20530
ddfded2f
MW
20531#undef ARM_VARIANT
20532#define ARM_VARIANT & arm_ext_pan
20533#undef THUMB_VARIANT
20534#define THUMB_VARIANT & arm_ext_pan
20535
20536 TUF("setpan", 1100000, b610, 1, (I7), setpan, t_setpan),
20537
c921be7d 20538#undef ARM_VARIANT
74db7efb 20539#define ARM_VARIANT & arm_ext_v6t2
f4c65163
MGD
20540#undef THUMB_VARIANT
20541#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 20542
21d799b5
NC
20543 TCE("bfc", 7c0001f, f36f0000, 3, (RRnpc, I31, I32), bfc, t_bfc),
20544 TCE("bfi", 7c00010, f3600000, 4, (RRnpc, RRnpc_I0, I31, I32), bfi, t_bfi),
20545 TCE("sbfx", 7a00050, f3400000, 4, (RR, RR, I31, I32), bfx, t_bfx),
20546 TCE("ubfx", 7e00050, f3c00000, 4, (RR, RR, I31, I32), bfx, t_bfx),
c19d1205 20547
21d799b5 20548 TCE("mls", 0600090, fb000010, 4, (RRnpc, RRnpc, RRnpc, RRnpc), mlas, t_mla),
21d799b5 20549 TCE("rbit", 6ff0f30, fa90f0a0, 2, (RR, RR), rd_rm, t_rbit),
c19d1205 20550
5be8be5d
DG
20551 TC3("ldrht", 03000b0, f8300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
20552 TC3("ldrsht", 03000f0, f9300e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
20553 TC3("ldrsbt", 03000d0, f9100e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
20554 TC3("strht", 02000b0, f8200e00, 2, (RRnpc_npcsp, ADDR), ldsttv4, t_ldstt),
c19d1205 20555
91d8b670
JG
20556#undef ARM_VARIANT
20557#define ARM_VARIANT & arm_ext_v3
20558#undef THUMB_VARIANT
20559#define THUMB_VARIANT & arm_ext_v6t2
20560
20561 TUE("csdb", 320f014, f3af8014, 0, (), noargs, t_csdb),
c597cc3d
SD
20562 TUF("ssbb", 57ff040, f3bf8f40, 0, (), noargs, t_csdb),
20563 TUF("pssbb", 57ff044, f3bf8f44, 0, (), noargs, t_csdb),
91d8b670
JG
20564
20565#undef ARM_VARIANT
20566#define ARM_VARIANT & arm_ext_v6t2
ff8646ee
TP
20567#undef THUMB_VARIANT
20568#define THUMB_VARIANT & arm_ext_v6t2_v8m
20569 TCE("movw", 3000000, f2400000, 2, (RRnpc, HALF), mov16, t_mov16),
20570 TCE("movt", 3400000, f2c00000, 2, (RRnpc, HALF), mov16, t_mov16),
20571
bf3eeda7 20572 /* Thumb-only instructions. */
74db7efb 20573#undef ARM_VARIANT
bf3eeda7
NS
20574#define ARM_VARIANT NULL
20575 TUE("cbnz", 0, b900, 2, (RR, EXP), 0, t_cbz),
20576 TUE("cbz", 0, b100, 2, (RR, EXP), 0, t_cbz),
c921be7d
NC
20577
20578 /* ARM does not really have an IT instruction, so always allow it.
20579 The opcode is copied from Thumb in order to allow warnings in
20580 -mimplicit-it=[never | arm] modes. */
20581#undef ARM_VARIANT
20582#define ARM_VARIANT & arm_ext_v1
ff8646ee
TP
20583#undef THUMB_VARIANT
20584#define THUMB_VARIANT & arm_ext_v6t2
c921be7d 20585
21d799b5
NC
20586 TUE("it", bf08, bf08, 1, (COND), it, t_it),
20587 TUE("itt", bf0c, bf0c, 1, (COND), it, t_it),
20588 TUE("ite", bf04, bf04, 1, (COND), it, t_it),
20589 TUE("ittt", bf0e, bf0e, 1, (COND), it, t_it),
20590 TUE("itet", bf06, bf06, 1, (COND), it, t_it),
20591 TUE("itte", bf0a, bf0a, 1, (COND), it, t_it),
20592 TUE("itee", bf02, bf02, 1, (COND), it, t_it),
20593 TUE("itttt", bf0f, bf0f, 1, (COND), it, t_it),
20594 TUE("itett", bf07, bf07, 1, (COND), it, t_it),
20595 TUE("ittet", bf0b, bf0b, 1, (COND), it, t_it),
20596 TUE("iteet", bf03, bf03, 1, (COND), it, t_it),
20597 TUE("ittte", bf0d, bf0d, 1, (COND), it, t_it),
20598 TUE("itete", bf05, bf05, 1, (COND), it, t_it),
20599 TUE("ittee", bf09, bf09, 1, (COND), it, t_it),
20600 TUE("iteee", bf01, bf01, 1, (COND), it, t_it),
1c444d06 20601 /* ARM/Thumb-2 instructions with no Thumb-1 equivalent. */
21d799b5
NC
20602 TC3("rrx", 01a00060, ea4f0030, 2, (RR, RR), rd_rm, t_rrx),
20603 TC3("rrxs", 01b00060, ea5f0030, 2, (RR, RR), rd_rm, t_rrx),
c19d1205 20604
92e90b6e 20605 /* Thumb2 only instructions. */
c921be7d
NC
20606#undef ARM_VARIANT
20607#define ARM_VARIANT NULL
92e90b6e 20608
21d799b5
NC
20609 TCE("addw", 0, f2000000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
20610 TCE("subw", 0, f2a00000, 3, (RR, RR, EXPi), 0, t_add_sub_w),
20611 TCE("orn", 0, ea600000, 3, (RR, oRR, SH), 0, t_orn),
20612 TCE("orns", 0, ea700000, 3, (RR, oRR, SH), 0, t_orn),
20613 TCE("tbb", 0, e8d0f000, 1, (TB), 0, t_tb),
20614 TCE("tbh", 0, e8d0f010, 1, (TB), 0, t_tb),
92e90b6e 20615
eea54501
MGD
20616 /* Hardware division instructions. */
20617#undef ARM_VARIANT
20618#define ARM_VARIANT & arm_ext_adiv
c921be7d
NC
20619#undef THUMB_VARIANT
20620#define THUMB_VARIANT & arm_ext_div
20621
eea54501
MGD
20622 TCE("sdiv", 710f010, fb90f0f0, 3, (RR, oRR, RR), div, t_div),
20623 TCE("udiv", 730f010, fbb0f0f0, 3, (RR, oRR, RR), div, t_div),
62b3e311 20624
7e806470 20625 /* ARM V6M/V7 instructions. */
c921be7d
NC
20626#undef ARM_VARIANT
20627#define ARM_VARIANT & arm_ext_barrier
20628#undef THUMB_VARIANT
20629#define THUMB_VARIANT & arm_ext_barrier
20630
ccb84d65
JB
20631 TUF("dmb", 57ff050, f3bf8f50, 1, (oBARRIER_I15), barrier, barrier),
20632 TUF("dsb", 57ff040, f3bf8f40, 1, (oBARRIER_I15), barrier, barrier),
20633 TUF("isb", 57ff060, f3bf8f60, 1, (oBARRIER_I15), barrier, barrier),
7e806470 20634
62b3e311 20635 /* ARM V7 instructions. */
c921be7d
NC
20636#undef ARM_VARIANT
20637#define ARM_VARIANT & arm_ext_v7
20638#undef THUMB_VARIANT
20639#define THUMB_VARIANT & arm_ext_v7
20640
21d799b5
NC
20641 TUF("pli", 450f000, f910f000, 1, (ADDR), pli, t_pld),
20642 TCE("dbg", 320f0f0, f3af80f0, 1, (I15), dbg, t_dbg),
62b3e311 20643
74db7efb 20644#undef ARM_VARIANT
60e5ef9f 20645#define ARM_VARIANT & arm_ext_mp
74db7efb 20646#undef THUMB_VARIANT
60e5ef9f
MGD
20647#define THUMB_VARIANT & arm_ext_mp
20648
20649 TUF("pldw", 410f000, f830f000, 1, (ADDR), pld, t_pld),
20650
53c4b28b
MGD
20651 /* AArchv8 instructions. */
20652#undef ARM_VARIANT
20653#define ARM_VARIANT & arm_ext_v8
4ed7ed8d
TP
20654
20655/* Instructions shared between armv8-a and armv8-m. */
53c4b28b 20656#undef THUMB_VARIANT
4ed7ed8d 20657#define THUMB_VARIANT & arm_ext_atomics
53c4b28b 20658
4ed7ed8d
TP
20659 TCE("lda", 1900c9f, e8d00faf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20660 TCE("ldab", 1d00c9f, e8d00f8f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20661 TCE("ldah", 1f00c9f, e8d00f9f, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20662 TCE("stl", 180fc90, e8c00faf, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
20663 TCE("stlb", 1c0fc90, e8c00f8f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
20664 TCE("stlh", 1e0fc90, e8c00f9f, 2, (RRnpc, RRnpcb), rm_rn, rd_rn),
4b8c8c02 20665 TCE("ldaex", 1900e9f, e8d00fef, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
4b8c8c02
RE
20666 TCE("ldaexb", 1d00e9f, e8d00fcf, 2, (RRnpc,RRnpcb), rd_rn, rd_rn),
20667 TCE("ldaexh", 1f00e9f, e8d00fdf, 2, (RRnpc, RRnpcb), rd_rn, rd_rn),
20668 TCE("stlex", 1800e90, e8c00fe0, 3, (RRnpc, RRnpc, RRnpcb),
20669 stlex, t_stlex),
4b8c8c02
RE
20670 TCE("stlexb", 1c00e90, e8c00fc0, 3, (RRnpc, RRnpc, RRnpcb),
20671 stlex, t_stlex),
20672 TCE("stlexh", 1e00e90, e8c00fd0, 3, (RRnpc, RRnpc, RRnpcb),
20673 stlex, t_stlex),
4ed7ed8d
TP
20674#undef THUMB_VARIANT
20675#define THUMB_VARIANT & arm_ext_v8
53c4b28b 20676
4ed7ed8d 20677 tCE("sevl", 320f005, _sevl, 0, (), noargs, t_hint),
4ed7ed8d
TP
20678 TCE("ldaexd", 1b00e9f, e8d000ff, 3, (RRnpc, oRRnpc, RRnpcb),
20679 ldrexd, t_ldrexd),
20680 TCE("stlexd", 1a00e90, e8c000f0, 4, (RRnpc, RRnpc, oRRnpc, RRnpcb),
20681 strexd, t_strexd),
f7dd2fb2
TC
20682
20683/* Defined in V8 but is in undefined encoding space for earlier
20684 architectures. However earlier architectures are required to treat
20685 this instuction as a semihosting trap as well. Hence while not explicitly
20686 defined as such, it is in fact correct to define the instruction for all
20687 architectures. */
20688#undef THUMB_VARIANT
20689#define THUMB_VARIANT & arm_ext_v1
20690#undef ARM_VARIANT
20691#define ARM_VARIANT & arm_ext_v1
20692 TUE("hlt", 1000070, ba80, 1, (oIffffb), bkpt, t_hlt),
20693
8884b720 20694 /* ARMv8 T32 only. */
74db7efb 20695#undef ARM_VARIANT
b79f7053
MGD
20696#define ARM_VARIANT NULL
20697 TUF("dcps1", 0, f78f8001, 0, (), noargs, noargs),
20698 TUF("dcps2", 0, f78f8002, 0, (), noargs, noargs),
20699 TUF("dcps3", 0, f78f8003, 0, (), noargs, noargs),
20700
33399f07
MGD
20701 /* FP for ARMv8. */
20702#undef ARM_VARIANT
a715796b 20703#define ARM_VARIANT & fpu_vfp_ext_armv8xd
33399f07 20704#undef THUMB_VARIANT
a715796b 20705#define THUMB_VARIANT & fpu_vfp_ext_armv8xd
33399f07
MGD
20706
20707 nUF(vseleq, _vseleq, 3, (RVSD, RVSD, RVSD), vsel),
20708 nUF(vselvs, _vselvs, 3, (RVSD, RVSD, RVSD), vsel),
20709 nUF(vselge, _vselge, 3, (RVSD, RVSD, RVSD), vsel),
20710 nUF(vselgt, _vselgt, 3, (RVSD, RVSD, RVSD), vsel),
73924fbc
MGD
20711 nUF(vmaxnm, _vmaxnm, 3, (RNSDQ, oRNSDQ, RNSDQ), vmaxnm),
20712 nUF(vminnm, _vminnm, 3, (RNSDQ, oRNSDQ, RNSDQ), vmaxnm),
7e8e6784
MGD
20713 nUF(vcvta, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvta),
20714 nUF(vcvtn, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvtn),
20715 nUF(vcvtp, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvtp),
20716 nUF(vcvtm, _vcvta, 2, (RNSDQ, oRNSDQ), neon_cvtm),
30bdf752
MGD
20717 nCE(vrintr, _vrintr, 2, (RNSDQ, oRNSDQ), vrintr),
20718 nCE(vrintz, _vrintr, 2, (RNSDQ, oRNSDQ), vrintz),
20719 nCE(vrintx, _vrintr, 2, (RNSDQ, oRNSDQ), vrintx),
20720 nUF(vrinta, _vrinta, 2, (RNSDQ, oRNSDQ), vrinta),
20721 nUF(vrintn, _vrinta, 2, (RNSDQ, oRNSDQ), vrintn),
20722 nUF(vrintp, _vrinta, 2, (RNSDQ, oRNSDQ), vrintp),
20723 nUF(vrintm, _vrinta, 2, (RNSDQ, oRNSDQ), vrintm),
33399f07 20724
91ff7894
MGD
20725 /* Crypto v1 extensions. */
20726#undef ARM_VARIANT
20727#define ARM_VARIANT & fpu_crypto_ext_armv8
20728#undef THUMB_VARIANT
20729#define THUMB_VARIANT & fpu_crypto_ext_armv8
20730
20731 nUF(aese, _aes, 2, (RNQ, RNQ), aese),
20732 nUF(aesd, _aes, 2, (RNQ, RNQ), aesd),
20733 nUF(aesmc, _aes, 2, (RNQ, RNQ), aesmc),
20734 nUF(aesimc, _aes, 2, (RNQ, RNQ), aesimc),
48adcd8e
MGD
20735 nUF(sha1c, _sha3op, 3, (RNQ, RNQ, RNQ), sha1c),
20736 nUF(sha1p, _sha3op, 3, (RNQ, RNQ, RNQ), sha1p),
20737 nUF(sha1m, _sha3op, 3, (RNQ, RNQ, RNQ), sha1m),
20738 nUF(sha1su0, _sha3op, 3, (RNQ, RNQ, RNQ), sha1su0),
20739 nUF(sha256h, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h),
20740 nUF(sha256h2, _sha3op, 3, (RNQ, RNQ, RNQ), sha256h2),
20741 nUF(sha256su1, _sha3op, 3, (RNQ, RNQ, RNQ), sha256su1),
3c9017d2
MGD
20742 nUF(sha1h, _sha1h, 2, (RNQ, RNQ), sha1h),
20743 nUF(sha1su1, _sha2op, 2, (RNQ, RNQ), sha1su1),
20744 nUF(sha256su0, _sha2op, 2, (RNQ, RNQ), sha256su0),
91ff7894 20745
dd5181d5 20746#undef ARM_VARIANT
74db7efb 20747#define ARM_VARIANT & crc_ext_armv8
dd5181d5
KT
20748#undef THUMB_VARIANT
20749#define THUMB_VARIANT & crc_ext_armv8
20750 TUEc("crc32b", 1000040, fac0f080, 3, (RR, oRR, RR), crc32b),
20751 TUEc("crc32h", 1200040, fac0f090, 3, (RR, oRR, RR), crc32h),
20752 TUEc("crc32w", 1400040, fac0f0a0, 3, (RR, oRR, RR), crc32w),
20753 TUEc("crc32cb",1000240, fad0f080, 3, (RR, oRR, RR), crc32cb),
20754 TUEc("crc32ch",1200240, fad0f090, 3, (RR, oRR, RR), crc32ch),
20755 TUEc("crc32cw",1400240, fad0f0a0, 3, (RR, oRR, RR), crc32cw),
20756
105bde57
MW
20757 /* ARMv8.2 RAS extension. */
20758#undef ARM_VARIANT
4d1464f2 20759#define ARM_VARIANT & arm_ext_ras
105bde57 20760#undef THUMB_VARIANT
4d1464f2 20761#define THUMB_VARIANT & arm_ext_ras
105bde57
MW
20762 TUE ("esb", 320f010, f3af8010, 0, (), noargs, noargs),
20763
49e8a725
SN
20764#undef ARM_VARIANT
20765#define ARM_VARIANT & arm_ext_v8_3
20766#undef THUMB_VARIANT
20767#define THUMB_VARIANT & arm_ext_v8_3
20768 NCE (vjcvt, eb90bc0, 2, (RVS, RVD), vjcvt),
c28eeff2
SN
20769 NUF (vcmla, 0, 4, (RNDQ, RNDQ, RNDQ_RNSC, EXPi), vcmla),
20770 NUF (vcadd, 0, 4, (RNDQ, RNDQ, RNDQ, EXPi), vcadd),
49e8a725 20771
c604a79a
JW
20772#undef ARM_VARIANT
20773#define ARM_VARIANT & fpu_neon_ext_dotprod
20774#undef THUMB_VARIANT
20775#define THUMB_VARIANT & fpu_neon_ext_dotprod
20776 NUF (vsdot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_s),
20777 NUF (vudot, d00, 3, (RNDQ, RNDQ, RNDQ_RNSC), neon_dotproduct_u),
20778
c921be7d
NC
20779#undef ARM_VARIANT
20780#define ARM_VARIANT & fpu_fpa_ext_v1 /* Core FPA instruction set (V1). */
53c4b28b
MGD
20781#undef THUMB_VARIANT
20782#define THUMB_VARIANT NULL
c921be7d 20783
21d799b5
NC
20784 cCE("wfs", e200110, 1, (RR), rd),
20785 cCE("rfs", e300110, 1, (RR), rd),
20786 cCE("wfc", e400110, 1, (RR), rd),
20787 cCE("rfc", e500110, 1, (RR), rd),
20788
20789 cCL("ldfs", c100100, 2, (RF, ADDRGLDC), rd_cpaddr),
20790 cCL("ldfd", c108100, 2, (RF, ADDRGLDC), rd_cpaddr),
20791 cCL("ldfe", c500100, 2, (RF, ADDRGLDC), rd_cpaddr),
20792 cCL("ldfp", c508100, 2, (RF, ADDRGLDC), rd_cpaddr),
20793
20794 cCL("stfs", c000100, 2, (RF, ADDRGLDC), rd_cpaddr),
20795 cCL("stfd", c008100, 2, (RF, ADDRGLDC), rd_cpaddr),
20796 cCL("stfe", c400100, 2, (RF, ADDRGLDC), rd_cpaddr),
20797 cCL("stfp", c408100, 2, (RF, ADDRGLDC), rd_cpaddr),
20798
20799 cCL("mvfs", e008100, 2, (RF, RF_IF), rd_rm),
20800 cCL("mvfsp", e008120, 2, (RF, RF_IF), rd_rm),
20801 cCL("mvfsm", e008140, 2, (RF, RF_IF), rd_rm),
20802 cCL("mvfsz", e008160, 2, (RF, RF_IF), rd_rm),
20803 cCL("mvfd", e008180, 2, (RF, RF_IF), rd_rm),
20804 cCL("mvfdp", e0081a0, 2, (RF, RF_IF), rd_rm),
20805 cCL("mvfdm", e0081c0, 2, (RF, RF_IF), rd_rm),
20806 cCL("mvfdz", e0081e0, 2, (RF, RF_IF), rd_rm),
20807 cCL("mvfe", e088100, 2, (RF, RF_IF), rd_rm),
20808 cCL("mvfep", e088120, 2, (RF, RF_IF), rd_rm),
20809 cCL("mvfem", e088140, 2, (RF, RF_IF), rd_rm),
20810 cCL("mvfez", e088160, 2, (RF, RF_IF), rd_rm),
20811
20812 cCL("mnfs", e108100, 2, (RF, RF_IF), rd_rm),
20813 cCL("mnfsp", e108120, 2, (RF, RF_IF), rd_rm),
20814 cCL("mnfsm", e108140, 2, (RF, RF_IF), rd_rm),
20815 cCL("mnfsz", e108160, 2, (RF, RF_IF), rd_rm),
20816 cCL("mnfd", e108180, 2, (RF, RF_IF), rd_rm),
20817 cCL("mnfdp", e1081a0, 2, (RF, RF_IF), rd_rm),
20818 cCL("mnfdm", e1081c0, 2, (RF, RF_IF), rd_rm),
20819 cCL("mnfdz", e1081e0, 2, (RF, RF_IF), rd_rm),
20820 cCL("mnfe", e188100, 2, (RF, RF_IF), rd_rm),
20821 cCL("mnfep", e188120, 2, (RF, RF_IF), rd_rm),
20822 cCL("mnfem", e188140, 2, (RF, RF_IF), rd_rm),
20823 cCL("mnfez", e188160, 2, (RF, RF_IF), rd_rm),
20824
20825 cCL("abss", e208100, 2, (RF, RF_IF), rd_rm),
20826 cCL("abssp", e208120, 2, (RF, RF_IF), rd_rm),
20827 cCL("abssm", e208140, 2, (RF, RF_IF), rd_rm),
20828 cCL("abssz", e208160, 2, (RF, RF_IF), rd_rm),
20829 cCL("absd", e208180, 2, (RF, RF_IF), rd_rm),
20830 cCL("absdp", e2081a0, 2, (RF, RF_IF), rd_rm),
20831 cCL("absdm", e2081c0, 2, (RF, RF_IF), rd_rm),
20832 cCL("absdz", e2081e0, 2, (RF, RF_IF), rd_rm),
20833 cCL("abse", e288100, 2, (RF, RF_IF), rd_rm),
20834 cCL("absep", e288120, 2, (RF, RF_IF), rd_rm),
20835 cCL("absem", e288140, 2, (RF, RF_IF), rd_rm),
20836 cCL("absez", e288160, 2, (RF, RF_IF), rd_rm),
20837
20838 cCL("rnds", e308100, 2, (RF, RF_IF), rd_rm),
20839 cCL("rndsp", e308120, 2, (RF, RF_IF), rd_rm),
20840 cCL("rndsm", e308140, 2, (RF, RF_IF), rd_rm),
20841 cCL("rndsz", e308160, 2, (RF, RF_IF), rd_rm),
20842 cCL("rndd", e308180, 2, (RF, RF_IF), rd_rm),
20843 cCL("rnddp", e3081a0, 2, (RF, RF_IF), rd_rm),
20844 cCL("rnddm", e3081c0, 2, (RF, RF_IF), rd_rm),
20845 cCL("rnddz", e3081e0, 2, (RF, RF_IF), rd_rm),
20846 cCL("rnde", e388100, 2, (RF, RF_IF), rd_rm),
20847 cCL("rndep", e388120, 2, (RF, RF_IF), rd_rm),
20848 cCL("rndem", e388140, 2, (RF, RF_IF), rd_rm),
20849 cCL("rndez", e388160, 2, (RF, RF_IF), rd_rm),
20850
20851 cCL("sqts", e408100, 2, (RF, RF_IF), rd_rm),
20852 cCL("sqtsp", e408120, 2, (RF, RF_IF), rd_rm),
20853 cCL("sqtsm", e408140, 2, (RF, RF_IF), rd_rm),
20854 cCL("sqtsz", e408160, 2, (RF, RF_IF), rd_rm),
20855 cCL("sqtd", e408180, 2, (RF, RF_IF), rd_rm),
20856 cCL("sqtdp", e4081a0, 2, (RF, RF_IF), rd_rm),
20857 cCL("sqtdm", e4081c0, 2, (RF, RF_IF), rd_rm),
20858 cCL("sqtdz", e4081e0, 2, (RF, RF_IF), rd_rm),
20859 cCL("sqte", e488100, 2, (RF, RF_IF), rd_rm),
20860 cCL("sqtep", e488120, 2, (RF, RF_IF), rd_rm),
20861 cCL("sqtem", e488140, 2, (RF, RF_IF), rd_rm),
20862 cCL("sqtez", e488160, 2, (RF, RF_IF), rd_rm),
20863
20864 cCL("logs", e508100, 2, (RF, RF_IF), rd_rm),
20865 cCL("logsp", e508120, 2, (RF, RF_IF), rd_rm),
20866 cCL("logsm", e508140, 2, (RF, RF_IF), rd_rm),
20867 cCL("logsz", e508160, 2, (RF, RF_IF), rd_rm),
20868 cCL("logd", e508180, 2, (RF, RF_IF), rd_rm),
20869 cCL("logdp", e5081a0, 2, (RF, RF_IF), rd_rm),
20870 cCL("logdm", e5081c0, 2, (RF, RF_IF), rd_rm),
20871 cCL("logdz", e5081e0, 2, (RF, RF_IF), rd_rm),
20872 cCL("loge", e588100, 2, (RF, RF_IF), rd_rm),
20873 cCL("logep", e588120, 2, (RF, RF_IF), rd_rm),
20874 cCL("logem", e588140, 2, (RF, RF_IF), rd_rm),
20875 cCL("logez", e588160, 2, (RF, RF_IF), rd_rm),
20876
20877 cCL("lgns", e608100, 2, (RF, RF_IF), rd_rm),
20878 cCL("lgnsp", e608120, 2, (RF, RF_IF), rd_rm),
20879 cCL("lgnsm", e608140, 2, (RF, RF_IF), rd_rm),
20880 cCL("lgnsz", e608160, 2, (RF, RF_IF), rd_rm),
20881 cCL("lgnd", e608180, 2, (RF, RF_IF), rd_rm),
20882 cCL("lgndp", e6081a0, 2, (RF, RF_IF), rd_rm),
20883 cCL("lgndm", e6081c0, 2, (RF, RF_IF), rd_rm),
20884 cCL("lgndz", e6081e0, 2, (RF, RF_IF), rd_rm),
20885 cCL("lgne", e688100, 2, (RF, RF_IF), rd_rm),
20886 cCL("lgnep", e688120, 2, (RF, RF_IF), rd_rm),
20887 cCL("lgnem", e688140, 2, (RF, RF_IF), rd_rm),
20888 cCL("lgnez", e688160, 2, (RF, RF_IF), rd_rm),
20889
20890 cCL("exps", e708100, 2, (RF, RF_IF), rd_rm),
20891 cCL("expsp", e708120, 2, (RF, RF_IF), rd_rm),
20892 cCL("expsm", e708140, 2, (RF, RF_IF), rd_rm),
20893 cCL("expsz", e708160, 2, (RF, RF_IF), rd_rm),
20894 cCL("expd", e708180, 2, (RF, RF_IF), rd_rm),
20895 cCL("expdp", e7081a0, 2, (RF, RF_IF), rd_rm),
20896 cCL("expdm", e7081c0, 2, (RF, RF_IF), rd_rm),
20897 cCL("expdz", e7081e0, 2, (RF, RF_IF), rd_rm),
20898 cCL("expe", e788100, 2, (RF, RF_IF), rd_rm),
20899 cCL("expep", e788120, 2, (RF, RF_IF), rd_rm),
20900 cCL("expem", e788140, 2, (RF, RF_IF), rd_rm),
20901 cCL("expdz", e788160, 2, (RF, RF_IF), rd_rm),
20902
20903 cCL("sins", e808100, 2, (RF, RF_IF), rd_rm),
20904 cCL("sinsp", e808120, 2, (RF, RF_IF), rd_rm),
20905 cCL("sinsm", e808140, 2, (RF, RF_IF), rd_rm),
20906 cCL("sinsz", e808160, 2, (RF, RF_IF), rd_rm),
20907 cCL("sind", e808180, 2, (RF, RF_IF), rd_rm),
20908 cCL("sindp", e8081a0, 2, (RF, RF_IF), rd_rm),
20909 cCL("sindm", e8081c0, 2, (RF, RF_IF), rd_rm),
20910 cCL("sindz", e8081e0, 2, (RF, RF_IF), rd_rm),
20911 cCL("sine", e888100, 2, (RF, RF_IF), rd_rm),
20912 cCL("sinep", e888120, 2, (RF, RF_IF), rd_rm),
20913 cCL("sinem", e888140, 2, (RF, RF_IF), rd_rm),
20914 cCL("sinez", e888160, 2, (RF, RF_IF), rd_rm),
20915
20916 cCL("coss", e908100, 2, (RF, RF_IF), rd_rm),
20917 cCL("cossp", e908120, 2, (RF, RF_IF), rd_rm),
20918 cCL("cossm", e908140, 2, (RF, RF_IF), rd_rm),
20919 cCL("cossz", e908160, 2, (RF, RF_IF), rd_rm),
20920 cCL("cosd", e908180, 2, (RF, RF_IF), rd_rm),
20921 cCL("cosdp", e9081a0, 2, (RF, RF_IF), rd_rm),
20922 cCL("cosdm", e9081c0, 2, (RF, RF_IF), rd_rm),
20923 cCL("cosdz", e9081e0, 2, (RF, RF_IF), rd_rm),
20924 cCL("cose", e988100, 2, (RF, RF_IF), rd_rm),
20925 cCL("cosep", e988120, 2, (RF, RF_IF), rd_rm),
20926 cCL("cosem", e988140, 2, (RF, RF_IF), rd_rm),
20927 cCL("cosez", e988160, 2, (RF, RF_IF), rd_rm),
20928
20929 cCL("tans", ea08100, 2, (RF, RF_IF), rd_rm),
20930 cCL("tansp", ea08120, 2, (RF, RF_IF), rd_rm),
20931 cCL("tansm", ea08140, 2, (RF, RF_IF), rd_rm),
20932 cCL("tansz", ea08160, 2, (RF, RF_IF), rd_rm),
20933 cCL("tand", ea08180, 2, (RF, RF_IF), rd_rm),
20934 cCL("tandp", ea081a0, 2, (RF, RF_IF), rd_rm),
20935 cCL("tandm", ea081c0, 2, (RF, RF_IF), rd_rm),
20936 cCL("tandz", ea081e0, 2, (RF, RF_IF), rd_rm),
20937 cCL("tane", ea88100, 2, (RF, RF_IF), rd_rm),
20938 cCL("tanep", ea88120, 2, (RF, RF_IF), rd_rm),
20939 cCL("tanem", ea88140, 2, (RF, RF_IF), rd_rm),
20940 cCL("tanez", ea88160, 2, (RF, RF_IF), rd_rm),
20941
20942 cCL("asns", eb08100, 2, (RF, RF_IF), rd_rm),
20943 cCL("asnsp", eb08120, 2, (RF, RF_IF), rd_rm),
20944 cCL("asnsm", eb08140, 2, (RF, RF_IF), rd_rm),
20945 cCL("asnsz", eb08160, 2, (RF, RF_IF), rd_rm),
20946 cCL("asnd", eb08180, 2, (RF, RF_IF), rd_rm),
20947 cCL("asndp", eb081a0, 2, (RF, RF_IF), rd_rm),
20948 cCL("asndm", eb081c0, 2, (RF, RF_IF), rd_rm),
20949 cCL("asndz", eb081e0, 2, (RF, RF_IF), rd_rm),
20950 cCL("asne", eb88100, 2, (RF, RF_IF), rd_rm),
20951 cCL("asnep", eb88120, 2, (RF, RF_IF), rd_rm),
20952 cCL("asnem", eb88140, 2, (RF, RF_IF), rd_rm),
20953 cCL("asnez", eb88160, 2, (RF, RF_IF), rd_rm),
20954
20955 cCL("acss", ec08100, 2, (RF, RF_IF), rd_rm),
20956 cCL("acssp", ec08120, 2, (RF, RF_IF), rd_rm),
20957 cCL("acssm", ec08140, 2, (RF, RF_IF), rd_rm),
20958 cCL("acssz", ec08160, 2, (RF, RF_IF), rd_rm),
20959 cCL("acsd", ec08180, 2, (RF, RF_IF), rd_rm),
20960 cCL("acsdp", ec081a0, 2, (RF, RF_IF), rd_rm),
20961 cCL("acsdm", ec081c0, 2, (RF, RF_IF), rd_rm),
20962 cCL("acsdz", ec081e0, 2, (RF, RF_IF), rd_rm),
20963 cCL("acse", ec88100, 2, (RF, RF_IF), rd_rm),
20964 cCL("acsep", ec88120, 2, (RF, RF_IF), rd_rm),
20965 cCL("acsem", ec88140, 2, (RF, RF_IF), rd_rm),
20966 cCL("acsez", ec88160, 2, (RF, RF_IF), rd_rm),
20967
20968 cCL("atns", ed08100, 2, (RF, RF_IF), rd_rm),
20969 cCL("atnsp", ed08120, 2, (RF, RF_IF), rd_rm),
20970 cCL("atnsm", ed08140, 2, (RF, RF_IF), rd_rm),
20971 cCL("atnsz", ed08160, 2, (RF, RF_IF), rd_rm),
20972 cCL("atnd", ed08180, 2, (RF, RF_IF), rd_rm),
20973 cCL("atndp", ed081a0, 2, (RF, RF_IF), rd_rm),
20974 cCL("atndm", ed081c0, 2, (RF, RF_IF), rd_rm),
20975 cCL("atndz", ed081e0, 2, (RF, RF_IF), rd_rm),
20976 cCL("atne", ed88100, 2, (RF, RF_IF), rd_rm),
20977 cCL("atnep", ed88120, 2, (RF, RF_IF), rd_rm),
20978 cCL("atnem", ed88140, 2, (RF, RF_IF), rd_rm),
20979 cCL("atnez", ed88160, 2, (RF, RF_IF), rd_rm),
20980
20981 cCL("urds", ee08100, 2, (RF, RF_IF), rd_rm),
20982 cCL("urdsp", ee08120, 2, (RF, RF_IF), rd_rm),
20983 cCL("urdsm", ee08140, 2, (RF, RF_IF), rd_rm),
20984 cCL("urdsz", ee08160, 2, (RF, RF_IF), rd_rm),
20985 cCL("urdd", ee08180, 2, (RF, RF_IF), rd_rm),
20986 cCL("urddp", ee081a0, 2, (RF, RF_IF), rd_rm),
20987 cCL("urddm", ee081c0, 2, (RF, RF_IF), rd_rm),
20988 cCL("urddz", ee081e0, 2, (RF, RF_IF), rd_rm),
20989 cCL("urde", ee88100, 2, (RF, RF_IF), rd_rm),
20990 cCL("urdep", ee88120, 2, (RF, RF_IF), rd_rm),
20991 cCL("urdem", ee88140, 2, (RF, RF_IF), rd_rm),
20992 cCL("urdez", ee88160, 2, (RF, RF_IF), rd_rm),
20993
20994 cCL("nrms", ef08100, 2, (RF, RF_IF), rd_rm),
20995 cCL("nrmsp", ef08120, 2, (RF, RF_IF), rd_rm),
20996 cCL("nrmsm", ef08140, 2, (RF, RF_IF), rd_rm),
20997 cCL("nrmsz", ef08160, 2, (RF, RF_IF), rd_rm),
20998 cCL("nrmd", ef08180, 2, (RF, RF_IF), rd_rm),
20999 cCL("nrmdp", ef081a0, 2, (RF, RF_IF), rd_rm),
21000 cCL("nrmdm", ef081c0, 2, (RF, RF_IF), rd_rm),
21001 cCL("nrmdz", ef081e0, 2, (RF, RF_IF), rd_rm),
21002 cCL("nrme", ef88100, 2, (RF, RF_IF), rd_rm),
21003 cCL("nrmep", ef88120, 2, (RF, RF_IF), rd_rm),
21004 cCL("nrmem", ef88140, 2, (RF, RF_IF), rd_rm),
21005 cCL("nrmez", ef88160, 2, (RF, RF_IF), rd_rm),
21006
21007 cCL("adfs", e000100, 3, (RF, RF, RF_IF), rd_rn_rm),
21008 cCL("adfsp", e000120, 3, (RF, RF, RF_IF), rd_rn_rm),
21009 cCL("adfsm", e000140, 3, (RF, RF, RF_IF), rd_rn_rm),
21010 cCL("adfsz", e000160, 3, (RF, RF, RF_IF), rd_rn_rm),
21011 cCL("adfd", e000180, 3, (RF, RF, RF_IF), rd_rn_rm),
21012 cCL("adfdp", e0001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21013 cCL("adfdm", e0001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21014 cCL("adfdz", e0001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21015 cCL("adfe", e080100, 3, (RF, RF, RF_IF), rd_rn_rm),
21016 cCL("adfep", e080120, 3, (RF, RF, RF_IF), rd_rn_rm),
21017 cCL("adfem", e080140, 3, (RF, RF, RF_IF), rd_rn_rm),
21018 cCL("adfez", e080160, 3, (RF, RF, RF_IF), rd_rn_rm),
21019
21020 cCL("sufs", e200100, 3, (RF, RF, RF_IF), rd_rn_rm),
21021 cCL("sufsp", e200120, 3, (RF, RF, RF_IF), rd_rn_rm),
21022 cCL("sufsm", e200140, 3, (RF, RF, RF_IF), rd_rn_rm),
21023 cCL("sufsz", e200160, 3, (RF, RF, RF_IF), rd_rn_rm),
21024 cCL("sufd", e200180, 3, (RF, RF, RF_IF), rd_rn_rm),
21025 cCL("sufdp", e2001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21026 cCL("sufdm", e2001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21027 cCL("sufdz", e2001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21028 cCL("sufe", e280100, 3, (RF, RF, RF_IF), rd_rn_rm),
21029 cCL("sufep", e280120, 3, (RF, RF, RF_IF), rd_rn_rm),
21030 cCL("sufem", e280140, 3, (RF, RF, RF_IF), rd_rn_rm),
21031 cCL("sufez", e280160, 3, (RF, RF, RF_IF), rd_rn_rm),
21032
21033 cCL("rsfs", e300100, 3, (RF, RF, RF_IF), rd_rn_rm),
21034 cCL("rsfsp", e300120, 3, (RF, RF, RF_IF), rd_rn_rm),
21035 cCL("rsfsm", e300140, 3, (RF, RF, RF_IF), rd_rn_rm),
21036 cCL("rsfsz", e300160, 3, (RF, RF, RF_IF), rd_rn_rm),
21037 cCL("rsfd", e300180, 3, (RF, RF, RF_IF), rd_rn_rm),
21038 cCL("rsfdp", e3001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21039 cCL("rsfdm", e3001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21040 cCL("rsfdz", e3001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21041 cCL("rsfe", e380100, 3, (RF, RF, RF_IF), rd_rn_rm),
21042 cCL("rsfep", e380120, 3, (RF, RF, RF_IF), rd_rn_rm),
21043 cCL("rsfem", e380140, 3, (RF, RF, RF_IF), rd_rn_rm),
21044 cCL("rsfez", e380160, 3, (RF, RF, RF_IF), rd_rn_rm),
21045
21046 cCL("mufs", e100100, 3, (RF, RF, RF_IF), rd_rn_rm),
21047 cCL("mufsp", e100120, 3, (RF, RF, RF_IF), rd_rn_rm),
21048 cCL("mufsm", e100140, 3, (RF, RF, RF_IF), rd_rn_rm),
21049 cCL("mufsz", e100160, 3, (RF, RF, RF_IF), rd_rn_rm),
21050 cCL("mufd", e100180, 3, (RF, RF, RF_IF), rd_rn_rm),
21051 cCL("mufdp", e1001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21052 cCL("mufdm", e1001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21053 cCL("mufdz", e1001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21054 cCL("mufe", e180100, 3, (RF, RF, RF_IF), rd_rn_rm),
21055 cCL("mufep", e180120, 3, (RF, RF, RF_IF), rd_rn_rm),
21056 cCL("mufem", e180140, 3, (RF, RF, RF_IF), rd_rn_rm),
21057 cCL("mufez", e180160, 3, (RF, RF, RF_IF), rd_rn_rm),
21058
21059 cCL("dvfs", e400100, 3, (RF, RF, RF_IF), rd_rn_rm),
21060 cCL("dvfsp", e400120, 3, (RF, RF, RF_IF), rd_rn_rm),
21061 cCL("dvfsm", e400140, 3, (RF, RF, RF_IF), rd_rn_rm),
21062 cCL("dvfsz", e400160, 3, (RF, RF, RF_IF), rd_rn_rm),
21063 cCL("dvfd", e400180, 3, (RF, RF, RF_IF), rd_rn_rm),
21064 cCL("dvfdp", e4001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21065 cCL("dvfdm", e4001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21066 cCL("dvfdz", e4001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21067 cCL("dvfe", e480100, 3, (RF, RF, RF_IF), rd_rn_rm),
21068 cCL("dvfep", e480120, 3, (RF, RF, RF_IF), rd_rn_rm),
21069 cCL("dvfem", e480140, 3, (RF, RF, RF_IF), rd_rn_rm),
21070 cCL("dvfez", e480160, 3, (RF, RF, RF_IF), rd_rn_rm),
21071
21072 cCL("rdfs", e500100, 3, (RF, RF, RF_IF), rd_rn_rm),
21073 cCL("rdfsp", e500120, 3, (RF, RF, RF_IF), rd_rn_rm),
21074 cCL("rdfsm", e500140, 3, (RF, RF, RF_IF), rd_rn_rm),
21075 cCL("rdfsz", e500160, 3, (RF, RF, RF_IF), rd_rn_rm),
21076 cCL("rdfd", e500180, 3, (RF, RF, RF_IF), rd_rn_rm),
21077 cCL("rdfdp", e5001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21078 cCL("rdfdm", e5001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21079 cCL("rdfdz", e5001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21080 cCL("rdfe", e580100, 3, (RF, RF, RF_IF), rd_rn_rm),
21081 cCL("rdfep", e580120, 3, (RF, RF, RF_IF), rd_rn_rm),
21082 cCL("rdfem", e580140, 3, (RF, RF, RF_IF), rd_rn_rm),
21083 cCL("rdfez", e580160, 3, (RF, RF, RF_IF), rd_rn_rm),
21084
21085 cCL("pows", e600100, 3, (RF, RF, RF_IF), rd_rn_rm),
21086 cCL("powsp", e600120, 3, (RF, RF, RF_IF), rd_rn_rm),
21087 cCL("powsm", e600140, 3, (RF, RF, RF_IF), rd_rn_rm),
21088 cCL("powsz", e600160, 3, (RF, RF, RF_IF), rd_rn_rm),
21089 cCL("powd", e600180, 3, (RF, RF, RF_IF), rd_rn_rm),
21090 cCL("powdp", e6001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21091 cCL("powdm", e6001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21092 cCL("powdz", e6001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21093 cCL("powe", e680100, 3, (RF, RF, RF_IF), rd_rn_rm),
21094 cCL("powep", e680120, 3, (RF, RF, RF_IF), rd_rn_rm),
21095 cCL("powem", e680140, 3, (RF, RF, RF_IF), rd_rn_rm),
21096 cCL("powez", e680160, 3, (RF, RF, RF_IF), rd_rn_rm),
21097
21098 cCL("rpws", e700100, 3, (RF, RF, RF_IF), rd_rn_rm),
21099 cCL("rpwsp", e700120, 3, (RF, RF, RF_IF), rd_rn_rm),
21100 cCL("rpwsm", e700140, 3, (RF, RF, RF_IF), rd_rn_rm),
21101 cCL("rpwsz", e700160, 3, (RF, RF, RF_IF), rd_rn_rm),
21102 cCL("rpwd", e700180, 3, (RF, RF, RF_IF), rd_rn_rm),
21103 cCL("rpwdp", e7001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21104 cCL("rpwdm", e7001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21105 cCL("rpwdz", e7001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21106 cCL("rpwe", e780100, 3, (RF, RF, RF_IF), rd_rn_rm),
21107 cCL("rpwep", e780120, 3, (RF, RF, RF_IF), rd_rn_rm),
21108 cCL("rpwem", e780140, 3, (RF, RF, RF_IF), rd_rn_rm),
21109 cCL("rpwez", e780160, 3, (RF, RF, RF_IF), rd_rn_rm),
21110
21111 cCL("rmfs", e800100, 3, (RF, RF, RF_IF), rd_rn_rm),
21112 cCL("rmfsp", e800120, 3, (RF, RF, RF_IF), rd_rn_rm),
21113 cCL("rmfsm", e800140, 3, (RF, RF, RF_IF), rd_rn_rm),
21114 cCL("rmfsz", e800160, 3, (RF, RF, RF_IF), rd_rn_rm),
21115 cCL("rmfd", e800180, 3, (RF, RF, RF_IF), rd_rn_rm),
21116 cCL("rmfdp", e8001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21117 cCL("rmfdm", e8001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21118 cCL("rmfdz", e8001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21119 cCL("rmfe", e880100, 3, (RF, RF, RF_IF), rd_rn_rm),
21120 cCL("rmfep", e880120, 3, (RF, RF, RF_IF), rd_rn_rm),
21121 cCL("rmfem", e880140, 3, (RF, RF, RF_IF), rd_rn_rm),
21122 cCL("rmfez", e880160, 3, (RF, RF, RF_IF), rd_rn_rm),
21123
21124 cCL("fmls", e900100, 3, (RF, RF, RF_IF), rd_rn_rm),
21125 cCL("fmlsp", e900120, 3, (RF, RF, RF_IF), rd_rn_rm),
21126 cCL("fmlsm", e900140, 3, (RF, RF, RF_IF), rd_rn_rm),
21127 cCL("fmlsz", e900160, 3, (RF, RF, RF_IF), rd_rn_rm),
21128 cCL("fmld", e900180, 3, (RF, RF, RF_IF), rd_rn_rm),
21129 cCL("fmldp", e9001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21130 cCL("fmldm", e9001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21131 cCL("fmldz", e9001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21132 cCL("fmle", e980100, 3, (RF, RF, RF_IF), rd_rn_rm),
21133 cCL("fmlep", e980120, 3, (RF, RF, RF_IF), rd_rn_rm),
21134 cCL("fmlem", e980140, 3, (RF, RF, RF_IF), rd_rn_rm),
21135 cCL("fmlez", e980160, 3, (RF, RF, RF_IF), rd_rn_rm),
21136
21137 cCL("fdvs", ea00100, 3, (RF, RF, RF_IF), rd_rn_rm),
21138 cCL("fdvsp", ea00120, 3, (RF, RF, RF_IF), rd_rn_rm),
21139 cCL("fdvsm", ea00140, 3, (RF, RF, RF_IF), rd_rn_rm),
21140 cCL("fdvsz", ea00160, 3, (RF, RF, RF_IF), rd_rn_rm),
21141 cCL("fdvd", ea00180, 3, (RF, RF, RF_IF), rd_rn_rm),
21142 cCL("fdvdp", ea001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21143 cCL("fdvdm", ea001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21144 cCL("fdvdz", ea001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21145 cCL("fdve", ea80100, 3, (RF, RF, RF_IF), rd_rn_rm),
21146 cCL("fdvep", ea80120, 3, (RF, RF, RF_IF), rd_rn_rm),
21147 cCL("fdvem", ea80140, 3, (RF, RF, RF_IF), rd_rn_rm),
21148 cCL("fdvez", ea80160, 3, (RF, RF, RF_IF), rd_rn_rm),
21149
21150 cCL("frds", eb00100, 3, (RF, RF, RF_IF), rd_rn_rm),
21151 cCL("frdsp", eb00120, 3, (RF, RF, RF_IF), rd_rn_rm),
21152 cCL("frdsm", eb00140, 3, (RF, RF, RF_IF), rd_rn_rm),
21153 cCL("frdsz", eb00160, 3, (RF, RF, RF_IF), rd_rn_rm),
21154 cCL("frdd", eb00180, 3, (RF, RF, RF_IF), rd_rn_rm),
21155 cCL("frddp", eb001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21156 cCL("frddm", eb001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21157 cCL("frddz", eb001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21158 cCL("frde", eb80100, 3, (RF, RF, RF_IF), rd_rn_rm),
21159 cCL("frdep", eb80120, 3, (RF, RF, RF_IF), rd_rn_rm),
21160 cCL("frdem", eb80140, 3, (RF, RF, RF_IF), rd_rn_rm),
21161 cCL("frdez", eb80160, 3, (RF, RF, RF_IF), rd_rn_rm),
21162
21163 cCL("pols", ec00100, 3, (RF, RF, RF_IF), rd_rn_rm),
21164 cCL("polsp", ec00120, 3, (RF, RF, RF_IF), rd_rn_rm),
21165 cCL("polsm", ec00140, 3, (RF, RF, RF_IF), rd_rn_rm),
21166 cCL("polsz", ec00160, 3, (RF, RF, RF_IF), rd_rn_rm),
21167 cCL("pold", ec00180, 3, (RF, RF, RF_IF), rd_rn_rm),
21168 cCL("poldp", ec001a0, 3, (RF, RF, RF_IF), rd_rn_rm),
21169 cCL("poldm", ec001c0, 3, (RF, RF, RF_IF), rd_rn_rm),
21170 cCL("poldz", ec001e0, 3, (RF, RF, RF_IF), rd_rn_rm),
21171 cCL("pole", ec80100, 3, (RF, RF, RF_IF), rd_rn_rm),
21172 cCL("polep", ec80120, 3, (RF, RF, RF_IF), rd_rn_rm),
21173 cCL("polem", ec80140, 3, (RF, RF, RF_IF), rd_rn_rm),
21174 cCL("polez", ec80160, 3, (RF, RF, RF_IF), rd_rn_rm),
21175
21176 cCE("cmf", e90f110, 2, (RF, RF_IF), fpa_cmp),
21177 C3E("cmfe", ed0f110, 2, (RF, RF_IF), fpa_cmp),
21178 cCE("cnf", eb0f110, 2, (RF, RF_IF), fpa_cmp),
21179 C3E("cnfe", ef0f110, 2, (RF, RF_IF), fpa_cmp),
21180
21181 cCL("flts", e000110, 2, (RF, RR), rn_rd),
21182 cCL("fltsp", e000130, 2, (RF, RR), rn_rd),
21183 cCL("fltsm", e000150, 2, (RF, RR), rn_rd),
21184 cCL("fltsz", e000170, 2, (RF, RR), rn_rd),
21185 cCL("fltd", e000190, 2, (RF, RR), rn_rd),
21186 cCL("fltdp", e0001b0, 2, (RF, RR), rn_rd),
21187 cCL("fltdm", e0001d0, 2, (RF, RR), rn_rd),
21188 cCL("fltdz", e0001f0, 2, (RF, RR), rn_rd),
21189 cCL("flte", e080110, 2, (RF, RR), rn_rd),
21190 cCL("fltep", e080130, 2, (RF, RR), rn_rd),
21191 cCL("fltem", e080150, 2, (RF, RR), rn_rd),
21192 cCL("fltez", e080170, 2, (RF, RR), rn_rd),
b99bd4ef 21193
c19d1205
ZW
21194 /* The implementation of the FIX instruction is broken on some
21195 assemblers, in that it accepts a precision specifier as well as a
21196 rounding specifier, despite the fact that this is meaningless.
21197 To be more compatible, we accept it as well, though of course it
21198 does not set any bits. */
21d799b5
NC
21199 cCE("fix", e100110, 2, (RR, RF), rd_rm),
21200 cCL("fixp", e100130, 2, (RR, RF), rd_rm),
21201 cCL("fixm", e100150, 2, (RR, RF), rd_rm),
21202 cCL("fixz", e100170, 2, (RR, RF), rd_rm),
21203 cCL("fixsp", e100130, 2, (RR, RF), rd_rm),
21204 cCL("fixsm", e100150, 2, (RR, RF), rd_rm),
21205 cCL("fixsz", e100170, 2, (RR, RF), rd_rm),
21206 cCL("fixdp", e100130, 2, (RR, RF), rd_rm),
21207 cCL("fixdm", e100150, 2, (RR, RF), rd_rm),
21208 cCL("fixdz", e100170, 2, (RR, RF), rd_rm),
21209 cCL("fixep", e100130, 2, (RR, RF), rd_rm),
21210 cCL("fixem", e100150, 2, (RR, RF), rd_rm),
21211 cCL("fixez", e100170, 2, (RR, RF), rd_rm),
bfae80f2 21212
c19d1205 21213 /* Instructions that were new with the real FPA, call them V2. */
c921be7d
NC
21214#undef ARM_VARIANT
21215#define ARM_VARIANT & fpu_fpa_ext_v2
21216
21d799b5
NC
21217 cCE("lfm", c100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21218 cCL("lfmfd", c900200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21219 cCL("lfmea", d100200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21220 cCE("sfm", c000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21221 cCL("sfmfd", d000200, 3, (RF, I4b, ADDR), fpa_ldmstm),
21222 cCL("sfmea", c800200, 3, (RF, I4b, ADDR), fpa_ldmstm),
c19d1205 21223
c921be7d
NC
21224#undef ARM_VARIANT
21225#define ARM_VARIANT & fpu_vfp_ext_v1xd /* VFP V1xD (single precision). */
21226
c19d1205 21227 /* Moves and type conversions. */
21d799b5
NC
21228 cCE("fcpys", eb00a40, 2, (RVS, RVS), vfp_sp_monadic),
21229 cCE("fmrs", e100a10, 2, (RR, RVS), vfp_reg_from_sp),
21230 cCE("fmsr", e000a10, 2, (RVS, RR), vfp_sp_from_reg),
21231 cCE("fmstat", ef1fa10, 0, (), noargs),
7465e07a
NC
21232 cCE("vmrs", ef00a10, 2, (APSR_RR, RVC), vmrs),
21233 cCE("vmsr", ee00a10, 2, (RVC, RR), vmsr),
21d799b5
NC
21234 cCE("fsitos", eb80ac0, 2, (RVS, RVS), vfp_sp_monadic),
21235 cCE("fuitos", eb80a40, 2, (RVS, RVS), vfp_sp_monadic),
21236 cCE("ftosis", ebd0a40, 2, (RVS, RVS), vfp_sp_monadic),
21237 cCE("ftosizs", ebd0ac0, 2, (RVS, RVS), vfp_sp_monadic),
21238 cCE("ftouis", ebc0a40, 2, (RVS, RVS), vfp_sp_monadic),
21239 cCE("ftouizs", ebc0ac0, 2, (RVS, RVS), vfp_sp_monadic),
21240 cCE("fmrx", ef00a10, 2, (RR, RVC), rd_rn),
21241 cCE("fmxr", ee00a10, 2, (RVC, RR), rn_rd),
c19d1205
ZW
21242
21243 /* Memory operations. */
21d799b5
NC
21244 cCE("flds", d100a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
21245 cCE("fsts", d000a00, 2, (RVS, ADDRGLDC), vfp_sp_ldst),
55881a11
MGD
21246 cCE("fldmias", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21247 cCE("fldmfds", c900a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21248 cCE("fldmdbs", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21249 cCE("fldmeas", d300a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21250 cCE("fldmiax", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21251 cCE("fldmfdx", c900b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21252 cCE("fldmdbx", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
21253 cCE("fldmeax", d300b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
21254 cCE("fstmias", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21255 cCE("fstmeas", c800a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmia),
21256 cCE("fstmdbs", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21257 cCE("fstmfds", d200a00, 2, (RRnpctw, VRSLST), vfp_sp_ldstmdb),
21258 cCE("fstmiax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21259 cCE("fstmeax", c800b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmia),
21260 cCE("fstmdbx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
21261 cCE("fstmfdx", d200b00, 2, (RRnpctw, VRDLST), vfp_xp_ldstmdb),
bfae80f2 21262
c19d1205 21263 /* Monadic operations. */
21d799b5
NC
21264 cCE("fabss", eb00ac0, 2, (RVS, RVS), vfp_sp_monadic),
21265 cCE("fnegs", eb10a40, 2, (RVS, RVS), vfp_sp_monadic),
21266 cCE("fsqrts", eb10ac0, 2, (RVS, RVS), vfp_sp_monadic),
c19d1205
ZW
21267
21268 /* Dyadic operations. */
21d799b5
NC
21269 cCE("fadds", e300a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21270 cCE("fsubs", e300a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21271 cCE("fmuls", e200a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21272 cCE("fdivs", e800a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21273 cCE("fmacs", e000a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21274 cCE("fmscs", e100a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21275 cCE("fnmuls", e200a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21276 cCE("fnmacs", e000a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21277 cCE("fnmscs", e100a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
b99bd4ef 21278
c19d1205 21279 /* Comparisons. */
21d799b5
NC
21280 cCE("fcmps", eb40a40, 2, (RVS, RVS), vfp_sp_monadic),
21281 cCE("fcmpzs", eb50a40, 1, (RVS), vfp_sp_compare_z),
21282 cCE("fcmpes", eb40ac0, 2, (RVS, RVS), vfp_sp_monadic),
21283 cCE("fcmpezs", eb50ac0, 1, (RVS), vfp_sp_compare_z),
b99bd4ef 21284
62f3b8c8
PB
21285 /* Double precision load/store are still present on single precision
21286 implementations. */
21287 cCE("fldd", d100b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
21288 cCE("fstd", d000b00, 2, (RVD, ADDRGLDC), vfp_dp_ldst),
55881a11
MGD
21289 cCE("fldmiad", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21290 cCE("fldmfdd", c900b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21291 cCE("fldmdbd", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
21292 cCE("fldmead", d300b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
21293 cCE("fstmiad", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21294 cCE("fstmead", c800b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmia),
21295 cCE("fstmdbd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
21296 cCE("fstmfdd", d200b00, 2, (RRnpctw, VRDLST), vfp_dp_ldstmdb),
62f3b8c8 21297
c921be7d
NC
21298#undef ARM_VARIANT
21299#define ARM_VARIANT & fpu_vfp_ext_v1 /* VFP V1 (Double precision). */
21300
c19d1205 21301 /* Moves and type conversions. */
21d799b5
NC
21302 cCE("fcpyd", eb00b40, 2, (RVD, RVD), vfp_dp_rd_rm),
21303 cCE("fcvtds", eb70ac0, 2, (RVD, RVS), vfp_dp_sp_cvt),
21304 cCE("fcvtsd", eb70bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
21305 cCE("fmdhr", e200b10, 2, (RVD, RR), vfp_dp_rn_rd),
21306 cCE("fmdlr", e000b10, 2, (RVD, RR), vfp_dp_rn_rd),
21307 cCE("fmrdh", e300b10, 2, (RR, RVD), vfp_dp_rd_rn),
21308 cCE("fmrdl", e100b10, 2, (RR, RVD), vfp_dp_rd_rn),
21309 cCE("fsitod", eb80bc0, 2, (RVD, RVS), vfp_dp_sp_cvt),
21310 cCE("fuitod", eb80b40, 2, (RVD, RVS), vfp_dp_sp_cvt),
21311 cCE("ftosid", ebd0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
21312 cCE("ftosizd", ebd0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
21313 cCE("ftouid", ebc0b40, 2, (RVS, RVD), vfp_sp_dp_cvt),
21314 cCE("ftouizd", ebc0bc0, 2, (RVS, RVD), vfp_sp_dp_cvt),
c19d1205 21315
c19d1205 21316 /* Monadic operations. */
21d799b5
NC
21317 cCE("fabsd", eb00bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
21318 cCE("fnegd", eb10b40, 2, (RVD, RVD), vfp_dp_rd_rm),
21319 cCE("fsqrtd", eb10bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
c19d1205
ZW
21320
21321 /* Dyadic operations. */
21d799b5
NC
21322 cCE("faddd", e300b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21323 cCE("fsubd", e300b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21324 cCE("fmuld", e200b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21325 cCE("fdivd", e800b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21326 cCE("fmacd", e000b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21327 cCE("fmscd", e100b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21328 cCE("fnmuld", e200b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21329 cCE("fnmacd", e000b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21330 cCE("fnmscd", e100b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
b99bd4ef 21331
c19d1205 21332 /* Comparisons. */
21d799b5
NC
21333 cCE("fcmpd", eb40b40, 2, (RVD, RVD), vfp_dp_rd_rm),
21334 cCE("fcmpzd", eb50b40, 1, (RVD), vfp_dp_rd),
21335 cCE("fcmped", eb40bc0, 2, (RVD, RVD), vfp_dp_rd_rm),
21336 cCE("fcmpezd", eb50bc0, 1, (RVD), vfp_dp_rd),
c19d1205 21337
c921be7d
NC
21338#undef ARM_VARIANT
21339#define ARM_VARIANT & fpu_vfp_ext_v2
21340
21d799b5
NC
21341 cCE("fmsrr", c400a10, 3, (VRSLST, RR, RR), vfp_sp2_from_reg2),
21342 cCE("fmrrs", c500a10, 3, (RR, RR, VRSLST), vfp_reg2_from_sp2),
21343 cCE("fmdrr", c400b10, 3, (RVD, RR, RR), vfp_dp_rm_rd_rn),
21344 cCE("fmrrd", c500b10, 3, (RR, RR, RVD), vfp_dp_rd_rn_rm),
5287ad62 21345
037e8744
JB
21346/* Instructions which may belong to either the Neon or VFP instruction sets.
21347 Individual encoder functions perform additional architecture checks. */
c921be7d
NC
21348#undef ARM_VARIANT
21349#define ARM_VARIANT & fpu_vfp_ext_v1xd
21350#undef THUMB_VARIANT
21351#define THUMB_VARIANT & fpu_vfp_ext_v1xd
21352
037e8744
JB
21353 /* These mnemonics are unique to VFP. */
21354 NCE(vsqrt, 0, 2, (RVSD, RVSD), vfp_nsyn_sqrt),
21355 NCE(vdiv, 0, 3, (RVSD, RVSD, RVSD), vfp_nsyn_div),
21d799b5
NC
21356 nCE(vnmul, _vnmul, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21357 nCE(vnmla, _vnmla, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21358 nCE(vnmls, _vnmls, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
aacf0b33
KT
21359 nCE(vcmp, _vcmp, 2, (RVSD, RSVD_FI0), vfp_nsyn_cmp),
21360 nCE(vcmpe, _vcmpe, 2, (RVSD, RSVD_FI0), vfp_nsyn_cmp),
037e8744
JB
21361 NCE(vpush, 0, 1, (VRSDLST), vfp_nsyn_push),
21362 NCE(vpop, 0, 1, (VRSDLST), vfp_nsyn_pop),
21363 NCE(vcvtz, 0, 2, (RVSD, RVSD), vfp_nsyn_cvtz),
21364
21365 /* Mnemonics shared by Neon and VFP. */
21d799b5
NC
21366 nCEF(vmul, _vmul, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mul),
21367 nCEF(vmla, _vmla, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
21368 nCEF(vmls, _vmls, 3, (RNSDQ, oRNSDQ, RNSDQ_RNSC), neon_mac_maybe_scalar),
037e8744 21369
21d799b5
NC
21370 nCEF(vadd, _vadd, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_addsub_if_i),
21371 nCEF(vsub, _vsub, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_addsub_if_i),
037e8744
JB
21372
21373 NCEF(vabs, 1b10300, 2, (RNSDQ, RNSDQ), neon_abs_neg),
21374 NCEF(vneg, 1b10380, 2, (RNSDQ, RNSDQ), neon_abs_neg),
21375
55881a11
MGD
21376 NCE(vldm, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21377 NCE(vldmia, c900b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21378 NCE(vldmdb, d100b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21379 NCE(vstm, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21380 NCE(vstmia, c800b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
21381 NCE(vstmdb, d000b00, 2, (RRnpctw, VRSDLST), neon_ldm_stm),
037e8744 21382
5f1af56b 21383 nCEF(vcvt, _vcvt, 3, (RNSDQ, RNSDQ, oI32z), neon_cvt),
e3e535bc 21384 nCEF(vcvtr, _vcvt, 2, (RNSDQ, RNSDQ), neon_cvtr),
c70a8987
MGD
21385 NCEF(vcvtb, eb20a40, 2, (RVSD, RVSD), neon_cvtb),
21386 NCEF(vcvtt, eb20a40, 2, (RVSD, RVSD), neon_cvtt),
f31fef98 21387
037e8744
JB
21388
21389 /* NOTE: All VMOV encoding is special-cased! */
21390 NCE(vmov, 0, 1, (VMOV), neon_mov),
21391 NCE(vmovq, 0, 1, (VMOV), neon_mov),
21392
32c36c3c
AV
21393#undef THUMB_VARIANT
21394/* Could be either VLDR/VSTR or VLDR/VSTR (system register) which are guarded
21395 by different feature bits. Since we are setting the Thumb guard, we can
21396 require Thumb-1 which makes it a nop guard and set the right feature bit in
21397 do_vldr_vstr (). */
21398#define THUMB_VARIANT & arm_ext_v4t
21399 NCE(vldr, d100b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
21400 NCE(vstr, d000b00, 2, (VLDR, ADDRGLDC), vldr_vstr),
21401
9db2f6b4
RL
21402#undef ARM_VARIANT
21403#define ARM_VARIANT & arm_ext_fp16
21404#undef THUMB_VARIANT
21405#define THUMB_VARIANT & arm_ext_fp16
21406 /* New instructions added from v8.2, allowing the extraction and insertion of
21407 the upper 16 bits of a 32-bit vector register. */
21408 NCE (vmovx, eb00a40, 2, (RVS, RVS), neon_movhf),
21409 NCE (vins, eb00ac0, 2, (RVS, RVS), neon_movhf),
21410
dec41383
JW
21411 /* New backported fma/fms instructions optional in v8.2. */
21412 NCE (vfmal, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmal),
21413 NCE (vfmsl, 810, 3, (RNDQ, RNSD, RNSD_RNSC), neon_vfmsl),
21414
c921be7d
NC
21415#undef THUMB_VARIANT
21416#define THUMB_VARIANT & fpu_neon_ext_v1
21417#undef ARM_VARIANT
21418#define ARM_VARIANT & fpu_neon_ext_v1
21419
5287ad62
JB
21420 /* Data processing with three registers of the same length. */
21421 /* integer ops, valid types S8 S16 S32 U8 U16 U32. */
21422 NUF(vaba, 0000710, 3, (RNDQ, RNDQ, RNDQ), neon_dyadic_i_su),
21423 NUF(vabaq, 0000710, 3, (RNQ, RNQ, RNQ), neon_dyadic_i_su),
21424 NUF(vhadd, 0000000, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su),
21425 NUF(vhaddq, 0000000, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
21426 NUF(vrhadd, 0000100, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su),
21427 NUF(vrhaddq, 0000100, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
21428 NUF(vhsub, 0000200, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i_su),
21429 NUF(vhsubq, 0000200, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i_su),
21430 /* integer ops, valid types S8 S16 S32 S64 U8 U16 U32 U64. */
21431 NUF(vqadd, 0000010, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
21432 NUF(vqaddq, 0000010, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
21433 NUF(vqsub, 0000210, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_i64_su),
21434 NUF(vqsubq, 0000210, 3, (RNQ, oRNQ, RNQ), neon_dyadic_i64_su),
627907b7
JB
21435 NUF(vrshl, 0000500, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
21436 NUF(vrshlq, 0000500, 3, (RNQ, oRNQ, RNQ), neon_rshl),
21437 NUF(vqrshl, 0000510, 3, (RNDQ, oRNDQ, RNDQ), neon_rshl),
21438 NUF(vqrshlq, 0000510, 3, (RNQ, oRNQ, RNQ), neon_rshl),
5287ad62
JB
21439 /* If not immediate, fall back to neon_dyadic_i64_su.
21440 shl_imm should accept I8 I16 I32 I64,
21441 qshl_imm should accept S8 S16 S32 S64 U8 U16 U32 U64. */
21d799b5
NC
21442 nUF(vshl, _vshl, 3, (RNDQ, oRNDQ, RNDQ_I63b), neon_shl_imm),
21443 nUF(vshlq, _vshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_shl_imm),
21444 nUF(vqshl, _vqshl, 3, (RNDQ, oRNDQ, RNDQ_I63b), neon_qshl_imm),
21445 nUF(vqshlq, _vqshl, 3, (RNQ, oRNQ, RNDQ_I63b), neon_qshl_imm),
5287ad62 21446 /* Logic ops, types optional & ignored. */
4316f0d2
DG
21447 nUF(vand, _vand, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21448 nUF(vandq, _vand, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21449 nUF(vbic, _vbic, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21450 nUF(vbicq, _vbic, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21451 nUF(vorr, _vorr, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21452 nUF(vorrq, _vorr, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21453 nUF(vorn, _vorn, 3, (RNDQ, oRNDQ, RNDQ_Ibig), neon_logic),
21454 nUF(vornq, _vorn, 3, (RNQ, oRNQ, RNDQ_Ibig), neon_logic),
21455 nUF(veor, _veor, 3, (RNDQ, oRNDQ, RNDQ), neon_logic),
21456 nUF(veorq, _veor, 3, (RNQ, oRNQ, RNQ), neon_logic),
5287ad62
JB
21457 /* Bitfield ops, untyped. */
21458 NUF(vbsl, 1100110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
21459 NUF(vbslq, 1100110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
21460 NUF(vbit, 1200110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
21461 NUF(vbitq, 1200110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
21462 NUF(vbif, 1300110, 3, (RNDQ, RNDQ, RNDQ), neon_bitfield),
21463 NUF(vbifq, 1300110, 3, (RNQ, RNQ, RNQ), neon_bitfield),
cc933301 21464 /* Int and float variants, types S8 S16 S32 U8 U16 U32 F16 F32. */
21d799b5
NC
21465 nUF(vabd, _vabd, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
21466 nUF(vabdq, _vabd, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21467 nUF(vmax, _vmax, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
21468 nUF(vmaxq, _vmax, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
21469 nUF(vmin, _vmin, 3, (RNDQ, oRNDQ, RNDQ), neon_dyadic_if_su),
21470 nUF(vminq, _vmin, 3, (RNQ, oRNQ, RNQ), neon_dyadic_if_su),
5287ad62
JB
21471 /* Comparisons. Types S8 S16 S32 U8 U16 U32 F32. Non-immediate versions fall
21472 back to neon_dyadic_if_su. */
21d799b5
NC
21473 nUF(vcge, _vcge, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
21474 nUF(vcgeq, _vcge, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
21475 nUF(vcgt, _vcgt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp),
21476 nUF(vcgtq, _vcgt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp),
21477 nUF(vclt, _vclt, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
21478 nUF(vcltq, _vclt, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
21479 nUF(vcle, _vcle, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_cmp_inv),
21480 nUF(vcleq, _vcle, 3, (RNQ, oRNQ, RNDQ_I0), neon_cmp_inv),
428e3f1f 21481 /* Comparison. Type I8 I16 I32 F32. */
21d799b5
NC
21482 nUF(vceq, _vceq, 3, (RNDQ, oRNDQ, RNDQ_I0), neon_ceq),
21483 nUF(vceqq, _vceq, 3, (RNQ, oRNQ, RNDQ_I0), neon_ceq),
5287ad62 21484 /* As above, D registers only. */
21d799b5
NC
21485 nUF(vpmax, _vpmax, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
21486 nUF(vpmin, _vpmin, 3, (RND, oRND, RND), neon_dyadic_if_su_d),
5287ad62 21487 /* Int and float variants, signedness unimportant. */
21d799b5
NC
21488 nUF(vmlaq, _vmla, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
21489 nUF(vmlsq, _vmls, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mac_maybe_scalar),
21490 nUF(vpadd, _vpadd, 3, (RND, oRND, RND), neon_dyadic_if_i_d),
5287ad62 21491 /* Add/sub take types I8 I16 I32 I64 F32. */
21d799b5
NC
21492 nUF(vaddq, _vadd, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
21493 nUF(vsubq, _vsub, 3, (RNQ, oRNQ, RNQ), neon_addsub_if_i),
5287ad62
JB
21494 /* vtst takes sizes 8, 16, 32. */
21495 NUF(vtst, 0000810, 3, (RNDQ, oRNDQ, RNDQ), neon_tst),
21496 NUF(vtstq, 0000810, 3, (RNQ, oRNQ, RNQ), neon_tst),
21497 /* VMUL takes I8 I16 I32 F32 P8. */
21d799b5 21498 nUF(vmulq, _vmul, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_mul),
5287ad62 21499 /* VQD{R}MULH takes S16 S32. */
21d799b5
NC
21500 nUF(vqdmulh, _vqdmulh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qdmulh),
21501 nUF(vqdmulhq, _vqdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
21502 nUF(vqrdmulh, _vqrdmulh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qdmulh),
21503 nUF(vqrdmulhq, _vqrdmulh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qdmulh),
5287ad62
JB
21504 NUF(vacge, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
21505 NUF(vacgeq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
21506 NUF(vacgt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute),
21507 NUF(vacgtq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute),
92559b5b
PB
21508 NUF(vaclt, 0200e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
21509 NUF(vacltq, 0200e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
21510 NUF(vacle, 0000e10, 3, (RNDQ, oRNDQ, RNDQ), neon_fcmp_absolute_inv),
21511 NUF(vacleq, 0000e10, 3, (RNQ, oRNQ, RNQ), neon_fcmp_absolute_inv),
5287ad62
JB
21512 NUF(vrecps, 0000f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
21513 NUF(vrecpsq, 0000f10, 3, (RNQ, oRNQ, RNQ), neon_step),
21514 NUF(vrsqrts, 0200f10, 3, (RNDQ, oRNDQ, RNDQ), neon_step),
21515 NUF(vrsqrtsq, 0200f10, 3, (RNQ, oRNQ, RNQ), neon_step),
d6b4b13e 21516 /* ARM v8.1 extension. */
643afb90
MW
21517 nUF (vqrdmlah, _vqrdmlah, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
21518 nUF (vqrdmlahq, _vqrdmlah, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
21519 nUF (vqrdmlsh, _vqrdmlsh, 3, (RNDQ, oRNDQ, RNDQ_RNSC), neon_qrdmlah),
21520 nUF (vqrdmlshq, _vqrdmlsh, 3, (RNQ, oRNQ, RNDQ_RNSC), neon_qrdmlah),
5287ad62
JB
21521
21522 /* Two address, int/float. Types S8 S16 S32 F32. */
5287ad62 21523 NUF(vabsq, 1b10300, 2, (RNQ, RNQ), neon_abs_neg),
5287ad62
JB
21524 NUF(vnegq, 1b10380, 2, (RNQ, RNQ), neon_abs_neg),
21525
21526 /* Data processing with two registers and a shift amount. */
21527 /* Right shifts, and variants with rounding.
21528 Types accepted S8 S16 S32 S64 U8 U16 U32 U64. */
21529 NUF(vshr, 0800010, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
21530 NUF(vshrq, 0800010, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
21531 NUF(vrshr, 0800210, 3, (RNDQ, oRNDQ, I64z), neon_rshift_round_imm),
21532 NUF(vrshrq, 0800210, 3, (RNQ, oRNQ, I64z), neon_rshift_round_imm),
21533 NUF(vsra, 0800110, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
21534 NUF(vsraq, 0800110, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
21535 NUF(vrsra, 0800310, 3, (RNDQ, oRNDQ, I64), neon_rshift_round_imm),
21536 NUF(vrsraq, 0800310, 3, (RNQ, oRNQ, I64), neon_rshift_round_imm),
21537 /* Shift and insert. Sizes accepted 8 16 32 64. */
21538 NUF(vsli, 1800510, 3, (RNDQ, oRNDQ, I63), neon_sli),
21539 NUF(vsliq, 1800510, 3, (RNQ, oRNQ, I63), neon_sli),
21540 NUF(vsri, 1800410, 3, (RNDQ, oRNDQ, I64), neon_sri),
21541 NUF(vsriq, 1800410, 3, (RNQ, oRNQ, I64), neon_sri),
21542 /* QSHL{U} immediate accepts S8 S16 S32 S64 U8 U16 U32 U64. */
21543 NUF(vqshlu, 1800610, 3, (RNDQ, oRNDQ, I63), neon_qshlu_imm),
21544 NUF(vqshluq, 1800610, 3, (RNQ, oRNQ, I63), neon_qshlu_imm),
21545 /* Right shift immediate, saturating & narrowing, with rounding variants.
21546 Types accepted S16 S32 S64 U16 U32 U64. */
21547 NUF(vqshrn, 0800910, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
21548 NUF(vqrshrn, 0800950, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow),
21549 /* As above, unsigned. Types accepted S16 S32 S64. */
21550 NUF(vqshrun, 0800810, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
21551 NUF(vqrshrun, 0800850, 3, (RND, RNQ, I32z), neon_rshift_sat_narrow_u),
21552 /* Right shift narrowing. Types accepted I16 I32 I64. */
21553 NUF(vshrn, 0800810, 3, (RND, RNQ, I32z), neon_rshift_narrow),
21554 NUF(vrshrn, 0800850, 3, (RND, RNQ, I32z), neon_rshift_narrow),
21555 /* Special case. Types S8 S16 S32 U8 U16 U32. Handles max shift variant. */
21d799b5 21556 nUF(vshll, _vshll, 3, (RNQ, RND, I32), neon_shll),
5287ad62 21557 /* CVT with optional immediate for fixed-point variant. */
21d799b5 21558 nUF(vcvtq, _vcvt, 3, (RNQ, RNQ, oI32b), neon_cvt),
b7fc2769 21559
4316f0d2
DG
21560 nUF(vmvn, _vmvn, 2, (RNDQ, RNDQ_Ibig), neon_mvn),
21561 nUF(vmvnq, _vmvn, 2, (RNQ, RNDQ_Ibig), neon_mvn),
5287ad62
JB
21562
21563 /* Data processing, three registers of different lengths. */
21564 /* Dyadic, long insns. Types S8 S16 S32 U8 U16 U32. */
21565 NUF(vabal, 0800500, 3, (RNQ, RND, RND), neon_abal),
21566 NUF(vabdl, 0800700, 3, (RNQ, RND, RND), neon_dyadic_long),
21567 NUF(vaddl, 0800000, 3, (RNQ, RND, RND), neon_dyadic_long),
21568 NUF(vsubl, 0800200, 3, (RNQ, RND, RND), neon_dyadic_long),
21569 /* If not scalar, fall back to neon_dyadic_long.
21570 Vector types as above, scalar types S16 S32 U16 U32. */
21d799b5
NC
21571 nUF(vmlal, _vmlal, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
21572 nUF(vmlsl, _vmlsl, 3, (RNQ, RND, RND_RNSC), neon_mac_maybe_scalar_long),
5287ad62
JB
21573 /* Dyadic, widening insns. Types S8 S16 S32 U8 U16 U32. */
21574 NUF(vaddw, 0800100, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
21575 NUF(vsubw, 0800300, 3, (RNQ, oRNQ, RND), neon_dyadic_wide),
21576 /* Dyadic, narrowing insns. Types I16 I32 I64. */
21577 NUF(vaddhn, 0800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21578 NUF(vraddhn, 1800400, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21579 NUF(vsubhn, 0800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21580 NUF(vrsubhn, 1800600, 3, (RND, RNQ, RNQ), neon_dyadic_narrow),
21581 /* Saturating doubling multiplies. Types S16 S32. */
21d799b5
NC
21582 nUF(vqdmlal, _vqdmlal, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
21583 nUF(vqdmlsl, _vqdmlsl, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
21584 nUF(vqdmull, _vqdmull, 3, (RNQ, RND, RND_RNSC), neon_mul_sat_scalar_long),
5287ad62
JB
21585 /* VMULL. Vector types S8 S16 S32 U8 U16 U32 P8, scalar types
21586 S16 S32 U16 U32. */
21d799b5 21587 nUF(vmull, _vmull, 3, (RNQ, RND, RND_RNSC), neon_vmull),
5287ad62
JB
21588
21589 /* Extract. Size 8. */
3b8d421e
PB
21590 NUF(vext, 0b00000, 4, (RNDQ, oRNDQ, RNDQ, I15), neon_ext),
21591 NUF(vextq, 0b00000, 4, (RNQ, oRNQ, RNQ, I15), neon_ext),
5287ad62
JB
21592
21593 /* Two registers, miscellaneous. */
21594 /* Reverse. Sizes 8 16 32 (must be < size in opcode). */
21595 NUF(vrev64, 1b00000, 2, (RNDQ, RNDQ), neon_rev),
21596 NUF(vrev64q, 1b00000, 2, (RNQ, RNQ), neon_rev),
21597 NUF(vrev32, 1b00080, 2, (RNDQ, RNDQ), neon_rev),
21598 NUF(vrev32q, 1b00080, 2, (RNQ, RNQ), neon_rev),
21599 NUF(vrev16, 1b00100, 2, (RNDQ, RNDQ), neon_rev),
21600 NUF(vrev16q, 1b00100, 2, (RNQ, RNQ), neon_rev),
21601 /* Vector replicate. Sizes 8 16 32. */
21d799b5
NC
21602 nCE(vdup, _vdup, 2, (RNDQ, RR_RNSC), neon_dup),
21603 nCE(vdupq, _vdup, 2, (RNQ, RR_RNSC), neon_dup),
5287ad62
JB
21604 /* VMOVL. Types S8 S16 S32 U8 U16 U32. */
21605 NUF(vmovl, 0800a10, 2, (RNQ, RND), neon_movl),
21606 /* VMOVN. Types I16 I32 I64. */
21d799b5 21607 nUF(vmovn, _vmovn, 2, (RND, RNQ), neon_movn),
5287ad62 21608 /* VQMOVN. Types S16 S32 S64 U16 U32 U64. */
21d799b5 21609 nUF(vqmovn, _vqmovn, 2, (RND, RNQ), neon_qmovn),
5287ad62 21610 /* VQMOVUN. Types S16 S32 S64. */
21d799b5 21611 nUF(vqmovun, _vqmovun, 2, (RND, RNQ), neon_qmovun),
5287ad62
JB
21612 /* VZIP / VUZP. Sizes 8 16 32. */
21613 NUF(vzip, 1b20180, 2, (RNDQ, RNDQ), neon_zip_uzp),
21614 NUF(vzipq, 1b20180, 2, (RNQ, RNQ), neon_zip_uzp),
21615 NUF(vuzp, 1b20100, 2, (RNDQ, RNDQ), neon_zip_uzp),
21616 NUF(vuzpq, 1b20100, 2, (RNQ, RNQ), neon_zip_uzp),
21617 /* VQABS / VQNEG. Types S8 S16 S32. */
21618 NUF(vqabs, 1b00700, 2, (RNDQ, RNDQ), neon_sat_abs_neg),
21619 NUF(vqabsq, 1b00700, 2, (RNQ, RNQ), neon_sat_abs_neg),
21620 NUF(vqneg, 1b00780, 2, (RNDQ, RNDQ), neon_sat_abs_neg),
21621 NUF(vqnegq, 1b00780, 2, (RNQ, RNQ), neon_sat_abs_neg),
21622 /* Pairwise, lengthening. Types S8 S16 S32 U8 U16 U32. */
21623 NUF(vpadal, 1b00600, 2, (RNDQ, RNDQ), neon_pair_long),
21624 NUF(vpadalq, 1b00600, 2, (RNQ, RNQ), neon_pair_long),
21625 NUF(vpaddl, 1b00200, 2, (RNDQ, RNDQ), neon_pair_long),
21626 NUF(vpaddlq, 1b00200, 2, (RNQ, RNQ), neon_pair_long),
cc933301 21627 /* Reciprocal estimates. Types U32 F16 F32. */
5287ad62
JB
21628 NUF(vrecpe, 1b30400, 2, (RNDQ, RNDQ), neon_recip_est),
21629 NUF(vrecpeq, 1b30400, 2, (RNQ, RNQ), neon_recip_est),
21630 NUF(vrsqrte, 1b30480, 2, (RNDQ, RNDQ), neon_recip_est),
21631 NUF(vrsqrteq, 1b30480, 2, (RNQ, RNQ), neon_recip_est),
21632 /* VCLS. Types S8 S16 S32. */
21633 NUF(vcls, 1b00400, 2, (RNDQ, RNDQ), neon_cls),
21634 NUF(vclsq, 1b00400, 2, (RNQ, RNQ), neon_cls),
21635 /* VCLZ. Types I8 I16 I32. */
21636 NUF(vclz, 1b00480, 2, (RNDQ, RNDQ), neon_clz),
21637 NUF(vclzq, 1b00480, 2, (RNQ, RNQ), neon_clz),
21638 /* VCNT. Size 8. */
21639 NUF(vcnt, 1b00500, 2, (RNDQ, RNDQ), neon_cnt),
21640 NUF(vcntq, 1b00500, 2, (RNQ, RNQ), neon_cnt),
21641 /* Two address, untyped. */
21642 NUF(vswp, 1b20000, 2, (RNDQ, RNDQ), neon_swp),
21643 NUF(vswpq, 1b20000, 2, (RNQ, RNQ), neon_swp),
21644 /* VTRN. Sizes 8 16 32. */
21d799b5
NC
21645 nUF(vtrn, _vtrn, 2, (RNDQ, RNDQ), neon_trn),
21646 nUF(vtrnq, _vtrn, 2, (RNQ, RNQ), neon_trn),
5287ad62
JB
21647
21648 /* Table lookup. Size 8. */
21649 NUF(vtbl, 1b00800, 3, (RND, NRDLST, RND), neon_tbl_tbx),
21650 NUF(vtbx, 1b00840, 3, (RND, NRDLST, RND), neon_tbl_tbx),
21651
c921be7d
NC
21652#undef THUMB_VARIANT
21653#define THUMB_VARIANT & fpu_vfp_v3_or_neon_ext
21654#undef ARM_VARIANT
21655#define ARM_VARIANT & fpu_vfp_v3_or_neon_ext
21656
5287ad62 21657 /* Neon element/structure load/store. */
21d799b5
NC
21658 nUF(vld1, _vld1, 2, (NSTRLST, ADDR), neon_ldx_stx),
21659 nUF(vst1, _vst1, 2, (NSTRLST, ADDR), neon_ldx_stx),
21660 nUF(vld2, _vld2, 2, (NSTRLST, ADDR), neon_ldx_stx),
21661 nUF(vst2, _vst2, 2, (NSTRLST, ADDR), neon_ldx_stx),
21662 nUF(vld3, _vld3, 2, (NSTRLST, ADDR), neon_ldx_stx),
21663 nUF(vst3, _vst3, 2, (NSTRLST, ADDR), neon_ldx_stx),
21664 nUF(vld4, _vld4, 2, (NSTRLST, ADDR), neon_ldx_stx),
21665 nUF(vst4, _vst4, 2, (NSTRLST, ADDR), neon_ldx_stx),
5287ad62 21666
c921be7d 21667#undef THUMB_VARIANT
74db7efb
NC
21668#define THUMB_VARIANT & fpu_vfp_ext_v3xd
21669#undef ARM_VARIANT
21670#define ARM_VARIANT & fpu_vfp_ext_v3xd
62f3b8c8
PB
21671 cCE("fconsts", eb00a00, 2, (RVS, I255), vfp_sp_const),
21672 cCE("fshtos", eba0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21673 cCE("fsltos", eba0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21674 cCE("fuhtos", ebb0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21675 cCE("fultos", ebb0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21676 cCE("ftoshs", ebe0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21677 cCE("ftosls", ebe0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21678 cCE("ftouhs", ebf0a40, 2, (RVS, I16z), vfp_sp_conv_16),
21679 cCE("ftouls", ebf0ac0, 2, (RVS, I32), vfp_sp_conv_32),
21680
74db7efb 21681#undef THUMB_VARIANT
c921be7d
NC
21682#define THUMB_VARIANT & fpu_vfp_ext_v3
21683#undef ARM_VARIANT
21684#define ARM_VARIANT & fpu_vfp_ext_v3
21685
21d799b5 21686 cCE("fconstd", eb00b00, 2, (RVD, I255), vfp_dp_const),
21d799b5 21687 cCE("fshtod", eba0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21688 cCE("fsltod", eba0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 21689 cCE("fuhtod", ebb0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21690 cCE("fultod", ebb0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 21691 cCE("ftoshd", ebe0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21692 cCE("ftosld", ebe0bc0, 2, (RVD, I32), vfp_dp_conv_32),
21d799b5 21693 cCE("ftouhd", ebf0b40, 2, (RVD, I16z), vfp_dp_conv_16),
21d799b5 21694 cCE("ftould", ebf0bc0, 2, (RVD, I32), vfp_dp_conv_32),
c19d1205 21695
74db7efb
NC
21696#undef ARM_VARIANT
21697#define ARM_VARIANT & fpu_vfp_ext_fma
21698#undef THUMB_VARIANT
21699#define THUMB_VARIANT & fpu_vfp_ext_fma
62f3b8c8
PB
21700 /* Mnemonics shared by Neon and VFP. These are included in the
21701 VFP FMA variant; NEON and VFP FMA always includes the NEON
21702 FMA instructions. */
21703 nCEF(vfma, _vfma, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_fmac),
21704 nCEF(vfms, _vfms, 3, (RNSDQ, oRNSDQ, RNSDQ), neon_fmac),
21705 /* ffmas/ffmad/ffmss/ffmsd are dummy mnemonics to satisfy gas;
21706 the v form should always be used. */
21707 cCE("ffmas", ea00a00, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21708 cCE("ffnmas", ea00a40, 3, (RVS, RVS, RVS), vfp_sp_dyadic),
21709 cCE("ffmad", ea00b00, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21710 cCE("ffnmad", ea00b40, 3, (RVD, RVD, RVD), vfp_dp_rd_rn_rm),
21711 nCE(vfnma, _vfnma, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21712 nCE(vfnms, _vfnms, 3, (RVSD, RVSD, RVSD), vfp_nsyn_nmul),
21713
5287ad62 21714#undef THUMB_VARIANT
c921be7d
NC
21715#undef ARM_VARIANT
21716#define ARM_VARIANT & arm_cext_xscale /* Intel XScale extensions. */
21717
21d799b5
NC
21718 cCE("mia", e200010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21719 cCE("miaph", e280010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21720 cCE("miabb", e2c0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21721 cCE("miabt", e2d0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21722 cCE("miatb", e2e0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21723 cCE("miatt", e2f0010, 3, (RXA, RRnpc, RRnpc), xsc_mia),
21724 cCE("mar", c400000, 3, (RXA, RRnpc, RRnpc), xsc_mar),
21725 cCE("mra", c500000, 3, (RRnpc, RRnpc, RXA), xsc_mra),
c19d1205 21726
c921be7d
NC
21727#undef ARM_VARIANT
21728#define ARM_VARIANT & arm_cext_iwmmxt /* Intel Wireless MMX technology. */
21729
21d799b5
NC
21730 cCE("tandcb", e13f130, 1, (RR), iwmmxt_tandorc),
21731 cCE("tandch", e53f130, 1, (RR), iwmmxt_tandorc),
21732 cCE("tandcw", e93f130, 1, (RR), iwmmxt_tandorc),
21733 cCE("tbcstb", e400010, 2, (RIWR, RR), rn_rd),
21734 cCE("tbcsth", e400050, 2, (RIWR, RR), rn_rd),
21735 cCE("tbcstw", e400090, 2, (RIWR, RR), rn_rd),
21736 cCE("textrcb", e130170, 2, (RR, I7), iwmmxt_textrc),
21737 cCE("textrch", e530170, 2, (RR, I7), iwmmxt_textrc),
21738 cCE("textrcw", e930170, 2, (RR, I7), iwmmxt_textrc),
74db7efb
NC
21739 cCE("textrmub",e100070, 3, (RR, RIWR, I7), iwmmxt_textrm),
21740 cCE("textrmuh",e500070, 3, (RR, RIWR, I7), iwmmxt_textrm),
21741 cCE("textrmuw",e900070, 3, (RR, RIWR, I7), iwmmxt_textrm),
21742 cCE("textrmsb",e100078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21743 cCE("textrmsh",e500078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21744 cCE("textrmsw",e900078, 3, (RR, RIWR, I7), iwmmxt_textrm),
21d799b5
NC
21745 cCE("tinsrb", e600010, 3, (RIWR, RR, I7), iwmmxt_tinsr),
21746 cCE("tinsrh", e600050, 3, (RIWR, RR, I7), iwmmxt_tinsr),
21747 cCE("tinsrw", e600090, 3, (RIWR, RR, I7), iwmmxt_tinsr),
21748 cCE("tmcr", e000110, 2, (RIWC_RIWG, RR), rn_rd),
21749 cCE("tmcrr", c400000, 3, (RIWR, RR, RR), rm_rd_rn),
21750 cCE("tmia", e200010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21751 cCE("tmiaph", e280010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21752 cCE("tmiabb", e2c0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21753 cCE("tmiabt", e2d0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21754 cCE("tmiatb", e2e0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
21755 cCE("tmiatt", e2f0010, 3, (RIWR, RR, RR), iwmmxt_tmia),
74db7efb
NC
21756 cCE("tmovmskb",e100030, 2, (RR, RIWR), rd_rn),
21757 cCE("tmovmskh",e500030, 2, (RR, RIWR), rd_rn),
21758 cCE("tmovmskw",e900030, 2, (RR, RIWR), rd_rn),
21d799b5
NC
21759 cCE("tmrc", e100110, 2, (RR, RIWC_RIWG), rd_rn),
21760 cCE("tmrrc", c500000, 3, (RR, RR, RIWR), rd_rn_rm),
21761 cCE("torcb", e13f150, 1, (RR), iwmmxt_tandorc),
21762 cCE("torch", e53f150, 1, (RR), iwmmxt_tandorc),
21763 cCE("torcw", e93f150, 1, (RR), iwmmxt_tandorc),
21764 cCE("waccb", e0001c0, 2, (RIWR, RIWR), rd_rn),
21765 cCE("wacch", e4001c0, 2, (RIWR, RIWR), rd_rn),
21766 cCE("waccw", e8001c0, 2, (RIWR, RIWR), rd_rn),
21767 cCE("waddbss", e300180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21768 cCE("waddb", e000180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21769 cCE("waddbus", e100180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21770 cCE("waddhss", e700180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21771 cCE("waddh", e400180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21772 cCE("waddhus", e500180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21773 cCE("waddwss", eb00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21774 cCE("waddw", e800180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21775 cCE("waddwus", e900180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21776 cCE("waligni", e000020, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_waligni),
74db7efb
NC
21777 cCE("walignr0",e800020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21778 cCE("walignr1",e900020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21779 cCE("walignr2",ea00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21780 cCE("walignr3",eb00020, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
21781 cCE("wand", e200000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21782 cCE("wandn", e300000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21783 cCE("wavg2b", e800000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21784 cCE("wavg2br", e900000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21785 cCE("wavg2h", ec00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21786 cCE("wavg2hr", ed00000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21787 cCE("wcmpeqb", e000060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21788 cCE("wcmpeqh", e400060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21789 cCE("wcmpeqw", e800060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
21790 cCE("wcmpgtub",e100060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21791 cCE("wcmpgtuh",e500060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21792 cCE("wcmpgtuw",e900060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21793 cCE("wcmpgtsb",e300060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21794 cCE("wcmpgtsh",e700060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21795 cCE("wcmpgtsw",eb00060, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
21796 cCE("wldrb", c100000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21797 cCE("wldrh", c500000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21798 cCE("wldrw", c100100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
21799 cCE("wldrd", c500100, 2, (RIWR, ADDR), iwmmxt_wldstd),
21800 cCE("wmacs", e600100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21801 cCE("wmacsz", e700100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21802 cCE("wmacu", e400100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21803 cCE("wmacuz", e500100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21804 cCE("wmadds", ea00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21805 cCE("wmaddu", e800100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21806 cCE("wmaxsb", e200160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21807 cCE("wmaxsh", e600160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21808 cCE("wmaxsw", ea00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21809 cCE("wmaxub", e000160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21810 cCE("wmaxuh", e400160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21811 cCE("wmaxuw", e800160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21812 cCE("wminsb", e300160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21813 cCE("wminsh", e700160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21814 cCE("wminsw", eb00160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21815 cCE("wminub", e100160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21816 cCE("wminuh", e500160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21817 cCE("wminuw", e900160, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21818 cCE("wmov", e000000, 2, (RIWR, RIWR), iwmmxt_wmov),
21819 cCE("wmulsm", e300100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21820 cCE("wmulsl", e200100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21821 cCE("wmulum", e100100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21822 cCE("wmulul", e000100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21823 cCE("wor", e000000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
74db7efb
NC
21824 cCE("wpackhss",e700080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21825 cCE("wpackhus",e500080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21826 cCE("wpackwss",eb00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21827 cCE("wpackwus",e900080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21828 cCE("wpackdss",ef00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21829 cCE("wpackdus",ed00080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21d799b5
NC
21830 cCE("wrorh", e700040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21831 cCE("wrorhg", e700148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21832 cCE("wrorw", eb00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21833 cCE("wrorwg", eb00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21834 cCE("wrord", ef00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21835 cCE("wrordg", ef00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21836 cCE("wsadb", e000120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21837 cCE("wsadbz", e100120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21838 cCE("wsadh", e400120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21839 cCE("wsadhz", e500120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21840 cCE("wshufh", e0001e0, 3, (RIWR, RIWR, I255), iwmmxt_wshufh),
21841 cCE("wsllh", e500040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21842 cCE("wsllhg", e500148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21843 cCE("wsllw", e900040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21844 cCE("wsllwg", e900148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21845 cCE("wslld", ed00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21846 cCE("wslldg", ed00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21847 cCE("wsrah", e400040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21848 cCE("wsrahg", e400148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21849 cCE("wsraw", e800040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21850 cCE("wsrawg", e800148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21851 cCE("wsrad", ec00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21852 cCE("wsradg", ec00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21853 cCE("wsrlh", e600040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21854 cCE("wsrlhg", e600148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21855 cCE("wsrlw", ea00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21856 cCE("wsrlwg", ea00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21857 cCE("wsrld", ee00040, 3, (RIWR, RIWR, RIWR_I32z),iwmmxt_wrwrwr_or_imm5),
21858 cCE("wsrldg", ee00148, 3, (RIWR, RIWR, RIWG), rd_rn_rm),
21859 cCE("wstrb", c000000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21860 cCE("wstrh", c400000, 2, (RIWR, ADDR), iwmmxt_wldstbh),
21861 cCE("wstrw", c000100, 2, (RIWR_RIWC, ADDR), iwmmxt_wldstw),
21862 cCE("wstrd", c400100, 2, (RIWR, ADDR), iwmmxt_wldstd),
21863 cCE("wsubbss", e3001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21864 cCE("wsubb", e0001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21865 cCE("wsubbus", e1001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21866 cCE("wsubhss", e7001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21867 cCE("wsubh", e4001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21868 cCE("wsubhus", e5001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21869 cCE("wsubwss", eb001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21870 cCE("wsubw", e8001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21871 cCE("wsubwus", e9001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21872 cCE("wunpckehub",e0000c0, 2, (RIWR, RIWR), rd_rn),
21873 cCE("wunpckehuh",e4000c0, 2, (RIWR, RIWR), rd_rn),
21874 cCE("wunpckehuw",e8000c0, 2, (RIWR, RIWR), rd_rn),
21875 cCE("wunpckehsb",e2000c0, 2, (RIWR, RIWR), rd_rn),
21876 cCE("wunpckehsh",e6000c0, 2, (RIWR, RIWR), rd_rn),
21877 cCE("wunpckehsw",ea000c0, 2, (RIWR, RIWR), rd_rn),
21878 cCE("wunpckihb", e1000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21879 cCE("wunpckihh", e5000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21880 cCE("wunpckihw", e9000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21881 cCE("wunpckelub",e0000e0, 2, (RIWR, RIWR), rd_rn),
21882 cCE("wunpckeluh",e4000e0, 2, (RIWR, RIWR), rd_rn),
21883 cCE("wunpckeluw",e8000e0, 2, (RIWR, RIWR), rd_rn),
21884 cCE("wunpckelsb",e2000e0, 2, (RIWR, RIWR), rd_rn),
21885 cCE("wunpckelsh",e6000e0, 2, (RIWR, RIWR), rd_rn),
21886 cCE("wunpckelsw",ea000e0, 2, (RIWR, RIWR), rd_rn),
21887 cCE("wunpckilb", e1000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21888 cCE("wunpckilh", e5000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21889 cCE("wunpckilw", e9000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21890 cCE("wxor", e100000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21891 cCE("wzero", e300000, 1, (RIWR), iwmmxt_wzero),
c19d1205 21892
c921be7d
NC
21893#undef ARM_VARIANT
21894#define ARM_VARIANT & arm_cext_iwmmxt2 /* Intel Wireless MMX technology, version 2. */
21895
21d799b5
NC
21896 cCE("torvscb", e12f190, 1, (RR), iwmmxt_tandorc),
21897 cCE("torvsch", e52f190, 1, (RR), iwmmxt_tandorc),
21898 cCE("torvscw", e92f190, 1, (RR), iwmmxt_tandorc),
21899 cCE("wabsb", e2001c0, 2, (RIWR, RIWR), rd_rn),
21900 cCE("wabsh", e6001c0, 2, (RIWR, RIWR), rd_rn),
21901 cCE("wabsw", ea001c0, 2, (RIWR, RIWR), rd_rn),
21902 cCE("wabsdiffb", e1001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21903 cCE("wabsdiffh", e5001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21904 cCE("wabsdiffw", e9001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21905 cCE("waddbhusl", e2001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21906 cCE("waddbhusm", e6001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21907 cCE("waddhc", e600180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21908 cCE("waddwc", ea00180, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21909 cCE("waddsubhx", ea001a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21910 cCE("wavg4", e400000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21911 cCE("wavg4r", e500000, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21912 cCE("wmaddsn", ee00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21913 cCE("wmaddsx", eb00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21914 cCE("wmaddun", ec00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21915 cCE("wmaddux", e900100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21916 cCE("wmerge", e000080, 4, (RIWR, RIWR, RIWR, I7), iwmmxt_wmerge),
21917 cCE("wmiabb", e0000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21918 cCE("wmiabt", e1000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21919 cCE("wmiatb", e2000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21920 cCE("wmiatt", e3000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21921 cCE("wmiabbn", e4000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21922 cCE("wmiabtn", e5000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21923 cCE("wmiatbn", e6000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21924 cCE("wmiattn", e7000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21925 cCE("wmiawbb", e800120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21926 cCE("wmiawbt", e900120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21927 cCE("wmiawtb", ea00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21928 cCE("wmiawtt", eb00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21929 cCE("wmiawbbn", ec00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21930 cCE("wmiawbtn", ed00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21931 cCE("wmiawtbn", ee00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21932 cCE("wmiawttn", ef00120, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21933 cCE("wmulsmr", ef00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21934 cCE("wmulumr", ed00100, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21935 cCE("wmulwumr", ec000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21936 cCE("wmulwsmr", ee000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21937 cCE("wmulwum", ed000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21938 cCE("wmulwsm", ef000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21939 cCE("wmulwl", eb000c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21940 cCE("wqmiabb", e8000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21941 cCE("wqmiabt", e9000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21942 cCE("wqmiatb", ea000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21943 cCE("wqmiatt", eb000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21944 cCE("wqmiabbn", ec000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21945 cCE("wqmiabtn", ed000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21946 cCE("wqmiatbn", ee000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21947 cCE("wqmiattn", ef000a0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21948 cCE("wqmulm", e100080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21949 cCE("wqmulmr", e300080, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21950 cCE("wqmulwm", ec000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21951 cCE("wqmulwmr", ee000e0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
21952 cCE("wsubaddhx", ed001c0, 3, (RIWR, RIWR, RIWR), rd_rn_rm),
2d447fca 21953
c921be7d
NC
21954#undef ARM_VARIANT
21955#define ARM_VARIANT & arm_cext_maverick /* Cirrus Maverick instructions. */
21956
21d799b5
NC
21957 cCE("cfldrs", c100400, 2, (RMF, ADDRGLDC), rd_cpaddr),
21958 cCE("cfldrd", c500400, 2, (RMD, ADDRGLDC), rd_cpaddr),
21959 cCE("cfldr32", c100500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
21960 cCE("cfldr64", c500500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
21961 cCE("cfstrs", c000400, 2, (RMF, ADDRGLDC), rd_cpaddr),
21962 cCE("cfstrd", c400400, 2, (RMD, ADDRGLDC), rd_cpaddr),
21963 cCE("cfstr32", c000500, 2, (RMFX, ADDRGLDC), rd_cpaddr),
21964 cCE("cfstr64", c400500, 2, (RMDX, ADDRGLDC), rd_cpaddr),
21965 cCE("cfmvsr", e000450, 2, (RMF, RR), rn_rd),
21966 cCE("cfmvrs", e100450, 2, (RR, RMF), rd_rn),
21967 cCE("cfmvdlr", e000410, 2, (RMD, RR), rn_rd),
21968 cCE("cfmvrdl", e100410, 2, (RR, RMD), rd_rn),
21969 cCE("cfmvdhr", e000430, 2, (RMD, RR), rn_rd),
21970 cCE("cfmvrdh", e100430, 2, (RR, RMD), rd_rn),
74db7efb
NC
21971 cCE("cfmv64lr",e000510, 2, (RMDX, RR), rn_rd),
21972 cCE("cfmvr64l",e100510, 2, (RR, RMDX), rd_rn),
21973 cCE("cfmv64hr",e000530, 2, (RMDX, RR), rn_rd),
21974 cCE("cfmvr64h",e100530, 2, (RR, RMDX), rd_rn),
21975 cCE("cfmval32",e200440, 2, (RMAX, RMFX), rd_rn),
21976 cCE("cfmv32al",e100440, 2, (RMFX, RMAX), rd_rn),
21977 cCE("cfmvam32",e200460, 2, (RMAX, RMFX), rd_rn),
21978 cCE("cfmv32am",e100460, 2, (RMFX, RMAX), rd_rn),
21979 cCE("cfmvah32",e200480, 2, (RMAX, RMFX), rd_rn),
21980 cCE("cfmv32ah",e100480, 2, (RMFX, RMAX), rd_rn),
21d799b5
NC
21981 cCE("cfmva32", e2004a0, 2, (RMAX, RMFX), rd_rn),
21982 cCE("cfmv32a", e1004a0, 2, (RMFX, RMAX), rd_rn),
21983 cCE("cfmva64", e2004c0, 2, (RMAX, RMDX), rd_rn),
21984 cCE("cfmv64a", e1004c0, 2, (RMDX, RMAX), rd_rn),
74db7efb
NC
21985 cCE("cfmvsc32",e2004e0, 2, (RMDS, RMDX), mav_dspsc),
21986 cCE("cfmv32sc",e1004e0, 2, (RMDX, RMDS), rd),
21d799b5
NC
21987 cCE("cfcpys", e000400, 2, (RMF, RMF), rd_rn),
21988 cCE("cfcpyd", e000420, 2, (RMD, RMD), rd_rn),
21989 cCE("cfcvtsd", e000460, 2, (RMD, RMF), rd_rn),
21990 cCE("cfcvtds", e000440, 2, (RMF, RMD), rd_rn),
74db7efb
NC
21991 cCE("cfcvt32s",e000480, 2, (RMF, RMFX), rd_rn),
21992 cCE("cfcvt32d",e0004a0, 2, (RMD, RMFX), rd_rn),
21993 cCE("cfcvt64s",e0004c0, 2, (RMF, RMDX), rd_rn),
21994 cCE("cfcvt64d",e0004e0, 2, (RMD, RMDX), rd_rn),
21995 cCE("cfcvts32",e100580, 2, (RMFX, RMF), rd_rn),
21996 cCE("cfcvtd32",e1005a0, 2, (RMFX, RMD), rd_rn),
21d799b5
NC
21997 cCE("cftruncs32",e1005c0, 2, (RMFX, RMF), rd_rn),
21998 cCE("cftruncd32",e1005e0, 2, (RMFX, RMD), rd_rn),
74db7efb
NC
21999 cCE("cfrshl32",e000550, 3, (RMFX, RMFX, RR), mav_triple),
22000 cCE("cfrshl64",e000570, 3, (RMDX, RMDX, RR), mav_triple),
21d799b5
NC
22001 cCE("cfsh32", e000500, 3, (RMFX, RMFX, I63s), mav_shift),
22002 cCE("cfsh64", e200500, 3, (RMDX, RMDX, I63s), mav_shift),
22003 cCE("cfcmps", e100490, 3, (RR, RMF, RMF), rd_rn_rm),
22004 cCE("cfcmpd", e1004b0, 3, (RR, RMD, RMD), rd_rn_rm),
22005 cCE("cfcmp32", e100590, 3, (RR, RMFX, RMFX), rd_rn_rm),
22006 cCE("cfcmp64", e1005b0, 3, (RR, RMDX, RMDX), rd_rn_rm),
22007 cCE("cfabss", e300400, 2, (RMF, RMF), rd_rn),
22008 cCE("cfabsd", e300420, 2, (RMD, RMD), rd_rn),
22009 cCE("cfnegs", e300440, 2, (RMF, RMF), rd_rn),
22010 cCE("cfnegd", e300460, 2, (RMD, RMD), rd_rn),
22011 cCE("cfadds", e300480, 3, (RMF, RMF, RMF), rd_rn_rm),
22012 cCE("cfaddd", e3004a0, 3, (RMD, RMD, RMD), rd_rn_rm),
22013 cCE("cfsubs", e3004c0, 3, (RMF, RMF, RMF), rd_rn_rm),
22014 cCE("cfsubd", e3004e0, 3, (RMD, RMD, RMD), rd_rn_rm),
22015 cCE("cfmuls", e100400, 3, (RMF, RMF, RMF), rd_rn_rm),
22016 cCE("cfmuld", e100420, 3, (RMD, RMD, RMD), rd_rn_rm),
22017 cCE("cfabs32", e300500, 2, (RMFX, RMFX), rd_rn),
22018 cCE("cfabs64", e300520, 2, (RMDX, RMDX), rd_rn),
22019 cCE("cfneg32", e300540, 2, (RMFX, RMFX), rd_rn),
22020 cCE("cfneg64", e300560, 2, (RMDX, RMDX), rd_rn),
22021 cCE("cfadd32", e300580, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
22022 cCE("cfadd64", e3005a0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
22023 cCE("cfsub32", e3005c0, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
22024 cCE("cfsub64", e3005e0, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
22025 cCE("cfmul32", e100500, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
22026 cCE("cfmul64", e100520, 3, (RMDX, RMDX, RMDX), rd_rn_rm),
22027 cCE("cfmac32", e100540, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
22028 cCE("cfmsc32", e100560, 3, (RMFX, RMFX, RMFX), rd_rn_rm),
74db7efb
NC
22029 cCE("cfmadd32",e000600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
22030 cCE("cfmsub32",e100600, 4, (RMAX, RMFX, RMFX, RMFX), mav_quad),
21d799b5
NC
22031 cCE("cfmadda32", e200600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
22032 cCE("cfmsuba32", e300600, 4, (RMAX, RMAX, RMFX, RMFX), mav_quad),
4ed7ed8d 22033
7fadb25d
SD
22034 /* ARMv8.5-A instructions. */
22035#undef ARM_VARIANT
22036#define ARM_VARIANT & arm_ext_sb
22037#undef THUMB_VARIANT
22038#define THUMB_VARIANT & arm_ext_sb
22039 TUF("sb", 57ff070, f3bf8f70, 0, (), noargs, noargs),
22040
dad0c3bf
SD
22041#undef ARM_VARIANT
22042#define ARM_VARIANT & arm_ext_predres
22043#undef THUMB_VARIANT
22044#define THUMB_VARIANT & arm_ext_predres
22045 CE("cfprctx", e070f93, 1, (RRnpc), rd),
22046 CE("dvprctx", e070fb3, 1, (RRnpc), rd),
22047 CE("cpprctx", e070ff3, 1, (RRnpc), rd),
22048
16a1fa25 22049 /* ARMv8-M instructions. */
4ed7ed8d
TP
22050#undef ARM_VARIANT
22051#define ARM_VARIANT NULL
22052#undef THUMB_VARIANT
22053#define THUMB_VARIANT & arm_ext_v8m
cf3cf39d
TP
22054 ToU("sg", e97fe97f, 0, (), noargs),
22055 ToC("blxns", 4784, 1, (RRnpc), t_blx),
22056 ToC("bxns", 4704, 1, (RRnpc), t_bx),
22057 ToC("tt", e840f000, 2, (RRnpc, RRnpc), tt),
22058 ToC("ttt", e840f040, 2, (RRnpc, RRnpc), tt),
22059 ToC("tta", e840f080, 2, (RRnpc, RRnpc), tt),
22060 ToC("ttat", e840f0c0, 2, (RRnpc, RRnpc), tt),
16a1fa25
TP
22061
22062 /* FP for ARMv8-M Mainline. Enabled for ARMv8-M Mainline because the
22063 instructions behave as nop if no VFP is present. */
22064#undef THUMB_VARIANT
22065#define THUMB_VARIANT & arm_ext_v8m_main
cf3cf39d
TP
22066 ToC("vlldm", ec300a00, 1, (RRnpc), rn),
22067 ToC("vlstm", ec200a00, 1, (RRnpc), rn),
4389b29a
AV
22068
22069 /* Armv8.1-M Mainline instructions. */
22070#undef THUMB_VARIANT
22071#define THUMB_VARIANT & arm_ext_v8_1m_main
22072 toC("bf", _bf, 2, (EXPs, EXPs), t_branch_future),
f6b2b12d 22073 toU("bfcsel", _bfcsel, 4, (EXPs, EXPs, EXPs, COND), t_branch_future),
f1c7f421 22074 toC("bfx", _bfx, 2, (EXPs, RRnpcsp), t_branch_future),
65d1bc05 22075 toC("bfl", _bfl, 2, (EXPs, EXPs), t_branch_future),
f1c7f421 22076 toC("bflx", _bflx, 2, (EXPs, RRnpcsp), t_branch_future),
60f993ce
AV
22077
22078 toU("dls", _dls, 2, (LR, RRnpcsp), t_loloop),
22079 toU("wls", _wls, 3, (LR, RRnpcsp, EXP), t_loloop),
22080 toU("le", _le, 2, (oLR, EXP), t_loloop),
4b5a202f 22081
efd6b359
AV
22082 ToC("clrm", e89f0000, 1, (CLRMLST), t_clrm),
22083 ToC("vscclrm", ec9f0a00, 1, (VRSDVLST), t_vscclrm)
c19d1205
ZW
22084};
22085#undef ARM_VARIANT
22086#undef THUMB_VARIANT
22087#undef TCE
c19d1205
ZW
22088#undef TUE
22089#undef TUF
22090#undef TCC
8f06b2d8 22091#undef cCE
e3cb604e
PB
22092#undef cCL
22093#undef C3E
4389b29a 22094#undef C3
c19d1205
ZW
22095#undef CE
22096#undef CM
4389b29a 22097#undef CL
c19d1205
ZW
22098#undef UE
22099#undef UF
22100#undef UT
5287ad62
JB
22101#undef NUF
22102#undef nUF
22103#undef NCE
22104#undef nCE
c19d1205
ZW
22105#undef OPS0
22106#undef OPS1
22107#undef OPS2
22108#undef OPS3
22109#undef OPS4
22110#undef OPS5
22111#undef OPS6
22112#undef do_0
4389b29a
AV
22113#undef ToC
22114#undef toC
22115#undef ToU
f6b2b12d 22116#undef toU
c19d1205
ZW
22117\f
22118/* MD interface: bits in the object file. */
bfae80f2 22119
c19d1205
ZW
22120/* Turn an integer of n bytes (in val) into a stream of bytes appropriate
22121 for use in the a.out file, and stores them in the array pointed to by buf.
22122 This knows about the endian-ness of the target machine and does
22123 THE RIGHT THING, whatever it is. Possible values for n are 1 (byte)
22124 2 (short) and 4 (long) Floating numbers are put out as a series of
22125 LITTLENUMS (shorts, here at least). */
b99bd4ef 22126
c19d1205
ZW
22127void
22128md_number_to_chars (char * buf, valueT val, int n)
22129{
22130 if (target_big_endian)
22131 number_to_chars_bigendian (buf, val, n);
22132 else
22133 number_to_chars_littleendian (buf, val, n);
bfae80f2
RE
22134}
22135
c19d1205
ZW
22136static valueT
22137md_chars_to_number (char * buf, int n)
bfae80f2 22138{
c19d1205
ZW
22139 valueT result = 0;
22140 unsigned char * where = (unsigned char *) buf;
bfae80f2 22141
c19d1205 22142 if (target_big_endian)
b99bd4ef 22143 {
c19d1205
ZW
22144 while (n--)
22145 {
22146 result <<= 8;
22147 result |= (*where++ & 255);
22148 }
b99bd4ef 22149 }
c19d1205 22150 else
b99bd4ef 22151 {
c19d1205
ZW
22152 while (n--)
22153 {
22154 result <<= 8;
22155 result |= (where[n] & 255);
22156 }
bfae80f2 22157 }
b99bd4ef 22158
c19d1205 22159 return result;
bfae80f2 22160}
b99bd4ef 22161
c19d1205 22162/* MD interface: Sections. */
b99bd4ef 22163
fa94de6b
RM
22164/* Calculate the maximum variable size (i.e., excluding fr_fix)
22165 that an rs_machine_dependent frag may reach. */
22166
22167unsigned int
22168arm_frag_max_var (fragS *fragp)
22169{
22170 /* We only use rs_machine_dependent for variable-size Thumb instructions,
22171 which are either THUMB_SIZE (2) or INSN_SIZE (4).
22172
22173 Note that we generate relaxable instructions even for cases that don't
22174 really need it, like an immediate that's a trivial constant. So we're
22175 overestimating the instruction size for some of those cases. Rather
22176 than putting more intelligence here, it would probably be better to
22177 avoid generating a relaxation frag in the first place when it can be
22178 determined up front that a short instruction will suffice. */
22179
22180 gas_assert (fragp->fr_type == rs_machine_dependent);
22181 return INSN_SIZE;
22182}
22183
0110f2b8
PB
22184/* Estimate the size of a frag before relaxing. Assume everything fits in
22185 2 bytes. */
22186
c19d1205 22187int
0110f2b8 22188md_estimate_size_before_relax (fragS * fragp,
c19d1205
ZW
22189 segT segtype ATTRIBUTE_UNUSED)
22190{
0110f2b8
PB
22191 fragp->fr_var = 2;
22192 return 2;
22193}
22194
22195/* Convert a machine dependent frag. */
22196
22197void
22198md_convert_frag (bfd *abfd, segT asec ATTRIBUTE_UNUSED, fragS *fragp)
22199{
22200 unsigned long insn;
22201 unsigned long old_op;
22202 char *buf;
22203 expressionS exp;
22204 fixS *fixp;
22205 int reloc_type;
22206 int pc_rel;
22207 int opcode;
22208
22209 buf = fragp->fr_literal + fragp->fr_fix;
22210
22211 old_op = bfd_get_16(abfd, buf);
5f4273c7
NC
22212 if (fragp->fr_symbol)
22213 {
0110f2b8
PB
22214 exp.X_op = O_symbol;
22215 exp.X_add_symbol = fragp->fr_symbol;
5f4273c7
NC
22216 }
22217 else
22218 {
0110f2b8 22219 exp.X_op = O_constant;
5f4273c7 22220 }
0110f2b8
PB
22221 exp.X_add_number = fragp->fr_offset;
22222 opcode = fragp->fr_subtype;
22223 switch (opcode)
22224 {
22225 case T_MNEM_ldr_pc:
22226 case T_MNEM_ldr_pc2:
22227 case T_MNEM_ldr_sp:
22228 case T_MNEM_str_sp:
22229 case T_MNEM_ldr:
22230 case T_MNEM_ldrb:
22231 case T_MNEM_ldrh:
22232 case T_MNEM_str:
22233 case T_MNEM_strb:
22234 case T_MNEM_strh:
22235 if (fragp->fr_var == 4)
22236 {
5f4273c7 22237 insn = THUMB_OP32 (opcode);
0110f2b8
PB
22238 if ((old_op >> 12) == 4 || (old_op >> 12) == 9)
22239 {
22240 insn |= (old_op & 0x700) << 4;
22241 }
22242 else
22243 {
22244 insn |= (old_op & 7) << 12;
22245 insn |= (old_op & 0x38) << 13;
22246 }
22247 insn |= 0x00000c00;
22248 put_thumb32_insn (buf, insn);
22249 reloc_type = BFD_RELOC_ARM_T32_OFFSET_IMM;
22250 }
22251 else
22252 {
22253 reloc_type = BFD_RELOC_ARM_THUMB_OFFSET;
22254 }
22255 pc_rel = (opcode == T_MNEM_ldr_pc2);
22256 break;
22257 case T_MNEM_adr:
22258 if (fragp->fr_var == 4)
22259 {
22260 insn = THUMB_OP32 (opcode);
22261 insn |= (old_op & 0xf0) << 4;
22262 put_thumb32_insn (buf, insn);
22263 reloc_type = BFD_RELOC_ARM_T32_ADD_PC12;
22264 }
22265 else
22266 {
22267 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
22268 exp.X_add_number -= 4;
22269 }
22270 pc_rel = 1;
22271 break;
22272 case T_MNEM_mov:
22273 case T_MNEM_movs:
22274 case T_MNEM_cmp:
22275 case T_MNEM_cmn:
22276 if (fragp->fr_var == 4)
22277 {
22278 int r0off = (opcode == T_MNEM_mov
22279 || opcode == T_MNEM_movs) ? 0 : 8;
22280 insn = THUMB_OP32 (opcode);
22281 insn = (insn & 0xe1ffffff) | 0x10000000;
22282 insn |= (old_op & 0x700) << r0off;
22283 put_thumb32_insn (buf, insn);
22284 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
22285 }
22286 else
22287 {
22288 reloc_type = BFD_RELOC_ARM_THUMB_IMM;
22289 }
22290 pc_rel = 0;
22291 break;
22292 case T_MNEM_b:
22293 if (fragp->fr_var == 4)
22294 {
22295 insn = THUMB_OP32(opcode);
22296 put_thumb32_insn (buf, insn);
22297 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH25;
22298 }
22299 else
22300 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH12;
22301 pc_rel = 1;
22302 break;
22303 case T_MNEM_bcond:
22304 if (fragp->fr_var == 4)
22305 {
22306 insn = THUMB_OP32(opcode);
22307 insn |= (old_op & 0xf00) << 14;
22308 put_thumb32_insn (buf, insn);
22309 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH20;
22310 }
22311 else
22312 reloc_type = BFD_RELOC_THUMB_PCREL_BRANCH9;
22313 pc_rel = 1;
22314 break;
22315 case T_MNEM_add_sp:
22316 case T_MNEM_add_pc:
22317 case T_MNEM_inc_sp:
22318 case T_MNEM_dec_sp:
22319 if (fragp->fr_var == 4)
22320 {
22321 /* ??? Choose between add and addw. */
22322 insn = THUMB_OP32 (opcode);
22323 insn |= (old_op & 0xf0) << 4;
22324 put_thumb32_insn (buf, insn);
16805f35
PB
22325 if (opcode == T_MNEM_add_pc)
22326 reloc_type = BFD_RELOC_ARM_T32_IMM12;
22327 else
22328 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
0110f2b8
PB
22329 }
22330 else
22331 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
22332 pc_rel = 0;
22333 break;
22334
22335 case T_MNEM_addi:
22336 case T_MNEM_addis:
22337 case T_MNEM_subi:
22338 case T_MNEM_subis:
22339 if (fragp->fr_var == 4)
22340 {
22341 insn = THUMB_OP32 (opcode);
22342 insn |= (old_op & 0xf0) << 4;
22343 insn |= (old_op & 0xf) << 16;
22344 put_thumb32_insn (buf, insn);
16805f35
PB
22345 if (insn & (1 << 20))
22346 reloc_type = BFD_RELOC_ARM_T32_ADD_IMM;
22347 else
22348 reloc_type = BFD_RELOC_ARM_T32_IMMEDIATE;
0110f2b8
PB
22349 }
22350 else
22351 reloc_type = BFD_RELOC_ARM_THUMB_ADD;
22352 pc_rel = 0;
22353 break;
22354 default:
5f4273c7 22355 abort ();
0110f2b8
PB
22356 }
22357 fixp = fix_new_exp (fragp, fragp->fr_fix, fragp->fr_var, &exp, pc_rel,
21d799b5 22358 (enum bfd_reloc_code_real) reloc_type);
0110f2b8
PB
22359 fixp->fx_file = fragp->fr_file;
22360 fixp->fx_line = fragp->fr_line;
22361 fragp->fr_fix += fragp->fr_var;
3cfdb781
TG
22362
22363 /* Set whether we use thumb-2 ISA based on final relaxation results. */
22364 if (thumb_mode && fragp->fr_var == 4 && no_cpu_selected ()
22365 && !ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_t2))
22366 ARM_MERGE_FEATURE_SETS (arm_arch_used, thumb_arch_used, arm_ext_v6t2);
0110f2b8
PB
22367}
22368
22369/* Return the size of a relaxable immediate operand instruction.
22370 SHIFT and SIZE specify the form of the allowable immediate. */
22371static int
22372relax_immediate (fragS *fragp, int size, int shift)
22373{
22374 offsetT offset;
22375 offsetT mask;
22376 offsetT low;
22377
22378 /* ??? Should be able to do better than this. */
22379 if (fragp->fr_symbol)
22380 return 4;
22381
22382 low = (1 << shift) - 1;
22383 mask = (1 << (shift + size)) - (1 << shift);
22384 offset = fragp->fr_offset;
22385 /* Force misaligned offsets to 32-bit variant. */
22386 if (offset & low)
5e77afaa 22387 return 4;
0110f2b8
PB
22388 if (offset & ~mask)
22389 return 4;
22390 return 2;
22391}
22392
5e77afaa
PB
22393/* Get the address of a symbol during relaxation. */
22394static addressT
5f4273c7 22395relaxed_symbol_addr (fragS *fragp, long stretch)
5e77afaa
PB
22396{
22397 fragS *sym_frag;
22398 addressT addr;
22399 symbolS *sym;
22400
22401 sym = fragp->fr_symbol;
22402 sym_frag = symbol_get_frag (sym);
22403 know (S_GET_SEGMENT (sym) != absolute_section
22404 || sym_frag == &zero_address_frag);
22405 addr = S_GET_VALUE (sym) + fragp->fr_offset;
22406
22407 /* If frag has yet to be reached on this pass, assume it will
22408 move by STRETCH just as we did. If this is not so, it will
22409 be because some frag between grows, and that will force
22410 another pass. */
22411
22412 if (stretch != 0
22413 && sym_frag->relax_marker != fragp->relax_marker)
4396b686
PB
22414 {
22415 fragS *f;
22416
22417 /* Adjust stretch for any alignment frag. Note that if have
22418 been expanding the earlier code, the symbol may be
22419 defined in what appears to be an earlier frag. FIXME:
22420 This doesn't handle the fr_subtype field, which specifies
22421 a maximum number of bytes to skip when doing an
22422 alignment. */
22423 for (f = fragp; f != NULL && f != sym_frag; f = f->fr_next)
22424 {
22425 if (f->fr_type == rs_align || f->fr_type == rs_align_code)
22426 {
22427 if (stretch < 0)
22428 stretch = - ((- stretch)
22429 & ~ ((1 << (int) f->fr_offset) - 1));
22430 else
22431 stretch &= ~ ((1 << (int) f->fr_offset) - 1);
22432 if (stretch == 0)
22433 break;
22434 }
22435 }
22436 if (f != NULL)
22437 addr += stretch;
22438 }
5e77afaa
PB
22439
22440 return addr;
22441}
22442
0110f2b8
PB
22443/* Return the size of a relaxable adr pseudo-instruction or PC-relative
22444 load. */
22445static int
5e77afaa 22446relax_adr (fragS *fragp, asection *sec, long stretch)
0110f2b8
PB
22447{
22448 addressT addr;
22449 offsetT val;
22450
22451 /* Assume worst case for symbols not known to be in the same section. */
974da60d
NC
22452 if (fragp->fr_symbol == NULL
22453 || !S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
22454 || sec != S_GET_SEGMENT (fragp->fr_symbol)
22455 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
22456 return 4;
22457
5f4273c7 22458 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
22459 addr = fragp->fr_address + fragp->fr_fix;
22460 addr = (addr + 4) & ~3;
5e77afaa 22461 /* Force misaligned targets to 32-bit variant. */
0110f2b8 22462 if (val & 3)
5e77afaa 22463 return 4;
0110f2b8
PB
22464 val -= addr;
22465 if (val < 0 || val > 1020)
22466 return 4;
22467 return 2;
22468}
22469
22470/* Return the size of a relaxable add/sub immediate instruction. */
22471static int
22472relax_addsub (fragS *fragp, asection *sec)
22473{
22474 char *buf;
22475 int op;
22476
22477 buf = fragp->fr_literal + fragp->fr_fix;
22478 op = bfd_get_16(sec->owner, buf);
22479 if ((op & 0xf) == ((op >> 4) & 0xf))
22480 return relax_immediate (fragp, 8, 0);
22481 else
22482 return relax_immediate (fragp, 3, 0);
22483}
22484
e83a675f
RE
22485/* Return TRUE iff the definition of symbol S could be pre-empted
22486 (overridden) at link or load time. */
22487static bfd_boolean
22488symbol_preemptible (symbolS *s)
22489{
22490 /* Weak symbols can always be pre-empted. */
22491 if (S_IS_WEAK (s))
22492 return TRUE;
22493
22494 /* Non-global symbols cannot be pre-empted. */
22495 if (! S_IS_EXTERNAL (s))
22496 return FALSE;
22497
22498#ifdef OBJ_ELF
22499 /* In ELF, a global symbol can be marked protected, or private. In that
22500 case it can't be pre-empted (other definitions in the same link unit
22501 would violate the ODR). */
22502 if (ELF_ST_VISIBILITY (S_GET_OTHER (s)) > STV_DEFAULT)
22503 return FALSE;
22504#endif
22505
22506 /* Other global symbols might be pre-empted. */
22507 return TRUE;
22508}
0110f2b8
PB
22509
22510/* Return the size of a relaxable branch instruction. BITS is the
22511 size of the offset field in the narrow instruction. */
22512
22513static int
5e77afaa 22514relax_branch (fragS *fragp, asection *sec, int bits, long stretch)
0110f2b8
PB
22515{
22516 addressT addr;
22517 offsetT val;
22518 offsetT limit;
22519
22520 /* Assume worst case for symbols not known to be in the same section. */
5f4273c7 22521 if (!S_IS_DEFINED (fragp->fr_symbol)
77db8e2e
NC
22522 || sec != S_GET_SEGMENT (fragp->fr_symbol)
22523 || S_IS_WEAK (fragp->fr_symbol))
0110f2b8
PB
22524 return 4;
22525
267bf995 22526#ifdef OBJ_ELF
e83a675f 22527 /* A branch to a function in ARM state will require interworking. */
267bf995
RR
22528 if (S_IS_DEFINED (fragp->fr_symbol)
22529 && ARM_IS_FUNC (fragp->fr_symbol))
22530 return 4;
e83a675f 22531#endif
0d9b4b55 22532
e83a675f 22533 if (symbol_preemptible (fragp->fr_symbol))
0d9b4b55 22534 return 4;
267bf995 22535
5f4273c7 22536 val = relaxed_symbol_addr (fragp, stretch);
0110f2b8
PB
22537 addr = fragp->fr_address + fragp->fr_fix + 4;
22538 val -= addr;
22539
22540 /* Offset is a signed value *2 */
22541 limit = 1 << bits;
22542 if (val >= limit || val < -limit)
22543 return 4;
22544 return 2;
22545}
22546
22547
22548/* Relax a machine dependent frag. This returns the amount by which
22549 the current size of the frag should change. */
22550
22551int
5e77afaa 22552arm_relax_frag (asection *sec, fragS *fragp, long stretch)
0110f2b8
PB
22553{
22554 int oldsize;
22555 int newsize;
22556
22557 oldsize = fragp->fr_var;
22558 switch (fragp->fr_subtype)
22559 {
22560 case T_MNEM_ldr_pc2:
5f4273c7 22561 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
22562 break;
22563 case T_MNEM_ldr_pc:
22564 case T_MNEM_ldr_sp:
22565 case T_MNEM_str_sp:
5f4273c7 22566 newsize = relax_immediate (fragp, 8, 2);
0110f2b8
PB
22567 break;
22568 case T_MNEM_ldr:
22569 case T_MNEM_str:
5f4273c7 22570 newsize = relax_immediate (fragp, 5, 2);
0110f2b8
PB
22571 break;
22572 case T_MNEM_ldrh:
22573 case T_MNEM_strh:
5f4273c7 22574 newsize = relax_immediate (fragp, 5, 1);
0110f2b8
PB
22575 break;
22576 case T_MNEM_ldrb:
22577 case T_MNEM_strb:
5f4273c7 22578 newsize = relax_immediate (fragp, 5, 0);
0110f2b8
PB
22579 break;
22580 case T_MNEM_adr:
5f4273c7 22581 newsize = relax_adr (fragp, sec, stretch);
0110f2b8
PB
22582 break;
22583 case T_MNEM_mov:
22584 case T_MNEM_movs:
22585 case T_MNEM_cmp:
22586 case T_MNEM_cmn:
5f4273c7 22587 newsize = relax_immediate (fragp, 8, 0);
0110f2b8
PB
22588 break;
22589 case T_MNEM_b:
5f4273c7 22590 newsize = relax_branch (fragp, sec, 11, stretch);
0110f2b8
PB
22591 break;
22592 case T_MNEM_bcond:
5f4273c7 22593 newsize = relax_branch (fragp, sec, 8, stretch);
0110f2b8
PB
22594 break;
22595 case T_MNEM_add_sp:
22596 case T_MNEM_add_pc:
22597 newsize = relax_immediate (fragp, 8, 2);
22598 break;
22599 case T_MNEM_inc_sp:
22600 case T_MNEM_dec_sp:
22601 newsize = relax_immediate (fragp, 7, 2);
22602 break;
22603 case T_MNEM_addi:
22604 case T_MNEM_addis:
22605 case T_MNEM_subi:
22606 case T_MNEM_subis:
22607 newsize = relax_addsub (fragp, sec);
22608 break;
22609 default:
5f4273c7 22610 abort ();
0110f2b8 22611 }
5e77afaa
PB
22612
22613 fragp->fr_var = newsize;
22614 /* Freeze wide instructions that are at or before the same location as
22615 in the previous pass. This avoids infinite loops.
5f4273c7
NC
22616 Don't freeze them unconditionally because targets may be artificially
22617 misaligned by the expansion of preceding frags. */
5e77afaa 22618 if (stretch <= 0 && newsize > 2)
0110f2b8 22619 {
0110f2b8 22620 md_convert_frag (sec->owner, sec, fragp);
5f4273c7 22621 frag_wane (fragp);
0110f2b8 22622 }
5e77afaa 22623
0110f2b8 22624 return newsize - oldsize;
c19d1205 22625}
b99bd4ef 22626
c19d1205 22627/* Round up a section size to the appropriate boundary. */
b99bd4ef 22628
c19d1205
ZW
22629valueT
22630md_section_align (segT segment ATTRIBUTE_UNUSED,
22631 valueT size)
22632{
6844c0cc 22633 return size;
bfae80f2 22634}
b99bd4ef 22635
c19d1205
ZW
22636/* This is called from HANDLE_ALIGN in write.c. Fill in the contents
22637 of an rs_align_code fragment. */
22638
22639void
22640arm_handle_align (fragS * fragP)
bfae80f2 22641{
d9235011 22642 static unsigned char const arm_noop[2][2][4] =
e7495e45
NS
22643 {
22644 { /* ARMv1 */
22645 {0x00, 0x00, 0xa0, 0xe1}, /* LE */
22646 {0xe1, 0xa0, 0x00, 0x00}, /* BE */
22647 },
22648 { /* ARMv6k */
22649 {0x00, 0xf0, 0x20, 0xe3}, /* LE */
22650 {0xe3, 0x20, 0xf0, 0x00}, /* BE */
22651 },
22652 };
d9235011 22653 static unsigned char const thumb_noop[2][2][2] =
e7495e45
NS
22654 {
22655 { /* Thumb-1 */
22656 {0xc0, 0x46}, /* LE */
22657 {0x46, 0xc0}, /* BE */
22658 },
22659 { /* Thumb-2 */
22660 {0x00, 0xbf}, /* LE */
22661 {0xbf, 0x00} /* BE */
22662 }
22663 };
d9235011 22664 static unsigned char const wide_thumb_noop[2][4] =
e7495e45
NS
22665 { /* Wide Thumb-2 */
22666 {0xaf, 0xf3, 0x00, 0x80}, /* LE */
22667 {0xf3, 0xaf, 0x80, 0x00}, /* BE */
22668 };
c921be7d 22669
e7495e45 22670 unsigned bytes, fix, noop_size;
c19d1205 22671 char * p;
d9235011
TS
22672 const unsigned char * noop;
22673 const unsigned char *narrow_noop = NULL;
cd000bff
DJ
22674#ifdef OBJ_ELF
22675 enum mstate state;
22676#endif
bfae80f2 22677
c19d1205 22678 if (fragP->fr_type != rs_align_code)
bfae80f2
RE
22679 return;
22680
c19d1205
ZW
22681 bytes = fragP->fr_next->fr_address - fragP->fr_address - fragP->fr_fix;
22682 p = fragP->fr_literal + fragP->fr_fix;
22683 fix = 0;
bfae80f2 22684
c19d1205
ZW
22685 if (bytes > MAX_MEM_FOR_RS_ALIGN_CODE)
22686 bytes &= MAX_MEM_FOR_RS_ALIGN_CODE;
bfae80f2 22687
cd000bff 22688 gas_assert ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) != 0);
8dc2430f 22689
cd000bff 22690 if (fragP->tc_frag_data.thumb_mode & (~ MODE_RECORDED))
a737bd4d 22691 {
7f78eb34
JW
22692 if (ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
22693 ? selected_cpu : arm_arch_none, arm_ext_v6t2))
e7495e45
NS
22694 {
22695 narrow_noop = thumb_noop[1][target_big_endian];
22696 noop = wide_thumb_noop[target_big_endian];
22697 }
c19d1205 22698 else
e7495e45
NS
22699 noop = thumb_noop[0][target_big_endian];
22700 noop_size = 2;
cd000bff
DJ
22701#ifdef OBJ_ELF
22702 state = MAP_THUMB;
22703#endif
7ed4c4c5
NC
22704 }
22705 else
22706 {
7f78eb34
JW
22707 noop = arm_noop[ARM_CPU_HAS_FEATURE (selected_cpu_name[0]
22708 ? selected_cpu : arm_arch_none,
22709 arm_ext_v6k) != 0]
e7495e45
NS
22710 [target_big_endian];
22711 noop_size = 4;
cd000bff
DJ
22712#ifdef OBJ_ELF
22713 state = MAP_ARM;
22714#endif
7ed4c4c5 22715 }
c921be7d 22716
e7495e45 22717 fragP->fr_var = noop_size;
c921be7d 22718
c19d1205 22719 if (bytes & (noop_size - 1))
7ed4c4c5 22720 {
c19d1205 22721 fix = bytes & (noop_size - 1);
cd000bff
DJ
22722#ifdef OBJ_ELF
22723 insert_data_mapping_symbol (state, fragP->fr_fix, fragP, fix);
22724#endif
c19d1205
ZW
22725 memset (p, 0, fix);
22726 p += fix;
22727 bytes -= fix;
a737bd4d 22728 }
a737bd4d 22729
e7495e45
NS
22730 if (narrow_noop)
22731 {
22732 if (bytes & noop_size)
22733 {
22734 /* Insert a narrow noop. */
22735 memcpy (p, narrow_noop, noop_size);
22736 p += noop_size;
22737 bytes -= noop_size;
22738 fix += noop_size;
22739 }
22740
22741 /* Use wide noops for the remainder */
22742 noop_size = 4;
22743 }
22744
c19d1205 22745 while (bytes >= noop_size)
a737bd4d 22746 {
c19d1205
ZW
22747 memcpy (p, noop, noop_size);
22748 p += noop_size;
22749 bytes -= noop_size;
22750 fix += noop_size;
a737bd4d
NC
22751 }
22752
c19d1205 22753 fragP->fr_fix += fix;
a737bd4d
NC
22754}
22755
c19d1205
ZW
22756/* Called from md_do_align. Used to create an alignment
22757 frag in a code section. */
22758
22759void
22760arm_frag_align_code (int n, int max)
bfae80f2 22761{
c19d1205 22762 char * p;
7ed4c4c5 22763
c19d1205 22764 /* We assume that there will never be a requirement
6ec8e702 22765 to support alignments greater than MAX_MEM_FOR_RS_ALIGN_CODE bytes. */
c19d1205 22766 if (max > MAX_MEM_FOR_RS_ALIGN_CODE)
6ec8e702
NC
22767 {
22768 char err_msg[128];
22769
fa94de6b 22770 sprintf (err_msg,
477330fc
RM
22771 _("alignments greater than %d bytes not supported in .text sections."),
22772 MAX_MEM_FOR_RS_ALIGN_CODE + 1);
20203fb9 22773 as_fatal ("%s", err_msg);
6ec8e702 22774 }
bfae80f2 22775
c19d1205
ZW
22776 p = frag_var (rs_align_code,
22777 MAX_MEM_FOR_RS_ALIGN_CODE,
22778 1,
22779 (relax_substateT) max,
22780 (symbolS *) NULL,
22781 (offsetT) n,
22782 (char *) NULL);
22783 *p = 0;
22784}
bfae80f2 22785
8dc2430f
NC
22786/* Perform target specific initialisation of a frag.
22787 Note - despite the name this initialisation is not done when the frag
22788 is created, but only when its type is assigned. A frag can be created
22789 and used a long time before its type is set, so beware of assuming that
33eaf5de 22790 this initialisation is performed first. */
bfae80f2 22791
cd000bff
DJ
22792#ifndef OBJ_ELF
22793void
22794arm_init_frag (fragS * fragP, int max_chars ATTRIBUTE_UNUSED)
22795{
22796 /* Record whether this frag is in an ARM or a THUMB area. */
2e98972e 22797 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
cd000bff
DJ
22798}
22799
22800#else /* OBJ_ELF is defined. */
c19d1205 22801void
cd000bff 22802arm_init_frag (fragS * fragP, int max_chars)
c19d1205 22803{
e8d84ca1 22804 bfd_boolean frag_thumb_mode;
b968d18a 22805
8dc2430f
NC
22806 /* If the current ARM vs THUMB mode has not already
22807 been recorded into this frag then do so now. */
cd000bff 22808 if ((fragP->tc_frag_data.thumb_mode & MODE_RECORDED) == 0)
b968d18a
JW
22809 fragP->tc_frag_data.thumb_mode = thumb_mode | MODE_RECORDED;
22810
e8d84ca1
NC
22811 /* PR 21809: Do not set a mapping state for debug sections
22812 - it just confuses other tools. */
22813 if (bfd_get_section_flags (NULL, now_seg) & SEC_DEBUGGING)
22814 return;
22815
b968d18a 22816 frag_thumb_mode = fragP->tc_frag_data.thumb_mode ^ MODE_RECORDED;
cd000bff 22817
f9c1b181
RL
22818 /* Record a mapping symbol for alignment frags. We will delete this
22819 later if the alignment ends up empty. */
22820 switch (fragP->fr_type)
22821 {
22822 case rs_align:
22823 case rs_align_test:
22824 case rs_fill:
22825 mapping_state_2 (MAP_DATA, max_chars);
22826 break;
22827 case rs_align_code:
b968d18a 22828 mapping_state_2 (frag_thumb_mode ? MAP_THUMB : MAP_ARM, max_chars);
f9c1b181
RL
22829 break;
22830 default:
22831 break;
cd000bff 22832 }
bfae80f2
RE
22833}
22834
c19d1205
ZW
22835/* When we change sections we need to issue a new mapping symbol. */
22836
22837void
22838arm_elf_change_section (void)
bfae80f2 22839{
c19d1205
ZW
22840 /* Link an unlinked unwind index table section to the .text section. */
22841 if (elf_section_type (now_seg) == SHT_ARM_EXIDX
22842 && elf_linked_to_section (now_seg) == NULL)
22843 elf_linked_to_section (now_seg) = text_section;
bfae80f2
RE
22844}
22845
c19d1205
ZW
22846int
22847arm_elf_section_type (const char * str, size_t len)
e45d0630 22848{
c19d1205
ZW
22849 if (len == 5 && strncmp (str, "exidx", 5) == 0)
22850 return SHT_ARM_EXIDX;
e45d0630 22851
c19d1205
ZW
22852 return -1;
22853}
22854\f
22855/* Code to deal with unwinding tables. */
e45d0630 22856
c19d1205 22857static void add_unwind_adjustsp (offsetT);
e45d0630 22858
5f4273c7 22859/* Generate any deferred unwind frame offset. */
e45d0630 22860
bfae80f2 22861static void
c19d1205 22862flush_pending_unwind (void)
bfae80f2 22863{
c19d1205 22864 offsetT offset;
bfae80f2 22865
c19d1205
ZW
22866 offset = unwind.pending_offset;
22867 unwind.pending_offset = 0;
22868 if (offset != 0)
22869 add_unwind_adjustsp (offset);
bfae80f2
RE
22870}
22871
c19d1205
ZW
22872/* Add an opcode to this list for this function. Two-byte opcodes should
22873 be passed as op[0] << 8 | op[1]. The list of opcodes is built in reverse
22874 order. */
22875
bfae80f2 22876static void
c19d1205 22877add_unwind_opcode (valueT op, int length)
bfae80f2 22878{
c19d1205
ZW
22879 /* Add any deferred stack adjustment. */
22880 if (unwind.pending_offset)
22881 flush_pending_unwind ();
bfae80f2 22882
c19d1205 22883 unwind.sp_restored = 0;
bfae80f2 22884
c19d1205 22885 if (unwind.opcode_count + length > unwind.opcode_alloc)
bfae80f2 22886 {
c19d1205
ZW
22887 unwind.opcode_alloc += ARM_OPCODE_CHUNK_SIZE;
22888 if (unwind.opcodes)
325801bd
TS
22889 unwind.opcodes = XRESIZEVEC (unsigned char, unwind.opcodes,
22890 unwind.opcode_alloc);
c19d1205 22891 else
325801bd 22892 unwind.opcodes = XNEWVEC (unsigned char, unwind.opcode_alloc);
bfae80f2 22893 }
c19d1205 22894 while (length > 0)
bfae80f2 22895 {
c19d1205
ZW
22896 length--;
22897 unwind.opcodes[unwind.opcode_count] = op & 0xff;
22898 op >>= 8;
22899 unwind.opcode_count++;
bfae80f2 22900 }
bfae80f2
RE
22901}
22902
c19d1205
ZW
22903/* Add unwind opcodes to adjust the stack pointer. */
22904
bfae80f2 22905static void
c19d1205 22906add_unwind_adjustsp (offsetT offset)
bfae80f2 22907{
c19d1205 22908 valueT op;
bfae80f2 22909
c19d1205 22910 if (offset > 0x200)
bfae80f2 22911 {
c19d1205
ZW
22912 /* We need at most 5 bytes to hold a 32-bit value in a uleb128. */
22913 char bytes[5];
22914 int n;
22915 valueT o;
bfae80f2 22916
c19d1205
ZW
22917 /* Long form: 0xb2, uleb128. */
22918 /* This might not fit in a word so add the individual bytes,
22919 remembering the list is built in reverse order. */
22920 o = (valueT) ((offset - 0x204) >> 2);
22921 if (o == 0)
22922 add_unwind_opcode (0, 1);
bfae80f2 22923
c19d1205
ZW
22924 /* Calculate the uleb128 encoding of the offset. */
22925 n = 0;
22926 while (o)
22927 {
22928 bytes[n] = o & 0x7f;
22929 o >>= 7;
22930 if (o)
22931 bytes[n] |= 0x80;
22932 n++;
22933 }
22934 /* Add the insn. */
22935 for (; n; n--)
22936 add_unwind_opcode (bytes[n - 1], 1);
22937 add_unwind_opcode (0xb2, 1);
22938 }
22939 else if (offset > 0x100)
bfae80f2 22940 {
c19d1205
ZW
22941 /* Two short opcodes. */
22942 add_unwind_opcode (0x3f, 1);
22943 op = (offset - 0x104) >> 2;
22944 add_unwind_opcode (op, 1);
bfae80f2 22945 }
c19d1205
ZW
22946 else if (offset > 0)
22947 {
22948 /* Short opcode. */
22949 op = (offset - 4) >> 2;
22950 add_unwind_opcode (op, 1);
22951 }
22952 else if (offset < 0)
bfae80f2 22953 {
c19d1205
ZW
22954 offset = -offset;
22955 while (offset > 0x100)
bfae80f2 22956 {
c19d1205
ZW
22957 add_unwind_opcode (0x7f, 1);
22958 offset -= 0x100;
bfae80f2 22959 }
c19d1205
ZW
22960 op = ((offset - 4) >> 2) | 0x40;
22961 add_unwind_opcode (op, 1);
bfae80f2 22962 }
bfae80f2
RE
22963}
22964
c19d1205 22965/* Finish the list of unwind opcodes for this function. */
0198d5e6 22966
c19d1205
ZW
22967static void
22968finish_unwind_opcodes (void)
bfae80f2 22969{
c19d1205 22970 valueT op;
bfae80f2 22971
c19d1205 22972 if (unwind.fp_used)
bfae80f2 22973 {
708587a4 22974 /* Adjust sp as necessary. */
c19d1205
ZW
22975 unwind.pending_offset += unwind.fp_offset - unwind.frame_size;
22976 flush_pending_unwind ();
bfae80f2 22977
c19d1205
ZW
22978 /* After restoring sp from the frame pointer. */
22979 op = 0x90 | unwind.fp_reg;
22980 add_unwind_opcode (op, 1);
22981 }
22982 else
22983 flush_pending_unwind ();
bfae80f2
RE
22984}
22985
bfae80f2 22986
c19d1205
ZW
22987/* Start an exception table entry. If idx is nonzero this is an index table
22988 entry. */
bfae80f2
RE
22989
22990static void
c19d1205 22991start_unwind_section (const segT text_seg, int idx)
bfae80f2 22992{
c19d1205
ZW
22993 const char * text_name;
22994 const char * prefix;
22995 const char * prefix_once;
22996 const char * group_name;
c19d1205 22997 char * sec_name;
c19d1205
ZW
22998 int type;
22999 int flags;
23000 int linkonce;
bfae80f2 23001
c19d1205 23002 if (idx)
bfae80f2 23003 {
c19d1205
ZW
23004 prefix = ELF_STRING_ARM_unwind;
23005 prefix_once = ELF_STRING_ARM_unwind_once;
23006 type = SHT_ARM_EXIDX;
bfae80f2 23007 }
c19d1205 23008 else
bfae80f2 23009 {
c19d1205
ZW
23010 prefix = ELF_STRING_ARM_unwind_info;
23011 prefix_once = ELF_STRING_ARM_unwind_info_once;
23012 type = SHT_PROGBITS;
bfae80f2
RE
23013 }
23014
c19d1205
ZW
23015 text_name = segment_name (text_seg);
23016 if (streq (text_name, ".text"))
23017 text_name = "";
23018
23019 if (strncmp (text_name, ".gnu.linkonce.t.",
23020 strlen (".gnu.linkonce.t.")) == 0)
bfae80f2 23021 {
c19d1205
ZW
23022 prefix = prefix_once;
23023 text_name += strlen (".gnu.linkonce.t.");
bfae80f2
RE
23024 }
23025
29a2809e 23026 sec_name = concat (prefix, text_name, (char *) NULL);
bfae80f2 23027
c19d1205
ZW
23028 flags = SHF_ALLOC;
23029 linkonce = 0;
23030 group_name = 0;
bfae80f2 23031
c19d1205
ZW
23032 /* Handle COMDAT group. */
23033 if (prefix != prefix_once && (text_seg->flags & SEC_LINK_ONCE) != 0)
bfae80f2 23034 {
c19d1205
ZW
23035 group_name = elf_group_name (text_seg);
23036 if (group_name == NULL)
23037 {
bd3ba5d1 23038 as_bad (_("Group section `%s' has no group signature"),
c19d1205
ZW
23039 segment_name (text_seg));
23040 ignore_rest_of_line ();
23041 return;
23042 }
23043 flags |= SHF_GROUP;
23044 linkonce = 1;
bfae80f2
RE
23045 }
23046
a91e1603
L
23047 obj_elf_change_section (sec_name, type, 0, flags, 0, group_name,
23048 linkonce, 0);
bfae80f2 23049
5f4273c7 23050 /* Set the section link for index tables. */
c19d1205
ZW
23051 if (idx)
23052 elf_linked_to_section (now_seg) = text_seg;
bfae80f2
RE
23053}
23054
bfae80f2 23055
c19d1205
ZW
23056/* Start an unwind table entry. HAVE_DATA is nonzero if we have additional
23057 personality routine data. Returns zero, or the index table value for
cad0da33 23058 an inline entry. */
c19d1205
ZW
23059
23060static valueT
23061create_unwind_entry (int have_data)
bfae80f2 23062{
c19d1205
ZW
23063 int size;
23064 addressT where;
23065 char *ptr;
23066 /* The current word of data. */
23067 valueT data;
23068 /* The number of bytes left in this word. */
23069 int n;
bfae80f2 23070
c19d1205 23071 finish_unwind_opcodes ();
bfae80f2 23072
c19d1205
ZW
23073 /* Remember the current text section. */
23074 unwind.saved_seg = now_seg;
23075 unwind.saved_subseg = now_subseg;
bfae80f2 23076
c19d1205 23077 start_unwind_section (now_seg, 0);
bfae80f2 23078
c19d1205 23079 if (unwind.personality_routine == NULL)
bfae80f2 23080 {
c19d1205
ZW
23081 if (unwind.personality_index == -2)
23082 {
23083 if (have_data)
5f4273c7 23084 as_bad (_("handlerdata in cantunwind frame"));
c19d1205
ZW
23085 return 1; /* EXIDX_CANTUNWIND. */
23086 }
bfae80f2 23087
c19d1205
ZW
23088 /* Use a default personality routine if none is specified. */
23089 if (unwind.personality_index == -1)
23090 {
23091 if (unwind.opcode_count > 3)
23092 unwind.personality_index = 1;
23093 else
23094 unwind.personality_index = 0;
23095 }
bfae80f2 23096
c19d1205
ZW
23097 /* Space for the personality routine entry. */
23098 if (unwind.personality_index == 0)
23099 {
23100 if (unwind.opcode_count > 3)
23101 as_bad (_("too many unwind opcodes for personality routine 0"));
bfae80f2 23102
c19d1205
ZW
23103 if (!have_data)
23104 {
23105 /* All the data is inline in the index table. */
23106 data = 0x80;
23107 n = 3;
23108 while (unwind.opcode_count > 0)
23109 {
23110 unwind.opcode_count--;
23111 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
23112 n--;
23113 }
bfae80f2 23114
c19d1205
ZW
23115 /* Pad with "finish" opcodes. */
23116 while (n--)
23117 data = (data << 8) | 0xb0;
bfae80f2 23118
c19d1205
ZW
23119 return data;
23120 }
23121 size = 0;
23122 }
23123 else
23124 /* We get two opcodes "free" in the first word. */
23125 size = unwind.opcode_count - 2;
23126 }
23127 else
5011093d 23128 {
cad0da33
NC
23129 /* PR 16765: Missing or misplaced unwind directives can trigger this. */
23130 if (unwind.personality_index != -1)
23131 {
23132 as_bad (_("attempt to recreate an unwind entry"));
23133 return 1;
23134 }
5011093d
NC
23135
23136 /* An extra byte is required for the opcode count. */
23137 size = unwind.opcode_count + 1;
23138 }
bfae80f2 23139
c19d1205
ZW
23140 size = (size + 3) >> 2;
23141 if (size > 0xff)
23142 as_bad (_("too many unwind opcodes"));
bfae80f2 23143
c19d1205
ZW
23144 frag_align (2, 0, 0);
23145 record_alignment (now_seg, 2);
23146 unwind.table_entry = expr_build_dot ();
23147
23148 /* Allocate the table entry. */
23149 ptr = frag_more ((size << 2) + 4);
74929e7b
NC
23150 /* PR 13449: Zero the table entries in case some of them are not used. */
23151 memset (ptr, 0, (size << 2) + 4);
c19d1205 23152 where = frag_now_fix () - ((size << 2) + 4);
bfae80f2 23153
c19d1205 23154 switch (unwind.personality_index)
bfae80f2 23155 {
c19d1205
ZW
23156 case -1:
23157 /* ??? Should this be a PLT generating relocation? */
23158 /* Custom personality routine. */
23159 fix_new (frag_now, where, 4, unwind.personality_routine, 0, 1,
23160 BFD_RELOC_ARM_PREL31);
bfae80f2 23161
c19d1205
ZW
23162 where += 4;
23163 ptr += 4;
bfae80f2 23164
c19d1205 23165 /* Set the first byte to the number of additional words. */
5011093d 23166 data = size > 0 ? size - 1 : 0;
c19d1205
ZW
23167 n = 3;
23168 break;
bfae80f2 23169
c19d1205
ZW
23170 /* ABI defined personality routines. */
23171 case 0:
23172 /* Three opcodes bytes are packed into the first word. */
23173 data = 0x80;
23174 n = 3;
23175 break;
bfae80f2 23176
c19d1205
ZW
23177 case 1:
23178 case 2:
23179 /* The size and first two opcode bytes go in the first word. */
23180 data = ((0x80 + unwind.personality_index) << 8) | size;
23181 n = 2;
23182 break;
bfae80f2 23183
c19d1205
ZW
23184 default:
23185 /* Should never happen. */
23186 abort ();
23187 }
bfae80f2 23188
c19d1205
ZW
23189 /* Pack the opcodes into words (MSB first), reversing the list at the same
23190 time. */
23191 while (unwind.opcode_count > 0)
23192 {
23193 if (n == 0)
23194 {
23195 md_number_to_chars (ptr, data, 4);
23196 ptr += 4;
23197 n = 4;
23198 data = 0;
23199 }
23200 unwind.opcode_count--;
23201 n--;
23202 data = (data << 8) | unwind.opcodes[unwind.opcode_count];
23203 }
23204
23205 /* Finish off the last word. */
23206 if (n < 4)
23207 {
23208 /* Pad with "finish" opcodes. */
23209 while (n--)
23210 data = (data << 8) | 0xb0;
23211
23212 md_number_to_chars (ptr, data, 4);
23213 }
23214
23215 if (!have_data)
23216 {
23217 /* Add an empty descriptor if there is no user-specified data. */
23218 ptr = frag_more (4);
23219 md_number_to_chars (ptr, 0, 4);
23220 }
23221
23222 return 0;
bfae80f2
RE
23223}
23224
f0927246
NC
23225
23226/* Initialize the DWARF-2 unwind information for this procedure. */
23227
23228void
23229tc_arm_frame_initial_instructions (void)
23230{
23231 cfi_add_CFA_def_cfa (REG_SP, 0);
23232}
23233#endif /* OBJ_ELF */
23234
c19d1205
ZW
23235/* Convert REGNAME to a DWARF-2 register number. */
23236
23237int
1df69f4f 23238tc_arm_regname_to_dw2regnum (char *regname)
bfae80f2 23239{
1df69f4f 23240 int reg = arm_reg_parse (&regname, REG_TYPE_RN);
1f5afe1c
NC
23241 if (reg != FAIL)
23242 return reg;
c19d1205 23243
1f5afe1c
NC
23244 /* PR 16694: Allow VFP registers as well. */
23245 reg = arm_reg_parse (&regname, REG_TYPE_VFS);
23246 if (reg != FAIL)
23247 return 64 + reg;
c19d1205 23248
1f5afe1c
NC
23249 reg = arm_reg_parse (&regname, REG_TYPE_VFD);
23250 if (reg != FAIL)
23251 return reg + 256;
23252
0198d5e6 23253 return FAIL;
bfae80f2
RE
23254}
23255
f0927246 23256#ifdef TE_PE
c19d1205 23257void
f0927246 23258tc_pe_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
bfae80f2 23259{
91d6fa6a 23260 expressionS exp;
bfae80f2 23261
91d6fa6a
NC
23262 exp.X_op = O_secrel;
23263 exp.X_add_symbol = symbol;
23264 exp.X_add_number = 0;
23265 emit_expr (&exp, size);
f0927246
NC
23266}
23267#endif
bfae80f2 23268
c19d1205 23269/* MD interface: Symbol and relocation handling. */
bfae80f2 23270
2fc8bdac
ZW
23271/* Return the address within the segment that a PC-relative fixup is
23272 relative to. For ARM, PC-relative fixups applied to instructions
23273 are generally relative to the location of the fixup plus 8 bytes.
23274 Thumb branches are offset by 4, and Thumb loads relative to PC
23275 require special handling. */
bfae80f2 23276
c19d1205 23277long
2fc8bdac 23278md_pcrel_from_section (fixS * fixP, segT seg)
bfae80f2 23279{
2fc8bdac
ZW
23280 offsetT base = fixP->fx_where + fixP->fx_frag->fr_address;
23281
23282 /* If this is pc-relative and we are going to emit a relocation
23283 then we just want to put out any pipeline compensation that the linker
53baae48
NC
23284 will need. Otherwise we want to use the calculated base.
23285 For WinCE we skip the bias for externals as well, since this
23286 is how the MS ARM-CE assembler behaves and we want to be compatible. */
5f4273c7 23287 if (fixP->fx_pcrel
2fc8bdac 23288 && ((fixP->fx_addsy && S_GET_SEGMENT (fixP->fx_addsy) != seg)
53baae48
NC
23289 || (arm_force_relocation (fixP)
23290#ifdef TE_WINCE
23291 && !S_IS_EXTERNAL (fixP->fx_addsy)
23292#endif
23293 )))
2fc8bdac 23294 base = 0;
bfae80f2 23295
267bf995 23296
c19d1205 23297 switch (fixP->fx_r_type)
bfae80f2 23298 {
2fc8bdac
ZW
23299 /* PC relative addressing on the Thumb is slightly odd as the
23300 bottom two bits of the PC are forced to zero for the
23301 calculation. This happens *after* application of the
23302 pipeline offset. However, Thumb adrl already adjusts for
23303 this, so we need not do it again. */
c19d1205 23304 case BFD_RELOC_ARM_THUMB_ADD:
2fc8bdac 23305 return base & ~3;
c19d1205
ZW
23306
23307 case BFD_RELOC_ARM_THUMB_OFFSET:
23308 case BFD_RELOC_ARM_T32_OFFSET_IMM:
e9f89963 23309 case BFD_RELOC_ARM_T32_ADD_PC12:
8f06b2d8 23310 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
2fc8bdac 23311 return (base + 4) & ~3;
c19d1205 23312
2fc8bdac 23313 /* Thumb branches are simply offset by +4. */
e12437dc 23314 case BFD_RELOC_THUMB_PCREL_BRANCH5:
2fc8bdac
ZW
23315 case BFD_RELOC_THUMB_PCREL_BRANCH7:
23316 case BFD_RELOC_THUMB_PCREL_BRANCH9:
23317 case BFD_RELOC_THUMB_PCREL_BRANCH12:
23318 case BFD_RELOC_THUMB_PCREL_BRANCH20:
2fc8bdac 23319 case BFD_RELOC_THUMB_PCREL_BRANCH25:
f6b2b12d 23320 case BFD_RELOC_THUMB_PCREL_BFCSEL:
e5d6e09e 23321 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 23322 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 23323 case BFD_RELOC_ARM_THUMB_BF13:
60f993ce 23324 case BFD_RELOC_ARM_THUMB_LOOP12:
2fc8bdac 23325 return base + 4;
bfae80f2 23326
267bf995 23327 case BFD_RELOC_THUMB_PCREL_BRANCH23:
486499d0
CL
23328 if (fixP->fx_addsy
23329 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23330 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995 23331 && ARM_IS_FUNC (fixP->fx_addsy)
477330fc
RM
23332 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23333 base = fixP->fx_where + fixP->fx_frag->fr_address;
267bf995
RR
23334 return base + 4;
23335
00adf2d4
JB
23336 /* BLX is like branches above, but forces the low two bits of PC to
23337 zero. */
486499d0
CL
23338 case BFD_RELOC_THUMB_PCREL_BLX:
23339 if (fixP->fx_addsy
23340 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23341 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
23342 && THUMB_IS_FUNC (fixP->fx_addsy)
23343 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23344 base = fixP->fx_where + fixP->fx_frag->fr_address;
00adf2d4
JB
23345 return (base + 4) & ~3;
23346
2fc8bdac
ZW
23347 /* ARM mode branches are offset by +8. However, the Windows CE
23348 loader expects the relocation not to take this into account. */
267bf995 23349 case BFD_RELOC_ARM_PCREL_BLX:
486499d0
CL
23350 if (fixP->fx_addsy
23351 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23352 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
23353 && ARM_IS_FUNC (fixP->fx_addsy)
23354 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23355 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 23356 return base + 8;
267bf995 23357
486499d0
CL
23358 case BFD_RELOC_ARM_PCREL_CALL:
23359 if (fixP->fx_addsy
23360 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 23361 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
477330fc
RM
23362 && THUMB_IS_FUNC (fixP->fx_addsy)
23363 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
23364 base = fixP->fx_where + fixP->fx_frag->fr_address;
486499d0 23365 return base + 8;
267bf995 23366
2fc8bdac 23367 case BFD_RELOC_ARM_PCREL_BRANCH:
39b41c9c 23368 case BFD_RELOC_ARM_PCREL_JUMP:
2fc8bdac 23369 case BFD_RELOC_ARM_PLT32:
c19d1205 23370#ifdef TE_WINCE
5f4273c7 23371 /* When handling fixups immediately, because we have already
477330fc 23372 discovered the value of a symbol, or the address of the frag involved
53baae48 23373 we must account for the offset by +8, as the OS loader will never see the reloc.
477330fc
RM
23374 see fixup_segment() in write.c
23375 The S_IS_EXTERNAL test handles the case of global symbols.
23376 Those need the calculated base, not just the pipe compensation the linker will need. */
53baae48
NC
23377 if (fixP->fx_pcrel
23378 && fixP->fx_addsy != NULL
23379 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
23380 && (S_IS_EXTERNAL (fixP->fx_addsy) || !arm_force_relocation (fixP)))
23381 return base + 8;
2fc8bdac 23382 return base;
c19d1205 23383#else
2fc8bdac 23384 return base + 8;
c19d1205 23385#endif
2fc8bdac 23386
267bf995 23387
2fc8bdac
ZW
23388 /* ARM mode loads relative to PC are also offset by +8. Unlike
23389 branches, the Windows CE loader *does* expect the relocation
23390 to take this into account. */
23391 case BFD_RELOC_ARM_OFFSET_IMM:
23392 case BFD_RELOC_ARM_OFFSET_IMM8:
23393 case BFD_RELOC_ARM_HWLITERAL:
23394 case BFD_RELOC_ARM_LITERAL:
23395 case BFD_RELOC_ARM_CP_OFF_IMM:
23396 return base + 8;
23397
23398
23399 /* Other PC-relative relocations are un-offset. */
23400 default:
23401 return base;
23402 }
bfae80f2
RE
23403}
23404
8b2d793c
NC
23405static bfd_boolean flag_warn_syms = TRUE;
23406
ae8714c2
NC
23407bfd_boolean
23408arm_tc_equal_in_insn (int c ATTRIBUTE_UNUSED, char * name)
bfae80f2 23409{
8b2d793c
NC
23410 /* PR 18347 - Warn if the user attempts to create a symbol with the same
23411 name as an ARM instruction. Whilst strictly speaking it is allowed, it
23412 does mean that the resulting code might be very confusing to the reader.
23413 Also this warning can be triggered if the user omits an operand before
23414 an immediate address, eg:
23415
23416 LDR =foo
23417
23418 GAS treats this as an assignment of the value of the symbol foo to a
23419 symbol LDR, and so (without this code) it will not issue any kind of
23420 warning or error message.
23421
23422 Note - ARM instructions are case-insensitive but the strings in the hash
23423 table are all stored in lower case, so we must first ensure that name is
ae8714c2
NC
23424 lower case too. */
23425 if (flag_warn_syms && arm_ops_hsh)
8b2d793c
NC
23426 {
23427 char * nbuf = strdup (name);
23428 char * p;
23429
23430 for (p = nbuf; *p; p++)
23431 *p = TOLOWER (*p);
23432 if (hash_find (arm_ops_hsh, nbuf) != NULL)
23433 {
23434 static struct hash_control * already_warned = NULL;
23435
23436 if (already_warned == NULL)
23437 already_warned = hash_new ();
23438 /* Only warn about the symbol once. To keep the code
23439 simple we let hash_insert do the lookup for us. */
3076e594 23440 if (hash_insert (already_warned, nbuf, NULL) == NULL)
ae8714c2 23441 as_warn (_("[-mwarn-syms]: Assignment makes a symbol match an ARM instruction: %s"), name);
8b2d793c
NC
23442 }
23443 else
23444 free (nbuf);
23445 }
3739860c 23446
ae8714c2
NC
23447 return FALSE;
23448}
23449
23450/* Under ELF we need to default _GLOBAL_OFFSET_TABLE.
23451 Otherwise we have no need to default values of symbols. */
23452
23453symbolS *
23454md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
23455{
23456#ifdef OBJ_ELF
23457 if (name[0] == '_' && name[1] == 'G'
23458 && streq (name, GLOBAL_OFFSET_TABLE_NAME))
23459 {
23460 if (!GOT_symbol)
23461 {
23462 if (symbol_find (name))
23463 as_bad (_("GOT already in the symbol table"));
23464
23465 GOT_symbol = symbol_new (name, undefined_section,
23466 (valueT) 0, & zero_address_frag);
23467 }
23468
23469 return GOT_symbol;
23470 }
23471#endif
23472
c921be7d 23473 return NULL;
bfae80f2
RE
23474}
23475
55cf6793 23476/* Subroutine of md_apply_fix. Check to see if an immediate can be
c19d1205
ZW
23477 computed as two separate immediate values, added together. We
23478 already know that this value cannot be computed by just one ARM
23479 instruction. */
23480
23481static unsigned int
23482validate_immediate_twopart (unsigned int val,
23483 unsigned int * highpart)
bfae80f2 23484{
c19d1205
ZW
23485 unsigned int a;
23486 unsigned int i;
bfae80f2 23487
c19d1205
ZW
23488 for (i = 0; i < 32; i += 2)
23489 if (((a = rotate_left (val, i)) & 0xff) != 0)
23490 {
23491 if (a & 0xff00)
23492 {
23493 if (a & ~ 0xffff)
23494 continue;
23495 * highpart = (a >> 8) | ((i + 24) << 7);
23496 }
23497 else if (a & 0xff0000)
23498 {
23499 if (a & 0xff000000)
23500 continue;
23501 * highpart = (a >> 16) | ((i + 16) << 7);
23502 }
23503 else
23504 {
9c2799c2 23505 gas_assert (a & 0xff000000);
c19d1205
ZW
23506 * highpart = (a >> 24) | ((i + 8) << 7);
23507 }
bfae80f2 23508
c19d1205
ZW
23509 return (a & 0xff) | (i << 7);
23510 }
bfae80f2 23511
c19d1205 23512 return FAIL;
bfae80f2
RE
23513}
23514
c19d1205
ZW
23515static int
23516validate_offset_imm (unsigned int val, int hwse)
23517{
23518 if ((hwse && val > 255) || val > 4095)
23519 return FAIL;
23520 return val;
23521}
bfae80f2 23522
55cf6793 23523/* Subroutine of md_apply_fix. Do those data_ops which can take a
c19d1205
ZW
23524 negative immediate constant by altering the instruction. A bit of
23525 a hack really.
23526 MOV <-> MVN
23527 AND <-> BIC
23528 ADC <-> SBC
23529 by inverting the second operand, and
23530 ADD <-> SUB
23531 CMP <-> CMN
23532 by negating the second operand. */
bfae80f2 23533
c19d1205
ZW
23534static int
23535negate_data_op (unsigned long * instruction,
23536 unsigned long value)
bfae80f2 23537{
c19d1205
ZW
23538 int op, new_inst;
23539 unsigned long negated, inverted;
bfae80f2 23540
c19d1205
ZW
23541 negated = encode_arm_immediate (-value);
23542 inverted = encode_arm_immediate (~value);
bfae80f2 23543
c19d1205
ZW
23544 op = (*instruction >> DATA_OP_SHIFT) & 0xf;
23545 switch (op)
bfae80f2 23546 {
c19d1205
ZW
23547 /* First negates. */
23548 case OPCODE_SUB: /* ADD <-> SUB */
23549 new_inst = OPCODE_ADD;
23550 value = negated;
23551 break;
bfae80f2 23552
c19d1205
ZW
23553 case OPCODE_ADD:
23554 new_inst = OPCODE_SUB;
23555 value = negated;
23556 break;
bfae80f2 23557
c19d1205
ZW
23558 case OPCODE_CMP: /* CMP <-> CMN */
23559 new_inst = OPCODE_CMN;
23560 value = negated;
23561 break;
bfae80f2 23562
c19d1205
ZW
23563 case OPCODE_CMN:
23564 new_inst = OPCODE_CMP;
23565 value = negated;
23566 break;
bfae80f2 23567
c19d1205
ZW
23568 /* Now Inverted ops. */
23569 case OPCODE_MOV: /* MOV <-> MVN */
23570 new_inst = OPCODE_MVN;
23571 value = inverted;
23572 break;
bfae80f2 23573
c19d1205
ZW
23574 case OPCODE_MVN:
23575 new_inst = OPCODE_MOV;
23576 value = inverted;
23577 break;
bfae80f2 23578
c19d1205
ZW
23579 case OPCODE_AND: /* AND <-> BIC */
23580 new_inst = OPCODE_BIC;
23581 value = inverted;
23582 break;
bfae80f2 23583
c19d1205
ZW
23584 case OPCODE_BIC:
23585 new_inst = OPCODE_AND;
23586 value = inverted;
23587 break;
bfae80f2 23588
c19d1205
ZW
23589 case OPCODE_ADC: /* ADC <-> SBC */
23590 new_inst = OPCODE_SBC;
23591 value = inverted;
23592 break;
bfae80f2 23593
c19d1205
ZW
23594 case OPCODE_SBC:
23595 new_inst = OPCODE_ADC;
23596 value = inverted;
23597 break;
bfae80f2 23598
c19d1205
ZW
23599 /* We cannot do anything. */
23600 default:
23601 return FAIL;
b99bd4ef
NC
23602 }
23603
c19d1205
ZW
23604 if (value == (unsigned) FAIL)
23605 return FAIL;
23606
23607 *instruction &= OPCODE_MASK;
23608 *instruction |= new_inst << DATA_OP_SHIFT;
23609 return value;
b99bd4ef
NC
23610}
23611
ef8d22e6
PB
23612/* Like negate_data_op, but for Thumb-2. */
23613
23614static unsigned int
16dd5e42 23615thumb32_negate_data_op (offsetT *instruction, unsigned int value)
ef8d22e6
PB
23616{
23617 int op, new_inst;
23618 int rd;
16dd5e42 23619 unsigned int negated, inverted;
ef8d22e6
PB
23620
23621 negated = encode_thumb32_immediate (-value);
23622 inverted = encode_thumb32_immediate (~value);
23623
23624 rd = (*instruction >> 8) & 0xf;
23625 op = (*instruction >> T2_DATA_OP_SHIFT) & 0xf;
23626 switch (op)
23627 {
23628 /* ADD <-> SUB. Includes CMP <-> CMN. */
23629 case T2_OPCODE_SUB:
23630 new_inst = T2_OPCODE_ADD;
23631 value = negated;
23632 break;
23633
23634 case T2_OPCODE_ADD:
23635 new_inst = T2_OPCODE_SUB;
23636 value = negated;
23637 break;
23638
23639 /* ORR <-> ORN. Includes MOV <-> MVN. */
23640 case T2_OPCODE_ORR:
23641 new_inst = T2_OPCODE_ORN;
23642 value = inverted;
23643 break;
23644
23645 case T2_OPCODE_ORN:
23646 new_inst = T2_OPCODE_ORR;
23647 value = inverted;
23648 break;
23649
23650 /* AND <-> BIC. TST has no inverted equivalent. */
23651 case T2_OPCODE_AND:
23652 new_inst = T2_OPCODE_BIC;
23653 if (rd == 15)
23654 value = FAIL;
23655 else
23656 value = inverted;
23657 break;
23658
23659 case T2_OPCODE_BIC:
23660 new_inst = T2_OPCODE_AND;
23661 value = inverted;
23662 break;
23663
23664 /* ADC <-> SBC */
23665 case T2_OPCODE_ADC:
23666 new_inst = T2_OPCODE_SBC;
23667 value = inverted;
23668 break;
23669
23670 case T2_OPCODE_SBC:
23671 new_inst = T2_OPCODE_ADC;
23672 value = inverted;
23673 break;
23674
23675 /* We cannot do anything. */
23676 default:
23677 return FAIL;
23678 }
23679
16dd5e42 23680 if (value == (unsigned int)FAIL)
ef8d22e6
PB
23681 return FAIL;
23682
23683 *instruction &= T2_OPCODE_MASK;
23684 *instruction |= new_inst << T2_DATA_OP_SHIFT;
23685 return value;
23686}
23687
8f06b2d8 23688/* Read a 32-bit thumb instruction from buf. */
0198d5e6 23689
8f06b2d8
PB
23690static unsigned long
23691get_thumb32_insn (char * buf)
23692{
23693 unsigned long insn;
23694 insn = md_chars_to_number (buf, THUMB_SIZE) << 16;
23695 insn |= md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
23696
23697 return insn;
23698}
23699
a8bc6c78
PB
23700/* We usually want to set the low bit on the address of thumb function
23701 symbols. In particular .word foo - . should have the low bit set.
23702 Generic code tries to fold the difference of two symbols to
23703 a constant. Prevent this and force a relocation when the first symbols
23704 is a thumb function. */
c921be7d
NC
23705
23706bfd_boolean
a8bc6c78
PB
23707arm_optimize_expr (expressionS *l, operatorT op, expressionS *r)
23708{
23709 if (op == O_subtract
23710 && l->X_op == O_symbol
23711 && r->X_op == O_symbol
23712 && THUMB_IS_FUNC (l->X_add_symbol))
23713 {
23714 l->X_op = O_subtract;
23715 l->X_op_symbol = r->X_add_symbol;
23716 l->X_add_number -= r->X_add_number;
c921be7d 23717 return TRUE;
a8bc6c78 23718 }
c921be7d 23719
a8bc6c78 23720 /* Process as normal. */
c921be7d 23721 return FALSE;
a8bc6c78
PB
23722}
23723
4a42ebbc
RR
23724/* Encode Thumb2 unconditional branches and calls. The encoding
23725 for the 2 are identical for the immediate values. */
23726
23727static void
23728encode_thumb2_b_bl_offset (char * buf, offsetT value)
23729{
23730#define T2I1I2MASK ((1 << 13) | (1 << 11))
23731 offsetT newval;
23732 offsetT newval2;
23733 addressT S, I1, I2, lo, hi;
23734
23735 S = (value >> 24) & 0x01;
23736 I1 = (value >> 23) & 0x01;
23737 I2 = (value >> 22) & 0x01;
23738 hi = (value >> 12) & 0x3ff;
fa94de6b 23739 lo = (value >> 1) & 0x7ff;
4a42ebbc
RR
23740 newval = md_chars_to_number (buf, THUMB_SIZE);
23741 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
23742 newval |= (S << 10) | hi;
23743 newval2 &= ~T2I1I2MASK;
23744 newval2 |= (((I1 ^ S) << 13) | ((I2 ^ S) << 11) | lo) ^ T2I1I2MASK;
23745 md_number_to_chars (buf, newval, THUMB_SIZE);
23746 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
23747}
23748
c19d1205 23749void
55cf6793 23750md_apply_fix (fixS * fixP,
c19d1205
ZW
23751 valueT * valP,
23752 segT seg)
23753{
23754 offsetT value = * valP;
23755 offsetT newval;
23756 unsigned int newimm;
23757 unsigned long temp;
23758 int sign;
23759 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
b99bd4ef 23760
9c2799c2 23761 gas_assert (fixP->fx_r_type <= BFD_RELOC_UNUSED);
b99bd4ef 23762
c19d1205 23763 /* Note whether this will delete the relocation. */
4962c51a 23764
c19d1205
ZW
23765 if (fixP->fx_addsy == 0 && !fixP->fx_pcrel)
23766 fixP->fx_done = 1;
b99bd4ef 23767
adbaf948 23768 /* On a 64-bit host, silently truncate 'value' to 32 bits for
5f4273c7 23769 consistency with the behaviour on 32-bit hosts. Remember value
adbaf948
ZW
23770 for emit_reloc. */
23771 value &= 0xffffffff;
23772 value ^= 0x80000000;
5f4273c7 23773 value -= 0x80000000;
adbaf948
ZW
23774
23775 *valP = value;
c19d1205 23776 fixP->fx_addnumber = value;
b99bd4ef 23777
adbaf948
ZW
23778 /* Same treatment for fixP->fx_offset. */
23779 fixP->fx_offset &= 0xffffffff;
23780 fixP->fx_offset ^= 0x80000000;
23781 fixP->fx_offset -= 0x80000000;
23782
c19d1205 23783 switch (fixP->fx_r_type)
b99bd4ef 23784 {
c19d1205
ZW
23785 case BFD_RELOC_NONE:
23786 /* This will need to go in the object file. */
23787 fixP->fx_done = 0;
23788 break;
b99bd4ef 23789
c19d1205
ZW
23790 case BFD_RELOC_ARM_IMMEDIATE:
23791 /* We claim that this fixup has been processed here,
23792 even if in fact we generate an error because we do
23793 not have a reloc for it, so tc_gen_reloc will reject it. */
23794 fixP->fx_done = 1;
b99bd4ef 23795
77db8e2e 23796 if (fixP->fx_addsy)
b99bd4ef 23797 {
77db8e2e 23798 const char *msg = 0;
b99bd4ef 23799
77db8e2e
NC
23800 if (! S_IS_DEFINED (fixP->fx_addsy))
23801 msg = _("undefined symbol %s used as an immediate value");
23802 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
23803 msg = _("symbol %s is in a different section");
23804 else if (S_IS_WEAK (fixP->fx_addsy))
23805 msg = _("symbol %s is weak and may be overridden later");
23806
23807 if (msg)
23808 {
23809 as_bad_where (fixP->fx_file, fixP->fx_line,
23810 msg, S_GET_NAME (fixP->fx_addsy));
23811 break;
23812 }
42e5fcbf
AS
23813 }
23814
c19d1205
ZW
23815 temp = md_chars_to_number (buf, INSN_SIZE);
23816
5e73442d
SL
23817 /* If the offset is negative, we should use encoding A2 for ADR. */
23818 if ((temp & 0xfff0000) == 0x28f0000 && value < 0)
23819 newimm = negate_data_op (&temp, value);
23820 else
23821 {
23822 newimm = encode_arm_immediate (value);
23823
23824 /* If the instruction will fail, see if we can fix things up by
23825 changing the opcode. */
23826 if (newimm == (unsigned int) FAIL)
23827 newimm = negate_data_op (&temp, value);
bada4342
JW
23828 /* MOV accepts both ARM modified immediate (A1 encoding) and
23829 UINT16 (A2 encoding) when possible, MOVW only accepts UINT16.
23830 When disassembling, MOV is preferred when there is no encoding
23831 overlap. */
23832 if (newimm == (unsigned int) FAIL
23833 && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV
23834 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)
23835 && !((temp >> SBIT_SHIFT) & 0x1)
23836 && value >= 0 && value <= 0xffff)
23837 {
23838 /* Clear bits[23:20] to change encoding from A1 to A2. */
23839 temp &= 0xff0fffff;
23840 /* Encoding high 4bits imm. Code below will encode the remaining
23841 low 12bits. */
23842 temp |= (value & 0x0000f000) << 4;
23843 newimm = value & 0x00000fff;
23844 }
5e73442d
SL
23845 }
23846
23847 if (newimm == (unsigned int) FAIL)
b99bd4ef 23848 {
c19d1205
ZW
23849 as_bad_where (fixP->fx_file, fixP->fx_line,
23850 _("invalid constant (%lx) after fixup"),
23851 (unsigned long) value);
23852 break;
b99bd4ef 23853 }
b99bd4ef 23854
c19d1205
ZW
23855 newimm |= (temp & 0xfffff000);
23856 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
23857 break;
b99bd4ef 23858
c19d1205
ZW
23859 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
23860 {
23861 unsigned int highpart = 0;
23862 unsigned int newinsn = 0xe1a00000; /* nop. */
b99bd4ef 23863
77db8e2e 23864 if (fixP->fx_addsy)
42e5fcbf 23865 {
77db8e2e 23866 const char *msg = 0;
42e5fcbf 23867
77db8e2e
NC
23868 if (! S_IS_DEFINED (fixP->fx_addsy))
23869 msg = _("undefined symbol %s used as an immediate value");
23870 else if (S_GET_SEGMENT (fixP->fx_addsy) != seg)
23871 msg = _("symbol %s is in a different section");
23872 else if (S_IS_WEAK (fixP->fx_addsy))
23873 msg = _("symbol %s is weak and may be overridden later");
42e5fcbf 23874
77db8e2e
NC
23875 if (msg)
23876 {
23877 as_bad_where (fixP->fx_file, fixP->fx_line,
23878 msg, S_GET_NAME (fixP->fx_addsy));
23879 break;
23880 }
23881 }
fa94de6b 23882
c19d1205
ZW
23883 newimm = encode_arm_immediate (value);
23884 temp = md_chars_to_number (buf, INSN_SIZE);
b99bd4ef 23885
c19d1205
ZW
23886 /* If the instruction will fail, see if we can fix things up by
23887 changing the opcode. */
23888 if (newimm == (unsigned int) FAIL
23889 && (newimm = negate_data_op (& temp, value)) == (unsigned int) FAIL)
23890 {
23891 /* No ? OK - try using two ADD instructions to generate
23892 the value. */
23893 newimm = validate_immediate_twopart (value, & highpart);
b99bd4ef 23894
c19d1205
ZW
23895 /* Yes - then make sure that the second instruction is
23896 also an add. */
23897 if (newimm != (unsigned int) FAIL)
23898 newinsn = temp;
23899 /* Still No ? Try using a negated value. */
23900 else if ((newimm = validate_immediate_twopart (- value, & highpart)) != (unsigned int) FAIL)
23901 temp = newinsn = (temp & OPCODE_MASK) | OPCODE_SUB << DATA_OP_SHIFT;
23902 /* Otherwise - give up. */
23903 else
23904 {
23905 as_bad_where (fixP->fx_file, fixP->fx_line,
23906 _("unable to compute ADRL instructions for PC offset of 0x%lx"),
23907 (long) value);
23908 break;
23909 }
b99bd4ef 23910
c19d1205
ZW
23911 /* Replace the first operand in the 2nd instruction (which
23912 is the PC) with the destination register. We have
23913 already added in the PC in the first instruction and we
23914 do not want to do it again. */
23915 newinsn &= ~ 0xf0000;
23916 newinsn |= ((newinsn & 0x0f000) << 4);
23917 }
b99bd4ef 23918
c19d1205
ZW
23919 newimm |= (temp & 0xfffff000);
23920 md_number_to_chars (buf, (valueT) newimm, INSN_SIZE);
b99bd4ef 23921
c19d1205
ZW
23922 highpart |= (newinsn & 0xfffff000);
23923 md_number_to_chars (buf + INSN_SIZE, (valueT) highpart, INSN_SIZE);
23924 }
23925 break;
b99bd4ef 23926
c19d1205 23927 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
23928 if (!fixP->fx_done && seg->use_rela_p)
23929 value = 0;
1a0670f3 23930 /* Fall through. */
00a97672 23931
c19d1205 23932 case BFD_RELOC_ARM_LITERAL:
26d97720 23933 sign = value > 0;
b99bd4ef 23934
c19d1205
ZW
23935 if (value < 0)
23936 value = - value;
b99bd4ef 23937
c19d1205 23938 if (validate_offset_imm (value, 0) == FAIL)
f03698e6 23939 {
c19d1205
ZW
23940 if (fixP->fx_r_type == BFD_RELOC_ARM_LITERAL)
23941 as_bad_where (fixP->fx_file, fixP->fx_line,
23942 _("invalid literal constant: pool needs to be closer"));
23943 else
23944 as_bad_where (fixP->fx_file, fixP->fx_line,
23945 _("bad immediate value for offset (%ld)"),
23946 (long) value);
23947 break;
f03698e6
RE
23948 }
23949
c19d1205 23950 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
23951 if (value == 0)
23952 newval &= 0xfffff000;
23953 else
23954 {
23955 newval &= 0xff7ff000;
23956 newval |= value | (sign ? INDEX_UP : 0);
23957 }
c19d1205
ZW
23958 md_number_to_chars (buf, newval, INSN_SIZE);
23959 break;
b99bd4ef 23960
c19d1205
ZW
23961 case BFD_RELOC_ARM_OFFSET_IMM8:
23962 case BFD_RELOC_ARM_HWLITERAL:
26d97720 23963 sign = value > 0;
b99bd4ef 23964
c19d1205
ZW
23965 if (value < 0)
23966 value = - value;
b99bd4ef 23967
c19d1205 23968 if (validate_offset_imm (value, 1) == FAIL)
b99bd4ef 23969 {
c19d1205
ZW
23970 if (fixP->fx_r_type == BFD_RELOC_ARM_HWLITERAL)
23971 as_bad_where (fixP->fx_file, fixP->fx_line,
23972 _("invalid literal constant: pool needs to be closer"));
23973 else
427d0db6
RM
23974 as_bad_where (fixP->fx_file, fixP->fx_line,
23975 _("bad immediate value for 8-bit offset (%ld)"),
23976 (long) value);
c19d1205 23977 break;
b99bd4ef
NC
23978 }
23979
c19d1205 23980 newval = md_chars_to_number (buf, INSN_SIZE);
26d97720
NS
23981 if (value == 0)
23982 newval &= 0xfffff0f0;
23983 else
23984 {
23985 newval &= 0xff7ff0f0;
23986 newval |= ((value >> 4) << 8) | (value & 0xf) | (sign ? INDEX_UP : 0);
23987 }
c19d1205
ZW
23988 md_number_to_chars (buf, newval, INSN_SIZE);
23989 break;
b99bd4ef 23990
c19d1205
ZW
23991 case BFD_RELOC_ARM_T32_OFFSET_U8:
23992 if (value < 0 || value > 1020 || value % 4 != 0)
23993 as_bad_where (fixP->fx_file, fixP->fx_line,
23994 _("bad immediate value for offset (%ld)"), (long) value);
23995 value /= 4;
b99bd4ef 23996
c19d1205 23997 newval = md_chars_to_number (buf+2, THUMB_SIZE);
c19d1205
ZW
23998 newval |= value;
23999 md_number_to_chars (buf+2, newval, THUMB_SIZE);
24000 break;
b99bd4ef 24001
c19d1205
ZW
24002 case BFD_RELOC_ARM_T32_OFFSET_IMM:
24003 /* This is a complicated relocation used for all varieties of Thumb32
24004 load/store instruction with immediate offset:
24005
24006 1110 100P u1WL NNNN XXXX YYYY iiii iiii - +/-(U) pre/post(P) 8-bit,
477330fc 24007 *4, optional writeback(W)
c19d1205
ZW
24008 (doubleword load/store)
24009
24010 1111 100S uTTL 1111 XXXX iiii iiii iiii - +/-(U) 12-bit PC-rel
24011 1111 100S 0TTL NNNN XXXX 1Pu1 iiii iiii - +/-(U) pre/post(P) 8-bit
24012 1111 100S 0TTL NNNN XXXX 1110 iiii iiii - positive 8-bit (T instruction)
24013 1111 100S 1TTL NNNN XXXX iiii iiii iiii - positive 12-bit
24014 1111 100S 0TTL NNNN XXXX 1100 iiii iiii - negative 8-bit
24015
24016 Uppercase letters indicate bits that are already encoded at
24017 this point. Lowercase letters are our problem. For the
24018 second block of instructions, the secondary opcode nybble
24019 (bits 8..11) is present, and bit 23 is zero, even if this is
24020 a PC-relative operation. */
24021 newval = md_chars_to_number (buf, THUMB_SIZE);
24022 newval <<= 16;
24023 newval |= md_chars_to_number (buf+THUMB_SIZE, THUMB_SIZE);
b99bd4ef 24024
c19d1205 24025 if ((newval & 0xf0000000) == 0xe0000000)
b99bd4ef 24026 {
c19d1205
ZW
24027 /* Doubleword load/store: 8-bit offset, scaled by 4. */
24028 if (value >= 0)
24029 newval |= (1 << 23);
24030 else
24031 value = -value;
24032 if (value % 4 != 0)
24033 {
24034 as_bad_where (fixP->fx_file, fixP->fx_line,
24035 _("offset not a multiple of 4"));
24036 break;
24037 }
24038 value /= 4;
216d22bc 24039 if (value > 0xff)
c19d1205
ZW
24040 {
24041 as_bad_where (fixP->fx_file, fixP->fx_line,
24042 _("offset out of range"));
24043 break;
24044 }
24045 newval &= ~0xff;
b99bd4ef 24046 }
c19d1205 24047 else if ((newval & 0x000f0000) == 0x000f0000)
b99bd4ef 24048 {
c19d1205
ZW
24049 /* PC-relative, 12-bit offset. */
24050 if (value >= 0)
24051 newval |= (1 << 23);
24052 else
24053 value = -value;
216d22bc 24054 if (value > 0xfff)
c19d1205
ZW
24055 {
24056 as_bad_where (fixP->fx_file, fixP->fx_line,
24057 _("offset out of range"));
24058 break;
24059 }
24060 newval &= ~0xfff;
b99bd4ef 24061 }
c19d1205 24062 else if ((newval & 0x00000100) == 0x00000100)
b99bd4ef 24063 {
c19d1205
ZW
24064 /* Writeback: 8-bit, +/- offset. */
24065 if (value >= 0)
24066 newval |= (1 << 9);
24067 else
24068 value = -value;
216d22bc 24069 if (value > 0xff)
c19d1205
ZW
24070 {
24071 as_bad_where (fixP->fx_file, fixP->fx_line,
24072 _("offset out of range"));
24073 break;
24074 }
24075 newval &= ~0xff;
b99bd4ef 24076 }
c19d1205 24077 else if ((newval & 0x00000f00) == 0x00000e00)
b99bd4ef 24078 {
c19d1205 24079 /* T-instruction: positive 8-bit offset. */
216d22bc 24080 if (value < 0 || value > 0xff)
b99bd4ef 24081 {
c19d1205
ZW
24082 as_bad_where (fixP->fx_file, fixP->fx_line,
24083 _("offset out of range"));
24084 break;
b99bd4ef 24085 }
c19d1205
ZW
24086 newval &= ~0xff;
24087 newval |= value;
b99bd4ef
NC
24088 }
24089 else
b99bd4ef 24090 {
c19d1205
ZW
24091 /* Positive 12-bit or negative 8-bit offset. */
24092 int limit;
24093 if (value >= 0)
b99bd4ef 24094 {
c19d1205
ZW
24095 newval |= (1 << 23);
24096 limit = 0xfff;
24097 }
24098 else
24099 {
24100 value = -value;
24101 limit = 0xff;
24102 }
24103 if (value > limit)
24104 {
24105 as_bad_where (fixP->fx_file, fixP->fx_line,
24106 _("offset out of range"));
24107 break;
b99bd4ef 24108 }
c19d1205 24109 newval &= ~limit;
b99bd4ef 24110 }
b99bd4ef 24111
c19d1205
ZW
24112 newval |= value;
24113 md_number_to_chars (buf, (newval >> 16) & 0xffff, THUMB_SIZE);
24114 md_number_to_chars (buf + THUMB_SIZE, newval & 0xffff, THUMB_SIZE);
24115 break;
404ff6b5 24116
c19d1205
ZW
24117 case BFD_RELOC_ARM_SHIFT_IMM:
24118 newval = md_chars_to_number (buf, INSN_SIZE);
24119 if (((unsigned long) value) > 32
24120 || (value == 32
24121 && (((newval & 0x60) == 0) || (newval & 0x60) == 0x60)))
24122 {
24123 as_bad_where (fixP->fx_file, fixP->fx_line,
24124 _("shift expression is too large"));
24125 break;
24126 }
404ff6b5 24127
c19d1205
ZW
24128 if (value == 0)
24129 /* Shifts of zero must be done as lsl. */
24130 newval &= ~0x60;
24131 else if (value == 32)
24132 value = 0;
24133 newval &= 0xfffff07f;
24134 newval |= (value & 0x1f) << 7;
24135 md_number_to_chars (buf, newval, INSN_SIZE);
24136 break;
404ff6b5 24137
c19d1205 24138 case BFD_RELOC_ARM_T32_IMMEDIATE:
16805f35 24139 case BFD_RELOC_ARM_T32_ADD_IMM:
92e90b6e 24140 case BFD_RELOC_ARM_T32_IMM12:
e9f89963 24141 case BFD_RELOC_ARM_T32_ADD_PC12:
c19d1205
ZW
24142 /* We claim that this fixup has been processed here,
24143 even if in fact we generate an error because we do
24144 not have a reloc for it, so tc_gen_reloc will reject it. */
24145 fixP->fx_done = 1;
404ff6b5 24146
c19d1205
ZW
24147 if (fixP->fx_addsy
24148 && ! S_IS_DEFINED (fixP->fx_addsy))
24149 {
24150 as_bad_where (fixP->fx_file, fixP->fx_line,
24151 _("undefined symbol %s used as an immediate value"),
24152 S_GET_NAME (fixP->fx_addsy));
24153 break;
24154 }
404ff6b5 24155
c19d1205
ZW
24156 newval = md_chars_to_number (buf, THUMB_SIZE);
24157 newval <<= 16;
24158 newval |= md_chars_to_number (buf+2, THUMB_SIZE);
404ff6b5 24159
16805f35 24160 newimm = FAIL;
bada4342
JW
24161 if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
24162 /* ARMv8-M Baseline MOV will reach here, but it doesn't support
24163 Thumb2 modified immediate encoding (T2). */
24164 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2))
16805f35 24165 || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
ef8d22e6
PB
24166 {
24167 newimm = encode_thumb32_immediate (value);
24168 if (newimm == (unsigned int) FAIL)
24169 newimm = thumb32_negate_data_op (&newval, value);
24170 }
bada4342 24171 if (newimm == (unsigned int) FAIL)
92e90b6e 24172 {
bada4342 24173 if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE)
e9f89963 24174 {
bada4342
JW
24175 /* Turn add/sum into addw/subw. */
24176 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM)
24177 newval = (newval & 0xfeffffff) | 0x02000000;
24178 /* No flat 12-bit imm encoding for addsw/subsw. */
24179 if ((newval & 0x00100000) == 0)
40f246e3 24180 {
bada4342
JW
24181 /* 12 bit immediate for addw/subw. */
24182 if (value < 0)
24183 {
24184 value = -value;
24185 newval ^= 0x00a00000;
24186 }
24187 if (value > 0xfff)
24188 newimm = (unsigned int) FAIL;
24189 else
24190 newimm = value;
24191 }
24192 }
24193 else
24194 {
24195 /* MOV accepts both Thumb2 modified immediate (T2 encoding) and
24196 UINT16 (T3 encoding), MOVW only accepts UINT16. When
24197 disassembling, MOV is preferred when there is no encoding
db7bf105 24198 overlap. */
bada4342 24199 if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR
db7bf105
NC
24200 /* NOTE: MOV uses the ORR opcode in Thumb 2 mode
24201 but with the Rn field [19:16] set to 1111. */
24202 && (((newval >> 16) & 0xf) == 0xf)
bada4342
JW
24203 && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m)
24204 && !((newval >> T2_SBIT_SHIFT) & 0x1)
db7bf105 24205 && value >= 0 && value <= 0xffff)
bada4342
JW
24206 {
24207 /* Toggle bit[25] to change encoding from T2 to T3. */
24208 newval ^= 1 << 25;
24209 /* Clear bits[19:16]. */
24210 newval &= 0xfff0ffff;
24211 /* Encoding high 4bits imm. Code below will encode the
24212 remaining low 12bits. */
24213 newval |= (value & 0x0000f000) << 4;
24214 newimm = value & 0x00000fff;
40f246e3 24215 }
e9f89963 24216 }
92e90b6e 24217 }
cc8a6dd0 24218
c19d1205 24219 if (newimm == (unsigned int)FAIL)
3631a3c8 24220 {
c19d1205
ZW
24221 as_bad_where (fixP->fx_file, fixP->fx_line,
24222 _("invalid constant (%lx) after fixup"),
24223 (unsigned long) value);
24224 break;
3631a3c8
NC
24225 }
24226
c19d1205
ZW
24227 newval |= (newimm & 0x800) << 15;
24228 newval |= (newimm & 0x700) << 4;
24229 newval |= (newimm & 0x0ff);
cc8a6dd0 24230
c19d1205
ZW
24231 md_number_to_chars (buf, (valueT) ((newval >> 16) & 0xffff), THUMB_SIZE);
24232 md_number_to_chars (buf+2, (valueT) (newval & 0xffff), THUMB_SIZE);
24233 break;
a737bd4d 24234
3eb17e6b 24235 case BFD_RELOC_ARM_SMC:
c19d1205
ZW
24236 if (((unsigned long) value) > 0xffff)
24237 as_bad_where (fixP->fx_file, fixP->fx_line,
3eb17e6b 24238 _("invalid smc expression"));
2fc8bdac 24239 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
24240 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
24241 md_number_to_chars (buf, newval, INSN_SIZE);
24242 break;
a737bd4d 24243
90ec0d68
MGD
24244 case BFD_RELOC_ARM_HVC:
24245 if (((unsigned long) value) > 0xffff)
24246 as_bad_where (fixP->fx_file, fixP->fx_line,
24247 _("invalid hvc expression"));
24248 newval = md_chars_to_number (buf, INSN_SIZE);
24249 newval |= (value & 0xf) | ((value & 0xfff0) << 4);
24250 md_number_to_chars (buf, newval, INSN_SIZE);
24251 break;
24252
c19d1205 24253 case BFD_RELOC_ARM_SWI:
adbaf948 24254 if (fixP->tc_fix_data != 0)
c19d1205
ZW
24255 {
24256 if (((unsigned long) value) > 0xff)
24257 as_bad_where (fixP->fx_file, fixP->fx_line,
24258 _("invalid swi expression"));
2fc8bdac 24259 newval = md_chars_to_number (buf, THUMB_SIZE);
c19d1205
ZW
24260 newval |= value;
24261 md_number_to_chars (buf, newval, THUMB_SIZE);
24262 }
24263 else
24264 {
24265 if (((unsigned long) value) > 0x00ffffff)
24266 as_bad_where (fixP->fx_file, fixP->fx_line,
24267 _("invalid swi expression"));
2fc8bdac 24268 newval = md_chars_to_number (buf, INSN_SIZE);
c19d1205
ZW
24269 newval |= value;
24270 md_number_to_chars (buf, newval, INSN_SIZE);
24271 }
24272 break;
a737bd4d 24273
c19d1205
ZW
24274 case BFD_RELOC_ARM_MULTI:
24275 if (((unsigned long) value) > 0xffff)
24276 as_bad_where (fixP->fx_file, fixP->fx_line,
24277 _("invalid expression in load/store multiple"));
24278 newval = value | md_chars_to_number (buf, INSN_SIZE);
24279 md_number_to_chars (buf, newval, INSN_SIZE);
24280 break;
a737bd4d 24281
c19d1205 24282#ifdef OBJ_ELF
39b41c9c 24283 case BFD_RELOC_ARM_PCREL_CALL:
267bf995
RR
24284
24285 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
24286 && fixP->fx_addsy
34e77a92 24287 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24288 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24289 && THUMB_IS_FUNC (fixP->fx_addsy))
24290 /* Flip the bl to blx. This is a simple flip
24291 bit here because we generate PCREL_CALL for
24292 unconditional bls. */
24293 {
24294 newval = md_chars_to_number (buf, INSN_SIZE);
24295 newval = newval | 0x10000000;
24296 md_number_to_chars (buf, newval, INSN_SIZE);
24297 temp = 1;
24298 fixP->fx_done = 1;
24299 }
39b41c9c
PB
24300 else
24301 temp = 3;
24302 goto arm_branch_common;
24303
24304 case BFD_RELOC_ARM_PCREL_JUMP:
267bf995
RR
24305 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
24306 && fixP->fx_addsy
34e77a92 24307 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24308 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24309 && THUMB_IS_FUNC (fixP->fx_addsy))
24310 {
24311 /* This would map to a bl<cond>, b<cond>,
24312 b<always> to a Thumb function. We
24313 need to force a relocation for this particular
24314 case. */
24315 newval = md_chars_to_number (buf, INSN_SIZE);
24316 fixP->fx_done = 0;
24317 }
1a0670f3 24318 /* Fall through. */
267bf995 24319
2fc8bdac 24320 case BFD_RELOC_ARM_PLT32:
c19d1205 24321#endif
39b41c9c
PB
24322 case BFD_RELOC_ARM_PCREL_BRANCH:
24323 temp = 3;
24324 goto arm_branch_common;
a737bd4d 24325
39b41c9c 24326 case BFD_RELOC_ARM_PCREL_BLX:
267bf995 24327
39b41c9c 24328 temp = 1;
267bf995
RR
24329 if (ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
24330 && fixP->fx_addsy
34e77a92 24331 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24332 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24333 && ARM_IS_FUNC (fixP->fx_addsy))
24334 {
24335 /* Flip the blx to a bl and warn. */
24336 const char *name = S_GET_NAME (fixP->fx_addsy);
24337 newval = 0xeb000000;
24338 as_warn_where (fixP->fx_file, fixP->fx_line,
24339 _("blx to '%s' an ARM ISA state function changed to bl"),
24340 name);
24341 md_number_to_chars (buf, newval, INSN_SIZE);
24342 temp = 3;
24343 fixP->fx_done = 1;
24344 }
24345
24346#ifdef OBJ_ELF
24347 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
477330fc 24348 fixP->fx_r_type = BFD_RELOC_ARM_PCREL_CALL;
267bf995
RR
24349#endif
24350
39b41c9c 24351 arm_branch_common:
c19d1205 24352 /* We are going to store value (shifted right by two) in the
39b41c9c
PB
24353 instruction, in a 24 bit, signed field. Bits 26 through 32 either
24354 all clear or all set and bit 0 must be clear. For B/BL bit 1 must
de194d85 24355 also be clear. */
39b41c9c 24356 if (value & temp)
c19d1205 24357 as_bad_where (fixP->fx_file, fixP->fx_line,
2fc8bdac
ZW
24358 _("misaligned branch destination"));
24359 if ((value & (offsetT)0xfe000000) != (offsetT)0
24360 && (value & (offsetT)0xfe000000) != (offsetT)0xfe000000)
08f10d51 24361 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 24362
2fc8bdac 24363 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 24364 {
2fc8bdac
ZW
24365 newval = md_chars_to_number (buf, INSN_SIZE);
24366 newval |= (value >> 2) & 0x00ffffff;
7ae2971b
PB
24367 /* Set the H bit on BLX instructions. */
24368 if (temp == 1)
24369 {
24370 if (value & 2)
24371 newval |= 0x01000000;
24372 else
24373 newval &= ~0x01000000;
24374 }
2fc8bdac 24375 md_number_to_chars (buf, newval, INSN_SIZE);
c19d1205 24376 }
c19d1205 24377 break;
a737bd4d 24378
25fe350b
MS
24379 case BFD_RELOC_THUMB_PCREL_BRANCH7: /* CBZ */
24380 /* CBZ can only branch forward. */
a737bd4d 24381
738755b0 24382 /* Attempts to use CBZ to branch to the next instruction
477330fc
RM
24383 (which, strictly speaking, are prohibited) will be turned into
24384 no-ops.
738755b0
MS
24385
24386 FIXME: It may be better to remove the instruction completely and
24387 perform relaxation. */
24388 if (value == -2)
2fc8bdac
ZW
24389 {
24390 newval = md_chars_to_number (buf, THUMB_SIZE);
738755b0 24391 newval = 0xbf00; /* NOP encoding T1 */
2fc8bdac
ZW
24392 md_number_to_chars (buf, newval, THUMB_SIZE);
24393 }
738755b0
MS
24394 else
24395 {
24396 if (value & ~0x7e)
08f10d51 24397 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
738755b0 24398
477330fc 24399 if (fixP->fx_done || !seg->use_rela_p)
738755b0
MS
24400 {
24401 newval = md_chars_to_number (buf, THUMB_SIZE);
24402 newval |= ((value & 0x3e) << 2) | ((value & 0x40) << 3);
24403 md_number_to_chars (buf, newval, THUMB_SIZE);
24404 }
24405 }
c19d1205 24406 break;
a737bd4d 24407
c19d1205 24408 case BFD_RELOC_THUMB_PCREL_BRANCH9: /* Conditional branch. */
2fc8bdac 24409 if ((value & ~0xff) && ((value & ~0xff) != ~0xff))
08f10d51 24410 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 24411
2fc8bdac
ZW
24412 if (fixP->fx_done || !seg->use_rela_p)
24413 {
24414 newval = md_chars_to_number (buf, THUMB_SIZE);
24415 newval |= (value & 0x1ff) >> 1;
24416 md_number_to_chars (buf, newval, THUMB_SIZE);
24417 }
c19d1205 24418 break;
a737bd4d 24419
c19d1205 24420 case BFD_RELOC_THUMB_PCREL_BRANCH12: /* Unconditional branch. */
2fc8bdac 24421 if ((value & ~0x7ff) && ((value & ~0x7ff) != ~0x7ff))
08f10d51 24422 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
a737bd4d 24423
2fc8bdac
ZW
24424 if (fixP->fx_done || !seg->use_rela_p)
24425 {
24426 newval = md_chars_to_number (buf, THUMB_SIZE);
24427 newval |= (value & 0xfff) >> 1;
24428 md_number_to_chars (buf, newval, THUMB_SIZE);
24429 }
c19d1205 24430 break;
a737bd4d 24431
c19d1205 24432 case BFD_RELOC_THUMB_PCREL_BRANCH20:
267bf995
RR
24433 if (fixP->fx_addsy
24434 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 24435 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24436 && ARM_IS_FUNC (fixP->fx_addsy)
24437 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
24438 {
24439 /* Force a relocation for a branch 20 bits wide. */
24440 fixP->fx_done = 0;
24441 }
08f10d51 24442 if ((value & ~0x1fffff) && ((value & ~0x0fffff) != ~0x0fffff))
2fc8bdac
ZW
24443 as_bad_where (fixP->fx_file, fixP->fx_line,
24444 _("conditional branch out of range"));
404ff6b5 24445
2fc8bdac
ZW
24446 if (fixP->fx_done || !seg->use_rela_p)
24447 {
24448 offsetT newval2;
24449 addressT S, J1, J2, lo, hi;
404ff6b5 24450
2fc8bdac
ZW
24451 S = (value & 0x00100000) >> 20;
24452 J2 = (value & 0x00080000) >> 19;
24453 J1 = (value & 0x00040000) >> 18;
24454 hi = (value & 0x0003f000) >> 12;
24455 lo = (value & 0x00000ffe) >> 1;
6c43fab6 24456
2fc8bdac
ZW
24457 newval = md_chars_to_number (buf, THUMB_SIZE);
24458 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
24459 newval |= (S << 10) | hi;
24460 newval2 |= (J1 << 13) | (J2 << 11) | lo;
24461 md_number_to_chars (buf, newval, THUMB_SIZE);
24462 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
24463 }
c19d1205 24464 break;
6c43fab6 24465
c19d1205 24466 case BFD_RELOC_THUMB_PCREL_BLX:
267bf995
RR
24467 /* If there is a blx from a thumb state function to
24468 another thumb function flip this to a bl and warn
24469 about it. */
24470
24471 if (fixP->fx_addsy
34e77a92 24472 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24473 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
24474 && THUMB_IS_FUNC (fixP->fx_addsy))
24475 {
24476 const char *name = S_GET_NAME (fixP->fx_addsy);
24477 as_warn_where (fixP->fx_file, fixP->fx_line,
24478 _("blx to Thumb func '%s' from Thumb ISA state changed to bl"),
24479 name);
24480 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
24481 newval = newval | 0x1000;
24482 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
24483 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
24484 fixP->fx_done = 1;
24485 }
24486
24487
24488 goto thumb_bl_common;
24489
c19d1205 24490 case BFD_RELOC_THUMB_PCREL_BRANCH23:
267bf995
RR
24491 /* A bl from Thumb state ISA to an internal ARM state function
24492 is converted to a blx. */
24493 if (fixP->fx_addsy
24494 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
34e77a92 24495 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
267bf995
RR
24496 && ARM_IS_FUNC (fixP->fx_addsy)
24497 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t))
24498 {
24499 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
24500 newval = newval & ~0x1000;
24501 md_number_to_chars (buf+THUMB_SIZE, newval, THUMB_SIZE);
24502 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BLX;
24503 fixP->fx_done = 1;
24504 }
24505
24506 thumb_bl_common:
24507
2fc8bdac
ZW
24508 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
24509 /* For a BLX instruction, make sure that the relocation is rounded up
24510 to a word boundary. This follows the semantics of the instruction
24511 which specifies that bit 1 of the target address will come from bit
24512 1 of the base address. */
d406f3e4
JB
24513 value = (value + 3) & ~ 3;
24514
24515#ifdef OBJ_ELF
24516 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4
24517 && fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BLX)
24518 fixP->fx_r_type = BFD_RELOC_THUMB_PCREL_BRANCH23;
24519#endif
404ff6b5 24520
2b2f5df9
NC
24521 if ((value & ~0x3fffff) && ((value & ~0x3fffff) != ~0x3fffff))
24522 {
fc289b0a 24523 if (!(ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)))
2b2f5df9
NC
24524 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
24525 else if ((value & ~0x1ffffff)
24526 && ((value & ~0x1ffffff) != ~0x1ffffff))
24527 as_bad_where (fixP->fx_file, fixP->fx_line,
24528 _("Thumb2 branch out of range"));
24529 }
4a42ebbc
RR
24530
24531 if (fixP->fx_done || !seg->use_rela_p)
24532 encode_thumb2_b_bl_offset (buf, value);
24533
c19d1205 24534 break;
404ff6b5 24535
c19d1205 24536 case BFD_RELOC_THUMB_PCREL_BRANCH25:
08f10d51
NC
24537 if ((value & ~0x0ffffff) && ((value & ~0x0ffffff) != ~0x0ffffff))
24538 as_bad_where (fixP->fx_file, fixP->fx_line, BAD_RANGE);
6c43fab6 24539
2fc8bdac 24540 if (fixP->fx_done || !seg->use_rela_p)
4a42ebbc 24541 encode_thumb2_b_bl_offset (buf, value);
6c43fab6 24542
2fc8bdac 24543 break;
a737bd4d 24544
2fc8bdac
ZW
24545 case BFD_RELOC_8:
24546 if (fixP->fx_done || !seg->use_rela_p)
4b1a927e 24547 *buf = value;
c19d1205 24548 break;
a737bd4d 24549
c19d1205 24550 case BFD_RELOC_16:
2fc8bdac 24551 if (fixP->fx_done || !seg->use_rela_p)
c19d1205 24552 md_number_to_chars (buf, value, 2);
c19d1205 24553 break;
a737bd4d 24554
c19d1205 24555#ifdef OBJ_ELF
0855e32b
NS
24556 case BFD_RELOC_ARM_TLS_CALL:
24557 case BFD_RELOC_ARM_THM_TLS_CALL:
24558 case BFD_RELOC_ARM_TLS_DESCSEQ:
24559 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
0855e32b 24560 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205
ZW
24561 case BFD_RELOC_ARM_TLS_GD32:
24562 case BFD_RELOC_ARM_TLS_LE32:
24563 case BFD_RELOC_ARM_TLS_IE32:
24564 case BFD_RELOC_ARM_TLS_LDM32:
24565 case BFD_RELOC_ARM_TLS_LDO32:
24566 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4b1a927e 24567 break;
6c43fab6 24568
5c5a4843
CL
24569 /* Same handling as above, but with the arm_fdpic guard. */
24570 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
24571 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
24572 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
24573 if (arm_fdpic)
24574 {
24575 S_SET_THREAD_LOCAL (fixP->fx_addsy);
24576 }
24577 else
24578 {
24579 as_bad_where (fixP->fx_file, fixP->fx_line,
24580 _("Relocation supported only in FDPIC mode"));
24581 }
24582 break;
24583
c19d1205
ZW
24584 case BFD_RELOC_ARM_GOT32:
24585 case BFD_RELOC_ARM_GOTOFF:
c19d1205 24586 break;
b43420e6
NC
24587
24588 case BFD_RELOC_ARM_GOT_PREL:
24589 if (fixP->fx_done || !seg->use_rela_p)
477330fc 24590 md_number_to_chars (buf, value, 4);
b43420e6
NC
24591 break;
24592
9a6f4e97
NS
24593 case BFD_RELOC_ARM_TARGET2:
24594 /* TARGET2 is not partial-inplace, so we need to write the
477330fc
RM
24595 addend here for REL targets, because it won't be written out
24596 during reloc processing later. */
9a6f4e97
NS
24597 if (fixP->fx_done || !seg->use_rela_p)
24598 md_number_to_chars (buf, fixP->fx_offset, 4);
24599 break;
188fd7ae
CL
24600
24601 /* Relocations for FDPIC. */
24602 case BFD_RELOC_ARM_GOTFUNCDESC:
24603 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
24604 case BFD_RELOC_ARM_FUNCDESC:
24605 if (arm_fdpic)
24606 {
24607 if (fixP->fx_done || !seg->use_rela_p)
24608 md_number_to_chars (buf, 0, 4);
24609 }
24610 else
24611 {
24612 as_bad_where (fixP->fx_file, fixP->fx_line,
24613 _("Relocation supported only in FDPIC mode"));
24614 }
24615 break;
c19d1205 24616#endif
6c43fab6 24617
c19d1205
ZW
24618 case BFD_RELOC_RVA:
24619 case BFD_RELOC_32:
24620 case BFD_RELOC_ARM_TARGET1:
24621 case BFD_RELOC_ARM_ROSEGREL32:
24622 case BFD_RELOC_ARM_SBREL32:
24623 case BFD_RELOC_32_PCREL:
f0927246
NC
24624#ifdef TE_PE
24625 case BFD_RELOC_32_SECREL:
24626#endif
2fc8bdac 24627 if (fixP->fx_done || !seg->use_rela_p)
53baae48
NC
24628#ifdef TE_WINCE
24629 /* For WinCE we only do this for pcrel fixups. */
24630 if (fixP->fx_done || fixP->fx_pcrel)
24631#endif
24632 md_number_to_chars (buf, value, 4);
c19d1205 24633 break;
6c43fab6 24634
c19d1205
ZW
24635#ifdef OBJ_ELF
24636 case BFD_RELOC_ARM_PREL31:
2fc8bdac 24637 if (fixP->fx_done || !seg->use_rela_p)
c19d1205
ZW
24638 {
24639 newval = md_chars_to_number (buf, 4) & 0x80000000;
24640 if ((value ^ (value >> 1)) & 0x40000000)
24641 {
24642 as_bad_where (fixP->fx_file, fixP->fx_line,
24643 _("rel31 relocation overflow"));
24644 }
24645 newval |= value & 0x7fffffff;
24646 md_number_to_chars (buf, newval, 4);
24647 }
24648 break;
c19d1205 24649#endif
a737bd4d 24650
c19d1205 24651 case BFD_RELOC_ARM_CP_OFF_IMM:
8f06b2d8 24652 case BFD_RELOC_ARM_T32_CP_OFF_IMM:
32c36c3c 24653 case BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM:
9db2f6b4
RL
24654 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM)
24655 newval = md_chars_to_number (buf, INSN_SIZE);
24656 else
24657 newval = get_thumb32_insn (buf);
24658 if ((newval & 0x0f200f00) == 0x0d000900)
24659 {
24660 /* This is a fp16 vstr/vldr. The immediate offset in the mnemonic
24661 has permitted values that are multiples of 2, in the range 0
24662 to 510. */
24663 if (value < -510 || value > 510 || (value & 1))
24664 as_bad_where (fixP->fx_file, fixP->fx_line,
24665 _("co-processor offset out of range"));
24666 }
32c36c3c
AV
24667 else if ((newval & 0xfe001f80) == 0xec000f80)
24668 {
24669 if (value < -511 || value > 512 || (value & 3))
24670 as_bad_where (fixP->fx_file, fixP->fx_line,
24671 _("co-processor offset out of range"));
24672 }
9db2f6b4 24673 else if (value < -1023 || value > 1023 || (value & 3))
c19d1205
ZW
24674 as_bad_where (fixP->fx_file, fixP->fx_line,
24675 _("co-processor offset out of range"));
24676 cp_off_common:
26d97720 24677 sign = value > 0;
c19d1205
ZW
24678 if (value < 0)
24679 value = -value;
8f06b2d8
PB
24680 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
24681 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
24682 newval = md_chars_to_number (buf, INSN_SIZE);
24683 else
24684 newval = get_thumb32_insn (buf);
26d97720 24685 if (value == 0)
32c36c3c
AV
24686 {
24687 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
24688 newval &= 0xffffff80;
24689 else
24690 newval &= 0xffffff00;
24691 }
26d97720
NS
24692 else
24693 {
32c36c3c
AV
24694 if (fixP->fx_r_type == BFD_RELOC_ARM_T32_VLDR_VSTR_OFF_IMM)
24695 newval &= 0xff7fff80;
24696 else
24697 newval &= 0xff7fff00;
9db2f6b4
RL
24698 if ((newval & 0x0f200f00) == 0x0d000900)
24699 {
24700 /* This is a fp16 vstr/vldr.
24701
24702 It requires the immediate offset in the instruction is shifted
24703 left by 1 to be a half-word offset.
24704
24705 Here, left shift by 1 first, and later right shift by 2
24706 should get the right offset. */
24707 value <<= 1;
24708 }
26d97720
NS
24709 newval |= (value >> 2) | (sign ? INDEX_UP : 0);
24710 }
8f06b2d8
PB
24711 if (fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
24712 || fixP->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2)
24713 md_number_to_chars (buf, newval, INSN_SIZE);
24714 else
24715 put_thumb32_insn (buf, newval);
c19d1205 24716 break;
a737bd4d 24717
c19d1205 24718 case BFD_RELOC_ARM_CP_OFF_IMM_S2:
8f06b2d8 24719 case BFD_RELOC_ARM_T32_CP_OFF_IMM_S2:
c19d1205
ZW
24720 if (value < -255 || value > 255)
24721 as_bad_where (fixP->fx_file, fixP->fx_line,
24722 _("co-processor offset out of range"));
df7849c5 24723 value *= 4;
c19d1205 24724 goto cp_off_common;
6c43fab6 24725
c19d1205
ZW
24726 case BFD_RELOC_ARM_THUMB_OFFSET:
24727 newval = md_chars_to_number (buf, THUMB_SIZE);
24728 /* Exactly what ranges, and where the offset is inserted depends
24729 on the type of instruction, we can establish this from the
24730 top 4 bits. */
24731 switch (newval >> 12)
24732 {
24733 case 4: /* PC load. */
24734 /* Thumb PC loads are somewhat odd, bit 1 of the PC is
24735 forced to zero for these loads; md_pcrel_from has already
24736 compensated for this. */
24737 if (value & 3)
24738 as_bad_where (fixP->fx_file, fixP->fx_line,
24739 _("invalid offset, target not word aligned (0x%08lX)"),
0359e808
NC
24740 (((unsigned long) fixP->fx_frag->fr_address
24741 + (unsigned long) fixP->fx_where) & ~3)
24742 + (unsigned long) value);
a737bd4d 24743
c19d1205
ZW
24744 if (value & ~0x3fc)
24745 as_bad_where (fixP->fx_file, fixP->fx_line,
24746 _("invalid offset, value too big (0x%08lX)"),
24747 (long) value);
a737bd4d 24748
c19d1205
ZW
24749 newval |= value >> 2;
24750 break;
a737bd4d 24751
c19d1205
ZW
24752 case 9: /* SP load/store. */
24753 if (value & ~0x3fc)
24754 as_bad_where (fixP->fx_file, fixP->fx_line,
24755 _("invalid offset, value too big (0x%08lX)"),
24756 (long) value);
24757 newval |= value >> 2;
24758 break;
6c43fab6 24759
c19d1205
ZW
24760 case 6: /* Word load/store. */
24761 if (value & ~0x7c)
24762 as_bad_where (fixP->fx_file, fixP->fx_line,
24763 _("invalid offset, value too big (0x%08lX)"),
24764 (long) value);
24765 newval |= value << 4; /* 6 - 2. */
24766 break;
a737bd4d 24767
c19d1205
ZW
24768 case 7: /* Byte load/store. */
24769 if (value & ~0x1f)
24770 as_bad_where (fixP->fx_file, fixP->fx_line,
24771 _("invalid offset, value too big (0x%08lX)"),
24772 (long) value);
24773 newval |= value << 6;
24774 break;
a737bd4d 24775
c19d1205
ZW
24776 case 8: /* Halfword load/store. */
24777 if (value & ~0x3e)
24778 as_bad_where (fixP->fx_file, fixP->fx_line,
24779 _("invalid offset, value too big (0x%08lX)"),
24780 (long) value);
24781 newval |= value << 5; /* 6 - 1. */
24782 break;
a737bd4d 24783
c19d1205
ZW
24784 default:
24785 as_bad_where (fixP->fx_file, fixP->fx_line,
24786 "Unable to process relocation for thumb opcode: %lx",
24787 (unsigned long) newval);
24788 break;
24789 }
24790 md_number_to_chars (buf, newval, THUMB_SIZE);
24791 break;
a737bd4d 24792
c19d1205
ZW
24793 case BFD_RELOC_ARM_THUMB_ADD:
24794 /* This is a complicated relocation, since we use it for all of
24795 the following immediate relocations:
a737bd4d 24796
c19d1205
ZW
24797 3bit ADD/SUB
24798 8bit ADD/SUB
24799 9bit ADD/SUB SP word-aligned
24800 10bit ADD PC/SP word-aligned
a737bd4d 24801
c19d1205
ZW
24802 The type of instruction being processed is encoded in the
24803 instruction field:
a737bd4d 24804
c19d1205
ZW
24805 0x8000 SUB
24806 0x00F0 Rd
24807 0x000F Rs
24808 */
24809 newval = md_chars_to_number (buf, THUMB_SIZE);
24810 {
24811 int rd = (newval >> 4) & 0xf;
24812 int rs = newval & 0xf;
24813 int subtract = !!(newval & 0x8000);
a737bd4d 24814
c19d1205
ZW
24815 /* Check for HI regs, only very restricted cases allowed:
24816 Adjusting SP, and using PC or SP to get an address. */
24817 if ((rd > 7 && (rd != REG_SP || rs != REG_SP))
24818 || (rs > 7 && rs != REG_SP && rs != REG_PC))
24819 as_bad_where (fixP->fx_file, fixP->fx_line,
24820 _("invalid Hi register with immediate"));
a737bd4d 24821
c19d1205
ZW
24822 /* If value is negative, choose the opposite instruction. */
24823 if (value < 0)
24824 {
24825 value = -value;
24826 subtract = !subtract;
24827 if (value < 0)
24828 as_bad_where (fixP->fx_file, fixP->fx_line,
24829 _("immediate value out of range"));
24830 }
a737bd4d 24831
c19d1205
ZW
24832 if (rd == REG_SP)
24833 {
75c11999 24834 if (value & ~0x1fc)
c19d1205
ZW
24835 as_bad_where (fixP->fx_file, fixP->fx_line,
24836 _("invalid immediate for stack address calculation"));
24837 newval = subtract ? T_OPCODE_SUB_ST : T_OPCODE_ADD_ST;
24838 newval |= value >> 2;
24839 }
24840 else if (rs == REG_PC || rs == REG_SP)
24841 {
c12d2c9d
NC
24842 /* PR gas/18541. If the addition is for a defined symbol
24843 within range of an ADR instruction then accept it. */
24844 if (subtract
24845 && value == 4
24846 && fixP->fx_addsy != NULL)
24847 {
24848 subtract = 0;
24849
24850 if (! S_IS_DEFINED (fixP->fx_addsy)
24851 || S_GET_SEGMENT (fixP->fx_addsy) != seg
24852 || S_IS_WEAK (fixP->fx_addsy))
24853 {
24854 as_bad_where (fixP->fx_file, fixP->fx_line,
24855 _("address calculation needs a strongly defined nearby symbol"));
24856 }
24857 else
24858 {
24859 offsetT v = fixP->fx_where + fixP->fx_frag->fr_address;
24860
24861 /* Round up to the next 4-byte boundary. */
24862 if (v & 3)
24863 v = (v + 3) & ~ 3;
24864 else
24865 v += 4;
24866 v = S_GET_VALUE (fixP->fx_addsy) - v;
24867
24868 if (v & ~0x3fc)
24869 {
24870 as_bad_where (fixP->fx_file, fixP->fx_line,
24871 _("symbol too far away"));
24872 }
24873 else
24874 {
24875 fixP->fx_done = 1;
24876 value = v;
24877 }
24878 }
24879 }
24880
c19d1205
ZW
24881 if (subtract || value & ~0x3fc)
24882 as_bad_where (fixP->fx_file, fixP->fx_line,
24883 _("invalid immediate for address calculation (value = 0x%08lX)"),
5fc177c8 24884 (unsigned long) (subtract ? - value : value));
c19d1205
ZW
24885 newval = (rs == REG_PC ? T_OPCODE_ADD_PC : T_OPCODE_ADD_SP);
24886 newval |= rd << 8;
24887 newval |= value >> 2;
24888 }
24889 else if (rs == rd)
24890 {
24891 if (value & ~0xff)
24892 as_bad_where (fixP->fx_file, fixP->fx_line,
24893 _("immediate value out of range"));
24894 newval = subtract ? T_OPCODE_SUB_I8 : T_OPCODE_ADD_I8;
24895 newval |= (rd << 8) | value;
24896 }
24897 else
24898 {
24899 if (value & ~0x7)
24900 as_bad_where (fixP->fx_file, fixP->fx_line,
24901 _("immediate value out of range"));
24902 newval = subtract ? T_OPCODE_SUB_I3 : T_OPCODE_ADD_I3;
24903 newval |= rd | (rs << 3) | (value << 6);
24904 }
24905 }
24906 md_number_to_chars (buf, newval, THUMB_SIZE);
24907 break;
a737bd4d 24908
c19d1205
ZW
24909 case BFD_RELOC_ARM_THUMB_IMM:
24910 newval = md_chars_to_number (buf, THUMB_SIZE);
24911 if (value < 0 || value > 255)
24912 as_bad_where (fixP->fx_file, fixP->fx_line,
4e6e072b 24913 _("invalid immediate: %ld is out of range"),
c19d1205
ZW
24914 (long) value);
24915 newval |= value;
24916 md_number_to_chars (buf, newval, THUMB_SIZE);
24917 break;
a737bd4d 24918
c19d1205
ZW
24919 case BFD_RELOC_ARM_THUMB_SHIFT:
24920 /* 5bit shift value (0..32). LSL cannot take 32. */
24921 newval = md_chars_to_number (buf, THUMB_SIZE) & 0xf83f;
24922 temp = newval & 0xf800;
24923 if (value < 0 || value > 32 || (value == 32 && temp == T_OPCODE_LSL_I))
24924 as_bad_where (fixP->fx_file, fixP->fx_line,
24925 _("invalid shift value: %ld"), (long) value);
24926 /* Shifts of zero must be encoded as LSL. */
24927 if (value == 0)
24928 newval = (newval & 0x003f) | T_OPCODE_LSL_I;
24929 /* Shifts of 32 are encoded as zero. */
24930 else if (value == 32)
24931 value = 0;
24932 newval |= value << 6;
24933 md_number_to_chars (buf, newval, THUMB_SIZE);
24934 break;
a737bd4d 24935
c19d1205
ZW
24936 case BFD_RELOC_VTABLE_INHERIT:
24937 case BFD_RELOC_VTABLE_ENTRY:
24938 fixP->fx_done = 0;
24939 return;
6c43fab6 24940
b6895b4f
PB
24941 case BFD_RELOC_ARM_MOVW:
24942 case BFD_RELOC_ARM_MOVT:
24943 case BFD_RELOC_ARM_THUMB_MOVW:
24944 case BFD_RELOC_ARM_THUMB_MOVT:
24945 if (fixP->fx_done || !seg->use_rela_p)
24946 {
24947 /* REL format relocations are limited to a 16-bit addend. */
24948 if (!fixP->fx_done)
24949 {
39623e12 24950 if (value < -0x8000 || value > 0x7fff)
b6895b4f 24951 as_bad_where (fixP->fx_file, fixP->fx_line,
ff5075ca 24952 _("offset out of range"));
b6895b4f
PB
24953 }
24954 else if (fixP->fx_r_type == BFD_RELOC_ARM_MOVT
24955 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
24956 {
24957 value >>= 16;
24958 }
24959
24960 if (fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
24961 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT)
24962 {
24963 newval = get_thumb32_insn (buf);
24964 newval &= 0xfbf08f00;
24965 newval |= (value & 0xf000) << 4;
24966 newval |= (value & 0x0800) << 15;
24967 newval |= (value & 0x0700) << 4;
24968 newval |= (value & 0x00ff);
24969 put_thumb32_insn (buf, newval);
24970 }
24971 else
24972 {
24973 newval = md_chars_to_number (buf, 4);
24974 newval &= 0xfff0f000;
24975 newval |= value & 0x0fff;
24976 newval |= (value & 0xf000) << 4;
24977 md_number_to_chars (buf, newval, 4);
24978 }
24979 }
24980 return;
24981
72d98d16
MG
24982 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
24983 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
24984 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
24985 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
24986 gas_assert (!fixP->fx_done);
24987 {
24988 bfd_vma insn;
24989 bfd_boolean is_mov;
24990 bfd_vma encoded_addend = value;
24991
24992 /* Check that addend can be encoded in instruction. */
24993 if (!seg->use_rela_p && (value < 0 || value > 255))
24994 as_bad_where (fixP->fx_file, fixP->fx_line,
24995 _("the offset 0x%08lX is not representable"),
24996 (unsigned long) encoded_addend);
24997
24998 /* Extract the instruction. */
24999 insn = md_chars_to_number (buf, THUMB_SIZE);
25000 is_mov = (insn & 0xf800) == 0x2000;
25001
25002 /* Encode insn. */
25003 if (is_mov)
25004 {
25005 if (!seg->use_rela_p)
25006 insn |= encoded_addend;
25007 }
25008 else
25009 {
25010 int rd, rs;
25011
25012 /* Extract the instruction. */
25013 /* Encoding is the following
25014 0x8000 SUB
25015 0x00F0 Rd
25016 0x000F Rs
25017 */
25018 /* The following conditions must be true :
25019 - ADD
25020 - Rd == Rs
25021 - Rd <= 7
25022 */
25023 rd = (insn >> 4) & 0xf;
25024 rs = insn & 0xf;
25025 if ((insn & 0x8000) || (rd != rs) || rd > 7)
25026 as_bad_where (fixP->fx_file, fixP->fx_line,
25027 _("Unable to process relocation for thumb opcode: %lx"),
25028 (unsigned long) insn);
25029
25030 /* Encode as ADD immediate8 thumb 1 code. */
25031 insn = 0x3000 | (rd << 8);
25032
25033 /* Place the encoded addend into the first 8 bits of the
25034 instruction. */
25035 if (!seg->use_rela_p)
25036 insn |= encoded_addend;
25037 }
25038
25039 /* Update the instruction. */
25040 md_number_to_chars (buf, insn, THUMB_SIZE);
25041 }
25042 break;
25043
4962c51a
MS
25044 case BFD_RELOC_ARM_ALU_PC_G0_NC:
25045 case BFD_RELOC_ARM_ALU_PC_G0:
25046 case BFD_RELOC_ARM_ALU_PC_G1_NC:
25047 case BFD_RELOC_ARM_ALU_PC_G1:
25048 case BFD_RELOC_ARM_ALU_PC_G2:
25049 case BFD_RELOC_ARM_ALU_SB_G0_NC:
25050 case BFD_RELOC_ARM_ALU_SB_G0:
25051 case BFD_RELOC_ARM_ALU_SB_G1_NC:
25052 case BFD_RELOC_ARM_ALU_SB_G1:
25053 case BFD_RELOC_ARM_ALU_SB_G2:
9c2799c2 25054 gas_assert (!fixP->fx_done);
4962c51a
MS
25055 if (!seg->use_rela_p)
25056 {
477330fc
RM
25057 bfd_vma insn;
25058 bfd_vma encoded_addend;
3ca4a8ec 25059 bfd_vma addend_abs = llabs (value);
477330fc
RM
25060
25061 /* Check that the absolute value of the addend can be
25062 expressed as an 8-bit constant plus a rotation. */
25063 encoded_addend = encode_arm_immediate (addend_abs);
25064 if (encoded_addend == (unsigned int) FAIL)
4962c51a 25065 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
25066 _("the offset 0x%08lX is not representable"),
25067 (unsigned long) addend_abs);
25068
25069 /* Extract the instruction. */
25070 insn = md_chars_to_number (buf, INSN_SIZE);
25071
25072 /* If the addend is positive, use an ADD instruction.
25073 Otherwise use a SUB. Take care not to destroy the S bit. */
25074 insn &= 0xff1fffff;
25075 if (value < 0)
25076 insn |= 1 << 22;
25077 else
25078 insn |= 1 << 23;
25079
25080 /* Place the encoded addend into the first 12 bits of the
25081 instruction. */
25082 insn &= 0xfffff000;
25083 insn |= encoded_addend;
25084
25085 /* Update the instruction. */
25086 md_number_to_chars (buf, insn, INSN_SIZE);
4962c51a
MS
25087 }
25088 break;
25089
25090 case BFD_RELOC_ARM_LDR_PC_G0:
25091 case BFD_RELOC_ARM_LDR_PC_G1:
25092 case BFD_RELOC_ARM_LDR_PC_G2:
25093 case BFD_RELOC_ARM_LDR_SB_G0:
25094 case BFD_RELOC_ARM_LDR_SB_G1:
25095 case BFD_RELOC_ARM_LDR_SB_G2:
9c2799c2 25096 gas_assert (!fixP->fx_done);
4962c51a 25097 if (!seg->use_rela_p)
477330fc
RM
25098 {
25099 bfd_vma insn;
3ca4a8ec 25100 bfd_vma addend_abs = llabs (value);
4962c51a 25101
477330fc
RM
25102 /* Check that the absolute value of the addend can be
25103 encoded in 12 bits. */
25104 if (addend_abs >= 0x1000)
4962c51a 25105 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
25106 _("bad offset 0x%08lX (only 12 bits available for the magnitude)"),
25107 (unsigned long) addend_abs);
25108
25109 /* Extract the instruction. */
25110 insn = md_chars_to_number (buf, INSN_SIZE);
25111
25112 /* If the addend is negative, clear bit 23 of the instruction.
25113 Otherwise set it. */
25114 if (value < 0)
25115 insn &= ~(1 << 23);
25116 else
25117 insn |= 1 << 23;
25118
25119 /* Place the absolute value of the addend into the first 12 bits
25120 of the instruction. */
25121 insn &= 0xfffff000;
25122 insn |= addend_abs;
25123
25124 /* Update the instruction. */
25125 md_number_to_chars (buf, insn, INSN_SIZE);
25126 }
4962c51a
MS
25127 break;
25128
25129 case BFD_RELOC_ARM_LDRS_PC_G0:
25130 case BFD_RELOC_ARM_LDRS_PC_G1:
25131 case BFD_RELOC_ARM_LDRS_PC_G2:
25132 case BFD_RELOC_ARM_LDRS_SB_G0:
25133 case BFD_RELOC_ARM_LDRS_SB_G1:
25134 case BFD_RELOC_ARM_LDRS_SB_G2:
9c2799c2 25135 gas_assert (!fixP->fx_done);
4962c51a 25136 if (!seg->use_rela_p)
477330fc
RM
25137 {
25138 bfd_vma insn;
3ca4a8ec 25139 bfd_vma addend_abs = llabs (value);
4962c51a 25140
477330fc
RM
25141 /* Check that the absolute value of the addend can be
25142 encoded in 8 bits. */
25143 if (addend_abs >= 0x100)
4962c51a 25144 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
25145 _("bad offset 0x%08lX (only 8 bits available for the magnitude)"),
25146 (unsigned long) addend_abs);
25147
25148 /* Extract the instruction. */
25149 insn = md_chars_to_number (buf, INSN_SIZE);
25150
25151 /* If the addend is negative, clear bit 23 of the instruction.
25152 Otherwise set it. */
25153 if (value < 0)
25154 insn &= ~(1 << 23);
25155 else
25156 insn |= 1 << 23;
25157
25158 /* Place the first four bits of the absolute value of the addend
25159 into the first 4 bits of the instruction, and the remaining
25160 four into bits 8 .. 11. */
25161 insn &= 0xfffff0f0;
25162 insn |= (addend_abs & 0xf) | ((addend_abs & 0xf0) << 4);
25163
25164 /* Update the instruction. */
25165 md_number_to_chars (buf, insn, INSN_SIZE);
25166 }
4962c51a
MS
25167 break;
25168
25169 case BFD_RELOC_ARM_LDC_PC_G0:
25170 case BFD_RELOC_ARM_LDC_PC_G1:
25171 case BFD_RELOC_ARM_LDC_PC_G2:
25172 case BFD_RELOC_ARM_LDC_SB_G0:
25173 case BFD_RELOC_ARM_LDC_SB_G1:
25174 case BFD_RELOC_ARM_LDC_SB_G2:
9c2799c2 25175 gas_assert (!fixP->fx_done);
4962c51a 25176 if (!seg->use_rela_p)
477330fc
RM
25177 {
25178 bfd_vma insn;
3ca4a8ec 25179 bfd_vma addend_abs = llabs (value);
4962c51a 25180
477330fc
RM
25181 /* Check that the absolute value of the addend is a multiple of
25182 four and, when divided by four, fits in 8 bits. */
25183 if (addend_abs & 0x3)
4962c51a 25184 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
25185 _("bad offset 0x%08lX (must be word-aligned)"),
25186 (unsigned long) addend_abs);
4962c51a 25187
477330fc 25188 if ((addend_abs >> 2) > 0xff)
4962c51a 25189 as_bad_where (fixP->fx_file, fixP->fx_line,
477330fc
RM
25190 _("bad offset 0x%08lX (must be an 8-bit number of words)"),
25191 (unsigned long) addend_abs);
25192
25193 /* Extract the instruction. */
25194 insn = md_chars_to_number (buf, INSN_SIZE);
25195
25196 /* If the addend is negative, clear bit 23 of the instruction.
25197 Otherwise set it. */
25198 if (value < 0)
25199 insn &= ~(1 << 23);
25200 else
25201 insn |= 1 << 23;
25202
25203 /* Place the addend (divided by four) into the first eight
25204 bits of the instruction. */
25205 insn &= 0xfffffff0;
25206 insn |= addend_abs >> 2;
25207
25208 /* Update the instruction. */
25209 md_number_to_chars (buf, insn, INSN_SIZE);
25210 }
4962c51a
MS
25211 break;
25212
e12437dc
AV
25213 case BFD_RELOC_THUMB_PCREL_BRANCH5:
25214 if (fixP->fx_addsy
25215 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25216 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25217 && ARM_IS_FUNC (fixP->fx_addsy)
25218 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25219 {
25220 /* Force a relocation for a branch 5 bits wide. */
25221 fixP->fx_done = 0;
25222 }
25223 if (v8_1_branch_value_check (value, 5, FALSE) == FAIL)
25224 as_bad_where (fixP->fx_file, fixP->fx_line,
25225 BAD_BRANCH_OFF);
25226
25227 if (fixP->fx_done || !seg->use_rela_p)
25228 {
25229 addressT boff = value >> 1;
25230
25231 newval = md_chars_to_number (buf, THUMB_SIZE);
25232 newval |= (boff << 7);
25233 md_number_to_chars (buf, newval, THUMB_SIZE);
25234 }
25235 break;
25236
f6b2b12d
AV
25237 case BFD_RELOC_THUMB_PCREL_BFCSEL:
25238 if (fixP->fx_addsy
25239 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25240 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25241 && ARM_IS_FUNC (fixP->fx_addsy)
25242 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25243 {
25244 fixP->fx_done = 0;
25245 }
25246 if ((value & ~0x7f) && ((value & ~0x3f) != ~0x3f))
25247 as_bad_where (fixP->fx_file, fixP->fx_line,
25248 _("branch out of range"));
25249
25250 if (fixP->fx_done || !seg->use_rela_p)
25251 {
25252 newval = md_chars_to_number (buf, THUMB_SIZE);
25253
25254 addressT boff = ((newval & 0x0780) >> 7) << 1;
25255 addressT diff = value - boff;
25256
25257 if (diff == 4)
25258 {
25259 newval |= 1 << 1; /* T bit. */
25260 }
25261 else if (diff != 2)
25262 {
25263 as_bad_where (fixP->fx_file, fixP->fx_line,
25264 _("out of range label-relative fixup value"));
25265 }
25266 md_number_to_chars (buf, newval, THUMB_SIZE);
25267 }
25268 break;
25269
e5d6e09e
AV
25270 case BFD_RELOC_ARM_THUMB_BF17:
25271 if (fixP->fx_addsy
25272 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25273 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25274 && ARM_IS_FUNC (fixP->fx_addsy)
25275 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25276 {
25277 /* Force a relocation for a branch 17 bits wide. */
25278 fixP->fx_done = 0;
25279 }
25280
25281 if (v8_1_branch_value_check (value, 17, TRUE) == FAIL)
25282 as_bad_where (fixP->fx_file, fixP->fx_line,
25283 BAD_BRANCH_OFF);
25284
25285 if (fixP->fx_done || !seg->use_rela_p)
25286 {
25287 offsetT newval2;
25288 addressT immA, immB, immC;
25289
25290 immA = (value & 0x0001f000) >> 12;
25291 immB = (value & 0x00000ffc) >> 2;
25292 immC = (value & 0x00000002) >> 1;
25293
25294 newval = md_chars_to_number (buf, THUMB_SIZE);
25295 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25296 newval |= immA;
25297 newval2 |= (immC << 11) | (immB << 1);
25298 md_number_to_chars (buf, newval, THUMB_SIZE);
25299 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
25300 }
25301 break;
25302
1caf72a5
AV
25303 case BFD_RELOC_ARM_THUMB_BF19:
25304 if (fixP->fx_addsy
25305 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25306 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25307 && ARM_IS_FUNC (fixP->fx_addsy)
25308 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25309 {
25310 /* Force a relocation for a branch 19 bits wide. */
25311 fixP->fx_done = 0;
25312 }
25313
25314 if (v8_1_branch_value_check (value, 19, TRUE) == FAIL)
25315 as_bad_where (fixP->fx_file, fixP->fx_line,
25316 BAD_BRANCH_OFF);
25317
25318 if (fixP->fx_done || !seg->use_rela_p)
25319 {
25320 offsetT newval2;
25321 addressT immA, immB, immC;
25322
25323 immA = (value & 0x0007f000) >> 12;
25324 immB = (value & 0x00000ffc) >> 2;
25325 immC = (value & 0x00000002) >> 1;
25326
25327 newval = md_chars_to_number (buf, THUMB_SIZE);
25328 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25329 newval |= immA;
25330 newval2 |= (immC << 11) | (immB << 1);
25331 md_number_to_chars (buf, newval, THUMB_SIZE);
25332 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
25333 }
25334 break;
25335
1889da70
AV
25336 case BFD_RELOC_ARM_THUMB_BF13:
25337 if (fixP->fx_addsy
25338 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25339 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25340 && ARM_IS_FUNC (fixP->fx_addsy)
25341 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25342 {
25343 /* Force a relocation for a branch 13 bits wide. */
25344 fixP->fx_done = 0;
25345 }
25346
25347 if (v8_1_branch_value_check (value, 13, TRUE) == FAIL)
25348 as_bad_where (fixP->fx_file, fixP->fx_line,
25349 BAD_BRANCH_OFF);
25350
25351 if (fixP->fx_done || !seg->use_rela_p)
25352 {
25353 offsetT newval2;
25354 addressT immA, immB, immC;
25355
25356 immA = (value & 0x00001000) >> 12;
25357 immB = (value & 0x00000ffc) >> 2;
25358 immC = (value & 0x00000002) >> 1;
25359
25360 newval = md_chars_to_number (buf, THUMB_SIZE);
25361 newval2 = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25362 newval |= immA;
25363 newval2 |= (immC << 11) | (immB << 1);
25364 md_number_to_chars (buf, newval, THUMB_SIZE);
25365 md_number_to_chars (buf + THUMB_SIZE, newval2, THUMB_SIZE);
25366 }
25367 break;
25368
60f993ce
AV
25369 case BFD_RELOC_ARM_THUMB_LOOP12:
25370 if (fixP->fx_addsy
25371 && (S_GET_SEGMENT (fixP->fx_addsy) == seg)
25372 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE)
25373 && ARM_IS_FUNC (fixP->fx_addsy)
25374 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v8_1m_main))
25375 {
25376 /* Force a relocation for a branch 12 bits wide. */
25377 fixP->fx_done = 0;
25378 }
25379
25380 bfd_vma insn = get_thumb32_insn (buf);
25381 /* le lr, <label> or le <label> */
25382 if (((insn & 0xffffffff) == 0xf00fc001)
25383 || ((insn & 0xffffffff) == 0xf02fc001))
25384 value = -value;
25385
25386 if (v8_1_branch_value_check (value, 12, FALSE) == FAIL)
25387 as_bad_where (fixP->fx_file, fixP->fx_line,
25388 BAD_BRANCH_OFF);
25389 if (fixP->fx_done || !seg->use_rela_p)
25390 {
25391 addressT imml, immh;
25392
25393 immh = (value & 0x00000ffc) >> 2;
25394 imml = (value & 0x00000002) >> 1;
25395
25396 newval = md_chars_to_number (buf + THUMB_SIZE, THUMB_SIZE);
25397 newval |= (imml << 11) | (immh << 1);
25398 md_number_to_chars (buf + THUMB_SIZE, newval, THUMB_SIZE);
25399 }
25400 break;
25401
845b51d6
PB
25402 case BFD_RELOC_ARM_V4BX:
25403 /* This will need to go in the object file. */
25404 fixP->fx_done = 0;
25405 break;
25406
c19d1205
ZW
25407 case BFD_RELOC_UNUSED:
25408 default:
25409 as_bad_where (fixP->fx_file, fixP->fx_line,
25410 _("bad relocation fixup type (%d)"), fixP->fx_r_type);
25411 }
6c43fab6
RE
25412}
25413
c19d1205
ZW
25414/* Translate internal representation of relocation info to BFD target
25415 format. */
a737bd4d 25416
c19d1205 25417arelent *
00a97672 25418tc_gen_reloc (asection *section, fixS *fixp)
a737bd4d 25419{
c19d1205
ZW
25420 arelent * reloc;
25421 bfd_reloc_code_real_type code;
a737bd4d 25422
325801bd 25423 reloc = XNEW (arelent);
a737bd4d 25424
325801bd 25425 reloc->sym_ptr_ptr = XNEW (asymbol *);
c19d1205
ZW
25426 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
25427 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
a737bd4d 25428
2fc8bdac 25429 if (fixp->fx_pcrel)
00a97672
RS
25430 {
25431 if (section->use_rela_p)
25432 fixp->fx_offset -= md_pcrel_from_section (fixp, section);
25433 else
25434 fixp->fx_offset = reloc->address;
25435 }
c19d1205 25436 reloc->addend = fixp->fx_offset;
a737bd4d 25437
c19d1205 25438 switch (fixp->fx_r_type)
a737bd4d 25439 {
c19d1205
ZW
25440 case BFD_RELOC_8:
25441 if (fixp->fx_pcrel)
25442 {
25443 code = BFD_RELOC_8_PCREL;
25444 break;
25445 }
1a0670f3 25446 /* Fall through. */
a737bd4d 25447
c19d1205
ZW
25448 case BFD_RELOC_16:
25449 if (fixp->fx_pcrel)
25450 {
25451 code = BFD_RELOC_16_PCREL;
25452 break;
25453 }
1a0670f3 25454 /* Fall through. */
6c43fab6 25455
c19d1205
ZW
25456 case BFD_RELOC_32:
25457 if (fixp->fx_pcrel)
25458 {
25459 code = BFD_RELOC_32_PCREL;
25460 break;
25461 }
1a0670f3 25462 /* Fall through. */
a737bd4d 25463
b6895b4f
PB
25464 case BFD_RELOC_ARM_MOVW:
25465 if (fixp->fx_pcrel)
25466 {
25467 code = BFD_RELOC_ARM_MOVW_PCREL;
25468 break;
25469 }
1a0670f3 25470 /* Fall through. */
b6895b4f
PB
25471
25472 case BFD_RELOC_ARM_MOVT:
25473 if (fixp->fx_pcrel)
25474 {
25475 code = BFD_RELOC_ARM_MOVT_PCREL;
25476 break;
25477 }
1a0670f3 25478 /* Fall through. */
b6895b4f
PB
25479
25480 case BFD_RELOC_ARM_THUMB_MOVW:
25481 if (fixp->fx_pcrel)
25482 {
25483 code = BFD_RELOC_ARM_THUMB_MOVW_PCREL;
25484 break;
25485 }
1a0670f3 25486 /* Fall through. */
b6895b4f
PB
25487
25488 case BFD_RELOC_ARM_THUMB_MOVT:
25489 if (fixp->fx_pcrel)
25490 {
25491 code = BFD_RELOC_ARM_THUMB_MOVT_PCREL;
25492 break;
25493 }
1a0670f3 25494 /* Fall through. */
b6895b4f 25495
c19d1205
ZW
25496 case BFD_RELOC_NONE:
25497 case BFD_RELOC_ARM_PCREL_BRANCH:
25498 case BFD_RELOC_ARM_PCREL_BLX:
25499 case BFD_RELOC_RVA:
25500 case BFD_RELOC_THUMB_PCREL_BRANCH7:
25501 case BFD_RELOC_THUMB_PCREL_BRANCH9:
25502 case BFD_RELOC_THUMB_PCREL_BRANCH12:
25503 case BFD_RELOC_THUMB_PCREL_BRANCH20:
25504 case BFD_RELOC_THUMB_PCREL_BRANCH23:
25505 case BFD_RELOC_THUMB_PCREL_BRANCH25:
c19d1205
ZW
25506 case BFD_RELOC_VTABLE_ENTRY:
25507 case BFD_RELOC_VTABLE_INHERIT:
f0927246
NC
25508#ifdef TE_PE
25509 case BFD_RELOC_32_SECREL:
25510#endif
c19d1205
ZW
25511 code = fixp->fx_r_type;
25512 break;
a737bd4d 25513
00adf2d4
JB
25514 case BFD_RELOC_THUMB_PCREL_BLX:
25515#ifdef OBJ_ELF
25516 if (EF_ARM_EABI_VERSION (meabi_flags) >= EF_ARM_EABI_VER4)
25517 code = BFD_RELOC_THUMB_PCREL_BRANCH23;
25518 else
25519#endif
25520 code = BFD_RELOC_THUMB_PCREL_BLX;
25521 break;
25522
c19d1205
ZW
25523 case BFD_RELOC_ARM_LITERAL:
25524 case BFD_RELOC_ARM_HWLITERAL:
25525 /* If this is called then the a literal has
25526 been referenced across a section boundary. */
25527 as_bad_where (fixp->fx_file, fixp->fx_line,
25528 _("literal referenced across section boundary"));
25529 return NULL;
a737bd4d 25530
c19d1205 25531#ifdef OBJ_ELF
0855e32b
NS
25532 case BFD_RELOC_ARM_TLS_CALL:
25533 case BFD_RELOC_ARM_THM_TLS_CALL:
25534 case BFD_RELOC_ARM_TLS_DESCSEQ:
25535 case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
c19d1205
ZW
25536 case BFD_RELOC_ARM_GOT32:
25537 case BFD_RELOC_ARM_GOTOFF:
b43420e6 25538 case BFD_RELOC_ARM_GOT_PREL:
c19d1205
ZW
25539 case BFD_RELOC_ARM_PLT32:
25540 case BFD_RELOC_ARM_TARGET1:
25541 case BFD_RELOC_ARM_ROSEGREL32:
25542 case BFD_RELOC_ARM_SBREL32:
25543 case BFD_RELOC_ARM_PREL31:
25544 case BFD_RELOC_ARM_TARGET2:
c19d1205 25545 case BFD_RELOC_ARM_TLS_LDO32:
39b41c9c
PB
25546 case BFD_RELOC_ARM_PCREL_CALL:
25547 case BFD_RELOC_ARM_PCREL_JUMP:
4962c51a
MS
25548 case BFD_RELOC_ARM_ALU_PC_G0_NC:
25549 case BFD_RELOC_ARM_ALU_PC_G0:
25550 case BFD_RELOC_ARM_ALU_PC_G1_NC:
25551 case BFD_RELOC_ARM_ALU_PC_G1:
25552 case BFD_RELOC_ARM_ALU_PC_G2:
25553 case BFD_RELOC_ARM_LDR_PC_G0:
25554 case BFD_RELOC_ARM_LDR_PC_G1:
25555 case BFD_RELOC_ARM_LDR_PC_G2:
25556 case BFD_RELOC_ARM_LDRS_PC_G0:
25557 case BFD_RELOC_ARM_LDRS_PC_G1:
25558 case BFD_RELOC_ARM_LDRS_PC_G2:
25559 case BFD_RELOC_ARM_LDC_PC_G0:
25560 case BFD_RELOC_ARM_LDC_PC_G1:
25561 case BFD_RELOC_ARM_LDC_PC_G2:
25562 case BFD_RELOC_ARM_ALU_SB_G0_NC:
25563 case BFD_RELOC_ARM_ALU_SB_G0:
25564 case BFD_RELOC_ARM_ALU_SB_G1_NC:
25565 case BFD_RELOC_ARM_ALU_SB_G1:
25566 case BFD_RELOC_ARM_ALU_SB_G2:
25567 case BFD_RELOC_ARM_LDR_SB_G0:
25568 case BFD_RELOC_ARM_LDR_SB_G1:
25569 case BFD_RELOC_ARM_LDR_SB_G2:
25570 case BFD_RELOC_ARM_LDRS_SB_G0:
25571 case BFD_RELOC_ARM_LDRS_SB_G1:
25572 case BFD_RELOC_ARM_LDRS_SB_G2:
25573 case BFD_RELOC_ARM_LDC_SB_G0:
25574 case BFD_RELOC_ARM_LDC_SB_G1:
25575 case BFD_RELOC_ARM_LDC_SB_G2:
845b51d6 25576 case BFD_RELOC_ARM_V4BX:
72d98d16
MG
25577 case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
25578 case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
25579 case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
25580 case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
188fd7ae
CL
25581 case BFD_RELOC_ARM_GOTFUNCDESC:
25582 case BFD_RELOC_ARM_GOTOFFFUNCDESC:
25583 case BFD_RELOC_ARM_FUNCDESC:
e5d6e09e 25584 case BFD_RELOC_ARM_THUMB_BF17:
1caf72a5 25585 case BFD_RELOC_ARM_THUMB_BF19:
1889da70 25586 case BFD_RELOC_ARM_THUMB_BF13:
c19d1205
ZW
25587 code = fixp->fx_r_type;
25588 break;
a737bd4d 25589
0855e32b 25590 case BFD_RELOC_ARM_TLS_GOTDESC:
c19d1205 25591 case BFD_RELOC_ARM_TLS_GD32:
5c5a4843 25592 case BFD_RELOC_ARM_TLS_GD32_FDPIC:
75c11999 25593 case BFD_RELOC_ARM_TLS_LE32:
c19d1205 25594 case BFD_RELOC_ARM_TLS_IE32:
5c5a4843 25595 case BFD_RELOC_ARM_TLS_IE32_FDPIC:
c19d1205 25596 case BFD_RELOC_ARM_TLS_LDM32:
5c5a4843 25597 case BFD_RELOC_ARM_TLS_LDM32_FDPIC:
c19d1205
ZW
25598 /* BFD will include the symbol's address in the addend.
25599 But we don't want that, so subtract it out again here. */
25600 if (!S_IS_COMMON (fixp->fx_addsy))
25601 reloc->addend -= (*reloc->sym_ptr_ptr)->value;
25602 code = fixp->fx_r_type;
25603 break;
25604#endif
a737bd4d 25605
c19d1205
ZW
25606 case BFD_RELOC_ARM_IMMEDIATE:
25607 as_bad_where (fixp->fx_file, fixp->fx_line,
25608 _("internal relocation (type: IMMEDIATE) not fixed up"));
25609 return NULL;
a737bd4d 25610
c19d1205
ZW
25611 case BFD_RELOC_ARM_ADRL_IMMEDIATE:
25612 as_bad_where (fixp->fx_file, fixp->fx_line,
25613 _("ADRL used for a symbol not defined in the same file"));
25614 return NULL;
a737bd4d 25615
e12437dc 25616 case BFD_RELOC_THUMB_PCREL_BRANCH5:
f6b2b12d 25617 case BFD_RELOC_THUMB_PCREL_BFCSEL:
60f993ce 25618 case BFD_RELOC_ARM_THUMB_LOOP12:
e12437dc
AV
25619 as_bad_where (fixp->fx_file, fixp->fx_line,
25620 _("%s used for a symbol not defined in the same file"),
25621 bfd_get_reloc_code_name (fixp->fx_r_type));
25622 return NULL;
25623
c19d1205 25624 case BFD_RELOC_ARM_OFFSET_IMM:
00a97672
RS
25625 if (section->use_rela_p)
25626 {
25627 code = fixp->fx_r_type;
25628 break;
25629 }
25630
c19d1205
ZW
25631 if (fixp->fx_addsy != NULL
25632 && !S_IS_DEFINED (fixp->fx_addsy)
25633 && S_IS_LOCAL (fixp->fx_addsy))
a737bd4d 25634 {
c19d1205
ZW
25635 as_bad_where (fixp->fx_file, fixp->fx_line,
25636 _("undefined local label `%s'"),
25637 S_GET_NAME (fixp->fx_addsy));
25638 return NULL;
a737bd4d
NC
25639 }
25640
c19d1205
ZW
25641 as_bad_where (fixp->fx_file, fixp->fx_line,
25642 _("internal_relocation (type: OFFSET_IMM) not fixed up"));
25643 return NULL;
a737bd4d 25644
c19d1205
ZW
25645 default:
25646 {
e0471c16 25647 const char * type;
6c43fab6 25648
c19d1205
ZW
25649 switch (fixp->fx_r_type)
25650 {
25651 case BFD_RELOC_NONE: type = "NONE"; break;
25652 case BFD_RELOC_ARM_OFFSET_IMM8: type = "OFFSET_IMM8"; break;
25653 case BFD_RELOC_ARM_SHIFT_IMM: type = "SHIFT_IMM"; break;
3eb17e6b 25654 case BFD_RELOC_ARM_SMC: type = "SMC"; break;
c19d1205
ZW
25655 case BFD_RELOC_ARM_SWI: type = "SWI"; break;
25656 case BFD_RELOC_ARM_MULTI: type = "MULTI"; break;
25657 case BFD_RELOC_ARM_CP_OFF_IMM: type = "CP_OFF_IMM"; break;
db187cb9 25658 case BFD_RELOC_ARM_T32_OFFSET_IMM: type = "T32_OFFSET_IMM"; break;
8f06b2d8 25659 case BFD_RELOC_ARM_T32_CP_OFF_IMM: type = "T32_CP_OFF_IMM"; break;
c19d1205
ZW
25660 case BFD_RELOC_ARM_THUMB_ADD: type = "THUMB_ADD"; break;
25661 case BFD_RELOC_ARM_THUMB_SHIFT: type = "THUMB_SHIFT"; break;
25662 case BFD_RELOC_ARM_THUMB_IMM: type = "THUMB_IMM"; break;
25663 case BFD_RELOC_ARM_THUMB_OFFSET: type = "THUMB_OFFSET"; break;
25664 default: type = _("<unknown>"); break;
25665 }
25666 as_bad_where (fixp->fx_file, fixp->fx_line,
25667 _("cannot represent %s relocation in this object file format"),
25668 type);
25669 return NULL;
25670 }
a737bd4d 25671 }
6c43fab6 25672
c19d1205
ZW
25673#ifdef OBJ_ELF
25674 if ((code == BFD_RELOC_32_PCREL || code == BFD_RELOC_32)
25675 && GOT_symbol
25676 && fixp->fx_addsy == GOT_symbol)
25677 {
25678 code = BFD_RELOC_ARM_GOTPC;
25679 reloc->addend = fixp->fx_offset = reloc->address;
25680 }
25681#endif
6c43fab6 25682
c19d1205 25683 reloc->howto = bfd_reloc_type_lookup (stdoutput, code);
6c43fab6 25684
c19d1205
ZW
25685 if (reloc->howto == NULL)
25686 {
25687 as_bad_where (fixp->fx_file, fixp->fx_line,
25688 _("cannot represent %s relocation in this object file format"),
25689 bfd_get_reloc_code_name (code));
25690 return NULL;
25691 }
6c43fab6 25692
c19d1205
ZW
25693 /* HACK: Since arm ELF uses Rel instead of Rela, encode the
25694 vtable entry to be used in the relocation's section offset. */
25695 if (fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
25696 reloc->address = fixp->fx_offset;
6c43fab6 25697
c19d1205 25698 return reloc;
6c43fab6
RE
25699}
25700
c19d1205 25701/* This fix_new is called by cons via TC_CONS_FIX_NEW. */
6c43fab6 25702
c19d1205
ZW
25703void
25704cons_fix_new_arm (fragS * frag,
25705 int where,
25706 int size,
62ebcb5c
AM
25707 expressionS * exp,
25708 bfd_reloc_code_real_type reloc)
6c43fab6 25709{
c19d1205 25710 int pcrel = 0;
6c43fab6 25711
c19d1205
ZW
25712 /* Pick a reloc.
25713 FIXME: @@ Should look at CPU word size. */
25714 switch (size)
25715 {
25716 case 1:
62ebcb5c 25717 reloc = BFD_RELOC_8;
c19d1205
ZW
25718 break;
25719 case 2:
62ebcb5c 25720 reloc = BFD_RELOC_16;
c19d1205
ZW
25721 break;
25722 case 4:
25723 default:
62ebcb5c 25724 reloc = BFD_RELOC_32;
c19d1205
ZW
25725 break;
25726 case 8:
62ebcb5c 25727 reloc = BFD_RELOC_64;
c19d1205
ZW
25728 break;
25729 }
6c43fab6 25730
f0927246
NC
25731#ifdef TE_PE
25732 if (exp->X_op == O_secrel)
25733 {
25734 exp->X_op = O_symbol;
62ebcb5c 25735 reloc = BFD_RELOC_32_SECREL;
f0927246
NC
25736 }
25737#endif
25738
62ebcb5c 25739 fix_new_exp (frag, where, size, exp, pcrel, reloc);
c19d1205 25740}
6c43fab6 25741
4343666d 25742#if defined (OBJ_COFF)
c19d1205
ZW
25743void
25744arm_validate_fix (fixS * fixP)
6c43fab6 25745{
c19d1205
ZW
25746 /* If the destination of the branch is a defined symbol which does not have
25747 the THUMB_FUNC attribute, then we must be calling a function which has
25748 the (interfacearm) attribute. We look for the Thumb entry point to that
25749 function and change the branch to refer to that function instead. */
25750 if (fixP->fx_r_type == BFD_RELOC_THUMB_PCREL_BRANCH23
25751 && fixP->fx_addsy != NULL
25752 && S_IS_DEFINED (fixP->fx_addsy)
25753 && ! THUMB_IS_FUNC (fixP->fx_addsy))
6c43fab6 25754 {
c19d1205 25755 fixP->fx_addsy = find_real_start (fixP->fx_addsy);
6c43fab6 25756 }
c19d1205
ZW
25757}
25758#endif
6c43fab6 25759
267bf995 25760
c19d1205
ZW
25761int
25762arm_force_relocation (struct fix * fixp)
25763{
25764#if defined (OBJ_COFF) && defined (TE_PE)
25765 if (fixp->fx_r_type == BFD_RELOC_RVA)
25766 return 1;
25767#endif
6c43fab6 25768
267bf995
RR
25769 /* In case we have a call or a branch to a function in ARM ISA mode from
25770 a thumb function or vice-versa force the relocation. These relocations
25771 are cleared off for some cores that might have blx and simple transformations
25772 are possible. */
25773
25774#ifdef OBJ_ELF
25775 switch (fixp->fx_r_type)
25776 {
25777 case BFD_RELOC_ARM_PCREL_JUMP:
25778 case BFD_RELOC_ARM_PCREL_CALL:
25779 case BFD_RELOC_THUMB_PCREL_BLX:
25780 if (THUMB_IS_FUNC (fixp->fx_addsy))
25781 return 1;
25782 break;
25783
25784 case BFD_RELOC_ARM_PCREL_BLX:
25785 case BFD_RELOC_THUMB_PCREL_BRANCH25:
25786 case BFD_RELOC_THUMB_PCREL_BRANCH20:
25787 case BFD_RELOC_THUMB_PCREL_BRANCH23:
25788 if (ARM_IS_FUNC (fixp->fx_addsy))
25789 return 1;
25790 break;
25791
25792 default:
25793 break;
25794 }
25795#endif
25796
b5884301
PB
25797 /* Resolve these relocations even if the symbol is extern or weak.
25798 Technically this is probably wrong due to symbol preemption.
25799 In practice these relocations do not have enough range to be useful
25800 at dynamic link time, and some code (e.g. in the Linux kernel)
25801 expects these references to be resolved. */
c19d1205
ZW
25802 if (fixp->fx_r_type == BFD_RELOC_ARM_IMMEDIATE
25803 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM
b5884301 25804 || fixp->fx_r_type == BFD_RELOC_ARM_OFFSET_IMM8
0110f2b8 25805 || fixp->fx_r_type == BFD_RELOC_ARM_ADRL_IMMEDIATE
b5884301
PB
25806 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM
25807 || fixp->fx_r_type == BFD_RELOC_ARM_CP_OFF_IMM_S2
25808 || fixp->fx_r_type == BFD_RELOC_ARM_THUMB_OFFSET
16805f35 25809 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM
0110f2b8
PB
25810 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE
25811 || fixp->fx_r_type == BFD_RELOC_ARM_T32_IMM12
b5884301
PB
25812 || fixp->fx_r_type == BFD_RELOC_ARM_T32_OFFSET_IMM
25813 || fixp->fx_r_type == BFD_RELOC_ARM_T32_ADD_PC12
25814 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM
25815 || fixp->fx_r_type == BFD_RELOC_ARM_T32_CP_OFF_IMM_S2)
c19d1205 25816 return 0;
a737bd4d 25817
4962c51a
MS
25818 /* Always leave these relocations for the linker. */
25819 if ((fixp->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
25820 && fixp->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
25821 || fixp->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
25822 return 1;
25823
f0291e4c
PB
25824 /* Always generate relocations against function symbols. */
25825 if (fixp->fx_r_type == BFD_RELOC_32
25826 && fixp->fx_addsy
25827 && (symbol_get_bfdsym (fixp->fx_addsy)->flags & BSF_FUNCTION))
25828 return 1;
25829
c19d1205 25830 return generic_force_reloc (fixp);
404ff6b5
AH
25831}
25832
0ffdc86c 25833#if defined (OBJ_ELF) || defined (OBJ_COFF)
e28387c3
PB
25834/* Relocations against function names must be left unadjusted,
25835 so that the linker can use this information to generate interworking
25836 stubs. The MIPS version of this function
c19d1205
ZW
25837 also prevents relocations that are mips-16 specific, but I do not
25838 know why it does this.
404ff6b5 25839
c19d1205
ZW
25840 FIXME:
25841 There is one other problem that ought to be addressed here, but
25842 which currently is not: Taking the address of a label (rather
25843 than a function) and then later jumping to that address. Such
25844 addresses also ought to have their bottom bit set (assuming that
25845 they reside in Thumb code), but at the moment they will not. */
404ff6b5 25846
c19d1205
ZW
25847bfd_boolean
25848arm_fix_adjustable (fixS * fixP)
404ff6b5 25849{
c19d1205
ZW
25850 if (fixP->fx_addsy == NULL)
25851 return 1;
404ff6b5 25852
e28387c3
PB
25853 /* Preserve relocations against symbols with function type. */
25854 if (symbol_get_bfdsym (fixP->fx_addsy)->flags & BSF_FUNCTION)
c921be7d 25855 return FALSE;
e28387c3 25856
c19d1205
ZW
25857 if (THUMB_IS_FUNC (fixP->fx_addsy)
25858 && fixP->fx_subsy == NULL)
c921be7d 25859 return FALSE;
a737bd4d 25860
c19d1205
ZW
25861 /* We need the symbol name for the VTABLE entries. */
25862 if ( fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
25863 || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
c921be7d 25864 return FALSE;
404ff6b5 25865
c19d1205
ZW
25866 /* Don't allow symbols to be discarded on GOT related relocs. */
25867 if (fixP->fx_r_type == BFD_RELOC_ARM_PLT32
25868 || fixP->fx_r_type == BFD_RELOC_ARM_GOT32
25869 || fixP->fx_r_type == BFD_RELOC_ARM_GOTOFF
25870 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32
5c5a4843 25871 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GD32_FDPIC
c19d1205
ZW
25872 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LE32
25873 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
5c5a4843 25874 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32_FDPIC
c19d1205 25875 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
5c5a4843 25876 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32_FDPIC
c19d1205 25877 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
0855e32b
NS
25878 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
25879 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
25880 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
25881 || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
25882 || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
c19d1205 25883 || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
c921be7d 25884 return FALSE;
a737bd4d 25885
4962c51a
MS
25886 /* Similarly for group relocations. */
25887 if ((fixP->fx_r_type >= BFD_RELOC_ARM_ALU_PC_G0_NC
25888 && fixP->fx_r_type <= BFD_RELOC_ARM_LDC_SB_G2)
25889 || fixP->fx_r_type == BFD_RELOC_ARM_LDR_PC_G0)
c921be7d 25890 return FALSE;
4962c51a 25891
79947c54
CD
25892 /* MOVW/MOVT REL relocations have limited offsets, so keep the symbols. */
25893 if (fixP->fx_r_type == BFD_RELOC_ARM_MOVW
25894 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT
25895 || fixP->fx_r_type == BFD_RELOC_ARM_MOVW_PCREL
25896 || fixP->fx_r_type == BFD_RELOC_ARM_MOVT_PCREL
25897 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW
25898 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT
25899 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVW_PCREL
25900 || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
c921be7d 25901 return FALSE;
79947c54 25902
72d98d16
MG
25903 /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
25904 offsets, so keep these symbols. */
25905 if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
25906 && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
25907 return FALSE;
25908
c921be7d 25909 return TRUE;
a737bd4d 25910}
0ffdc86c
NC
25911#endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
25912
25913#ifdef OBJ_ELF
c19d1205
ZW
25914const char *
25915elf32_arm_target_format (void)
404ff6b5 25916{
c19d1205
ZW
25917#ifdef TE_SYMBIAN
25918 return (target_big_endian
25919 ? "elf32-bigarm-symbian"
25920 : "elf32-littlearm-symbian");
25921#elif defined (TE_VXWORKS)
25922 return (target_big_endian
25923 ? "elf32-bigarm-vxworks"
25924 : "elf32-littlearm-vxworks");
b38cadfb
NC
25925#elif defined (TE_NACL)
25926 return (target_big_endian
25927 ? "elf32-bigarm-nacl"
25928 : "elf32-littlearm-nacl");
c19d1205 25929#else
18a20338
CL
25930 if (arm_fdpic)
25931 {
25932 if (target_big_endian)
25933 return "elf32-bigarm-fdpic";
25934 else
25935 return "elf32-littlearm-fdpic";
25936 }
c19d1205 25937 else
18a20338
CL
25938 {
25939 if (target_big_endian)
25940 return "elf32-bigarm";
25941 else
25942 return "elf32-littlearm";
25943 }
c19d1205 25944#endif
404ff6b5
AH
25945}
25946
c19d1205
ZW
25947void
25948armelf_frob_symbol (symbolS * symp,
25949 int * puntp)
404ff6b5 25950{
c19d1205
ZW
25951 elf_frob_symbol (symp, puntp);
25952}
25953#endif
404ff6b5 25954
c19d1205 25955/* MD interface: Finalization. */
a737bd4d 25956
c19d1205
ZW
25957void
25958arm_cleanup (void)
25959{
25960 literal_pool * pool;
a737bd4d 25961
e07e6e58
NC
25962 /* Ensure that all the IT blocks are properly closed. */
25963 check_it_blocks_finished ();
25964
c19d1205
ZW
25965 for (pool = list_of_pools; pool; pool = pool->next)
25966 {
5f4273c7 25967 /* Put it at the end of the relevant section. */
c19d1205
ZW
25968 subseg_set (pool->section, pool->sub_section);
25969#ifdef OBJ_ELF
25970 arm_elf_change_section ();
25971#endif
25972 s_ltorg (0);
25973 }
404ff6b5
AH
25974}
25975
cd000bff
DJ
25976#ifdef OBJ_ELF
25977/* Remove any excess mapping symbols generated for alignment frags in
25978 SEC. We may have created a mapping symbol before a zero byte
25979 alignment; remove it if there's a mapping symbol after the
25980 alignment. */
25981static void
25982check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED, asection *sec,
25983 void *dummy ATTRIBUTE_UNUSED)
25984{
25985 segment_info_type *seginfo = seg_info (sec);
25986 fragS *fragp;
25987
25988 if (seginfo == NULL || seginfo->frchainP == NULL)
25989 return;
25990
25991 for (fragp = seginfo->frchainP->frch_root;
25992 fragp != NULL;
25993 fragp = fragp->fr_next)
25994 {
25995 symbolS *sym = fragp->tc_frag_data.last_map;
25996 fragS *next = fragp->fr_next;
25997
25998 /* Variable-sized frags have been converted to fixed size by
25999 this point. But if this was variable-sized to start with,
26000 there will be a fixed-size frag after it. So don't handle
26001 next == NULL. */
26002 if (sym == NULL || next == NULL)
26003 continue;
26004
26005 if (S_GET_VALUE (sym) < next->fr_address)
26006 /* Not at the end of this frag. */
26007 continue;
26008 know (S_GET_VALUE (sym) == next->fr_address);
26009
26010 do
26011 {
26012 if (next->tc_frag_data.first_map != NULL)
26013 {
26014 /* Next frag starts with a mapping symbol. Discard this
26015 one. */
26016 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
26017 break;
26018 }
26019
26020 if (next->fr_next == NULL)
26021 {
26022 /* This mapping symbol is at the end of the section. Discard
26023 it. */
26024 know (next->fr_fix == 0 && next->fr_var == 0);
26025 symbol_remove (sym, &symbol_rootP, &symbol_lastP);
26026 break;
26027 }
26028
26029 /* As long as we have empty frags without any mapping symbols,
26030 keep looking. */
26031 /* If the next frag is non-empty and does not start with a
26032 mapping symbol, then this mapping symbol is required. */
26033 if (next->fr_address != next->fr_next->fr_address)
26034 break;
26035
26036 next = next->fr_next;
26037 }
26038 while (next != NULL);
26039 }
26040}
26041#endif
26042
c19d1205
ZW
26043/* Adjust the symbol table. This marks Thumb symbols as distinct from
26044 ARM ones. */
404ff6b5 26045
c19d1205
ZW
26046void
26047arm_adjust_symtab (void)
404ff6b5 26048{
c19d1205
ZW
26049#ifdef OBJ_COFF
26050 symbolS * sym;
404ff6b5 26051
c19d1205
ZW
26052 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
26053 {
26054 if (ARM_IS_THUMB (sym))
26055 {
26056 if (THUMB_IS_FUNC (sym))
26057 {
26058 /* Mark the symbol as a Thumb function. */
26059 if ( S_GET_STORAGE_CLASS (sym) == C_STAT
26060 || S_GET_STORAGE_CLASS (sym) == C_LABEL) /* This can happen! */
26061 S_SET_STORAGE_CLASS (sym, C_THUMBSTATFUNC);
404ff6b5 26062
c19d1205
ZW
26063 else if (S_GET_STORAGE_CLASS (sym) == C_EXT)
26064 S_SET_STORAGE_CLASS (sym, C_THUMBEXTFUNC);
26065 else
26066 as_bad (_("%s: unexpected function type: %d"),
26067 S_GET_NAME (sym), S_GET_STORAGE_CLASS (sym));
26068 }
26069 else switch (S_GET_STORAGE_CLASS (sym))
26070 {
26071 case C_EXT:
26072 S_SET_STORAGE_CLASS (sym, C_THUMBEXT);
26073 break;
26074 case C_STAT:
26075 S_SET_STORAGE_CLASS (sym, C_THUMBSTAT);
26076 break;
26077 case C_LABEL:
26078 S_SET_STORAGE_CLASS (sym, C_THUMBLABEL);
26079 break;
26080 default:
26081 /* Do nothing. */
26082 break;
26083 }
26084 }
a737bd4d 26085
c19d1205
ZW
26086 if (ARM_IS_INTERWORK (sym))
26087 coffsymbol (symbol_get_bfdsym (sym))->native->u.syment.n_flags = 0xFF;
404ff6b5 26088 }
c19d1205
ZW
26089#endif
26090#ifdef OBJ_ELF
26091 symbolS * sym;
26092 char bind;
404ff6b5 26093
c19d1205 26094 for (sym = symbol_rootP; sym != NULL; sym = symbol_next (sym))
404ff6b5 26095 {
c19d1205
ZW
26096 if (ARM_IS_THUMB (sym))
26097 {
26098 elf_symbol_type * elf_sym;
404ff6b5 26099
c19d1205
ZW
26100 elf_sym = elf_symbol (symbol_get_bfdsym (sym));
26101 bind = ELF_ST_BIND (elf_sym->internal_elf_sym.st_info);
404ff6b5 26102
b0796911
PB
26103 if (! bfd_is_arm_special_symbol_name (elf_sym->symbol.name,
26104 BFD_ARM_SPECIAL_SYM_TYPE_ANY))
c19d1205
ZW
26105 {
26106 /* If it's a .thumb_func, declare it as so,
26107 otherwise tag label as .code 16. */
26108 if (THUMB_IS_FUNC (sym))
39d911fc
TP
26109 ARM_SET_SYM_BRANCH_TYPE (elf_sym->internal_elf_sym.st_target_internal,
26110 ST_BRANCH_TO_THUMB);
3ba67470 26111 else if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
c19d1205
ZW
26112 elf_sym->internal_elf_sym.st_info =
26113 ELF_ST_INFO (bind, STT_ARM_16BIT);
26114 }
26115 }
26116 }
cd000bff
DJ
26117
26118 /* Remove any overlapping mapping symbols generated by alignment frags. */
26119 bfd_map_over_sections (stdoutput, check_mapping_symbols, (char *) 0);
709001e9
MM
26120 /* Now do generic ELF adjustments. */
26121 elf_adjust_symtab ();
c19d1205 26122#endif
404ff6b5
AH
26123}
26124
c19d1205 26125/* MD interface: Initialization. */
404ff6b5 26126
a737bd4d 26127static void
c19d1205 26128set_constant_flonums (void)
a737bd4d 26129{
c19d1205 26130 int i;
404ff6b5 26131
c19d1205
ZW
26132 for (i = 0; i < NUM_FLOAT_VALS; i++)
26133 if (atof_ieee ((char *) fp_const[i], 'x', fp_values[i]) == NULL)
26134 abort ();
a737bd4d 26135}
404ff6b5 26136
3e9e4fcf
JB
26137/* Auto-select Thumb mode if it's the only available instruction set for the
26138 given architecture. */
26139
26140static void
26141autoselect_thumb_from_cpu_variant (void)
26142{
26143 if (!ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v1))
26144 opcode_select (16);
26145}
26146
c19d1205
ZW
26147void
26148md_begin (void)
a737bd4d 26149{
c19d1205
ZW
26150 unsigned mach;
26151 unsigned int i;
404ff6b5 26152
c19d1205
ZW
26153 if ( (arm_ops_hsh = hash_new ()) == NULL
26154 || (arm_cond_hsh = hash_new ()) == NULL
26155 || (arm_shift_hsh = hash_new ()) == NULL
26156 || (arm_psr_hsh = hash_new ()) == NULL
62b3e311 26157 || (arm_v7m_psr_hsh = hash_new ()) == NULL
c19d1205 26158 || (arm_reg_hsh = hash_new ()) == NULL
62b3e311
PB
26159 || (arm_reloc_hsh = hash_new ()) == NULL
26160 || (arm_barrier_opt_hsh = hash_new ()) == NULL)
c19d1205
ZW
26161 as_fatal (_("virtual memory exhausted"));
26162
26163 for (i = 0; i < sizeof (insns) / sizeof (struct asm_opcode); i++)
d3ce72d0 26164 hash_insert (arm_ops_hsh, insns[i].template_name, (void *) (insns + i));
c19d1205 26165 for (i = 0; i < sizeof (conds) / sizeof (struct asm_cond); i++)
d3ce72d0 26166 hash_insert (arm_cond_hsh, conds[i].template_name, (void *) (conds + i));
c19d1205 26167 for (i = 0; i < sizeof (shift_names) / sizeof (struct asm_shift_name); i++)
5a49b8ac 26168 hash_insert (arm_shift_hsh, shift_names[i].name, (void *) (shift_names + i));
c19d1205 26169 for (i = 0; i < sizeof (psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 26170 hash_insert (arm_psr_hsh, psrs[i].template_name, (void *) (psrs + i));
62b3e311 26171 for (i = 0; i < sizeof (v7m_psrs) / sizeof (struct asm_psr); i++)
d3ce72d0 26172 hash_insert (arm_v7m_psr_hsh, v7m_psrs[i].template_name,
477330fc 26173 (void *) (v7m_psrs + i));
c19d1205 26174 for (i = 0; i < sizeof (reg_names) / sizeof (struct reg_entry); i++)
5a49b8ac 26175 hash_insert (arm_reg_hsh, reg_names[i].name, (void *) (reg_names + i));
62b3e311
PB
26176 for (i = 0;
26177 i < sizeof (barrier_opt_names) / sizeof (struct asm_barrier_opt);
26178 i++)
d3ce72d0 26179 hash_insert (arm_barrier_opt_hsh, barrier_opt_names[i].template_name,
5a49b8ac 26180 (void *) (barrier_opt_names + i));
c19d1205 26181#ifdef OBJ_ELF
3da1d841
NC
26182 for (i = 0; i < ARRAY_SIZE (reloc_names); i++)
26183 {
26184 struct reloc_entry * entry = reloc_names + i;
26185
26186 if (arm_is_eabi() && entry->reloc == BFD_RELOC_ARM_PLT32)
26187 /* This makes encode_branch() use the EABI versions of this relocation. */
26188 entry->reloc = BFD_RELOC_UNUSED;
26189
26190 hash_insert (arm_reloc_hsh, entry->name, (void *) entry);
26191 }
c19d1205
ZW
26192#endif
26193
26194 set_constant_flonums ();
404ff6b5 26195
c19d1205
ZW
26196 /* Set the cpu variant based on the command-line options. We prefer
26197 -mcpu= over -march= if both are set (as for GCC); and we prefer
26198 -mfpu= over any other way of setting the floating point unit.
26199 Use of legacy options with new options are faulted. */
e74cfd16 26200 if (legacy_cpu)
404ff6b5 26201 {
e74cfd16 26202 if (mcpu_cpu_opt || march_cpu_opt)
c19d1205
ZW
26203 as_bad (_("use of old and new-style options to set CPU type"));
26204
4d354d8b 26205 selected_arch = *legacy_cpu;
404ff6b5 26206 }
4d354d8b
TP
26207 else if (mcpu_cpu_opt)
26208 {
26209 selected_arch = *mcpu_cpu_opt;
26210 selected_ext = *mcpu_ext_opt;
26211 }
26212 else if (march_cpu_opt)
c168ce07 26213 {
4d354d8b
TP
26214 selected_arch = *march_cpu_opt;
26215 selected_ext = *march_ext_opt;
c168ce07 26216 }
4d354d8b 26217 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
404ff6b5 26218
e74cfd16 26219 if (legacy_fpu)
c19d1205 26220 {
e74cfd16 26221 if (mfpu_opt)
c19d1205 26222 as_bad (_("use of old and new-style options to set FPU type"));
03b1477f 26223
4d354d8b 26224 selected_fpu = *legacy_fpu;
03b1477f 26225 }
4d354d8b
TP
26226 else if (mfpu_opt)
26227 selected_fpu = *mfpu_opt;
26228 else
03b1477f 26229 {
45eb4c1b
NS
26230#if !(defined (EABI_DEFAULT) || defined (TE_LINUX) \
26231 || defined (TE_NetBSD) || defined (TE_VXWORKS))
39c2da32
RE
26232 /* Some environments specify a default FPU. If they don't, infer it
26233 from the processor. */
e74cfd16 26234 if (mcpu_fpu_opt)
4d354d8b 26235 selected_fpu = *mcpu_fpu_opt;
e7da50fa 26236 else if (march_fpu_opt)
4d354d8b 26237 selected_fpu = *march_fpu_opt;
39c2da32 26238#else
4d354d8b 26239 selected_fpu = fpu_default;
39c2da32 26240#endif
03b1477f
RE
26241 }
26242
4d354d8b 26243 if (ARM_FEATURE_ZERO (selected_fpu))
03b1477f 26244 {
4d354d8b
TP
26245 if (!no_cpu_selected ())
26246 selected_fpu = fpu_default;
03b1477f 26247 else
4d354d8b 26248 selected_fpu = fpu_arch_fpa;
03b1477f
RE
26249 }
26250
ee065d83 26251#ifdef CPU_DEFAULT
4d354d8b 26252 if (ARM_FEATURE_ZERO (selected_arch))
ee065d83 26253 {
4d354d8b
TP
26254 selected_arch = cpu_default;
26255 selected_cpu = selected_arch;
ee065d83 26256 }
4d354d8b 26257 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
e74cfd16 26258#else
4d354d8b
TP
26259 /* Autodection of feature mode: allow all features in cpu_variant but leave
26260 selected_cpu unset. It will be set in aeabi_set_public_attributes ()
26261 after all instruction have been processed and we can decide what CPU
26262 should be selected. */
26263 if (ARM_FEATURE_ZERO (selected_arch))
26264 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
ee065d83 26265 else
4d354d8b 26266 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83 26267#endif
03b1477f 26268
3e9e4fcf
JB
26269 autoselect_thumb_from_cpu_variant ();
26270
e74cfd16 26271 arm_arch_used = thumb_arch_used = arm_arch_none;
ee065d83 26272
f17c130b 26273#if defined OBJ_COFF || defined OBJ_ELF
b99bd4ef 26274 {
7cc69913
NC
26275 unsigned int flags = 0;
26276
26277#if defined OBJ_ELF
26278 flags = meabi_flags;
d507cf36
PB
26279
26280 switch (meabi_flags)
33a392fb 26281 {
d507cf36 26282 case EF_ARM_EABI_UNKNOWN:
7cc69913 26283#endif
d507cf36
PB
26284 /* Set the flags in the private structure. */
26285 if (uses_apcs_26) flags |= F_APCS26;
26286 if (support_interwork) flags |= F_INTERWORK;
26287 if (uses_apcs_float) flags |= F_APCS_FLOAT;
c19d1205 26288 if (pic_code) flags |= F_PIC;
e74cfd16 26289 if (!ARM_CPU_HAS_FEATURE (cpu_variant, fpu_any_hard))
7cc69913
NC
26290 flags |= F_SOFT_FLOAT;
26291
d507cf36
PB
26292 switch (mfloat_abi_opt)
26293 {
26294 case ARM_FLOAT_ABI_SOFT:
26295 case ARM_FLOAT_ABI_SOFTFP:
26296 flags |= F_SOFT_FLOAT;
26297 break;
33a392fb 26298
d507cf36
PB
26299 case ARM_FLOAT_ABI_HARD:
26300 if (flags & F_SOFT_FLOAT)
26301 as_bad (_("hard-float conflicts with specified fpu"));
26302 break;
26303 }
03b1477f 26304
e74cfd16
PB
26305 /* Using pure-endian doubles (even if soft-float). */
26306 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_endian_pure))
7cc69913 26307 flags |= F_VFP_FLOAT;
f17c130b 26308
fde78edd 26309#if defined OBJ_ELF
e74cfd16 26310 if (ARM_CPU_HAS_FEATURE (cpu_variant, fpu_arch_maverick))
d507cf36 26311 flags |= EF_ARM_MAVERICK_FLOAT;
d507cf36
PB
26312 break;
26313
8cb51566 26314 case EF_ARM_EABI_VER4:
3a4a14e9 26315 case EF_ARM_EABI_VER5:
c19d1205 26316 /* No additional flags to set. */
d507cf36
PB
26317 break;
26318
26319 default:
26320 abort ();
26321 }
7cc69913 26322#endif
b99bd4ef
NC
26323 bfd_set_private_flags (stdoutput, flags);
26324
26325 /* We have run out flags in the COFF header to encode the
26326 status of ATPCS support, so instead we create a dummy,
c19d1205 26327 empty, debug section called .arm.atpcs. */
b99bd4ef
NC
26328 if (atpcs)
26329 {
26330 asection * sec;
26331
26332 sec = bfd_make_section (stdoutput, ".arm.atpcs");
26333
26334 if (sec != NULL)
26335 {
26336 bfd_set_section_flags
26337 (stdoutput, sec, SEC_READONLY | SEC_DEBUGGING /* | SEC_HAS_CONTENTS */);
26338 bfd_set_section_size (stdoutput, sec, 0);
26339 bfd_set_section_contents (stdoutput, sec, NULL, 0, 0);
26340 }
26341 }
7cc69913 26342 }
f17c130b 26343#endif
b99bd4ef
NC
26344
26345 /* Record the CPU type as well. */
2d447fca
JM
26346 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt2))
26347 mach = bfd_mach_arm_iWMMXt2;
26348 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_iwmmxt))
e16bb312 26349 mach = bfd_mach_arm_iWMMXt;
e74cfd16 26350 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_xscale))
b99bd4ef 26351 mach = bfd_mach_arm_XScale;
e74cfd16 26352 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_cext_maverick))
fde78edd 26353 mach = bfd_mach_arm_ep9312;
e74cfd16 26354 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5e))
b99bd4ef 26355 mach = bfd_mach_arm_5TE;
e74cfd16 26356 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v5))
b99bd4ef 26357 {
e74cfd16 26358 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
26359 mach = bfd_mach_arm_5T;
26360 else
26361 mach = bfd_mach_arm_5;
26362 }
e74cfd16 26363 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4))
b99bd4ef 26364 {
e74cfd16 26365 if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v4t))
b99bd4ef
NC
26366 mach = bfd_mach_arm_4T;
26367 else
26368 mach = bfd_mach_arm_4;
26369 }
e74cfd16 26370 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3m))
b99bd4ef 26371 mach = bfd_mach_arm_3M;
e74cfd16
PB
26372 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v3))
26373 mach = bfd_mach_arm_3;
26374 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2s))
26375 mach = bfd_mach_arm_2a;
26376 else if (ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v2))
26377 mach = bfd_mach_arm_2;
26378 else
26379 mach = bfd_mach_arm_unknown;
b99bd4ef
NC
26380
26381 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach);
26382}
26383
c19d1205 26384/* Command line processing. */
b99bd4ef 26385
c19d1205
ZW
26386/* md_parse_option
26387 Invocation line includes a switch not recognized by the base assembler.
26388 See if it's a processor-specific option.
b99bd4ef 26389
c19d1205
ZW
26390 This routine is somewhat complicated by the need for backwards
26391 compatibility (since older releases of gcc can't be changed).
26392 The new options try to make the interface as compatible as
26393 possible with GCC.
b99bd4ef 26394
c19d1205 26395 New options (supported) are:
b99bd4ef 26396
c19d1205
ZW
26397 -mcpu=<cpu name> Assemble for selected processor
26398 -march=<architecture name> Assemble for selected architecture
26399 -mfpu=<fpu architecture> Assemble for selected FPU.
26400 -EB/-mbig-endian Big-endian
26401 -EL/-mlittle-endian Little-endian
26402 -k Generate PIC code
26403 -mthumb Start in Thumb mode
26404 -mthumb-interwork Code supports ARM/Thumb interworking
b99bd4ef 26405
278df34e 26406 -m[no-]warn-deprecated Warn about deprecated features
8b2d793c 26407 -m[no-]warn-syms Warn when symbols match instructions
267bf995 26408
c19d1205 26409 For now we will also provide support for:
b99bd4ef 26410
c19d1205
ZW
26411 -mapcs-32 32-bit Program counter
26412 -mapcs-26 26-bit Program counter
26413 -macps-float Floats passed in FP registers
26414 -mapcs-reentrant Reentrant code
26415 -matpcs
26416 (sometime these will probably be replaced with -mapcs=<list of options>
26417 and -matpcs=<list of options>)
b99bd4ef 26418
c19d1205
ZW
26419 The remaining options are only supported for back-wards compatibility.
26420 Cpu variants, the arm part is optional:
26421 -m[arm]1 Currently not supported.
26422 -m[arm]2, -m[arm]250 Arm 2 and Arm 250 processor
26423 -m[arm]3 Arm 3 processor
26424 -m[arm]6[xx], Arm 6 processors
26425 -m[arm]7[xx][t][[d]m] Arm 7 processors
26426 -m[arm]8[10] Arm 8 processors
26427 -m[arm]9[20][tdmi] Arm 9 processors
26428 -mstrongarm[110[0]] StrongARM processors
26429 -mxscale XScale processors
26430 -m[arm]v[2345[t[e]]] Arm architectures
26431 -mall All (except the ARM1)
26432 FP variants:
26433 -mfpa10, -mfpa11 FPA10 and 11 co-processor instructions
26434 -mfpe-old (No float load/store multiples)
26435 -mvfpxd VFP Single precision
26436 -mvfp All VFP
26437 -mno-fpu Disable all floating point instructions
b99bd4ef 26438
c19d1205
ZW
26439 The following CPU names are recognized:
26440 arm1, arm2, arm250, arm3, arm6, arm600, arm610, arm620,
26441 arm7, arm7m, arm7d, arm7dm, arm7di, arm7dmi, arm70, arm700,
26442 arm700i, arm710 arm710t, arm720, arm720t, arm740t, arm710c,
26443 arm7100, arm7500, arm7500fe, arm7tdmi, arm8, arm810, arm9,
26444 arm920, arm920t, arm940t, arm946, arm966, arm9tdmi, arm9e,
26445 arm10t arm10e, arm1020t, arm1020e, arm10200e,
26446 strongarm, strongarm110, strongarm1100, strongarm1110, xscale.
b99bd4ef 26447
c19d1205 26448 */
b99bd4ef 26449
c19d1205 26450const char * md_shortopts = "m:k";
b99bd4ef 26451
c19d1205
ZW
26452#ifdef ARM_BI_ENDIAN
26453#define OPTION_EB (OPTION_MD_BASE + 0)
26454#define OPTION_EL (OPTION_MD_BASE + 1)
b99bd4ef 26455#else
c19d1205
ZW
26456#if TARGET_BYTES_BIG_ENDIAN
26457#define OPTION_EB (OPTION_MD_BASE + 0)
b99bd4ef 26458#else
c19d1205
ZW
26459#define OPTION_EL (OPTION_MD_BASE + 1)
26460#endif
b99bd4ef 26461#endif
845b51d6 26462#define OPTION_FIX_V4BX (OPTION_MD_BASE + 2)
18a20338 26463#define OPTION_FDPIC (OPTION_MD_BASE + 3)
b99bd4ef 26464
c19d1205 26465struct option md_longopts[] =
b99bd4ef 26466{
c19d1205
ZW
26467#ifdef OPTION_EB
26468 {"EB", no_argument, NULL, OPTION_EB},
26469#endif
26470#ifdef OPTION_EL
26471 {"EL", no_argument, NULL, OPTION_EL},
b99bd4ef 26472#endif
845b51d6 26473 {"fix-v4bx", no_argument, NULL, OPTION_FIX_V4BX},
18a20338
CL
26474#ifdef OBJ_ELF
26475 {"fdpic", no_argument, NULL, OPTION_FDPIC},
26476#endif
c19d1205
ZW
26477 {NULL, no_argument, NULL, 0}
26478};
b99bd4ef 26479
c19d1205 26480size_t md_longopts_size = sizeof (md_longopts);
b99bd4ef 26481
c19d1205 26482struct arm_option_table
b99bd4ef 26483{
0198d5e6
TC
26484 const char * option; /* Option name to match. */
26485 const char * help; /* Help information. */
26486 int * var; /* Variable to change. */
26487 int value; /* What to change it to. */
26488 const char * deprecated; /* If non-null, print this message. */
c19d1205 26489};
b99bd4ef 26490
c19d1205
ZW
26491struct arm_option_table arm_opts[] =
26492{
26493 {"k", N_("generate PIC code"), &pic_code, 1, NULL},
26494 {"mthumb", N_("assemble Thumb code"), &thumb_mode, 1, NULL},
26495 {"mthumb-interwork", N_("support ARM/Thumb interworking"),
26496 &support_interwork, 1, NULL},
26497 {"mapcs-32", N_("code uses 32-bit program counter"), &uses_apcs_26, 0, NULL},
26498 {"mapcs-26", N_("code uses 26-bit program counter"), &uses_apcs_26, 1, NULL},
26499 {"mapcs-float", N_("floating point args are in fp regs"), &uses_apcs_float,
26500 1, NULL},
26501 {"mapcs-reentrant", N_("re-entrant code"), &pic_code, 1, NULL},
26502 {"matpcs", N_("code is ATPCS conformant"), &atpcs, 1, NULL},
26503 {"mbig-endian", N_("assemble for big-endian"), &target_big_endian, 1, NULL},
26504 {"mlittle-endian", N_("assemble for little-endian"), &target_big_endian, 0,
26505 NULL},
b99bd4ef 26506
c19d1205
ZW
26507 /* These are recognized by the assembler, but have no affect on code. */
26508 {"mapcs-frame", N_("use frame pointer"), NULL, 0, NULL},
26509 {"mapcs-stack-check", N_("use stack size checking"), NULL, 0, NULL},
278df34e
NS
26510
26511 {"mwarn-deprecated", NULL, &warn_on_deprecated, 1, NULL},
26512 {"mno-warn-deprecated", N_("do not warn on use of deprecated feature"),
26513 &warn_on_deprecated, 0, NULL},
8b2d793c
NC
26514 {"mwarn-syms", N_("warn about symbols that match instruction names [default]"), (int *) (& flag_warn_syms), TRUE, NULL},
26515 {"mno-warn-syms", N_("disable warnings about symobls that match instructions"), (int *) (& flag_warn_syms), FALSE, NULL},
e74cfd16
PB
26516 {NULL, NULL, NULL, 0, NULL}
26517};
26518
26519struct arm_legacy_option_table
26520{
0198d5e6
TC
26521 const char * option; /* Option name to match. */
26522 const arm_feature_set ** var; /* Variable to change. */
26523 const arm_feature_set value; /* What to change it to. */
26524 const char * deprecated; /* If non-null, print this message. */
e74cfd16 26525};
b99bd4ef 26526
e74cfd16
PB
26527const struct arm_legacy_option_table arm_legacy_opts[] =
26528{
c19d1205
ZW
26529 /* DON'T add any new processors to this list -- we want the whole list
26530 to go away... Add them to the processors table instead. */
e74cfd16
PB
26531 {"marm1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
26532 {"m1", &legacy_cpu, ARM_ARCH_V1, N_("use -mcpu=arm1")},
26533 {"marm2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
26534 {"m2", &legacy_cpu, ARM_ARCH_V2, N_("use -mcpu=arm2")},
26535 {"marm250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
26536 {"m250", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm250")},
26537 {"marm3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
26538 {"m3", &legacy_cpu, ARM_ARCH_V2S, N_("use -mcpu=arm3")},
26539 {"marm6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
26540 {"m6", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm6")},
26541 {"marm600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
26542 {"m600", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm600")},
26543 {"marm610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
26544 {"m610", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm610")},
26545 {"marm620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
26546 {"m620", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm620")},
26547 {"marm7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
26548 {"m7", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7")},
26549 {"marm70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
26550 {"m70", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm70")},
26551 {"marm700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
26552 {"m700", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700")},
26553 {"marm700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
26554 {"m700i", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm700i")},
26555 {"marm710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
26556 {"m710", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710")},
26557 {"marm710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
26558 {"m710c", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm710c")},
26559 {"marm720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
26560 {"m720", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm720")},
26561 {"marm7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
26562 {"m7d", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7d")},
26563 {"marm7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
26564 {"m7di", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7di")},
26565 {"marm7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
26566 {"m7m", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7m")},
26567 {"marm7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
26568 {"m7dm", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dm")},
26569 {"marm7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
26570 {"m7dmi", &legacy_cpu, ARM_ARCH_V3M, N_("use -mcpu=arm7dmi")},
26571 {"marm7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
26572 {"m7100", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7100")},
26573 {"marm7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
26574 {"m7500", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500")},
26575 {"marm7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
26576 {"m7500fe", &legacy_cpu, ARM_ARCH_V3, N_("use -mcpu=arm7500fe")},
26577 {"marm7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26578 {"m7t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26579 {"marm7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26580 {"m7tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm7tdmi")},
26581 {"marm710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
26582 {"m710t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm710t")},
26583 {"marm720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
26584 {"m720t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm720t")},
26585 {"marm740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
26586 {"m740t", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm740t")},
26587 {"marm8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
26588 {"m8", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm8")},
26589 {"marm810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
26590 {"m810", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=arm810")},
26591 {"marm9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
26592 {"m9", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9")},
26593 {"marm9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
26594 {"m9tdmi", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm9tdmi")},
26595 {"marm920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
26596 {"m920", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm920")},
26597 {"marm940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
26598 {"m940", &legacy_cpu, ARM_ARCH_V4T, N_("use -mcpu=arm940")},
26599 {"mstrongarm", &legacy_cpu, ARM_ARCH_V4, N_("use -mcpu=strongarm")},
26600 {"mstrongarm110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 26601 N_("use -mcpu=strongarm110")},
e74cfd16 26602 {"mstrongarm1100", &legacy_cpu, ARM_ARCH_V4,
c19d1205 26603 N_("use -mcpu=strongarm1100")},
e74cfd16 26604 {"mstrongarm1110", &legacy_cpu, ARM_ARCH_V4,
c19d1205 26605 N_("use -mcpu=strongarm1110")},
e74cfd16
PB
26606 {"mxscale", &legacy_cpu, ARM_ARCH_XSCALE, N_("use -mcpu=xscale")},
26607 {"miwmmxt", &legacy_cpu, ARM_ARCH_IWMMXT, N_("use -mcpu=iwmmxt")},
26608 {"mall", &legacy_cpu, ARM_ANY, N_("use -mcpu=all")},
7ed4c4c5 26609
c19d1205 26610 /* Architecture variants -- don't add any more to this list either. */
e74cfd16
PB
26611 {"mv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
26612 {"marmv2", &legacy_cpu, ARM_ARCH_V2, N_("use -march=armv2")},
26613 {"mv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
26614 {"marmv2a", &legacy_cpu, ARM_ARCH_V2S, N_("use -march=armv2a")},
26615 {"mv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
26616 {"marmv3", &legacy_cpu, ARM_ARCH_V3, N_("use -march=armv3")},
26617 {"mv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
26618 {"marmv3m", &legacy_cpu, ARM_ARCH_V3M, N_("use -march=armv3m")},
26619 {"mv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
26620 {"marmv4", &legacy_cpu, ARM_ARCH_V4, N_("use -march=armv4")},
26621 {"mv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
26622 {"marmv4t", &legacy_cpu, ARM_ARCH_V4T, N_("use -march=armv4t")},
26623 {"mv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
26624 {"marmv5", &legacy_cpu, ARM_ARCH_V5, N_("use -march=armv5")},
26625 {"mv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
26626 {"marmv5t", &legacy_cpu, ARM_ARCH_V5T, N_("use -march=armv5t")},
26627 {"mv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
26628 {"marmv5e", &legacy_cpu, ARM_ARCH_V5TE, N_("use -march=armv5te")},
7ed4c4c5 26629
c19d1205 26630 /* Floating point variants -- don't add any more to this list either. */
0198d5e6
TC
26631 {"mfpe-old", &legacy_fpu, FPU_ARCH_FPE, N_("use -mfpu=fpe")},
26632 {"mfpa10", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa10")},
26633 {"mfpa11", &legacy_fpu, FPU_ARCH_FPA, N_("use -mfpu=fpa11")},
26634 {"mno-fpu", &legacy_fpu, ARM_ARCH_NONE,
c19d1205 26635 N_("use either -mfpu=softfpa or -mfpu=softvfp")},
7ed4c4c5 26636
e74cfd16 26637 {NULL, NULL, ARM_ARCH_NONE, NULL}
c19d1205 26638};
7ed4c4c5 26639
c19d1205 26640struct arm_cpu_option_table
7ed4c4c5 26641{
0198d5e6
TC
26642 const char * name;
26643 size_t name_len;
26644 const arm_feature_set value;
26645 const arm_feature_set ext;
c19d1205
ZW
26646 /* For some CPUs we assume an FPU unless the user explicitly sets
26647 -mfpu=... */
0198d5e6 26648 const arm_feature_set default_fpu;
ee065d83
PB
26649 /* The canonical name of the CPU, or NULL to use NAME converted to upper
26650 case. */
0198d5e6 26651 const char * canonical_name;
c19d1205 26652};
7ed4c4c5 26653
c19d1205
ZW
26654/* This list should, at a minimum, contain all the cpu names
26655 recognized by GCC. */
996b5569 26656#define ARM_CPU_OPT(N, CN, V, E, DF) { N, sizeof (N) - 1, V, E, DF, CN }
0198d5e6 26657
e74cfd16 26658static const struct arm_cpu_option_table arm_cpus[] =
c19d1205 26659{
996b5569
TP
26660 ARM_CPU_OPT ("all", NULL, ARM_ANY,
26661 ARM_ARCH_NONE,
26662 FPU_ARCH_FPA),
26663 ARM_CPU_OPT ("arm1", NULL, ARM_ARCH_V1,
26664 ARM_ARCH_NONE,
26665 FPU_ARCH_FPA),
26666 ARM_CPU_OPT ("arm2", NULL, ARM_ARCH_V2,
26667 ARM_ARCH_NONE,
26668 FPU_ARCH_FPA),
26669 ARM_CPU_OPT ("arm250", NULL, ARM_ARCH_V2S,
26670 ARM_ARCH_NONE,
26671 FPU_ARCH_FPA),
26672 ARM_CPU_OPT ("arm3", NULL, ARM_ARCH_V2S,
26673 ARM_ARCH_NONE,
26674 FPU_ARCH_FPA),
26675 ARM_CPU_OPT ("arm6", NULL, ARM_ARCH_V3,
26676 ARM_ARCH_NONE,
26677 FPU_ARCH_FPA),
26678 ARM_CPU_OPT ("arm60", NULL, ARM_ARCH_V3,
26679 ARM_ARCH_NONE,
26680 FPU_ARCH_FPA),
26681 ARM_CPU_OPT ("arm600", NULL, ARM_ARCH_V3,
26682 ARM_ARCH_NONE,
26683 FPU_ARCH_FPA),
26684 ARM_CPU_OPT ("arm610", NULL, ARM_ARCH_V3,
26685 ARM_ARCH_NONE,
26686 FPU_ARCH_FPA),
26687 ARM_CPU_OPT ("arm620", NULL, ARM_ARCH_V3,
26688 ARM_ARCH_NONE,
26689 FPU_ARCH_FPA),
26690 ARM_CPU_OPT ("arm7", NULL, ARM_ARCH_V3,
26691 ARM_ARCH_NONE,
26692 FPU_ARCH_FPA),
26693 ARM_CPU_OPT ("arm7m", NULL, ARM_ARCH_V3M,
26694 ARM_ARCH_NONE,
26695 FPU_ARCH_FPA),
26696 ARM_CPU_OPT ("arm7d", NULL, ARM_ARCH_V3,
26697 ARM_ARCH_NONE,
26698 FPU_ARCH_FPA),
26699 ARM_CPU_OPT ("arm7dm", NULL, ARM_ARCH_V3M,
26700 ARM_ARCH_NONE,
26701 FPU_ARCH_FPA),
26702 ARM_CPU_OPT ("arm7di", NULL, ARM_ARCH_V3,
26703 ARM_ARCH_NONE,
26704 FPU_ARCH_FPA),
26705 ARM_CPU_OPT ("arm7dmi", NULL, ARM_ARCH_V3M,
26706 ARM_ARCH_NONE,
26707 FPU_ARCH_FPA),
26708 ARM_CPU_OPT ("arm70", NULL, ARM_ARCH_V3,
26709 ARM_ARCH_NONE,
26710 FPU_ARCH_FPA),
26711 ARM_CPU_OPT ("arm700", NULL, ARM_ARCH_V3,
26712 ARM_ARCH_NONE,
26713 FPU_ARCH_FPA),
26714 ARM_CPU_OPT ("arm700i", NULL, ARM_ARCH_V3,
26715 ARM_ARCH_NONE,
26716 FPU_ARCH_FPA),
26717 ARM_CPU_OPT ("arm710", NULL, ARM_ARCH_V3,
26718 ARM_ARCH_NONE,
26719 FPU_ARCH_FPA),
26720 ARM_CPU_OPT ("arm710t", NULL, ARM_ARCH_V4T,
26721 ARM_ARCH_NONE,
26722 FPU_ARCH_FPA),
26723 ARM_CPU_OPT ("arm720", NULL, ARM_ARCH_V3,
26724 ARM_ARCH_NONE,
26725 FPU_ARCH_FPA),
26726 ARM_CPU_OPT ("arm720t", NULL, ARM_ARCH_V4T,
26727 ARM_ARCH_NONE,
26728 FPU_ARCH_FPA),
26729 ARM_CPU_OPT ("arm740t", NULL, ARM_ARCH_V4T,
26730 ARM_ARCH_NONE,
26731 FPU_ARCH_FPA),
26732 ARM_CPU_OPT ("arm710c", NULL, ARM_ARCH_V3,
26733 ARM_ARCH_NONE,
26734 FPU_ARCH_FPA),
26735 ARM_CPU_OPT ("arm7100", NULL, ARM_ARCH_V3,
26736 ARM_ARCH_NONE,
26737 FPU_ARCH_FPA),
26738 ARM_CPU_OPT ("arm7500", NULL, ARM_ARCH_V3,
26739 ARM_ARCH_NONE,
26740 FPU_ARCH_FPA),
26741 ARM_CPU_OPT ("arm7500fe", NULL, ARM_ARCH_V3,
26742 ARM_ARCH_NONE,
26743 FPU_ARCH_FPA),
26744 ARM_CPU_OPT ("arm7t", NULL, ARM_ARCH_V4T,
26745 ARM_ARCH_NONE,
26746 FPU_ARCH_FPA),
26747 ARM_CPU_OPT ("arm7tdmi", NULL, ARM_ARCH_V4T,
26748 ARM_ARCH_NONE,
26749 FPU_ARCH_FPA),
26750 ARM_CPU_OPT ("arm7tdmi-s", NULL, ARM_ARCH_V4T,
26751 ARM_ARCH_NONE,
26752 FPU_ARCH_FPA),
26753 ARM_CPU_OPT ("arm8", NULL, ARM_ARCH_V4,
26754 ARM_ARCH_NONE,
26755 FPU_ARCH_FPA),
26756 ARM_CPU_OPT ("arm810", NULL, ARM_ARCH_V4,
26757 ARM_ARCH_NONE,
26758 FPU_ARCH_FPA),
26759 ARM_CPU_OPT ("strongarm", NULL, ARM_ARCH_V4,
26760 ARM_ARCH_NONE,
26761 FPU_ARCH_FPA),
26762 ARM_CPU_OPT ("strongarm1", NULL, ARM_ARCH_V4,
26763 ARM_ARCH_NONE,
26764 FPU_ARCH_FPA),
26765 ARM_CPU_OPT ("strongarm110", NULL, ARM_ARCH_V4,
26766 ARM_ARCH_NONE,
26767 FPU_ARCH_FPA),
26768 ARM_CPU_OPT ("strongarm1100", NULL, ARM_ARCH_V4,
26769 ARM_ARCH_NONE,
26770 FPU_ARCH_FPA),
26771 ARM_CPU_OPT ("strongarm1110", NULL, ARM_ARCH_V4,
26772 ARM_ARCH_NONE,
26773 FPU_ARCH_FPA),
26774 ARM_CPU_OPT ("arm9", NULL, ARM_ARCH_V4T,
26775 ARM_ARCH_NONE,
26776 FPU_ARCH_FPA),
26777 ARM_CPU_OPT ("arm920", "ARM920T", ARM_ARCH_V4T,
26778 ARM_ARCH_NONE,
26779 FPU_ARCH_FPA),
26780 ARM_CPU_OPT ("arm920t", NULL, ARM_ARCH_V4T,
26781 ARM_ARCH_NONE,
26782 FPU_ARCH_FPA),
26783 ARM_CPU_OPT ("arm922t", NULL, ARM_ARCH_V4T,
26784 ARM_ARCH_NONE,
26785 FPU_ARCH_FPA),
26786 ARM_CPU_OPT ("arm940t", NULL, ARM_ARCH_V4T,
26787 ARM_ARCH_NONE,
26788 FPU_ARCH_FPA),
26789 ARM_CPU_OPT ("arm9tdmi", NULL, ARM_ARCH_V4T,
26790 ARM_ARCH_NONE,
26791 FPU_ARCH_FPA),
26792 ARM_CPU_OPT ("fa526", NULL, ARM_ARCH_V4,
26793 ARM_ARCH_NONE,
26794 FPU_ARCH_FPA),
26795 ARM_CPU_OPT ("fa626", NULL, ARM_ARCH_V4,
26796 ARM_ARCH_NONE,
26797 FPU_ARCH_FPA),
26798
c19d1205
ZW
26799 /* For V5 or later processors we default to using VFP; but the user
26800 should really set the FPU type explicitly. */
996b5569
TP
26801 ARM_CPU_OPT ("arm9e-r0", NULL, ARM_ARCH_V5TExP,
26802 ARM_ARCH_NONE,
26803 FPU_ARCH_VFP_V2),
26804 ARM_CPU_OPT ("arm9e", NULL, ARM_ARCH_V5TE,
26805 ARM_ARCH_NONE,
26806 FPU_ARCH_VFP_V2),
26807 ARM_CPU_OPT ("arm926ej", "ARM926EJ-S", ARM_ARCH_V5TEJ,
26808 ARM_ARCH_NONE,
26809 FPU_ARCH_VFP_V2),
26810 ARM_CPU_OPT ("arm926ejs", "ARM926EJ-S", ARM_ARCH_V5TEJ,
26811 ARM_ARCH_NONE,
26812 FPU_ARCH_VFP_V2),
26813 ARM_CPU_OPT ("arm926ej-s", NULL, ARM_ARCH_V5TEJ,
26814 ARM_ARCH_NONE,
26815 FPU_ARCH_VFP_V2),
26816 ARM_CPU_OPT ("arm946e-r0", NULL, ARM_ARCH_V5TExP,
26817 ARM_ARCH_NONE,
26818 FPU_ARCH_VFP_V2),
26819 ARM_CPU_OPT ("arm946e", "ARM946E-S", ARM_ARCH_V5TE,
26820 ARM_ARCH_NONE,
26821 FPU_ARCH_VFP_V2),
26822 ARM_CPU_OPT ("arm946e-s", NULL, ARM_ARCH_V5TE,
26823 ARM_ARCH_NONE,
26824 FPU_ARCH_VFP_V2),
26825 ARM_CPU_OPT ("arm966e-r0", NULL, ARM_ARCH_V5TExP,
26826 ARM_ARCH_NONE,
26827 FPU_ARCH_VFP_V2),
26828 ARM_CPU_OPT ("arm966e", "ARM966E-S", ARM_ARCH_V5TE,
26829 ARM_ARCH_NONE,
26830 FPU_ARCH_VFP_V2),
26831 ARM_CPU_OPT ("arm966e-s", NULL, ARM_ARCH_V5TE,
26832 ARM_ARCH_NONE,
26833 FPU_ARCH_VFP_V2),
26834 ARM_CPU_OPT ("arm968e-s", NULL, ARM_ARCH_V5TE,
26835 ARM_ARCH_NONE,
26836 FPU_ARCH_VFP_V2),
26837 ARM_CPU_OPT ("arm10t", NULL, ARM_ARCH_V5T,
26838 ARM_ARCH_NONE,
26839 FPU_ARCH_VFP_V1),
26840 ARM_CPU_OPT ("arm10tdmi", NULL, ARM_ARCH_V5T,
26841 ARM_ARCH_NONE,
26842 FPU_ARCH_VFP_V1),
26843 ARM_CPU_OPT ("arm10e", NULL, ARM_ARCH_V5TE,
26844 ARM_ARCH_NONE,
26845 FPU_ARCH_VFP_V2),
26846 ARM_CPU_OPT ("arm1020", "ARM1020E", ARM_ARCH_V5TE,
26847 ARM_ARCH_NONE,
26848 FPU_ARCH_VFP_V2),
26849 ARM_CPU_OPT ("arm1020t", NULL, ARM_ARCH_V5T,
26850 ARM_ARCH_NONE,
26851 FPU_ARCH_VFP_V1),
26852 ARM_CPU_OPT ("arm1020e", NULL, ARM_ARCH_V5TE,
26853 ARM_ARCH_NONE,
26854 FPU_ARCH_VFP_V2),
26855 ARM_CPU_OPT ("arm1022e", NULL, ARM_ARCH_V5TE,
26856 ARM_ARCH_NONE,
26857 FPU_ARCH_VFP_V2),
26858 ARM_CPU_OPT ("arm1026ejs", "ARM1026EJ-S", ARM_ARCH_V5TEJ,
26859 ARM_ARCH_NONE,
26860 FPU_ARCH_VFP_V2),
26861 ARM_CPU_OPT ("arm1026ej-s", NULL, ARM_ARCH_V5TEJ,
26862 ARM_ARCH_NONE,
26863 FPU_ARCH_VFP_V2),
26864 ARM_CPU_OPT ("fa606te", NULL, ARM_ARCH_V5TE,
26865 ARM_ARCH_NONE,
26866 FPU_ARCH_VFP_V2),
26867 ARM_CPU_OPT ("fa616te", NULL, ARM_ARCH_V5TE,
26868 ARM_ARCH_NONE,
26869 FPU_ARCH_VFP_V2),
26870 ARM_CPU_OPT ("fa626te", NULL, ARM_ARCH_V5TE,
26871 ARM_ARCH_NONE,
26872 FPU_ARCH_VFP_V2),
26873 ARM_CPU_OPT ("fmp626", NULL, ARM_ARCH_V5TE,
26874 ARM_ARCH_NONE,
26875 FPU_ARCH_VFP_V2),
26876 ARM_CPU_OPT ("fa726te", NULL, ARM_ARCH_V5TE,
26877 ARM_ARCH_NONE,
26878 FPU_ARCH_VFP_V2),
26879 ARM_CPU_OPT ("arm1136js", "ARM1136J-S", ARM_ARCH_V6,
26880 ARM_ARCH_NONE,
26881 FPU_NONE),
26882 ARM_CPU_OPT ("arm1136j-s", NULL, ARM_ARCH_V6,
26883 ARM_ARCH_NONE,
26884 FPU_NONE),
26885 ARM_CPU_OPT ("arm1136jfs", "ARM1136JF-S", ARM_ARCH_V6,
26886 ARM_ARCH_NONE,
26887 FPU_ARCH_VFP_V2),
26888 ARM_CPU_OPT ("arm1136jf-s", NULL, ARM_ARCH_V6,
26889 ARM_ARCH_NONE,
26890 FPU_ARCH_VFP_V2),
26891 ARM_CPU_OPT ("mpcore", "MPCore", ARM_ARCH_V6K,
26892 ARM_ARCH_NONE,
26893 FPU_ARCH_VFP_V2),
26894 ARM_CPU_OPT ("mpcorenovfp", "MPCore", ARM_ARCH_V6K,
26895 ARM_ARCH_NONE,
26896 FPU_NONE),
26897 ARM_CPU_OPT ("arm1156t2-s", NULL, ARM_ARCH_V6T2,
26898 ARM_ARCH_NONE,
26899 FPU_NONE),
26900 ARM_CPU_OPT ("arm1156t2f-s", NULL, ARM_ARCH_V6T2,
26901 ARM_ARCH_NONE,
26902 FPU_ARCH_VFP_V2),
26903 ARM_CPU_OPT ("arm1176jz-s", NULL, ARM_ARCH_V6KZ,
26904 ARM_ARCH_NONE,
26905 FPU_NONE),
26906 ARM_CPU_OPT ("arm1176jzf-s", NULL, ARM_ARCH_V6KZ,
26907 ARM_ARCH_NONE,
26908 FPU_ARCH_VFP_V2),
26909 ARM_CPU_OPT ("cortex-a5", "Cortex-A5", ARM_ARCH_V7A,
26910 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
26911 FPU_NONE),
26912 ARM_CPU_OPT ("cortex-a7", "Cortex-A7", ARM_ARCH_V7VE,
26913 ARM_ARCH_NONE,
26914 FPU_ARCH_NEON_VFP_V4),
26915 ARM_CPU_OPT ("cortex-a8", "Cortex-A8", ARM_ARCH_V7A,
26916 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
26917 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
26918 ARM_CPU_OPT ("cortex-a9", "Cortex-A9", ARM_ARCH_V7A,
26919 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
26920 ARM_FEATURE_COPROC (FPU_VFP_V3 | FPU_NEON_EXT_V1)),
26921 ARM_CPU_OPT ("cortex-a12", "Cortex-A12", ARM_ARCH_V7VE,
26922 ARM_ARCH_NONE,
26923 FPU_ARCH_NEON_VFP_V4),
26924 ARM_CPU_OPT ("cortex-a15", "Cortex-A15", ARM_ARCH_V7VE,
26925 ARM_ARCH_NONE,
26926 FPU_ARCH_NEON_VFP_V4),
26927 ARM_CPU_OPT ("cortex-a17", "Cortex-A17", ARM_ARCH_V7VE,
26928 ARM_ARCH_NONE,
26929 FPU_ARCH_NEON_VFP_V4),
26930 ARM_CPU_OPT ("cortex-a32", "Cortex-A32", ARM_ARCH_V8A,
26931 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26932 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26933 ARM_CPU_OPT ("cortex-a35", "Cortex-A35", ARM_ARCH_V8A,
26934 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26935 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26936 ARM_CPU_OPT ("cortex-a53", "Cortex-A53", ARM_ARCH_V8A,
26937 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26938 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
26939 ARM_CPU_OPT ("cortex-a55", "Cortex-A55", ARM_ARCH_V8_2A,
26940 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 26941 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
26942 ARM_CPU_OPT ("cortex-a57", "Cortex-A57", ARM_ARCH_V8A,
26943 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26944 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26945 ARM_CPU_OPT ("cortex-a72", "Cortex-A72", ARM_ARCH_V8A,
26946 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26947 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
26948 ARM_CPU_OPT ("cortex-a73", "Cortex-A73", ARM_ARCH_V8A,
26949 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26950 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
15a7695f
JG
26951 ARM_CPU_OPT ("cortex-a75", "Cortex-A75", ARM_ARCH_V8_2A,
26952 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
0198d5e6 26953 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
7ebd1359 26954 ARM_CPU_OPT ("cortex-a76", "Cortex-A76", ARM_ARCH_V8_2A,
26955 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
26956 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
ef8df4ca
KT
26957 ARM_CPU_OPT ("ares", "Ares", ARM_ARCH_V8_2A,
26958 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
26959 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
996b5569
TP
26960 ARM_CPU_OPT ("cortex-r4", "Cortex-R4", ARM_ARCH_V7R,
26961 ARM_ARCH_NONE,
26962 FPU_NONE),
26963 ARM_CPU_OPT ("cortex-r4f", "Cortex-R4F", ARM_ARCH_V7R,
26964 ARM_ARCH_NONE,
26965 FPU_ARCH_VFP_V3D16),
26966 ARM_CPU_OPT ("cortex-r5", "Cortex-R5", ARM_ARCH_V7R,
26967 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
26968 FPU_NONE),
26969 ARM_CPU_OPT ("cortex-r7", "Cortex-R7", ARM_ARCH_V7R,
26970 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
26971 FPU_ARCH_VFP_V3D16),
26972 ARM_CPU_OPT ("cortex-r8", "Cortex-R8", ARM_ARCH_V7R,
26973 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV),
26974 FPU_ARCH_VFP_V3D16),
0cda1e19
TP
26975 ARM_CPU_OPT ("cortex-r52", "Cortex-R52", ARM_ARCH_V8R,
26976 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
26977 FPU_ARCH_NEON_VFP_ARMV8),
996b5569
TP
26978 ARM_CPU_OPT ("cortex-m33", "Cortex-M33", ARM_ARCH_V8M_MAIN,
26979 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
26980 FPU_NONE),
26981 ARM_CPU_OPT ("cortex-m23", "Cortex-M23", ARM_ARCH_V8M_BASE,
26982 ARM_ARCH_NONE,
26983 FPU_NONE),
26984 ARM_CPU_OPT ("cortex-m7", "Cortex-M7", ARM_ARCH_V7EM,
26985 ARM_ARCH_NONE,
26986 FPU_NONE),
26987 ARM_CPU_OPT ("cortex-m4", "Cortex-M4", ARM_ARCH_V7EM,
26988 ARM_ARCH_NONE,
26989 FPU_NONE),
26990 ARM_CPU_OPT ("cortex-m3", "Cortex-M3", ARM_ARCH_V7M,
26991 ARM_ARCH_NONE,
26992 FPU_NONE),
26993 ARM_CPU_OPT ("cortex-m1", "Cortex-M1", ARM_ARCH_V6SM,
26994 ARM_ARCH_NONE,
26995 FPU_NONE),
26996 ARM_CPU_OPT ("cortex-m0", "Cortex-M0", ARM_ARCH_V6SM,
26997 ARM_ARCH_NONE,
26998 FPU_NONE),
26999 ARM_CPU_OPT ("cortex-m0plus", "Cortex-M0+", ARM_ARCH_V6SM,
27000 ARM_ARCH_NONE,
27001 FPU_NONE),
27002 ARM_CPU_OPT ("exynos-m1", "Samsung Exynos M1", ARM_ARCH_V8A,
27003 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
27004 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
83f43c83
KT
27005 ARM_CPU_OPT ("neoverse-n1", "Neoverse N1", ARM_ARCH_V8_2A,
27006 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
27007 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_DOTPROD),
c19d1205 27008 /* ??? XSCALE is really an architecture. */
996b5569
TP
27009 ARM_CPU_OPT ("xscale", NULL, ARM_ARCH_XSCALE,
27010 ARM_ARCH_NONE,
27011 FPU_ARCH_VFP_V2),
27012
c19d1205 27013 /* ??? iwmmxt is not a processor. */
996b5569
TP
27014 ARM_CPU_OPT ("iwmmxt", NULL, ARM_ARCH_IWMMXT,
27015 ARM_ARCH_NONE,
27016 FPU_ARCH_VFP_V2),
27017 ARM_CPU_OPT ("iwmmxt2", NULL, ARM_ARCH_IWMMXT2,
27018 ARM_ARCH_NONE,
27019 FPU_ARCH_VFP_V2),
27020 ARM_CPU_OPT ("i80200", NULL, ARM_ARCH_XSCALE,
27021 ARM_ARCH_NONE,
27022 FPU_ARCH_VFP_V2),
27023
0198d5e6 27024 /* Maverick. */
996b5569
TP
27025 ARM_CPU_OPT ("ep9312", "ARM920T",
27026 ARM_FEATURE_LOW (ARM_AEXT_V4T, ARM_CEXT_MAVERICK),
27027 ARM_ARCH_NONE, FPU_ARCH_MAVERICK),
27028
da4339ed 27029 /* Marvell processors. */
996b5569
TP
27030 ARM_CPU_OPT ("marvell-pj4", NULL, ARM_ARCH_V7A,
27031 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
27032 FPU_ARCH_VFP_V3D16),
27033 ARM_CPU_OPT ("marvell-whitney", NULL, ARM_ARCH_V7A,
27034 ARM_FEATURE_CORE_LOW (ARM_EXT_MP | ARM_EXT_SEC),
27035 FPU_ARCH_NEON_VFP_V4),
da4339ed 27036
996b5569
TP
27037 /* APM X-Gene family. */
27038 ARM_CPU_OPT ("xgene1", "APM X-Gene 1", ARM_ARCH_V8A,
27039 ARM_ARCH_NONE,
27040 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
27041 ARM_CPU_OPT ("xgene2", "APM X-Gene 2", ARM_ARCH_V8A,
27042 ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
27043 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8),
27044
27045 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 27046};
f3bad469 27047#undef ARM_CPU_OPT
7ed4c4c5 27048
34ef62f4
AV
27049struct arm_ext_table
27050{
27051 const char * name;
27052 size_t name_len;
27053 const arm_feature_set merge;
27054 const arm_feature_set clear;
27055};
27056
c19d1205 27057struct arm_arch_option_table
7ed4c4c5 27058{
34ef62f4
AV
27059 const char * name;
27060 size_t name_len;
27061 const arm_feature_set value;
27062 const arm_feature_set default_fpu;
27063 const struct arm_ext_table * ext_table;
27064};
27065
27066/* Used to add support for +E and +noE extension. */
27067#define ARM_EXT(E, M, C) { E, sizeof (E) - 1, M, C }
27068/* Used to add support for a +E extension. */
27069#define ARM_ADD(E, M) { E, sizeof(E) - 1, M, ARM_ARCH_NONE }
27070/* Used to add support for a +noE extension. */
27071#define ARM_REMOVE(E, C) { E, sizeof(E) -1, ARM_ARCH_NONE, C }
27072
27073#define ALL_FP ARM_FEATURE (0, ARM_EXT2_FP16_INST | ARM_EXT2_FP16_FML, \
27074 ~0 & ~FPU_ENDIAN_PURE)
27075
27076static const struct arm_ext_table armv5te_ext_table[] =
27077{
27078 ARM_EXT ("fp", FPU_ARCH_VFP_V2, ALL_FP),
27079 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27080};
27081
27082static const struct arm_ext_table armv7_ext_table[] =
27083{
27084 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
27085 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27086};
27087
27088static const struct arm_ext_table armv7ve_ext_table[] =
27089{
27090 ARM_EXT ("fp", FPU_ARCH_VFP_V4D16, ALL_FP),
27091 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16),
27092 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
27093 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
27094 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
27095 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16), /* Alias for +fp. */
27096 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
27097
27098 ARM_EXT ("simd", FPU_ARCH_NEON_VFP_V4,
27099 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
27100
27101 /* Aliases for +simd. */
27102 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
27103
27104 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
27105 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
27106 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
27107
27108 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27109};
27110
27111static const struct arm_ext_table armv7a_ext_table[] =
27112{
27113 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
27114 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
27115 ARM_ADD ("vfpv3", FPU_ARCH_VFP_V3),
27116 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
27117 ARM_ADD ("vfpv3-fp16", FPU_ARCH_VFP_V3_FP16),
27118 ARM_ADD ("vfpv4-d16", FPU_ARCH_VFP_V4D16),
27119 ARM_ADD ("vfpv4", FPU_ARCH_VFP_V4),
27120
27121 ARM_EXT ("simd", FPU_ARCH_VFP_V3_PLUS_NEON_V1,
27122 ARM_FEATURE_COPROC (FPU_NEON_EXT_V1 | FPU_NEON_EXT_FMA)),
27123
27124 /* Aliases for +simd. */
27125 ARM_ADD ("neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
27126 ARM_ADD ("neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1),
27127
27128 ARM_ADD ("neon-fp16", FPU_ARCH_NEON_FP16),
27129 ARM_ADD ("neon-vfpv4", FPU_ARCH_NEON_VFP_V4),
27130
27131 ARM_ADD ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP)),
27132 ARM_ADD ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC)),
27133 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27134};
27135
27136static const struct arm_ext_table armv7r_ext_table[] =
27137{
27138 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V3xD),
27139 ARM_ADD ("vfpv3xd", FPU_ARCH_VFP_V3xD), /* Alias for +fp.sp. */
27140 ARM_EXT ("fp", FPU_ARCH_VFP_V3D16, ALL_FP),
27141 ARM_ADD ("vfpv3-d16", FPU_ARCH_VFP_V3D16), /* Alias for +fp. */
27142 ARM_ADD ("vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16),
27143 ARM_ADD ("vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16),
27144 ARM_EXT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
27145 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV)),
27146 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27147};
27148
27149static const struct arm_ext_table armv7em_ext_table[] =
27150{
27151 ARM_EXT ("fp", FPU_ARCH_VFP_V4_SP_D16, ALL_FP),
27152 /* Alias for +fp, used to be known as fpv4-sp-d16. */
27153 ARM_ADD ("vfpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16),
27154 ARM_ADD ("fpv5", FPU_ARCH_VFP_V5_SP_D16),
27155 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
27156 ARM_ADD ("fpv5-d16", FPU_ARCH_VFP_V5D16),
27157 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27158};
27159
27160static const struct arm_ext_table armv8a_ext_table[] =
27161{
27162 ARM_ADD ("crc", ARCH_CRC_ARMV8),
27163 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
27164 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
27165 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27166
27167 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27168 should use the +simd option to turn on FP. */
27169 ARM_REMOVE ("fp", ALL_FP),
27170 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
27171 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
27172 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27173};
27174
27175
27176static const struct arm_ext_table armv81a_ext_table[] =
27177{
27178 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
27179 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
27180 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27181
27182 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27183 should use the +simd option to turn on FP. */
27184 ARM_REMOVE ("fp", ALL_FP),
27185 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
27186 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
27187 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27188};
27189
27190static const struct arm_ext_table armv82a_ext_table[] =
27191{
27192 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8_1),
27193 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_2_FP16),
27194 ARM_ADD ("fp16fml", FPU_ARCH_NEON_VFP_ARMV8_2_FP16FML),
27195 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1,
27196 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27197 ARM_ADD ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
27198
27199 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27200 should use the +simd option to turn on FP. */
27201 ARM_REMOVE ("fp", ALL_FP),
27202 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
27203 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
27204 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27205};
27206
27207static const struct arm_ext_table armv84a_ext_table[] =
27208{
27209 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
27210 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
27211 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
27212 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27213
27214 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27215 should use the +simd option to turn on FP. */
27216 ARM_REMOVE ("fp", ALL_FP),
27217 ARM_ADD ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB)),
27218 ARM_ADD ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES)),
27219 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27220};
27221
27222static const struct arm_ext_table armv85a_ext_table[] =
27223{
27224 ARM_ADD ("simd", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8),
27225 ARM_ADD ("fp16", FPU_ARCH_NEON_VFP_ARMV8_4_FP16FML),
27226 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_4,
27227 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27228
27229 /* Armv8-a does not allow an FP implementation without SIMD, so the user
27230 should use the +simd option to turn on FP. */
27231 ARM_REMOVE ("fp", ALL_FP),
27232 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27233};
27234
27235static const struct arm_ext_table armv8m_main_ext_table[] =
27236{
27237 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27238 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
27239 ARM_EXT ("fp", FPU_ARCH_VFP_V5_SP_D16, ALL_FP),
27240 ARM_ADD ("fp.dp", FPU_ARCH_VFP_V5D16),
27241 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27242};
27243
e0991585
AV
27244static const struct arm_ext_table armv8_1m_main_ext_table[] =
27245{
27246 ARM_EXT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27247 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP)),
27248 ARM_EXT ("fp",
27249 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
27250 FPU_VFP_V5_SP_D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA),
27251 ALL_FP),
27252 ARM_ADD ("fp.dp",
27253 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
27254 FPU_VFP_V5D16 | FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
a7ad558c
AV
27255 ARM_EXT ("mve", ARM_FEATURE_COPROC (FPU_MVE),
27256 ARM_FEATURE_COPROC (FPU_MVE | FPU_MVE_FP)),
27257 ARM_ADD ("mve.fp",
27258 ARM_FEATURE (0, ARM_EXT2_FP16_INST,
27259 FPU_MVE | FPU_MVE_FP | FPU_VFP_V5_SP_D16 |
27260 FPU_VFP_EXT_FP16 | FPU_VFP_EXT_FMA)),
e0991585
AV
27261 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
27262};
27263
34ef62f4
AV
27264static const struct arm_ext_table armv8r_ext_table[] =
27265{
27266 ARM_ADD ("crc", ARCH_CRC_ARMV8),
27267 ARM_ADD ("simd", FPU_ARCH_NEON_VFP_ARMV8),
27268 ARM_EXT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
27269 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8)),
27270 ARM_REMOVE ("fp", ALL_FP),
27271 ARM_ADD ("fp.sp", FPU_ARCH_VFP_V5_SP_D16),
27272 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
c19d1205 27273};
7ed4c4c5 27274
c19d1205
ZW
27275/* This list should, at a minimum, contain all the architecture names
27276 recognized by GCC. */
34ef62f4
AV
27277#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF, NULL }
27278#define ARM_ARCH_OPT2(N, V, DF, ext) \
27279 { N, sizeof (N) - 1, V, DF, ext##_ext_table }
0198d5e6 27280
e74cfd16 27281static const struct arm_arch_option_table arm_archs[] =
c19d1205 27282{
497d849d
TP
27283 ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
27284 ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
27285 ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
27286 ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
27287 ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
27288 ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
27289 ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
27290 ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
27291 ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
27292 ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
27293 ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
27294 ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
27295 ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
27296 ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
34ef62f4
AV
27297 ARM_ARCH_OPT2 ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP, armv5te),
27298 ARM_ARCH_OPT2 ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP, armv5te),
27299 ARM_ARCH_OPT2 ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP, armv5te),
27300 ARM_ARCH_OPT2 ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
27301 ARM_ARCH_OPT2 ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP, armv5te),
27302 ARM_ARCH_OPT2 ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP, armv5te),
27303 ARM_ARCH_OPT2 ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP, armv5te),
f33026a9
MW
27304 /* The official spelling of this variant is ARMv6KZ, the name "armv6zk" is
27305 kept to preserve existing behaviour. */
34ef62f4
AV
27306 ARM_ARCH_OPT2 ("armv6kz", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
27307 ARM_ARCH_OPT2 ("armv6zk", ARM_ARCH_V6KZ, FPU_ARCH_VFP, armv5te),
27308 ARM_ARCH_OPT2 ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP, armv5te),
27309 ARM_ARCH_OPT2 ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP, armv5te),
27310 ARM_ARCH_OPT2 ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP, armv5te),
f33026a9
MW
27311 /* The official spelling of this variant is ARMv6KZ, the name "armv6zkt2" is
27312 kept to preserve existing behaviour. */
34ef62f4
AV
27313 ARM_ARCH_OPT2 ("armv6kzt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
27314 ARM_ARCH_OPT2 ("armv6zkt2", ARM_ARCH_V6KZT2, FPU_ARCH_VFP, armv5te),
497d849d
TP
27315 ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
27316 ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
34ef62f4 27317 ARM_ARCH_OPT2 ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP, armv7),
c450d570
PB
27318 /* The official spelling of the ARMv7 profile variants is the dashed form.
27319 Accept the non-dashed form for compatibility with old toolchains. */
34ef62f4
AV
27320 ARM_ARCH_OPT2 ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
27321 ARM_ARCH_OPT2 ("armv7ve", ARM_ARCH_V7VE, FPU_ARCH_VFP, armv7ve),
27322 ARM_ARCH_OPT2 ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 27323 ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4
AV
27324 ARM_ARCH_OPT2 ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP, armv7a),
27325 ARM_ARCH_OPT2 ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP, armv7r),
497d849d 27326 ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
34ef62f4 27327 ARM_ARCH_OPT2 ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP, armv7em),
497d849d 27328 ARM_ARCH_OPT ("armv8-m.base", ARM_ARCH_V8M_BASE, FPU_ARCH_VFP),
34ef62f4
AV
27329 ARM_ARCH_OPT2 ("armv8-m.main", ARM_ARCH_V8M_MAIN, FPU_ARCH_VFP,
27330 armv8m_main),
e0991585
AV
27331 ARM_ARCH_OPT2 ("armv8.1-m.main", ARM_ARCH_V8_1M_MAIN, FPU_ARCH_VFP,
27332 armv8_1m_main),
34ef62f4
AV
27333 ARM_ARCH_OPT2 ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP, armv8a),
27334 ARM_ARCH_OPT2 ("armv8.1-a", ARM_ARCH_V8_1A, FPU_ARCH_VFP, armv81a),
27335 ARM_ARCH_OPT2 ("armv8.2-a", ARM_ARCH_V8_2A, FPU_ARCH_VFP, armv82a),
27336 ARM_ARCH_OPT2 ("armv8.3-a", ARM_ARCH_V8_3A, FPU_ARCH_VFP, armv82a),
27337 ARM_ARCH_OPT2 ("armv8-r", ARM_ARCH_V8R, FPU_ARCH_VFP, armv8r),
27338 ARM_ARCH_OPT2 ("armv8.4-a", ARM_ARCH_V8_4A, FPU_ARCH_VFP, armv84a),
27339 ARM_ARCH_OPT2 ("armv8.5-a", ARM_ARCH_V8_5A, FPU_ARCH_VFP, armv85a),
497d849d
TP
27340 ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
27341 ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
27342 ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2, FPU_ARCH_VFP),
34ef62f4 27343 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, NULL }
c19d1205 27344};
f3bad469 27345#undef ARM_ARCH_OPT
7ed4c4c5 27346
69133863 27347/* ISA extensions in the co-processor and main instruction set space. */
0198d5e6 27348
69133863 27349struct arm_option_extension_value_table
c19d1205 27350{
0198d5e6
TC
27351 const char * name;
27352 size_t name_len;
27353 const arm_feature_set merge_value;
27354 const arm_feature_set clear_value;
d942732e
TP
27355 /* List of architectures for which an extension is available. ARM_ARCH_NONE
27356 indicates that an extension is available for all architectures while
27357 ARM_ANY marks an empty entry. */
0198d5e6 27358 const arm_feature_set allowed_archs[2];
c19d1205 27359};
7ed4c4c5 27360
0198d5e6
TC
27361/* The following table must be in alphabetical order with a NULL last entry. */
27362
d942732e
TP
27363#define ARM_EXT_OPT(N, M, C, AA) { N, sizeof (N) - 1, M, C, { AA, ARM_ANY } }
27364#define ARM_EXT_OPT2(N, M, C, AA1, AA2) { N, sizeof (N) - 1, M, C, {AA1, AA2} }
0198d5e6 27365
34ef62f4
AV
27366/* DEPRECATED: Refrain from using this table to add any new extensions, instead
27367 use the context sensitive approach using arm_ext_table's. */
69133863 27368static const struct arm_option_extension_value_table arm_extensions[] =
c19d1205 27369{
823d2571
TG
27370 ARM_EXT_OPT ("crc", ARCH_CRC_ARMV8, ARM_FEATURE_COPROC (CRC_EXT_ARMV8),
27371 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
bca38921 27372 ARM_EXT_OPT ("crypto", FPU_ARCH_CRYPTO_NEON_VFP_ARMV8,
823d2571
TG
27373 ARM_FEATURE_COPROC (FPU_CRYPTO_ARMV8),
27374 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
c604a79a
JW
27375 ARM_EXT_OPT ("dotprod", FPU_ARCH_DOTPROD_NEON_VFP_ARMV8,
27376 ARM_FEATURE_COPROC (FPU_NEON_EXT_DOTPROD),
27377 ARM_ARCH_V8_2A),
15afaa63
TP
27378 ARM_EXT_OPT ("dsp", ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27379 ARM_FEATURE_CORE_LOW (ARM_EXT_V5ExP | ARM_EXT_V6_DSP),
27380 ARM_FEATURE_CORE (ARM_EXT_V7M, ARM_EXT2_V8M)),
823d2571
TG
27381 ARM_EXT_OPT ("fp", FPU_ARCH_VFP_ARMV8, ARM_FEATURE_COPROC (FPU_VFP_ARMV8),
27382 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
b8ec4e87
JW
27383 ARM_EXT_OPT ("fp16", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
27384 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST),
27385 ARM_ARCH_V8_2A),
01f48020
TC
27386 ARM_EXT_OPT ("fp16fml", ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
27387 | ARM_EXT2_FP16_FML),
27388 ARM_FEATURE_CORE_HIGH (ARM_EXT2_FP16_INST
27389 | ARM_EXT2_FP16_FML),
27390 ARM_ARCH_V8_2A),
d942732e 27391 ARM_EXT_OPT2 ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
823d2571 27392 ARM_FEATURE_CORE_LOW (ARM_EXT_ADIV | ARM_EXT_DIV),
d942732e
TP
27393 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
27394 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
3d030cdb
TP
27395 /* Duplicate entry for the purpose of allowing ARMv7 to match in presence of
27396 Thumb divide instruction. Due to this having the same name as the
27397 previous entry, this will be ignored when doing command-line parsing and
27398 only considered by build attribute selection code. */
27399 ARM_EXT_OPT ("idiv", ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
27400 ARM_FEATURE_CORE_LOW (ARM_EXT_DIV),
27401 ARM_FEATURE_CORE_LOW (ARM_EXT_V7)),
823d2571 27402 ARM_EXT_OPT ("iwmmxt",ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT),
d942732e 27403 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT), ARM_ARCH_NONE),
823d2571 27404 ARM_EXT_OPT ("iwmmxt2", ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2),
d942732e 27405 ARM_FEATURE_COPROC (ARM_CEXT_IWMMXT2), ARM_ARCH_NONE),
823d2571 27406 ARM_EXT_OPT ("maverick", ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK),
d942732e
TP
27407 ARM_FEATURE_COPROC (ARM_CEXT_MAVERICK), ARM_ARCH_NONE),
27408 ARM_EXT_OPT2 ("mp", ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
823d2571 27409 ARM_FEATURE_CORE_LOW (ARM_EXT_MP),
d942732e
TP
27410 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A),
27411 ARM_FEATURE_CORE_LOW (ARM_EXT_V7R)),
823d2571
TG
27412 ARM_EXT_OPT ("os", ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
27413 ARM_FEATURE_CORE_LOW (ARM_EXT_OS),
27414 ARM_FEATURE_CORE_LOW (ARM_EXT_V6M)),
ddfded2f
MW
27415 ARM_EXT_OPT ("pan", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PAN),
27416 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_PAN, 0),
ced40572 27417 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
dad0c3bf
SD
27418 ARM_EXT_OPT ("predres", ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
27419 ARM_FEATURE_CORE_HIGH (ARM_EXT2_PREDRES),
27420 ARM_ARCH_V8A),
4d1464f2
MW
27421 ARM_EXT_OPT ("ras", ARM_FEATURE_CORE_HIGH (ARM_EXT2_RAS),
27422 ARM_FEATURE (ARM_EXT_V8, ARM_EXT2_RAS, 0),
ced40572 27423 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
643afb90
MW
27424 ARM_EXT_OPT ("rdma", FPU_ARCH_NEON_VFP_ARMV8_1,
27425 ARM_FEATURE_COPROC (FPU_NEON_ARMV8 | FPU_NEON_EXT_RDMA),
ced40572 27426 ARM_FEATURE_CORE_HIGH (ARM_EXT2_V8A)),
7fadb25d
SD
27427 ARM_EXT_OPT ("sb", ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
27428 ARM_FEATURE_CORE_HIGH (ARM_EXT2_SB),
27429 ARM_ARCH_V8A),
d942732e 27430 ARM_EXT_OPT2 ("sec", ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
823d2571 27431 ARM_FEATURE_CORE_LOW (ARM_EXT_SEC),
d942732e
TP
27432 ARM_FEATURE_CORE_LOW (ARM_EXT_V6K),
27433 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
643afb90
MW
27434 ARM_EXT_OPT ("simd", FPU_ARCH_NEON_VFP_ARMV8,
27435 ARM_FEATURE_COPROC (FPU_NEON_ARMV8),
27436 ARM_FEATURE_CORE_LOW (ARM_EXT_V8)),
823d2571
TG
27437 ARM_EXT_OPT ("virt", ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT | ARM_EXT_ADIV
27438 | ARM_EXT_DIV),
27439 ARM_FEATURE_CORE_LOW (ARM_EXT_VIRT),
27440 ARM_FEATURE_CORE_LOW (ARM_EXT_V7A)),
27441 ARM_EXT_OPT ("xscale",ARM_FEATURE_COPROC (ARM_CEXT_XSCALE),
d942732e
TP
27442 ARM_FEATURE_COPROC (ARM_CEXT_XSCALE), ARM_ARCH_NONE),
27443 { NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE, { ARM_ARCH_NONE, ARM_ARCH_NONE } }
69133863 27444};
f3bad469 27445#undef ARM_EXT_OPT
69133863
MGD
27446
27447/* ISA floating-point and Advanced SIMD extensions. */
27448struct arm_option_fpu_value_table
27449{
0198d5e6
TC
27450 const char * name;
27451 const arm_feature_set value;
c19d1205 27452};
7ed4c4c5 27453
c19d1205
ZW
27454/* This list should, at a minimum, contain all the fpu names
27455 recognized by GCC. */
69133863 27456static const struct arm_option_fpu_value_table arm_fpus[] =
c19d1205
ZW
27457{
27458 {"softfpa", FPU_NONE},
27459 {"fpe", FPU_ARCH_FPE},
27460 {"fpe2", FPU_ARCH_FPE},
27461 {"fpe3", FPU_ARCH_FPA}, /* Third release supports LFM/SFM. */
27462 {"fpa", FPU_ARCH_FPA},
27463 {"fpa10", FPU_ARCH_FPA},
27464 {"fpa11", FPU_ARCH_FPA},
27465 {"arm7500fe", FPU_ARCH_FPA},
27466 {"softvfp", FPU_ARCH_VFP},
27467 {"softvfp+vfp", FPU_ARCH_VFP_V2},
27468 {"vfp", FPU_ARCH_VFP_V2},
27469 {"vfp9", FPU_ARCH_VFP_V2},
d5e0ba9c 27470 {"vfp3", FPU_ARCH_VFP_V3}, /* Undocumented, use vfpv3. */
c19d1205
ZW
27471 {"vfp10", FPU_ARCH_VFP_V2},
27472 {"vfp10-r0", FPU_ARCH_VFP_V1},
27473 {"vfpxd", FPU_ARCH_VFP_V1xD},
b1cc4aeb
PB
27474 {"vfpv2", FPU_ARCH_VFP_V2},
27475 {"vfpv3", FPU_ARCH_VFP_V3},
62f3b8c8 27476 {"vfpv3-fp16", FPU_ARCH_VFP_V3_FP16},
b1cc4aeb 27477 {"vfpv3-d16", FPU_ARCH_VFP_V3D16},
62f3b8c8
PB
27478 {"vfpv3-d16-fp16", FPU_ARCH_VFP_V3D16_FP16},
27479 {"vfpv3xd", FPU_ARCH_VFP_V3xD},
27480 {"vfpv3xd-fp16", FPU_ARCH_VFP_V3xD_FP16},
c19d1205
ZW
27481 {"arm1020t", FPU_ARCH_VFP_V1},
27482 {"arm1020e", FPU_ARCH_VFP_V2},
d5e0ba9c 27483 {"arm1136jfs", FPU_ARCH_VFP_V2}, /* Undocumented, use arm1136jf-s. */
c19d1205
ZW
27484 {"arm1136jf-s", FPU_ARCH_VFP_V2},
27485 {"maverick", FPU_ARCH_MAVERICK},
d5e0ba9c 27486 {"neon", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
d3375ddd 27487 {"neon-vfpv3", FPU_ARCH_VFP_V3_PLUS_NEON_V1},
8e79c3df 27488 {"neon-fp16", FPU_ARCH_NEON_FP16},
62f3b8c8
PB
27489 {"vfpv4", FPU_ARCH_VFP_V4},
27490 {"vfpv4-d16", FPU_ARCH_VFP_V4D16},
ada65aa3 27491 {"fpv4-sp-d16", FPU_ARCH_VFP_V4_SP_D16},
a715796b
TG
27492 {"fpv5-d16", FPU_ARCH_VFP_V5D16},
27493 {"fpv5-sp-d16", FPU_ARCH_VFP_V5_SP_D16},
62f3b8c8 27494 {"neon-vfpv4", FPU_ARCH_NEON_VFP_V4},
bca38921
MGD
27495 {"fp-armv8", FPU_ARCH_VFP_ARMV8},
27496 {"neon-fp-armv8", FPU_ARCH_NEON_VFP_ARMV8},
27497 {"crypto-neon-fp-armv8",
27498 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8},
d6b4b13e 27499 {"neon-fp-armv8.1", FPU_ARCH_NEON_VFP_ARMV8_1},
081e4c7d
MW
27500 {"crypto-neon-fp-armv8.1",
27501 FPU_ARCH_CRYPTO_NEON_VFP_ARMV8_1},
e74cfd16
PB
27502 {NULL, ARM_ARCH_NONE}
27503};
27504
27505struct arm_option_value_table
27506{
e0471c16 27507 const char *name;
e74cfd16 27508 long value;
c19d1205 27509};
7ed4c4c5 27510
e74cfd16 27511static const struct arm_option_value_table arm_float_abis[] =
c19d1205
ZW
27512{
27513 {"hard", ARM_FLOAT_ABI_HARD},
27514 {"softfp", ARM_FLOAT_ABI_SOFTFP},
27515 {"soft", ARM_FLOAT_ABI_SOFT},
e74cfd16 27516 {NULL, 0}
c19d1205 27517};
7ed4c4c5 27518
c19d1205 27519#ifdef OBJ_ELF
3a4a14e9 27520/* We only know how to output GNU and ver 4/5 (AAELF) formats. */
e74cfd16 27521static const struct arm_option_value_table arm_eabis[] =
c19d1205
ZW
27522{
27523 {"gnu", EF_ARM_EABI_UNKNOWN},
27524 {"4", EF_ARM_EABI_VER4},
3a4a14e9 27525 {"5", EF_ARM_EABI_VER5},
e74cfd16 27526 {NULL, 0}
c19d1205
ZW
27527};
27528#endif
7ed4c4c5 27529
c19d1205
ZW
27530struct arm_long_option_table
27531{
0198d5e6 27532 const char * option; /* Substring to match. */
e0471c16 27533 const char * help; /* Help information. */
17b9d67d 27534 int (* func) (const char * subopt); /* Function to decode sub-option. */
e0471c16 27535 const char * deprecated; /* If non-null, print this message. */
c19d1205 27536};
7ed4c4c5 27537
c921be7d 27538static bfd_boolean
c168ce07 27539arm_parse_extension (const char *str, const arm_feature_set *opt_set,
34ef62f4
AV
27540 arm_feature_set *ext_set,
27541 const struct arm_ext_table *ext_table)
7ed4c4c5 27542{
69133863 27543 /* We insist on extensions being specified in alphabetical order, and with
fa94de6b
RM
27544 extensions being added before being removed. We achieve this by having
27545 the global ARM_EXTENSIONS table in alphabetical order, and using the
69133863 27546 ADDING_VALUE variable to indicate whether we are adding an extension (1)
fa94de6b 27547 or removing it (0) and only allowing it to change in the order
69133863
MGD
27548 -1 -> 1 -> 0. */
27549 const struct arm_option_extension_value_table * opt = NULL;
d942732e 27550 const arm_feature_set arm_any = ARM_ANY;
69133863
MGD
27551 int adding_value = -1;
27552
c19d1205 27553 while (str != NULL && *str != 0)
7ed4c4c5 27554 {
82b8a785 27555 const char *ext;
f3bad469 27556 size_t len;
7ed4c4c5 27557
c19d1205
ZW
27558 if (*str != '+')
27559 {
27560 as_bad (_("invalid architectural extension"));
c921be7d 27561 return FALSE;
c19d1205 27562 }
7ed4c4c5 27563
c19d1205
ZW
27564 str++;
27565 ext = strchr (str, '+');
7ed4c4c5 27566
c19d1205 27567 if (ext != NULL)
f3bad469 27568 len = ext - str;
c19d1205 27569 else
f3bad469 27570 len = strlen (str);
7ed4c4c5 27571
f3bad469 27572 if (len >= 2 && strncmp (str, "no", 2) == 0)
69133863
MGD
27573 {
27574 if (adding_value != 0)
27575 {
27576 adding_value = 0;
27577 opt = arm_extensions;
27578 }
27579
f3bad469 27580 len -= 2;
69133863
MGD
27581 str += 2;
27582 }
f3bad469 27583 else if (len > 0)
69133863
MGD
27584 {
27585 if (adding_value == -1)
27586 {
27587 adding_value = 1;
27588 opt = arm_extensions;
27589 }
27590 else if (adding_value != 1)
27591 {
27592 as_bad (_("must specify extensions to add before specifying "
27593 "those to remove"));
27594 return FALSE;
27595 }
27596 }
27597
f3bad469 27598 if (len == 0)
c19d1205
ZW
27599 {
27600 as_bad (_("missing architectural extension"));
c921be7d 27601 return FALSE;
c19d1205 27602 }
7ed4c4c5 27603
69133863
MGD
27604 gas_assert (adding_value != -1);
27605 gas_assert (opt != NULL);
27606
34ef62f4
AV
27607 if (ext_table != NULL)
27608 {
27609 const struct arm_ext_table * ext_opt = ext_table;
27610 bfd_boolean found = FALSE;
27611 for (; ext_opt->name != NULL; ext_opt++)
27612 if (ext_opt->name_len == len
27613 && strncmp (ext_opt->name, str, len) == 0)
27614 {
27615 if (adding_value)
27616 {
27617 if (ARM_FEATURE_ZERO (ext_opt->merge))
27618 /* TODO: Option not supported. When we remove the
27619 legacy table this case should error out. */
27620 continue;
27621
27622 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, ext_opt->merge);
27623 }
27624 else
27625 {
27626 if (ARM_FEATURE_ZERO (ext_opt->clear))
27627 /* TODO: Option not supported. When we remove the
27628 legacy table this case should error out. */
27629 continue;
27630 ARM_CLEAR_FEATURE (*ext_set, *ext_set, ext_opt->clear);
27631 }
27632 found = TRUE;
27633 break;
27634 }
27635 if (found)
27636 {
27637 str = ext;
27638 continue;
27639 }
27640 }
27641
69133863
MGD
27642 /* Scan over the options table trying to find an exact match. */
27643 for (; opt->name != NULL; opt++)
f3bad469 27644 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 27645 {
d942732e
TP
27646 int i, nb_allowed_archs =
27647 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
69133863 27648 /* Check we can apply the extension to this architecture. */
d942732e
TP
27649 for (i = 0; i < nb_allowed_archs; i++)
27650 {
27651 /* Empty entry. */
27652 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_any))
27653 continue;
c168ce07 27654 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *opt_set))
d942732e
TP
27655 break;
27656 }
27657 if (i == nb_allowed_archs)
69133863
MGD
27658 {
27659 as_bad (_("extension does not apply to the base architecture"));
27660 return FALSE;
27661 }
27662
27663 /* Add or remove the extension. */
27664 if (adding_value)
4d354d8b 27665 ARM_MERGE_FEATURE_SETS (*ext_set, *ext_set, opt->merge_value);
69133863 27666 else
4d354d8b 27667 ARM_CLEAR_FEATURE (*ext_set, *ext_set, opt->clear_value);
69133863 27668
3d030cdb
TP
27669 /* Allowing Thumb division instructions for ARMv7 in autodetection
27670 rely on this break so that duplicate extensions (extensions
27671 with the same name as a previous extension in the list) are not
27672 considered for command-line parsing. */
c19d1205
ZW
27673 break;
27674 }
7ed4c4c5 27675
c19d1205
ZW
27676 if (opt->name == NULL)
27677 {
69133863
MGD
27678 /* Did we fail to find an extension because it wasn't specified in
27679 alphabetical order, or because it does not exist? */
27680
27681 for (opt = arm_extensions; opt->name != NULL; opt++)
f3bad469 27682 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
69133863
MGD
27683 break;
27684
27685 if (opt->name == NULL)
27686 as_bad (_("unknown architectural extension `%s'"), str);
27687 else
27688 as_bad (_("architectural extensions must be specified in "
27689 "alphabetical order"));
27690
c921be7d 27691 return FALSE;
c19d1205 27692 }
69133863
MGD
27693 else
27694 {
27695 /* We should skip the extension we've just matched the next time
27696 round. */
27697 opt++;
27698 }
7ed4c4c5 27699
c19d1205
ZW
27700 str = ext;
27701 };
7ed4c4c5 27702
c921be7d 27703 return TRUE;
c19d1205 27704}
7ed4c4c5 27705
c921be7d 27706static bfd_boolean
17b9d67d 27707arm_parse_cpu (const char *str)
7ed4c4c5 27708{
f3bad469 27709 const struct arm_cpu_option_table *opt;
82b8a785 27710 const char *ext = strchr (str, '+');
f3bad469 27711 size_t len;
7ed4c4c5 27712
c19d1205 27713 if (ext != NULL)
f3bad469 27714 len = ext - str;
7ed4c4c5 27715 else
f3bad469 27716 len = strlen (str);
7ed4c4c5 27717
f3bad469 27718 if (len == 0)
7ed4c4c5 27719 {
c19d1205 27720 as_bad (_("missing cpu name `%s'"), str);
c921be7d 27721 return FALSE;
7ed4c4c5
NC
27722 }
27723
c19d1205 27724 for (opt = arm_cpus; opt->name != NULL; opt++)
f3bad469 27725 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 27726 {
c168ce07 27727 mcpu_cpu_opt = &opt->value;
4d354d8b
TP
27728 if (mcpu_ext_opt == NULL)
27729 mcpu_ext_opt = XNEW (arm_feature_set);
27730 *mcpu_ext_opt = opt->ext;
e74cfd16 27731 mcpu_fpu_opt = &opt->default_fpu;
ee065d83 27732 if (opt->canonical_name)
ef8e6722
JW
27733 {
27734 gas_assert (sizeof selected_cpu_name > strlen (opt->canonical_name));
27735 strcpy (selected_cpu_name, opt->canonical_name);
27736 }
ee065d83
PB
27737 else
27738 {
f3bad469 27739 size_t i;
c921be7d 27740
ef8e6722
JW
27741 if (len >= sizeof selected_cpu_name)
27742 len = (sizeof selected_cpu_name) - 1;
27743
f3bad469 27744 for (i = 0; i < len; i++)
ee065d83
PB
27745 selected_cpu_name[i] = TOUPPER (opt->name[i]);
27746 selected_cpu_name[i] = 0;
27747 }
7ed4c4c5 27748
c19d1205 27749 if (ext != NULL)
34ef62f4 27750 return arm_parse_extension (ext, mcpu_cpu_opt, mcpu_ext_opt, NULL);
7ed4c4c5 27751
c921be7d 27752 return TRUE;
c19d1205 27753 }
7ed4c4c5 27754
c19d1205 27755 as_bad (_("unknown cpu `%s'"), str);
c921be7d 27756 return FALSE;
7ed4c4c5
NC
27757}
27758
c921be7d 27759static bfd_boolean
17b9d67d 27760arm_parse_arch (const char *str)
7ed4c4c5 27761{
e74cfd16 27762 const struct arm_arch_option_table *opt;
82b8a785 27763 const char *ext = strchr (str, '+');
f3bad469 27764 size_t len;
7ed4c4c5 27765
c19d1205 27766 if (ext != NULL)
f3bad469 27767 len = ext - str;
7ed4c4c5 27768 else
f3bad469 27769 len = strlen (str);
7ed4c4c5 27770
f3bad469 27771 if (len == 0)
7ed4c4c5 27772 {
c19d1205 27773 as_bad (_("missing architecture name `%s'"), str);
c921be7d 27774 return FALSE;
7ed4c4c5
NC
27775 }
27776
c19d1205 27777 for (opt = arm_archs; opt->name != NULL; opt++)
f3bad469 27778 if (opt->name_len == len && strncmp (opt->name, str, len) == 0)
c19d1205 27779 {
e74cfd16 27780 march_cpu_opt = &opt->value;
4d354d8b
TP
27781 if (march_ext_opt == NULL)
27782 march_ext_opt = XNEW (arm_feature_set);
27783 *march_ext_opt = arm_arch_none;
e74cfd16 27784 march_fpu_opt = &opt->default_fpu;
5f4273c7 27785 strcpy (selected_cpu_name, opt->name);
7ed4c4c5 27786
c19d1205 27787 if (ext != NULL)
34ef62f4
AV
27788 return arm_parse_extension (ext, march_cpu_opt, march_ext_opt,
27789 opt->ext_table);
7ed4c4c5 27790
c921be7d 27791 return TRUE;
c19d1205
ZW
27792 }
27793
27794 as_bad (_("unknown architecture `%s'\n"), str);
c921be7d 27795 return FALSE;
7ed4c4c5 27796}
eb043451 27797
c921be7d 27798static bfd_boolean
17b9d67d 27799arm_parse_fpu (const char * str)
c19d1205 27800{
69133863 27801 const struct arm_option_fpu_value_table * opt;
b99bd4ef 27802
c19d1205
ZW
27803 for (opt = arm_fpus; opt->name != NULL; opt++)
27804 if (streq (opt->name, str))
27805 {
e74cfd16 27806 mfpu_opt = &opt->value;
c921be7d 27807 return TRUE;
c19d1205 27808 }
b99bd4ef 27809
c19d1205 27810 as_bad (_("unknown floating point format `%s'\n"), str);
c921be7d 27811 return FALSE;
c19d1205
ZW
27812}
27813
c921be7d 27814static bfd_boolean
17b9d67d 27815arm_parse_float_abi (const char * str)
b99bd4ef 27816{
e74cfd16 27817 const struct arm_option_value_table * opt;
b99bd4ef 27818
c19d1205
ZW
27819 for (opt = arm_float_abis; opt->name != NULL; opt++)
27820 if (streq (opt->name, str))
27821 {
27822 mfloat_abi_opt = opt->value;
c921be7d 27823 return TRUE;
c19d1205 27824 }
cc8a6dd0 27825
c19d1205 27826 as_bad (_("unknown floating point abi `%s'\n"), str);
c921be7d 27827 return FALSE;
c19d1205 27828}
b99bd4ef 27829
c19d1205 27830#ifdef OBJ_ELF
c921be7d 27831static bfd_boolean
17b9d67d 27832arm_parse_eabi (const char * str)
c19d1205 27833{
e74cfd16 27834 const struct arm_option_value_table *opt;
cc8a6dd0 27835
c19d1205
ZW
27836 for (opt = arm_eabis; opt->name != NULL; opt++)
27837 if (streq (opt->name, str))
27838 {
27839 meabi_flags = opt->value;
c921be7d 27840 return TRUE;
c19d1205
ZW
27841 }
27842 as_bad (_("unknown EABI `%s'\n"), str);
c921be7d 27843 return FALSE;
c19d1205
ZW
27844}
27845#endif
cc8a6dd0 27846
c921be7d 27847static bfd_boolean
17b9d67d 27848arm_parse_it_mode (const char * str)
e07e6e58 27849{
c921be7d 27850 bfd_boolean ret = TRUE;
e07e6e58
NC
27851
27852 if (streq ("arm", str))
27853 implicit_it_mode = IMPLICIT_IT_MODE_ARM;
27854 else if (streq ("thumb", str))
27855 implicit_it_mode = IMPLICIT_IT_MODE_THUMB;
27856 else if (streq ("always", str))
27857 implicit_it_mode = IMPLICIT_IT_MODE_ALWAYS;
27858 else if (streq ("never", str))
27859 implicit_it_mode = IMPLICIT_IT_MODE_NEVER;
27860 else
27861 {
27862 as_bad (_("unknown implicit IT mode `%s', should be "\
477330fc 27863 "arm, thumb, always, or never."), str);
c921be7d 27864 ret = FALSE;
e07e6e58
NC
27865 }
27866
27867 return ret;
27868}
27869
2e6976a8 27870static bfd_boolean
17b9d67d 27871arm_ccs_mode (const char * unused ATTRIBUTE_UNUSED)
2e6976a8
DG
27872{
27873 codecomposer_syntax = TRUE;
27874 arm_comment_chars[0] = ';';
27875 arm_line_separator_chars[0] = 0;
27876 return TRUE;
27877}
27878
c19d1205
ZW
27879struct arm_long_option_table arm_long_opts[] =
27880{
27881 {"mcpu=", N_("<cpu name>\t assemble for CPU <cpu name>"),
27882 arm_parse_cpu, NULL},
27883 {"march=", N_("<arch name>\t assemble for architecture <arch name>"),
27884 arm_parse_arch, NULL},
27885 {"mfpu=", N_("<fpu name>\t assemble for FPU architecture <fpu name>"),
27886 arm_parse_fpu, NULL},
27887 {"mfloat-abi=", N_("<abi>\t assemble for floating point ABI <abi>"),
27888 arm_parse_float_abi, NULL},
27889#ifdef OBJ_ELF
7fac0536 27890 {"meabi=", N_("<ver>\t\t assemble for eabi version <ver>"),
c19d1205
ZW
27891 arm_parse_eabi, NULL},
27892#endif
e07e6e58
NC
27893 {"mimplicit-it=", N_("<mode>\t controls implicit insertion of IT instructions"),
27894 arm_parse_it_mode, NULL},
2e6976a8
DG
27895 {"mccs", N_("\t\t\t TI CodeComposer Studio syntax compatibility mode"),
27896 arm_ccs_mode, NULL},
c19d1205
ZW
27897 {NULL, NULL, 0, NULL}
27898};
cc8a6dd0 27899
c19d1205 27900int
17b9d67d 27901md_parse_option (int c, const char * arg)
c19d1205
ZW
27902{
27903 struct arm_option_table *opt;
e74cfd16 27904 const struct arm_legacy_option_table *fopt;
c19d1205 27905 struct arm_long_option_table *lopt;
b99bd4ef 27906
c19d1205 27907 switch (c)
b99bd4ef 27908 {
c19d1205
ZW
27909#ifdef OPTION_EB
27910 case OPTION_EB:
27911 target_big_endian = 1;
27912 break;
27913#endif
cc8a6dd0 27914
c19d1205
ZW
27915#ifdef OPTION_EL
27916 case OPTION_EL:
27917 target_big_endian = 0;
27918 break;
27919#endif
b99bd4ef 27920
845b51d6
PB
27921 case OPTION_FIX_V4BX:
27922 fix_v4bx = TRUE;
27923 break;
27924
18a20338
CL
27925#ifdef OBJ_ELF
27926 case OPTION_FDPIC:
27927 arm_fdpic = TRUE;
27928 break;
27929#endif /* OBJ_ELF */
27930
c19d1205
ZW
27931 case 'a':
27932 /* Listing option. Just ignore these, we don't support additional
27933 ones. */
27934 return 0;
b99bd4ef 27935
c19d1205
ZW
27936 default:
27937 for (opt = arm_opts; opt->option != NULL; opt++)
27938 {
27939 if (c == opt->option[0]
27940 && ((arg == NULL && opt->option[1] == 0)
27941 || streq (arg, opt->option + 1)))
27942 {
c19d1205 27943 /* If the option is deprecated, tell the user. */
278df34e 27944 if (warn_on_deprecated && opt->deprecated != NULL)
c19d1205
ZW
27945 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
27946 arg ? arg : "", _(opt->deprecated));
b99bd4ef 27947
c19d1205
ZW
27948 if (opt->var != NULL)
27949 *opt->var = opt->value;
cc8a6dd0 27950
c19d1205
ZW
27951 return 1;
27952 }
27953 }
b99bd4ef 27954
e74cfd16
PB
27955 for (fopt = arm_legacy_opts; fopt->option != NULL; fopt++)
27956 {
27957 if (c == fopt->option[0]
27958 && ((arg == NULL && fopt->option[1] == 0)
27959 || streq (arg, fopt->option + 1)))
27960 {
e74cfd16 27961 /* If the option is deprecated, tell the user. */
278df34e 27962 if (warn_on_deprecated && fopt->deprecated != NULL)
e74cfd16
PB
27963 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c,
27964 arg ? arg : "", _(fopt->deprecated));
e74cfd16
PB
27965
27966 if (fopt->var != NULL)
27967 *fopt->var = &fopt->value;
27968
27969 return 1;
27970 }
27971 }
27972
c19d1205
ZW
27973 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
27974 {
27975 /* These options are expected to have an argument. */
27976 if (c == lopt->option[0]
27977 && arg != NULL
27978 && strncmp (arg, lopt->option + 1,
27979 strlen (lopt->option + 1)) == 0)
27980 {
c19d1205 27981 /* If the option is deprecated, tell the user. */
278df34e 27982 if (warn_on_deprecated && lopt->deprecated != NULL)
c19d1205
ZW
27983 as_tsktsk (_("option `-%c%s' is deprecated: %s"), c, arg,
27984 _(lopt->deprecated));
b99bd4ef 27985
c19d1205
ZW
27986 /* Call the sup-option parser. */
27987 return lopt->func (arg + strlen (lopt->option) - 1);
27988 }
27989 }
a737bd4d 27990
c19d1205
ZW
27991 return 0;
27992 }
a394c00f 27993
c19d1205
ZW
27994 return 1;
27995}
a394c00f 27996
c19d1205
ZW
27997void
27998md_show_usage (FILE * fp)
a394c00f 27999{
c19d1205
ZW
28000 struct arm_option_table *opt;
28001 struct arm_long_option_table *lopt;
a394c00f 28002
c19d1205 28003 fprintf (fp, _(" ARM-specific assembler options:\n"));
a394c00f 28004
c19d1205
ZW
28005 for (opt = arm_opts; opt->option != NULL; opt++)
28006 if (opt->help != NULL)
28007 fprintf (fp, " -%-23s%s\n", opt->option, _(opt->help));
a394c00f 28008
c19d1205
ZW
28009 for (lopt = arm_long_opts; lopt->option != NULL; lopt++)
28010 if (lopt->help != NULL)
28011 fprintf (fp, " -%s%s\n", lopt->option, _(lopt->help));
a394c00f 28012
c19d1205
ZW
28013#ifdef OPTION_EB
28014 fprintf (fp, _("\
28015 -EB assemble code for a big-endian cpu\n"));
a394c00f
NC
28016#endif
28017
c19d1205
ZW
28018#ifdef OPTION_EL
28019 fprintf (fp, _("\
28020 -EL assemble code for a little-endian cpu\n"));
a737bd4d 28021#endif
845b51d6
PB
28022
28023 fprintf (fp, _("\
28024 --fix-v4bx Allow BX in ARMv4 code\n"));
18a20338
CL
28025
28026#ifdef OBJ_ELF
28027 fprintf (fp, _("\
28028 --fdpic generate an FDPIC object file\n"));
28029#endif /* OBJ_ELF */
c19d1205 28030}
ee065d83 28031
ee065d83 28032#ifdef OBJ_ELF
0198d5e6 28033
62b3e311
PB
28034typedef struct
28035{
28036 int val;
28037 arm_feature_set flags;
28038} cpu_arch_ver_table;
28039
2c6b98ea
TP
28040/* Mapping from CPU features to EABI CPU arch values. Table must be sorted
28041 chronologically for architectures, with an exception for ARMv6-M and
28042 ARMv6S-M due to legacy reasons. No new architecture should have a
28043 special case. This allows for build attribute selection results to be
28044 stable when new architectures are added. */
62b3e311
PB
28045static const cpu_arch_ver_table cpu_arch_ver[] =
28046{
031254f2
AV
28047 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V1},
28048 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2},
28049 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V2S},
28050 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3},
28051 {TAG_CPU_ARCH_PRE_V4, ARM_ARCH_V3M},
28052 {TAG_CPU_ARCH_V4, ARM_ARCH_V4xM},
28053 {TAG_CPU_ARCH_V4, ARM_ARCH_V4},
28054 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4TxM},
28055 {TAG_CPU_ARCH_V4T, ARM_ARCH_V4T},
28056 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5xM},
28057 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5},
28058 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5TxM},
28059 {TAG_CPU_ARCH_V5T, ARM_ARCH_V5T},
28060 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TExP},
28061 {TAG_CPU_ARCH_V5TE, ARM_ARCH_V5TE},
28062 {TAG_CPU_ARCH_V5TEJ, ARM_ARCH_V5TEJ},
28063 {TAG_CPU_ARCH_V6, ARM_ARCH_V6},
28064 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6Z},
28065 {TAG_CPU_ARCH_V6KZ, ARM_ARCH_V6KZ},
28066 {TAG_CPU_ARCH_V6K, ARM_ARCH_V6K},
28067 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6T2},
28068 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KT2},
28069 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6ZT2},
28070 {TAG_CPU_ARCH_V6T2, ARM_ARCH_V6KZT2},
2c6b98ea
TP
28071
28072 /* When assembling a file with only ARMv6-M or ARMv6S-M instruction, GNU as
28073 always selected build attributes to match those of ARMv6-M
28074 (resp. ARMv6S-M). However, due to these architectures being a strict
28075 subset of ARMv7-M in terms of instructions available, ARMv7-M attributes
28076 would be selected when fully respecting chronology of architectures.
28077 It is thus necessary to make a special case of ARMv6-M and ARMv6S-M and
28078 move them before ARMv7 architectures. */
031254f2
AV
28079 {TAG_CPU_ARCH_V6_M, ARM_ARCH_V6M},
28080 {TAG_CPU_ARCH_V6S_M, ARM_ARCH_V6SM},
28081
28082 {TAG_CPU_ARCH_V7, ARM_ARCH_V7},
28083 {TAG_CPU_ARCH_V7, ARM_ARCH_V7A},
28084 {TAG_CPU_ARCH_V7, ARM_ARCH_V7R},
28085 {TAG_CPU_ARCH_V7, ARM_ARCH_V7M},
28086 {TAG_CPU_ARCH_V7, ARM_ARCH_V7VE},
28087 {TAG_CPU_ARCH_V7E_M, ARM_ARCH_V7EM},
28088 {TAG_CPU_ARCH_V8, ARM_ARCH_V8A},
28089 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_1A},
28090 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_2A},
28091 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_3A},
28092 {TAG_CPU_ARCH_V8M_BASE, ARM_ARCH_V8M_BASE},
28093 {TAG_CPU_ARCH_V8M_MAIN, ARM_ARCH_V8M_MAIN},
28094 {TAG_CPU_ARCH_V8R, ARM_ARCH_V8R},
28095 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_4A},
28096 {TAG_CPU_ARCH_V8, ARM_ARCH_V8_5A},
28097 {TAG_CPU_ARCH_V8_1M_MAIN, ARM_ARCH_V8_1M_MAIN},
28098 {-1, ARM_ARCH_NONE}
62b3e311
PB
28099};
28100
ee3c0378 28101/* Set an attribute if it has not already been set by the user. */
0198d5e6 28102
ee3c0378
AS
28103static void
28104aeabi_set_attribute_int (int tag, int value)
28105{
28106 if (tag < 1
28107 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
28108 || !attributes_set_explicitly[tag])
28109 bfd_elf_add_proc_attr_int (stdoutput, tag, value);
28110}
28111
28112static void
28113aeabi_set_attribute_string (int tag, const char *value)
28114{
28115 if (tag < 1
28116 || tag >= NUM_KNOWN_OBJ_ATTRIBUTES
28117 || !attributes_set_explicitly[tag])
28118 bfd_elf_add_proc_attr_string (stdoutput, tag, value);
28119}
28120
2c6b98ea
TP
28121/* Return whether features in the *NEEDED feature set are available via
28122 extensions for the architecture whose feature set is *ARCH_FSET. */
0198d5e6 28123
2c6b98ea
TP
28124static bfd_boolean
28125have_ext_for_needed_feat_p (const arm_feature_set *arch_fset,
28126 const arm_feature_set *needed)
28127{
28128 int i, nb_allowed_archs;
28129 arm_feature_set ext_fset;
28130 const struct arm_option_extension_value_table *opt;
28131
28132 ext_fset = arm_arch_none;
28133 for (opt = arm_extensions; opt->name != NULL; opt++)
28134 {
28135 /* Extension does not provide any feature we need. */
28136 if (!ARM_CPU_HAS_FEATURE (*needed, opt->merge_value))
28137 continue;
28138
28139 nb_allowed_archs =
28140 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[0]);
28141 for (i = 0; i < nb_allowed_archs; i++)
28142 {
28143 /* Empty entry. */
28144 if (ARM_FEATURE_EQUAL (opt->allowed_archs[i], arm_arch_any))
28145 break;
28146
28147 /* Extension is available, add it. */
28148 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], *arch_fset))
28149 ARM_MERGE_FEATURE_SETS (ext_fset, ext_fset, opt->merge_value);
28150 }
28151 }
28152
28153 /* Can we enable all features in *needed? */
28154 return ARM_FSET_CPU_SUBSET (*needed, ext_fset);
28155}
28156
28157/* Select value for Tag_CPU_arch and Tag_CPU_arch_profile build attributes for
28158 a given architecture feature set *ARCH_EXT_FSET including extension feature
28159 set *EXT_FSET. Selection logic used depend on EXACT_MATCH:
28160 - if true, check for an exact match of the architecture modulo extensions;
28161 - otherwise, select build attribute value of the first superset
28162 architecture released so that results remains stable when new architectures
28163 are added.
28164 For -march/-mcpu=all the build attribute value of the most featureful
28165 architecture is returned. Tag_CPU_arch_profile result is returned in
28166 PROFILE. */
0198d5e6 28167
2c6b98ea
TP
28168static int
28169get_aeabi_cpu_arch_from_fset (const arm_feature_set *arch_ext_fset,
28170 const arm_feature_set *ext_fset,
28171 char *profile, int exact_match)
28172{
28173 arm_feature_set arch_fset;
28174 const cpu_arch_ver_table *p_ver, *p_ver_ret = NULL;
28175
28176 /* Select most featureful architecture with all its extensions if building
28177 for -march=all as the feature sets used to set build attributes. */
28178 if (ARM_FEATURE_EQUAL (*arch_ext_fset, arm_arch_any))
28179 {
28180 /* Force revisiting of decision for each new architecture. */
031254f2 28181 gas_assert (MAX_TAG_CPU_ARCH <= TAG_CPU_ARCH_V8_1M_MAIN);
2c6b98ea
TP
28182 *profile = 'A';
28183 return TAG_CPU_ARCH_V8;
28184 }
28185
28186 ARM_CLEAR_FEATURE (arch_fset, *arch_ext_fset, *ext_fset);
28187
28188 for (p_ver = cpu_arch_ver; p_ver->val != -1; p_ver++)
28189 {
28190 arm_feature_set known_arch_fset;
28191
28192 ARM_CLEAR_FEATURE (known_arch_fset, p_ver->flags, fpu_any);
28193 if (exact_match)
28194 {
28195 /* Base architecture match user-specified architecture and
28196 extensions, eg. ARMv6S-M matching -march=armv6-m+os. */
28197 if (ARM_FEATURE_EQUAL (*arch_ext_fset, known_arch_fset))
28198 {
28199 p_ver_ret = p_ver;
28200 goto found;
28201 }
28202 /* Base architecture match user-specified architecture only
28203 (eg. ARMv6-M in the same case as above). Record it in case we
28204 find a match with above condition. */
28205 else if (p_ver_ret == NULL
28206 && ARM_FEATURE_EQUAL (arch_fset, known_arch_fset))
28207 p_ver_ret = p_ver;
28208 }
28209 else
28210 {
28211
28212 /* Architecture has all features wanted. */
28213 if (ARM_FSET_CPU_SUBSET (arch_fset, known_arch_fset))
28214 {
28215 arm_feature_set added_fset;
28216
28217 /* Compute features added by this architecture over the one
28218 recorded in p_ver_ret. */
28219 if (p_ver_ret != NULL)
28220 ARM_CLEAR_FEATURE (added_fset, known_arch_fset,
28221 p_ver_ret->flags);
28222 /* First architecture that match incl. with extensions, or the
28223 only difference in features over the recorded match is
28224 features that were optional and are now mandatory. */
28225 if (p_ver_ret == NULL
28226 || ARM_FSET_CPU_SUBSET (added_fset, arch_fset))
28227 {
28228 p_ver_ret = p_ver;
28229 goto found;
28230 }
28231 }
28232 else if (p_ver_ret == NULL)
28233 {
28234 arm_feature_set needed_ext_fset;
28235
28236 ARM_CLEAR_FEATURE (needed_ext_fset, arch_fset, known_arch_fset);
28237
28238 /* Architecture has all features needed when using some
28239 extensions. Record it and continue searching in case there
28240 exist an architecture providing all needed features without
28241 the need for extensions (eg. ARMv6S-M Vs ARMv6-M with
28242 OS extension). */
28243 if (have_ext_for_needed_feat_p (&known_arch_fset,
28244 &needed_ext_fset))
28245 p_ver_ret = p_ver;
28246 }
28247 }
28248 }
28249
28250 if (p_ver_ret == NULL)
28251 return -1;
28252
28253found:
28254 /* Tag_CPU_arch_profile. */
28255 if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7a)
28256 || ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8)
28257 || (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_atomics)
28258 && !ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v8m_m_only)))
28259 *profile = 'A';
28260 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_v7r))
28261 *profile = 'R';
28262 else if (ARM_CPU_HAS_FEATURE (p_ver_ret->flags, arm_ext_m))
28263 *profile = 'M';
28264 else
28265 *profile = '\0';
28266 return p_ver_ret->val;
28267}
28268
ee065d83 28269/* Set the public EABI object attributes. */
0198d5e6 28270
c168ce07 28271static void
ee065d83
PB
28272aeabi_set_public_attributes (void)
28273{
b90d5ba0 28274 char profile = '\0';
2c6b98ea 28275 int arch = -1;
90ec0d68 28276 int virt_sec = 0;
bca38921 28277 int fp16_optional = 0;
2c6b98ea
TP
28278 int skip_exact_match = 0;
28279 arm_feature_set flags, flags_arch, flags_ext;
ee065d83 28280
54bab281
TP
28281 /* Autodetection mode, choose the architecture based the instructions
28282 actually used. */
28283 if (no_cpu_selected ())
28284 {
28285 ARM_MERGE_FEATURE_SETS (flags, arm_arch_used, thumb_arch_used);
ddd7f988 28286
54bab281
TP
28287 if (ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any))
28288 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v1);
ddd7f988 28289
54bab281
TP
28290 if (ARM_CPU_HAS_FEATURE (thumb_arch_used, arm_arch_any))
28291 ARM_MERGE_FEATURE_SETS (flags, flags, arm_ext_v4t);
ddd7f988 28292
54bab281 28293 /* Code run during relaxation relies on selected_cpu being set. */
4d354d8b
TP
28294 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
28295 flags_ext = arm_arch_none;
28296 ARM_CLEAR_FEATURE (selected_arch, flags_arch, flags_ext);
28297 selected_ext = flags_ext;
54bab281
TP
28298 selected_cpu = flags;
28299 }
28300 /* Otherwise, choose the architecture based on the capabilities of the
28301 requested cpu. */
28302 else
4d354d8b
TP
28303 {
28304 ARM_MERGE_FEATURE_SETS (flags_arch, selected_arch, selected_ext);
28305 ARM_CLEAR_FEATURE (flags_arch, flags_arch, fpu_any);
28306 flags_ext = selected_ext;
28307 flags = selected_cpu;
28308 }
28309 ARM_MERGE_FEATURE_SETS (flags, flags, selected_fpu);
7f78eb34 28310
ddd7f988 28311 /* Allow the user to override the reported architecture. */
4d354d8b 28312 if (!ARM_FEATURE_ZERO (selected_object_arch))
7a1d4c38 28313 {
4d354d8b 28314 ARM_CLEAR_FEATURE (flags_arch, selected_object_arch, fpu_any);
2c6b98ea 28315 flags_ext = arm_arch_none;
7a1d4c38 28316 }
2c6b98ea 28317 else
4d354d8b 28318 skip_exact_match = ARM_FEATURE_EQUAL (selected_cpu, arm_arch_any);
2c6b98ea
TP
28319
28320 /* When this function is run again after relaxation has happened there is no
28321 way to determine whether an architecture or CPU was specified by the user:
28322 - selected_cpu is set above for relaxation to work;
28323 - march_cpu_opt is not set if only -mcpu or .cpu is used;
28324 - mcpu_cpu_opt is set to arm_arch_any for autodetection.
28325 Therefore, if not in -march=all case we first try an exact match and fall
28326 back to autodetection. */
28327 if (!skip_exact_match)
28328 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 1);
28329 if (arch == -1)
28330 arch = get_aeabi_cpu_arch_from_fset (&flags_arch, &flags_ext, &profile, 0);
28331 if (arch == -1)
28332 as_bad (_("no architecture contains all the instructions used\n"));
9e3c6df6 28333
ee065d83
PB
28334 /* Tag_CPU_name. */
28335 if (selected_cpu_name[0])
28336 {
91d6fa6a 28337 char *q;
ee065d83 28338
91d6fa6a
NC
28339 q = selected_cpu_name;
28340 if (strncmp (q, "armv", 4) == 0)
ee065d83
PB
28341 {
28342 int i;
5f4273c7 28343
91d6fa6a
NC
28344 q += 4;
28345 for (i = 0; q[i]; i++)
28346 q[i] = TOUPPER (q[i]);
ee065d83 28347 }
91d6fa6a 28348 aeabi_set_attribute_string (Tag_CPU_name, q);
ee065d83 28349 }
62f3b8c8 28350
ee065d83 28351 /* Tag_CPU_arch. */
ee3c0378 28352 aeabi_set_attribute_int (Tag_CPU_arch, arch);
62f3b8c8 28353
62b3e311 28354 /* Tag_CPU_arch_profile. */
69239280
MGD
28355 if (profile != '\0')
28356 aeabi_set_attribute_int (Tag_CPU_arch_profile, profile);
62f3b8c8 28357
15afaa63 28358 /* Tag_DSP_extension. */
4d354d8b 28359 if (ARM_CPU_HAS_FEATURE (selected_ext, arm_ext_dsp))
6c290d53 28360 aeabi_set_attribute_int (Tag_DSP_extension, 1);
15afaa63 28361
2c6b98ea 28362 ARM_CLEAR_FEATURE (flags_arch, flags, fpu_any);
ee065d83 28363 /* Tag_ARM_ISA_use. */
ee3c0378 28364 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v1)
2c6b98ea 28365 || ARM_FEATURE_ZERO (flags_arch))
ee3c0378 28366 aeabi_set_attribute_int (Tag_ARM_ISA_use, 1);
62f3b8c8 28367
ee065d83 28368 /* Tag_THUMB_ISA_use. */
ee3c0378 28369 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v4t)
2c6b98ea 28370 || ARM_FEATURE_ZERO (flags_arch))
4ed7ed8d
TP
28371 {
28372 int thumb_isa_use;
28373
28374 if (!ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
16a1fa25 28375 && ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m_m_only))
4ed7ed8d
TP
28376 thumb_isa_use = 3;
28377 else if (ARM_CPU_HAS_FEATURE (flags, arm_arch_t2))
28378 thumb_isa_use = 2;
28379 else
28380 thumb_isa_use = 1;
28381 aeabi_set_attribute_int (Tag_THUMB_ISA_use, thumb_isa_use);
28382 }
62f3b8c8 28383
ee065d83 28384 /* Tag_VFP_arch. */
a715796b
TG
28385 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_armv8xd))
28386 aeabi_set_attribute_int (Tag_VFP_arch,
28387 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
28388 ? 7 : 8);
bca38921 28389 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_fma))
62f3b8c8
PB
28390 aeabi_set_attribute_int (Tag_VFP_arch,
28391 ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32)
28392 ? 5 : 6);
28393 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_d32))
bca38921
MGD
28394 {
28395 fp16_optional = 1;
28396 aeabi_set_attribute_int (Tag_VFP_arch, 3);
28397 }
ada65aa3 28398 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v3xd))
bca38921
MGD
28399 {
28400 aeabi_set_attribute_int (Tag_VFP_arch, 4);
28401 fp16_optional = 1;
28402 }
ee3c0378
AS
28403 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v2))
28404 aeabi_set_attribute_int (Tag_VFP_arch, 2);
28405 else if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1)
477330fc 28406 || ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd))
ee3c0378 28407 aeabi_set_attribute_int (Tag_VFP_arch, 1);
62f3b8c8 28408
4547cb56
NC
28409 /* Tag_ABI_HardFP_use. */
28410 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1xd)
28411 && !ARM_CPU_HAS_FEATURE (flags, fpu_vfp_ext_v1))
28412 aeabi_set_attribute_int (Tag_ABI_HardFP_use, 1);
28413
ee065d83 28414 /* Tag_WMMX_arch. */
ee3c0378
AS
28415 if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt2))
28416 aeabi_set_attribute_int (Tag_WMMX_arch, 2);
28417 else if (ARM_CPU_HAS_FEATURE (flags, arm_cext_iwmmxt))
28418 aeabi_set_attribute_int (Tag_WMMX_arch, 1);
62f3b8c8 28419
ee3c0378 28420 /* Tag_Advanced_SIMD_arch (formerly Tag_NEON_arch). */
9411fd44
MW
28421 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v8_1))
28422 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 4);
28423 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_armv8))
bca38921
MGD
28424 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 3);
28425 else if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_v1))
28426 {
28427 if (ARM_CPU_HAS_FEATURE (flags, fpu_neon_ext_fma))
28428 {
28429 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 2);
28430 }
28431 else
28432 {
28433 aeabi_set_attribute_int (Tag_Advanced_SIMD_arch, 1);
28434 fp16_optional = 1;
28435 }
28436 }
fa94de6b 28437
a7ad558c
AV
28438 if (ARM_CPU_HAS_FEATURE (flags, mve_fp_ext))
28439 aeabi_set_attribute_int (Tag_MVE_arch, 2);
28440 else if (ARM_CPU_HAS_FEATURE (flags, mve_ext))
28441 aeabi_set_attribute_int (Tag_MVE_arch, 1);
28442
ee3c0378 28443 /* Tag_VFP_HP_extension (formerly Tag_NEON_FP16_arch). */
bca38921 28444 if (ARM_CPU_HAS_FEATURE (flags, fpu_vfp_fp16) && fp16_optional)
ee3c0378 28445 aeabi_set_attribute_int (Tag_VFP_HP_extension, 1);
4547cb56 28446
69239280
MGD
28447 /* Tag_DIV_use.
28448
28449 We set Tag_DIV_use to two when integer divide instructions have been used
28450 in ARM state, or when Thumb integer divide instructions have been used,
28451 but we have no architecture profile set, nor have we any ARM instructions.
28452
4ed7ed8d
TP
28453 For ARMv8-A and ARMv8-M we set the tag to 0 as integer divide is implied
28454 by the base architecture.
bca38921 28455
69239280 28456 For new architectures we will have to check these tests. */
031254f2 28457 gas_assert (arch <= TAG_CPU_ARCH_V8_1M_MAIN);
4ed7ed8d
TP
28458 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_v8)
28459 || ARM_CPU_HAS_FEATURE (flags, arm_ext_v8m))
bca38921
MGD
28460 aeabi_set_attribute_int (Tag_DIV_use, 0);
28461 else if (ARM_CPU_HAS_FEATURE (flags, arm_ext_adiv)
28462 || (profile == '\0'
28463 && ARM_CPU_HAS_FEATURE (flags, arm_ext_div)
28464 && !ARM_CPU_HAS_FEATURE (arm_arch_used, arm_arch_any)))
eea54501 28465 aeabi_set_attribute_int (Tag_DIV_use, 2);
60e5ef9f
MGD
28466
28467 /* Tag_MP_extension_use. */
28468 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_mp))
28469 aeabi_set_attribute_int (Tag_MPextension_use, 1);
f4c65163
MGD
28470
28471 /* Tag Virtualization_use. */
28472 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_sec))
90ec0d68
MGD
28473 virt_sec |= 1;
28474 if (ARM_CPU_HAS_FEATURE (flags, arm_ext_virt))
28475 virt_sec |= 2;
28476 if (virt_sec != 0)
28477 aeabi_set_attribute_int (Tag_Virtualization_use, virt_sec);
ee065d83
PB
28478}
28479
c168ce07
TP
28480/* Post relaxation hook. Recompute ARM attributes now that relaxation is
28481 finished and free extension feature bits which will not be used anymore. */
0198d5e6 28482
c168ce07
TP
28483void
28484arm_md_post_relax (void)
28485{
28486 aeabi_set_public_attributes ();
4d354d8b
TP
28487 XDELETE (mcpu_ext_opt);
28488 mcpu_ext_opt = NULL;
28489 XDELETE (march_ext_opt);
28490 march_ext_opt = NULL;
c168ce07
TP
28491}
28492
104d59d1 28493/* Add the default contents for the .ARM.attributes section. */
0198d5e6 28494
ee065d83
PB
28495void
28496arm_md_end (void)
28497{
ee065d83
PB
28498 if (EF_ARM_EABI_VERSION (meabi_flags) < EF_ARM_EABI_VER4)
28499 return;
28500
28501 aeabi_set_public_attributes ();
ee065d83 28502}
8463be01 28503#endif /* OBJ_ELF */
ee065d83 28504
ee065d83
PB
28505/* Parse a .cpu directive. */
28506
28507static void
28508s_arm_cpu (int ignored ATTRIBUTE_UNUSED)
28509{
e74cfd16 28510 const struct arm_cpu_option_table *opt;
ee065d83
PB
28511 char *name;
28512 char saved_char;
28513
28514 name = input_line_pointer;
5f4273c7 28515 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
28516 input_line_pointer++;
28517 saved_char = *input_line_pointer;
28518 *input_line_pointer = 0;
28519
28520 /* Skip the first "all" entry. */
28521 for (opt = arm_cpus + 1; opt->name != NULL; opt++)
28522 if (streq (opt->name, name))
28523 {
4d354d8b
TP
28524 selected_arch = opt->value;
28525 selected_ext = opt->ext;
28526 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
ee065d83 28527 if (opt->canonical_name)
5f4273c7 28528 strcpy (selected_cpu_name, opt->canonical_name);
ee065d83
PB
28529 else
28530 {
28531 int i;
28532 for (i = 0; opt->name[i]; i++)
28533 selected_cpu_name[i] = TOUPPER (opt->name[i]);
f3bad469 28534
ee065d83
PB
28535 selected_cpu_name[i] = 0;
28536 }
4d354d8b
TP
28537 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
28538
ee065d83
PB
28539 *input_line_pointer = saved_char;
28540 demand_empty_rest_of_line ();
28541 return;
28542 }
28543 as_bad (_("unknown cpu `%s'"), name);
28544 *input_line_pointer = saved_char;
28545 ignore_rest_of_line ();
28546}
28547
ee065d83
PB
28548/* Parse a .arch directive. */
28549
28550static void
28551s_arm_arch (int ignored ATTRIBUTE_UNUSED)
28552{
e74cfd16 28553 const struct arm_arch_option_table *opt;
ee065d83
PB
28554 char saved_char;
28555 char *name;
28556
28557 name = input_line_pointer;
5f4273c7 28558 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
28559 input_line_pointer++;
28560 saved_char = *input_line_pointer;
28561 *input_line_pointer = 0;
28562
28563 /* Skip the first "all" entry. */
28564 for (opt = arm_archs + 1; opt->name != NULL; opt++)
28565 if (streq (opt->name, name))
28566 {
4d354d8b
TP
28567 selected_arch = opt->value;
28568 selected_ext = arm_arch_none;
28569 selected_cpu = selected_arch;
5f4273c7 28570 strcpy (selected_cpu_name, opt->name);
4d354d8b 28571 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
28572 *input_line_pointer = saved_char;
28573 demand_empty_rest_of_line ();
28574 return;
28575 }
28576
28577 as_bad (_("unknown architecture `%s'\n"), name);
28578 *input_line_pointer = saved_char;
28579 ignore_rest_of_line ();
28580}
28581
7a1d4c38
PB
28582/* Parse a .object_arch directive. */
28583
28584static void
28585s_arm_object_arch (int ignored ATTRIBUTE_UNUSED)
28586{
28587 const struct arm_arch_option_table *opt;
28588 char saved_char;
28589 char *name;
28590
28591 name = input_line_pointer;
5f4273c7 28592 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
7a1d4c38
PB
28593 input_line_pointer++;
28594 saved_char = *input_line_pointer;
28595 *input_line_pointer = 0;
28596
28597 /* Skip the first "all" entry. */
28598 for (opt = arm_archs + 1; opt->name != NULL; opt++)
28599 if (streq (opt->name, name))
28600 {
4d354d8b 28601 selected_object_arch = opt->value;
7a1d4c38
PB
28602 *input_line_pointer = saved_char;
28603 demand_empty_rest_of_line ();
28604 return;
28605 }
28606
28607 as_bad (_("unknown architecture `%s'\n"), name);
28608 *input_line_pointer = saved_char;
28609 ignore_rest_of_line ();
28610}
28611
69133863
MGD
28612/* Parse a .arch_extension directive. */
28613
28614static void
28615s_arm_arch_extension (int ignored ATTRIBUTE_UNUSED)
28616{
28617 const struct arm_option_extension_value_table *opt;
28618 char saved_char;
28619 char *name;
28620 int adding_value = 1;
28621
28622 name = input_line_pointer;
28623 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
28624 input_line_pointer++;
28625 saved_char = *input_line_pointer;
28626 *input_line_pointer = 0;
28627
28628 if (strlen (name) >= 2
28629 && strncmp (name, "no", 2) == 0)
28630 {
28631 adding_value = 0;
28632 name += 2;
28633 }
28634
28635 for (opt = arm_extensions; opt->name != NULL; opt++)
28636 if (streq (opt->name, name))
28637 {
d942732e
TP
28638 int i, nb_allowed_archs =
28639 sizeof (opt->allowed_archs) / sizeof (opt->allowed_archs[i]);
28640 for (i = 0; i < nb_allowed_archs; i++)
28641 {
28642 /* Empty entry. */
4d354d8b 28643 if (ARM_CPU_IS_ANY (opt->allowed_archs[i]))
d942732e 28644 continue;
4d354d8b 28645 if (ARM_FSET_CPU_SUBSET (opt->allowed_archs[i], selected_arch))
d942732e
TP
28646 break;
28647 }
28648
28649 if (i == nb_allowed_archs)
69133863
MGD
28650 {
28651 as_bad (_("architectural extension `%s' is not allowed for the "
28652 "current base architecture"), name);
28653 break;
28654 }
28655
28656 if (adding_value)
4d354d8b 28657 ARM_MERGE_FEATURE_SETS (selected_ext, selected_ext,
5a70a223 28658 opt->merge_value);
69133863 28659 else
4d354d8b 28660 ARM_CLEAR_FEATURE (selected_ext, selected_ext, opt->clear_value);
69133863 28661
4d354d8b
TP
28662 ARM_MERGE_FEATURE_SETS (selected_cpu, selected_arch, selected_ext);
28663 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
69133863
MGD
28664 *input_line_pointer = saved_char;
28665 demand_empty_rest_of_line ();
3d030cdb
TP
28666 /* Allowing Thumb division instructions for ARMv7 in autodetection rely
28667 on this return so that duplicate extensions (extensions with the
28668 same name as a previous extension in the list) are not considered
28669 for command-line parsing. */
69133863
MGD
28670 return;
28671 }
28672
28673 if (opt->name == NULL)
e673710a 28674 as_bad (_("unknown architecture extension `%s'\n"), name);
69133863
MGD
28675
28676 *input_line_pointer = saved_char;
28677 ignore_rest_of_line ();
28678}
28679
ee065d83
PB
28680/* Parse a .fpu directive. */
28681
28682static void
28683s_arm_fpu (int ignored ATTRIBUTE_UNUSED)
28684{
69133863 28685 const struct arm_option_fpu_value_table *opt;
ee065d83
PB
28686 char saved_char;
28687 char *name;
28688
28689 name = input_line_pointer;
5f4273c7 28690 while (*input_line_pointer && !ISSPACE (*input_line_pointer))
ee065d83
PB
28691 input_line_pointer++;
28692 saved_char = *input_line_pointer;
28693 *input_line_pointer = 0;
5f4273c7 28694
ee065d83
PB
28695 for (opt = arm_fpus; opt->name != NULL; opt++)
28696 if (streq (opt->name, name))
28697 {
4d354d8b
TP
28698 selected_fpu = opt->value;
28699#ifndef CPU_DEFAULT
28700 if (no_cpu_selected ())
28701 ARM_MERGE_FEATURE_SETS (cpu_variant, arm_arch_any, selected_fpu);
28702 else
28703#endif
28704 ARM_MERGE_FEATURE_SETS (cpu_variant, selected_cpu, selected_fpu);
ee065d83
PB
28705 *input_line_pointer = saved_char;
28706 demand_empty_rest_of_line ();
28707 return;
28708 }
28709
28710 as_bad (_("unknown floating point format `%s'\n"), name);
28711 *input_line_pointer = saved_char;
28712 ignore_rest_of_line ();
28713}
ee065d83 28714
794ba86a 28715/* Copy symbol information. */
f31fef98 28716
794ba86a
DJ
28717void
28718arm_copy_symbol_attributes (symbolS *dest, symbolS *src)
28719{
28720 ARM_GET_FLAG (dest) = ARM_GET_FLAG (src);
28721}
e04befd0 28722
f31fef98 28723#ifdef OBJ_ELF
e04befd0
AS
28724/* Given a symbolic attribute NAME, return the proper integer value.
28725 Returns -1 if the attribute is not known. */
f31fef98 28726
e04befd0
AS
28727int
28728arm_convert_symbolic_attribute (const char *name)
28729{
f31fef98
NC
28730 static const struct
28731 {
28732 const char * name;
28733 const int tag;
28734 }
28735 attribute_table[] =
28736 {
28737 /* When you modify this table you should
28738 also modify the list in doc/c-arm.texi. */
e04befd0 28739#define T(tag) {#tag, tag}
f31fef98
NC
28740 T (Tag_CPU_raw_name),
28741 T (Tag_CPU_name),
28742 T (Tag_CPU_arch),
28743 T (Tag_CPU_arch_profile),
28744 T (Tag_ARM_ISA_use),
28745 T (Tag_THUMB_ISA_use),
75375b3e 28746 T (Tag_FP_arch),
f31fef98
NC
28747 T (Tag_VFP_arch),
28748 T (Tag_WMMX_arch),
28749 T (Tag_Advanced_SIMD_arch),
28750 T (Tag_PCS_config),
28751 T (Tag_ABI_PCS_R9_use),
28752 T (Tag_ABI_PCS_RW_data),
28753 T (Tag_ABI_PCS_RO_data),
28754 T (Tag_ABI_PCS_GOT_use),
28755 T (Tag_ABI_PCS_wchar_t),
28756 T (Tag_ABI_FP_rounding),
28757 T (Tag_ABI_FP_denormal),
28758 T (Tag_ABI_FP_exceptions),
28759 T (Tag_ABI_FP_user_exceptions),
28760 T (Tag_ABI_FP_number_model),
75375b3e 28761 T (Tag_ABI_align_needed),
f31fef98 28762 T (Tag_ABI_align8_needed),
75375b3e 28763 T (Tag_ABI_align_preserved),
f31fef98
NC
28764 T (Tag_ABI_align8_preserved),
28765 T (Tag_ABI_enum_size),
28766 T (Tag_ABI_HardFP_use),
28767 T (Tag_ABI_VFP_args),
28768 T (Tag_ABI_WMMX_args),
28769 T (Tag_ABI_optimization_goals),
28770 T (Tag_ABI_FP_optimization_goals),
28771 T (Tag_compatibility),
28772 T (Tag_CPU_unaligned_access),
75375b3e 28773 T (Tag_FP_HP_extension),
f31fef98
NC
28774 T (Tag_VFP_HP_extension),
28775 T (Tag_ABI_FP_16bit_format),
cd21e546
MGD
28776 T (Tag_MPextension_use),
28777 T (Tag_DIV_use),
f31fef98
NC
28778 T (Tag_nodefaults),
28779 T (Tag_also_compatible_with),
28780 T (Tag_conformance),
28781 T (Tag_T2EE_use),
28782 T (Tag_Virtualization_use),
15afaa63 28783 T (Tag_DSP_extension),
a7ad558c 28784 T (Tag_MVE_arch),
cd21e546 28785 /* We deliberately do not include Tag_MPextension_use_legacy. */
e04befd0 28786#undef T
f31fef98 28787 };
e04befd0
AS
28788 unsigned int i;
28789
28790 if (name == NULL)
28791 return -1;
28792
f31fef98 28793 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
c921be7d 28794 if (streq (name, attribute_table[i].name))
e04befd0
AS
28795 return attribute_table[i].tag;
28796
28797 return -1;
28798}
267bf995 28799
93ef582d
NC
28800/* Apply sym value for relocations only in the case that they are for
28801 local symbols in the same segment as the fixup and you have the
28802 respective architectural feature for blx and simple switches. */
0198d5e6 28803
267bf995 28804int
93ef582d 28805arm_apply_sym_value (struct fix * fixP, segT this_seg)
267bf995
RR
28806{
28807 if (fixP->fx_addsy
28808 && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v5t)
93ef582d
NC
28809 /* PR 17444: If the local symbol is in a different section then a reloc
28810 will always be generated for it, so applying the symbol value now
28811 will result in a double offset being stored in the relocation. */
28812 && (S_GET_SEGMENT (fixP->fx_addsy) == this_seg)
34e77a92 28813 && !S_FORCE_RELOC (fixP->fx_addsy, TRUE))
267bf995
RR
28814 {
28815 switch (fixP->fx_r_type)
28816 {
28817 case BFD_RELOC_ARM_PCREL_BLX:
28818 case BFD_RELOC_THUMB_PCREL_BRANCH23:
28819 if (ARM_IS_FUNC (fixP->fx_addsy))
28820 return 1;
28821 break;
28822
28823 case BFD_RELOC_ARM_PCREL_CALL:
28824 case BFD_RELOC_THUMB_PCREL_BLX:
28825 if (THUMB_IS_FUNC (fixP->fx_addsy))
93ef582d 28826 return 1;
267bf995
RR
28827 break;
28828
28829 default:
28830 break;
28831 }
28832
28833 }
28834 return 0;
28835}
f31fef98 28836#endif /* OBJ_ELF */